Show proven trade gross edge total
All checks were successful
deploy / deploy (push) Successful in 35s

Proof: successful trade summary now aggregates gross edge estimates only from completed lifecycle rows with linked settlement evidence; tests prove completed-without-delta rows are excluded.

Assumptions: gross edge estimate is useful operator evidence but remains pre-fee and not venue-native realized PnL.

Still fake: fee-complete realized trade PnL and venue-native terminal fill events remain unavailable.
This commit is contained in:
philipp 2026-04-14 10:07:00 +02:00
parent 558a162cd2
commit 51461a25bc
4 changed files with 37 additions and 0 deletions

View file

@ -1341,8 +1341,12 @@ function buildTradeFunnelSummary(lifecycleRows = []) {
} }
} }
const grossEdgeEstimate = summarizeGrossEdgeEstimate(successfulTrades);
return { return {
successful_trade_count: successfulTrades.length, successful_trade_count: successfulTrades.length,
successful_trade_gross_edge_estimate_eure: grossEdgeEstimate.total_eure,
successful_trade_gross_edge_estimate_count: grossEdgeEstimate.count,
unresolved_submission_count: unresolvedSubmissions.length, unresolved_submission_count: unresolvedSubmissions.length,
no_trade_count: noTradeRows.length, no_trade_count: noTradeRows.length,
successful_trades: successfulTrades, successful_trades: successfulTrades,
@ -1356,6 +1360,23 @@ function buildTradeFunnelSummary(lifecycleRows = []) {
}; };
} }
function summarizeGrossEdgeEstimate(rows = []) {
let total = 0n;
let count = 0;
for (const row of rows || []) {
const value = row?.gross_edge_value_eure || estimateGrossEdgeValueEure(row);
if (value == null) continue;
total += parseScaledDecimal(value);
count += 1;
}
return {
count,
total_eure: count > 0 ? formatScaledDecimal(total) : null,
};
}
function buildSystemSummary({ servicesByName, activeAlerts, recentAlerts }) { function buildSystemSummary({ servicesByName, activeAlerts, recentAlerts }) {
const historyWriterState = servicesByName['history-writer']?.state || {}; const historyWriterState = servicesByName['history-writer']?.state || {};
void activeAlerts; void activeAlerts;

View file

@ -293,6 +293,12 @@ export default function StrategyPage({ strategy }) {
</div> </div>
<div className="metric-grid"> <div className="metric-grid">
<MetricCard label="Successful trades" meta="Requires linked terminal outcome and settlement" value={String(funnel.successful_trade_count || 0)} /> <MetricCard label="Successful trades" meta="Requires linked terminal outcome and settlement" value={String(funnel.successful_trade_count || 0)} />
<MetricCard
label="Gross edge est."
meta={`${funnel.successful_trade_gross_edge_estimate_count || 0} proven trades, before fees`}
signedValue={funnel.successful_trade_gross_edge_estimate_eure}
value={formatEur(funnel.successful_trade_gross_edge_estimate_eure)}
/>
<MetricCard label="Not filled" meta="Submitted but no settled inventory delta" value={String(counts.not_filled || 0)} /> <MetricCard label="Not filled" meta="Submitted but no settled inventory delta" value={String(counts.not_filled || 0)} />
<MetricCard label="Awaiting outcome" meta="Submitted, no durable terminal result yet" value={String(funnel.unresolved_submission_count || 0)} /> <MetricCard label="Awaiting outcome" meta="Submitted, no durable terminal result yet" value={String(funnel.unresolved_submission_count || 0)} />
<MetricCard label="Rejected / blocked" meta="Strategy rejection or executor block" value={String((counts.rejected || 0) + (counts.blocked || 0))} /> <MetricCard label="Rejected / blocked" meta="Strategy rejection or executor block" value={String((counts.rejected || 0) + (counts.blocked || 0))} />
@ -312,6 +318,7 @@ export default function StrategyPage({ strategy }) {
</div> </div>
<div className="pills"> <div className="pills">
<Pill label={`${counts.completed || 0} completed`} stateLabel={(counts.completed || 0) > 0 ? 'healthy' : 'unknown'} /> <Pill label={`${counts.completed || 0} completed`} stateLabel={(counts.completed || 0) > 0 ? 'healthy' : 'unknown'} />
<Pill label={`${formatEur(funnel.successful_trade_gross_edge_estimate_eure)} gross edge est.`} stateLabel={funnel.successful_trade_gross_edge_estimate_eure ? 'healthy' : 'unknown'} />
<Pill label={`${counts.not_filled || 0} not filled`} stateLabel={(counts.not_filled || 0) > 0 ? 'warning' : 'unknown'} /> <Pill label={`${counts.not_filled || 0} not filled`} stateLabel={(counts.not_filled || 0) > 0 ? 'warning' : 'unknown'} />
</div> </div>
</div> </div>

View file

@ -11,6 +11,9 @@ test('strategy page owns consolidated quote lifecycle and successful trade table
assert.match(strategySource, /Incoming quotes and what happened next/); assert.match(strategySource, /Incoming quotes and what happened next/);
assert.match(strategySource, /Responded\?/); assert.match(strategySource, /Responded\?/);
assert.match(strategySource, /Successful trades only/); assert.match(strategySource, /Successful trades only/);
assert.match(strategySource, /Gross edge est\./);
assert.match(strategySource, /successful_trade_gross_edge_estimate_eure/);
assert.match(strategySource, /before fees/);
assert.match(strategySource, /Show lifecycle/); assert.match(strategySource, /Show lifecycle/);
assert.match(strategySource, /Submitted means the relay accepted the response; it does not prove a trade\./); assert.match(strategySource, /Submitted means the relay accepted the response; it does not prove a trade\./);
assert.doesNotMatch(strategySource, /Actionable|actionable/); assert.doesNotMatch(strategySource, /Actionable|actionable/);

View file

@ -752,6 +752,8 @@ test('successful trade rows require completed outcome with linked settled invent
command_id: 'cmd-completed', command_id: 'cmd-completed',
quote_id: 'quote-completed', quote_id: 'quote-completed',
pair: config.activePair, pair: config.activePair,
gross_edge_pct: '0.49',
eure_notional: '50',
outcome_status: 'completed', outcome_status: 'completed',
outcome_reason: 'matched_inventory_delta', outcome_reason: 'matched_inventory_delta',
outcome_observed_at: '2026-04-09T09:01:00.000Z', outcome_observed_at: '2026-04-09T09:01:00.000Z',
@ -770,6 +772,8 @@ test('successful trade rows require completed outcome with linked settled invent
command_id: 'cmd-completed-no-delta', command_id: 'cmd-completed-no-delta',
quote_id: 'quote-completed-no-delta', quote_id: 'quote-completed-no-delta',
pair: config.activePair, pair: config.activePair,
gross_edge_pct: '99',
eure_notional: '100',
outcome_status: 'completed', outcome_status: 'completed',
outcome_reason: 'settled', outcome_reason: 'settled',
outcome_observed_at: '2026-04-09T09:02:00.000Z', outcome_observed_at: '2026-04-09T09:02:00.000Z',
@ -786,6 +790,8 @@ test('successful trade rows require completed outcome with linked settled invent
const funnel = bootstrap.strategy.strategy_state.trade_funnel; const funnel = bootstrap.strategy.strategy_state.trade_funnel;
assert.equal(funnel.successful_trade_count, 1); assert.equal(funnel.successful_trade_count, 1);
assert.equal(funnel.successful_trades[0].quote_id, 'quote-completed'); assert.equal(funnel.successful_trades[0].quote_id, 'quote-completed');
assert.equal(funnel.successful_trade_gross_edge_estimate_eure, '0.245');
assert.equal(funnel.successful_trade_gross_edge_estimate_count, 1);
assert.match(funnel.successful_trades[0].settlement_summary.text, /\+0\.00037014 BTC/); assert.match(funnel.successful_trades[0].settlement_summary.text, /\+0\.00037014 BTC/);
assert.equal(funnel.counts.submitted, 1); assert.equal(funnel.counts.submitted, 1);
assert.equal(funnel.counts.completed, 2); assert.equal(funnel.counts.completed, 2);