GitHubBlog

Search Documentation

Search for a page in the docs

Snapshots & Equity

Status: active development. The UTA stack and trading workflow are evolving fast and known to be unstable across releases. Treat live trading as opt-in only after validating with paper / demo accounts. If you hit a bug or unexpected behaviour, please open an issue at github.com/TraderAlice/OpenAlice/issues so it can be reproduced and fixed.

Snapshots capture your account state at regular intervals and after key events, building a time-series of your portfolio's performance.

What's Captured

Each snapshot records:

FieldDescription
timestampWhen the snapshot was taken
triggerWhat triggered it: scheduled, post-push, post-reject, or manual
account.baseCurrencyDenomination of all monetary fields
account.netLiquidationTotal account value (cash + positions)
account.totalCashValueCash balance
account.unrealizedPnL / realizedPnLP&L across all positions
account.buyingPower / initMarginReq / maintMarginReqMargin info (where supported)
positionsArray of current positions (aliceId, side, quantity, avgCost, marketPrice, marketValue, PnL)
openOrdersPending orders at the time of capture
healthBroker health at snapshot time: healthy / degraded / offline / disabled
headCommit / pendingCommitsTrading-git head hash and any commits awaiting push

All financial values are stored as strings to avoid floating-point precision loss.

Triggers

Snapshots are taken automatically in four cases:

  • Scheduled — Periodic snapshots at a configurable interval (default: every 15 minutes). Managed by the snapshot scheduler via the cron engine.
  • Post-push — Immediately after a trading commit is pushed (order executed). Captures the account state right after a trade.
  • Post-reject — After a commit is rejected by the user. Records the state at the time of rejection.
  • Manual — Taken on demand from the Dev page in the Web UI. Useful for marking a specific moment or debugging.

Configuration

Configure in data/config/snapshot.json:

{
  "enabled": true,
  "every": "15m"
}
FieldDescription
enabledEnable/disable scheduled snapshots
everyInterval for scheduled snapshots (e.g. "15m", "1h", "30m")

Post-push and post-reject snapshots are always taken regardless of this setting.

Storage

Snapshots are stored as chunked JSONL files per account:

data/trading/{accountId}/snapshots/
├── index.json           # Chunk manifest (file names, counts, time ranges)
└── chunk-NNNN.jsonl     # ~50 snapshots per chunk, one JSON object per line

Chunking keeps individual files small and makes range queries (e.g. "last 7 days") cheap — the index tells you which chunks to open. Standard tools (jq, grep, awk) work on each chunk directly.

The Dev page in the Web UI provides a snapshot management view where you can browse, export, or take manual snapshots without leaving the app.

Equity Curve

The Web UI builds an equity curve from snapshot history, showing your portfolio value over time. This visualization helps you:

  • Track overall performance trends
  • Spot drawdowns and recovery periods
  • Compare performance across accounts
  • See the impact of specific trades

Resilience

Skipped snapshots — If the broker is unreachable when a scheduled snapshot fires, it's skipped rather than storing stale data. A snapshot.skipped event is logged.

Retry — When taking snapshots across all accounts, failed accounts get one automatic retry after a 3-second delay.

Carry-forward — The equity curve visualization handles gaps gracefully, carrying forward the last known value when snapshots are missing.

Aggregated Equity

The AccountManager can aggregate equity across all enabled accounts, giving you a unified view of your total portfolio value even when running multiple broker accounts.