OptionsLabOptionsLab

Data Model

Database schema

OptionsLab uses TimescaleDB (PostgreSQL-compatible) as its primary database. The schema is managed with Alembic migrations. Core trading data lives in the public schema; backtesting and agent memory use isolated schemas for multi-tenancy and permission clarity.

Schema namespaces

public

Core trading entities: users, accounts, symbols, orders, positions, webhooks.

backtesting

Backtest run metadata, equity curves, and trade-level simulation results.

agentic

LLM agent memory, tool call logs, and agent execution history.

public

users

System users (traders, admins). Passwords are bcrypt-hashed; role controls dashboard access level.

ColumnTypeNotes
idserialPrimary key.
emailtextUnique login identity.
password_hashtextbcrypt hash — never stored in plaintext.
roletext'admin' or 'trader'.
created_attimestamptzAccount creation timestamp.
public

accounts

Broker accounts. Each account maps to one IB account number and holds its own watchlist, settings, and order history.

ColumnTypeNotes
idserialPrimary key.
user_idint → usersOwning user.
nametextHuman-readable label.
ib_accounttextIB account number (e.g. DU1234567).
ib_client_idintIB API client ID — must be unique per connected client.
settingsjsonbPer-account configuration: default lot size, bracket params.
public

account_symbols

Watchlist entries — symbols an account is tracking. Stores mode (auto/manual) and optional pinned contract for options.

ColumnTypeNotes
idserialPrimary key (used as entryId in URLs).
account_idint → accountsParent account.
symboltextTicker symbol (e.g. SPX, AAPL).
modetext'auto' or 'manual'.
settingsjsonbSymbol-level overrides for position sizing, brackets.
pinned_contractjsonbPinned options contract details (expiry, strike, right).
added_attimestamptzWhen the symbol was added to the watchlist.
public

orders

Order log. Every order submitted through OptionsLab (via webhook or direct API) is recorded here regardless of IB status.

ColumnTypeNotes
idserialPrimary key.
account_idint → accountsAccount that placed the order.
ib_order_idintIB-assigned order ID. Null until IB confirms placement.
symboltextUnderlying ticker.
actiontext'BUY' or 'SELL'.
quantitynumericNumber of contracts or shares.
order_typetext'MKT', 'LMT', etc.
statustextLast known IB status (Submitted, Filled, Cancelled…).
filled_attimestamptzExecution timestamp (null if not filled).
avg_fill_pricenumericVolume-weighted average fill price.
created_attimestamptzOrder creation time.
backtesting

runs

Backtest run metadata. Lives in the 'backtesting' schema, which maps to a separate TimescaleDB schema for isolation.

ColumnTypeNotes
iduuidRun ID — used in URLs and API responses.
account_idint → accountsAccount the strategy config was pulled from.
statustext'pending', 'running', 'completed', 'failed'.
strategy_configjsonbFull strategy parameters snapshot at run time.
result_summaryjsonbCAGR, max drawdown, Sharpe, trade count.
created_attimestamptzRun submission time.
completed_attimestamptzRun finish time.
agentic

agent_memory

LLM agent long-term memory store. Each entry is a scoped fact or observation the agent persisted for future reasoning.

ColumnTypeNotes
iduuidPrimary key.
agent_idtextAgent identifier (e.g. 'market-scanner-v1').
account_idint → accountsTenant scope — memories are isolated per account.
keytextSemantic key for retrieval (e.g. 'spx_regime_2026-05').
valuejsonbStored fact, observation, or structured data.
created_attimestamptzWhen the memory was written.
expires_attimestamptzOptional TTL — null means permanent.

Migrations

Schema changes are managed with Alembic. All migration files live in alembic/versions/. Run pending migrations after deploying a new version:

docker compose exec bot alembic upgrade head

See the Deployment guide for full upgrade procedures including zero-downtime strategies.