如何借助 Claude Code,把 Polymarket 的 5 分钟 BTC 市场变成月入 1万美元的交易机器人

大多数人玩 Polymarket 就像去赌场一样:选个方向,双手合十祈祷,第二天再来看结果
但我现在不这么操作了
我专攻 BTC(比特币)的 5 分钟盘。每 5 分钟就会开一个新盘口:BTC 的价格会高于还是低于目标价?你买入份额,等待盘口结算。要么赚,要么赔,接着开启下一轮。
每天 400 多个盘口,24 小时连轴转,周末无休。
我搭建了一个自动交易机器人,大部分代码都是 Claude Code 帮忙写的。总成本:每个月 25 美元。
过去 30 天:净赚 14200 美元。胜率:71%。平均持仓时间:3 分 12 秒。
以下就是我打造它的完整过程
写在前面:
这个机器人是基于 4 个开源代码库、Claude Code 以及一台 5 美元的 VPS(虚拟机)运行的。这里没有任何其他付费,下面提供的所有链接都完全免费
首先需要了解为什么 5 分钟盘与众不同
传统的 Polymarket 盘口通常需要几天甚至几周才会结算。比如你花 42 美分买入“特朗普赢得 2028 年大选”,然后苦等三个月,祈祷自己押中了。
5 分钟 BTC 盘口则截然相反。它们每 5 分钟结算一次。运行周期如下:
- 开盘给出一个目标价——即 BTC 的价格基准
- 你买入“看涨 (UP)”或“看跌 (DOWN)”份额
- 5 分钟后,智能合约读取 Chainlink 预言机的喂价数据
- 如果 BTC 现价高于目标价 -> “看涨”份额兑付 1 美元,“看跌”份额归零
- 紧接着立即开启下一个新盘口
无需漫长等待,不用担心交易逻辑失效,更没有隔夜风险。
但这里有个难点:5 分钟的时间窗口对传统技术指标来说太短了。RSI、MACD、EMA —— 在 5 分钟级别里没一个靠得住。信噪比低得令人发指。
所以我不再盯着指标看,而是开始研究订单薄
首先:搞懂资金的真实流向
在写下哪怕一行代码之前,必须先弄明白到底在交易什么。
Polymarket 采用的是一种混合型中央限价订单簿(Central Limit Order Book)模式。为了保证速度,订单撮合在链下进行,随后通过 Polygon 上的 CTF Exchange 智能合约在链上结算。每一笔交易都具备原子性——条件代币的铸造和转移都在一笔交易中完成
Polymarket 上没有市价单。所有的交易都是限价单。当你在界面上点击“买入”时,它实际上是以最优卖价下了一个限价单。这一点至关重要,因为在 5 分钟的窗口期内,以 48 美分成交还是 52 美分成交,往往决定了你是盈利还是亏损
我订阅了 Polymarket 的 WebSocket,用来接收实时的订单簿更新。不采用轮询,没有延迟。终端界面显示双边的实时深度,每当有订单下达或取消,都会立刻刷新
在动代码之前,我盯着这些数据整整看了两周
我发现:
- 聪明的资金通常在开盘后 30-90 秒进场——绝不会一开盘就冲进去
- 单边出现大额订单,大约有 63% 的概率能预测最终结果——单靠这一个指标还不够,但如果结合价格数据,就是一个强烈的信号
- 在最后 60 秒,订单簿会变得非常薄弱——这正是大多数散户资金进场并被“收割”的时候
第一步:多源价格分歧
目标价是由 Chainlink 提供的。但是,BTC 同时在几十家交易所进行交易,而且各个平台的价格总是存在差异。
我同步抓取了三个数据源的 BTC 价格:
import asyncio
import aiohttp
async def get_prices():
async with aiohttp.ClientSession() as session:
binance = session.get("https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT")
coinbase = session.get("https://api.coinbase.com/v2/prices/BTC-USD/spot")
chainlink = get_chainlink_price() # on-chain read
results = await asyncio.gather(binance, coinbase, chainlink)
return {
"binance": float((await results[0].json())["price"]),
"coinbase": float((await results[1].json())["data"]["amount"]),
"chainlink": results[2],
}
当币安(Binance)和 Coinbase 上的价格都涨到了目标价之上,而 Chainlink 还没有更新时——这就是一个“价差(gap)”。 Chainlink 的喂价迟早会跟上。问题在于,它是否能在 5 分钟的结算窗口关闭前跟上。
Claude Code 分析了过去 3 周的历史价格背离数据,发现了这样一个规律
> "analyze the lag between Binance/Coinbase price movements
and Chainlink feed updates. what's the average delay?
what's the probability that Chainlink follows within 5 minutes?"
Claude: "Average Chainlink update lag: 14 seconds after
major exchange price movements. When both Binance and
Coinbase move >$50 in the same direction within 30 seconds,
Chainlink follows within 2 minutes 94% of the time."
当两家交易所的数据一致时,后续如期兑现的概率高达 94%。这可不是抛硬币碰运气。这就是实打实的交易优势
第二步:订单簿失衡检测

价格分歧能告诉你 BTC 实际的走向,而订单簿则暴露了其他交易员以为它会怎么走。
def calculate_imbalance(order_book):
"""
Measures the ratio of buy-side depth to sell-side depth.
Values > 1.0 = more buyers than sellers = bullish pressure.
"""
bid_depth = sum(order["size"] for order in order_book["bids"][:10])
ask_depth = sum(order["size"] for order in order_book["asks"][:10])
if ask_depth == 0:
return float('inf')
return round(bid_depth / ask_depth, 3)
失衡比率一旦超过 1.8,意味着买方正在大举挂单,买盘堆积;若低于 0.55,则说明卖方占据主导。
但光看这些冷冰冰的数据还不够。进场的时机才是关键:
def detect_smart_entry(imbalance_history, threshold=1.8, window_seconds=90):
"""
Smart money enters 30-90 seconds after market open.
If imbalance spikes during that window, it's a signal.
"""
early_window = [
ib for ib in imbalance_history
if 30 <= ib["seconds_since_open"] <= window_seconds
]
if not early_window:
return None
max_imbalance = max(ib["ratio"] for ib in early_window)
if max_imbalance >= threshold:
return {
"direction": "UP",
"strength": max_imbalance,
"confidence": min(max_imbalance / 2.5, 0.95)
}
elif min(ib["ratio"] for ib in early_window) <= 1/threshold:
return {
"direction": "DOWN",
"strength": 1 / min(ib["ratio"] for ib in early_window),
"confidence": min((1/min(ib["ratio"] for ib in early_window)) / 2.5, 0.95)
}
return None
当那些真正懂行的资金在开盘的前 90 秒大举挂单,而且价格分歧也印证了这个走向时——这就是我果断出手的时刻。
第三步:信号融合

单靠哪一个信号都不行。只看价格分歧:胜率 63%。只看订单簿失衡:胜率 58%。两者结合:胜率 71%。
Claude Code 编写了信号融合器:
def should_trade(price_data, order_book, market):
"""
Only trade when both signals agree.
Kill everything else.
"""
# Signal 1: Price divergence
binance_delta = price_data["binance"] - market["price_to_beat"]
coinbase_delta = price_data["coinbase"] - market["price_to_beat"]
exchanges_agree = (
(binance_delta > 50 and coinbase_delta > 50) or
(binance_delta < -50 and coinbase_delta < -50)
)
if not exchanges_agree:
return None # no clear divergence
direction = "UP" if binance_delta > 0 else "DOWN"
# Signal 2: Order book confirmation
imbalance = calculate_imbalance(order_book)
book_confirms = (
(direction == "UP" and imbalance > 1.8) or
(direction == "DOWN" and imbalance < 0.55)
)
if not book_confirms:
return None # divergence without book support = trap
# Both signals agree
confidence = min(0.95, 0.6 + abs(binance_delta) / 500 + abs(imbalance - 1.0) / 5)
return {
"direction": direction,
"confidence": round(confidence, 3),
"size": kelly_size(confidence, market["price"], bankroll=2000),
}
85% 的 5 分钟窗口在这一步会被直接过滤掉。按兵不动。机器人只有在两个信号完美共振时才会果断进场。
第四步:执行时机
这是绝大多数人容易犯错的地方。他们一看到信号就立马满仓杀入。在 Polymarket 上,这无异于自寻死路。
别忘了:这里没有市价单。一切都是限价单。在短短的 5 分钟窗口里,成交速度决定一切。
async def execute_trade(signal, market, ws_connection):
"""
Place order at optimal timing:
- Not too early (signal might reverse)
- Not too late (can't fill, can't exit)
- Sweet spot: 60-180 seconds after market open
"""
seconds_since_open = market["elapsed_seconds"]
if seconds_since_open < 60:
await asyncio.sleep(60 - seconds_since_open) # wait for confirmation
if seconds_since_open > 180:
return None # too late - can't exit if wrong
# Place limit order at current best price
side = "buy" if signal["direction"] == "UP" else "buy" # always buying shares
token_id = market["up_token"] if signal["direction"] == "UP" else market["down_token"]
order = await place_limit_order(
token_id=token_id,
price=market["best_ask"][signal["direction"].lower()],
size=signal["size"],
)
return order
最佳窗口期是开盘后的 60 到 180 秒之间。早于 60 秒,信号还没完全确认;晚于 180 秒,万一行情反转,连跑路的时间都不够。
第五步:提前离场(结算前平仓)
这也是我和大多数 5 分钟盘交易员做法截然不同的地方。
绝大多数人会死扛到结算。48 美分买入,干等盘口出结果,要么拿到 1 美元,要么血本无归。
我可不这么干。
只要能锁定利润,我就会提前获利了结。要知道,在整个 5 分钟里,这些份额是可以在订单簿上持续交易的。如果我以 48 美分买入了“看涨 (UP)”,随后价格涨到了 72 美分,我会直接卖给买盘(bid side)套现,稳赚这 24 美分的差价,绝不干等最终的结算。
async def monitor_position(position, market, ws_connection):
"""
Three exit conditions:
1. Profit target: sell when shares hit 75c+ (we entered around 48-52c)
2. Stop loss: sell if shares drop below 35c
3. Time exit: if <60 seconds remain, hold to resolution
"""
while True:
current_price = await get_current_price(position["token_id"])
time_remaining = market["resolution_time"] - time.time()
# Exit 1: Profit target
if current_price >= 0.75:
await sell_shares(position, current_price)
return {"exit": "PROFIT_TARGET", "pnl": current_price - position["entry"]}
# Exit 2: Stop loss
if current_price <= 0.35:
await sell_shares(position, current_price)
return {"exit": "STOP_LOSS", "pnl": current_price - position["entry"]}
# Exit 3: Time - hold to resolution
if time_remaining < 60:
return {"exit": "HOLD_TO_RESOLUTION", "pnl": "pending"}
await asyncio.sleep(2)
为什么要提前离场?
因为链上结算有延迟。当你买入份额时,交易需要在 Polygon 上铸造、确认并最终结算。这都要花时间。如果你在只剩 90 秒的时候买入,万一行情走势不对,你可能根本卖不掉,因为你的份额还没结算完成呢。
提前离场能直接抹掉这个风险。赚走潜在利润的 60-70%,然后潇洒地转战下一个 5 分钟盘。
第六步:引擎循环

整个机器人的运作机制就像一台生命周期引擎。每一个 5 分钟的窗口期,都是一轮完整的循环周期:
async def run_engine():
"""
Main loop. One market lifecycle per 5-minute window.
"""
bankroll = 2000
daily_pnl = 0
trades_today = 0
while True:
market = await get_next_market()
print(f"[{datetime.now()}] New market: {market['question']}")
print(f" Price to Beat: ${market['price_to_beat']:,.2f}")
# Wait for the entry window (60 seconds after open)
await wait_for_entry_window(market)
# Collect signals
prices = await get_prices()
order_book = await get_order_book(market)
signal = should_trade(prices, order_book, market)
if signal is None:
print(f" SKIP - no signal convergence")
await wait_for_next_market(market)
continue
# Execute
position = await execute_trade(signal, market)
if position is None:
print(f" SKIP - execution window missed")
await wait_for_next_market(market)
continue
# Monitor and exit
result = await monitor_position(position, market)
daily_pnl += result.get("pnl", 0)
trades_today += 1
print(f" {result['exit']} | PNL: ${result['pnl']:.2f}")
print(f" Daily: ${daily_pnl:.2f} | Trades: {trades_today}")
# Update bankroll
bankroll += result.get("pnl", 0)
await wait_for_next_market(market)
每天有 400 多个这样的窗口期。机器人只在其中 50 到 60 个窗口出手交易,其余时间全部过滤掉。
技术栈
| Tool | Cost | What It Does |
| -------------------- | ------ | ------------------------------------------------ |
| Claude Code | $20/mo | Strategy logic, signal analysis, code generation |
| VPS (Hetzner) | $5/mo | Runs the engine 24/7 |
| Polymarket WebSocket | Free | Real-time order book data |
| Binance API | Free | BTC price feed |
| Coinbase API | Free | BTC price feed (cross-reference) |
| Chainlink feed | Free | On-chain price (resolution source) |
| Total | $25/mo | |
成果:30 天战绩
第一周基本都在调教模型。起步胜率在 59%。单靠订单簿失衡这一个指标,假信号太多了。
加上了价格分歧过滤器后,胜率直接跳到了 66%。
把进场窗口期从最初的 30-240 秒,精准压缩到了 60-180 秒之间。胜率飙升到了 71%。
随后引入了 75 美分提前止盈的策略。虽然这导致每笔成功交易的平均利润从 47 美元降到了 34 美元,但每笔亏损交易的平均损失却大幅缩减,从 52 美元骤降至 19 美元。最终效果:每周净赚 3100 美元。

过去 30 天数据汇总:
- 交易盘口总数:1,847 个
- 胜率:71%
- 单笔平均盈利:+34 美元
- 单笔平均亏损:-19 美元
- 净利润:+14,200 美元
- 夏普比率 (Sharpe Ratio):2.84
- 单日最高盈利:+1,100 美元
- 单日最大亏损:-280 美元
- 最大回撤:-640 美元
这个机器人运行在芬兰赫尔辛基一台每个月 5 美元的 VPS 上。我每天早上只看一眼。多数日子里,我也就是扫一眼当天的盈亏数字,然后关掉网页就完事了。
踩过的坑(哪些做法行不通)
- 逢盘必做: 每天 400 多个盘口,绝大多数都是噪音。我的机器人只有在两个独立信号相互印证时才会进场。85% 的窗口期都被我直接放弃了。
- 死扛到结算: 结算延迟会带来风险。在 75 美分时提前平仓,其收益表现始终优于持有到最终结算。
- 单一数据源: 光看币安,准确率只有 57%。加上 Coinbase 交叉验证,准确率提高到了 63%。再加上订单簿失衡指标,胜率才最终冲到了 71%。
- 在最后 60 秒交易: 万一做错了,根本没有时间跑路。此时订单簿变得极薄,买卖价差也会拉大。所以我彻底砍掉了所有临近结束前的进场操作。
- 依赖 RSI/MACD 等技术指标: 在 5 分钟级别里纯属废话,噪音太多。我完全抛弃了技术指标,转而死磕订单流和价格分歧。
为什么这套策略眼下依然奏效
Polymarket 上的 5 分钟 BTC 盘口还算是相对新鲜的事物。我所利用的这些订单簿规律之所以存在,主要是因为大多数交易员都在犯以下错误:
- 进场太早(信号还没确认就急着上车)
- 进场太晚(拖到最后 60 秒,买卖价差已经被彻底拉大)
- 死扛到结算,不懂得提前获利了结
- 全凭直觉做单,毫无多源信号交叉验证的意识
随着时间推移,这些套利空间必然会被逐渐压缩。随着更多机器人入场,买卖价差会越来越小,交易优势也会随之缩水。今天一单能赚 34 美元的策略,半年后可能就只能赚 15 美元了。
但至少在眼下,这扇盈利的时间窗口依然敞开着。
没人愿意谈论的残酷真相
亏损是必然的。有些日子机器人会满盘皆绿(亏损),有些周你会觉得交易优势正在消失。
这套逻辑的核心不在于永不亏损,而在于如何通过 1847 次反复操作,做到“小输、大赢”。
我所使用的代码库如下:
- github.com/warproxxx/poly_data —— 获取用于回测的历史交易数据。
- github.com/Polymarket/polymarket-cli —— 负责扫描市场并下单。
- github.com/Polymarket/agents —— 智能体框架及 LLM(大语言模型)集成。
- github.com/KaustubhPatange/polymarket-trade-engine —— 5 分钟盘的市场引擎架构。
其中 80% 的逻辑代码由 Claude Code 完成,我负责制定策略,剩下的交由 VPS 运行。
每月 25 美元成本。一个周末搞定开发。每天只需盯着一个网页。