abfrage der prozentwerte für tag/1 monat, 3 monate, 6 monate, 12 monate

test muß noch
This commit is contained in:
Frederik Jaeckel 2022-11-25 15:28:49 +01:00
parent cba2117d13
commit d70e674e58
6 changed files with 159 additions and 95 deletions

168
asset.py
View file

@ -15,6 +15,9 @@ from sql.conditionals import Case, Coalesce
from sql import Literal
digits_percent = 2
class Asset(ModelSQL, ModelView):
'Asset'
__name__ = 'investment.asset'
@ -56,8 +59,7 @@ class Asset(ModelSQL, ModelView):
currency = fields.Many2One(string='Currency', select=True,
required=True, model_name='currency.currency', ondelete='RESTRICT')
currency_digits = fields.Integer(string='Currency Digits',
required=True)
currency_digits = fields.Integer(string='Digits', required=True)
wkn = fields.Function(fields.Char(string='NSIN', readonly=True,
help='National Securities Identifying Number'),
@ -81,33 +83,33 @@ class Asset(ModelSQL, ModelView):
'get_nextupdtates', searcher='search_nextupdtate')
# percentage change
change_today = fields.Function(fields.Numeric(string='Previous Day',
change_day1 = fields.Function(fields.Numeric(string='Previous Day',
help='percentage change in value compared to the previous day',
readonly=True, digits=(16,1)),
readonly=True, digits=(16,digits_percent)),
'get_percentage_change')
change_month = fields.Function(fields.Numeric(string='1 Month',
change_month1 = fields.Function(fields.Numeric(string='1 Month',
help='percentage change in value compared to last month',
readonly=True, digits=(16,1)),
readonly=True, digits=(16,digits_percent)),
'get_percentage_change')
change_3month = fields.Function(fields.Numeric(string='3 Months',
change_month3 = fields.Function(fields.Numeric(string='3 Months',
help='percentage change in value during 3 months',
readonly=True, digits=(16,1)),
readonly=True, digits=(16,digits_percent)),
'get_percentage_change')
change_6month = fields.Function(fields.Numeric(string='6 Months',
change_month6 = fields.Function(fields.Numeric(string='6 Months',
help='percentage change in value during 6 months',
readonly=True, digits=(16,1)),
readonly=True, digits=(16,digits_percent)),
'get_percentage_change')
change_12month = fields.Function(fields.Numeric(string='1 Year',
change_month12 = fields.Function(fields.Numeric(string='1 Year',
help='percentage change in value during 1 year',
readonly=True, digits=(16,1)),
readonly=True, digits=(16,digits_percent)),
'get_percentage_change')
@classmethod
def view_attributes(cls):
return super().view_attributes() + [
('/tree', 'visual',
If(Eval('change_today', 0) < 0, 'warning',
If(Eval('change_today', 0) > 0, 'success', '')
If(Eval('change_day1', 0) < 0, 'warning',
If(Eval('change_day1', 0) > 0, 'success', '')
)),
]
@ -134,17 +136,25 @@ class Asset(ModelSQL, ModelView):
return 4
@classmethod
def get_percentage_sql(cls, table_asset):
def get_percentage_sql(cls, table_asset, name_lst):
""" get table for percentages and dates
generate adapted query
"""
pool = Pool()
Rate = pool.get('investment.rate')
tab_rate_today = Rate.__table__()
tab_rate_1day = Rate.__table__()
tab_rate_1month = Rate.__table__()
tab_rate_3month = Rate.__table__()
rate_tab = {
'day1': {'tab': Rate.__table__(), 'day': 0},
'month1': {'tab': Rate.__table__(), 'day': 30},
'month3': {'tab': Rate.__table__(), 'day': 3*30},
'month6': {'tab': Rate.__table__(), 'day': 6*30},
'month12': {'tab': Rate.__table__(), 'day': 12*30},
}
context = Transaction().context
# create tables to query percentual changes for
# 1 day, 30 days, 3 months, 6 months, 1 year
query_date = context.get('qdate', CurrentDate())
query_today = table_asset.join(tab_rate_today,
condition=table_asset.id==tab_rate_today.asset,
@ -157,41 +167,76 @@ class Asset(ModelSQL, ModelView):
where=tab_rate_today.date <= query_date,
)
query = query_today.join(tab_rate_1day,
# select newest date from yesterday until 3 days old
condition=(query_today.id==tab_rate_1day.asset) & \
(query_today.date > tab_rate_1day.date) & \
(query_today.date < tab_rate_1day.date + Literal(3)),
type_ = 'LEFT OUTER',
).join(tab_rate_1month,
# select newest date from 1 month ago until +3 days old
condition=(query_today.id==tab_rate_1month.asset) & \
(query_today.date > tab_rate_1month.date + Literal(30)) & \
(query_today.date < tab_rate_1month.date + Literal(33)),
type_ = 'LEFT OUTER',
).select(
query_today.id,
query_today.date,
# create join for requested fields, to minimize database-load
query = query_today
for name in name_lst:
query = query.join(rate_tab[name]['tab'],
# select newest date from <period> until 3 days older
condition=(query_today.id==rate_tab[name]['tab'].asset) & \
(query_today.date > (rate_tab[name]['tab'].date + Literal(rate_tab[name]['day']))) & \
(query_today.date < (rate_tab[name]['tab'].date + Literal(rate_tab[name]['day'] + 3))),
type_ = 'LEFT OUTER')
# add select for requested fields to join
select_lst = [
query_today.id,
query_today.date,
]
for name in name_lst:
select_lst.append(
Case(
((tab_rate_1day.rate != None) & (query_today.rate != None) & \
(tab_rate_1day.rate != Literal(0.0)),
query_today.rate * Literal(100.0) / tab_rate_1day.rate - Literal(100.0)),
((rate_tab[name]['tab'].rate != None) & (query_today.rate != None) & \
(rate_tab[name]['tab'].rate != Literal(0.0)),
query_today.rate * Literal(100.0) / rate_tab[name]['tab'].rate - Literal(100.0)),
else_ = None,
).as_('day1'),
Case(
((tab_rate_1month.rate != None) & (query_today.rate != None) & \
(tab_rate_1month.rate != Literal(0.0)),
query_today.rate * Literal(100.0) / tab_rate_1month.rate - Literal(100.0)),
else_ = None,
).as_('month1'),
distinct_on=[query_today.id],
order_by=[
query_today.id,
tab_rate_1day.date.desc,
tab_rate_1month.date.desc,
],
).as_(name))
order_by_lst = [query_today.id]
order_by_lst.extend([
rate_tab[name]['tab'].date.desc for name in name_lst
])
query = query.select(
*select_lst,
distinct_on=[query_today.id],
order_by=order_by_lst,
)
# ~ query = query_today.join(tab_rate_1day,
# ~ # select newest date from yesterday until 3 days old
# ~ condition=(query_today.id==tab_rate_1day.asset) & \
# ~ (query_today.date > tab_rate_1day.date) & \
# ~ (query_today.date < tab_rate_1day.date + Literal(3)),
# ~ type_ = 'LEFT OUTER',
# ~ ).join(tab_rate_1month,
# ~ # select newest date from 1 month ago until +3 days old
# ~ condition=(query_today.id==tab_rate_1month.asset) & \
# ~ (query_today.date > tab_rate_1month.date + Literal(30)) & \
# ~ (query_today.date < tab_rate_1month.date + Literal(33)),
# ~ type_ = 'LEFT OUTER',
# ~ ).select(
# ~ query_today.id,
# ~ query_today.date,
# ~ Case(
# ~ ((tab_rate_1day.rate != None) & (query_today.rate != None) & \
# ~ (tab_rate_1day.rate != Literal(0.0)),
# ~ query_today.rate * Literal(100.0) / tab_rate_1day.rate - Literal(100.0)),
# ~ else_ = None,
# ~ ).as_('day1'),
# ~ Case(
# ~ ((tab_rate_1month.rate != None) & (query_today.rate != None) & \
# ~ (tab_rate_1month.rate != Literal(0.0)),
# ~ query_today.rate * Literal(100.0) / tab_rate_1month.rate - Literal(100.0)),
# ~ else_ = None,
# ~ ).as_('month1'),
# ~ distinct_on=[query_today.id],
# ~ order_by=[
# ~ query_today.id,
# ~ tab_rate_1day.date.desc,
# ~ tab_rate_1month.date.desc,
# ~ ],
# ~ )
return query
@classmethod
@ -203,33 +248,26 @@ class Asset(ModelSQL, ModelView):
tab_asset = Asset.__table__()
cursor = Transaction().connection.cursor()
tab_percent = cls.get_percentage_sql(tab_asset)
name_lst = [x[len('change_'):] for x in names]
tab_percent = cls.get_percentage_sql(tab_asset, name_lst)
query = tab_percent.select(
tab_percent.id,
tab_percent.day1,
tab_percent.month1,
*[getattr(tab_percent, x) for x in name_lst],
where=tab_percent.id.in_([x.id for x in assets]),
)
cursor.execute(*query)
records = cursor.fetchall()
result = {x:{y.id: None for y in assets} for x in names}
exp = Decimal(Decimal(1) / 10 ** digits_percent)
for record in records:
values = {
'change_today': record[1].quantize(Decimal('0.1')) \
if record[1] is not None else None,
'change_month': record[2].quantize(Decimal('0.1')) \
if record[2] is not None else None,
'change_3month': None,
'change_6month': None,
'change_12month': None,
}
for name in names:
result[name][record[0]] = values[name]
cnt1 = 1
for x in name_lst:
result['change_%s' % x][record[0]] = record[cnt1].quantize(exp) \
if record[cnt1] is not None else None
cnt1 += 1
return result
@classmethod
def get_rate_data(cls, assets, names):
""" get date and rate of asset