mirror of
https://github.com/theodore-song/polymarket-analyst.git
synced 2026-08-19 18:48:10 +00:00
Contain severe losing signal regimes early
This commit is contained in:
+19
-4
@@ -1546,7 +1546,7 @@ function tradeReturnForLearning(trade,closed){
|
|||||||
return clamp(pnl/basis,-1,2);
|
return clamp(pnl/basis,-1,2);
|
||||||
}
|
}
|
||||||
function buildAdaptiveProfile(p){
|
function buildAdaptiveProfile(p){
|
||||||
const buckets={},observations=[];
|
const buckets={},observations=[],closedReturns=[];
|
||||||
const add=(trade,closed)=>{
|
const add=(trade,closed)=>{
|
||||||
if(Number(trade.strategy_version||0)<34)return;
|
if(Number(trade.strategy_version||0)<34)return;
|
||||||
const age=Math.max(0,Date.now()-new Date(trade.closed_at||trade.opened_at||0).getTime());
|
const age=Math.max(0,Date.now()-new Date(trade.closed_at||trade.opened_at||0).getTime());
|
||||||
@@ -1554,7 +1554,7 @@ function buildAdaptiveProfile(p){
|
|||||||
const weight=recency*(closed?1:Math.min(0.30,Math.max(0.08,daysHeld(trade)/20)));
|
const weight=recency*(closed?1:Math.min(0.30,Math.max(0.08,daysHeld(trade)/20)));
|
||||||
const ret=tradeReturnForLearning(trade,closed);
|
const ret=tradeReturnForLearning(trade,closed);
|
||||||
if(!Number.isFinite(ret)||weight<=0)return;
|
if(!Number.isFinite(ret)||weight<=0)return;
|
||||||
observations.push({ret,weight,closed});
|
observations.push({ret,weight,closed});if(closed)closedReturns.push(ret);
|
||||||
learningFeatures(trade).forEach(key=>{
|
learningFeatures(trade).forEach(key=>{
|
||||||
const b=buckets[key]||(buckets[key]={weight:0,sum:0,wins:0,count:0});
|
const b=buckets[key]||(buckets[key]={weight:0,sum:0,wins:0,count:0});
|
||||||
b.weight+=weight;b.sum+=ret*weight;b.wins+=(ret>0?weight:0);b.count++;
|
b.weight+=weight;b.sum+=ret*weight;b.wins+=(ret>0?weight:0);b.count++;
|
||||||
@@ -1571,6 +1571,8 @@ function buildAdaptiveProfile(p){
|
|||||||
.sort((a,b)=>b[1].score-a[1].score);
|
.sort((a,b)=>b[1].score-a[1].score);
|
||||||
return {version:SUGGESTION_ENGINE_VERSION,samples:(p.closed||[]).filter(t=>Number(t.strategy_version||0)>=34).length,
|
return {version:SUGGESTION_ENGINE_VERSION,samples:(p.closed||[]).filter(t=>Number(t.strategy_version||0)>=34).length,
|
||||||
effective_samples:+totalWeight.toFixed(2),global_score:+globalScore.toFixed(4),buckets:learned,
|
effective_samples:+totalWeight.toFixed(2),global_score:+globalScore.toFixed(4),buckets:learned,
|
||||||
|
worst_return:closedReturns.length?+Math.min(...closedReturns).toFixed(4):0,
|
||||||
|
large_loss_count:closedReturns.filter(x=>x<=-0.30).length,
|
||||||
best:ranked[0]?{feature:ranked[0][0],score:ranked[0][1].score}:null,
|
best:ranked[0]?{feature:ranked[0][0],score:ranked[0][1].score}:null,
|
||||||
worst:ranked.length?{feature:ranked[ranked.length-1][0],score:ranked[ranked.length-1][1].score}:null};
|
worst:ranked.length?{feature:ranked[ranked.length-1][0],score:ranked[ranked.length-1][1].score}:null};
|
||||||
}
|
}
|
||||||
@@ -1583,7 +1585,7 @@ function learnedOpportunity(cfg,p,s,profile=null){
|
|||||||
const model=profile||buildAdaptiveProfile(p),features=learningFeatures(s),rows=features.map(k=>model.buckets[k]).filter(Boolean);
|
const model=profile||buildAdaptiveProfile(p),features=learningFeatures(s),rows=features.map(k=>model.buckets[k]).filter(Boolean);
|
||||||
const weight=rows.reduce((sum,r)=>sum+r.weight,0),score=rows.length?rows.reduce((sum,r)=>sum+r.score,0)/rows.length:0;
|
const weight=rows.reduce((sum,r)=>sum+r.weight,0),score=rows.length?rows.reduce((sum,r)=>sum+r.score,0)/rows.length:0;
|
||||||
const confidence=weight/(weight+12),exploration=stableExploration(cfg.id,s.market_id);
|
const confidence=weight/(weight+12),exploration=stableExploration(cfg.id,s.market_id);
|
||||||
const blocked=model.samples>=8&&confidence>=0.45&&score<-0.055&&!exploration;
|
const blocked=((model.samples>=4&&confidence>=0.32&&score<-0.045)||(model.samples>=8&&confidence>=0.45&&score<-0.035))&&!exploration;
|
||||||
return {score:+score.toFixed(4),confidence:+confidence.toFixed(3),multiplier:+clamp(1+score*2.4,0.72,1.28).toFixed(3),
|
return {score:+score.toFixed(4),confidence:+confidence.toFixed(3),multiplier:+clamp(1+score*2.4,0.72,1.28).toFixed(3),
|
||||||
exploration,allowed:!blocked,features};
|
exploration,allowed:!blocked,features};
|
||||||
}
|
}
|
||||||
@@ -1621,6 +1623,10 @@ function adaptiveDecision(cfg,p,rank,total,leaderEq){
|
|||||||
if(profile.global_score>0.015){maxFrac*=1.08;reason+=" Its own recent trade evidence is positive, so proven setups receive a small bounded size increase.";}
|
if(profile.global_score>0.015){maxFrac*=1.08;reason+=" Its own recent trade evidence is positive, so proven setups receive a small bounded size increase.";}
|
||||||
else if(profile.global_score<-0.015){maxFrac*=0.88;reason+=" Its own recent trade evidence is negative, so weak regimes are down-weighted while a 15% exploration allowance remains.";}
|
else if(profile.global_score<-0.015){maxFrac*=0.88;reason+=" Its own recent trade evidence is negative, so weak regimes are down-weighted while a 15% exploration allowance remains.";}
|
||||||
}
|
}
|
||||||
|
if(profile.effective_samples>=1.5&&(profile.global_score<-0.04||profile.worst_return<=-0.30)){
|
||||||
|
mode="Loss Regime Containment";minConv+=2;maxNew=Math.min(maxNew,1);maxFrac*=0.72;
|
||||||
|
reason+=" A severe realized loss was detected, so new risk is cut immediately while the learner identifies which signal regime failed.";
|
||||||
|
}
|
||||||
reason+=` Emotion is reported as ${emo.label.toLowerCase()} but cannot increase size, reduce confirmation, or add attack slots.`;
|
reason+=` Emotion is reported as ${emo.label.toLowerCase()} but cannot increase size, reduce confirmation, or add attack slots.`;
|
||||||
const todaySnaps=(p.snapshots||[]).filter(s=>s.date===todayStr());
|
const todaySnaps=(p.snapshots||[]).filter(s=>s.date===todayStr());
|
||||||
const cycleStart=todaySnaps.length?Number(todaySnaps[0].equity||eq):eq;
|
const cycleStart=todaySnaps.length?Number(todaySnaps[0].equity||eq):eq;
|
||||||
@@ -3970,6 +3976,14 @@ function runEngineSelfTest(){
|
|||||||
const learningProfile=buildAdaptiveProfile(learner);
|
const learningProfile=buildAdaptiveProfile(learner);
|
||||||
const learnedTrend=learnedOpportunity(AGENTS[0],learner,{market_id:"learn-trend",signal_type:"trend",quality:"confirmed",category:"Politics",side:"YES",entry_price:0.42},learningProfile);
|
const learnedTrend=learnedOpportunity(AGENTS[0],learner,{market_id:"learn-trend",signal_type:"trend",quality:"confirmed",category:"Politics",side:"YES",entry_price:0.42},learningProfile);
|
||||||
const learnedReversal=learnedOpportunity(AGENTS[0],learner,{market_id:"learn-reversal",signal_type:"reversal",quality:"reversal",category:"Sports",side:"NO",entry_price:0.42},learningProfile);
|
const learnedReversal=learnedOpportunity(AGENTS[0],learner,{market_id:"learn-reversal",signal_type:"reversal",quality:"reversal",category:"Sports",side:"NO",entry_price:0.42},learningProfile);
|
||||||
|
const lossLearner=defaultPortfolio();
|
||||||
|
for(let i=0;i<4;i++)lossLearner.closed.push({strategy_version:35,signal_type:"trend",quality:"confirmed",category:"Politics",side:"YES",entry_price:0.42,original_cost:100,
|
||||||
|
realized_pnl:-50,opened_at:hoursAgo(72+i),closed_at:closedAt});
|
||||||
|
let lossMarketId="loss-regime-0",lossIndex=0;
|
||||||
|
while(stableExploration(AGENTS[0].id,lossMarketId))lossMarketId=`loss-regime-${++lossIndex}`;
|
||||||
|
const lossProfile=buildAdaptiveProfile(lossLearner);
|
||||||
|
const lossOpportunity=learnedOpportunity(AGENTS[0],lossLearner,{market_id:lossMarketId,signal_type:"trend",quality:"confirmed",category:"Politics",side:"YES",entry_price:0.42},lossProfile);
|
||||||
|
const lossDecision=adaptiveDecision(AGENTS[0],lossLearner,5,10,STARTING_BALANCE);
|
||||||
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:100,current_price:0.5,entry_price:0.5,cost:50,value:50,unrealized_pnl:0,conviction:70-i,opened_at:hoursAgo(24)}));
|
||||||
reduceStrategyOverlap(mock);
|
reduceStrategyOverlap(mock);
|
||||||
@@ -3979,7 +3993,8 @@ function runEngineSelfTest(){
|
|||||||
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},
|
||||||
reversal:{ready:reversal.trade_ready,quality:reversal.quality,side:reversal.side,margin:reversal.net_edge},
|
reversal:{ready:reversal.trade_ready,quality:reversal.quality,side:reversal.side,margin:reversal.net_edge},
|
||||||
highEntryTargets:targets,targetsReachable:targets.every(x=>x>0.82&&x<1),
|
highEntryTargets:targets,targetsReachable:targets.every(x=>x>0.82&&x<1),
|
||||||
adaptation:{samples:learningProfile.samples,trendMultiplier:learnedTrend.multiplier,reversalMultiplier:learnedReversal.multiplier,learnsDirection:learnedTrend.multiplier>learnedReversal.multiplier},
|
adaptation:{samples:learningProfile.samples,trendMultiplier:learnedTrend.multiplier,reversalMultiplier:learnedReversal.multiplier,learnsDirection:learnedTrend.multiplier>learnedReversal.multiplier,
|
||||||
|
blocksConfirmedLosingRegime:!lossOpportunity.allowed,containmentMode:lossDecision.mode,containmentMaxNew:lossDecision.maxNew},
|
||||||
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,rules:window.PMA_ENGINE_DIAGNOSTICS.rules};
|
||||||
|
|||||||
Reference in New Issue
Block a user