关于 binance-prediction-updown
用于 Binance BTC 涨跌轮次交易的脚手架技能,面向希望评估自定义概率信号并管理下单流程的开发者。它提供筛选门槛、决策接口、结算赎回和离线评估工具,但不附带交易策略。
主要功能
- 01轮次调度与市场筛选
- 02概率信号与报价比较
- 03下单、结算及赎回处理
- 04预算、仓位与轮次限制
- 05离线回测与定价检验
适用场景
- 01离线评估 BTC 涨跌信号
- 02观察市场报价是否已反映信号
- 03干运行记录决策而不下单
- 04按预算和订单簿深度控制交易
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ binance/ binance-skills-hub --skill binance-prediction-updown安装后在 Claude Code 中输入/binance-prediction-updown确认已加载。
附带文件scripts/backtest.pyscripts/updown.py
详细介绍
Binance 预测涨跌
用于交易定期开盘的 BTC 涨跌轮次的脚手架:轮次调度器、筛选门槛、将你的概率与报价进行比较的决策约定、订单与结算处理、赎回,以及两个离线评估工具。
请先阅读
此处的所有风险控制、投注额和阈值都只是建议,并非安全保障。
- 此技能不提供策略。 随附的钩子只是一个让整个流程运行起来的示例;它读取的数值需要由你测量并提供。“策略钩子”一节中记录的参考信号,扣除成本后每轮约为 +0.65%,误差范围为 ±1.9 个百分点——这是一个关于门槛的示例,不是可直接照搬的配置。
- 命中率不等于优势。 如果市场已经对你的信号所依据的状态进行了定价,那么 58% 的命中率也不会带来收益。只有演练的第 3 步能排除这种情况。
- 仓位到期时可能一文不值;每轮最大损失为投注额。无需设置止损——仓位会自行结算。
依赖项
| 技能 | 用途 |
|---|---|
binance-agentic-wallet | prediction *、wallet * |
K 线数据来自 Binance 公共市场数据端点(api/v3/klines)——无需密钥,也无需会话。
baw --version
baw cli-check --required-version "$(grep -m1 requiredCliVersion SKILL.md | tr -dc '0-9.')" --json
尚未发布。 此技能仅存在于你安装它的位置。
binance-agentic-wallet来自https://github.com/binance/binance-skills-hub;此技能目前尚未在该处发布。
开始使用
第 1 步和第 3 步都不花钱,而且任一步都可能让你放弃这个想法。启用实盘模式前请先完成这两步。
1 · 离线回测——无需登录、配置或资金。
python3 backtest.py fetch --symbol BTCUSDT --interval 1h
python3 backtest.py eval --interval 1h --hurdle 0.521
使用你要交易的轮次间隔(5m/15m/1h/1d)——同一信号在不同间隔下的表现差异很大。eval 会输出 hit_table,供你粘贴到配置中。
2 · 编写配置——首次运行会写入一个空模板,然后退出。
python3 updown.py # writes the template
$EDITOR $UPDOWN_HOME/config.json # mode: dry-run, expected_slippage_bps: 0
3 · 收集报价,然后检验信号是否已被市场定价。
python3 updown.py # dry-run: decides and records, places nothing
python3 backtest.py pricedin # reads it back
streak dir n implied P(up) realized P(up) gap read as
3 1 64 0.421 0.428 +0.007 PRICED IN — no edge here
如果你的信号触发时差值接近零,说明市场已经知道了——到此为止。这需要积累几十次出现记录:对于 1h 且 min_streak 为 3 的情况,需要好几天。
4 · 检查运行状态——运行 tail -f $UPDOWN_HOME/updown.log。长时间没有动静是正常的;应查看 HEARTBEAT 计数,而不是仅凭没有订单来判断是否卡住。
5 · 编写自己的钩子——rounds.jsonl 会记录每轮的概率、两边的卖价、超额收益、盈亏平衡点和优势。
6 · 开始实盘——先使用最低投注额,直到资金流转路径验证无误;然后根据成交日志中的 ALL-IN 行设置 expected_slippage_bps。
功能对应表
| 阶段 | 命令 |
|---|---|
| 列出轮次 | prediction market list --l1Category crypto --l2Category up-down |
| 订单簿 / 最新价格 | prediction market order-book · market last-trade-price |
| 报价、下单、取消 | prediction trade quote · place-order · cancel |
| 持仓、结算 | prediction position list · settled-history · pnl |
| 赎回 | prediction trade redeem |
| 订单状态 | prediction order history |
| 风控读取 | wallet balance · left-quota · settings |
轮次生命周期
任意时刻都会列出 12 个主题——三个交易对 × 四种周期(5 min、15 min、1 hour、daily),每个主题都有自己的订单簿、手续费和价格数据源。配置中必须指定 symbol 和 timeframe;一个守护进程只交易一种组合。
enumerate → gates → probability hook (cannot see quotes) → compare to quote
→ guards → quote → place → confirm fill → settlement → redeem
与现货交易流程相比有两点不同:
- 没有止损,也没有退出计划。 仓位会自行结算;所有决策都在入场时做出。
- 赢了也不会自动收到钱。 收益会留在
PENDING_CLAIM中,直到赎回。守护进程会按定时计划处理赎回;稳态下PENDING_CLAIM应为空。
哪个数据源用于结算你的回合
| 频率 | 数据源 |
|---|---|
| 5 min、15 min | CHAINLINK |
| 1 hour、daily | BINANCE 现货 |
每个主题都会在 variantData.priceFeedProvider 中发布该值——请读取,不要假设。它决定回测必须使用哪组数据序列。主题也会发布 startPrice,因此回合结束后可以独立核对结果。
决策约定
报价就是隐含概率。 有三个分支,第三个最常见:
| 分支 | 条件 |
|---|---|
| 买入 Up | P(up) − up_ask − cost > edge_threshold |
| 买入 Down | (1 − P(up)) − down_ask − cost > edge_threshold |
| 不交易 | 其他所有情况 |
盈亏平衡命中率等于报价加成本——以 0.55 买入 Up,手续费为 2% 时,命中率必须高于 57%。每个回合都会由机制层计算并记录,不会留给策略处理。
成本 = 主题的 feeRateBps + expected_slippage_bps。 订单的 slippage_bps 是一种容差,而非成本;如果将其计入成本,就会因为一种很少发生的最坏情况而对每个回合收费。
筛选门槛
机制层会在调用钩子之前执行三个硬性门槛:
| # | 门槛 | 来源 |
|---|---|---|
| 1 | 超额价差 up_ask + dn_ask − 1 | market order-book |
| 2 | 每侧价差 | 同上 |
| 3 | 距离收盘的时间 | 主题的 endDate |
门槛 1 最有效:它基于订单簿中的可观测事实,而非预测。在一个 BTC 1 小时回合中进行实时测量:卖价为 0.55 / 0.46 → 超额价差为 1.0%,同一回合 22 秒后则达到 3.0%。下单前应立即筛选。
第四项检查在确定仓位规模时执行,而非筛选时,因为它取决于下注金额:
| 检查 | 行为 |
|---|---|
| 最优卖价档位的深度 | 如果下注金额超过订单簿顶部挂单的 USDT 数量,则拒绝订单。筛选时依据的是该价格;如果订单金额超过该档位,就会沿订单簿以更差的价格成交,决策所依据的价格便不再是实际成交价格。观察到最优卖价档位仅有 $5——应根据订单簿确定仓位规模,而不是根据预算 |
公平价值偏差和“盈亏平衡命中率 ≤ 已证明的校准水平”是你的钩子要负责的事,而非机制层的职责:两者都依赖脚手架中没有的模型。此处列出是为了明确职责划分,并不表示守护进程会强制执行。
阈值默认未设置。别人交易场所的数据只能反映他们的订单簿。
两类市场
| 类型 | 公平价值 | 影响 |
|---|---|---|
| 平值 | 自然约为 0.50 | 没有模型优势。 只有对这个 0.50 的错误定价 |
| 行权价或区间 | 可根据时间和波动率计算 | 偏差可测量;尾部概率是大众容易判断错误的地方 |
策略钩子
estimate_probability(rnd, ctx) -> float | None # P(round closes UP); None skips
size_position(rnd, ctx, edge) -> float # USD; clamped to stake_usd and budget
ctx 包含 cfg、policy(原样传入)、streak、streak_dir、open、now_ms。
ctx故意不包含报价。 能看到价格的估算器会受其影响而锚定价格,校准报告随后衡量的结果看似准确,实际却没有优势。接口会强制执行这一点,不依赖自律。超出范围或非数值的返回值会被拒绝,并触发ALERT,而不会被截断。
包含的内容,以及关于所读取信号的已知信息
钩子是编写策略的地方。随附的实现只是一个能让流水线运行的示例——其中的每项判断和每个数字都应替换为你自己的分析结果。
随附的实现只读取一个机械特征——当前同方向 K 线连续出现的长度——然后在由你提供的 policy.hit_table 中查找答案。它不附带任何数字,因为一张表描述的是某个标的在某种周期下的情况,照搬别人的表并不能说明任何问题。backtest.py eval --interval <iv> 会输出一张可直接粘贴的表。
供参考,同一特征家族在结算序列上按下列各个周期测得的结果:
| K 线 | 连续 2 根 | 3 | 4 | 5 | 是否单调? |
|---|---|---|---|---|---|
| 5m(n≈9.8k) | 0.520 | 0.509 | 0.512 | 0.514 | 否 |
| 15m(n≈9.6k) | 0.536 | 0.538 | 0.544 | 0.540 | 否 |
| 1h(n≈5.8k) | 0.539 | 0.544 | 0.552 | 0.559 | 是 |
| 1d(n≈1.6k) | 0.538 | 0.531 | 0.536 | 0.535 | 否 |
- 15m、1h 和 1d 周期都存在约 +3 个百分点的整体反转倾向。这一结果具有可重复性。
- “连续次数越多,反转越强”并不成立——这种现象只在四种周期中的一种出现,而且会随样本窗口变化。四分之一的情况,正是噪声的表现。
扣除测得的成本后,在平值轮次中,streak ≥ 3 时:
| 命中率 | 0.544 |
| − 公允价值 | −0.500 |
| − 超额价差,单边 | −0.005 |
| − 手续费,200 bps | −0.020 |
| − 成交时观测到的滑点 | −0.0125 |
| 每轮净收益 | +0.0065 |
命中率的误差范围为 ±0.019,是优势的 2.9 倍。要判断 +0.65% 与零是否有差异,约需 22,700 轮:在 min_streak 为 3 时相当于 11.5 年。这既不代表“会亏钱”,也不代表“会赚钱”——而是按这些轮次出现的速度,无法验证;并且所有数字都假设轮次按公允价值报价,第 3 步演练正是用来检验这一点的。
请把上表视为说明门槛的示例,而不是可直接照抄的配置。
budget_usd 会限制什么,不会限制什么
它限制的是亏损,而不是交易额。只有在以下条件成立时,才允许进行一轮交易:
realised losses + capital currently at risk + this stake ≤ budget_usd
因此,即使最坏情况发生——每一轮未结算交易最终都归零——亏损仍不会超出你已确认的金额。盈利轮次的下注额会返还到资金池,守护进程会继续运行。
这对长时间运行很重要。早期版本把该数值当作累计交易额,结算时也不会释放,因此 $50 的预算在每轮下注 $1 时,无论结果如何,都会在 50 轮后停止——这种停止与风险无关,也无法满足此类策略所需的样本量。若要在固定轮数后停止,请使用 max_rounds_per_day。
机制防护措施
这些防护措施在此处强制执行,钩子无法绕过。具体数值由你决定。
| 防护项 | 行为 |
|---|---|
budget_usd | 总亏损上限,按 已实现亏损 + 当前承担风险的资金 ≤ budget_usd 执行。轮次结算后,下注额会返还,因此该门槛跟踪的是风险,而不是交易额 |
stake_usd | 执行仓位调整钩子后的每轮上限。下限为 1 USDT(平台最低要求) |
max_open_rounds | 同时未结算的轮次数 |
max_rounds_per_day | 在 UTC 午夜重置——这是此周期下真正的成本控制 |
max_consecutive_losses | 停止新的入场,并记录原因 |
| 单实例 | 使用 flock;持有进程退出时由内核释放锁 |
| 实盘门槛 | 除非确认文件中保存了当前的 budget_usd,否则拒绝启动 |
STOP / KILL | 停止开仓 / 退出 |
配置
$UPDOWN_HOME/config.json(默认为 ~/.local/updown)。首次运行会写入一个空模板。
任何涉及资金的设置都没有默认值。 唯一例外是
mode——缺省时为dry-run,因此遗漏该项不会导致实盘交易。
必填(机制)
| 键 | 如何确定 |
|---|---|
chain | baw wallet chains --json |
symbol | BTCUSDT / ETHUSDT / BNBUSDT |
timeframe | 5 min / 15 min / 1 hour / daily——必须是精确字符串;拼写错误会在启动时被拒绝,并显示实时目录 |
budget_usd | 一个你能接受其全部亏损的金额。严格执行:只有在亏掉这笔金额,加上已亏损的全部金额和当前所有风险敞口,仍不超过此数值时,才会开启一轮。启用实盘前需要再次输入 |
stake_usd | ≥ 1 USDT,且低于最佳卖价挂单量 |
max_open_rounds | 在你的账户上验证资金路径之前设为 1 |
max_rounds_per_day | 节奏控制,与预算无关。每轮 2% 时,它限制了安静策略的手续费——并非根据 budget_usd 推导 |
max_consecutive_losses | 胜率约为 55% 时,连续亏四次并不稀奇 |
必填(策略——由捆绑的钩子读取)
| 键 | 如何确定 |
|---|---|
min_streak | 4+ 很少触发,但衡量最强信号;2 触发频繁,衡量最弱信号 |
edge_threshold | 高于你自己命中率估算的不确定性,否则你交易的只是噪声 |
max_overround | 先观察盘口一小时。观察到的数值在相隔几分钟时为 1%–3% |
max_spread | 方法相同。在流动性良好的 BTC 轮次中观察到 0.01 |
min_seconds_to_close / max_seconds_to_close | 临近结算时市价单曾直接失败。留出余量 |
slippage_bps | 订单容差,不是成本 |
hit_table | {"2": 0.53, "3": 0.54, …},适用于你交易的节奏,通过 backtest.py eval --interval <iv> 获取。没有默认值——借用的表格毫无参考价值 |
expected_slippage_bps | 从 0 开始,用最小仓位运行,读取每笔成交日志中的 ALL-IN … = +N bps,减去手续费,再填入你看到的数值。一笔成交:总计 +325 bps,而手续费为 200 bps |
可选——kline_interval(默认为该轮的节奏)· 其他钩子会读取的任何内容
有默认值(基础设施)——mode · poll_sec · settle_poll_sec · kline_refresh_sec ·
l1_category · l2_category
运行时文件与评估
$UPDOWN_HOME 包含 config.json · state.json · rounds.jsonl(每项决策均会记录,包括已交易的决策)· orders.jsonl · outcomes.jsonl · quotes.jsonl · updown.log。
rounds.jsonl 和 outcomes.jsonl 通过 key 关联。
| 工具 | 用途 |
|---|---|
backtest.py eval | 信号在样本外是否能通过成本门槛?离线运行,可供不信任守护进程的人审计 |
backtest.py pricedin | 信号是否已反映在价格中?这是回测无法回答的问题 |
eval 会强制划分训练集和测试集,打印置信区间而非点估计,统计已检验的假设,并在完整样本上检查剂量反应。任何非实盘运行都会写入 quotes.jsonl,记录它能读取的每个盘口,包括被你的门槛拒绝的盘口——只对可交易的盘口采样会使价格反映分析产生偏差。
校准时有三列很重要:你的概率、恒定的 0.50,以及报价。如果表现不如报价列,就不存在有效策略,无论命中率看起来多好。
平台行为说明
死掉的会话绝不能看起来像平静的市场。 每次读取预测都需要经过身份验证的会话,而会话会过期。预检会直接探测预测端点(wallet status 在预测会话失效时仍可能返回);运行时,任何身份验证失败都会记录为 ALERT,并记为该轮的跳过原因。
order-book 使用 --marketId,而不是 --marketTopicId。 两者是不同的标识符;一个主题包含多个市场。
最低订单金额为 1 USDT——quote 会拒绝更低的金额。
已下单的订单仍可能失败。 已观察到:place-order 返回成功,但订单结算为 FAILED(“Failed to execute the market order”),成交量为零。下单成功只是回执。守护进程会轮询,直到订单达到终态;如果失败,就将本金退回预算并丢弃该轮——否则,失败的订单会永远占用预算,并留下一个虚假的未结轮次。
已结算的盈亏记录在 realizedPnl 中;pnl 返回 null。 读取错误字段会把每次盈利都记为零,并破坏校准账本。
赎回针对整个账户,而非仅限于守护进程:赎回扫描会领取账户中所有可领取的资产,包括此守护进程从未开仓的持仓。结算记账仅涵盖其自身 state.json 中的轮次。
报价可能会在报价与下单之间过期;守护进程会重新获取一次报价。
挂单卖单可能会对同一批份额重复预留,且只有在市场结算后才会释放。此后,若市场仍开放,继续卖出会因持仓不足而失败。每个持仓最多保留一个挂单。
预检
只读——不要通过下单进行探测。
baw wallet status --json
baw wallet chains --json
baw wallet balance --binanceChainId <chain> --json
baw prediction category list --json # confirm crypto / up-down exists
baw prediction position list --limit 1 --json # confirm the prediction session is alive
运行
cd <skill-dir>/scripts && python3 updown.py # foreground
nohup python3 -u updown.py >> runner.log 2>&1 & disown # long-running
python3 updown.py --collect-quotes # records only
| 操作 | 命令 |
|---|---|
| 停止开启新轮次 | touch $UPDOWN_HOME/STOP |
| 退出进程 | touch $UPDOWN_HOME/KILL |
| 确认风险金额 | echo <budget_usd> > $UPDOWN_HOME/I_UNDERSTAND_THE_RISK |
| 恢复实盘开关 | rm $UPDOWN_HOME/I_UNDERSTAND_THE_RISK |
开始实盘:将 mode 设置为 live。除非确认文件中包含当前的 budget_usd,否则运行会拒绝启动——因此,复制运行目录无法继承该确认,且提高 budget_usd 会使确认失效。操作员确认金额后,Agent 可以写入该文件。
退出不会关闭未结轮次。 它们会自行结算,之后仍需赎回。
保持运行
这是一个带内部循环的前台进程,不是 Unix 守护进程:不会 fork,也不会调用 setsid。nohup … & 可以让进程在注销后继续运行,但无法在重启后恢复。该进程的能力与限制如下:
| 应对暂时性错误 | 可以——循环会捕获错误,记录 ERROR main loop,并按 15 秒 → 300 秒的间隔逐步延长等待时间 |
| 在崩溃或重启后继续运行 | 不可以——没有任何机制会重启它。这是进程监控器的职责 |
| 安全重启 | 可以——state.json 保存预算、未结轮次和每日计数器;flock 可防止同时运行多个实例 |
| 恢复遗漏的结算 | 可以——每次运行时,赎回扫描都会重新读取持仓和 PENDING_CLAIM |
| 在会话过期后继续运行 | 不可以——进程会继续运行,但会跳过每一轮,并发出醒目提示(ALERT)。请重新进行身份验证 |
launchd(macOS)——~/Library/LaunchAgents/local.updown.plist:
<plist version="1.0"><dict>
<key>Label</key><string>local.updown</string>
<key>ProgramArguments</key>
<array><string>/usr/bin/python3</string><string>/ABSOLUTE/PATH/scripts/updown.py</string></array>
<key>EnvironmentVariables</key><dict><key>UPDOWN_HOME</key><string>/Users/you/.local/updown</string></dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/Users/you/.local/updown/runner.log</string>
<key>StandardErrorPath</key><string>/Users/you/.local/updown/runner.log</string>
</dict></plist>
launchctl load ~/Library/LaunchAgents/local.updown.plist
systemd(Linux)——~/.config/systemd/user/updown.service:
[Service]
Environment=UPDOWN_HOME=%h/.local/updown
ExecStart=/usr/bin/python3 /ABSOLUTE/PATH/scripts/updown.py
Restart=always
RestartSec=30
[Install]
WantedBy=default.target
systemctl --user enable --now updown
进程监控器只会重启进程,不会重新进行身份验证。 会话过期后,所有交易都会停止,直到有人重新登录——请单独做好相关安排,并留意 ALERT 日志,而不要以为没有动静就代表运行正常。
已知限制
| 限制 | 详情 |
|---|---|
| 捆绑策略无法验证 | 每轮约 +0.65%,误差范围为 ±1.9 个百分点;需要约 22,700 轮才能确认。这是一个示例,展示你的信号必须达到的标准,而不是建议投入资金的信号 |
| 命中率不等于优势 | 如果报价反映了当前状态,那么命中率再高也无法盈利。只有 pricedin 才能排除这种情况 |
| 平价轮次 | 公允价值 ≈0.50;在这些轮次中的任何盈利都来自定价错误,而非预测 |
| 费用占主导 | 每轮 200 个基点,由平台公布 |
| 无法退出,也没有止损 | 所有决策都在入场时做出 |
| 必须赎回 | 盈利在结算前一直处于未领取状态 |
| 会话会过期 | 可通过警报缓解,但无法彻底解决。长期运行需要重新进行身份验证 |
| Dry-run 不涉及资金流转 | 只有实盘运行才会执行下单、成交、结算和赎回 |
| 深度不足 | 曾观察到最优卖价处的资金只有个位数美元 |
| 无监督程序 | 使用 launchd、systemd 或容器重启策略 |
免责声明
这只是脚手架,不是交易产品。
- 捆绑策略是一项经过测量的参考,没有证据证明其扣除成本后具有正期望收益;提供它是为了展示管道能够运行,且测试框架能够区分不同情况。
- 此处的每项风险控制和参数都只是建议,并非保障措施。守护进程会执行你配置的检查,但不会判断这些检查是否足够。
- 此处内容不构成投资、金融或交易建议。
- 持仓可能到期归零。市场状况、平台行为变化、本软件缺陷或你编写的策略缺陷,都可能导致自动交易亏损。
- 按原样提供,不作任何保证。在法律允许的最大范围内,对于因使用本软件而造成的任何损失,均不承担责任。
- 你须对自己的运行内容、所选参数、遵守适用法律以及投入的任何资金承担全部责任。
如果你无法承受全部损失 budget_usd,请勿将 mode 设置为 live。