mirror of
https://github.com/theodore-song/polymarket-analyst.git
synced 2026-08-19 18:48:10 +00:00
Ignore tiny runners in agent overlap limits
This commit is contained in:
@@ -31,6 +31,8 @@ Engine v36 treats each binary stake as capable of falling to zero even when the
|
|||||||
aggressive positions at 3%-5%, with lower limits for near-term, extreme-price,
|
aggressive positions at 3%-5%, with lower limits for near-term, extreme-price,
|
||||||
reversal, and fast-moving setups. Oversized positions inherited from older
|
reversal, and fast-moving setups. Oversized positions inherited from older
|
||||||
engines are reduced to the same loss budget during live marking.
|
engines are reduced to the same loss budget during live marking.
|
||||||
|
The two-agent overlap guard counts only positions worth at least 1.25% of an
|
||||||
|
agent's equity, so tiny profit-lock runners do not block a new material trade.
|
||||||
|
|
||||||
A separate walk-forward ledger records each trade-ready signal before its future
|
A separate walk-forward ledger records each trade-ready signal before its future
|
||||||
price is known, grades it at least 12 hours later, and combines that broad market
|
price is known, grades it at least 12 hours later, and combines that broad market
|
||||||
|
|||||||
+12
-6
@@ -1967,6 +1967,7 @@ function peerMarketStats(st,selfId){
|
|||||||
const p=st.agents&&st.agents[a.id]; if(!p)return;
|
const p=st.agents&&st.agents[a.id]; if(!p)return;
|
||||||
const ret=(equity(p)/Math.max(p.starting_balance||STARTING_BALANCE,1)-1)*100;
|
const ret=(equity(p)/Math.max(p.starting_balance||STARTING_BALANCE,1)-1)*100;
|
||||||
(p.positions||[]).forEach(pos=>{
|
(p.positions||[]).forEach(pos=>{
|
||||||
|
if(!isMaterialPosition(p,pos))return;
|
||||||
const id=pos.market_id||pos.asset; if(!id)return;
|
const id=pos.market_id||pos.asset; if(!id)return;
|
||||||
const key=`${id}:${pos.side}`;
|
const key=`${id}:${pos.side}`;
|
||||||
const opp=`${id}:${pos.side==="YES"?"NO":"YES"}`;
|
const opp=`${id}:${pos.side==="YES"?"NO":"YES"}`;
|
||||||
@@ -1991,15 +1992,17 @@ function peerAdjustedSuggestion(s,peer){
|
|||||||
if(m.opposite&&m.oppositePnl>50){boost-=Math.min(12,4+m.opposite*2);peerNote=`peer warning: opposite-side holders are winning`;}
|
if(m.opposite&&m.oppositePnl>50){boost-=Math.min(12,4+m.opposite*2);peerNote=`peer warning: opposite-side holders are winning`;}
|
||||||
return Object.assign({},s,{peer_boost:boost,peer_note:peerNote,peer_conviction:+(Number(s.conviction||0)+boost).toFixed(1)});
|
return Object.assign({},s,{peer_boost:boost,peer_note:peerNote,peer_conviction:+(Number(s.conviction||0)+boost).toFixed(1)});
|
||||||
}
|
}
|
||||||
function addPortfolioMarketsToSet(set,p){
|
function materialPositionThreshold(p){return Math.max(50,equity(p)*0.0125);}
|
||||||
(p&&p.positions||[]).forEach(pos=>{const id=pos.market_id||pos.asset;if(id)set.add(String(id));});
|
function isMaterialPosition(p,pos){return Number(pos&&((pos.value!=null)?pos.value:Number(pos.shares||0)*Number(pos.current_price||0)))>=materialPositionThreshold(p);}
|
||||||
|
function addPortfolioMarketsToSet(set,p,{materialOnly=false}={}){
|
||||||
|
(p&&p.positions||[]).forEach(pos=>{const id=pos.market_id||pos.asset;if(id&&(!materialOnly||isMaterialPosition(p,pos)))set.add(String(id));});
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
function occupiedStrategyMarkets(st,selfId=null){
|
function occupiedStrategyMarkets(st,selfId=null){
|
||||||
const ids=new Set();
|
const ids=new Set();
|
||||||
AGENTS.filter(a=>a.kind==="strategy").forEach(a=>{
|
AGENTS.filter(a=>a.kind==="strategy").forEach(a=>{
|
||||||
if(a.id===selfId)return;
|
if(a.id===selfId)return;
|
||||||
addPortfolioMarketsToSet(ids,st.agents&&st.agents[a.id]);
|
addPortfolioMarketsToSet(ids,st.agents&&st.agents[a.id],{materialOnly:true});
|
||||||
});
|
});
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
@@ -2024,6 +2027,7 @@ function reduceStrategyOverlap(st){
|
|||||||
AGENTS.filter(a=>a.kind==="strategy").forEach(cfg=>{
|
AGENTS.filter(a=>a.kind==="strategy").forEach(cfg=>{
|
||||||
const p=st.agents&&st.agents[cfg.id]; if(!p)return;
|
const p=st.agents&&st.agents[cfg.id]; if(!p)return;
|
||||||
(p.positions||[]).forEach(pos=>{
|
(p.positions||[]).forEach(pos=>{
|
||||||
|
if(!isMaterialPosition(p,pos))return;
|
||||||
const id=pos.market_id||pos.asset; if(!id)return;
|
const id=pos.market_id||pos.asset; if(!id)return;
|
||||||
if(!groups[id])groups[id]=[];
|
if(!groups[id])groups[id]=[];
|
||||||
groups[id].push({cfg,p,pos,score:overlapKeeperScore(pos,cfg)});
|
groups[id].push({cfg,p,pos,score:overlapKeeperScore(pos,cfg)});
|
||||||
@@ -4058,7 +4062,7 @@ window.PMA_ENGINE_DIAGNOSTICS=Object.freeze({
|
|||||||
boundedStakeForRisk,
|
boundedStakeForRisk,
|
||||||
offlineCachePolicy,
|
offlineCachePolicy,
|
||||||
gainStopTargets:(entry)=>GAIN_STOP_TIERS.map(t=>gainStopTarget({entry_price:Number(entry),cost:1,shares:1,gain_stops:{}},t)),
|
gainStopTargets:(entry)=>GAIN_STOP_TIERS.map(t=>gainStopTarget({entry_price:Number(entry),cost:1,shares:1,gain_stops:{}},t)),
|
||||||
rules:Object.freeze({minimumPolicyHoldHours:MIN_POLICY_HOLD_HOURS,exitConfirmationHours:EXIT_CONFIRM_HOURS,maxAgentOverlap:2,stopLossPct:18,
|
rules:Object.freeze({minimumPolicyHoldHours:MIN_POLICY_HOLD_HOURS,exitConfirmationHours:EXIT_CONFIRM_HOURS,maxAgentOverlap:2,materialOverlapPct:1.25,stopLossPct:18,
|
||||||
coreTradeLossPct:MAX_CORE_TRADE_LOSS_PCT*100,aggressiveTradeLossPct:MAX_AGGRESSIVE_TRADE_LOSS_PCT*100,
|
coreTradeLossPct:MAX_CORE_TRADE_LOSS_PCT*100,aggressiveTradeLossPct:MAX_AGGRESSIVE_TRADE_LOSS_PCT*100,
|
||||||
coreGapTradeLossPct:MAX_CORE_GAP_TRADE_LOSS_PCT*100,aggressiveGapTradeLossPct:MAX_AGGRESSIVE_GAP_TRADE_LOSS_PCT*100,
|
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}),
|
offlineEntryMaxAgeMinutes:OFFLINE_ENTRY_MAX_AGE_MS/60000,offlineCacheMaxAgeHours:OFFLINE_CACHE_MAX_AGE_MS/3600000,explorationPct:15}),
|
||||||
@@ -4117,9 +4121,11 @@ function runEngineSelfTest(){
|
|||||||
riskBook.positions=[riskPos];
|
riskBook.positions=[riskPos];
|
||||||
normalizeLegacyPositionRisk(riskBook,riskPos,riskCfg,market({id:"risk-test",yes_price:0.5,no_price:0.5,days_to_resolution:5,price_change_1d:0.06}));
|
normalizeLegacyPositionRisk(riskBook,riskPos,riskCfg,market({id:"risk-test",yes_price:0.5,no_price:0.5,days_to_resolution:5,price_change_1d:0.06}));
|
||||||
const mock={agents:{}};AGENTS.forEach(a=>mock.agents[a.id]=defaultPortfolio());
|
const mock={agents:{}};AGENTS.forEach(a=>mock.agents[a.id]=defaultPortfolio());
|
||||||
["value","momentum","favorite"].forEach((id,i)=>mock.agents[id].positions.push({market_id:"overlap-test",question:"Overlap test",side:"YES",shares:100,current_price:0.5,entry_price:0.5,cost:50,value:50,unrealized_pnl:0,conviction:70-i,opened_at:hoursAgo(24)}));
|
["value","momentum","favorite"].forEach((id,i)=>mock.agents[id].positions.push({market_id:"overlap-test",question:"Overlap test",side:"YES",shares:1000,current_price:0.5,entry_price:0.5,cost:500,value:500,unrealized_pnl:0,conviction:70-i,opened_at:hoursAgo(24)}));
|
||||||
reduceStrategyOverlap(mock);
|
reduceStrategyOverlap(mock);
|
||||||
const overlapRemaining=AGENTS.reduce((sum,a)=>sum+mock.agents[a.id].positions.filter(p=>p.market_id==="overlap-test").length,0);
|
const overlapRemaining=AGENTS.reduce((sum,a)=>sum+mock.agents[a.id].positions.filter(p=>p.market_id==="overlap-test").length,0);
|
||||||
|
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");
|
||||||
return {version:SUGGESTION_ENGINE_VERSION,
|
return {version:SUGGESTION_ENGINE_VERSION,
|
||||||
trend:{ready:trend.trade_ready,quality:trend.quality,side:trend.side,margin:trend.net_edge},
|
trend:{ready:trend.trade_ready,quality:trend.quality,side:trend.side,margin:trend.net_edge},
|
||||||
noSignal:{ready:noSignal.trade_ready,quality:noSignal.quality,signal:noSignal.signal_type,margin:noSignal.net_edge},
|
noSignal:{ready:noSignal.trade_ready,quality:noSignal.quality,signal:noSignal.signal_type,margin:noSignal.net_edge},
|
||||||
@@ -4134,7 +4140,7 @@ function runEngineSelfTest(){
|
|||||||
legacyNormalizedValue:riskPos.value,equityPreserved:+equity(riskBook).toFixed(2),capsBinaryGap:aggressiveGapBudget===0.03&&riskPos.value<=300.01},
|
legacyNormalizedValue:riskPos.value,equityPreserved:+equity(riskBook).toFixed(2),capsBinaryGap:aggressiveGapBudget===0.03&&riskPos.value<=300.01},
|
||||||
offline:{fresh:offlineCachePolicy(30*60000),staleEntry:offlineCachePolicy(3*3600000),expired:offlineCachePolicy(25*3600000)},
|
offline:{fresh:offlineCachePolicy(30*60000),staleEntry:offlineCachePolicy(3*3600000),expired:offlineCachePolicy(25*3600000)},
|
||||||
exits:{youngConflict:exitReason(young,fresh,conflict,AGENTS[0]),matureConflict:exitReason(mature,fresh,conflict,AGENTS[0]),trailing:trailingProfitReason(trailing)},
|
exits:{youngConflict:exitReason(young,fresh,conflict,AGENTS[0]),matureConflict:exitReason(mature,fresh,conflict,AGENTS[0]),trailing:trailingProfitReason(trailing)},
|
||||||
overlapRemaining,rules:window.PMA_ENGINE_DIAGNOSTICS.rules};
|
overlapRemaining,immaterialRunnerDoesNotBlock,rules:window.PMA_ENGINE_DIAGNOSTICS.rules};
|
||||||
}
|
}
|
||||||
if(new URLSearchParams(location.search).get("engine_test")==="1"){
|
if(new URLSearchParams(location.search).get("engine_test")==="1"){
|
||||||
const output=document.createElement("output");output.id="engineSelfTest";output.hidden=true;output.textContent=JSON.stringify(runEngineSelfTest());document.body.appendChild(output);
|
const output=document.createElement("output");output.id="engineSelfTest";output.hidden=true;output.textContent=JSON.stringify(runEngineSelfTest());document.body.appendChild(output);
|
||||||
|
|||||||
Reference in New Issue
Block a user