feat: wire up stop levels, circuit breaker daily loss, profit-taking, real portfolio/decisions/history endpoints
This commit is contained in:
+79
-4
@@ -363,11 +363,60 @@ async def set_capital(body: CapitalRequest) -> dict[str, Any]:
|
||||
async def list_decisions(
|
||||
ticker: Optional[str] = None,
|
||||
decision: Optional[str] = None,
|
||||
is_micro_trade: Optional[bool] = None,
|
||||
limit: int = Query(default=50, le=200),
|
||||
offset: int = 0,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Return recent trading decisions (placeholder — paginated)."""
|
||||
return []
|
||||
"""Return recent trading decisions from the database."""
|
||||
if engine is None or engine.pool is None:
|
||||
return []
|
||||
|
||||
conditions = ["1=1"]
|
||||
params: list[Any] = []
|
||||
idx = 1
|
||||
|
||||
if ticker:
|
||||
conditions.append(f"ticker = ${idx}")
|
||||
params.append(ticker.upper())
|
||||
idx += 1
|
||||
if decision:
|
||||
conditions.append(f"decision = ${idx}")
|
||||
params.append(decision)
|
||||
idx += 1
|
||||
if is_micro_trade is not None:
|
||||
conditions.append(f"is_micro_trade = ${idx}")
|
||||
params.append(is_micro_trade)
|
||||
idx += 1
|
||||
|
||||
where = " AND ".join(conditions)
|
||||
params.extend([limit, offset])
|
||||
|
||||
try:
|
||||
rows = await engine.pool.fetch(
|
||||
f"SELECT id, recommendation_id, decision, skip_reason, ticker, "
|
||||
f"computed_position_size, computed_share_quantity, "
|
||||
f"risk_tier_at_decision, portfolio_heat_at_decision, "
|
||||
f"active_pool_at_decision, reserve_pool_at_decision, "
|
||||
f"circuit_breaker_status, is_micro_trade, created_at "
|
||||
f"FROM trading_decisions WHERE {where} "
|
||||
f"ORDER BY created_at DESC LIMIT ${idx} OFFSET ${idx + 1}",
|
||||
*params,
|
||||
)
|
||||
from decimal import Decimal as _Dec
|
||||
result = []
|
||||
for r in rows:
|
||||
d = dict(r)
|
||||
for k, v in d.items():
|
||||
if isinstance(v, _Dec):
|
||||
d[k] = float(v)
|
||||
elif isinstance(v, datetime):
|
||||
d[k] = v.isoformat()
|
||||
elif hasattr(v, '__str__') and not isinstance(v, (str, int, float, bool, type(None))):
|
||||
d[k] = str(v)
|
||||
result.append(d)
|
||||
return result
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -401,8 +450,34 @@ async def current_metrics() -> dict[str, Any]:
|
||||
async def metrics_history(
|
||||
limit: int = Query(default=30, le=365),
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Return historical daily snapshots (placeholder)."""
|
||||
return []
|
||||
"""Return historical daily portfolio snapshots."""
|
||||
if engine is None or engine.pool is None:
|
||||
return []
|
||||
|
||||
try:
|
||||
rows = await engine.pool.fetch(
|
||||
"SELECT id, snapshot_date, portfolio_value, active_pool, reserve_pool, "
|
||||
"daily_return, cumulative_return, unrealized_pnl, realized_pnl, "
|
||||
"win_count, loss_count, win_rate, sharpe_ratio, max_drawdown, "
|
||||
"current_drawdown_pct, portfolio_heat, risk_tier, created_at "
|
||||
"FROM portfolio_snapshots ORDER BY snapshot_date DESC LIMIT $1",
|
||||
limit,
|
||||
)
|
||||
from decimal import Decimal as _Dec
|
||||
result = []
|
||||
for r in rows:
|
||||
d = dict(r)
|
||||
for k, v in d.items():
|
||||
if isinstance(v, _Dec):
|
||||
d[k] = float(v)
|
||||
elif isinstance(v, datetime):
|
||||
d[k] = v.isoformat()
|
||||
elif hasattr(v, '__str__') and not isinstance(v, (str, int, float, bool, type(None))):
|
||||
d[k] = str(v)
|
||||
result.append(d)
|
||||
return result
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user