Trade Performance Analytics Metric Contract
Purpose
This contract defines what the Vol Dashboard means by trade performance. It also documents the current production boundary so users can distinguish sourced analytics from intentionally unavailable metrics.
The central decision question is:
Did we trade when the dashboard showed an opportunity, did we execute well, and did the trade get the expected outcome?
The answer must be separated into three families:
| Family | Question | Primary source |
|---|---|---|
| Opportunity alignment | Did the trade agree with the dashboard signal at entry? | Dashboard market/regime context at trade time |
| Execution quality | Was the fill good versus the instrument market at execution time? | TradFi option quote/mark/surface source for the traded instrument |
| Outcome quality | What happened after the trade, and under which regime/signal did it happen? | Sourced forward marks, realized outcomes, market context, and lifecycle grouping |
Do not collapse these into one score until each component has its own source, unit, and data-quality state. A trade can align with a signal and still execute poorly. A trade can execute well and still lose money. A trade can have no defensible outcome yet even if its entry context is complete.
Current Production Status
The current /performance screen is live and should be read as a source-quality-aware analytics view, not a complete P&L report.
| Performance family | Current status | What users can safely conclude |
|---|---|---|
| Opportunity alignment | Scored for the loaded Alpha trade sample. | Users can see whether synced Alpha trades were directionally consistent with available BTC-linked dashboard opportunity context at execution time. |
| Source-group quality | Displayed by context group. | Users can see which context groups are available, partial, unavailable, or deliberately not sourced before trusting the alignment read. BTC proxy liquidity is market backdrop only, not execution-quality liquidity. |
| Execution quality | Partially benchmarked for the loaded Alpha sample where backfills sourced fresh MSTR/COIN option bid/ask quotes. | Read fill-vs-mid only for quoted rows. stale and unavailable rows are excluded from execution aggregates and are not zero slippage. |
| Forward outcome P&L | Partially available where forward outcome mark backfill sourced fresh MSTR/COIN option marks. | pending means the horizon has not matured; unavailable means the horizon matured but no sourced post-trade mark exists. Neither is zero P&L. |
| Realized P&L | Not sourced yet. | Derived same-contract FIFO cashflow is not displayed as realized P&L until validated against authoritative accounting or explicit lifecycle intent. |
| Position coverage | Derived lifecycle state is available. | Users can inspect open/closed coverage, but this is not the same as authoritative realized P&L. |
Current known gaps for the next phase are remaining source coverage for execution-time MSTR/COIN option quotes, authoritative adjusted 2MSTR/2COIN contract mapping, trade-level MSTR/COIN option liquidity fields, source coverage for 1d/7d/30d post-trade marks, intentionally unsourced Alpha trade-level smile richness, and authoritative realized-P&L/lifecycle accounting.
As of the 2026-05-10 production API check for source=alpha_sync, lookback_days=365, and limit=1000, the default Performance population is:
| Metric | Current count | Contract interpretation |
|---|---|---|
| Alpha execution rows | 751 | Current default Performance population. |
| Opportunity context | 749/751 scored | 2 rows remain insufficient; missing context is no longer the main blocker. |
| Execution benchmarks | 331/751 quoted | Fill-vs-mid and spread reads are valid only for quoted rows. |
| Execution liquidity | 331 partial, 250 unavailable, 170 not sourced | Full liquidity is blocked by missing contract volume/OI and unresolved adjusted-contract mapping. |
| 7d forward outcomes | 177/751 available, 1 pending, 573 unavailable | P&L/hit-rate reads must quote available sample size and exclude unavailable rows. |
| Realized P&L | Not sourced | Must remain unavailable until authoritative accounting/lifecycle data exists. |
Current Alpha Inputs
Production Alpha sync writes source rows into internal_trades with source='alpha_sync'.
Current production scope:
| Portfolio | Current traded underlying | Dashboard opportunity/regime proxy | Execution/outcome quote source |
|---|---|---|---|
IMST | MSTR | BTC-linked dashboard context | MSTR option market data |
ICOI | COIN | BTC-linked dashboard context | COIN option market data |
The proxy split is intentional. BTC-linked volatility, gamma, VRP, term-structure, and stationarity context define the opportunity backdrop for current proxy trades. BTC proxy liquidity is context/backdrop only and should not be used to judge whether a MSTR/COIN option trade was executable. BTC smile remains a market-surface read, not an Alpha trade-level proxy. Execution and outcome marks must use the actual traded option market, not BTC option quotes.
The preparatory contract for exact, adjusted, standard-root fallback, SMA/OTC derivative-equivalent, unsupported, and unmapped identity states is maintained in Derivative Identity And Proxy Mapping.
The next preparatory work is split across Data Ingestion Readiness Plan, Trade Copilot Evaluation Specification, and SMA Ingestion Requirements. These documents define the durable sourcing plan, accident-avoidance and restructuring evaluation contract, and future SMA field requirements without changing the current Performance production boundary.
Available Fields
| Field | Unit / meaning | Current reliability |
|---|---|---|
source_trade_id | Alpha source trade ID | Required for idempotent upsert |
source_portfolio | Alpha portfolio | Required for scope and sync diagnostics |
trade_date | Execution timestamp | Required for filled rows |
underlying_symbol / currency | Traded underlying, e.g. MSTR, COIN | Required |
instrument | Source instrument label | Required |
direction | buy or sell | Required |
option_type | call or put | Required |
strike | Strike price | Required |
expiry | Expiry date | Required |
quantity | Filled quantity in quantity_unit | Required and positive |
quantity_unit | CONTRACTS or SHARES | Required |
price | Per-contract/source unit price in price_currency | Required and non-negative |
price_currency | Price currency | Required |
contract_multiplier | Source multiplier | Required and positive |
premium_usd | Total trade premium in USD | Source-provided or calculated only when price_currency=USD |
fees_usd | Total trade fees in USD | Optional |
trade_status | Source status, currently only filled rows are ingested | Required |
recon_status | Source reconciliation status | Required |
source_updated_at | Source update timestamp | Required for cursor/watermark sync |
Current Field Gaps
The current Alpha feed does not provide enough data for all performance analytics.
| Missing or not guaranteed | Consequence |
|---|---|
| Actual traded-underlying spot at trade | Alpha does not provide authoritative MSTR/COIN spot in the trade row. BTC proxy spot may be enriched for opportunity context, but it is not a traded-instrument quote source. |
| Traded IV | Cannot directly compare fill IV to realized vol or surface IV without enrichment. |
| Bid / ask / mid at execution | Cannot compute true slippage, spread capture, or fill-vs-mid without quote enrichment. |
| Strategy or intent tag | Cannot know whether a buy was intended as long-vol, directional upside, hedge, roll, or closing trade. |
| Lifecycle link / parent order | Cannot determine open/close pairs or position lifecycle from source row alone. |
| Subsequent marks | Cannot compute forward P&L or hit rate without sourced marks or settlement data. |
| Authoritative expiry settlement | Expiry outcome remains unavailable unless sourced separately. |
Blank or unavailable is the correct output when a required input is missing. Do not display zero for unavailable economics.
Data-Quality States
Every computed trade-performance metric must carry a quality state.
For the cross-document policy that defines which source and quality states may feed decision-grade marks, P&L, estimates, proxy outputs, and future copilot warnings, see the Source Authority Register.
| State | Meaning | UI/API behavior |
|---|---|---|
available | Computed from direct source inputs within tolerance. | Display normally with source label. |
proxy_mapped | Computed using an explicit market proxy such as BTC context for MSTR/COIN opportunity attribution. | Display with proxy label and confidence. |
estimated | Computed from a model or fallback, not a direct market/source observation. | Display only if visibly labelled as estimated. |
stale | Source observation exists but is outside the allowed time tolerance. | Display with stale warning or suppress from aggregates that require fresh data. |
unavailable | Required input is absent. | Display blank / no-data; do not coerce to zero. |
unsupported | Metric does not apply to the instrument, state, or current implementation. | Display unsupported/no-data with reason. |
Recommended common metadata fields:
| Field | Meaning |
|---|---|
metric_quality | One of the quality states above. |
source_name | Direct source used, e.g. alpha, amberdata, tradfi_quote, surface_model. |
source_timestamp | Timestamp of the source observation. |
time_delta_minutes | Absolute time difference from trade execution. |
missing_fields | Required fields that prevented a higher-quality result. |
calculation_version | Deterministic version label for metric logic. |
Required Direction And Sign Conventions
Direction must be explicit because buy and sell fills have opposite economics.
| Concept | Buy option | Sell option |
|---|---|---|
| Premium cash flow | Cash outflow | Cash inflow |
| Fill-vs-mid slippage | fill_price - mid_price; positive is worse | mid_price - fill_price; positive is worse |
| Spread capture | (ask_price - fill_price) / spread where spread = ask - bid | (fill_price - bid_price) / spread |
| Forward P&L | mark_value - entry_value - fees | entry_value - mark_value - fees |
| IV edge, long-vol assumption | Positive if entry IV is cheap versus benchmark/realized | Negative if entry IV is rich versus benchmark/realized |
| IV edge, short-vol assumption | Negative if entry IV is cheap versus benchmark/realized | Positive if entry IV is rich versus benchmark/realized |
If strategy intent is unknown, report both the raw component and the assumed interpretation. Do not infer that every option buy is a pure long-vol trade or that every option sell is a pure short-vol trade.
Metric Families
1. Execution Quality
Execution quality asks whether the fill was attractive relative to the actual traded instrument market at the time.
Execution benchmarks must use the traded instrument quote source. For current scope that means MSTR/COIN option data for execution marks, not BTC option data.
| Metric | Formula / definition | Unit | Required inputs | No-data behavior |
|---|---|---|---|---|
| Entry premium USD | Source premium_usd; if missing and price_currency=USD, price * quantity * contract_multiplier | USD | premium_usd or (price, quantity, contract_multiplier, price_currency=USD) | unavailable if non-USD price lacks source premium_usd |
| Fees as percent of premium | fees_usd / abs(entry_premium_usd) | Percent | fees_usd, entry premium | unavailable if fees or premium missing; do not assume zero fees unless source says zero |
| Benchmark mid price | (bid + ask) / 2 | Price per contract | Bid/ask for same contract near execution time | unavailable if no sourced quote |
| Fill vs mid | Buy: fill_price - mid_price; sell: mid_price - fill_price | Price points per contract and USD total | Fill price, benchmark mid, quantity, multiplier | unavailable if mid missing |
| Fill vs mid bps | fill_vs_mid / mid_price * 10000 | Basis points | Fill vs mid, positive mid | unavailable if mid <= 0 or missing |
| Spread capture | Buy: (ask - fill_price) / (ask - bid); sell: (fill_price - bid) / (ask - bid) | Ratio / percent | Bid, ask, fill price | unavailable if bid/ask missing or spread <= 0 |
| Execution-liquidity state | available, partial, stale, unavailable, not_entitled, or not_sourced | Quality state | Same-contract bid/ask, quote age, optional 24h volume, optional open interest | partial when bid/ask is sourced but volume/OI are not returned; missing volume/OI stay null |
| Contract 24h volume | Provider-sourced field only | Contracts | Explicit provider volume field for the traded MSTR/COIN option | unavailable if not returned; never substitute BTC volume |
| Contract open interest | Provider-sourced field only | Contracts | Explicit provider open-interest field for the traded MSTR/COIN option | unavailable if not returned; never substitute BTC OI |
| Fill vs surface mark | Buy: fill_price - surface_mark; sell: surface_mark - fill_price | Price points per contract and USD total | Surface/theoretical mark for traded instrument | estimated if surface-derived; unavailable if no mark |
| Entry IV edge | Direction/intent-aware comparison between trade_iv_estimate and benchmark/surface IV | Vol points | Traded or estimated IV, benchmark IV, strategy assumption | estimated if IV inverted/modelled; unavailable if no IV source |
Minimum execution-quality API shape:
execution_quality = {
trade_id,
source_trade_id,
fill_price,
benchmark_bid,
benchmark_ask,
benchmark_mid,
fill_vs_mid,
fill_vs_mid_bps,
spread_capture,
fill_vs_surface_mark,
entry_iv_edge,
source_name,
source_timestamp,
time_delta_minutes,
metric_quality,
missing_fields
}
2. Opportunity Alignment
Opportunity alignment asks whether the trade was entered when dashboard signals indicated a coherent opportunity. It is a signal-consistency measure, not a P&L measure.
The current MSTR/COIN scope should use BTC-linked dashboard context for these metrics unless a later decision changes the proxy mapping.
| Metric | Formula / definition | Unit | Required inputs | No-data behavior |
|---|---|---|---|---|
| Market proxy | Explicit mapping from trade underlying/portfolio to dashboard market context, e.g. MSTR -> BTC | Label | Trade underlying or portfolio, mapping config | unmapped / unsupported; never silently default to BTC |
| DVol percentile at entry | Percentile rank of DVol at trade time over configured lookback | Percentile 0-100 | Trade-time DVol, lookback distribution | unavailable if no timestamp-matched DVol |
| VRP at entry | implied_volatility - realized_volatility | Vol points | IV/DVol/ATM IV and RV context | unavailable if either side missing |
| VRP bucket | Bucketed VRP state, e.g. cheap_vol, neutral, rich_vol | Label | VRP and thresholds | unavailable if VRP missing |
| Smile rich/cheap bucket | Trailing z-score or equivalent surface-deviation bucket for relevant tenor/delta | Label plus z-score | Surface point and trailing baseline | not_sourced for current Alpha MSTR/COIN trade rows; otherwise unavailable if no comparable surface history |
| Gamma regime | short_gamma, neutral, or long_gamma from GEX imbalance percentiles | Label | GEX imbalance history near trade time | unavailable if no GEX context |
| Stationarity status | stable, unstable, or insufficient for regime-forward-return relationship | Label | Stationarity calculation near trade time | insufficient or unavailable as appropriate |
| Term structure state | Front/back IV relationship such as inverted, flat, or contango | Label | IV by tenor near trade time | unavailable if tenors missing |
| Flow confirmation | Whether contemporaneous block/flow/put-call signals agree with trade direction/vol stance | Score or label | Flow data, rule contract | unavailable if no flow data |
| Alignment score | Deterministic weighted score from available drivers and detractors | 0-100 | At least one signal and stated assumption | unavailable if no reliable signal context |
| Alignment confidence | Confidence reduction from stale data, proxy mapping, stationarity, missing fields | 0-1 or label | Quality states for drivers | Must reduce confidence when inputs are stale/proxy/estimated |
Candidate alignment interpretation:
| Trade assumption | Supportive signals | Detracting signals |
|---|---|---|
| Long volatility / option buy | Low DVol percentile, low/negative VRP, unstable/short-gamma regime, favorable convexity | High VRP, stable long-gamma regime without catalyst |
| Short volatility / option sell | High DVol percentile, positive/rich VRP, stable/long-gamma regime | Low VRP, unstable short-gamma regime |
| Directional call buy | Upside flow, call demand, favorable conditional upside density, stable enough regime | Put-heavy protection flow, downside conditional skew |
| Directional put buy | Downside flow, protection demand, negative/unstable spot-vol/gamma context | Upside flow, stable long-gamma pinning context |
Because Alpha currently lacks strategy intent, the first implementation should store the assumption used to calculate alignment.
Minimum opportunity-alignment API shape:
opportunity_alignment = {
trade_id,
source_trade_id,
market_proxy,
mapping_method,
mapping_confidence,
assumed_trade_intent,
alignment_score,
alignment_label,
drivers,
detractors,
confidence,
context_timestamp,
context_time_delta_minutes,
metric_quality,
missing_fields
}
3. Outcome Quality
Outcome quality asks what happened after the trade and whether outcomes cluster by regime or signal.
Outcome metrics should operate on both execution rows and lifecycle/position groups once lifecycle grouping exists. Per-trade outcome is useful, but position-level outcome is often the more defensible trading answer.
The backend persists sourced 1d/7d/30d marks in trade_forward_outcome_marks through /api/internal/trades/outcomes/backfill. Performance APIs read those persisted rows by default so user-facing P&L is repeatable and carries source quality.
| Metric | Formula / definition | Unit | Required inputs | No-data behavior |
|---|---|---|---|---|
| Forward mark at horizon | Sourced option mark at trade_date + horizon for the traded contract. If the requested horizon is after option expiry, use a sourced terminal option quote near expiry when available. | Price per contract | Same-contract mark/quote near horizon or terminal option quote near expiry | unavailable if no sourced mark |
| Forward mark quality | Current implementation: quoted, stale, pending, unavailable; terminal expiry marks use quoted quality plus explicit terminal_mark state/source labels. Future settlement/model states must remain explicit. | Label | Mark source metadata | Required for every displayed mark |
| Forward P&L | Before fees: buy = mark_value - entry_value, sell = entry_value - mark_value; after fees subtract sourced fees when fees are available. | USD | Entry value, mark value, quantity, multiplier, optional fees | unavailable if mark missing; never show zero by default |
| Forward return on premium | forward_pnl / abs(entry_premium_usd) | Percent | Forward P&L, entry premium | unavailable if premium <= 0 or P&L missing |
| Spot move after trade | (future_spot - entry_spot) / entry_spot | Percent | Entry/future spot for relevant market/underlying | unavailable if entry/future spot missing |
| Moneyness change | Entry moneyness versus forward moneyness | Percent or ratio | Strike, entry spot, future spot | unavailable if spot missing |
| Realized vol after trade | std(log_returns) * sqrt(365 * periods_per_day) * 100 over horizon | Annualized percent | Sufficient spot observations | unavailable if too few observations |
| Realized-vol capture | For long vol: realized_vol - entry_iv; for short vol: entry_iv - realized_vol | Vol points | Entry/traded IV or benchmark IV, realized vol | unavailable if either side missing |
| Hit rate | count(successful outcomes) / count(available outcomes) | Percent | Defined success rule and available outcomes | Exclude unavailable outcomes from denominator and report excluded count |
| Average edge by regime/signal | Mean outcome metric grouped by regime/signal bucket | USD, percent, or vol points | Outcome metric and trade-time context | Show sample size and quality mix |
Required horizons for first implementation:
| Horizon | Purpose | Quality requirement |
|---|---|---|
1d | Short-term execution/opportunity feedback | Sourced mark or explicit estimate label |
7d | Near-term signal follow-through | Sourced mark or explicit estimate label |
30d | Medium horizon outcome | Sourced mark or explicit estimate label |
expiry | Final outcome | Authoritative source required for displayed realized P&L; expiry quote marks are terminal marks, not accounting-realized P&L |
Expiry outcomes must remain unavailable unless backed by sourced quote, close, settlement, Alpha realized outcome, or equivalent authoritative mark. A model-estimated intrinsic value can only be shown as model_estimated, not as realized P&L.
Outcome states:
| State | Meaning |
|---|---|
unrealized_mark | P&L is computed from a fresh sourced mark at the requested horizon while the option is still live. |
terminal_mark | P&L is computed from a fresh sourced terminal option quote near expiry because the requested horizon is after expiry. This is not authoritative realized P&L. |
pending | The requested horizon has not matured and no terminal expiry mark can be known yet. |
unavailable | Required mark, entry premium, direction, quantity, or source data is unavailable. |
Minimum outcome API shape:
outcome = {
trade_id_or_position_id,
source_trade_ids,
horizon,
entry_value_usd,
mark_value_usd,
pnl_usd,
return_on_premium,
realized_vol,
realized_vol_capture,
spot_move,
regime_at_entry,
signal_bucket_at_entry,
mark_source,
mark_timestamp,
mark_time_delta_minutes,
metric_quality,
missing_fields
}
Position And Lifecycle Requirements
Raw Alpha rows are executions. Many performance questions need lifecycle grouping before they can be answered defensibly.
Minimum grouping key:
source_portfolio
underlying_symbol
instrument or option_symbol
option_type
strike
expiry
direction/sign
Required position/lifecycle metrics:
| Metric | Formula / definition | Unit | Required inputs | No-data behavior |
|---|---|---|---|---|
| Net quantity | Signed sum of executions | Contracts/shares | Direction, quantity, lifecycle grouping | unavailable if grouping ambiguous |
| Average entry price | Weighted average fill price for opening executions | Price per contract | Fill prices and quantities | unavailable if open/close cannot be separated |
| Total entry premium | Sum of signed or absolute entry premiums depending on view | USD | Premiums, direction, multiplier | unavailable if any required premium missing |
| Total fees | Sum of source fees | USD | Fees | Show unavailable or explicit zero only if source semantics are clear |
| Open/closed state | Whether net quantity is zero after offsets | Label | Full execution set for contract/scope | ambiguous if incomplete lifecycle |
| Realized closed P&L | Authoritative realized P&L from accounting or validated lifecycle cashflow | USD | Source-system P&L or explicitly validated open/close pairing | unavailable until sourced or validated |
If a row cannot be confidently paired, label it ambiguous_lifecycle. Do not force ambiguous rows into realized P&L. Same-contract FIFO cashflow can be retained for research, but it must not be shown as user-facing realized P&L until reconciled to source accounting.
Aggregation Contract
Aggregates are only meaningful when they expose sample size and quality composition.
Required aggregate dimensions:
| Dimension | Examples |
|---|---|
| Portfolio | IMST, ICOI |
| Traded underlying | MSTR, COIN |
| Dashboard market proxy | BTC |
| Date window | 1d, 7d, 30d, custom |
| Gamma regime | short, neutral, long |
| Stationarity status | stable, unstable, insufficient |
| VRP bucket | cheap, neutral, rich |
| DVol percentile bucket | bottom decile, middle, top decile |
| Smile bucket | not_sourced for current Alpha MSTR/COIN trade rows; cheap/fair/rich only when an approved trade-level smile source exists |
| Trade intent assumption | long-vol, short-vol, directional call, directional put, unknown |
| Outcome quality | sourced, estimated, stale, unavailable |
Every aggregate must include:
sample_count
available_count
unavailable_count
estimated_count
stale_count
proxy_mapped_count
Aggregates must not silently exclude bad data. If unavailable rows are excluded from a calculation, show the excluded count.
First-Screen Questions
The Trade Performance screen should answer these questions in order:
- Is the selected Alpha scope loaded cleanly enough to interpret Performance?
- Which trades have enough context to score opportunity alignment?
- When trades were entered, were dashboard signals cheap/rich, stable/unstable, or confirming/conflicting?
- Which context source groups are available, partial, or unavailable?
- Were fills good versus the actual traded instrument market? Current answer: available only for rows with fresh sourced execution-time quotes; otherwise not benchmarked, stale, or unavailable.
- What happened after entry at defensible horizons? Current answer: available only for rows with persisted fresh forward marks; pending for immature horizons and unavailable for matured horizons without sourced marks.
- Is realized P&L sourced? Current answer: unavailable until authoritative accounting or validated lifecycle data exists.
- Which regimes, signals, portfolios, or underlyings are associated with better or worse outcomes? Current answer: bucket counts are available; P&L and hit-rate aggregates are available only for rows with sourced forward marks.
- Which results are unavailable because data is missing rather than because economics were zero?
Implementation Sequence Dependencies
This contract originally preceded implementation. It now remains the governing contract for the live Performance screen and the follow-on data-sourcing work.
| Next ticket | Dependency from this contract |
|---|---|
ENG-4937 market proxy mapping | Requires explicit market_proxy, mapping_method, and no silent BTC fallback. |
ENG-4939 trade-time context | Requires context fields, freshness tolerances, missing-field tracking, and quality states. |
ENG-4940 execution benchmarks | Requires direction-aware fill-vs-mid, spread capture, quote/source metadata, and no fabricated bid/ask/mid. |
ENG-4942 lifecycle grouping | Requires execution-to-position aggregation and ambiguous lifecycle states. |
ENG-4941 opportunity alignment | Requires deterministic drivers, detractors, assumed intent, score, confidence, and data quality. |
ENG-4943 outcome attribution | Requires sourced/estimated/unavailable separation and horizon-specific quality states. |
ENG-4944 API/UI | Requires every displayed metric to include units, source, and quality state. |
ENG-4945 backfill/freshness/tests | Requires idempotent backfills and stale/unavailable quality reporting. |
Non-Goals For This Contract
- It does not treat missing TradFi quote coverage as zero slippage or zero P&L.
- It does not authorize displaying a metric without source and quality state.
- It does not authorize model-estimated expiry P&L as realized P&L.
- It does not infer strategy intent from direction alone.
- It does not change the Alpha sync or sync-completeness diagnostic workflow.
Review Checklist
- Each metric has a formula or deterministic definition.
- Each metric has a unit.
- Each metric names required inputs.
- Each metric defines no-data behavior.
- Proxy underlyings are separated from quote/outcome underlyings.
- Current Alpha field gaps are explicit.
- Aggregates expose sample count and data-quality composition.
- No missing input is represented as zero.