mirror of
https://github.com/theodore-song/polymarket-analyst.git
synced 2026-07-27 16:07:46 +00:00
Compare commits
2 Commits
49888c7b56
...
3c39cfe9f3
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c39cfe9f3 | |||
| 744387199e |
+1
-1
@@ -135,7 +135,7 @@ export default async function handler(req, res) {
|
||||
access: "private",
|
||||
allowOverwrite: true,
|
||||
contentType: "application/json",
|
||||
cacheControlMaxAge: 60,
|
||||
cacheControlMaxAge: 0,
|
||||
});
|
||||
return res.status(200).json({ ok: true, state });
|
||||
}
|
||||
|
||||
+32
-9
@@ -53,6 +53,7 @@ h1,h2,h3,.brand-name{font-family:'Space Grotesk','Inter',sans-serif}
|
||||
background:linear-gradient(135deg,var(--accent),var(--accent2));box-shadow:0 6px 20px -6px var(--accent)}
|
||||
.brand-name{font-size:18px;font-weight:700;letter-spacing:-.2px;line-height:1}
|
||||
.brand-sub{font-size:11px;color:var(--muted);margin-top:2px}
|
||||
.build-badge{display:inline-flex;align-items:center;margin-top:5px;padding:3px 8px;border-radius:999px;border:1px solid rgba(124,140,255,.35);background:rgba(124,140,255,.12);color:#cbd5ff;font-size:10px;font-weight:800;letter-spacing:.02em;text-transform:uppercase}
|
||||
.tabs{display:flex;gap:4px;background:rgba(255,255,255,.04);padding:4px;border-radius:12px;border:1px solid var(--border);max-width:100%;overflow-x:auto}
|
||||
.tab{appearance:none;border:0;background:transparent;color:var(--muted);font-family:inherit;
|
||||
font-size:13.5px;font-weight:600;padding:8px 14px;border-radius:9px;cursor:pointer;transition:.18s;white-space:nowrap}
|
||||
@@ -337,7 +338,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 · strategies, copycats & whales</div></div>
|
||||
<div><div class="brand-name">Polymarket Arena</div><div class="brand-sub">10 agents · strategies, copycats & whales</div><div class="build-badge">Top 5,000 analysis · v16</div></div>
|
||||
</div>
|
||||
<div class="tabs" id="tabs">
|
||||
<button class="tab" data-tab="overview">Overview</button>
|
||||
@@ -739,7 +740,7 @@ footer{margin-top:34px;padding-top:22px;border-top:1px solid var(--border);color
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
Build hold-fix · Paper trading only · Live prices from Polymarket's public Gamma API · Not financial advice ·
|
||||
Build top-5000-analysis-v16 · 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>
|
||||
@@ -766,7 +767,7 @@ const EXIT_STALE_DAYS = 10;
|
||||
const EXIT_RESOLUTION_DAYS = 2;
|
||||
const AGENTS_KEY = "pma_agents_v2";
|
||||
const SUG_KEY = "pma_suggestions_v5";
|
||||
const SUGGESTION_ENGINE_VERSION = 14;
|
||||
const SUGGESTION_ENGINE_VERSION = 16;
|
||||
const FOCUS_KEY = "pma_focus_v1";
|
||||
const VIEW_KEY = "pma_view_v1";
|
||||
const PF_SORT_KEY = "pma_portfolio_sort_v1";
|
||||
@@ -995,6 +996,7 @@ const MIN_ENTRY_DAYS=3.0;
|
||||
const EDGE_SCALE=0.13;
|
||||
const MAX_STRATEGY_POSITIONS=16;
|
||||
const MAX_ACTIVE_MARKET_PAGES=1000;
|
||||
const MARKET_ANALYSIS_LIMIT=5000;
|
||||
const SUGGESTION_TOTAL=900;
|
||||
const SUGGESTION_PER_CATEGORY=180;
|
||||
const VISIBLE_SUGGESTIONS=900;
|
||||
@@ -1057,6 +1059,23 @@ function fairValue(m){const p=m.yes_price,mom=momentumSignal(m),liq=liquiditySig
|
||||
const directional=mom>0.62?(mom-0.62)*0.08:(mom<0.26?(mom-0.26)*0.035:0);
|
||||
const liquidBump=(liq-0.55)*0.012;
|
||||
return clamp(p+directional+liquidBump,0.03,0.97);}
|
||||
function quickMarketGap(m){
|
||||
if(!m||!Number.isFinite(m.yes_price))return 0;
|
||||
return Math.abs(fairValue(m)-m.yes_price);
|
||||
}
|
||||
function marketAnalysisScore(m){
|
||||
const activity=Math.log10((m.volume_24hr||0)*8+(m.volume||0)+1);
|
||||
const liquidity=Math.log10((m.liquidity||0)+1);
|
||||
const gap=quickMarketGap(m);
|
||||
const timing=timingSignal(m.days_to_resolution);
|
||||
return activity*18+liquidity*9+gap*260+timing*8;
|
||||
}
|
||||
function selectMarketsForAnalysis(markets,limit=MARKET_ANALYSIS_LIMIT){
|
||||
return [...markets]
|
||||
.filter(m=>m&&m.question&&m.volume>=MIN_SCOUT_VOLUME&&m.liquidity>=MIN_SCOUT_LIQUIDITY)
|
||||
.sort((a,b)=>marketAnalysisScore(b)-marketAnalysisScore(a))
|
||||
.slice(0,limit);
|
||||
}
|
||||
function timingSignal(d){if(d==null)return 0.4;if(d<1)return 0.1;if(d<=3)return 0.5;if(d<=90)return 1.0-(d-3)/87.0*0.4;return 0.35;}
|
||||
function analyzeMarket(m,realWorldSignals={}){
|
||||
if(m.volume<MIN_SCOUT_VOLUME||m.liquidity<MIN_SCOUT_LIQUIDITY)return null;
|
||||
@@ -1207,7 +1226,7 @@ function compactSyncItems(items,limits=SYNC_LIMITS){
|
||||
}
|
||||
function saveState(st){localStorage.setItem(AGENTS_KEY,JSON.stringify(compactAgentStateForSync(st)));}
|
||||
function loadSuggestions(){try{const s=localStorage.getItem(SUG_KEY);return s?JSON.parse(s):{date:null,suggestions:[]};}catch(e){return {date:null,suggestions:[]};}}
|
||||
function saveSuggestions(sugs,marketCount=0){const p={date:todayStr(),generated_at:nowIso(),engine_version:SUGGESTION_ENGINE_VERSION,market_count:marketCount,suggestion_cap:SUGGESTION_TOTAL,suggestions:sugs};const compact=compactSuggestionsForSync(p);localStorage.setItem(SUG_KEY,JSON.stringify(compact));return compact;}
|
||||
function saveSuggestions(sugs,marketCount=0,analyzedCount=null){const p={date:todayStr(),generated_at:nowIso(),engine_version:SUGGESTION_ENGINE_VERSION,market_count:marketCount,analyzed_count:analyzedCount==null?marketCount:analyzedCount,analysis_limit:MARKET_ANALYSIS_LIMIT,suggestion_cap:SUGGESTION_TOTAL,suggestions:sugs};const compact=compactSuggestionsForSync(p);localStorage.setItem(SUG_KEY,JSON.stringify(compact));return compact;}
|
||||
function collectSyncItems(){const items={};SYNC_KEYS.forEach(k=>{const v=localStorage.getItem(k);if(v!=null)items[k]=v;});return compactSyncItems(items);}
|
||||
function applySyncItems(items){
|
||||
if(!items||typeof items!=="object")return false;
|
||||
@@ -2031,11 +2050,13 @@ async function runDailyCycle(){
|
||||
SNAP_TS=nowIso();
|
||||
setStatus("fetching markets…",true);
|
||||
const markets=await fetchMarkets(Infinity,100,count=>setStatus(`fetching all active markets (${count})…`,true));
|
||||
const analysisMarkets=selectMarketsForAnalysis(markets);
|
||||
setStatus(`selected top ${analysisMarkets.length.toLocaleString()} markets for analysis…`,true);
|
||||
setStatus("checking real-world context…",true);
|
||||
const realWorldSignals=await fetchRealWorldSignals(markets);
|
||||
const realWorldSignals=await fetchRealWorldSignals(analysisMarkets);
|
||||
setStatus("analyzing expected value…",true);
|
||||
const sugs=generateSuggestions(markets,SUGGESTION_TOTAL,SUGGESTION_PER_CATEGORY,realWorldSignals);
|
||||
saveSuggestions(sugs,markets.length);
|
||||
const sugs=generateSuggestions(analysisMarkets,SUGGESTION_TOTAL,SUGGESTION_PER_CATEGORY,realWorldSignals);
|
||||
saveSuggestions(sugs,markets.length,analysisMarkets.length);
|
||||
st=loadState();
|
||||
const emailOffsets=agentHistoryOffsets(st);
|
||||
const focus=getFocus();
|
||||
@@ -2428,9 +2449,11 @@ function renderSuggestions(){
|
||||
const filtered=pool.slice(0,VISIBLE_SUGGESTIONS);
|
||||
const buyCount=all.filter(s=>s.trade_ready).length,watchCount=all.length-buyCount;
|
||||
const evAvg=all.length?Math.round(all.reduce((s,x)=>s+Number(x.evidence_score||0),0)/all.length*100):0;
|
||||
const scanned=Number(data.market_count||0).toLocaleString();
|
||||
const analyzed=Number(data.analyzed_count||data.market_count||0).toLocaleString();
|
||||
$("focusNote").textContent=focus==="All"
|
||||
? `Scanned ${Number(data.market_count||0).toLocaleString()} active markets and kept ${all.length} ideas (${buyCount} BUY, ${watchCount} WATCH). Showing ${filtered.length}; agents trade only EV+ ideas after liquidity, chase, and real-world evidence checks. Avg evidence ${evAvg}.`
|
||||
: `Scanned ${Number(data.market_count||0).toLocaleString()} active markets. Showing ${filtered.length} of ${pool.length} ${focus} ideas; agents only open EV+ BUY ${focus} positions while this is selected.`;
|
||||
? `Scanned ${scanned} active markets, analyzed the top ${analyzed} by activity/liquidity/gap, and kept ${all.length} ideas (${buyCount} BUY, ${watchCount} WATCH). Showing ${filtered.length}; agents trade only EV+ ideas after liquidity, chase, and real-world evidence checks. Avg evidence ${evAvg}.`
|
||||
: `Scanned ${scanned} active markets and analyzed the top ${analyzed}. Showing ${filtered.length} of ${pool.length} ${focus} ideas; agents only open EV+ BUY ${focus} positions while this is selected.`;
|
||||
if(!filtered.length){root.innerHTML=`<div class="empty" style="grid-column:1/-1">No ${esc(focus)} suggestions in this live batch.</div>`;return;}
|
||||
root.innerHTML=filtered.map(s=>{
|
||||
const col=catColor(s.category);
|
||||
|
||||
Reference in New Issue
Block a user