Skip to content

Database & migrations

Postgres holds the web-app state — not the trading engine’s internal state, which NautilusTrader manages itself. Schema changes go through Alembic migrations only, never metadata.create_all() (except in unit tests, which build an in-memory SQLite schema).

Table What it holds
users The single account (username + Argon2id hash).
strategy_configs Saved parameterizations of registered strategies.
backtest_runs Run metadata + the summary metrics for every run (all kinds).
generated_strategies Studio-authored strategies (gen:<slug> + source).
studio_conversations The research-copilot chat thread per generated strategy.
saved_charts Charts-tab workspaces (symbol, timeframe, drawings, indicators, optional strategy).
trading_sessions Paper/live session records (strategies, lifecycle, labels).
session fills Per-session fills persisted from the runners.
go-live approvals The audited approve-to-live records.
audit_log Append-only record of every security-relevant action and order intent.

(Artifacts — equity curves, fills JSON, per-kind result JSON — are written to disk under ATS_ARTIFACTS_DIR, not the database.)

Migrations live in backend/ats/db/alembic/versions/. Common commands (from backend/):

Terminal window
uv run alembic upgrade head # apply all migrations (start.sh does this for you)
uv run alembic history # the migration graph
uv run alembic revision -m "..." # author a new migration

scripts/start.sh runs upgrade head automatically. A coverage test plus the linear revision chain keep the graph honest.

ATS_DATABASE_URL (default postgresql+asyncpg://ats:ats@localhost:5432/ats) — async SQLAlchemy 2.0. The models are defined in ats/db/models.py.