Skills Plugins MCP Prompt Model 博客 我的中心
数据分析与咨询 #trading #research

polymarket-quant-trader

Professional-grade Polymarket prediction market trading system. Includes Kelly Criterion position sizing, EV calculator, Bayesian probability updater, cross-platform arbitrage detector (Polymarket vs 1WIN), and autoresearch loop that self-improves strategy overnight via Brier score optimisation. Use when: user wants to trade prediction markets, find arbitrage opportunities, build a trading bot, or improve prediction accuracy. Triggers: polymarket, prediction markets, kelly criterion, EV trading, arb detector, brier score, prediction market bot, market making, quant trading, sports betting math, cross-platform arbitrage.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=leoyeai-openclaw-master-skills-skills-polymarket-quant-trader-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name polymarket-quant-trader description Professional-grade Polymarket prediction market trading system. Includes Kelly Criterion position sizing, EV calculator, Bayesian probability updater, cross-platform arbitrage detector (Polymarket vs 1WIN), and autoresearch loop that self-improves strategy overnight via Brier score optimisation. Use when: user wants to trade prediction markets, find arbitrage opportunities, build a trading bot, or improve prediction accuracy. Triggers: polymarket, prediction markets, kelly criterion, EV trading, arb detector, brier score, prediction market bot, market making, quant trading, sports betting math, cross-platform arbitrage. version 1.0.0 Polymarket Quant Trader A professional quant trading system for Polymarket prediction markets, built and battle-tested in production. Three alpha streams. One integrated system. Overview This skill gives you a complete quantitative trading system for Polymarket with three independent alpha streams: EV-Based Signal Trading — Kelly Criterion position sizing + Bayesian probability updating. Find edges, size them correctly, update beliefs as evidence arrives. Self-Improving Strategy (Autoresearch Loop) — An autonomous hill-climbing optimizer that tunes your strategy parameters overnight using Brier score as the objective function. Wake up to a better strategy. Cross-Platform Arbitrage (PM x 1WIN) — Detect spread discrepancies between Polymarket and 1WIN bookmaker. Fuzzy title matching, confidence tiering, Kelly-sized positions. Each stream works independently or together. The system ships with TypeScript source, npm scripts for every workflow, and a backtester to validate before going live. Current production performance: Brier score 0.18 (meaningful edge territory — baseline random is 0.25, professional is sub-0.12). Stream 1: EV-Based Signal Trading How It Works The core loop: estimate a probability, compare it to the market price, calculate expected value, size the position with Kelly Criterion, and update beliefs as new evidence arrives. Kelly Criterion Position Sizing Kelly answers: "Given my edge, what fraction of my bankroll should I bet?" The formula: f* = (p * b - q) / b where: f* = optimal fraction of bankroll to wager p = probability of winning (your estimate, 0-1) b = net odds multiplier (payout per $1 risked) q = 1 - p (probability of losing) In prediction markets, odds derive from the market price: b = (1 - marketYesPrice) / marketYesPrice If YES trades at $0.40, then b = 0.60/0.40 = 1.5 (you risk $0.40 to win $0.60). Implementation: // kelly-criterion.ts export function kelly ( p : number , b : number , q ?: number ): number { const qVal = q ?? 1 - p; return (p * b - qVal) / b; } export function quarterKelly ( p : number , b : number ): number { return 0.25 * kelly (p, b); } export function kellySizing ( bankroll : number , p : number , b : number , mode : 'full' | 'half' | 'quarter' = 'quarter' ): number { const fraction = mode === 'full' ? kelly (p, b) : mode === 'half' ? 0.5 * kelly (p, b) : quarterKelly (p, b); return Math . max ( 0 , bankroll * Math . min (fraction, 0.15 )); } Why quarter Kelly? Full Kelly maximizes long-run growth rate but produces brutal drawdowns (50%+ swings). Quarter Kelly captures ~75% of the growth rate with dramatically lower variance. Every serious quant fund uses fractional Kelly. EV Calculator Expected value quantifies your edge per dollar risked: // ev-calculator.ts export interface MarketEV { marketId : string ; ourP : number ; // Your estimated probability marketP : number ; // Market-implied probability (= YES price) b : number ; // Net odds: (1 - marketP) / marketP ev : number ; // Expected value per dollar risked edgePct : number ; // Edge as percentage of market price kellyFraction : number ; // Quarter Kelly optimal fraction recommend : boolean ; // Worth trading? (ev > 0 && edgePct >= 2%) } export function calcEV ( ourProbability : number , marketYesPrice : number ) { const b = ( 1 - marketYesPrice) / marketYesPrice; const ev = ourProbability * b - ( 1 - ourProbability); const edgePct = (ev / marketYesPrice) * 100 ; return { ev, edgePct, b }; } export function scoreMarket ( market : any , ourP : number ): MarketEV { const { ev, edgePct, b } = calcEV (ourP, market. yesPrice ); const kellyFraction = quarterKelly (ourP, b); return { marketId : market. id , ourP, marketP : market. yesPrice , b, ev, edgePct, kellyFraction, recommend : ev > 0 && edgePct >= 2 , }; } export function rankByEV ( markets : MarketEV [] ): MarketEV [] { return [...markets]. sort ( ( a, b ) => b. ev - a. ev ); } Reading the output: An edgePct of 5% means your model thinks the market is mispriced by 5%. The recommend flag fires when EV is positive AND edge exceeds 2% (below that, transaction costs eat your edge). Bayesian Probability Updater Update your probability estimates as new evidence arrives: // bayesian-updater.ts export interface BayesianState { marketId : string ; priorP : number ; currentP : number ; evidence : Evidence []; lastUpdated : Date ; } export interface Evidence { description : string ; likelihoodRatio : number ; // > 1 supports YES, < 1 supports NO timestamp : Date ; } export function bayesUpdate ( prior : number , likelihoodRatio : number ): number { const posterior = (prior * likelihoodRatio) / (prior * likelihoodRatio + ( 1 - prior)); return Math . max ( 0.001 , Math . min ( 0.999 , posterior)); } export function addEvidence ( state : BayesianState , evidence : Evidence ): BayesianState { const newP = bayesUpdate (state. currentP , evidence. likelihoodRatio ); return { ...state, currentP : newP, evidence : [...state. evidence , evidence], lastUpdated : evidence. timestamp , }; } export function getRecommendation ( state : BayesianState , marketPrice : number ): { action : 'buy' | 'sell' | 'hold' ; confidence : number ; reason : string } { const diff = state. currentP - marketPrice; if ( Math . abs (diff) < 0.02 ) return { action : 'hold' , confidence : 0 , reason : 'Within noise' }; if (diff > 0 ) return { action : 'buy' , confidence : diff, reason : `Model ${(diff* 100 ).toFixed( 1 )} % above market` }; return { action : 'sell' , confidence : -diff, reason : `Model ${(-diff* 100 ).toFixed( 1 )} % below market` }; } Likelihood ratios: A ratio of 2.0 means "this evidence is twice as likely if YES is true." A ratio of 0.5 means "this evidence is twice as likely if NO is true." The Bayesian updater chains multiple evidence items — each update feeds the next as a new prior. Market Scorer (Composite Ranking) Combines all signals into a single score for market selection: // market-scorer.ts — Weighted scoring model // EV Score: 40% weight — edge percentage // Kelly Fraction: 30% weight — optimal sizing (higher = more confident) // Expiry Window: 20% weight — sweet spot 6-72 hours // Volume Score: 10% weight — log-normalized liquidity Markets scoring highest get traded first. The expiry window filter avoids two failure modes: too-short expiry (can't exit if wrong) and too-long expiry (capital locked up, edge decays). Stream 2: Self-Improving Strategy (Autoresearch Loop) The Brier Score Metric Brier score measures prediction calibration — how close your probability estimates are to actual outcomes: brierScore = mean((predictedProbability - actualOutcome)^2) where actualOutcome = 1 if resolved YES, 0 if resolved NO Interpretation scale: Score Level Meaning 0.25 Random Coin-flip predictions 0.22 Weak edge Slightly better than random 0.18 Meaningful edge Consistent alpha 0.12 Professional Elite forecaster territory < 0.10 Superforecaster Top 1% calibration Lower is better. The system tracks Brier score as the primary optimization objective. Strategy Configuration The strategy is defined by tunable parameters: // research/strategy.ts export interface StrategyConfig { minVolume : number ; // Minimum market volume ($) minEdgePct : number ; // Minimum edge to trade (%) kellyMode : "full" | "half" | "quarter" ; maxKellyFraction : number ; // Cap on position size expiryMinHours : number ; // Earliest expiry to consider expiryMaxHours : number ; // Latest expiry to consider } export const DEFAULT_CONFIG : StrategyConfig = { minVolume : 10000 , minEdgePct : 3.0 , kellyMode : "quarter" , maxKellyFraction : 0.15 , expiryMinHours : 6 , expiryMaxHours : 72 , }; // Category-specific base rates (priors for YES resolution) const CATEGORY_PRIORS = { sports : 0.48 , crypto : 0.45 , politics : 0.50 , tech : 0.50 , weather : 0.45 , misc : 0.50 , }; Prediction logic: const PRIOR_WEIGHT = 0.15 ; // How much to weight the category prior ourProbability = marketYesPrice * ( 1 - PRIOR_WEIGHT ) + prior * PRIOR_WEIGHT ; edgePct = Math . abs (ourProbability - marketYesPrice) * 100 ; // Decision: if (edgePct < minEdgePct) → skip else if (ourP > marketYesPrice) → buy_yes else → buy_no Running the Autoresearch Loop # One-shot evaluation against resolved markets npm run research: eval # Manual iteration (5 rounds, stops on plateau) npm run research # Autonomous hill-climbing optimizer (run overnight) npm run research:auto How research:auto works: Loads current strategy config Tries a parameter mutation (e.g., minEdgePct 3.0 → 2.5) Evaluates against all resolved markets → gets Brier score If Brier improved → keep change, bump version, save checkpoint If Brier worsened → revert to backup Move to next untried mutation Stop when all mutations exhausted without improvement Parameter search space: // auto-improve.ts explores: minEdgePct : [ 1.0 , 1.5 , 2.5 , 3.0 ] PRIOR_WEIGHT : [ 0.05 , 0.10 , 0.20 , 0.25 , 0.30 ] maxKellyFraction : [ 0.08 , 0.10 , 0.12 , 0.20 ] minVolume : [ 5000 , 15000 , 20000 ] expiryMaxHours : [ 48 , 96 ] expiryMinHours : [ 4 , 8 , 12 ] kellyMode : quarter ↔ half categoryPriors : dynamic adjustments per category Reading the Iteration Log Results are logged to research/program.md : ## Iteration 4 (Auto 4/8) - Changed: minEdgePct 2 → 3 - Brier: 0.1804 (prev: 0.1814) - Improvement: +0.0010 - Status: ✅ KEPT — new best - Version: 1.0.1 Breaking a Plateau When auto-improve exhausts its search space without improvement: Inject a hypothesis manually — Edit research/strategy.ts with a theory (e.g., "crypto markets are less efficient after 10pm UTC") and run npm run research:eval Add new data — More resolved markets = more signal for the optimizer Change the objective — Weight Brier + Sharpe ratio instead of pure Brier Try category-specific strategies — Separate configs for sports vs politics vs crypto Stream 3: Cross-Platform Arbitrage (PM x 1WIN) How Spread Arbitrage Works When two platforms price the same event differently, you can profit from the spread: Polymarket YES price: $0.40 (implied 40%) 1WIN decimal odds: 2.80 (implied 1/2.80 = 35.7%) Spread = |40% - 35.7%| = 4.3% If Polymarket says 40% and 1WIN says 35.7%, Polymarket is pricing YES higher. The direction depends on which platform you think is wrong — or you can bet both sides if the spread exceeds the combined vig. Spread Calculator // spread-calculator.ts export function calcSpread ( polyProb : number , onewinDecimalOdds : number ) { const onewinProb = 1 / onewinDecimalOdds; const spread = Math . abs (polyProb - onewinProb); const spreadPct = spread * 100 ; const direction = polyProb < onewinProb ? "buy_poly_yes" : "buy_poly_no" ; return { onewinProb, spread, spreadPct, direction }; } export function calcExpectedProfit ( polyProb : number , onewinProb : number ): number { const edge = Math . abs (polyProb - onewinProb); const ONEWIN_VIG = 0.02 ; return Math . max ((edge - ONEWIN_VIG ) * 100 , 0 ); } export function calcKellyFraction ( polyProb : number , onewinProb : number ): number { const edge = Math . abs (polyProb - onewinProb); const fraction = edge / ( 1 - Math . min (polyProb, onewinProb)); return Math . min (fraction, 0.10 ); // Hard cap at 10% } export function getConfidence ( spreadPct : number ): "HIGH" | "MEDIUM" | "LOW" | null { if (spreadPct > 5 ) return "HIGH" ; if (spreadPct >= 3 ) return "MEDIUM" ; if (spreadPct >= 1 ) return "LOW" ; return null ; // Skip } Running the Arb Scanner npm run arb:scan What it does: Fetches active Polymarket markets (sports/crypto, expires within 48h, volume > 0) Fetches 1WIN events via API (with fallback to CLOB proxy if geo-blocked) Fuzzy-matches event titles across platforms (Dice coefficient, 0.4 threshold) Calculates spreads for all matches Tiers by confidence (HIGH/MEDIUM/LOW) Returns top 20 opportunities sorted by spread percentage Reading the output: 🟢 HIGH CONFIDENCE | Spread: 6.2% PM: "Will Bitcoin hit $100k by March?" @ $0.35 1WIN: Same event @ 2.50 odds (40.0%) Direction: buy_poly_yes Kelly: 4.8% of bankroll Expected profit: 4.2% 🟡 MEDIUM CONFIDENCE | Spread: 3.8% PM: "Lakers vs Celtics Game 5 winner" @ $0.55 1WIN: Same event @ 1.72 odds (58.1%) Direction: buy_poly_no Kelly: 2.1% of bankroll Expected profit: 1.8% Title Matching The fuzzy matcher handles cross-platform naming differences: // title-matcher.ts // Normalizes: lowercase, remove punctuation, strip stop words // Stop words: vs, v, the, will, who, win, to, in, at, on, a, an, // of, for, and, or, be, is, are, was, match, game, fight, bout // Dice coefficient: 2 * |intersection| / (|a| + |b|) // Threshold: 0.4 minimum for a match Continuous Monitoring // detector.ts — startMonitor() // Polls every 60 seconds // Tracks seen arb IDs to alert only on NEW opportunities // Logs all discoveries with timestamps Setup Guide 1. Clone and Install
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。