Diversify verified bundle search by event

This commit is contained in:
Theodore Song
2026-08-22 08:22:47 -04:00
parent a6c9fc1a14
commit 7ae2d6bdfc
5 changed files with 74 additions and 10 deletions
+9 -3
View File
@@ -67,7 +67,9 @@ Each Build 121 cycle also scans the 1,000 most-active Polymarket events for
complete negative-risk bundles and logically nested threshold or deadline complete negative-risk bundles and logically nested threshold or deadline
pairs. Gamma's market-specific fee flag replaces the old blanket 0.5-cent fee pairs. Gamma's market-specific fee flag replaces the old blanket 0.5-cent fee
reserve for markets declared fee-free. The closest 60 structures are then reserve for markets declared fee-free. The closest 60 structures are then
repriced from batched CLOB asks from the equal-unit size needed for at least a $50 ranked by locked-capital efficiency, with the best structure from each independent
event checked before alternates from events already represented. They are repriced
from batched CLOB asks from the equal-unit size needed for at least a $50
paper order up to a $400 verified-notional ceiling. The scanner applies each market's Gamma fee schedule at every paper order up to a $400 verified-notional ceiling. The scanner applies each market's Gamma fee schedule at every
consumed ask level and checks the CLOB fee-rate endpoint for a matching enabled consumed ask level and checks the CLOB fee-rate endpoint for a matching enabled
or fee-free state. Any opened position is capped to the exact equal-unit size or fee-free state. Any opened position is capped to the exact equal-unit size
@@ -102,8 +104,12 @@ favorite trends all had 90% upper bounds below zero at 12 hours. A separate
rules and found zero robust positive rule. Strategy 64 retains online rules and found zero robust positive rule. Strategy 64 retains online
directional evidence under fee policy 2. A separate probation gate can now use directional evidence under fee policy 2. A separate probation gate can now use
capital after at least 12 current-policy independent events produce a net-of-cost capital after at least 12 current-policy independent events produce a net-of-cost
six-hour lower confidence bound above 1% for every required cohort feature. It six-hour lower confidence bound above 1% for every required cohort feature.
uses at most 0.5% of equity per position, 1% per-agent total capital, one new The corresponding 500-market, 1,920-rule chronological audit selected zero
rules in validation at 6, 24, or 72 hours. No directional rule is preapproved;
probation and full sizing must be earned from new event-deduplicated forward
observations. Probation uses at most 0.5% of equity per position, 1% per-agent
total capital, one new
position per agent cycle, and one owner per Polymarket event across all agents. position per agent cycle, and one owner per Polymarket event across all agents.
Every probation position exits at the matching six-hour executable bid and keeps Every probation position exits at the matching six-hour executable bid and keeps
the 18% stop policy active. Normal directional sizing remains locked until the the 18% stop policy active. Normal directional sizing remains locked until the
+19 -2
View File
@@ -1320,6 +1320,15 @@ function compareBundleOpportunities(a,b){
||Number(b.net_edge||-Infinity)-Number(a.net_edge||-Infinity) ||Number(b.net_edge||-Infinity)-Number(a.net_edge||-Infinity)
||Number(b.bundle_net_profit_per_unit||-Infinity)-Number(a.bundle_net_profit_per_unit||-Infinity); ||Number(b.bundle_net_profit_per_unit||-Infinity)-Number(a.bundle_net_profit_per_unit||-Infinity);
} }
function prioritizeIndependentBundles(candidates,limit=Infinity){
const ranked=(candidates||[]).slice().sort(compareBundleOpportunities),firstByEvent=[],alternates=[],seenEvents=new Set();
ranked.forEach(candidate=>{
const eventKey=bundleEventKey(candidate)||String(candidate.bundle_id||candidate.market_id||"");
if(eventKey&&!seenEvents.has(eventKey)){seenEvents.add(eventKey);firstByEvent.push(candidate);}
else alternates.push(candidate);
});
return [...firstByEvent,...alternates].slice(0,Math.max(0,Number(limit)||0));
}
function bundleEventExposure(portfolio,eventKey){ function bundleEventExposure(portfolio,eventKey){
const key=String(eventKey||"");if(!key)return 0; const key=String(eventKey||"");if(!key)return 0;
return (portfolio&&portfolio.positions||[]).filter(pos=>pos.requires_complete_bundle&&bundleEventKey(pos)===key) return (portfolio&&portfolio.positions||[]).filter(pos=>pos.requires_complete_bundle&&bundleEventKey(pos)===key)
@@ -1367,7 +1376,7 @@ async function fetchBundleFeeRates(tokenIds){
await Promise.all(workers);return results; await Promise.all(workers);return results;
} }
async function verifyExecutableBundles(candidates){ async function verifyExecutableBundles(candidates){
const shortlist=(candidates||[]).slice().sort(compareBundleOpportunities).slice(0,BUNDLE_DEPTH_CANDIDATE_LIMIT); const shortlist=prioritizeIndependentBundles(candidates,BUNDLE_DEPTH_CANDIDATE_LIMIT);
const tokenIds=shortlist.flatMap(candidate=>(candidate.bundle_legs||[]).map(leg=>leg.token_id)); const tokenIds=shortlist.flatMap(candidate=>(candidate.bundle_legs||[]).map(leg=>leg.token_id));
const books=await fetchBundleBooks(tokenIds),depthChecked=shortlist.map(candidate=>{ const books=await fetchBundleBooks(tokenIds),depthChecked=shortlist.map(candidate=>{
const estimatedCost=Number(candidate.bundle_cost_per_unit),requiredUnits=bundleMinimumExecutionUnits(Math.max(estimatedCost,0.01)); const estimatedCost=Number(candidate.bundle_cost_per_unit),requiredUnits=bundleMinimumExecutionUnits(Math.max(estimatedCost,0.01));
@@ -1421,10 +1430,12 @@ async function fetchNegativeRiskBundles(limit=NEG_RISK_EVENT_SCAN_LIMIT){
const candidates=executableAudit.filter(candidate=>candidate.opportunity_actionable); const candidates=executableAudit.filter(candidate=>candidate.opportunity_actionable);
const seen=new Set(); const seen=new Set();
const unique=candidates.filter(candidate=>{const id=String(candidate.bundle_id||candidate.market_id);if(!id||seen.has(id))return false;seen.add(id);return true;}); const unique=candidates.filter(candidate=>{const id=String(candidate.bundle_id||candidate.market_id);if(!id||seen.has(id))return false;seen.add(id);return true;});
const prioritized=prioritizeIndependentBundles(unique,20);
const closest=executableAudit.find(candidate=>candidate.depth_verified)||executableAudit[0]||null; const closest=executableAudit.find(candidate=>candidate.depth_verified)||executableAudit[0]||null;
return {candidates:unique.slice(0,20),audit:{status:"ok",scanned_at:nowIso(),event_scan_limit:limit,events_scanned:events.length, return {candidates:prioritized,audit:{status:"ok",scanned_at:nowIso(),event_scan_limit:limit,events_scanned:events.length,
evaluated_structures:audited.length,depth_checked_structures:executableAudit.length,depth_verified_structures:executableAudit.filter(candidate=>candidate.depth_verified).length, evaluated_structures:audited.length,depth_checked_structures:executableAudit.length,depth_verified_structures:executableAudit.filter(candidate=>candidate.depth_verified).length,
fee_verified_structures:executableAudit.filter(candidate=>candidate.fees_verified).length,actionable_bundles:unique.length, fee_verified_structures:executableAudit.filter(candidate=>candidate.fees_verified).length,actionable_bundles:unique.length,
actionable_events:new Set(unique.map(bundleEventKey).filter(Boolean)).size,returned_events:new Set(prioritized.map(bundleEventKey).filter(Boolean)).size,
closest_margin_cents:closest?+(Number(closest.bundle_net_profit_per_unit)*100).toFixed(2):null, closest_margin_cents:closest?+(Number(closest.bundle_net_profit_per_unit)*100).toFixed(2):null,
closest_return_pct:closest?+(Number(closest.net_edge)*100).toFixed(3):null, closest_return_pct:closest?+(Number(closest.net_edge)*100).toFixed(3):null,
closest_title:closest?closest.question:null,closest_url:closest?closest.url:null}}; closest_title:closest?closest.question:null,closest_url:closest?closest.url:null}};
@@ -7215,6 +7226,11 @@ function runEngineSelfTest(){
Object.assign({},dominanceSuggestion,{bundle_id:"dominance:slow-event:a:b",bundle_event_id:"slow-event",net_edge:0.03,days_to_resolution:30}), Object.assign({},dominanceSuggestion,{bundle_id:"dominance:slow-event:a:b",bundle_event_id:"slow-event",net_edge:0.03,days_to_resolution:30}),
Object.assign({},dominanceSuggestion,{bundle_id:"dominance:fast-event:a:b",bundle_event_id:"fast-event",net_edge:0.02,days_to_resolution:5}), Object.assign({},dominanceSuggestion,{bundle_id:"dominance:fast-event:a:b",bundle_event_id:"fast-event",net_edge:0.02,days_to_resolution:5}),
].sort(compareBundleOpportunities); ].sort(compareBundleOpportunities);
const independentBundleOrder=prioritizeIndependentBundles([
Object.assign({},dominanceSuggestion,{bundle_id:"dominance:event-a:a:b",bundle_event_id:"event-a",net_edge:0.05,days_to_resolution:5}),
Object.assign({},dominanceSuggestion,{bundle_id:"dominance:event-a:c:d",bundle_event_id:"event-a",net_edge:0.04,days_to_resolution:5}),
Object.assign({},dominanceSuggestion,{bundle_id:"dominance:event-b:a:b",bundle_event_id:"event-b",net_edge:0.02,days_to_resolution:5}),
],3);
const eventCapBook=defaultPortfolio(); const eventCapBook=defaultPortfolio();
eventCapBook.cash=8800; eventCapBook.cash=8800;
eventCapBook.positions=[ eventCapBook.positions=[
@@ -7734,6 +7750,7 @@ function runEngineSelfTest(){
}, },
bundleArbitrage:{ bundleArbitrage:{
prioritizesReturnPerLockedDay:capitalEfficiencyOrder[0].bundle_event_id==="fast-event", prioritizesReturnPerLockedDay:capitalEfficiencyOrder[0].bundle_event_id==="fast-event",
prioritizesIndependentEventsBeforeAlternates:independentBundleOrder.map(row=>row.bundle_event_id).join(",")==="event-a,event-b,event-a",
derivesLegacyBundleEventKey:bundleEventKey({bundle_id:"dominance:legacy-event:market-a:market-b"})==="legacy-event", derivesLegacyBundleEventKey:bundleEventKey({bundle_id:"dominance:legacy-event:market-a:market-b"})==="legacy-event",
capsUnderlyingEventExposure:eventCapBook.positions.length===2&&eventCapBook.lastDecision.rejectionCounts.bundle_event_cap===1, capsUnderlyingEventExposure:eventCapBook.positions.length===2&&eventCapBook.lastDecision.rejectionCounts.bundle_event_cap===1,
blocksLowReturnPerLockedDay:slowCapitalBook.positions.length===0&&slowCapitalBook.lastDecision.rejectionCounts.bundle_capital_efficiency===1, blocksLowReturnPerLockedDay:slowCapitalBook.positions.length===0&&slowCapitalBook.lastDecision.rejectionCounts.bundle_capital_efficiency===1,
+31
View File
@@ -0,0 +1,31 @@
{
"strategy": 64,
"generated_at": "2026-08-22T12:17:23.498Z",
"requested_markets": 500,
"fetched_markets": 500,
"histories_with_data": 500,
"failures": 0,
"observations": 6115,
"methodology": {
"cost_cents": 0.5,
"observation_spacing_hours": 12,
"split": "60% train / 20% validation / 20% untouched holdout",
"cluster_unit": "Polymarket event",
"candidate_rules": 1920,
"promotion_gate": "Positive event-clustered 90% lower bound with minimum support in train, validation, and holdout"
},
"probation_rule_ids": [],
"durable_rule_ids": [],
"horizons": [
{"hours": 6, "train_rows": 3640, "validation_rows": 1226, "test_rows": 1223, "validation_selected": 0, "holdout_passed": 0},
{"hours": 24, "train_rows": 3482, "validation_rows": 875, "test_rows": 1223, "validation_selected": 0, "holdout_passed": 0},
{"hours": 72, "train_rows": 3043, "validation_rows": 215, "test_rows": 1223, "validation_selected": 0, "holdout_passed": 0}
],
"production_decision": {
"preapproved_directional_rules": [],
"six_hour_probation_requires_new_forward_evidence": true,
"full_directional_promotion_requires_new_forward_evidence": true,
"note": "No tested directional rule survived validation at any horizon. This active-market audit can still contain survivorship bias, so it cannot justify relaxing the live evidence gates."
},
"reproduce": "ADAPTIVE_MARKETS=500 ADAPTIVE_CONCURRENCY=12 npm run evaluate:adaptive"
}
+7 -5
View File
@@ -103,7 +103,7 @@ function observations(market, points) {
} }
if (!complete) continue; if (!complete) continue;
const future = {}; const future = {};
for (const hours of [24, 72]) { for (const hours of [6, 24, 72]) {
const next = atOrAfter(points, current.t + hours * HOUR); const next = atOrAfter(points, current.t + hours * HOUR);
if (next && next.t - (current.t + hours * HOUR) <= 3 * HOUR) future[hours] = next.p; if (next && next.t - (current.t + hours * HOUR) <= 3 * HOUR) future[hours] = next.p;
} }
@@ -203,11 +203,13 @@ function evaluateHorizon(horizon) {
} }
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 horizons = [24, 72].map(evaluateHorizon).map((result) => ({ ...result, const horizons = [6, 24, 72].map(evaluateHorizon).map((result) => ({ ...result,
candidates: result.candidates.map((candidate) => ({ rule: candidate.rule, passesHoldout: candidate.passesHoldout, candidates: result.candidates.map((candidate) => ({ rule: candidate.rule, passesHoldout: candidate.passesHoldout,
train: compact(candidate.train), validation: compact(candidate.validation), test: compact(candidate.test) })) })); train: compact(candidate.train), validation: compact(candidate.validation), test: compact(candidate.test) })) }));
const passedByHorizon = horizons.map((result) => new Set(result.candidates.filter((candidate) => candidate.passesHoldout).map((candidate) => candidate.rule.id))); const passedByHorizon = Object.fromEntries(horizons.map((result) => [result.horizon,
const durableRuleIds = [...passedByHorizon[0]].filter((id) => passedByHorizon[1].has(id)); new Set(result.candidates.filter((candidate) => candidate.passesHoldout).map((candidate) => candidate.rule.id))]));
const probationRuleIds = [...passedByHorizon[6]];
const durableRuleIds = [...passedByHorizon[24]].filter((id) => passedByHorizon[72].has(id));
console.log(JSON.stringify({ generatedAt: new Date().toISOString(), requestedMarkets: MARKET_LIMIT, fetchedMarkets: markets.length, console.log(JSON.stringify({ generatedAt: new Date().toISOString(), requestedMarkets: MARKET_LIMIT, fetchedMarkets: markets.length,
historiesWithData: histories.filter((result) => result && !result.error && result.points).length, historiesWithData: histories.filter((result) => result && !result.error && result.points).length,
@@ -215,4 +217,4 @@ console.log(JSON.stringify({ generatedAt: new Date().toISOString(), requestedMar
methodology: { costCents: COST * 100, observationSpacingHours: 12, split: "60% train / 20% validation / 20% untouched holdout", methodology: { costCents: COST * 100, observationSpacingHours: 12, split: "60% train / 20% validation / 20% untouched holdout",
clusterUnit: "Polymarket event", candidateRules: rules.length, clusterUnit: "Polymarket event", candidateRules: rules.length,
promotionGate: "positive event-clustered 90% lower bound with minimum support in train, validation, and holdout" }, promotionGate: "positive event-clustered 90% lower bound with minimum support in train, validation, and holdout" },
durableRuleIds, horizons }, null, 2)); probationRuleIds, durableRuleIds, horizons }, null, 2));
+8
View File
@@ -8,6 +8,7 @@ const workflow = fs.readFileSync(new URL("../.github/workflows/autonomous-cycle.
const runner = fs.readFileSync(new URL("./run-autonomous-cycle.mjs", import.meta.url), "utf8"); const runner = fs.readFileSync(new URL("./run-autonomous-cycle.mjs", import.meta.url), "utf8");
const resolutionAudit = JSON.parse(fs.readFileSync(new URL("../research/resolution-week-no-audit.json", import.meta.url), "utf8")); const resolutionAudit = JSON.parse(fs.readFileSync(new URL("../research/resolution-week-no-audit.json", import.meta.url), "utf8"));
const sportsContestAudit = JSON.parse(fs.readFileSync(new URL("../research/sports-contest-no-exploration-audit.json", import.meta.url), "utf8")); const sportsContestAudit = JSON.parse(fs.readFileSync(new URL("../research/sports-contest-no-exploration-audit.json", import.meta.url), "utf8"));
const adaptiveAudit = JSON.parse(fs.readFileSync(new URL("../research/adaptive-strategy-64-audit.json", import.meta.url), "utf8"));
const build = Number(index.match(/const BUILD_VERSION = (\d+);/)?.[1]); const build = Number(index.match(/const BUILD_VERSION = (\d+);/)?.[1]);
assert.equal(build, 121); assert.equal(build, 121);
@@ -79,6 +80,8 @@ assert.match(index, /const BUNDLE_MAX_VERIFIED_NOTIONAL=400;/);
assert.match(index, /const BUNDLE_EVENT_CAP_PCT=0\.12;/); assert.match(index, /const BUNDLE_EVENT_CAP_PCT=0\.12;/);
assert.match(index, /const BUNDLE_MIN_DAILY_RETURN=0\.0002;/); assert.match(index, /const BUNDLE_MIN_DAILY_RETURN=0\.0002;/);
assert.match(index, /function compareBundleOpportunities\(a,b\)/); assert.match(index, /function compareBundleOpportunities\(a,b\)/);
assert.match(index, /function prioritizeIndependentBundles\(candidates,limit=Infinity\)/);
assert.match(index, /prioritizesIndependentEventsBeforeAlternates:/);
assert.match(index, /function bundleEventExposure\(portfolio,eventKey\)/); assert.match(index, /function bundleEventExposure\(portfolio,eventKey\)/);
assert.match(index, /prioritizesReturnPerLockedDay:/); assert.match(index, /prioritizesReturnPerLockedDay:/);
assert.match(index, /capsUnderlyingEventExposure:/); assert.match(index, /capsUnderlyingEventExposure:/);
@@ -108,6 +111,11 @@ assert.ok(sportsContestAudit.corrected_5000_market_result.validation.lower_95 <
assert.equal(sportsContestAudit.production_constraints.initial_position_pct, 0.5); assert.equal(sportsContestAudit.production_constraints.initial_position_pct, 0.5);
assert.equal(sportsContestAudit.production_constraints.total_lane_cap_pct, 3); assert.equal(sportsContestAudit.production_constraints.total_lane_cap_pct, 3);
assert.equal(sportsContestAudit.production_constraints.exact_entry_fee_required, true); assert.equal(sportsContestAudit.production_constraints.exact_entry_fee_required, true);
assert.equal(adaptiveAudit.strategy, 64);
assert.equal(adaptiveAudit.fetched_markets, 500);
assert.deepEqual(adaptiveAudit.probation_rule_ids, []);
assert.deepEqual(adaptiveAudit.durable_rule_ids, []);
assert.ok(adaptiveAudit.horizons.every((row) => row.validation_selected === 0 && row.holdout_passed === 0));
assert.match(index, /function sportsContestKey\(m\)/); assert.match(index, /function sportsContestKey\(m\)/);
assert.match(index, /function sportsContestNoSuggestions\(markets\)/); assert.match(index, /function sportsContestNoSuggestions\(markets\)/);
assert.match(index, /const SPORTS_FAVORITE_MAX_NEW_PER_CYCLE=1;/); assert.match(index, /const SPORTS_FAVORITE_MAX_NEW_PER_CYCLE=1;/);