Implement FastAPI backend and Vue 3 frontend for Lowkey Backtest UI
- Added FastAPI backend with core API endpoints for strategies, backtests, and data management. - Introduced Vue 3 frontend with a dark theme, enabling users to run backtests, adjust parameters, and compare results. - Implemented Pydantic schemas for request/response validation and SQLAlchemy models for database interactions. - Enhanced project structure with dedicated modules for services, routers, and components. - Updated dependencies in `pyproject.toml` and `frontend/package.json` to include FastAPI, SQLAlchemy, and Vue-related packages. - Improved `.gitignore` to exclude unnecessary files and directories.
This commit is contained in:
162
api/models/schemas.py
Normal file
162
api/models/schemas.py
Normal file
@@ -0,0 +1,162 @@
|
||||
"""
|
||||
Pydantic schemas for API request/response models.
|
||||
"""
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# --- Strategy Schemas ---
|
||||
|
||||
class StrategyParam(BaseModel):
|
||||
"""Single strategy parameter definition."""
|
||||
name: str
|
||||
value: Any
|
||||
param_type: str = Field(description="Type: int, float, bool, list")
|
||||
min_value: float | None = None
|
||||
max_value: float | None = None
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class StrategyInfo(BaseModel):
|
||||
"""Strategy information with parameters."""
|
||||
name: str
|
||||
display_name: str
|
||||
market_type: str
|
||||
default_leverage: int
|
||||
default_params: dict[str, Any]
|
||||
grid_params: dict[str, Any]
|
||||
|
||||
|
||||
class StrategiesResponse(BaseModel):
|
||||
"""Response for GET /api/strategies."""
|
||||
strategies: list[StrategyInfo]
|
||||
|
||||
|
||||
# --- Symbol/Data Schemas ---
|
||||
|
||||
class SymbolInfo(BaseModel):
|
||||
"""Available symbol information."""
|
||||
symbol: str
|
||||
exchange: str
|
||||
market_type: str
|
||||
timeframes: list[str]
|
||||
start_date: str | None = None
|
||||
end_date: str | None = None
|
||||
row_count: int = 0
|
||||
|
||||
|
||||
class DataStatusResponse(BaseModel):
|
||||
"""Response for GET /api/data/status."""
|
||||
symbols: list[SymbolInfo]
|
||||
|
||||
|
||||
# --- Backtest Schemas ---
|
||||
|
||||
class BacktestRequest(BaseModel):
|
||||
"""Request body for POST /api/backtest."""
|
||||
strategy: str
|
||||
symbol: str
|
||||
exchange: str = "okx"
|
||||
timeframe: str = "1h"
|
||||
market_type: str = "perpetual"
|
||||
start_date: str | None = None
|
||||
end_date: str | None = None
|
||||
init_cash: float = 10000.0
|
||||
leverage: int | None = None
|
||||
fees: float | None = None
|
||||
slippage: float = 0.001
|
||||
sl_stop: float | None = None
|
||||
tp_stop: float | None = None
|
||||
sl_trail: bool = False
|
||||
params: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class TradeRecord(BaseModel):
|
||||
"""Single trade record."""
|
||||
entry_time: str
|
||||
exit_time: str | None = None
|
||||
entry_price: float
|
||||
exit_price: float | None = None
|
||||
size: float
|
||||
direction: str
|
||||
pnl: float | None = None
|
||||
return_pct: float | None = None
|
||||
status: str = "closed"
|
||||
|
||||
|
||||
class EquityPoint(BaseModel):
|
||||
"""Single point on equity curve."""
|
||||
timestamp: str
|
||||
value: float
|
||||
drawdown: float = 0.0
|
||||
|
||||
|
||||
class BacktestMetrics(BaseModel):
|
||||
"""Backtest performance metrics."""
|
||||
total_return: float
|
||||
benchmark_return: float = 0.0
|
||||
alpha: float = 0.0
|
||||
sharpe_ratio: float
|
||||
max_drawdown: float
|
||||
win_rate: float
|
||||
total_trades: int
|
||||
profit_factor: float | None = None
|
||||
avg_trade_return: float | None = None
|
||||
total_fees: float = 0.0
|
||||
total_funding: float = 0.0
|
||||
liquidation_count: int = 0
|
||||
liquidation_loss: float = 0.0
|
||||
adjusted_return: float | None = None
|
||||
|
||||
|
||||
class BacktestResult(BaseModel):
|
||||
"""Complete backtest result."""
|
||||
run_id: str
|
||||
strategy: str
|
||||
symbol: str
|
||||
market_type: str
|
||||
timeframe: str
|
||||
start_date: str
|
||||
end_date: str
|
||||
leverage: int
|
||||
params: dict[str, Any]
|
||||
metrics: BacktestMetrics
|
||||
equity_curve: list[EquityPoint]
|
||||
trades: list[TradeRecord]
|
||||
created_at: str
|
||||
|
||||
|
||||
class BacktestSummary(BaseModel):
|
||||
"""Summary for backtest list view."""
|
||||
run_id: str
|
||||
strategy: str
|
||||
symbol: str
|
||||
market_type: str
|
||||
timeframe: str
|
||||
total_return: float
|
||||
sharpe_ratio: float
|
||||
max_drawdown: float
|
||||
total_trades: int
|
||||
created_at: str
|
||||
params: dict[str, Any]
|
||||
|
||||
|
||||
class BacktestListResponse(BaseModel):
|
||||
"""Response for GET /api/backtests."""
|
||||
runs: list[BacktestSummary]
|
||||
total: int
|
||||
|
||||
|
||||
# --- Comparison Schemas ---
|
||||
|
||||
class CompareRequest(BaseModel):
|
||||
"""Request body for POST /api/compare."""
|
||||
run_ids: list[str] = Field(min_length=2, max_length=5)
|
||||
|
||||
|
||||
class CompareResult(BaseModel):
|
||||
"""Comparison of multiple backtest runs."""
|
||||
runs: list[BacktestResult]
|
||||
param_diff: dict[str, list[Any]]
|
||||
Reference in New Issue
Block a user