mirror of
https://github.com/Xe138/AI-Trader.git
synced 2026-04-02 01:27:24 -04:00
feat: add new day-centric results API endpoint
Implements new /results endpoint with day-centric data structure: - Returns starting_position, daily_metrics, trades, and final_position - Supports reasoning levels: none (default), summary, full - Uses database helper methods from trading_days schema - Replaces old positions-based endpoint Changes: - Created api/routes/results_v2.py with new endpoint - Registered router in api/main.py - Removed old /results endpoint (positions table) - Added comprehensive integration tests All tests pass.
This commit is contained in:
1
api/routes/__init__.py
Normal file
1
api/routes/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""API routes package."""
|
||||
112
api/routes/results_v2.py
Normal file
112
api/routes/results_v2.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""New results API with day-centric structure."""
|
||||
|
||||
from fastapi import APIRouter, Query, Depends
|
||||
from typing import Optional, Literal
|
||||
import json
|
||||
|
||||
from api.database import Database
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
def get_database() -> Database:
|
||||
"""Dependency for database instance."""
|
||||
return Database()
|
||||
|
||||
|
||||
@router.get("/results")
|
||||
async def get_results(
|
||||
job_id: Optional[str] = None,
|
||||
model: Optional[str] = None,
|
||||
date: Optional[str] = None,
|
||||
reasoning: Literal["none", "summary", "full"] = "none",
|
||||
db: Database = Depends(get_database)
|
||||
):
|
||||
"""Get trading results grouped by day.
|
||||
|
||||
Args:
|
||||
job_id: Filter by simulation job ID
|
||||
model: Filter by model signature
|
||||
date: Filter by trading date (YYYY-MM-DD)
|
||||
reasoning: Include reasoning logs (none/summary/full)
|
||||
db: Database instance (injected)
|
||||
|
||||
Returns:
|
||||
JSON with day-centric trading results and performance metrics
|
||||
"""
|
||||
|
||||
# Build query with filters
|
||||
query = "SELECT * FROM trading_days WHERE 1=1"
|
||||
params = []
|
||||
|
||||
if job_id:
|
||||
query += " AND job_id = ?"
|
||||
params.append(job_id)
|
||||
|
||||
if model:
|
||||
query += " AND model = ?"
|
||||
params.append(model)
|
||||
|
||||
if date:
|
||||
query += " AND date = ?"
|
||||
params.append(date)
|
||||
|
||||
query += " ORDER BY date ASC, model ASC"
|
||||
|
||||
# Execute query
|
||||
cursor = db.connection.execute(query, params)
|
||||
|
||||
# Format results
|
||||
formatted_results = []
|
||||
|
||||
for row in cursor.fetchall():
|
||||
trading_day_id = row[0]
|
||||
|
||||
# Build response object
|
||||
day_data = {
|
||||
"date": row[3],
|
||||
"model": row[2],
|
||||
"job_id": row[1],
|
||||
|
||||
"starting_position": {
|
||||
"holdings": db.get_starting_holdings(trading_day_id),
|
||||
"cash": row[4], # starting_cash
|
||||
"portfolio_value": row[5] # starting_portfolio_value
|
||||
},
|
||||
|
||||
"daily_metrics": {
|
||||
"profit": row[6], # daily_profit
|
||||
"return_pct": row[7], # daily_return_pct
|
||||
"days_since_last_trading": row[14] if len(row) > 14 else 1
|
||||
},
|
||||
|
||||
"trades": db.get_actions(trading_day_id),
|
||||
|
||||
"final_position": {
|
||||
"holdings": db.get_ending_holdings(trading_day_id),
|
||||
"cash": row[8], # ending_cash
|
||||
"portfolio_value": row[9] # ending_portfolio_value
|
||||
},
|
||||
|
||||
"metadata": {
|
||||
"total_actions": row[12] if row[12] is not None else 0,
|
||||
"session_duration_seconds": row[13],
|
||||
"completed_at": row[16] if len(row) > 16 else None
|
||||
}
|
||||
}
|
||||
|
||||
# Add reasoning if requested
|
||||
if reasoning == "summary":
|
||||
day_data["reasoning"] = row[10] # reasoning_summary
|
||||
elif reasoning == "full":
|
||||
reasoning_full = row[11] # reasoning_full
|
||||
day_data["reasoning"] = json.loads(reasoning_full) if reasoning_full else []
|
||||
else:
|
||||
day_data["reasoning"] = None
|
||||
|
||||
formatted_results.append(day_data)
|
||||
|
||||
return {
|
||||
"count": len(formatted_results),
|
||||
"results": formatted_results
|
||||
}
|
||||
Reference in New Issue
Block a user