Files
crypto_trading/backend/app/schemas.py
T
matitos 03dfa369e5
CI/CD / backend (pull_request) Successful in 6m18s
CI/CD / frontend (pull_request) Successful in 4m55s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
Risk controls, alerts, API token, more exchanges, presets
- RiskManager halts + flattens on max daily loss / drawdown, caps position
  size and trades per day; adds a manual kill switch (POST /api/bot/kill).
- Telegram and webhook notifications on trades, errors and halts.
- Optional API bearer token on /api, injected server-side by the frontend
  nginx so the browser never sees it.
- Kraken and Coinbase market data (public); Coinbase live broker. Live on an
  unsupported exchange now errors instead of silently falling back to paper.
- Strategy presets backed by the StrategyConfig table (CRUD API + UI).
- Idempotent additive-column migration so existing SQLite databases upgrade in
  place (fixes the new strategy_configs.name column).
2026-09-18 19:26:29 +00:00

209 lines
4.3 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field
class Candle(BaseModel):
ts: int
open: float
high: float
low: float
close: float
volume: float
class ParamSpec(BaseModel):
name: str
type: Literal["int", "float", "bool", "str"]
default: Any
description: str = ""
min: float | None = None
max: float | None = None
class StrategyOut(BaseModel):
key: str
name: str
description: str
params: list[ParamSpec]
class PositionOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
strategy_key: str
symbol: str
side: str
qty: float
entry_price: float
status: str
stop_loss: float | None = None
take_profit: float | None = None
exit_price: float | None = None
realized_pnl: float | None = None
unrealized_pnl: float | None = None
opened_at: datetime
closed_at: datetime | None = None
class OrderOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
position_id: int | None
strategy_key: str
symbol: str
side: str
qty: float
price: float
fee: float
reason: str
created_at: datetime
class EventOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
level: str
message: str
strategy_key: str | None
created_at: datetime
class EquityPointOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
equity: float
cash: float
price: float
created_at: datetime
class StatusOut(BaseModel):
running: bool
mode: str
exchange: str
symbol: str
timeframe: str
strategy_key: str | None
strategy_name: str | None
params: dict[str, Any] = Field(default_factory=dict)
price: float | None
cash: float
equity: float
starting_balance: float
realized_pnl: float
unrealized_pnl: float
total_pnl: float
open_positions: int
last_tick: datetime | None
error: str | None = None
halted: bool = False
halt_reason: str | None = None
trades_today: int = 0
day_pnl: float = 0.0
drawdown_pct: float = 0.0
class KillRequest(BaseModel):
reason: str = "manual kill switch"
class StrategyConfigIn(BaseModel):
name: str = Field(default="", max_length=80)
strategy_key: str
symbol: str
timeframe: str
params: dict[str, Any] = Field(default_factory=dict)
class StrategyConfigOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
strategy_key: str
symbol: str
timeframe: str
params: dict[str, Any]
created_at: datetime
class StartRequest(BaseModel):
strategy_key: str
symbol: str | None = None
timeframe: str | None = None
params: dict[str, Any] = Field(default_factory=dict)
starting_balance: float | None = None
class ManualOrderRequest(BaseModel):
side: Literal["buy", "sell"]
qty: float | None = None
quote_amount: float | None = None
reason: str = "manual"
class ClosePositionRequest(BaseModel):
reason: str = "manual"
class BacktestRequest(BaseModel):
strategy_key: str
params: dict[str, Any] = Field(default_factory=dict)
symbol: str | None = None
timeframe: str | None = None
limit: int = Field(default=500, ge=20, le=1000)
starting_balance: float | None = None
class BacktestTradeOut(BaseModel):
side: str
entry_ts: int
exit_ts: int
entry_price: float
exit_price: float
qty: float
pnl: float
return_pct: float
reason: str
class BacktestPointOut(BaseModel):
ts: int
equity: float
buy_hold: float
price: float
class BacktestMetricsOut(BaseModel):
initial_equity: float
final_equity: float
total_return_pct: float
buy_hold_return_pct: float
max_drawdown_pct: float
num_trades: int
win_rate_pct: float
profit_factor: float | None
avg_trade_pct: float
best_trade_pct: float
worst_trade_pct: float
sharpe: float | None
class BacktestResult(BaseModel):
strategy_key: str
strategy_name: str
symbol: str
timeframe: str
starting_balance: float
metrics: BacktestMetricsOut
equity_curve: list[BacktestPointOut]
trades: list[BacktestTradeOut]
error: str | None = None