Show proven trade gross edge total
All checks were successful
deploy / deploy (push) Successful in 35s
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:
parent
558a162cd2
commit
51461a25bc
4 changed files with 37 additions and 0 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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/);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue