DB - optimization_runs

abstract

Stores parameter sweep jobs — one row per optimization request — tracking the search space, progress, results ranking, and best parameter combination found.

Table Info

PropertyValue
Table Nameoptimization_runs
SQLAlchemy Modelbackend/db/models.py :: OptimizationRun
Pydantic Schemabackend/api/routes/backtest.py
Migration Filealembic/versions/
TimescaleDB HypertableNo
Partition Column

Columns

ColumnSQLAlchemy TypeNullableDefaultDescription
idIntegerNoautoPrimary key
strategy_idInteger FKNoFK → strategies.id (CASCADE delete, indexed)
symbolString(20)NoSymbol to optimize on (indexed)
timeframeString(10)No"M15"Candle timeframe
start_dateDateTime(timezone=True)NoOptimization date range start
end_dateDateTime(timezone=True)NoOptimization date range end
initial_balanceFloatNo10000.0Starting capital
spread_pipsFloatNo1.5Simulated spread
execution_modeString(20)No"close_price"Execution timing
volumeFloatNo0.1Trade volume in lots
risk_pctFloatYesnullRisk per trade (null = fixed volume)
commission_per_lotFloatNo0.0Commission per lot
tp_partial_close_ratioFloatNo0.5Partial close ratio at TP
max_workersIntegerNo4Concurrent parameter combinations
csv_upload_idTextYesnullPrimary timeframe CSV file path
csv_uploadsTextYesnullJSON dict of {timeframe: csv_path}
param_gridTextNo"{}"JSON dict of {param_name: [v1, v2, ...]}
optimize_metricString(50)No"sharpe_ratio"Metric to rank combinations by
statusString(20)No"pending"pending | running | completed | failed | cancelled
progress_pctIntegerNo0Progress 0–100
total_combinationsIntegerNo0Total parameter combinations in grid
completed_combinationsIntegerNo0Combinations tested so far
started_atDateTime(timezone=True)YesnullExecution start time
completed_atDateTime(timezone=True)YesnullExecution completion time
error_messageTextYesnullError if status=failed
resultsTextYesnullJSON ranked list of {params, metrics}
best_paramsTextYesnullJSON top-ranked parameter combination
created_atDateTime(timezone=True)Nodatetime.now(UTC)Request creation timestamp (indexed)

Constraints & Indexes

NameTypeColumnsPurpose
pk_optimization_runsPRIMARY KEYidRow uniqueness
idx_opt_strategyINDEXstrategy_idFilter by strategy
idx_opt_symbolINDEXsymbolFilter by symbol
idx_opt_createdINDEXcreated_atSort by recency
fk_opt_strategyFOREIGN KEYstrategy_id → strategies.id CASCADEDelete runs with strategy

Entity Relationships

SQLAlchemy Model (reference snapshot)

class OptimizationRun(Base):
    """Stores a parameter sweep job — one row per optimization request.
 
    param_grid  — JSON dict: {param_name: [v1, v2, ...]}  (the search space)
    results     — JSON list: [{params: {...}, metrics: {...}}, ...] ranked by optimize_metric
    best_params — JSON dict: the top-ranked param combination
    """
    __tablename__ = "optimization_runs"
 
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    strategy_id: Mapped[int] = mapped_column(Integer, ForeignKey("strategies.id", ondelete="CASCADE"), index=True)
    param_grid: Mapped[str] = mapped_column(Text, default="{}")
    optimize_metric: Mapped[str] = mapped_column(String(50), default="sharpe_ratio")
    status: Mapped[str] = mapped_column(String(20), default="pending")
    progress_pct: Mapped[int] = mapped_column(Integer, default=0)
    total_combinations: Mapped[int] = mapped_column(Integer, default=0)
    completed_combinations: Mapped[int] = mapped_column(Integer, default=0)
    results: Mapped[str | None] = mapped_column(Text, nullable=True)
    best_params: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(UTC), index=True)
 
    strategy: Mapped["Strategy"] = relationship("Strategy")
RoleLink
API EndpointAPI-POST-v1-Backtest-Optimize
Frontend PagePage - Backtest
Related TableDB - strategies
Related TableDB - backtest_runs