updated
All checks were successful
Deployment / deploy-docker (push) Successful in 16s

This commit is contained in:
Melchior Reimers
2026-01-25 18:31:13 +01:00
parent 3c9d277a4c
commit df478b0ea4
2 changed files with 294 additions and 57 deletions

View File

@@ -169,11 +169,12 @@ async def get_custom_analytics(
):
"""
Flexibler Analytics-Endpunkt für custom Graphen.
Nutzt vorberechnete Daten aus analytics_custom für bessere Performance.
Parameters:
- date_from: Startdatum (YYYY-MM-DD)
- date_to: Enddatum (YYYY-MM-DD)
- x_axis: X-Achse (date, exchange, isin)
- x_axis: X-Achse (date, exchange, isin) - aktuell nur "date" unterstützt
- y_axis: Y-Achse (volume, trade_count, avg_price)
- group_by: Gruppierung (exchange, isin, date)
- exchanges: Komma-separierte Liste von Exchanges (optional)
@@ -190,46 +191,123 @@ async def get_custom_analytics(
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}")
# Baue Query auf
y_axis_map = {
"volume": "sum(price * quantity)",
"trade_count": "count(*)",
"avg_price": "avg(price)"
}
# Für Custom Analytics: x_axis muss "date" sein (wird täglich vorberechnet)
if x_axis != "date":
# Fallback auf direkte Query für nicht-date x_axis
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)
x_axis_map = {
"date": "date_trunc('day', timestamp)",
"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]
# Nutze vorberechnete Daten aus analytics_custom
exchange_filter = "all"
if exchanges:
# Wenn mehrere Exchanges angegeben, müssen wir kombinieren
# Für jetzt: nutze nur wenn ein Exchange angegeben ist
exchange_list = [e.strip() for e in exchanges.split(",")]
if len(exchange_list) == 1:
exchange_filter = exchange_list[0]
# Bei mehreren Exchanges: Fallback auf direkte Query
else:
query = f"""
select
timestamp as x_value,
{group_by} as group_value,
{'sum(price * quantity)' if y_axis == 'volume' else 'count(*)' if y_axis == 'trade_count' else 'avg(price)'} as y_value
from trades
where timestamp >= '{date_from}'
and timestamp <= '{date_to}'
and exchange in ({','.join([f"'{e}'" for e in exchange_list])})
group by timestamp, {group_by}
order by timestamp asc, {group_by} asc
"""
data = query_questdb(query, timeout=15)
return format_questdb_response(data)
# Query für vorberechnete Daten
query = f"""
select
{x_label} as x_value,
{group_by_field} as group_value,
{y_metric} as y_value
from trades
timestamp as x_value,
group_value,
y_value
from analytics_custom
where timestamp >= '{date_from}'
and timestamp <= '{date_to}'
and y_axis = '{y_axis}'
and group_by = '{group_by}'
and exchange_filter = '{exchange_filter}'
order by timestamp asc, group_value asc
"""
if exchanges:
exchange_list = ",".join([f"'{e.strip()}'" for e in exchanges.split(",")])
query += f" and exchange in ({exchange_list})"
data = query_questdb(query, timeout=5)
if not data or not data.get('dataset'):
# Fallback: direkte Query wenn keine vorberechneten Daten vorhanden
logger.warning(f"No pre-calculated data found, falling back to direct query")
y_axis_map = {
"volume": "sum(price * quantity)",
"trade_count": "count(*)",
"avg_price": "avg(price)"
}
group_by_map = {
"exchange": "exchange",
"isin": "isin",
"date": "date_trunc('day', timestamp)"
}
y_metric = y_axis_map[y_axis]
group_by_field = group_by_map[group_by]
query = f"""
select
date_trunc('day', timestamp) 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 date_trunc('day', timestamp), {group_by_field} order by x_value asc, group_value asc"
data = query_questdb(query, timeout=15)
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)
@app.get("/api/statistics/moving-average")