Make sports forward learner quote aware

This commit is contained in:
Theodore Song
2026-08-20 18:27:39 -04:00
parent 39e893a553
commit 9fca4e303d
4 changed files with 64 additions and 32 deletions
+13 -12
View File
@@ -96,18 +96,19 @@ signals in the walk-forward observation ledger until current, independent-event
evidence proves an edge. evidence proves an edge.
Run `npm run evaluate:sports-favorites` for the separate pregame favorite audit. Run `npm run evaluate:sports-favorites` for the separate pregame favorite audit.
It anchors decisions to the published game start, rejects stale prices, charges a It anchors decisions to the published game start, rejects stale prices, takes only
modeled five-cent cost, takes only the highest-priced eligible favorite per event, the highest-priced eligible favorite per event, and uses a chronological 60/20/20
and uses a chronological 60/20/20 split. The refreshed August 20 run loaded all split. The refreshed August 20 run loaded all 3,000 histories with no failures and
3,000 histories with no failures and found zero train-pass rules. The Strategy 57 found zero train-pass rules. The Strategy 57 24-hour, 60%-85% capital rule was
24-hour, 60%-85% capital rule averaged -11.98% across 168 independent training negative even with zero modeled execution cost, so Strategy 58 retired it. The
events and -4.04% across 100 untouched holdout events after the five-cent cost, narrower 12-hour, 60%-75% cohort stayed positive by point estimate in train,
so Strategy 58 retires it at the next fresh executable mark. The narrower 12-hour, validation, and holdout at a one-cent cost, but the train and holdout confidence
60%-75% rule had positive point estimates in train, validation, and holdout but bounds still crossed zero; its holdout point estimate also turned negative near a
did not establish a positive lower confidence bound in train or holdout. Favorite two-cent cost. Build 74 therefore records only zero-capital observations whose
Backer therefore records it with zero capital, one market per event, and persists executable ask plus a 0.25-cent slippage buffer is no more than one cent above the
the pending and completed forward ledger offline. Only 30 new independent closed midpoint. It persists the pending and completed forward ledger offline, grades
events with a positive 90% lower confidence bound can promote 1.25% positions. only closed markets, and requires 30 new independent closed events with a positive
90% lower confidence bound before 1.25% positions can begin.
Run `npm run evaluate:settlement-calibration` for the stricter settlement-bias Run `npm run evaluate:settlement-calibration` for the stricter settlement-bias
search across up to 5,000 resolved markets. It uses a 60/20/20 chronological search across up to 5,000 resolved markets. It uses a 60/20/20 chronological
+37 -17
View File
@@ -341,7 +341,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
<nav class="topnav"> <nav class="topnav">
<div class="brand"> <div class="brand">
<div class="logo">🏆</div> <div class="logo">🏆</div>
<div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 58 · maker research 2 · build 73</div></div> <div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · 5 core + 5 aggressive</div><div class="build-badge">Adaptive strategy 58 · maker research 2 · build 74</div></div>
</div> </div>
<div class="tabs" id="tabs"> <div class="tabs" id="tabs">
<button class="tab" data-tab="overview">Overview</button> <button class="tab" data-tab="overview">Overview</button>
@@ -363,7 +363,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
<div class="personal-banner" id="personalBanner"> <div class="personal-banner" id="personalBanner">
<b>Personal research mode.</b> This copy is for your own analysis, paper tracking, and manual trade research only. It does not pool money, onboard investors, custody funds, bypass eligibility rules, or place orders without your manual approval. <b>Personal research mode.</b> This copy is for your own analysis, paper tracking, and manual trade research only. It does not pool money, onboard investors, custody funds, bypass eligibility rules, or place orders without your manual approval.
</div> </div>
<div class="live-build-banner"><b>Build 73 active:</b> a fresh 3,000-market replay rejected the Strategy 57 sports-capital rule, so that exposure is retired at the next fresh mark. Favorite Backer now records zero-capital 12-hour, 6075% sports observations and grades only closed markets. Capital stays at zero until 30 new independent forward events produce a positive lower confidence bound; only then can 1.25% positions begin. Temporary trading pauses cannot create exits or learner outcomes. Fresh cached snapshots remain usable for 90 minutes with timing rechecked locally. This remains paper trading; profits are not guaranteed.</div> <div class="live-build-banner"><b>Build 74 active:</b> Favorite Backer's zero-capital sports learner is now quote-aware. It observes one 6075% favorite per independent event near the 12-hour checkpoint only when the executable ask plus a 0.25-cent slippage buffer is no more than one cent above the market midpoint. The cost audit stayed positive by point estimate near one cent but turned negative around two cents, so expensive entries are rejected. Capital remains zero until 30 new independent closed events produce a positive lower confidence bound. Temporary trading pauses and offline snapshots cannot create outcomes. This remains paper trading; profits are not guaranteed.</div>
<!-- ============ OVERVIEW ============ --> <!-- ============ OVERVIEW ============ -->
<section class="tabpanel" data-tab="overview"> <section class="tabpanel" data-tab="overview">
@@ -745,7 +745,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
</section> </section>
<footer> <footer>
Build 73 · Adaptive strategy 58 · Maker research 2 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice · Build 74 · Adaptive strategy 58 · Maker research 2 · Paper trading only · Live prices from Polymarket's public Gamma and CLOB APIs · Not financial advice ·
<a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a> <a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a>
</footer> </footer>
</div> </div>
@@ -774,7 +774,7 @@ const POLITICS_TREND_MIN_HOLD_HOURS = 72;
const EXIT_CONFIRM_HOURS = 6; const EXIT_CONFIRM_HOURS = 6;
const AGENTS_KEY = "pma_agents_v2"; const AGENTS_KEY = "pma_agents_v2";
const SUG_KEY = "pma_suggestions_v5"; const SUG_KEY = "pma_suggestions_v5";
const BUILD_VERSION = 73; const BUILD_VERSION = 74;
const SUGGESTION_ENGINE_VERSION = 58; const SUGGESTION_ENGINE_VERSION = 58;
const MAKER_STRATEGY_VERSION = 2; const MAKER_STRATEGY_VERSION = 2;
const PREVIOUS_STRATEGY_VERSION = 57; const PREVIOUS_STRATEGY_VERSION = 57;
@@ -870,7 +870,7 @@ const AGENTS = [
rank:(s)=>[...s].sort((a,b)=>(b.volume_24hr*(b.conviction+20)*Math.max(.4,Math.abs(b.net_edge||b.edge||0)*18))-(a.volume_24hr*(a.conviction+20)*Math.max(.4,Math.abs(a.net_edge||a.edge||0)*18))), rank:(s)=>[...s].sort((a,b)=>(b.volume_24hr*(b.conviction+20)*Math.max(.4,Math.abs(b.net_edge||b.edge||0)*18))-(a.volume_24hr*(a.conviction+20)*Math.max(.4,Math.abs(a.net_edge||a.edge||0)*18))),
maxNew:5, maxFrac:0.06, minConv:57, kelly:0.30, targetExposure:0.72, drawdownExposure:0.50}, maxNew:5, maxFrac:0.06, minConv:57, kelly:0.30, targetExposure:0.72, drawdownExposure:0.50},
{id:"favorite", name:"Favorite Backer", emoji:"🛡️", color:"#38d2e6", kind:"strategy", {id:"favorite", name:"Favorite Backer", emoji:"🛡️", color:"#38d2e6", kind:"strategy",
blurb:"Runs a forward-only sports research lane after the fresh 3,000-market replay rejected the old capital rule. It observes one 6075% favorite per independent event near the 12-hour checkpoint with zero cash, grades only closed markets, and can begin 1.25% positions only after 30 new events establish a positive lower confidence bound.", blurb:"Runs a forward-only sports research lane after the fresh 3,000-market replay rejected the old capital rule. It observes one low-friction 6075% favorite per independent event near the 12-hour checkpoint using the executable ask plus a slippage buffer, grades only closed markets, and can begin 1.25% positions only after 30 new events establish a positive lower confidence bound.",
rank:(s)=>[...s].filter(x=>x.entry_price>=0.6).sort((a,b)=>(b.entry_price+Math.abs(b.net_edge||b.edge||0)+Number(b.evidence_score||0)*.2)-(a.entry_price+Math.abs(a.net_edge||a.edge||0)+Number(a.evidence_score||0)*.2)||b.conviction-a.conviction), rank:(s)=>[...s].filter(x=>x.entry_price>=0.6).sort((a,b)=>(b.entry_price+Math.abs(b.net_edge||b.edge||0)+Number(b.evidence_score||0)*.2)-(a.entry_price+Math.abs(a.net_edge||a.edge||0)+Number(a.evidence_score||0)*.2)||b.conviction-a.conviction),
maxNew:4, maxFrac:0.05, minConv:58, kelly:0.24, targetExposure:0.58, drawdownExposure:0.38}, maxNew:4, maxFrac:0.05, minConv:58, kelly:0.24, targetExposure:0.58, drawdownExposure:0.38},
{id:"longshot", name:"Longshot Hunter", emoji:"🎰", color:"#fbbf24", kind:"strategy", {id:"longshot", name:"Longshot Hunter", emoji:"🎰", color:"#fbbf24", kind:"strategy",
@@ -1183,6 +1183,8 @@ const SPORTS_FAVORITE_VERDICT_EVENTS=12;
const SPORTS_FAVORITE_PROMOTION_EVENTS=30; const SPORTS_FAVORITE_PROMOTION_EVENTS=30;
const SPORTS_FAVORITE_SHADOW_LIMIT=20; const SPORTS_FAVORITE_SHADOW_LIMIT=20;
const SPORTS_FAVORITE_OUTCOME_LIMIT=240; const SPORTS_FAVORITE_OUTCOME_LIMIT=240;
const SPORTS_FAVORITE_SLIPPAGE_BUFFER=0.0025;
const SPORTS_FAVORITE_MAX_EXECUTION_COST=0.01;
const MAKER_MAX_QUOTES=6; const MAKER_MAX_QUOTES=6;
const MAKER_MAX_QUOTE_CAPITAL_PCT=0.02; const MAKER_MAX_QUOTE_CAPITAL_PCT=0.02;
const MAKER_TOTAL_CAPITAL_PCT=0.10; const MAKER_TOTAL_CAPITAL_PCT=0.10;
@@ -1338,20 +1340,27 @@ function sportsFavoritePilotSuggestion(m){
if(!Number.isFinite(lead)||lead<minLead||lead>maxLead||m.spread<=0||m.spread>0.03||m.volume<5000||m.liquidity<2000)return null; if(!Number.isFinite(lead)||lead<minLead||lead>maxLead||m.spread<=0||m.spread>0.03||m.volume<5000||m.liquidity<2000)return null;
const side=Number(m.yes_price)>=Number(m.no_price)?"YES":"NO",marketPrice=side==="YES"?Number(m.yes_price):Number(m.no_price); const side=Number(m.yes_price)>=Number(m.no_price)?"YES":"NO",marketPrice=side==="YES"?Number(m.yes_price):Number(m.no_price);
if(marketPrice<SPORTS_FAVORITE_MIN_ENTRY||marketPrice>=SPORTS_FAVORITE_MAX_ENTRY)return null; if(marketPrice<SPORTS_FAVORITE_MIN_ENTRY||marketPrice>=SPORTS_FAVORITE_MAX_ENTRY)return null;
const modeledEntry=clamp(marketPrice+0.05,0.01,0.99),eventKey=String(m.event_id||m.event||m.id); const quotedAsk=side==="YES"?Number(m.best_ask):(Number(m.best_bid)>0?1-Number(m.best_bid):NaN);
const fallbackAsk=marketPrice+Math.max(0.0025,Number(m.spread||0)/2);
const executableAsk=Number.isFinite(quotedAsk)&&quotedAsk>=marketPrice&&quotedAsk<1?quotedAsk:fallbackAsk;
const modeledEntry=clamp(executableAsk+SPORTS_FAVORITE_SLIPPAGE_BUFFER,0.01,0.99);
const executionCost=Math.max(0,modeledEntry-marketPrice);
if(executionCost>SPORTS_FAVORITE_MAX_EXECUTION_COST+0.00001)return null;
const eventKey=String(m.event_id||m.event||m.id);
const conviction=+clamp(70+Math.log10(Math.max(1,m.liquidity))*1.4+Math.log10(Math.max(1,m.volume_24hr||m.volume))*0.8,70,80).toFixed(1); const conviction=+clamp(70+Math.log10(Math.max(1,m.liquidity))*1.4+Math.log10(Math.max(1,m.volume_24hr||m.volume))*0.8,70,80).toFixed(1);
return {market_id:m.id,question:m.question,event:m.event,event_key:eventKey,url:m.url,category:m.category,tags:m.tags, return {market_id:m.id,question:m.question,event:m.event,event_key:eventKey,url:m.url,category:m.category,tags:m.tags,
clob_yes:(m.clob_token_ids||[])[0]||null,clob_no:(m.clob_token_ids||[])[1]||null, clob_yes:(m.clob_token_ids||[])[0]||null,clob_no:(m.clob_token_ids||[])[1]||null,
yes_price:m.yes_price,no_price:m.no_price,fair_value:+modeledEntry.toFixed(4),edge:0,net_edge:0, yes_price:m.yes_price,no_price:m.no_price,fair_value:+modeledEntry.toFixed(4),edge:0,net_edge:0,
friction:0.05,chase_penalty:0,evidence_score:0.60,evidence_source_count:0,quality:"sports-favorite-shadow",side, friction:+executionCost.toFixed(4),chase_penalty:0,evidence_score:0.60,evidence_source_count:0,quality:"sports-favorite-shadow",side,
market_price:+marketPrice.toFixed(4),entry_price:+modeledEntry.toFixed(4),conviction,volume:m.volume,volume_24hr:m.volume_24hr,liquidity:m.liquidity, market_price:+marketPrice.toFixed(4),entry_price:+modeledEntry.toFixed(4),conviction,volume:m.volume,volume_24hr:m.volume_24hr,liquidity:m.liquidity,
spread:m.spread,price_change_1h:m.price_change_1h,price_change_1d:m.price_change_1d,price_change_1w:m.price_change_1w, spread:m.spread,price_change_1h:m.price_change_1h,price_change_1d:m.price_change_1d,price_change_1w:m.price_change_1w,
momentum_strength:0,signal_strength:0.60,signal_confidence:0.60,signal_type:"sports-favorite-shadow", momentum_strength:0,signal_strength:0.60,signal_confidence:0.60,signal_type:"sports-favorite-shadow",
trade_ready:false,entry_candidate:false,audited_observation_only:true,adaptive_promotion:false,watch_only:true,jump_risk:true,requires_live:false, trade_ready:false,entry_candidate:false,audited_observation_only:true,adaptive_promotion:false,watch_only:true,jump_risk:true,requires_live:false,
game_start:m.game_start,hours_to_start:+lead.toFixed(2),days_to_resolution:m.days_to_resolution!=null?+m.days_to_resolution.toFixed(1):null, game_start:m.game_start,hours_to_start:+lead.toFixed(2),days_to_resolution:m.days_to_resolution!=null?+m.days_to_resolution.toFixed(1):null,
pilot_prior:{markets:3000,event_legs:1,modeled_cost_cents:5,train_mean:0.00960,validation_mean:0.15695,holdout_mean:0.00407,strictly_promoted:false}, pilot_prior:{markets:3000,event_legs:1,modeled_cost_cents:+(executionCost*100).toFixed(2),zero_cost_train_mean:0.03064,
drivers:["zero-capital forward observation","one observation per sports event","6075% pregame favorite","within three hours of the 12h checkpoint","five-cent modeled entry cost"], zero_cost_holdout_mean:0.01852,one_cent_train_mean:0.01592,one_cent_holdout_mean:0.00364,strictly_promoted:false},
rationale:`Forward research only: ${side} is the ${Math.round(marketPrice*100)}% favorite ${lead.toFixed(1)}h before the published start. The fresh 3,000-market replay rejected the old 24-hour capital rule. This narrower 12-hour, 6075% cohort had positive point estimates in all three chronological partitions after a modeled five-cent cost, but its confidence bounds did not establish a durable edge. It therefore uses zero cash and can earn 1.25% capital only after 30 new independent closed events produce a positive lower confidence bound.`}; drivers:["zero-capital forward observation","one observation per sports event","6075% pregame favorite","within three hours of the 12h checkpoint","executable ask plus 0.25c slippage","maximum 1c entry friction"],
rationale:`Forward research only: ${side} is the ${Math.round(marketPrice*100)}% favorite ${lead.toFixed(1)}h before the published start. The modeled entry is ${pct(modeledEntry)} using the executable ask plus a 0.25-cent slippage buffer, ${(executionCost*100).toFixed(2)} cents above the midpoint. The 3,000-market cost curve kept positive train and holdout point estimates near one cent but turned negative around two cents; confidence bounds still crossed zero. This observation therefore uses zero cash and can earn 1.25% capital only after 30 new independent closed events produce a positive lower confidence bound.`};
} }
function analyzeMarket(m,realWorldSignals={}){ function analyzeMarket(m,realWorldSignals={}){
if(m.volume<MIN_SCOUT_VOLUME||m.liquidity<MIN_SCOUT_LIQUIDITY)return null; if(m.volume<MIN_SCOUT_VOLUME||m.liquidity<MIN_SCOUT_LIQUIDITY)return null;
@@ -2097,9 +2106,9 @@ function stageSportsFavoriteShadows(p,suggestions,{execute=true}={}){
p.sports_favorite_shadows.push({id:`sports-shadow:${marketId}:${Date.now()}:${staged}`,market_id:marketId,event_key:eventKey, p.sports_favorite_shadows.push({id:`sports-shadow:${marketId}:${Date.now()}:${staged}`,market_id:marketId,event_key:eventKey,
question:s.question,event:s.event||"",side:s.side,entry_price:Number(s.entry_price),market_price:Number(s.market_price), question:s.question,event:s.event||"",side:s.side,entry_price:Number(s.entry_price),market_price:Number(s.market_price),
current_price:Number(s.market_price),game_start:s.game_start,hours_to_start:s.hours_to_start,opened_at:openedAt, current_price:Number(s.market_price),game_start:s.game_start,hours_to_start:s.hours_to_start,opened_at:openedAt,
strategy_version:SUGGESTION_ENGINE_VERSION,modeled_cost:0.05,url:s.url||""}); strategy_version:SUGGESTION_ENGINE_VERSION,modeled_cost:+Math.max(0,Number(s.entry_price)-Number(s.market_price)).toFixed(4),url:s.url||""});
p.history.push({date:logDay(),action:"SPORTS_SHADOW",question:s.question,side:s.side, p.history.push({date:logDay(),action:"SPORTS_SHADOW",question:s.question,side:s.side,
detail:`Zero-capital forward observation recorded ${s.side} '${s.question.slice(0,40)}' at modeled ${pct(s.entry_price)} (${pct(s.market_price)} market + 5c cost) · one observation for event ${eventKey} · cash unchanged`}); detail:`Zero-capital forward observation recorded ${s.side} '${s.question.slice(0,40)}' at modeled ${pct(s.entry_price)} (${pct(s.market_price)} midpoint + ${((Number(s.entry_price)-Number(s.market_price))*100).toFixed(2)}c executable friction) · one observation for event ${eventKey} · cash unchanged`});
usedEvents.add(eventKey);usedMarkets.add(marketId);staged++; usedEvents.add(eventKey);usedMarkets.add(marketId);staged++;
} }
return {active:p.sports_favorite_shadows.length,staged,candidates:candidates.length}; return {active:p.sports_favorite_shadows.length,staged,candidates:candidates.length};
@@ -2119,7 +2128,7 @@ function manageSportsFavoriteShadows(p,priceMap,{execute=true}={}){
if(!p.sports_favorite_outcomes.some(outcome=>outcome.id===row.id))p.sports_favorite_outcomes.push(Object.assign({},row,{closed_at:cycleIso(), if(!p.sports_favorite_outcomes.some(outcome=>outcome.id===row.id))p.sports_favorite_outcomes.push(Object.assign({},row,{closed_at:cycleIso(),
exit_price:+price.toFixed(4),net_return:+netReturn.toFixed(4),pnl_per_100:+pnlPer100.toFixed(2)})); exit_price:+price.toFixed(4),net_return:+netReturn.toFixed(4),pnl_per_100:+pnlPer100.toFixed(2)}));
p.history.push({date:logDay(),action:"SPORTS_GRADE",question:row.question,side:row.side, p.history.push({date:logDay(),action:"SPORTS_GRADE",question:row.question,side:row.side,
detail:`Forward sports observation settled at ${pct(price)} · modeled net return ${(netReturn*100).toFixed(2)}% after the five-cent cost · portfolio cash unchanged`}); detail:`Forward sports observation settled at ${pct(price)} · modeled net return ${(netReturn*100).toFixed(2)}% after ${((row.modeled_cost||0)*100).toFixed(2)}c executable friction · portfolio cash unchanged`});
completed++; completed++;
} }
p.sports_favorite_shadows=keep; p.sports_favorite_shadows=keep;
@@ -3101,7 +3110,7 @@ function openPositions(p,cfg,rankedSugs,focus,decision,avoidMarketIds,peerStats=
risk_budget_pct:+(riskBudgetPct*100).toFixed(2), risk_budget_pct:+(riskBudgetPct*100).toFixed(2),
peak_price:+entry.toFixed(4),gain_stops:{},stop_losses:{}}); peak_price:+entry.toFixed(4),gain_stops:{},stop_losses:{}});
const openDetail=s.signal_type==="sports-favorite-pilot" const openDetail=s.signal_type==="sports-favorite-pilot"
?`${decision?decision.mode+" mode — ":""}Sports settlement pilot bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ modeled ${pct(entry)} for ${fmtUSD(cost)} (${pct(Number(s.market_price||entry))} market + 5c cost) · one position for event ${s.event_key||s.event||s.market_id} · pilot state ${pilotProfile.state} · ${(Number(s.hours_to_start)||0).toFixed(1)}h before start` ?`${decision?decision.mode+" mode — ":""}Forward-promoted sports position bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ modeled ${pct(entry)} for ${fmtUSD(cost)} (${pct(Number(s.market_price||entry))} midpoint + ${((entry-Number(s.market_price||entry))*100).toFixed(2)}c executable friction) · one position for event ${s.event_key||s.event||s.market_id} · learner state ${pilotProfile.state} · ${(Number(s.hours_to_start)||0).toFixed(1)}h before start`
:`${decision?decision.mode+" mode — ":""}Bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ ${pct(entry)} for ${fmtUSD(cost)} · max binary loss budget ${(riskBudgetPct*100).toFixed(1)}% · signal margin ${((Math.abs(s.net_edge!=null?s.net_edge:s.edge))*100).toFixed(1)}c · learned weight ${Number(s.learning_multiplier||1).toFixed(2)}x (${s.learning_state||"observing"}/${s.market_learning_state||"observing"})${(s.historical_prior_features||[]).length?` · history prior ${(s.historical_prior_features||[]).join("+")}`:""} · evidence ${Math.round((s.evidence_score||0)*100)}${s.peer_note?` (${s.peer_note})`:""}`; :`${decision?decision.mode+" mode — ":""}Bought ${shares} ${s.side} '${s.question.slice(0,40)}' @ ${pct(entry)} for ${fmtUSD(cost)} · max binary loss budget ${(riskBudgetPct*100).toFixed(1)}% · signal margin ${((Math.abs(s.net_edge!=null?s.net_edge:s.edge))*100).toFixed(1)}c · learned weight ${Number(s.learning_multiplier||1).toFixed(2)}x (${s.learning_state||"observing"}/${s.market_learning_state||"observing"})${(s.historical_prior_features||[]).length?` · history prior ${(s.historical_prior_features||[]).join("+")}`:""} · evidence ${Math.round((s.evidence_score||0)*100)}${s.peer_note?` (${s.peer_note})`:""}`;
p.history.push({date:logDay(),action:"OPEN",question:s.question,side:s.side,detail:openDetail}); p.history.push({date:logDay(),action:"OPEN",question:s.question,side:s.side,detail:openDetail});
if(s.signal_type==="sports-favorite-pilot")heldEventKeys.add(String(s.event_key||s.event||s.market_id||"")); if(s.signal_type==="sports-favorite-pilot")heldEventKeys.add(String(s.event_key||s.event||s.market_id||""));
@@ -5188,7 +5197,8 @@ window.PMA_ENGINE_DIAGNOSTICS=Object.freeze({
sportsFavoritePilot:{entryBand:[SPORTS_FAVORITE_MIN_ENTRY,SPORTS_FAVORITE_MAX_ENTRY],targetLeadHours:SPORTS_FAVORITE_TARGET_LEAD_HOURS, sportsFavoritePilot:{entryBand:[SPORTS_FAVORITE_MIN_ENTRY,SPORTS_FAVORITE_MAX_ENTRY],targetLeadHours:SPORTS_FAVORITE_TARGET_LEAD_HOURS,
leadToleranceHours:SPORTS_FAVORITE_LEAD_TOLERANCE_HOURS,pilotPositionPct:SPORTS_FAVORITE_PILOT_POSITION_PCT*100, leadToleranceHours:SPORTS_FAVORITE_LEAD_TOLERANCE_HOURS,pilotPositionPct:SPORTS_FAVORITE_PILOT_POSITION_PCT*100,
totalCapitalPct:SPORTS_FAVORITE_TOTAL_CAPITAL_PCT*100,shadowLimit:SPORTS_FAVORITE_SHADOW_LIMIT, totalCapitalPct:SPORTS_FAVORITE_TOTAL_CAPITAL_PCT*100,shadowLimit:SPORTS_FAVORITE_SHADOW_LIMIT,
verdictEvents:SPORTS_FAVORITE_VERDICT_EVENTS,promotionEvents:SPORTS_FAVORITE_PROMOTION_EVENTS,modeledCostCents:5, verdictEvents:SPORTS_FAVORITE_VERDICT_EVENTS,promotionEvents:SPORTS_FAVORITE_PROMOTION_EVENTS,
slippageBufferCents:SPORTS_FAVORITE_SLIPPAGE_BUFFER*100,maximumExecutionCostCents:SPORTS_FAVORITE_MAX_EXECUTION_COST*100,
capitalRequiresForwardPromotion:true,old24HourCapitalRuleRetired:true}, capitalRequiresForwardPromotion:true,old24HourCapitalRuleRetired:true},
historicalPrior:"All broad directional and corrected settlement-calibration rules failed clean validation and remain observation-only. The fresh 3,000-market replay rejected the Strategy 57 24-hour sports-capital rule: -11.98% train and -4.04% untouched holdout means after modeled cost. Favorite Backer now records a zero-capital 12-hour, 60%-75% forward cohort and requires 30 new independent closed events with a positive lower confidence bound before any capital. Live-priced complete negative-risk bundles may trade; paired maker quotes remain zero-capital observations until current cohorts independently promote"}), historicalPrior:"All broad directional and corrected settlement-calibration rules failed clean validation and remain observation-only. The fresh 3,000-market replay rejected the Strategy 57 24-hour sports-capital rule: -11.98% train and -4.04% untouched holdout means after modeled cost. Favorite Backer now records a zero-capital 12-hour, 60%-75% forward cohort and requires 30 new independent closed events with a positive lower confidence bound before any capital. Live-priced complete negative-risk bundles may trade; paired maker quotes remain zero-capital observations until current cohorts independently promote"}),
}); });
@@ -5211,7 +5221,14 @@ function runEngineSelfTest(){
const ordinaryDatedContract=analyzeMarket(market({id:"dated-test",question:"Will the policy pass on 2026-08-22?"}),news); const ordinaryDatedContract=analyzeMarket(market({id:"dated-test",question:"Will the policy pass on 2026-08-22?"}),news);
const sportsPilotStart=new Date(Date.now()+12*3600000).toISOString(); const sportsPilotStart=new Date(Date.now()+12*3600000).toISOString();
const sportsPilot=analyzeMarket(market({id:"sports-pilot",question:"Will Harbor FC win tomorrow?",event:"Harbor FC vs City FC",event_id:"sports-event-1", const sportsPilot=analyzeMarket(market({id:"sports-pilot",question:"Will Harbor FC win tomorrow?",event:"Harbor FC vs City FC",event_id:"sports-event-1",
category:"Sports",yes_price:0.72,no_price:0.28,game_start:sportsPilotStart,days_to_resolution:1,price_change_1h:0,price_change_1d:0,price_change_1w:0}),news); category:"Sports",yes_price:0.72,no_price:0.28,best_bid:0.715,best_ask:0.725,spread:0.01,
game_start:sportsPilotStart,days_to_resolution:1,price_change_1h:0,price_change_1d:0,price_change_1w:0}),news);
const expensiveSportsPilot=sportsFavoritePilotSuggestion(market({id:"sports-expensive",question:"Will Costly FC win tomorrow?",event:"Costly FC vs City FC",event_id:"sports-event-expensive",
category:"Sports",yes_price:0.72,no_price:0.28,best_bid:0.705,best_ask:0.735,spread:0.03,
game_start:sportsPilotStart,days_to_resolution:1,price_change_1h:0,price_change_1d:0,price_change_1w:0}));
const noSportsPilot=sportsFavoritePilotSuggestion(market({id:"sports-no",question:"Will Harbor FC fail to win tomorrow?",event:"Harbor FC vs City FC",event_id:"sports-event-no",
category:"Sports",yes_price:0.30,no_price:0.70,best_bid:0.295,best_ask:0.305,spread:0.01,
game_start:sportsPilotStart,days_to_resolution:1,price_change_1h:0,price_change_1d:0,price_change_1w:0}));
const sportsPilotSecond=Object.assign({},sportsPilot,{market_id:"sports-pilot-second",question:"Harbor FC first-half winner?"}); const sportsPilotSecond=Object.assign({},sportsPilot,{market_id:"sports-pilot-second",question:"Harbor FC first-half winner?"});
const sportsPilotBook=defaultPortfolio(),favoriteAgent=AGENTS.find(agent=>agent.id==="favorite"),sportsPilotCash=sportsPilotBook.cash; const sportsPilotBook=defaultPortfolio(),favoriteAgent=AGENTS.find(agent=>agent.id==="favorite"),sportsPilotCash=sportsPilotBook.cash;
const sportsShadowStage=stageSportsFavoriteShadows(sportsPilotBook,[sportsPilot,sportsPilotSecond]); const sportsShadowStage=stageSportsFavoriteShadows(sportsPilotBook,[sportsPilot,sportsPilotSecond]);
@@ -5661,7 +5678,10 @@ function runEngineSelfTest(){
sportsFavoritePilot:{ sportsFavoritePilot:{
identifiesTimedForwardShadow:Boolean(sportsPilot&&!sportsPilot.trade_ready&&sportsPilot.audited_observation_only identifiesTimedForwardShadow:Boolean(sportsPilot&&!sportsPilot.trade_ready&&sportsPilot.audited_observation_only
&&sportsPilot.quality==="sports-favorite-shadow"&&sportsPilot.side==="YES"), &&sportsPilot.quality==="sports-favorite-shadow"&&sportsPilot.side==="YES"),
chargesModeledFiveCentCost:Boolean(sportsPilot&&sportsPilot.market_price===0.72&&sportsPilot.entry_price===0.77&&sportsPilot.friction===0.05), usesExecutableAskPlusSlippage:Boolean(sportsPilot&&sportsPilot.market_price===0.72&&sportsPilot.entry_price===0.7275&&sportsPilot.friction===0.0075),
derivesNoAskFromYesBid:Boolean(noSportsPilot&&noSportsPilot.side==="NO"&&noSportsPilot.market_price===0.70
&&noSportsPilot.entry_price===0.7075&&noSportsPilot.friction===0.0075),
rejectsMoreThanOneCentFriction:expensiveSportsPilot===null,
noAgentAcceptsBeforePromotion:Boolean(sportsPilot&&!agentAcceptsSuggestion(favoriteAgent,sportsPilot) noAgentAcceptsBeforePromotion:Boolean(sportsPilot&&!agentAcceptsSuggestion(favoriteAgent,sportsPilot)
&&!agentAcceptsSuggestion(AGENTS.find(agent=>agent.id==="momentum"),sportsPilot)), &&!agentAcceptsSuggestion(AGENTS.find(agent=>agent.id==="momentum"),sportsPilot)),
stagesOneShadowPerEvent:sportsShadowStage.staged===1&&sportsPilotBook.sports_favorite_outcomes.length===1, stagesOneShadowPerEvent:sportsShadowStage.staged===1&&sportsPilotBook.sports_favorite_outcomes.length===1,
+13 -2
View File
@@ -5,6 +5,8 @@ const CONCURRENCY = Math.max(1, Math.min(12, Number(process.env.SPORTS_FAVORITE_
const COST = Math.max(0, Math.min(0.10, Number(process.env.SPORTS_FAVORITE_COST_CENTS || 5) / 100)); const COST = Math.max(0, Math.min(0.10, Number(process.env.SPORTS_FAVORITE_COST_CENTS || 5) / 100));
const MAX_STALENESS_HOURS = Math.max(1, Math.min(12, Number(process.env.SPORTS_FAVORITE_MAX_STALENESS_HOURS || 3))); const MAX_STALENESS_HOURS = Math.max(1, Math.min(12, Number(process.env.SPORTS_FAVORITE_MAX_STALENESS_HOURS || 3)));
const EVENT_LEGS = Math.max(1, Math.min(4, Number(process.env.SPORTS_FAVORITE_EVENT_LEGS || 1))); const EVENT_LEGS = Math.max(1, Math.min(4, Number(process.env.SPORTS_FAVORITE_EVENT_LEGS || 1)));
const COST_GRID = String(process.env.SPORTS_FAVORITE_COST_GRID_CENTS || "0,1,2,3,4,5")
.split(",").map(Number).filter((value) => Number.isFinite(value) && value >= 0 && value <= 10).map((value) => value / 100);
const HOUR = 3600; const HOUR = 3600;
function parseJson(value) { function parseJson(value) {
@@ -161,9 +163,16 @@ const evaluated = rules.map((rule) => {
}); });
const selected = evaluated.filter((row) => row.validationPassed).sort((a, b) => Number(b.passesHoldout) - Number(a.passesHoldout) || b.holdout.lower - a.holdout.lower); const selected = evaluated.filter((row) => row.validationPassed).sort((a, b) => Number(b.passesHoldout) - Number(a.passesHoldout) || b.holdout.lower - a.holdout.lower);
const baseline = evaluated.find((row) => row.rule.leadHours === 24 && row.rule.minEntry === 0.55 && row.rule.maxEntry === 0.95); const baseline = evaluated.find((row) => row.rule.leadHours === 24 && row.rule.minEntry === 0.55 && row.rule.maxEntry === 0.95);
const livePilot = evaluated.find((row) => row.rule.leadHours === 24 && row.rule.minEntry === 0.60 && row.rule.maxEntry === 0.85); const retiredPilot = evaluated.find((row) => row.rule.leadHours === 24 && row.rule.minEntry === 0.60 && row.rule.maxEntry === 0.85);
const forwardResearch = evaluated.find((row) => row.rule.leadHours === 12 && row.rule.minEntry === 0.60 && row.rule.maxEntry === 0.75);
const compact = (stats) => Object.fromEntries(Object.entries(stats).map(([key, value]) => [key, Number.isFinite(value) ? +value.toFixed(5) : value])); const compact = (stats) => Object.fromEntries(Object.entries(stats).map(([key, value]) => [key, Number.isFinite(value) ? +value.toFixed(5) : value]));
const candidate = (row) => ({ rule: row.rule, train: compact(row.train), validation: compact(row.validation), holdout: compact(row.holdout), passesHoldout: row.passesHoldout }); const candidate = (row) => ({ rule: row.rule, train: compact(row.train), validation: compact(row.validation), holdout: compact(row.holdout), passesHoldout: row.passesHoldout });
function costCurve(rule) {
if (!rule) return [];
const raw = Object.fromEntries(Object.entries(partitions).map(([name, partition]) => [name, tradesFor(partition, rule)]));
return COST_GRID.map((cost) => ({ modeledCostCents: cost * 100, ...Object.fromEntries(Object.entries(raw).map(([name, rows]) => [name,
compact(summarize(rows.map((row) => ({ ...row, netReturn: (row.won ? 1 : 0) / row.entry - 1 - cost / row.entry }))))])) }));
}
const closest = evaluated.filter((row) => row.train.events >= 25 && row.validation.events >= 10 && row.holdout.events >= 10) const closest = evaluated.filter((row) => row.train.events >= 25 && row.validation.events >= 10 && row.holdout.events >= 10)
.sort((a, b) => Math.min(b.train.lower, b.validation.lower, b.holdout.lower) .sort((a, b) => Math.min(b.train.lower, b.validation.lower, b.holdout.lower)
- Math.min(a.train.lower, a.validation.lower, a.holdout.lower)); - Math.min(a.train.lower, a.validation.lower, a.holdout.lower));
@@ -176,7 +185,9 @@ console.log(JSON.stringify({ generatedAt: new Date().toISOString(), requestedMar
partitionMarkets: Object.fromEntries(Object.entries(partitions).map(([key, value]) => [key, value.length])), partitionMarkets: Object.fromEntries(Object.entries(partitions).map(([key, value]) => [key, value.length])),
trainPassed: evaluated.filter((row) => row.trainPassed).length, validationSelected: selected.length, trainPassed: evaluated.filter((row) => row.trainPassed).length, validationSelected: selected.length,
holdoutPassed: selected.filter((row) => row.passesHoldout).length, baseline: baseline ? candidate(baseline) : null, holdoutPassed: selected.filter((row) => row.passesHoldout).length, baseline: baseline ? candidate(baseline) : null,
livePilot: livePilot ? candidate(livePilot) : null, retiredPilot: retiredPilot ? candidate(retiredPilot) : null,
forwardResearch: forwardResearch ? candidate(forwardResearch) : null,
costSensitivity: { retiredPilot: costCurve(retiredPilot?.rule), forwardResearch: costCurve(forwardResearch?.rule) },
closestCandidates: closest.slice(0, 15).map(candidate), closestCandidates: closest.slice(0, 15).map(candidate),
candidates: selected.slice(0, 20).map(candidate), candidates: selected.slice(0, 20).map(candidate),
holdoutExamples: (selected.find((row) => row.passesHoldout)?.holdoutRows || []).slice(0, 12) holdoutExamples: (selected.find((row) => row.passesHoldout)?.holdoutRows || []).slice(0, 12)
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE_NAME = "polymarket-arena-build-73"; const CACHE_NAME = "polymarket-arena-build-74";
const APP_SHELL = ["/", "/index.html", "/personal.html", "/cycle-worker.js"]; const APP_SHELL = ["/", "/index.html", "/personal.html", "/cycle-worker.js"];
self.addEventListener("install", event => { self.addEventListener("install", event => {