接口上有个 redeemable 字段,看名字就该是「这个仓位能不能赎回」。
实测下来它不能用来判断输赢:盘收盘之后,
赢的和输的会被一起标成可赎回。
另一个同族的坑更险 —— 查持仓返回「空」,你以为清干净了,其实钱还在里面。
盘收盘之后订单簿会清空。这时候去查持仓,会看到一个很奇怪的画面:
| 你持有的 | 接口说 | 给的参考价 | 真相 |
|---|---|---|---|
| 赢的那一侧 | redeemable: true | ≈ 0.5 | 值 $1 |
| 输的那一侧 | redeemable: true | ≈ 0.5 | 值 $0 |
0.5 这个数是怎么来的?订单簿空了之后,最优买价是 0、最优卖价是 1,
中间价就是 (0 + 1) / 2 = 0.5。它不是市场对这个仓位的估值,
它是「没有市场」这件事的数值表现。
补救一:只赎回价值 ≥ $0.50 的仓位。 结果是输掉的仓位也被放行 —— 因为它也显示 0.5。 你会为一堆注定归零的仓位不停发起赎回交易,白烧手续费。
补救二:把门槛提到 ≥ 0.9。 结果是赢的仓位被卡住 —— 它显示的也是 0.5,够不着 0.9。 钱会一直压在那里,直到别的机制把它救出来。
两条路都试过,都不通。问题不在门槛定多少, 在于「用价格判断输赢」这个思路本身就是错的: 收盘后那个价不携带任何输赢信息。
可靠的判据只有一个,而且它是结算本身,不是从价格推出来的:
| 它好在哪 | 说明 |
|---|---|
| 是结算本身 | 不是从价格、成交量或任何便利字段推出来的 |
| 不受订单簿影响 | 书空了、没人报价、盘冷门,都不影响这两个值 |
| 任何人可独立复核 | 链上公开,你可以拿任意一个已结算的盘自己验 |
| 没有临界模糊 | 不需要选阈值 —— 大于 0 就是赢,等于 0 就是输 |
我们把判断逻辑换成直接读这两个值之后,误判就消失了。 后来用它逐窗复核全部历史,与市场结算一致率 100% (分歧窗复核 207 : 0,另一批 31 : 0)。
这一个差点让我们把钱丢在盘里。
场景:停掉一条线,收工前查一次持仓确认清干净了。 接口返回 空。看起来完美 —— 于是把负责赎回的组件也关了。
实际上最后两个窗刚刚买入,还没被接口收录。 持仓是真实存在的,只是查的那一刻接口还不知道。
而赎回组件已经被关了 —— 如果不是复查,那笔钱会一直困在链上。 后来手动核对才发现:其中一窗是赢的,金额不算小。
教训停线之后判断「仓位已空」,不能只信接口的一次快照。 必须至少满足一条:等最后一个盘收盘再过几分钟, 或者拿自己的下单台账逐笔对一遍。
它们看起来无关,其实是同一个错误的两种形态:
| 接口说 | 你以为 | 实际 | |
|---|---|---|---|
| 坑一 | 可赎回,值 0.5 | 这是个还没定的仓位 | 已经定了,只是书空了没人报价 |
| 坑二 | 没有持仓 | 清干净了 | 有持仓,只是还没被收录 |
两个都是「查不到」被当成了「没有」。这是我们付过多次学费的同一类错误 —— 另外两次分别是把「活动流里没有记录」当成「没有亏损」 (差了八倍), 以及把空数组当成「这个盘没有奖励」 (API 口径陷阱)。
「这个盘结算了吗」也有类似问题:目录接口上的「已关闭」标记会滞后五到十分钟。 如果你等这个标记再去赎回,白白多等一轮。
而结算这件事链上已经自证了 —— 既然你要读链上的赔付结果, 就不需要先问目录接口「关了没有」。我们把这个多余的前置判断删掉之后, 整个赎回周期从十到二十分钟压到两到六分钟, 那已经是机制本身的下限。
如果你不用现成的库、自己拼请求去读链上数据,记得带 User-Agent 请求头 —— 否则会被静默拒绝:不报错,只是不给数据。
「静默」是关键词。这类失败看起来就像「链上没有这条记录」, 于是你会去怀疑数据本身,而不是怀疑请求。用库的人踩不到,因为库自带这个头。
| 不要用 | 改用 |
|---|---|
| 「可赎回」字段判输赢 | 链上赔付结果 |
| 收盘后的价格判输赢 | 同上 —— 那个价不携带输赢信息 |
| 一次持仓快照判「已清空」 | 等收盘后几分钟 + 台账逐笔对账 |
| 目录的「已关闭」标记判结算 | 直接读链上,它已经自证 |
| 「查不到」当成「没有」 | 先确认你查得对不对 |
收盘之后,价格不再携带任何输赢信息 —— 0.5 是「没有市场」的意思,不是「五五开」的意思。 判输赢只有一个地方可问:链上的结算结果。 而判「我清干净了没有」,则永远不要只信一次快照。
redeemable 均为 true,
参考价均 ≈ 0.5,即空订单簿的 (0+1)/2。