Files
signal-platform/app/schemas/paper_trade.py
T

60 lines
2.0 KiB
Python

"""Schemas for paper trades."""
from __future__ import annotations
from datetime import datetime
from pydantic import BaseModel, Field
class PaperTradeCreate(BaseModel):
symbol: str = Field(..., min_length=1, max_length=10)
direction: str = Field(..., pattern=r"^(long|short)$")
entry_price: float = Field(..., gt=0)
shares: float = Field(..., gt=0)
stop_loss: float = Field(..., gt=0)
target: float = Field(..., gt=0)
class PaperTradeClose(BaseModel):
close_price: float | None = Field(default=None, gt=0)
class ExitPolicyUpdate(BaseModel):
"""Auto-exit policy for open paper trades."""
mode: str | None = Field(default=None, pattern=r"^(time|trailing|atr_trailing|target)$")
trailing_pct: float | None = Field(default=None, ge=0.5, le=90)
atr_multiplier: float | None = Field(default=None, ge=0.5, le=10)
hold_days: int | None = Field(default=None, ge=2, le=250)
class PaperTradeResponse(BaseModel):
id: int
symbol: str
direction: str
entry_price: float
shares: float
stop_loss: float
target: float
status: str
opened_at: datetime
close_price: float | None = None
closed_at: datetime | None = None
current_price: float | None = None
# Alpha vs the S&P 500 (SPY) over the trade's holding period. None when the
# benchmark series doesn't cover the trade's open date yet.
benchmark_return_pct: float | None = None
alpha_pct: float | None = None
alpha_usd: float | None = None
close_reason: str | None = None
# Execution era: null = pre-cutover / unknown; "near_close" = post schedule cutover.
fill_mode: str | None = None
# Live trailing-stop level + how far price sits above it (% ), for open trades
# when the trailing exit policy is active.
trailing_stop: float | None = None
trailing_distance_pct: float | None = None
# Trading sessions represented by post-entry OHLCV bars. These are populated
# only while the active exit policy has a max-hold rule.
sessions_held: int | None = None
sessions_remaining: int | None = None