3 tháng Mười Một, 2026 · thực thi

Chúng tôi paper-trade một giao dịch basis. Một chân được khớp.

Chúng tôi paper-trade một giao dịch basis. Một chân được khớp.

Hàm có tên enter_pack. Đó lẽ ra phải là cảnh báo. Một research agent đã viết một cash-and-carry BTC: khi perpetual giao dịch hơn 8 basis point trên spot, mua spot, short perp, ngồi im. Funding và basis sẽ lo phần còn lại. Backtest khớp cả hai chân trong cùng một millisecond, tại mid, cộng thêm một tick lịch sự. Đường equity là một cầu thang. Chẳng ai gọi đó là thú vị. Đó chính là điểm bán.

Chúng tôi đưa nó lên paper vào một thứ Hai.

Thứ Hai: pack luôn khớp đủ

Tín hiệu đầu tiên đáp xuống lúc 11:17 UTC. Basis trên màn hình là 9.4 bps, perp đang đắt. Trong backtest, enter_pack trả về 2 fill và residual bằng 0. Trên paper nó trả về một fill spot 0.40 BTC tại ask, và một short resting trên perp không khớp.

Spot đã trả 4 bp phí taker và khoảng 1 bp spread. Giá perp chúng tôi muốn vẫn còn trên sổ, rồi thì không. 20 giây sau basis báo giá là 5 bps, vì chúng tôi vừa lift spot. 40 giây sau perp khớp, sau khi giá đã chạy. Chúng tôi đã thành pack. Chúng tôi thành pack ở một basis không còn đủ trả chi phí vào và ra.

Backtest sẽ ghi nhận "+9.4 bps carry, residual 0." Blotter thì có 4 bps chi phí taker spot, một vị thế long không hedge trong 40 giây, và một khoảng lệch vào lệnh khoảng 5. Tôi có mẫu gồm 1 quan sát và, dù vậy, vẫn quá tự tin vào cái cầu thang.

Thứ Ba: chúng tôi mở hàm ra

enter_pack nhận một list các chân và một mid mục tiêu. Nó lặp, khớp từng chân tại mid * (1 ± slip), và ghi 1 dòng portfolio. Không có timestamp thứ hai. Không có nhánh nào trong đó chân hai không tồn tại. Unit test assert residual == 0.

Đó là kiểu test khiến bạn cảm thấy mình là người lớn. Nó sẽ không bao giờ fail.

Chúng tôi tách pack thành 2 lệnh với state riêng: submitted, partial, filled, canceled. Incomplete trở thành đối tượng hạng nhất. Replay lịch sử vẫn không có sổ thật, nên chúng tôi ăn gian. Trì hoãn fill thứ hai bằng một lần rút từ thời gian chờ của thứ Hai (trung bình 26 giây, một đuôi tôi không thích), và trôi giá của nó theo những gì spot làm trong cửa sổ đó. Thô, nhưng cầu thang mọc thêm răng cưa trước giờ ăn trưa: những pack vào lệnh ở 3 bps, những pack chẳng bao giờ thành pack.

Thứ Tư: 3 giây, rồi dump

Nếu chân thứ hai chưa vào trong vòng 3 giây, flatten chân thứ nhất. Lẽ ra chúng tôi nên bắt đầu từ đó. Nghe thì thận trọng cho đến khi bạn định giá cái abort. Flatten nghĩa là bạn đã cross spot để vào và cross lần nữa để ra. 2 phí taker, 2 spread, không carry, không funding. Trong replay viết lại, những abort đó không hiếm. Chúng tụ lại trên những bar nơi basis trông "thật" nhất, mà thường chính là những bar nơi đã có thứ gì đó đang chảy qua spot.

Đến đêm thứ Tư chúng tôi có 17 tín hiệu paper để cãi nhau.

17tín hiệu paper trong 4 ngày
7pack khớp cả hai chân
18 bpsbiến động sau đó đi ngược vị thế long còn lại
Backtest, sáng thứ HaiPaper, đến thứ Tư
Vào lệnhCả hai chân tại mid, 1 timestampSpot tại ask; perp 5–40s sau, hoặc không bao giờ
ResidualLuôn bằng 0Không hedge trên 10 trong 17 tín hiệu
Phí trên một giao dịch đang chạy2 taker2 taker, hoặc 4 nếu chúng tôi abort
Động lực PnLBasis + fundingNhững gì spot làm trong lúc chúng tôi chờ
Một pack hoàn tất khi cả hai lệnh đều khớp, không thì đó là vị thế định hướng bạn không sizing cho. Mark residual theo sổ live suốt thời gian nó tồn tại. Không mark được thì không chạy được chiến lược.

Một đồng nghiệp vẫn còn notebook coi pack như một sản phẩm niêm yết, BTC_CARRY, với "thuế thực thi" phẳng 2 bp. Tôi thích notebook đó. Nó cho ra cùng cái cầu thang mà agent đã làm. Một khoản thuế là một trung bình. Orphan là một phân phối. Trung bình không bị cán trong một giờ mỏng; 0.40 BTC spot leftover thì có.

Thứ Năm: leftover, rồi cà phê

3 giây abort gần như mọi thứ khi chúng tôi còn phải chờ hàng. Chúng tôi nới paper lên 15. Lúc 02:11 UTC thứ Năm, spot khớp và perp thì không. Tôi vẫn đang ở giai đoạn đau buồn "nó sẽ rest, nó sẽ lift" thì đi pha cà phê.

02:11:08 filled BTCUSDT 0.40 buy
02:11:08 submitted BTCUSDT-PERP 0.40 sell, post-only
02:11:41 still working
02:26:00 residual mark −18.1 bps

BTC giảm 18 bps trong một cửa sổ yên ắng. Residual chính là toàn bộ giao dịch. Funding, khi in ra, ghi có một perp chúng tôi không có. Spot chỉ ngồi đó mà long. Đường overnight của backtest gốc chưa từng chứa vị thế 1 chân, nên nó chưa từng hỏi câu chúng tôi hỏi với mọi sổ khác: bar tệ nhất leftover này có thể in ra là gì, và stop cho vị thế chúng tôi không định giữ nằm ở đâu?

7 pack đầy đủ cũng chẳng phải anh hùng. Khi chân thứ hai in ra, chính cú lift spot của chúng tôi đã đè lên index, và basis vào lệnh đã kém 3–5 bps so với snapshot đã bắn tín hiệu. Ngưỡng 8 bps chỉ là một con số trên màn hình.

Những gì chúng tôi sẽ bỏ lần sau

Chúng tôi sẽ không ship một multi-leg như một hàm fill duy nhất. Cùng quy tắc với carry perp-spot, một calendar, hay call vertical mà một agent gửi như 2 lệnh limit rồi ăn mừng khi cả hai "fill" tại mid.

  1. State lệnh theo từng chân, kể cả partial. Coi pack là parent của 2 ticket.
  2. Một timer max-orphan thực sự bắn, và một đường flatten trả 2 spread trên đường ra.
  3. Mark-to-book trên residual, với stop được sizing cho leftover. Net đã pack là notional sai.
  4. Không ghi carry, không cộng funding, cho đến khi cả hai chân đã vào. Incomplete là incomplete.
  5. Từ chối mid-on-mid làm mặc định cho bất kỳ thứ gì có 2 ticket. Nếu phải đoán, đoán tệ hơn ở chân mỏng và muộn hơn ở fill thứ hai.

Và chúng tôi sẽ không để test_pack_is_atomic vào repo. Atomic là thuộc tính của matching engine, không phải của một hàm helper. Spot BTC và perpetual BTC là 2 sổ đôi khi vần với nhau. Paper là nơi chúng ngừng vần, và đó là lý do duy nhất cái cầu thang từng thú vị.

backtestingcash-and-carrythực thipaper tradinghợp đồng tương lai crypto
← Tất cả bài viết