64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter
|
|
from typing import Any, Dict, List
|
|
from datetime import datetime, timezone
|
|
|
|
from app.api.trading import simulation_state
|
|
from app.streaming.live_store import live_store
|
|
|
|
router = APIRouter(prefix="/account", tags=["Account"])
|
|
router_positions = APIRouter(tags=["Positions"])
|
|
|
|
|
|
def _latest_close(symbol: str, timeframe: str = "1m") -> float | None:
|
|
try:
|
|
history = live_store.get_history(symbol, timeframe)
|
|
if history:
|
|
return float(history[-1]["close"])
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
@router.get("")
|
|
async def get_account() -> Dict[str, Any]:
|
|
cash = float(simulation_state.get("cash", 0.0))
|
|
initial = float(simulation_state.get("initial_capital", 0.0))
|
|
pos = simulation_state.get("position")
|
|
position_value = 0.0
|
|
exposure: Dict[str, float] = {}
|
|
if pos:
|
|
symbol = pos.get("symbol", "XAU/USD")
|
|
last = _latest_close(symbol) or float(pos["avg_price"])
|
|
position_value = float(pos["quantity"]) * last
|
|
exposure[symbol] = position_value
|
|
equity = cash + position_value
|
|
return {
|
|
"time": datetime.now(timezone.utc).isoformat(),
|
|
"cash": cash,
|
|
"equity": equity,
|
|
"initial_capital": initial,
|
|
"margin_used": 0.0,
|
|
"exposure": exposure,
|
|
}
|
|
|
|
|
|
@router.get("/positions")
|
|
@router_positions.get("/positions")
|
|
async def get_positions() -> List[Dict[str, Any]]:
|
|
pos = simulation_state.get("position")
|
|
if not pos:
|
|
return []
|
|
symbol = pos.get("symbol", "XAU/USD")
|
|
last = _latest_close(symbol)
|
|
return [
|
|
{
|
|
"symbol": symbol,
|
|
"quantity": float(pos["quantity"]),
|
|
"avg_price": float(pos["avg_price"]),
|
|
"last_price": float(last) if last is not None else None,
|
|
"market_value": float(pos["quantity"]) * (float(last) if last is not None else float(pos["avg_price"]))
|
|
}
|
|
]
|