Skip to content

[engine] equity_points: a mode-partitioned mark-to-market equity time series (schema v16) #698

Description

@eaitbrahim

Context (verified)

Keel has no long-term equity series. What exists today:

  • agent_state["equity_history"] is a 7-day rolling window maintained only for the weekly drawdown rail (keel/execution/equity.py:157-163, rebased by keel record-flow).
  • The Insights "equity curve" is cumulative net P&L over closed trades, computed on demand with x-axis = trade order, not time (keel/commands/insights.py build_equity_curve, coordinates quantised server-side into a 1000x300 viewBox).
  • The agent already computes mark-to-market equity every cycle (agent._mark_to_market_equity, keel/agent/agent.py:404) — it is simply not persisted.

Every trading dashboard's core chart is account equity over time. Keel's honest version is agent-computed MTM equity — and it currently evaporates after 7 days.

Scope

  1. New table equity_points:
    • Columns: id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT NOT NULL, mode TEXT NOT NULL ('paper' | 'live'), and equity, cash, unrealized, hwm as TEXT exact-Decimal strings — money stays TEXT per the standing convention (keel/data/db.py:10-11). No integer-cents columns; wire conversion happens at payload time.
    • No profile column: the DB is already one-per-profile (ADR 0002); mode is the load-bearing partition (paper/live flips within one DB).
    • Written in the update_drawdown call path, once per cycle, alongside the existing 7-day window (which stays — the rail keeps its own semantics).
  2. Migration per the standing pattern (see v3 trade_outcomes, v5, v6): DDL added to _SCHEMA_STATEMENTS + a numbered, documented no-op step (_migrate_v16_equity_points — "table creation is handled by _SCHEMA_STATEMENTS; there is deliberately NO backfill"). SCHEMA_VERSION 15 → 16.
  3. Insights chart upgrade: the curve becomes time-axised, segmented by mode (paper vs live visually distinct), with the rail-11 high-water mark and weekly-drawdown ceiling rendered as threshold overlays on the same chart.

Refusals (constitutional / standing invariants)

  • No floats anywhere in storage or wire — payload Field contract only (keel/web/payload.py Rule 1; the guard test fails on any JSON number).
  • Zero client-side math: coordinates and polylines quantised server-side, exactly as the existing curve does.

Acceptance

  • Fresh DB stamps v16; a v15 DB migrates cleanly; re-running the migration is idempotent.
  • The Insights chart has a time axis, mode-partitioned segments, and rail overlays.
  • Tests: money-as-strings, migration idempotence, one row per cycle, mode flips produce two segments not one blended curve.

Sprint 1 (cockpit backbone), first — issues for Orders/Positions/Balances views build on the payload/nav patterns this establishes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

featureNew capability (groups under Features)pythonPull requests that update python code

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions