penti/backend/app/models/backtest.py

53 lines
2.1 KiB
Python
Raw Permalink Normal View History

2026-01-31 23:30:51 +09:00
"""Backtest models (백테스트)."""
from sqlalchemy import Column, String, Numeric, Date, DateTime, ForeignKey
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship
import uuid
from datetime import datetime
from app.database import Base
class BacktestRun(Base):
"""Backtest run model (백테스트 실행 기록)."""
__tablename__ = "backtest_runs"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = Column(String(100), nullable=False)
strategy_name = Column(String(50), nullable=False)
start_date = Column(Date, nullable=False)
end_date = Column(Date, nullable=False)
initial_capital = Column(Numeric(15, 2), nullable=False)
status = Column(String(20), default='running') # running, completed, failed
config = Column(JSONB) # 전략 설정 (JSON)
results = Column(JSONB) # 백테스트 결과 (JSON)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationship
trades = relationship("BacktestTrade", back_populates="backtest_run", cascade="all, delete-orphan")
def __repr__(self):
return f"<BacktestRun(id={self.id}, name={self.name}, strategy={self.strategy_name})>"
class BacktestTrade(Base):
"""Backtest trade model (백테스트 거래 기록)."""
__tablename__ = "backtest_trades"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
backtest_run_id = Column(UUID(as_uuid=True), ForeignKey("backtest_runs.id"), nullable=False)
ticker = Column(String(20), nullable=False)
trade_date = Column(DateTime, nullable=False)
action = Column(String(10), nullable=False) # buy, sell
quantity = Column(Numeric(15, 4), nullable=False)
price = Column(Numeric(15, 2), nullable=False)
commission = Column(Numeric(10, 2), default=0)
pnl = Column(Numeric(15, 2)) # Profit/Loss
# Relationship
backtest_run = relationship("BacktestRun", back_populates="trades")
def __repr__(self):
return f"<BacktestTrade(ticker={self.ticker}, action={self.action}, quantity={self.quantity})>"