Polymarket Informed Market Making 策略框架
核心理念:用做市的壳执行方向性交易。手续费从 Taker fee 变成 Maker rebate,方向性收益叠加 spread 收益。
0. 为什么不跟单 SM(Copy Trading 策略审查)
0.1 结论:跟单 SM 大概率亏钱
经过 DeepSeek 模型独立审查,纯跟单 Smart Money 策略存在系统性缺陷,实盘大概率亏损。
0.2 核心问题
① 信息延迟 — 你买到的是残渣
SM 下单 → 链上确认 → indexer 捕获 → 信号生成 → AI 过滤 → 你挂单
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这段延迟 = 30 秒到几分钟
价格已经被 SM 推上去了
你不是唯一一个在跟单。其他跟单机器人也在抢,你买在最差的价格。
② 止损与 SM 的赚钱方式矛盾(最致命)
SM 的盈利模式:
如果你加 -30% 止损 + 50% 止盈:
期望值 = 0.1 × (+200%) + 0.9 × (-30%) = +20% - 27% = -7% ❌
你继承了 SM 的高亏损频率,但截断了他们赚钱的方式(尾部收益)。
③ 幸存者偏差
从 748 个 trader 中选出 57 个历史赢家 = 事后选股。学术界反复证明:过去的 alpha 对未来预测力极弱。
④ LLM 概率估计不可靠
用 Gemini 估算"公允概率"然后跟市场价比 → 发现的 "Edge" 更可能来自 LLM 的系统性偏差,而不是真实的市场低效。
⑤ 跟单拥挤
你不是唯一监控 SM 的人。SM 甚至可以利用跟单者:先买入 → 等跟单者推高价格 → 反手卖给你。
⑥ 流动性不足
Polymarket 大部分市场 order book 很薄。3+ SM 同向操作后,流动性已被吃光。你的限价单要么不成交,要么成交在更差价位。
0.3 SM 数据的真正价值
SM 数据不是用来跟单的,而是用来:
| 用途 | 说明 |
|---|---|
| 市场选择 | SM 关注的市场 = 有交易量 + 有信息差 = 值得做市的市场 |
| 定价参考 | SM 持仓方向帮助判断 fair price 偏移 |
| 机会发现 | SM 集中某市场 = 可能有错误定价,但要自己判断方向 |
| 风险信号 | SM 大量平仓 = 可能有你不知道的信息,暂停做市 |
| Adverse Selection 保护 | SM 大额交易通过时暂停报价,避免被割 |
0.4 正确的策略:Informed Market Making
❌ 跟单: SM 买 → 你也买 (Taker, 付手续费, 买在高点)
✅ 做市: SM 买 → 你的报价偏移到 SM 方向 (Maker, 赚手续费 + spread + 方向)
以下是完整的 Informed Market Making 策略框架。
1. 费率结构
Polymarket CLOB 费率:
2. 策略核心:Informed Market Making
2.1 两层收益叠加
总收益 = Spread 收益 + Maker Rebate + 方向性收益(Alpha)
~~~~~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
确定性收益 确定性收益 概率性收益(靠信号质量)
与纯跟单的区别:跟单是 Taker(交手续费 + 只赚 alpha)。
做市是 Maker(赚手续费 + 赚 spread + 赚 alpha)。
2.2 报价模式
无方向信号(纯做市):
BID 0.48 ← 0.50 → 0.52 ASK 对称,纯赚 spread
弱方向信号(1-2 SM 同向):
BID 0.49 ← 0.50 → 0.53 ASK 轻微偏移,低风险积累方向
中等方向信号(3+ SM 同向 或 博彩赔率偏差):
BID 0.50 ← 0.50 → 0.54 ASK 明显偏移,积极积累方向
强方向信号(多信号共振):
BID 0.51 ← 0.50 → 0.56 ASK 激进偏移,主动吃方向
(bid 高于 mid = 主动买入,但仍以 Maker 方式挂单等成交)
极强信号 + 时间紧迫:
直接 Taker 吃单 牺牲手续费换速度(极少使用)
3. 方向预测信号系统
3.1 信号源(按可靠性和权重排序)
SIGNAL_WEIGHTS = {
'sm_consensus': 0.30, # SM 共识(核心信号)
'odds_edge': 0.25, # 博彩赔率差(体育类最强信号)
'onchain_flow': 0.20, # 链上资金流向
'price_momentum': 0.10, # 价格动量
'event_catalyst': 0.10, # 事件催化剂
'sentiment': 0.05, # 新闻情绪(最弱,仅辅助)
}
3.2 信号 1: SM Consensus(权重 30%)
数据源: 现有 SM 监控系统(57 个 SM,2700 万条历史数据)
信号分级:
| SM 数量 | Consensus % | 信号强度 | 报价偏移 |
|---|---|---|---|
| 1-2 | 任意 | 弱 | ±0.5% |
| 3-4 | ≥70% | 中 | ±1.5% |
| 5+ | ≥80% | 强 | ±3.0% |
| 5+ | ≥90% + 高额交易 | 极强 | ±5.0% |
SM 质量分层(不等权):
sm_weight = {
'tier1': 3.0, # Top 10 SM (PnL > $2M, 近 30 天活跃)
'tier2': 2.0, # 中等 SM (PnL $500K-$2M)
'tier3': 1.0, # 其他 SM
}
# 加权 consensus 比简单数人头更准
weighted_consensus = sum(sm_weight[tier] * direction) / sum(sm_weight[tier])
SM 按类别评估:
时效性:
3.3 信号 2: 博彩赔率差(权重 25%)
仅适用于体育类市场(Sports 类别 ~30% 的活跃市场)
数据源:
Edge 计算:
# 博彩隐含概率(去 vig 后)
pinnacle_prob = devig(pinnacle_odds)
# Polymarket 价格 = 隐含概率
poly_prob = token_price
# Edge
edge = pinnacle_prob - poly_prob
# 体育市场的博彩公司概率非常准(Brier score ~0.02)
# 所以 edge > 3% 就值得做
if abs(edge) > 0.03:
signal_strength = min(edge * 10, 1.0) # 3% edge → 0.3, 10% edge → 1.0
direction = 'YES' if edge > 0 else 'NO'
为什么这个信号可靠:
3.4 信号 3: 链上资金流向(权重 20%)
数据源: Polygon 链上数据(免费 RPC 或 Alchemy)
信号逻辑:
# 监控特定 market 的 CTF token 转账
# 大额 USDC 流入 = 有人准备大量买入
# 大额 token 转入交易所 = 有人准备卖出
# 1. 监控 USDC 大额转入 CLOB 合约
if usdc_inflow > $50K in 1h:
signal = 'BULLISH' if usdc_into_yes_token else 'BEARISH'
# 2. 监控 token mint/burn
if large_mint_event: # 有人在铸造新的 outcome token
signal = 'NEW_LARGE_PLAYER'
# 3. 已知 SM 地址的链上动作(比 Activity API 更快)
if sm_address_approves_usdc_to_clob:
# SM 正在准备交易!在 API 数据更新之前就知道了
signal = 'SM_PREPARING'
优势: 比 Activity API 更快 5-30 秒(链上确认 vs API 索引延迟)
3.5 信号 4: 价格动量(权重 10%)
# 短期动量(趋势跟随)
momentum_1h = (price_now - price_1h_ago) / price_1h_ago
momentum_6h = (price_now - price_6h_ago) / price_6h_ago
# 预测市场有均值回归倾向(不同于股市)
# 但在事件催化剂驱动时有动量效应
if has_catalyst:
signal = momentum_direction # 趋势跟随
else:
signal = -momentum_direction # 均值回归
# 成交量确认
if momentum_1h > 5% AND volume_1h > 3x_avg:
signal_strength = 'HIGH' # 放量突破 = 真信号
else:
signal_strength = 'LOW' # 缩量变动 = 噪声
3.6 信号 5: 事件催化剂(权重 10%)
# 临近关键日期时,市场波动加大,方向性机会增多
days_to_expiry = (market.end_date - now).days
catalyst_multiplier = {
'>14d': 0.5, # 远期:方向信号弱,纯做市为主
'7-14d': 1.0, # 中期:正常权重
'3-7d': 1.5, # 近期:方向信号放大
'1-3d': 2.0, # 临近:方向主导(但风险也大)
'<1d': 0.0, # 最后一天:停止做市,清仓
}
# 特定事件类型的催化剂
event_catalysts = {
'sports': ['game_day', 'injury_report', 'lineup_announce'],
'politics': ['debate', 'poll_release', 'endorsement'],
'crypto': ['fed_meeting', 'eth_upgrade', 'btc_halving'],
'geopolitics': ['un_vote', 'summit', 'military_action'],
}
3.7 信号 6: 新闻情绪(权重 5%)
# 不用 LLM 估概率(不可靠),只做情绪分类
# 用 Google News RSS 搜索市场相关新闻
news = search_google_news(market.question, max_results=10)
sentiment = classify_sentiment(news) # POSITIVE / NEGATIVE / NEUTRAL
# 分类方法:关键词 + 简单 NLP,不用 LLM
# 只在极端情绪时作为辅助信号
if sentiment == 'VERY_POSITIVE' AND sentiment_count > 5:
signal = 'YES', strength=0.3
elif sentiment == 'VERY_NEGATIVE' AND sentiment_count > 5:
signal = 'NO', strength=0.3
3.8 综合信号计算
def calculate_direction_signal(market):
"""返回 (-1.0 到 +1.0) 的方向信号,正=YES 负=NO"""
signals = {}
# 各信号源独立计算
signals['sm'] = get_sm_consensus_signal(market) # -1.0 ~ +1.0
signals['odds'] = get_odds_edge_signal(market) # -1.0 ~ +1.0 (仅体育)
signals['flow'] = get_onchain_flow_signal(market) # -1.0 ~ +1.0
signals['momentum'] = get_momentum_signal(market) # -1.0 ~ +1.0
signals['catalyst'] = get_catalyst_signal(market) # 0.5 ~ 2.0 (乘数)
signals['sentiment'] = get_sentiment_signal(market) # -1.0 ~ +1.0
# 加权合成
weighted = 0
total_weight = 0
for name, value in signals.items():
if name == 'catalyst':
continue # catalyst 是乘数
w = SIGNAL_WEIGHTS[name]
# 体育市场没有 odds 信号时重新分配权重
if name == 'odds' and signals['odds'] is None:
continue
weighted += value * w
total_weight += w
if total_weight > 0:
composite = weighted / total_weight
else:
composite = 0
# 应用催化剂乘数
composite *= signals.get('catalyst', 1.0)
# 截断到 [-1, 1]
composite = max(-1.0, min(1.0, composite))
return composite
4. 报价引擎
4.1 从信号到报价
def calculate_quotes(market, signal, inventory):
"""根据方向信号和库存计算 bid/ask"""
mid = get_mid_price(market)
base_spread = calculate_base_spread(market)
# ── 方向偏移 ──
# signal > 0 = 看涨 YES → bid 上移(想买),ask 上移(不想卖)
# signal < 0 = 看涨 NO → bid 下移(不想买 YES),ask 下移(想卖 YES)
direction_skew = signal * MAX_DIRECTION_SKEW # MAX = 5%
# ── 库存偏移 ──
# 持有太多 YES → 想卖 YES → ask 下移
inventory_skew = -inventory.net_yes_exposure * INVENTORY_PENALTY
# ── 合成 ──
fair_price = mid + direction_skew + inventory_skew
# ── 不对称 Spread ──
if signal > 0.3: # 看涨
bid_spread = base_spread * 0.5 # 压缩 bid spread(更愿意买)
ask_spread = base_spread * 1.5 # 放大 ask spread(不愿意卖)
elif signal < -0.3: # 看跌
bid_spread = base_spread * 1.5
ask_spread = base_spread * 0.5
else: # 中性
bid_spread = base_spread
ask_spread = base_spread
bid = fair_price - bid_spread
ask = fair_price + ask_spread
# ── Size 调整 ──
base_size = calculate_base_size(market)
if abs(signal) > 0.6: # 强信号
# 信号方向加大 size,反方向减小 size
if signal > 0:
bid_size = base_size * 2.0 # 多买
ask_size = base_size * 0.5 # 少卖
else:
bid_size = base_size * 0.5
ask_size = base_size * 2.0
else:
bid_size = base_size
ask_size = base_size
return Quote(bid, bid_size, ask, ask_size)
4.2 报价更新频率
UPDATE_TRIGGERS = {
'periodic': 30, # 每 30 秒常规更新
'sm_activity': 0, # SM 交易 → 立即更新
'price_change': 0.02, # 价格变动 > 2% → 立即更新
'fill': 0, # 自己的单被成交 → 立即更新
'inventory_limit': 0, # 库存接近限制 → 立即更新
}
5. 市场选择引擎
5.1 Market Scoring
def score_market(market):
"""评估一个市场是否值得做市,返回 0-100 分"""
score = 0
# 交易量(最重要)
if market.daily_volume > 50000: score += 25
elif market.daily_volume > 10000: score += 20
elif market.daily_volume > 5000: score += 15
elif market.daily_volume > 1000: score += 5
# SM 关注度
sm_count = count_sm_active(market, hours=48)
score += min(sm_count * 5, 20) # 最多 20 分
# Spread 机会
current_spread = market.ask - market.bid
if current_spread > 0.05: score += 15 # 5% spread = 大机会
elif current_spread > 0.03: score += 10
elif current_spread > 0.02: score += 5
# 方向信号强度
signal = abs(calculate_direction_signal(market))
score += signal * 20 # 最多 20 分
# 到期时间
days = (market.end_date - now).days
if 3 < days < 30: score += 10 # 最佳窗口
elif days > 30: score += 5 # 太远
elif days <= 3: score += 0 # 太近,风险大
# 体育 + 有博彩赔率 = 额外加分
if market.category == 'Sports' and has_odds_data(market):
score += 10
return score
# 选择 Top N 个市场做市
active_markets = sorted(all_markets, key=score_market, reverse=True)[:MAX_MARKETS]
6. 库存管理(方向性增强版)
6.1 有信号时的库存规则
# 传统做市:库存是风险,要减
# Informed MM:有方向信号时,库存是收益来源
def manage_inventory(market, inventory, signal):
# 库存与信号同向 = 好事(方向性持仓)
# 库存与信号反向 = 坏事(被割了或信号错误)
inventory_direction = 1 if inventory.net_yes > 0 else -1
aligned = (inventory_direction * signal) > 0
if aligned:
# 库存和信号同向 → 放宽库存限制
effective_max = MAX_POSITION * 1.5
# 但仍然要有上限
if abs(inventory.net_exposure) > effective_max:
reduce_inventory()
else:
# 库存和信号反向 → 积极减仓
if abs(signal) > 0.5:
# 强反向信号 → 快速清仓
cancel_all_orders(market)
place_aggressive_exit_order(market, inventory)
else:
# 弱反向 → 通过报价偏移慢慢减
skew_quotes_to_reduce(market, inventory)
6.2 到期管理
def expiry_management(market, inventory, signal):
days = (market.end_date - now).days
if days > 7:
# 正常做市 + 方向偏移
return 'NORMAL'
elif 3 < days <= 7:
# 减小仓位上限,但强信号仍可持有
max_position *= 0.5
return 'REDUCED'
elif 1 < days <= 3:
if abs(signal) > 0.7:
# 强信号 → 保留方向性仓位(这是赚大钱的时刻)
# 但停止做市(不再双边挂单)
return 'DIRECTIONAL_ONLY'
else:
# 弱信号 → 开始清仓
return 'LIQUIDATING'
elif days <= 1:
if abs(signal) > 0.9 and aligned_with_inventory:
# 极强信号 + 库存同向 → 持有到结算
return 'HOLD_TO_SETTLEMENT'
else:
# 否则全部清仓
return 'FORCE_CLOSE'
7. 风险控制
7.1 硬性限制
RISK_LIMITS = {
# 仓位限制
'max_position_per_market': 0.05, # 单市场最大仓位 = 5% 资金
'max_directional_position': 0.08, # 有强信号时可放宽到 8%
'max_total_exposure': 0.40, # 总敞口 = 40% 资金
'max_category_exposure': 0.15, # 单类别最大 = 15%
# 亏损限制
'max_loss_per_market': 0.03, # 单市场最大亏损 = 3% 资金
'max_daily_loss': 0.05, # 日最大亏损 = 5% 资金
'max_weekly_loss': 0.10, # 周最大亏损 = 10% 资金
# 做市参数
'min_spread': 0.01, # 最小 spread = 1%
'max_markets_active': 10, # 同时做市最多 10 个市场
# 方向性交易参数
'min_signal_for_skew': 0.2, # signal < 0.2 → 纯对称做市
'min_signal_for_directional': 0.6, # signal > 0.6 → 可以做方向性仓位
'max_direction_skew': 0.05, # 最大报价偏移 5%
}
7.2 紧急停止
CIRCUIT_BREAKERS = {
'daily_loss_5pct': '停止所有做市,撤所有单,通知微信',
'weekly_loss_10pct': '停止 48h,人工审查后恢复',
'price_jump_15pct': '撤该市场所有单,暂停 5 分钟',
'api_latency_5s': '撤所有单,等 API 恢复',
'sm_whale_trade': '暂停该市场 60 秒,重新评估',
'signal_flip': '信号反转 → 撤单 + 重新报价',
'settlement_dispute': '立即平仓退出该市场',
}
7.3 策略衰减检测
def check_strategy_health():
"""滚动检查策略是否还在赚钱"""
rolling_7d_pnl = get_rolling_pnl(days=7)
rolling_30d_sharpe = get_rolling_sharpe(days=30)
fill_rate_7d = get_fill_rate(days=7)
adverse_selection_rate = get_adverse_selection_rate(days=7)
warnings = []
if rolling_7d_pnl < 0:
warnings.append('7 天 PnL 为负')
if rolling_30d_sharpe < 0.5:
warnings.append('30 天 Sharpe < 0.5')
if fill_rate_7d < 0.1:
warnings.append('成交率 < 10%(报价没竞争力)')
if adverse_selection_rate > 0.5:
warnings.append('被 informed trader 割的比例 > 50%')
if len(warnings) >= 2:
send_wechat_alert(f'⚠️ 策略健康警告: {warnings}')
reduce_all_positions(50%) # 减仓 50%
if len(warnings) >= 3:
stop_all_trading()
send_wechat_alert('🛑 策略暂停!需要人工审查')
8. 收益模型(方向性增强版)
8.1 收益分解
假设 $10,000 资金,同时做市 5 个市场:
A. Spread 收益(确定性)
5 市场 × $400 成交/天 × 2% spread = $40/天
B. Maker Rebate(确定性)
5 市场 × $400 × 0.5% rebate = $10/天
C. 方向性收益(概率性)
假设 60% 的方向信号正确(SM + 赔率的优势)
平均仓位 $500,平均持有期 5 天
正确时赚 +15%,错误时亏 -10%(非对称因为做市有 spread 缓冲)
每天 ~1 个方向信号:
0.6 × $500 × 15% = $45(赢)
0.4 × $500 × 10% = $20(亏)
净 = $25/天
总毛收益 = $40 + $10 + $25 = $75/天
扣除:
- 库存亏损: -$15/天 (估)
- 不利选择: -$10/天 (估)
- Gas 费: -$2/天
净收益 = $48/天
年化 = $17,520 (175% APR)
8.2 与纯策略的对比
| 策略 | 日收益 | 年化 | 最大回撤 | Sharpe |
|---|---|---|---|---|
| 纯跟单(Taker) | -$5~$10 | -18%~36% | -30% | <0.5 |
| 纯做市(无方向) | $20~30 | 73%~110% | -10% | 1.5 |
| Informed MM | $40~60 | 146%~219% | -15% | 2.0+ |
9. 技术架构
┌─────────────────────────────────────────────────────┐
│ Informed Market Maker Engine │
├────────────┬──────────────┬──────────┬──────────────┤
│ Signal │ Price │ Order │ Risk │
│ Engine │ Engine │ Manager │ Engine │
│ │ │ │ │
│ • SM │ • Fair price │ • Place/ │ • Position │
│ consensus│ • Direction │ cancel │ limits │
│ • Odds │ skew │ • Fill │ • Loss │
│ edge │ • Inventory │ track │ limits │
│ • Onchain │ skew │ • Quote │ • Circuit │
│ flow │ • Spread │ update │ breakers │
│ • Momentum │ calc │ │ • Health │
│ • Catalyst │ │ │ check │
│ • Sentiment│ │ │ │
├────────────┴──────────────┴──────────┴──────────────┤
│ Market Selector │
│ Score markets → Pick Top N → Monitor lifecycle │
├─────────────────────────────────────────────────────┤
│ Data Layer │
│ • CLOB WebSocket (real-time orderbook + fills) │
│ • Polygon RPC (on-chain flow monitoring) │
│ • SM Activity DB (27M+ records) │
│ • Odds API (sports markets) │
│ • Google News RSS (sentiment) │
│ • Market Metadata (expiry, volume, category) │
├─────────────────────────────────────────────────────┤
│ Notification Layer │
│ • WeChat alerts (via OpenClaw) │
│ • Web Dashboard (existing Flask app) │
│ • Strategy health reports │
└─────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
CLOB API SQLite DB WeChat/OpenClaw
(trading) (state) (monitoring)
10. 实施路线
Phase 0: 准备(1 周)
py-clob-client,连通 CLOB APIPhase 1: 纯做市 Paper Trading(2 周)
Phase 2: 加入方向信号 Paper Trading(2 周)
Phase 3: 小资金实盘(2 周)
Phase 4: 扩展(持续)
11. 监控与报告
每日自动报告(微信推送)
📊 做市日报 2026-04-02
💰 今日 PnL
Spread 收益: +$42.30
Rebate: +$11.50
方向性收益: +$38.20 (3 赢 1 亏)
库存变动: -$12.40
净收益: +$79.60
📈 活跃市场 (5/10)
1. Iran by April 30 → BID 0.22 / ASK 0.26 | PnL +$15
2. NCAA Michigan → BID 0.31 / ASK 0.35 | PnL +$22
...
🎯 方向性持仓
Iran YES: $300 (signal: 0.72, SM: 4)
NCAA No: $200 (signal: -0.55, odds edge: 8%)
⚠️ 风险状态
总敞口: 23% (< 40% ✅)
最大单仓: 4.2% (< 5% ✅)
日亏损: 0% (< 5% ✅)
策略健康: ✅ Sharpe 2.1