Skip to content
All strategies

Strategies

FMZ '交割合约现货套利策略测试版' (Spot–Delivery Futures Arbitrage, test version) by ianzeng123, faithful port: ADF-gated z-score basis arbitrage, BTCUSDT.BINANCE_SPOT vs Binance USD-M BTC quarterly futures (current + next quarter), 1-minute bars

Outcome: Abandoned

FmzSpotDeliveryAdfZScoreBasisArb

Outcome Summary

FmzSpotDeliveryAdfZScoreBasisArb ported an FMZ open-source strategy that arbitrages the basis between BTC spot and Binance USD-M quarterly futures, using an ADF stationarity gate and a z-score entry on the spread rate, with fixed 0.05 BTC legs and futures at 10x leverage. The strategy rolled through every quarterly from BTCUSDT_210326 onward, aligning each contract with spot by timestamp. In its first iteration it stalled in verification and was abandoned after three timeouts ('verifying_stuck_3_timeouts'). It never reached backtesting, optimization or analyst review, so its edge was never measured.

Hypothesis

Faithful translation of ianzeng123's FMZ open-source strategy '交割合约现货套利策略测试版' (credit to the author). The source pairs a SPOT market (exchanges[0], BTC_USDT) with USDT-margined DELIVERY futures (exchanges[1], BTC_USDT.quarter and BTC_USDT.next_quarter; allowedCoins=['BTC']). For each delivery contract it keeps a 1-minute history of spreadRate = (deliveryClose - spotClose)/spotClose (max 5000 points), runs an hourly ADF stationarity test on the last 1000 points, and when the spread is 'stationary enough' and |z|……Show moreShow less

Faithful translation of ianzeng123's FMZ open-source strategy '交割合约现货套利策略测试版' (credit to the author). The source pairs a SPOT market (exchanges[0], BTC_USDT) with USDT-margined DELIVERY futures (exchanges[1], BTC_USDT.quarter and BTC_USDT.next_quarter; allowedCoins=['BTC']). For each delivery contract it keeps a 1-minute history of spreadRate = (deliveryClose - spotClose)/spotClose (max 5000 points), runs an hourly ADF stationarity test on the last 1000 points, and when the spread is 'stationary enough' and |z| >= 1.0 it opens a hedged pair: z>0 ('positive' / 正套) = BUY spot + SELL the delivery future; z<0 ('negative' / 反套) = SELL spot + BUY the delivery future. It exits when the dollar spread returns into a target band, on a 1.5% combined stop-loss, 1 day before delivery, or after 10 days if profitable. There is no take-profit. PLATFORM MAPPING. Spot leg: BTCUSDT.BINANCE_SPOT (CASH, 0.10%/side taker). Futures leg: Binance USD-M BTCUSDT dated quarterlies (BINANCE venue, MARGIN, 0.05% taker / 0.02% maker), catalog ids BTCUSDT_YYMMDD.BINANCE, 1-MINUTE bars verified present in the catalog for every quarterly from BTCUSDT_210326 to BTCUSDT_261225 (each with ~3-6 months of 1m history before its expiry; BTCUSDT_270326 has only started). Primary instrument = BTCUSDT.BINANCE_SPOT-1-MINUTE-LAST-EXTERNAL; every quarterly is an extra_instrument with its 1-MINUTE bar type. The source discovers pairs once at startup; in a multi-year backtest the port must re-run the discovery whenever a contract expires: at any bar the 'quarter' contract is the listed contract with the nearest delivery date that still has bars, 'next_quarter' the following one; each is paired with spot independently (own price history, ADF cache, fail counter, cooldowns and position record), and a contract is skipped for NEW entries when daysToDelivery < minDaysToDelivery (7). Delivery time is parsed exactly as the source does: the YYMMDD in the symbol at 16:00 UTC (parseDeliveryDateFromString). Bars of a contract after that time are ignored. Futures leg leverage = marginLevel 10 (config leverage 10.0; spot leg is CASH, unlevered). SIZING (source default, kept): orderAmount = 0.05 BTC spot per pair; futures quantity = the same 0.05 BTC (the source's calculateContractAmount floor(spotAmount/ctVal) is a coin-to-contract conversion so the futures notional matches the spot leg; Binance USD-M quarterlies are quoted in base units with 0.001 step, so the hedge is exactly 0.05 BTC). Spot buys require USDT balance >= 0.05*price + minUSDTReserve (10 USDT). With the $100k account this uses ~2-6% of equity per pair — that is the author's sizing and is kept on purpose; per-trade results are judged in % of notional. SPOT SHORTING. The account starts with USDT only, so the source's own checkSpotBalance('sell') fails for a reverse (z<0) entry ('BTC不足', canRetry=false: skip, no cooldown, keep waiting for a positive opportunity). The port keeps that check; coins already committed to the OTHER pair's open positive-arb record are treated as unavailable (otherwise the reverse arb on one contract would sell the hedge of the other — a corruption the source would also suffer, documented as the one deliberate deviation). In practice the strategy therefore runs only the positive (long spot / short quarterly) side unless spot BTC is free. Direction overall: market-neutral (long spot + short future).

BTC is over-represented in the corpus, but the mechanism genuinely requires it: BTC is the source's only allowed coin and Binance USD-M dated quarterlies with multi-year 1m history exist in our catalog only for majors (verified per contract: BTCUSDT_210326 through BTCUSDT_261225). It fills the most under-represented buckets: cross-venue (7.4% vs >=15% target), market-neutral/long-short, short horizon, and an untried mechanism (spot vs dated-futures basis).

verifying_stuck_3_timeouts

Implementation

Faithful bar-level port of ianzeng123's FMZ '交割合约现货套利策略测试版'. Pairs BTCUSDT.BINANCE_SPOT with Binance USD-M BTC dated quarterlies (BTCUSDT_YYMMDD.BINANCE, 1-minute bars). For each contract it keeps a 1m spreadRate=(fut-spot)/spot history (max 5000), runs an hourly ADF test (last 1000 points, lag floor(12*(n/100)^0.25), normal-approx p-value as in the source; 3 consecutive failures forbid trading), and on the nearest two live contracts ('quarter'/'next_quarter', re-discovered every bar so the chain rolls through the whole history) enters when |z|>=zScoreEntry: z>0 buys 0.05 BTC spot + sells 0.05 BTC of the quarterly; z<0 sells spot + buys the quarterly only if free spot BTC exists (source balance check). Exits when the dollar spread returns into [mu±0.5σ]*spot (widened to keep minProfitSpaceRate of room from the entry spread), at a 1.5% combined stop, <1 day before delivery (YYMMDD 16:00 UTC), or after 10 days if profitable. No take-profit.

Port follows the source loop per contract: updatePrices -> runStationarityChecks -> close checks -> open checks, with identical z-score (full-history mean/sample std), ADF gate, target band + min-profit adjustment, stop, delivery and max-hold exits, 0.05 BTC fixed sizing and the spot balance checks (USDT>=amount*price+10 for buys; free BTC for sells, where BTC committed to the OTHER contract's open positive pair is treated as unavailable — the one deliberate deviation, so a reverse arb can never sell another……Show moreShow less

Port follows the source loop per contract: updatePrices -> runStationarityChecks -> close checks -> open checks, with identical z-score (full-history mean/sample std), ADF gate, target band + min-profit adjustment, stop, delivery and max-hold exits, 0.05 BTC fixed sizing and the spot balance checks (USDT>=amount*price+10 for buys; free BTC for sells, where BTC committed to the OTHER contract's open positive pair is treated as unavailable — the one deliberate deviation, so a reverse arb can never sell another pair's hedge). Platform adaptations: (1) bar-level: the source's depth-mid re-verification, limit-order pricing (limitOrderSpreadRatio, orderWaitTimeout), leg ordering by deviation, stop-loss second confirmation and close tolerance (spreadTolerance) all re-read the same 1m close here, so they are pass-throughs; both legs go as market orders in the same timestamp (the source's limits are marketable, i.e. taker anyway). Those fixed parameters are kept in the config for the plan but are inert. (2) Rollback: if the futures leg is missing after an entry, the spot leg is unwound and a 10-minute pair cooldown applies (source rollbackSpotOrder/addCooldown); opportunityLostCooldown never triggers because the bar model has no stale-depth re-check. (3) Alignment: the base same-timeframe barrier is disabled (expired contracts would stall it forever); instead a contract steps only when its bar ts equals the spot bar ts, so no leg is read ahead of the other. (4) Contract chain: config extends the declared list (210326-250926) with 251226-270326, which exist in the catalog at 1m; without them the recent sandbox window has no live contract. Bars after a contract's delivery time are ignored. (5) Futures margin uses config leverage 10 (marginLevel) in the pre-trade margin check; spot is CASH. Per-bar cost is O(contracts) with running sums; the ADF OLS runs at most hourly per contract. Note: the spot leg is one NETTING position shared by up to two pairs, so the spot ledger can merge overlapping pairs. Honest concern: at 0.05 BTC per pair and ~0.30% round-trip taker cost per pair notional (0.10% spot + 0.05% futures per side), the 0.5% minProfitSpaceRate target leaves thin net edge; sizing is the author's and kept as instructed.

Outcome Summary

A multi-instrument 1-minute strategy that re-discovers a rolling chain of many quarterly contracts and runs periodic ADF regressions needs to fit the verification sandbox's wall-clock budget, for example by limiting which extra instruments are loaded, before it can be evaluated at all.

The run was abandoned in verification with reason 'verifying_stuck_3_timeouts' after 1 iteration: it timed out three times, so backtest review, optimization, analyst and risk review never ran.

A faithful port of ianzeng123's FMZ spot–delivery arbitrage: trade the BTC basis between BTCUSDT.BINANCE_SPOT and the nearest two Binance USD-M quarterly futures on 1-minute bars, opening hedged pairs when an hourly ADF test says the spread rate is stationary and |z| >= 1.0 (in practice only long spot / short future, because the account starts with USDT only).

No performance figures exist: the backtest report is empty and there is no optimization report, so it produced no return, Sharpe or trade-count numbers.

Analysis

交割合约现货套利策略测试版

Backtest and paper results are hypothetical. Trading involves risk of loss.