DB - strategies

abstract

Defines trading strategy configurations — symbols, timeframes, LLM provider overrides, execution mode, and time-based filters — used by the scheduler to drive automated analysis.

Table Info

PropertyValue
Table Namestrategies
SQLAlchemy Modelbackend/db/models.py :: Strategy
Pydantic Schemabackend/api/routes/strategies.py :: StrategyCreate / StrategyResponse
Migration Filealembic/versions/
TimescaleDB HypertableNo
Partition Column

Columns

ColumnSQLAlchemy TypeNullableDefaultDescription
idIntegerNoautoPrimary key
nameString(255)NoUnique strategy name
descriptionTextYesnullOptional human-readable description
strategy_typeString(20)No"config"config | prompt | code
execution_modeString(30)No"llm_only"llm_only | rule_then_llm | rule_only | hybrid_validator | multi_agent
primary_tfString(10)No"M15"Primary analysis timeframe
context_tfsTextNo"[]"JSON list of context timeframes
trigger_typeString(20)No"candle_close"candle_close | interval
interval_minutesIntegerYesnullUsed when trigger_type=interval
symbolsTextNo"[]"JSON list of symbols to trade
timeframeString(10)No"M15"Legacy/display timeframe field
lot_sizeFloatYesnullFixed lot size; null = use account risk_pct
sl_pipsFloatYesnullStop-loss in pips; null = LLM decides
tp_pipsFloatYesnullTake-profit in pips; null = LLM decides
news_filterBooleanNoTrueSkip analysis during high-impact news events
custom_promptTextYesnullCustom system prompt injected into LLM calls
module_pathString(255)YesnullPython module path for code type strategies
class_nameString(255)YesnullClass name within module_path
strategy_keyString(100)YesnullRegistry key (e.g., "harmonic")
strategy_paramsTextYesnullJSON dict of parameter overrides
is_activeBooleanNoTrueScheduler runs this strategy when True
maintenance_enabledBooleanNoTrueMaintenance agent monitors open trades
skip_hoursTextYesnullJSON int list of hours to skip (e.g., [4,6,7])
skip_hours_timezoneString(60)YesnullIANA timezone for skip_hours (e.g., "Asia/Bangkok")
skip_weekdaysTextYesnullJSON int list of weekdays to skip (0=Mon, 6=Sun)
llm_providerString(50)YesnullOverride global provider: openai | gemini | anthropic | openrouter
llm_modelString(100)YesnullOverride model name (e.g., "gpt-4o")
created_atDateTime(timezone=True)Nodatetime.now(UTC)Creation timestamp

Constraints & Indexes

NameTypeColumnsPurpose
pk_strategiesPRIMARY KEYidRow uniqueness
uq_strategies_nameUNIQUEnameNo duplicate strategy names

Entity Relationships

SQLAlchemy Model (reference snapshot)

class Strategy(Base):
    __tablename__ = "strategies"
 
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    name: Mapped[str] = mapped_column(String(255), unique=True)
    description: Mapped[str | None] = mapped_column(Text, nullable=True)
    strategy_type: Mapped[str] = mapped_column(String(20), default="config")
    execution_mode: Mapped[str] = mapped_column(String(30), default="llm_only")
    primary_tf: Mapped[str] = mapped_column(String(10), default="M15")
    context_tfs: Mapped[str] = mapped_column(Text, default="[]")      # JSON list
    trigger_type: Mapped[str] = mapped_column(String(20), default="candle_close")
    interval_minutes: Mapped[int | None] = mapped_column(Integer, nullable=True)
    symbols: Mapped[str] = mapped_column(Text, default="[]")           # JSON list
    timeframe: Mapped[str] = mapped_column(String(10), default="M15")
    lot_size: Mapped[float | None] = mapped_column(Float, nullable=True)
    sl_pips: Mapped[float | None] = mapped_column(Float, nullable=True)
    tp_pips: Mapped[float | None] = mapped_column(Float, nullable=True)
    news_filter: Mapped[bool] = mapped_column(Boolean, default=True)
    custom_prompt: Mapped[str | None] = mapped_column(Text, nullable=True)
    module_path: Mapped[str | None] = mapped_column(String(255), nullable=True)
    class_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
    strategy_key: Mapped[str | None] = mapped_column(String(100), nullable=True)
    strategy_params: Mapped[str | None] = mapped_column(Text, nullable=True)  # JSON dict
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)
    maintenance_enabled: Mapped[bool] = mapped_column(Boolean, default=True)
    skip_hours: Mapped[str | None] = mapped_column(Text, nullable=True)
    skip_hours_timezone: Mapped[str | None] = mapped_column(String(60), nullable=True)
    skip_weekdays: Mapped[str | None] = mapped_column(Text, nullable=True)
    llm_provider: Mapped[str | None] = mapped_column(String(50), nullable=True)
    llm_model: Mapped[str | None] = mapped_column(String(100), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(UTC))
 
    account_bindings: Mapped[list["AccountStrategy"]] = relationship(
        "AccountStrategy", back_populates="strategy", cascade="all, delete-orphan"
    )
    trades: Mapped[list["Trade"]] = relationship("Trade", back_populates="strategy")

Service Layer

LayerFilePurpose
Routerbackend/api/routes/strategies.pyCRUD + binding management
Schedulerbackend/services/scheduler.pyadd_binding_jobs(), remove_binding_jobs()
AI Pipelinebackend/ai/Reads strategy config to run LLM analysis
RoleLink
API EndpointAPI-POST-v1-Strategies
Frontend PagePage - Settings
Related TableDB - account_strategy
Related TableDB - trades
Related TableDB - backtest_runs