関数は enter_pack と呼ばれていた。それが警告であるべきだった。リサーチエージェントがBTCのキャッシュ・アンド・キャリーを書いていた。パーペチュアルがスポットより8ベーシスポイント以上高く取引されたら、スポットを買い、パーペチュアルをショートし、じっとしている。ファンディングとベーシスが残りをやってくれる。バックテストでは両脚が同じミリ秒に、ミッドで、1ティック分の礼儀を添えて約定した。エクイティカーブは階段だった。刺激的と呼ぶ人はいない。それが売りだった。
月曜日にペーパーへ昇格させた。
月曜日:いつも約定していたパック
最初のシグナルは11:17 UTCに届いた。画面上のベーシスは9.4 bps、パーペチュアルが割高。バックテストでは、enter_pack が2件の約定と残差0を返した。ペーパーでは、askで0.40 BTCのスポット約定と、約定しなかったパーペチュアルの待機ショートを返した。
スポットは4 bpのtaker手数料と約1 bpのスプレッドを払っていた。欲しかったパーペチュアルの価格は板に残っていた。それから、なくなった。20秒後、提示ベーシスは5 bpsになっていた。こちらがスポットをリフトしたからだ。40秒後、動いたあとにパーペチュアルが約定した。パックは完成した。出入りのコストを賄えなくなったベーシスで、パックは完成した。
バックテストなら「+9.4 bpsのキャリー、残差0」と記帳しただろう。ブロッターには4 bpsのスポットtakerコスト、40秒のヘッジなしロング、約5のエントリーギャップがあった。サンプルは1件なのに、それでも階段を信じすぎていた。
火曜日:関数を開いた
enter_pack はレッグのリストと目標ミッドを受け取った。ループして各レッグを mid * (1 ± slip) で約定させ、ポートフォリオ行を1行書いた。2つ目のタイムスタンプはなかった。レッグ2が存在しない分岐はなかった。ユニットテストがアサートしていたのは residual == 0 だった。
大人になった気分になれるテストだ。失敗することはない。
パックを、それぞれ独自の状態を持つ2つの注文に分解した。submitted、partial、filled、canceled。Incompleteは第一級のオブジェクトになった。ヒストリカルリプレイにはまだ本物の板がなかったので、ごまかした。2つ目の約定を月曜日の待ち時間からのドローで遅らせ(平均26秒、気に入らない裾があった)、その窓でスポットが動いた分だけ価格をドリフトさせる。粗いが、昼前には階段に段差ができた。3 bpsで入ったパック、パックにならなかったパック。
水曜日:3秒、それから捨てる
2つ目のレッグが3秒以内に乗らなければ、1つ目をフラットにする。そこから始めるべきだった。保守的に聞こえるが、中止のコストを見積もるまでだ。フラットにするということは、入るときにスポットをクロスし、出るときにもクロスする。taker手数料が2つ、スプレッドが2つ、キャリーなし、ファンディングなし。書き直したリプレイでは、その中止は珍しくなかった。ベーシスが最も「本物」に見えるバーに固まっていた。それはたいてい、すでに何かがスポットを流れているバーだ。
水曜日の夜までに、議論するペーパーシグナルが17件あった。
| バックテスト、月曜日の朝 | ペーパー、水曜日まで | |
|---|---|---|
| エントリー | 両脚ともミッド、タイムスタンプは1つ | スポットはask;パーペチュアルは5–40秒後、あるいは来ない |
| 残差 | 常に0 | 17件中10件がヘッジなし |
| 稼働中トレードの手数料 | takerが2回 | takerが2回、中止なら4回 |
| PnLの駆動要因 | ベーシス + ファンディング | 待っているあいだにスポットがしたこと |
同僚はいまだに、パックを上場商品、BTC_CARRY、として扱い、一律2 bpの「執行税」を乗せるノートを持っている。そのノートは好きだった。エージェントと同じ階段を出した。税は平均だ。孤児は分布だ。平均は板の薄い時間帯に轢かれない。残った0.40 BTCのスポットは轢かれる。
木曜日:残り物、それからコーヒー
キュー待ちも加わると、3秒ではほとんどすべてが中止になった。ペーパーを15秒に緩めた。木曜日02:11 UTC、スポットは約定し、パーペチュアルはしなかった。私はまだ「載る、リフトされる」という悲嘆の段階にいたまま、コーヒーを入れに行った。
02:11:08 約定 BTCUSDT 0.40 買い
02:11:08 発注 BTCUSDT-PERP 0.40 売り、post-only
02:11:41 まだworking
02:26:00 残差時価 −18.1 bps
静かな窓でBTCが18 bps売られた。残差がトレードのすべてだった。ファンディングが印字されたとき、持っていないパーペチュアルにクレジットされた。スポットはロングのまま座っていた。元のバックテストのオーバーナイトパスには片脚ポジションが一度も入っていなかった。だから、ほかのすべてのブックに聞く問いを、一度も聞かなかった。この残り物が印字しうる最悪のバーは何か、持つつもりがなかったポジションのストップはどこか。
7つの完全なパックも英雄ではなかった。2つ目のレッグが印字されるころには、自分たちのスポットリフトがすでに指数を押しており、エントリーベーシスはシグナルを発火させたスナップショットより3–5 bps悪かった。8 bpsの閾値は、画面についての数字だった。
次回は省くこと
複数レッグを単一の約定関数として出荷することはしない。パーペチュアルとスポットのキャリーでも、カレンダーでも、エージェントが2つの指値として出して両方がミッドで「約定」したと祝うコールバーティカルでも、同じルールだ。
- レッグごとの注文状態。部分約定も含む。パックを2枚のチケットの親として扱う。
- 実際に発火する最大孤児タイマーと、出るときにスプレッドを2つ払うフラット化パス。
- 残差の板に対する時価評価と、残り物のサイズに合わせたストップ。パック済みネットは誤った想定元本だ。
- 両脚が乗るまで、キャリーもファンディングも計上しない。IncompleteはIncompleteだ。
- チケットが2枚あるものに、ミッド対ミッドをデフォルトとして使わない。推測するなら、薄いレッグはより悪く、2つ目の約定はより遅く。
そして test_pack_is_atomic をリポジトリに入れたりはしない。Atomicはマッチングエンジンの性質であり、ヘルパー関数の性質ではない。BTCスポットとBTCパーペチュアルは、ときどき韻を踏む2つの板だ。韻が止まるのがペーパーであり、階段がおもしろかった唯一の理由だ。



