This commit is contained in:
@@ -547,10 +547,11 @@
|
||||
|
||||
async function fetchData() {
|
||||
try {
|
||||
// Verwende limit für trades um Performance zu verbessern
|
||||
const [t, m, s] = await Promise.all([
|
||||
fetch(`${API}/trades?days=7`).then(r => r.json()),
|
||||
fetch(`${API}/trades?days=7&limit=1000`).then(r => r.json()),
|
||||
fetch(`${API}/metadata`).then(r => r.json()),
|
||||
fetch(`${API}/summary`).then(r => r.json())
|
||||
fetch(`${API}/summary?days=7`).then(r => r.json())
|
||||
]);
|
||||
store = { ...store, trades: t.dataset || [], metadata: m.dataset || [], summary: s.dataset || [] };
|
||||
updateDashboard();
|
||||
|
||||
@@ -28,11 +28,15 @@ DB_AUTH = (DB_USER, DB_PASSWORD) if DB_USER and DB_PASSWORD else None
|
||||
DB_HOST = os.getenv("DB_HOST", "questdb")
|
||||
|
||||
@app.get("/api/trades")
|
||||
async def get_trades(isin: str = None, days: int = 7):
|
||||
async def get_trades(isin: str = None, days: int = 7, limit: int = 1000):
|
||||
"""
|
||||
Gibt Trades zurück. Standardmäßig limitiert auf 1000 für Performance.
|
||||
Für Dashboard-Übersicht werden nur die neuesten Trades benötigt.
|
||||
"""
|
||||
query = f"select * from trades where timestamp > dateadd('d', -{days}, now())"
|
||||
if isin:
|
||||
query += f" and isin = '{isin}'"
|
||||
query += " order by timestamp asc"
|
||||
query += f" order by timestamp desc limit {limit}"
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
@@ -54,19 +58,56 @@ async def get_metadata():
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/api/summary")
|
||||
async def get_summary():
|
||||
# Coalesce null values to 'Unknown' and group properly
|
||||
query = """
|
||||
async def get_summary(days: int = 7):
|
||||
"""
|
||||
Gibt Zusammenfassung zurück. Optimiert für schnelle Abfrage.
|
||||
Falls vorberechnete Daten verfügbar sind, verwende diese.
|
||||
"""
|
||||
# Versuche zuerst, aus analytics_exchange_daily zu aggregieren (schneller)
|
||||
# Falls das nicht funktioniert, falle auf die ursprüngliche Query zurück
|
||||
try:
|
||||
# Aggregiere aus analytics_exchange_daily für die letzten N Tage
|
||||
# Dies ist schneller als eine JOIN-Query auf alle Trades
|
||||
query = f"""
|
||||
select
|
||||
'All' as continent,
|
||||
sum(trade_count) as trade_count,
|
||||
sum(volume) as total_volume
|
||||
from analytics_exchange_daily
|
||||
where timestamp >= dateadd('d', -{days}, now())
|
||||
"""
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
# Wenn Daten vorhanden, verwende diese
|
||||
if data.get('dataset') and len(data['dataset']) > 0:
|
||||
# Formatiere für Kompatibilität mit dem Frontend
|
||||
result = {
|
||||
'columns': [
|
||||
{'name': 'continent'},
|
||||
{'name': 'trade_count'},
|
||||
{'name': 'total_volume'}
|
||||
],
|
||||
'dataset': [[row[0], row[1], row[2]] for row in data['dataset']]
|
||||
}
|
||||
return result
|
||||
except Exception:
|
||||
# Fallback auf ursprüngliche Query
|
||||
pass
|
||||
|
||||
# Fallback: Original Query mit Limit für Performance
|
||||
query = f"""
|
||||
select
|
||||
coalesce(m.continent, 'Unknown') as continent,
|
||||
count(*) as trade_count,
|
||||
sum(t.price * t.quantity) as total_volume
|
||||
from trades t
|
||||
left join metadata m on t.isin = m.isin
|
||||
where t.timestamp > dateadd('d', -{days}, now())
|
||||
group by continent
|
||||
"""
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH, timeout=10)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
@@ -175,6 +216,7 @@ async def get_moving_average(days: int = 7, exchange: str = None):
|
||||
"""
|
||||
Gibt Moving Average Daten für Tradezahlen und Volumen je Exchange zurück.
|
||||
Unterstützte Zeiträume: 7, 30, 42, 69, 180, 365 Tage
|
||||
Verwendet vorberechnete Daten aus analytics_exchange_daily für schnelle Antwortzeiten.
|
||||
"""
|
||||
if days not in [7, 30, 42, 69, 180, 365]:
|
||||
raise HTTPException(status_code=400, detail="Invalid days parameter. Must be one of: 7, 30, 42, 69, 180, 365")
|
||||
@@ -198,7 +240,7 @@ async def get_moving_average(days: int = 7, exchange: str = None):
|
||||
query += " order by date asc, exchange asc"
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH, timeout=5)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
@@ -210,6 +252,7 @@ async def get_volume_changes(days: int = 7):
|
||||
"""
|
||||
Gibt Änderungen in Volumen und Anzahl je Exchange zurück.
|
||||
Unterstützte Zeiträume: 7, 30, 42, 69, 180, 365 Tage
|
||||
Verwendet vorberechnete Daten aus analytics_volume_changes für schnelle Antwortzeiten.
|
||||
"""
|
||||
if days not in [7, 30, 42, 69, 180, 365]:
|
||||
raise HTTPException(status_code=400, detail="Invalid days parameter. Must be one of: 7, 30, 42, 69, 180, 365")
|
||||
@@ -229,7 +272,7 @@ async def get_volume_changes(days: int = 7):
|
||||
"""
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH, timeout=5)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
@@ -241,6 +284,7 @@ async def get_stock_trends(days: int = 7, limit: int = 20):
|
||||
"""
|
||||
Gibt Trendanalyse für häufig gehandelte Aktien zurück.
|
||||
Unterstützte Zeiträume: 7, 30, 42, 69, 180, 365 Tage
|
||||
Verwendet vorberechnete Daten aus analytics_stock_trends für schnelle Antwortzeiten.
|
||||
"""
|
||||
if days not in [7, 30, 42, 69, 180, 365]:
|
||||
raise HTTPException(status_code=400, detail="Invalid days parameter. Must be one of: 7, 30, 42, 69, 180, 365")
|
||||
@@ -261,7 +305,7 @@ async def get_stock_trends(days: int = 7, limit: int = 20):
|
||||
"""
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH, timeout=5)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
|
||||
Reference in New Issue
Block a user