🧪 模拟盘下单与平仓策略
香港天气合约 · Polymarket ·
1. 系统概述
模拟盘与实盘做市系统共享同一套预测模型和市场数据,但在模拟账户中交易,不涉及真实资金。 策略分为两个阶段:建仓和半仓平仓。
📡
发现市场
Gamma API → 今日香港合约
→
🔮
检测边缘
公平价 − 市场中间价
→
📥
建仓
买入偏见 / 卖出偏见
→
📤
半仓平仓
90%公平价 × 一半仓位
模拟盘使用 10 倍仓位(基础单 100 股 vs 实盘 10 股),最大单边持仓 500 股。
| 特性 | 模拟盘 | 实盘 |
|---|---|---|
| 基础单大小 | 100 股 | 10 股 |
| 单边最大持仓 | 500 股 | 风控管理 |
| 边缘阈值(最低) | 实盘的 ½ | 完整 |
| 自动交易开关 | simu_auto_trading.json | auto_trading.json |
| 下单方式 | 模拟撮合 | 真实 CLOB 挂单 |
| 退出策略 | 半仓平仓 | 做市 + 手动 |
2. 配置与开关
2.1 模拟盘主开关
data/mm/simulation.json
enabled: true启用 10× 仓位、减半边缘阈值
data/mm/simu_auto_trading.json
enabled: true控制模拟盘是否产生成交
simu_auto_trading.enabled 独立于
auto_trading.enabled(实盘开关)。实盘暂停时模拟盘仍可运行。
2.2 仓位倍数
SIM_SIZE_MULTIPLIER = 10 # 实盘的 10 倍
BASE_ORDER_SIZE = 10.0 # 实盘:每边 10 股
MIN_ORDER_SIZE = 6.0 # 实盘最小(5 股扣费后约 4.7 股)
# 模拟盘实际大小:
模拟基础单 = 10 × 10 = 100 股
模拟最小单 = 6 × 10 = 60 股
单合约单边最大 = 500 股
2.3 交易时间
交易开始 = 9:00 北京时间
交易结束 = 17:30 北京时间
扫描间隔 = 60 秒(Cron:每分 8-17 点)
模拟盘不受交易时间限制。当
sim_mode = true 时,
can_trade 始终为真。
3. 扫描周期(每 60 秒)
每次扫描执行以下流水线:
🔮
1. 获取预测
结算预测 + 概率分布 + 硬下界
→
🔍
2. 拉取市场
Gamma API → 按日期+硬下界过滤
→
💹
3. 获取价格
Gamma outcomePrices + CLOB 盘口
→
📐
4. 计算边缘
公平价 − 市场中间价 → 报价
→
⚡
5. 模拟成交
报价与盘口交叉 → 建仓成交
→
⚖️
6. 半仓平仓
遍历所有持仓 → 尝试平半仓
3.1 市场过滤
合约需通过三层过滤才可交易:
| 过滤条件 | 规则 | 示例 |
|---|---|---|
| 日期 | 仅当日合约(MM-DD 格式匹配) |
5月14日 → target_date = 05-14 |
| 硬下界 | 温度低于午夜最高温 → 不可能,除非有持仓 | 午夜=29.2°C → T21-T28 被拒绝 |
| 活跃 | 市场必须在 Polymarket 上活跃且未关闭 | — |
例外:已被硬下界排除但有持仓的合约,保留以监控和退出,避免留下孤儿仓位。
4. 建仓逻辑
4.1 报价模式(Quote Mode)
每次扫描为每个活跃市场生成一份报价,报价模式决定操作方向:
| 模式 | 触发条件 | 操作 | 买价 | 卖价 |
|---|---|---|---|---|
| buy_biased | edge > 0,无持仓 | 买入 YES | 买一 + 1tick |
卖一(被动) |
| sell_biased | edge < 0,无持仓 | 买入 NO(通过卖出 YES) | 买一(被动) |
卖一 − 1tick |
| buy_biased_holding | edge > 0,持有 YES | 加仓 + 赚价差 | 买一 + 1tick |
卖一 − 1tick ≥ 成本+1¢ |
| sell_biased_holding | edge < 0,持有 NO | 加仓 + 赚价差 | 买一 + 1tick ≤ 成本−1¢ |
卖一 − 1tick |
| closing_long | edge 消失,持有 YES | 市场价卖出 YES | 被动(远低于市价) | 买一(激进) |
| closing_short | edge 消失,持有 NO | 市场价买入平空 | 卖一(激进) |
被动(远高于市价) |
| none | |edge| 低于阈值,无持仓 | 跳过 | 0 | 0 |
4.2 边缘阈值(Edge Threshold)
| 合约类型 | 实盘最低 | 实盘强信号 | 模拟最低(½) | 模拟强信号(½) |
|---|---|---|---|---|
| exact(主导温度) | 0.02 | 0.08 | 0.01 | 0.04 |
| exact(非主导温度) | 0.06 | 0.15 | 0.03 | 0.075 |
| or_higher / or_lower | 0.03 | 0.10 | 0.015 | 0.05 |
| 硬边界(结算确认) | 0.01 | 0.03 | 0.01 | 0.03 |
4.3 模拟撮合逻辑
# 买入 YES:我方买价 ≥ 市场卖一即成交
if side == 'BUY' and our_bid >= market_ask:
fill_price = market_ask # 以卖一价成交
# 卖出 YES:我方卖价 ≤ 市场买一即成交
if side == 'SELL' and our_ask <= market_bid:
fill_price = market_bid # 以买一价成交
# 买入 NO(sell_biased 转换为 NO 侧):
# 由 YES 卖价推导:no_bid = 1.0 − ask_price
if no_bid >= no_market_ask:
fill_price = no_market_ask
高价合约调整:当 YES 超过 70¢ 时,
no_bid = 1 − ask_price 换算出的 NO 买价会偏低。
系统自动将 no_bid 提升到实际 NO 盘口的卖一价,以确保成交。
4.4 仓位冲突处理
建仓前检查是否存在反向持仓:
| 场景 | 处理方式 |
|---|---|
| edge > 0(买入)+ 持有 NO(空头) | 先平空再买入 |
| edge < 0(卖出)+ 持有 YES(多头) | 切换为 closing_long,优先平仓 |
5. 平仓逻辑
持仓可通过两种机制平仓:
5.1 信号驱动退出
当建仓时边缘较强,但后续边缘衰减到阈值以下,报价模式切换为
closing_long 或 closing_short,
以激进市价单退出。
| 模式 | 退出价 | 数量 |
|---|---|---|
| closing_long | 按 买一价 卖出 |
min(报价卖量, 持仓 YES 量) |
| closing_short | 按 卖一价 买入 |
min(报价买量, 持仓 NO 量) |
5.2 半仓平仓
独立于边缘信号,每次扫描遍历所有持仓尝试平半仓。 详见 §6。
6. 半仓平仓策略
参考来源:实盘交易页面
mm_weather.html 中的
⚖️ 公平价平仓 和 半仓折价 按钮逻辑。
6.1 规则总表
| 规则 | YES(多头) | NO(空头) |
|---|---|---|
| 公平价 | _fair_from_dist(temp, comp_type, prob_dist) |
1.0 − fair_price |
| 基础平仓价 | max(fair, market_bid) |
max(no_fair, no_market_bid) |
| 目标价(90%) | 基础平仓价 × 0.9 |
基础平仓价 × 0.9 |
| 成交条件 | market_bid ≥ 目标价 |
no_market_bid ≥ 目标价 |
| 平仓数量 | max(5, floor(持仓 / 2)) |
max(5, floor(持仓 / 2)) |
| 最低触发持仓 | ≥ 5 股 | ≥ 5 股 |
| 成交价 | 买一价(卖在买盘) |
NO 买一价(卖在买盘) |
6.2 从概率分布计算公平价
def _fair_from_dist(temp, comp_type, dist):
if comp_type == 'exact':
return dist[temp] # 例如 P(30°C) = 23.6%
elif comp_type == 'or_higher':
return Σ P(t) for t ≥ temp # 例如 P(≥31°C) = 4.4%
elif comp_type == 'or_lower':
return Σ P(t) for t ≤ temp # 例如 P(≤20°C)
6.3 实例演算
# 持仓:YES 500股 @ 30°C exact,成本=$26.81(均价 5.36¢)
# 概率分布:P(30°C) = 23.62%
公平价 = 0.2362 # 23.62¢
基础平仓价 = max(公平价, 买一价) # max(23.62¢, 9¢) = 23.62¢
目标价 = 基础平仓价 × 0.9 # 23.62 × 0.9 = 21.26¢
# 成交判断:买一价(9¢) ≥ 目标价(21.26¢)?
# → 9¢ < 21.26¢ → 不成交(市场价太低,继续持有)
# 若市场涨到 22¢ 买一:
# → 22¢ ≥ 21.26¢ → 成交!SELL 250 YES @ 22¢
# 盈亏 = (22¢ − 5.36¢) × 250 = $41.60
为什么折价 10%?在公平价基础上让利 10% 能显著提高成交概率,
在拿到好价格和实际成交之间取得平衡。参考实盘
半仓折价 按钮的设计。
7. 仓位大小与上限
7.1 仓位计算
# 仓位大小随边缘强度与合约类型动态调整
bid_size, ask_size = _calculate_sizes(
edge, fair_price, comp_type, net_exposure,
bid_price, ask_price, mode, simulation=True
)
# 基础大小 × 10(模拟倍率),再按边缘和合约类型缩放
7.2 仓位上限
| 上限 | 值 | 执行方式 |
|---|---|---|
| 单边最大 | 500 股 | 成交前截断 |
| 净持仓 | |YES − NO| ≤ 500 | 缩减成交量至不超过上限 |
| 最低金额 | $1.00/单 | 跳过低于最低金额的挂单 |
上限仅限制增加仓位的操作。平仓(减少 |净持仓|)永远不受上限约束——始终可以退出。
8. 盈亏计算
8.1 单笔盈亏
# 买入(开多或平空):
if 已有_NO > 0: # 平空
平仓量 = min(买入量, 已有_NO)
盈亏 = (NO均价 − 成交价) × 平仓量
else: # 开多
盈亏 = 0.0
# 卖出(平多):
if 已有_YES > 0: # 平多
平仓量 = min(卖出量, 已有_YES)
均价 = 总成本 / YES数量
盈亏 = (成交价 − 均价) × 平仓量
else: # 开空
盈亏 = 0.0
8.2 仓位追踪字段
| 字段 | 含义 |
|---|---|
yes_tokens | 持有的 YES 数量(多头) |
no_tokens | 持有的 NO 数量(空头) |
total_cost | 累计成本(买入花费 − 卖出收入) |
realized_pnl | 该仓位所有平仓盈亏之和 |
total_pnl | 全局所有仓位已实现盈亏总和 |
8.3 盈亏追踪示例
# T=1: BUY YES 180 @ 8.2¢ → 成本=$14.76, 盈亏=$0.00
# YES=180, 成本=$14.76, 均价=8.2¢
# T=2: BUY YES 180 @ 7.7¢ → 成本+=$13.86, 盈亏=$0.00
# YES=360, 成本=$28.62, 均价=7.95¢
# T=3: SELL YES 90 @ 12.0¢ → 平掉 360 股中的 90 股
# 盈亏 = (12.0¢ − 7.95¢) × 90 = $3.65
# YES=270, 成本=$21.47, 已实现盈亏=$3.65
# T=4: SELL YES 120 @ 9.0¢(半仓平仓)
# 盈亏 = (9.0¢ − 7.95¢) × 120 = $1.26
# YES=150, 成本=$11.93, 已实现盈亏=$4.91
9. 边缘与公平价计算
9.1 公平价
def get_fair_price(temp, comp_type):
dist = get_prob_distribution()
if comp_type == 'exact':
return dist[temp] # 原始概率
elif comp_type == 'or_higher':
return Σ dist[t] for t ≥ temp # ≥ temp 的累计概率
elif comp_type == 'or_lower':
return Σ dist[t] for t ≤ temp # ≤ temp 的累计概率
9.2 边缘
边缘 = 公平价 − 市场中间价 # 正值 = 被低估 → 买入
# 负值 = 被高估 → 卖出
9.3 今日概率分布
| 温度 | 23° | 24° | 25° | 26° | 27° | 28° | 29° | 30° | 31° | 32°+ |
|---|---|---|---|---|---|---|---|---|---|---|
| 概率 | 0% | 0% | 0% | 0% | 0% | 0% | 72% | 23.6% | 1.3% | 3.1% |
硬下界:午夜最高温 = 29.2°C。所有低于 29°C 的合约公平价 = 0,
直接拒绝(除非已有持仓需要监控退出)。
10. 数据文件
| 文件路径 | 用途 |
|---|---|
data/mm/simulation.json | 模拟模式开关(启用 10× 仓位) |
data/mm/simu_auto_trading.json | 模拟盘成交开关 |
data/mm/auto_trading.json | 实盘交易开关 |
data/mm/weather_paper_trader_state.json | 持久化持仓 + 交易记录 + 盈亏 |
data/mm/weather_state.json | 当前扫描状态(报价、元数据) |
data/mm/weather_trades.jsonl | 追加式交易日志 |
data/mm/weather_quotes.jsonl | 追加式报价日志 |
data/mm/pending_orders.json | 手动审批队列(仅实盘) |
data/hko/hko_prediction.json | 预测模型输出 |
data/hko/current.json | HKO 实时观测 |