fixed dashboard - updated analytics to include sectors instead of isin
Some checks failed
Deployment / deploy-docker (push) Has been cancelled

This commit is contained in:
Melchior Reimers
2026-02-03 13:58:47 +01:00
parent 33939c7e46
commit f608f7ca40
3 changed files with 37 additions and 44 deletions

View File

@@ -47,9 +47,9 @@ const ANALYTICS_CONFIG = {
label: 'Exchange', label: 'Exchange',
description: 'Gruppierung nach Exchange' description: 'Gruppierung nach Exchange'
}, },
'isin': { 'sector': {
label: 'ISIN', label: 'Sektor',
description: 'Gruppierung nach ISIN' description: 'Gruppierung nach Sektor'
}, },
'date': { 'date': {
label: 'Datum', label: 'Datum',

View File

@@ -383,7 +383,7 @@
if (typeof dateVal === 'string') { if (typeof dateVal === 'string') {
return dateVal.split('T')[0]; // Extract date part return dateVal.split('T')[0]; // Extract date part
} else if (typeof dateVal === 'number') { } else if (typeof dateVal === 'number') {
return new Date(dateVal / 1000).toISOString().split('T')[0]; return new Date(dateVal / 1000000).toISOString().split('T')[0];
} }
return dateVal; return dateVal;
}))].sort(); }))].sort();
@@ -424,7 +424,7 @@
if (typeof rowDate === 'string') { if (typeof rowDate === 'string') {
rowDateStr = rowDate.split('T')[0]; rowDateStr = rowDate.split('T')[0];
} else if (typeof rowDate === 'number') { } else if (typeof rowDate === 'number') {
rowDateStr = new Date(rowDate / 1000).toISOString().split('T')[0]; rowDateStr = new Date(rowDate / 1000000).toISOString().split('T')[0];
} }
return rowDateStr === date && config.exchanges.includes(exchange); return rowDateStr === date && config.exchanges.includes(exchange);
}); });

View File

@@ -203,7 +203,7 @@ async def get_custom_analytics(
# Validiere Parameter # Validiere Parameter
valid_x_axis = ["date", "exchange", "isin"] valid_x_axis = ["date", "exchange", "isin"]
valid_y_axis = ["volume", "trade_count", "avg_price"] valid_y_axis = ["volume", "trade_count", "avg_price"]
valid_group_by = ["exchange", "isin", "date"] valid_group_by = ["exchange", "sector", "date"]
if x_axis not in valid_x_axis: if x_axis not in valid_x_axis:
raise HTTPException(status_code=400, detail=f"Invalid x_axis. Must be one of: {valid_x_axis}") raise HTTPException(status_code=400, detail=f"Invalid x_axis. Must be one of: {valid_x_axis}")
@@ -212,6 +212,36 @@ async def get_custom_analytics(
if group_by not in valid_group_by: if group_by not in valid_group_by:
raise HTTPException(status_code=400, detail=f"Invalid group_by. Must be one of: {valid_group_by}") raise HTTPException(status_code=400, detail=f"Invalid group_by. Must be one of: {valid_group_by}")
# Für Sektor-Gruppierung: direkter JOIN mit metadata (nicht vorberechnet)
if group_by == "sector":
y_axis_map = {
"volume": "sum(t.price * t.quantity)",
"trade_count": "count(*)",
"avg_price": "avg(t.price)"
}
y_metric = y_axis_map[y_axis]
query = f"""
select
date_trunc('day', t.timestamp) as x_value,
coalesce(m.sector, 'Unbekannt') as group_value,
{y_metric} as y_value
from trades t
left join metadata m on t.isin = m.isin
where t.timestamp >= '{date_from}'
and t.timestamp <= '{date_to}'
"""
if exchanges:
exchange_list = ",".join([f"'{e.strip()}'" for e in exchanges.split(",")])
query += f" and t.exchange in ({exchange_list})"
query += f" group by date_trunc('day', t.timestamp), coalesce(m.sector, 'Unbekannt') order by x_value asc, group_value asc"
data = query_questdb(query, timeout=30)
return format_questdb_response(data)
# Für Custom Analytics: x_axis muss "date" sein (wird täglich vorberechnet) # Für Custom Analytics: x_axis muss "date" sein (wird täglich vorberechnet)
if x_axis != "date": if x_axis != "date":
# Für nicht-date x_axis: gib Fehler zurück, da dies nicht vorberechnet wird # Für nicht-date x_axis: gib Fehler zurück, da dies nicht vorberechnet wird
@@ -219,43 +249,6 @@ async def get_custom_analytics(
status_code=400, status_code=400,
detail="x_axis must be 'date' for pre-calculated analytics. Other x_axis values are not supported for performance reasons." detail="x_axis must be 'date' for pre-calculated analytics. Other x_axis values are not supported for performance reasons."
) )
y_axis_map = {
"volume": "sum(price * quantity)",
"trade_count": "count(*)",
"avg_price": "avg(price)"
}
x_axis_map = {
"exchange": "exchange",
"isin": "isin"
}
group_by_map = {
"exchange": "exchange",
"isin": "isin",
"date": "date_trunc('day', timestamp)"
}
y_metric = y_axis_map[y_axis]
x_label = x_axis_map[x_axis]
group_by_field = group_by_map[group_by]
query = f"""
select
{x_label} as x_value,
{group_by_field} as group_value,
{y_metric} as y_value
from trades
where timestamp >= '{date_from}'
and timestamp <= '{date_to}'
"""
if exchanges:
exchange_list = ",".join([f"'{e.strip()}'" for e in exchanges.split(",")])
query += f" and exchange in ({exchange_list})"
query += f" group by {x_label}, {group_by_field} order by {x_label} asc, {group_by_field} asc"
data = query_questdb(query, timeout=15)
return format_questdb_response(data)
# Nutze vorberechnete Daten aus analytics_custom # Nutze vorberechnete Daten aus analytics_custom
exchange_filter = "all" exchange_filter = "all"