Files
crypto_trader/backend/api/portfolio.py

85 lines
2.7 KiB
Python

"""Portfolio API endpoints."""
from typing import Optional
from fastapi import APIRouter, HTTPException, Depends, Query
from datetime import datetime, timedelta
from ..core.dependencies import get_portfolio_tracker
from ..core.schemas import PortfolioResponse, PortfolioHistoryResponse
router = APIRouter()
# Import portfolio analytics
def get_portfolio_analytics():
"""Get portfolio analytics instance."""
from src.portfolio.analytics import get_portfolio_analytics as _get_analytics
return _get_analytics()
@router.get("/current", response_model=PortfolioResponse)
async def get_current_portfolio(
paper_trading: bool = True,
tracker=Depends(get_portfolio_tracker)
):
"""Get current portfolio state."""
try:
portfolio = await tracker.get_current_portfolio(paper_trading=paper_trading)
return PortfolioResponse(**portfolio)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/history", response_model=PortfolioHistoryResponse)
async def get_portfolio_history(
days: int = Query(30, ge=1, le=365),
paper_trading: bool = True,
tracker=Depends(get_portfolio_tracker)
):
"""Get portfolio history."""
try:
history = await tracker.get_portfolio_history(days=days, paper_trading=paper_trading)
dates = [h['timestamp'] if isinstance(h['timestamp'], str) else h['timestamp'].isoformat()
for h in history]
values = [float(h['total_value']) for h in history]
pnl = [float(h.get('total_pnl', 0)) for h in history]
return PortfolioHistoryResponse(
dates=dates,
values=values,
pnl=pnl
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/positions/update-prices")
async def update_positions_prices(
prices: dict,
paper_trading: bool = True,
tracker=Depends(get_portfolio_tracker)
):
"""Update current prices for positions."""
try:
from decimal import Decimal
price_dict = {k: Decimal(str(v)) for k, v in prices.items()}
await tracker.update_positions_prices(price_dict, paper_trading=paper_trading)
return {"status": "updated"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/risk-metrics")
async def get_risk_metrics(
days: int = Query(30, ge=1, le=365),
paper_trading: bool = True,
analytics=Depends(get_portfolio_analytics)
):
"""Get portfolio risk metrics."""
try:
metrics = await analytics.get_performance_metrics(days=days, paper_trading=paper_trading)
return metrics
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))