mirror of
https://github.com/theodore-song/polymarket-analyst.git
synced 2026-08-19 18:48:10 +00:00
Align adaptation with audited outcomes
This commit is contained in:
+44
-31
@@ -341,7 +341,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
<nav class="topnav">
|
||||
<div class="brand">
|
||||
<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 42 · build 44</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 43 · build 45</div></div>
|
||||
</div>
|
||||
<div class="tabs" id="tabs">
|
||||
<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">
|
||||
<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 class="live-build-banner"><b>Build 44 active:</b> gap-prone and crypto positions are limited to one agent, and each historically blocked exploration market has one designated explorer. This prevents agents from duplicating the same high-risk loss. Strategy 42 starts a clean return baseline. This remains paper trading; profits are not guaranteed.</div>
|
||||
<div class="live-build-banner"><b>Build 45 active:</b> adaptation now grades signals after the same 24-hour minimum used by ordinary trade policy. Reversal and short-dated NO entries are disabled after independent price-history and settlement audits found repeatable net losses; Trend Endurance replaces the reversal agent. This remains paper trading; profits are not guaranteed.</div>
|
||||
|
||||
<!-- ============ OVERVIEW ============ -->
|
||||
<section class="tabpanel" data-tab="overview">
|
||||
@@ -714,7 +714,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
<!-- ============ ABOUT ============ -->
|
||||
<section class="tabpanel" data-tab="about">
|
||||
<div class="section-title">ℹ️ The competition</div>
|
||||
<p class="muted" style="margin-top:-6px;max-width:820px">Every agent starts with <b>$10,000</b> in paper money. Five core strategies use disciplined entry rules, while five aggressive strategies pursue catalysts, reversals, breakouts, asymmetric tails, and concentrated conviction. Aggressive agents may size confirmed setups more heavily, but cash is retained whenever their strategy has no qualifying signal.</p>
|
||||
<p class="muted" style="margin-top:-6px;max-width:820px">Every agent starts with <b>$10,000</b> in paper money. Five core strategies use disciplined entry rules, while five aggressive strategies pursue catalysts, durable trends, breakouts, asymmetric tails, and concentrated conviction. Aggressive agents may size confirmed setups more heavily, but cash is retained whenever their strategy has no qualifying signal.</p>
|
||||
<div class="about-grid" id="aboutAgents"></div>
|
||||
<div class="card" style="margin-top:16px">
|
||||
<div class="card-h"><h3>The live cycle</h3></div>
|
||||
@@ -745,7 +745,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
Build 44 · Adaptive strategy 42 · Paper trading only · Live prices from Polymarket's public Gamma API · Not financial advice ·
|
||||
Build 45 · Adaptive strategy 43 · Paper trading only · Live prices from Polymarket's public Gamma API · Not financial advice ·
|
||||
<a class="market-link" href="https://github.com/theodore-song/polymarket-analyst" target="_blank" rel="noopener">Source on GitHub</a>
|
||||
</footer>
|
||||
</div>
|
||||
@@ -774,9 +774,9 @@ const POLITICS_TREND_MIN_HOLD_HOURS = 72;
|
||||
const EXIT_CONFIRM_HOURS = 6;
|
||||
const AGENTS_KEY = "pma_agents_v2";
|
||||
const SUG_KEY = "pma_suggestions_v5";
|
||||
const BUILD_VERSION = 44;
|
||||
const SUGGESTION_ENGINE_VERSION = 42;
|
||||
const PREVIOUS_STRATEGY_VERSION = 40;
|
||||
const BUILD_VERSION = 45;
|
||||
const SUGGESTION_ENGINE_VERSION = 43;
|
||||
const PREVIOUS_STRATEGY_VERSION = 42;
|
||||
const LEGACY_BUILD_STRATEGY_LINEAGE = Object.freeze({40:40,41:40});
|
||||
function normalizedStrategyVersion(value){
|
||||
const version=Number(value||0);
|
||||
@@ -884,9 +884,11 @@ const AGENTS = [
|
||||
blurb:"An aggressive event-driven strategy that concentrates on markets with fresh outside context, multiple evidence signals, and enough activity for a fast repricing. It is willing to enter earlier than the core agents when a measurable catalyst and positive post-cost edge agree, while accepting larger swings to capture the move.",
|
||||
rank:(s)=>[...s].sort((a,b)=>(Number(b.evidence_source_count||0)*28+Number(b.evidence_score||0)*32+effectiveEntryEdge(b)*170+b.conviction+Math.log10(Number(b.volume_24hr||0)+1)*5)-(Number(a.evidence_source_count||0)*28+Number(a.evidence_score||0)*32+effectiveEntryEdge(a)*170+a.conviction+Math.log10(Number(a.volume_24hr||0)+1)*5)),
|
||||
maxNew:7, maxFrac:0.09, minConv:52, kelly:0.46, allocationFrac:0.055, maxPositions:18, maxCategoryPct:0.40, maxCycleDrawdown:8, targetExposure:0.72, drawdownExposure:0.60},
|
||||
{id:"reversal", name:"Reversal Edge", emoji:"↻", color:"#ff5f91", kind:"strategy", aggressive:true,
|
||||
blurb:"A contrarian mean-reversion strategy that waits for an hourly reversal after a sharp one-day move. It buys against the earlier direction only when that snapback is confirmed by liquidity, evidence, and a positive post-friction signal margin.",
|
||||
rank:(s)=>[...s].map(reversalCandidate).filter(Boolean).sort((a,b)=>(Math.abs(Number(b.price_change_1d||0))*95+effectiveEntryEdge(b)*190+Number(b.evidence_score||0)*24+b.conviction)-(Math.abs(Number(a.price_change_1d||0))*95+effectiveEntryEdge(a)*190+Number(a.evidence_score||0)*24+a.conviction)),
|
||||
{id:"reversal", name:"Trend Endurance", emoji:"⧗", color:"#ff5f91", kind:"strategy", aggressive:true,
|
||||
blurb:"A patient aggressive trend strategy built from the failure of short-horizon reversal trading. It favors confirmed, non-chased trends with at least three weeks to resolve, gives extra rank to Politics or Economy markets, and allows the move time to develop without assuming either contract side is inherently superior.",
|
||||
rank:(s)=>[...s].filter(x=>x.trade_ready&&x.signal_type==="trend"&&Math.abs(Number(x.price_change_1d||0))<=0.04&&Number(x.days_to_resolution||0)>=21)
|
||||
.sort((a,b)=>((["Politics","Economy"].includes(b.category)?8:0)+Number(b.signal_confidence||0)*45+effectiveEntryEdge(b)*180+Number(b.evidence_score||0)*24+b.conviction)
|
||||
-((["Politics","Economy"].includes(a.category)?8:0)+Number(a.signal_confidence||0)*45+effectiveEntryEdge(a)*180+Number(a.evidence_score||0)*24+a.conviction)),
|
||||
maxNew:6, maxFrac:0.08, minConv:54, kelly:0.42, maxPositions:18, maxCategoryPct:0.40, maxCycleDrawdown:8, targetExposure:0.80, drawdownExposure:0.65},
|
||||
{id:"breakout", name:"Breakout Velocity", emoji:"▲", color:"#00d5b5", kind:"strategy", aggressive:true,
|
||||
blurb:"A high-tempo breakout strategy that follows confirmed price direction when momentum, fresh volume, tight spreads, and positive modeled edge line up. It builds positions quickly and keeps less idle cash so strong moves can drive the portfolio, knowing failed breakouts will create sharper drawdowns.",
|
||||
@@ -921,7 +923,7 @@ const OFFLINE_ENTRY_MAX_AGE_MS = 90*60*1000;
|
||||
const OFFLINE_CACHE_MAX_AGE_MS = 24*60*60*1000;
|
||||
const NETWORK_REQUEST_TIMEOUT_MS = 8000;
|
||||
const PRICE_REQUEST_TIMEOUT_MS = 4000;
|
||||
const SIGNAL_EVAL_HOURS = 12;
|
||||
const SIGNAL_EVAL_HOURS = 24;
|
||||
const SIGNAL_LEDGER_PENDING_LIMIT = 300;
|
||||
const SIGNAL_LEDGER_OUTCOME_LIMIT = 500;
|
||||
const SIGNAL_LEDGER_RETRY_HOURS = 168;
|
||||
@@ -1204,9 +1206,6 @@ function tradeLossBudgetPct(cfg,s={}){
|
||||
function boundedStakeForRisk(eq,stake,cfg,s){
|
||||
return Math.max(0,Math.min(Number(stake||0),Number(eq||0)*tradeLossBudgetPct(cfg,s)));
|
||||
}
|
||||
function reversalCandidate(s){
|
||||
return s&&s.signal_type==="reversal"&&s.trade_ready?s:null;
|
||||
}
|
||||
function analyzeMarket(m,realWorldSignals={}){
|
||||
if(m.volume<MIN_SCOUT_VOLUME||m.liquidity<MIN_SCOUT_LIQUIDITY)return null;
|
||||
const external=realWorldSignals[m.id]||{},p=m.yes_price,policy=categoryPolicy(m.category);
|
||||
@@ -1760,7 +1759,8 @@ function stableExploration(agentId,marketId){
|
||||
}
|
||||
function historicalOpportunityPrior(s){
|
||||
const rows=[];
|
||||
if((s.signal_type||"")==="reversal")rows.push({feature:"reversal",score:-0.0413,samples:287,blocked:true});
|
||||
if((s.signal_type||"")==="reversal")rows.push({feature:"reversal",score:-0.0369,samples:207,blocked:true,hardBlocked:true});
|
||||
if((s.side||"")==="NO"&&Number(s.days_to_resolution)<=21)rows.push({feature:"short-no",score:-0.3733,samples:64,blocked:true,hardBlocked:true});
|
||||
if((s.signal_type||"")==="trend"&&(s.category||"Other")==="Sports")rows.push({feature:"sports-trend",score:-0.0353,samples:162,blocked:true});
|
||||
if((s.category||"Other")==="Crypto")rows.push({feature:"crypto",score:-0.0344,samples:140,blocked:false});
|
||||
if(entryBand(s.entry_price)==="longshot")rows.push({feature:"longshot",score:-0.0327,samples:277,blocked:false});
|
||||
@@ -1769,7 +1769,8 @@ function historicalOpportunityPrior(s){
|
||||
const score=rows.reduce((sum,row)=>sum+row.score,0)/rows.length;
|
||||
const samples=Math.max(...rows.map(row=>row.samples)),confidence=samples/(samples+200);
|
||||
return {score:+score.toFixed(4),confidence:+confidence.toFixed(3),
|
||||
multiplier:+clamp(1+score*confidence*2.5,0.82,1).toFixed(3),blocked:rows.some(row=>row.blocked),features:rows.map(row=>row.feature)};
|
||||
multiplier:+clamp(1+score*confidence*2.5,0.82,1).toFixed(3),blocked:rows.some(row=>row.blocked),
|
||||
hardBlocked:rows.some(row=>row.hardBlocked),features:rows.map(row=>row.feature)};
|
||||
}
|
||||
function learnedOpportunity(cfg,p,s,profile=null,calibration=null){
|
||||
const model=profile||buildAdaptiveProfile(p),features=learningFeatures(s),rows=features.map(k=>model.buckets[k]).filter(Boolean);
|
||||
@@ -1785,7 +1786,7 @@ function learnedOpportunity(cfg,p,s,profile=null,calibration=null){
|
||||
const personalEvidence=personalPromoted?positiveRows.reduce((sum,r)=>sum+Number(r.lower_bound||0),0)/positiveRows.length
|
||||
:(personalBlocked?negativeRows.reduce((sum,r)=>sum+Number(r.upper_bound||0),0)/negativeRows.length:score*0.10);
|
||||
const blockedBy=historical.blocked?"historical":(personalBlocked?"personal":(!market.allowed?"walk-forward":null));
|
||||
const blocked=Boolean(blockedBy)&&!exploration;
|
||||
const blocked=Boolean(blockedBy)&&(historical.hardBlocked||!exploration);
|
||||
return {score:+score.toFixed(4),confidence:+confidence.toFixed(3),market_score:market.score,market_confidence:market.confidence,
|
||||
personal_state:personalPromoted?"promoted":(personalBlocked?"demoted":"observing"),market_state:market.state,
|
||||
historical_score:historical.score,historical_confidence:historical.confidence,historical_features:historical.features,
|
||||
@@ -2190,7 +2191,8 @@ function agentAcceptsSuggestion(cfg,s){
|
||||
&&edge>=MIN_LIQUIDITY_EDGE&&evidence>=0.50;
|
||||
if(cfg.id==="catalyst")return ["catalyst","confirmed"].includes(quality)&&edge>=MIN_SELECTIVE_ENTRY_EDGE
|
||||
&&Number(s.evidence_source_count||0)>=1&&Number(s.signal_confidence||0)>=0.62;
|
||||
if(cfg.id==="reversal")return ["reversal","confirmed"].includes(quality)&&s.signal_type==="reversal"
|
||||
if(cfg.id==="reversal")return ["confirmed","trend","liquid-trend"].includes(quality)&&s.signal_type==="trend"
|
||||
&&Math.abs(Number(s.price_change_1d||0))<=0.04&&Number(s.days_to_resolution||0)>=21
|
||||
&&edge>=MIN_LIQUIDITY_EDGE&&Number(s.signal_confidence||0)>=0.64;
|
||||
if(cfg.id==="breakout")return ["confirmed","trend","liquid-trend","catalyst"].includes(quality)
|
||||
&&s.signal_type==="trend"&&edge>=MIN_TREND_EDGE&&Number(s.signal_strength||0)>=0.64&&evidence>=0.48;
|
||||
@@ -2675,7 +2677,7 @@ function decisionSummary(p){
|
||||
const blockerRows=Object.entries(d.rejectionCounts||{}).filter(([,count])=>count>0).sort((a,b)=>b[1]-a[1]);
|
||||
const blockers=blockerRows.length?` Blocks: ${blockerRows.slice(0,4).map(([key,count])=>`${blockerLabels[key]||key} ${count}`).join(", ")}.`:"";
|
||||
const learning=d.learning?` Learning: ${d.learning.samples} completed trades retained with older strategies down-weighted, ${(d.learning.global_score*100).toFixed(2)}% shrunk expectancy; ${d.learning.current_samples||0} completed under adaptive strategy ${SUGGESTION_ENGINE_VERSION}${d.learning.best?`; strongest ${d.learning.best.feature.replace(":"," ")}`:""}${d.learning.worst?`; weakest ${d.learning.worst.feature.replace(":"," ")}`:""}.`:"";
|
||||
const calibration=d.marketLearning?` Walk-forward calibration: ${d.marketLearning.samples||0} net-of-cost graded signals (${d.marketLearning.current_samples||0} under adaptive strategy ${SUGGESTION_ENGINE_VERSION}), ${d.marketLearning.pending||0} awaiting a future price${d.marketLearning.expired_ungraded?`, ${d.marketLearning.expired_ungraded} expired ungraded`:""}; ${d.marketLearning.promoted_buckets||0} feature cohorts promoted and ${d.marketLearning.demoted_buckets||0} demoted. Matured markets are repriced even after leaving the active scan. Confidence counts independent outcomes once and uncertainty gates sizing. Historical prior: reversal and sports-trend entries require the fixed 15% exploration lane; crypto, longshots, and YES entries are sized down, not forbidden. Politics trends receive 72 hours before ordinary signal exits.`:"";
|
||||
const calibration=d.marketLearning?` Walk-forward calibration: ${d.marketLearning.samples||0} net-of-cost signals graded after ${SIGNAL_EVAL_HOURS} hours (${d.marketLearning.current_samples||0} under adaptive strategy ${SUGGESTION_ENGINE_VERSION}), ${d.marketLearning.pending||0} awaiting a future price${d.marketLearning.expired_ungraded?`, ${d.marketLearning.expired_ungraded} expired ungraded`:""}; ${d.marketLearning.promoted_buckets||0} feature cohorts promoted and ${d.marketLearning.demoted_buckets||0} demoted. Matured markets are repriced even after leaving the active scan. Confidence counts independent outcomes once and uncertainty gates sizing. Historical prior: reversal and NO entries with 21 days or less are disabled; sports trends require the fixed exploration lane; crypto, longshots, and YES entries are sized down. Politics trends receive 72 hours before ordinary signal exits.`:"";
|
||||
return `${d.mode} mode: ${d.reason}${emotion} Limits now: ${d.maxNew} new trade${d.maxNew===1?"":"s"}, max ${(d.maxFrac*100).toFixed(1)}% per position${d.minConv?`, conviction ${d.minConv}+`:""}.${learning}${calibration}${exposure}${allocation}${candidates}${blockers}`;
|
||||
}
|
||||
function renderAgentBrief(cfg,p,st){
|
||||
@@ -2986,7 +2988,7 @@ function agentCompetitionPlan(cfg,row,rank,leader){
|
||||
if(cfg.id==="longshot")return "Plan: keep risk small but search for one underpriced outsider that can reprice sharply and leapfrog the leaderboard.";
|
||||
if(cfg.id==="diversifier")return "Plan: spread bets broadly, reduce single-market damage, and try to win through consistency rather than one heroic call.";
|
||||
if(cfg.id==="catalyst")return "Plan: deploy quickly when fresh real-world context and measured edge align, then concentrate enough capital for a catalyst repricing to move the account.";
|
||||
if(cfg.id==="reversal")return "Plan: attack overextended one-day moves from the opposite side, looking for liquid mean-reversion setups with enough evidence to justify the contrarian risk.";
|
||||
if(cfg.id==="reversal")return "Plan: hold confirmed, non-chased trends long enough to develop, favoring Politics or Economy markets with at least three weeks left instead of repeating the reversal rule that failed the audit.";
|
||||
if(cfg.id==="breakout")return "Plan: enter only confirmed momentum setups and press the cleanest breakouts where direction, activity, and signal margin agree.";
|
||||
if(cfg.id==="tailalpha")return "Plan: hunt underpriced low-cost contracts with asymmetric upside, accepting a volatile hit rate while keeping each tail position survivable.";
|
||||
if(cfg.id==="conviction")return "Plan: ignore marginal trades and commit the largest allowed stakes to a compact book of the strongest edge-and-evidence combinations.";
|
||||
@@ -3117,7 +3119,7 @@ function agentVoice(cfg){
|
||||
longshot:{tone:"opportunistic but risk-aware",hello:"I hunt asymmetric mispricing, but I keep the bet size honest.",signoff:"One repricing can matter, but only if I survive the misses."},
|
||||
diversifier:{tone:"calm, portfolio-minded, and broad",hello:"I care about the whole basket more than one perfect call.",signoff:"Many small edges can beat one loud opinion."},
|
||||
catalyst:{tone:"urgent, evidence-driven, and decisive",hello:"I am hunting the next event that can force a fast repricing.",signoff:"A catalyst only matters when the numbers agree."},
|
||||
reversal:{tone:"contrarian, sharp, and skeptical",hello:"I am looking for a crowd move that has gone too far.",signoff:"The best snapbacks begin where consensus gets stretched."},
|
||||
reversal:{tone:"patient, evidence-led, and persistent",hello:"I am looking for a confirmed trend with enough time to develop.",signoff:"I want durable direction, not a reflexive snapback bet."},
|
||||
breakout:{tone:"fast, aggressive, and momentum-led",hello:"I am scanning for direction that is strengthening right now.",signoff:"I press confirmed speed and cut failed momentum."},
|
||||
tailalpha:{tone:"bold, asymmetric, and probability-aware",hello:"I am searching for cheap contracts with mispriced upside.",signoff:"A low hit rate can work when the payoff is truly asymmetric."},
|
||||
conviction:{tone:"concentrated, demanding, and direct",hello:"I only want the few trades strong enough to deserve real weight.",signoff:"When evidence and edge align, I size with conviction."},
|
||||
@@ -4248,10 +4250,10 @@ window.PMA_ENGINE_DIAGNOSTICS=Object.freeze({
|
||||
coreGapTradeLossPct:MAX_CORE_GAP_TRADE_LOSS_PCT*100,aggressiveGapTradeLossPct:MAX_AGGRESSIVE_GAP_TRADE_LOSS_PCT*100,
|
||||
offlineEntryMaxAgeMinutes:OFFLINE_ENTRY_MAX_AGE_MS/60000,offlineCacheMaxAgeHours:OFFLINE_CACHE_MAX_AGE_MS/3600000,explorationPct:15,
|
||||
networkTimeoutSeconds:NETWORK_REQUEST_TIMEOUT_MS/1000,priceTimeoutSeconds:PRICE_REQUEST_TIMEOUT_MS/1000,
|
||||
staleCacheIsMarkOnly:true,strategyEvidenceSurvivesBuilds:true,signalRetryHours:SIGNAL_LEDGER_RETRY_HOURS,
|
||||
staleCacheIsMarkOnly:true,strategyEvidenceSurvivesBuilds:true,signalEvaluationHours:SIGNAL_EVAL_HOURS,signalRetryHours:SIGNAL_LEDGER_RETRY_HOURS,
|
||||
signalDueFetchLimit:SIGNAL_LEDGER_DUE_FETCH_LIMIT,survivorshipSafeSignalGrading:true,
|
||||
signalRoundTripCostCents:SIGNAL_ROUND_TRIP_COST*100,independentConfidence:true,uncertaintyGatedCalibration:true,
|
||||
historicalPrior:"reversal and sports trends blocked outside exploration; crypto, longshots, and YES sized down"}),
|
||||
historicalPrior:"reversal and short-dated NO entries disabled; sports trends blocked outside exploration; crypto, longshots, and YES sized down"}),
|
||||
});
|
||||
function runEngineSelfTest(){
|
||||
const market=(overrides={})=>Object.assign({
|
||||
@@ -4293,13 +4295,18 @@ function runEngineSelfTest(){
|
||||
while(stableExploration(AGENTS[0].id,sportsPriorId))sportsPriorId=`prior-sports-${++sportsPriorIndex}`;
|
||||
const priorSportsTrend=learnedOpportunity(AGENTS[0],defaultPortfolio(),{market_id:sportsPriorId,signal_type:"trend",quality:"confirmed",category:"Sports",side:"NO",entry_price:0.58});
|
||||
const priorPoliticsTrend=historicalOpportunityPrior({signal_type:"trend",category:"Politics",side:"NO",entry_price:0.58});
|
||||
const ledgerState={signal_ledger:{pending:[{key:"ledger-test",market_id:"ledger-test",observed_at:hoursAgo(13),side:"YES",entry_price:0.40,
|
||||
const shortNoPrior=learnedOpportunity(AGENTS[0],defaultPortfolio(),{market_id:"short-no",signal_type:"trend",quality:"confirmed",category:"Politics",side:"NO",entry_price:0.58,days_to_resolution:14});
|
||||
const longNoPrior=historicalOpportunityPrior({signal_type:"trend",category:"Politics",side:"NO",entry_price:0.58,days_to_resolution:30});
|
||||
const ledgerState={signal_ledger:{pending:[{key:"ledger-test",market_id:"ledger-test",observed_at:hoursAgo(25),side:"YES",entry_price:0.40,
|
||||
signal_type:"trend",quality:"confirmed",category:"Politics"}],outcomes:[]}};
|
||||
updateSignalLedger(ledgerState,[market({id:"ledger-test",yes_price:0.50,no_price:0.50})],[]);
|
||||
const earlyLedgerState={signal_ledger:{pending:[{key:"ledger-early",market_id:"ledger-early",observed_at:hoursAgo(13),side:"YES",entry_price:0.40,
|
||||
signal_type:"trend",quality:"confirmed",category:"Politics"}],outcomes:[]}};
|
||||
updateSignalLedger(earlyLedgerState,[market({id:"ledger-early",yes_price:0.50,no_price:0.50})],[]);
|
||||
const dueFetchLedger={pending:[
|
||||
{key:"known",market_id:"known-active",observed_at:hoursAgo(13)},
|
||||
{key:"outside-a",market_id:"outside-active-scan",observed_at:hoursAgo(14)},
|
||||
{key:"outside-b",market_id:"outside-active-scan",observed_at:hoursAgo(13)},
|
||||
{key:"known",market_id:"known-active",observed_at:hoursAgo(25)},
|
||||
{key:"outside-a",market_id:"outside-active-scan",observed_at:hoursAgo(26)},
|
||||
{key:"outside-b",market_id:"outside-active-scan",observed_at:hoursAgo(25)},
|
||||
{key:"young",market_id:"too-young",observed_at:hoursAgo(2)}],outcomes:[]};
|
||||
const dueFetchIds=pendingSignalMarketIds(dueFetchLedger,new Set(["known-active"]));
|
||||
const retryLedgerState={signal_ledger:{pending:[{key:"retry",market_id:"temporarily-unavailable",observed_at:hoursAgo(100),side:"YES",entry_price:0.4}],outcomes:[]}};
|
||||
@@ -4314,7 +4321,7 @@ function runEngineSelfTest(){
|
||||
const stableNegativeCalibration=calibratedOpportunity(calibrationCandidate,calibrationFromReturns(Array(24).fill(-0.12)));
|
||||
const noisyCalibration=calibratedOpportunity(calibrationCandidate,calibrationFromReturns(Array.from({length:24},(_,i)=>i%2?0.12:-0.12)));
|
||||
const legacyBuildCalibration=buildSignalCalibration({pending:[],outcomes:[Object.assign({},calibrationCandidate,
|
||||
{strategy_version:41,return:0.10,evaluated_at:closedAt})]});
|
||||
{strategy_version:PREVIOUS_STRATEGY_VERSION,return:0.10,evaluated_at:closedAt})]});
|
||||
const currentStrategyCalibration=buildSignalCalibration({pending:[],outcomes:[Object.assign({},calibrationCandidate,
|
||||
{strategy_version:SUGGESTION_ENGINE_VERSION,return:0.10,evaluated_at:closedAt})]});
|
||||
const lossLearner=defaultPortfolio();
|
||||
@@ -4351,6 +4358,7 @@ function runEngineSelfTest(){
|
||||
explorationOwners=AGENTS.filter(a=>stableExploration(a.id,explorationMarketId));
|
||||
if(!explorationOwners.length)explorationMarketId=`single-explorer-${++explorationIndex}`;
|
||||
}
|
||||
const explorerReversal=learnedOpportunity(explorationOwners[0],defaultPortfolio(),{market_id:explorationMarketId,signal_type:"reversal",quality:"reversal",category:"Politics",side:"NO",entry_price:0.42});
|
||||
mock.agents.tailalpha.positions.push({market_id:"runner-test",question:"Runner test",side:"YES",shares:100,current_price:0.5,entry_price:0.5,cost:50,value:50,unrealized_pnl:0,conviction:70,opened_at:hoursAgo(24)});
|
||||
const immaterialRunnerDoesNotBlock=!occupiedStrategyMarkets(mock).has("runner-test");
|
||||
const rejectBook=defaultPortfolio();rejectBook.cash=9900;
|
||||
@@ -4370,11 +4378,11 @@ function runEngineSelfTest(){
|
||||
delete executableBook.positions[0].price_status;
|
||||
markToMarket(executableBook,{"offline-mark":market({id:"offline-mark",yes_price:0.8,no_price:0.2})},AGENTS[0],{policyExits:true,executeTrades:true});
|
||||
const buildMigrationState=defaultState();
|
||||
buildMigrationState.engine_version=43;buildMigrationState.strategy_version=SUGGESTION_ENGINE_VERSION;
|
||||
buildMigrationState.engine_version=44;buildMigrationState.strategy_version=SUGGESTION_ENGINE_VERSION;
|
||||
buildMigrationState.agents.value.engine_baseline={version:SUGGESTION_ENGINE_VERSION,started_at:hoursAgo(2),equity:9876.54};
|
||||
reconcileStateVersions(buildMigrationState);
|
||||
const strategyMigrationState=defaultState();
|
||||
strategyMigrationState.engine_version=43;strategyMigrationState.strategy_version=PREVIOUS_STRATEGY_VERSION;
|
||||
strategyMigrationState.engine_version=44;strategyMigrationState.strategy_version=PREVIOUS_STRATEGY_VERSION;
|
||||
strategyMigrationState.agents.value.cash=9876.54;
|
||||
strategyMigrationState.agents.value.engine_baseline={version:PREVIOUS_STRATEGY_VERSION,started_at:hoursAgo(2),equity:10000};
|
||||
reconcileStateVersions(strategyMigrationState);
|
||||
@@ -4386,16 +4394,21 @@ function runEngineSelfTest(){
|
||||
adaptation:{samples:learningProfile.samples,trendMultiplier:learnedTrend.multiplier,reversalMultiplier:learnedReversal.multiplier,learnsDirection:learnedTrend.multiplier>learnedReversal.multiplier,
|
||||
calibrationSamples:calibrationProfile.samples,trendMarketScore:learnedTrend.market_score,reversalMarketScore:learnedReversal.market_score,
|
||||
historicalPriorBlocksReversal:!priorReversal.allowed&&priorReversal.blocked_by==="historical",
|
||||
reversalRemainsBlockedForExplorer:!explorerReversal.allowed&&explorerReversal.blocked_by==="historical",
|
||||
enduranceReplacesReversal:agentAcceptsSuggestion(AGENTS.find(a=>a.id==="reversal"),trend)&&!agentAcceptsSuggestion(AGENTS.find(a=>a.id==="reversal"),reversal),
|
||||
historicalPriorSizesRisk:!priorCryptoLongshot.blocked&&priorCryptoLongshot.multiplier<1&&priorCryptoLongshot.features.length===2,
|
||||
historicalPriorBlocksSportsTrend:!priorSportsTrend.allowed&&priorSportsTrend.blocked_by==="historical",
|
||||
historicalPriorAllowsPoliticsTrend:!priorPoliticsTrend.blocked,
|
||||
blocksShortDatedNo:!shortNoPrior.allowed&&shortNoPrior.blocked_by==="historical",
|
||||
allowsLongDatedNo:!longNoPrior.blocked,
|
||||
ledgerMaturesWithoutLookahead:ledgerState.signal_ledger.pending.length===0&&ledgerState.signal_ledger.outcomes.length===1&&ledgerState.signal_ledger.outcomes[0].return===0.2375,
|
||||
holdsSignalsUntilPolicyHorizon:earlyLedgerState.signal_ledger.pending.length===1&&earlyLedgerState.signal_ledger.outcomes.length===0,
|
||||
fetchesMaturedMarketsOutsideActiveScan:dueFetchIds.length===1&&dueFetchIds[0]==="outside-active-scan",
|
||||
keepsUnavailableGradesQueued:retryLedgerState.signal_ledger.pending.length===1&&retryLedgerState.signal_ledger.outcomes.length===0,
|
||||
expiresOnlyAfterRetryWindow:expiredLedgerState.signal_ledger.pending.length===0&&expiredLedgerState.signal_ledger.expired_ungraded===1,
|
||||
ledgerIsNetOfCosts:ledgerState.signal_ledger.outcomes[0].gross_return===0.25&&ledgerState.signal_ledger.outcomes[0].estimated_cost_return===0.0125,
|
||||
independentCalibrationConfidence:singleCalibration.confidence<0.06,
|
||||
legacyBuildMapsToPreviousStrategy:normalizedStrategyVersion(41)===PREVIOUS_STRATEGY_VERSION,
|
||||
legacyBuildLineageRemainsHistorical:normalizedStrategyVersion(41)===40,
|
||||
previousStrategyIsDownWeighted:legacyBuildCalibration.current_samples===0&&legacyBuildCalibration.buckets["signal:trend"].weight>0.54&&legacyBuildCalibration.buckets["signal:trend"].weight<=0.55,
|
||||
currentStrategyKeepsFullWeight:currentStrategyCalibration.current_samples===1&¤tStrategyCalibration.buckets["signal:trend"].weight>0.99,
|
||||
baselineSurvivesBuildMigration:buildMigrationState.agents.value.engine_baseline.equity===9876.54&&buildMigrationState.agents.value.engine_baseline.version===SUGGESTION_ENGINE_VERSION,
|
||||
|
||||
Reference in New Issue
Block a user