Cross-Exchange Equity Perpetual Spread Reversion
Cross-Exchange Equity Perpetual Spread Reversion
Risk warning: This strategy sends real orders to exchanges. Cross-exchange hedging does not eliminate spread divergence, single-leg liquidation, funding or execution mismatch risk. Normal exits have no price stop-loss, and the holding-time setting is not a forced exit deadline. Expected net returns and the strategy P&L curve do not fully include funding and other account costs. Verify fees, margin, contract specifications and API permissions before use.
Strategy Concept
The strategy trades price relationships between perpetual contracts tracking the same stock or ETF on different exchanges. It estimates the fair cross-exchange basis online, sells the relatively expensive leg and buys the relatively inexpensive leg when deviation, cost and market-data checks all pass. Positions are closed when the estimated net take-profit target is reached or the applicable reversion or time-based exit conditions are satisfied.
A Kalman filter fits the two venues' price relationship using depth-weighted micro-prices. Bid-ask width and quote timing differences add to observation uncertainty. Entry Z-scores use executable bid and ask prices, with persistence, freshness, short-term jump and available top-of-book depth checks to reduce untradeable signals.
WS Interface and Execution Architecture
The strategy uses FMZ's WebSocket event interface to process quotes, execution and account updates in one event loop, reducing repeated polling requests. Actual latency depends on the venue, account type, node network and market load.
- Live quotes:
ctx.subscribesubscribes to BBO bid/ask prices and quantities in latest mode. The strategy subscribes to the scan pool while flat and focuses on the two active legs while holding. Subscriptions are grouped per exchange; incoming quotes drive model updates, signal confirmation and exit checks. - WS orders: supported venues and accounts use
ctx.submit. Normal entries and exits are market orders; by default, both legs are submitted before waiting for results. An acknowledgement means acceptance, not a fill. The strategy waits for fill quantities, prices and terminal order states. - Private streams: order, fill and position updates support execution reconciliation. New entries require private-stream readiness. Position snapshots must pass freshness and post-fill update checks; missing or unreliable snapshots fall back to REST position queries.
- REST support: market metadata, startup screening, margin and necessary order/position reconciliation still use REST. Unsupported WS submissions or submissions without a valid request identifier may use the existing REST fallback. The code selects REST orders when it detects a Binance portfolio-margin account. A request with an identifier but unresolved terminal state is not blindly resubmitted; new entries are blocked pending reconciliation.
- Data and connection protection: stale quotes suspend quote-based decisions. Quote skew and spread width increase model noise. Market-data outages while holding raise a warning and wait for recovery rather than force a close. Reconnection alone does not confirm that orders and positions have been reconciled.
Use a node supporting ctx.subscribe, ctx.poll, ctx.submit and the selected exchanges' market and account streams. Configure exchange accounts with query and trading permissions in FMZ. WS order support depends on the venue and account. REST order fallback does not replace the required WS market data and private streams. Check the “Connections and Risk” status tab and order logs for subscription state, routing and errors.
Trading Workflow
text
Add at least two futures accounts → verify underlying, contracts and actual fees
↓
Screen symbols and venue pairs → subscribe to WS BBO and private streams
↓
Fit fair basis and uncertainty → calculate executable directional Z-scores
↓
Confirm persistent deviation → check round-trip costs, quote freshness and margin
↓
Submit two market legs → wait for terminal states → reconcile actual positions
↓
Take-profit / reversion plus net-return gate / elapsed time plus net-return gate → close
↓
Reconcile fills and P&L → record measured slippage → cool down and resume scanning
The candidate universe starts with Binance equity perpetuals. Matching markets on configured exchanges are checked for quantity precision, minimum order size, spreads, estimated costs and price range. Eligible symbols are selected by cost. Initial model warm-up takes about one minute with defaults and adequate fresh data; interruptions extend it.
Entry requires the directional Z-score threshold and persistence confirmation. Estimated reversion profit must cover entry and exit spread crossings, four trading fees and a measured slippage buffer, and still meet the minimum expected net edge. The default submits both market legs concurrently. Optional slow-venue-first execution hedges the confirmed filled quantity on the other venue.
Take-profit targets use actual entry fills. A normal close requires either the take-profit target, or live model reversion together with the minimum estimated close net return. When a holding-time threshold is enabled, elapsed time also requires that minimum net return. There is no normal price stop-loss.
Execution checks compare reports with actual positions. Partial fills, one-sided exposure, unresolved orders and reconciliation discrepancies follow exception handling, which may reduce or close exposure and block new entries pending review. Only one spread position is held at a time.
Fees and Arbitrage Conditions
A complete two-leg entry and exit involves four fills. With similar notionals on both legs, round-trip fees are approximately 2 × (venue A taker fee + venue B taker fee).
Accounts with lower effective taker fees, VIP discounts or realized fee benefits have a better chance of covering the same spread opportunity's costs and leaving room for slippage and profit. For example, reducing each venue's per-fill fee from 4 bps to 1 bps lowers estimated round-trip fees from 16 bps to 4 bps, saving about 12 bps. This is a cost illustration, not a return forecast. Lower fees do not ensure reversion or profitable fills.
Set taker fees to the actual account and market rates; 1 bp = 0.01%. Built-in values are estimates and do not automatically read VIP tiers, changing discounts or rebate settlements. Do not deduct unrealized rebates in advance or apply maker discounts to market execution. Specific markets may have separate fee rules; reconcile against actual statements. Official fee-rule reference
Live Configuration
Add at least two futures exchanges with the relevant equity perpetual markets. Only one account per exchange is allowed. Avoid sharing participating positions with manual trading or another strategy. Automatic symbol and price matching is candidate screening; verify the underlying, contract multiplier, quote currency, sessions, index and settlement rules yourself.
Default per-leg notional is 20 U, with a hard cap of 500 U and default leverage of 3. Both exchanges' precision and minimum-order rules must be satisfied. The legs use equal underlying quantities; model beta estimates the price relationship and does not dynamically resize the hedge. Trading sessions follow the normal New York clock and daylight saving changes, without a full holiday calendar.
Main Live Parameters
| Parameter | Default | Purpose |
|---|---|---|
| Per-leg notional | 20 | Startup checks precision and minimum order requirements; hard cap 500 U. |
| Scanned symbols | 30 | Select eligible symbols by estimated pair cost. |
| Candidate symbols | 60 | Binance equity-perpetual candidates ranked by 24-hour turnover. |
| Entry Z-score | 2.5 | Required directional deviation before entry confirmation. |
| Reversion Z-score | 0 | Exit also requires the minimum estimated close net return. |
| Minimum expected net edge (bps) | 5 | Entry gate after round-trip spread, fee and slippage estimates. |
| Model update interval (seconds) | 2 | Only sufficiently fresh quotes update the model. |
| Minimum model updates | 30 | No entry before this many valid updates. |
| Basis drift (bps/minute) | 0.3 | Controls model adaptation to structural basis changes. |
| Signal confirmation (ms) | 500 | Both legs must refresh during confirmation; 0 disables it. |
| Maximum execution quote age (ms) | 800 | Freshness gate for sampling and normal entry/exit decisions. |
| Take-profit fraction | 0.6 | Fraction of estimated reversion profit using actual entry prices. |
| Minimum take-profit target (bps) | 10 | Target floor; takes priority over the sigma cap. |
| Take-profit sigma cap | 3 | Caps the proportional target using entry uncertainty, subject to the floor. |
| Holding-time threshold (minutes) | 0 | 0 disables it; elapsed time alone does not force an exit. |
| Minimum close net return (bps) | 0 | Required for reversion and time-based exits; excludes funding. |
| Leverage | 3 | Configured per participating market; does not remove liquidation risk. |
| Daily realized-loss limit (U) | 3 | Blocks new entries; UTC day resets at 08:00 Beijing time. |
| Cumulative realized-loss limit (U) | 10 | Blocks new entries relative to the risk baseline; excludes floating P&L. |
| Slow venue first | Off | When enabled and latency difference is at least 150 ms, hedge after confirmed first-leg fills. |
| Order terminal-state wait (seconds) | 8 | Unresolved orders block new entries and require reconciliation. |
| Stale quote threshold (seconds) | 3 | Missing market data suspends quote-based decisions; no outage-triggered exit. |
| Scan-pool refresh (minutes) | 0 | 0 selects only at startup; otherwise refresh only while flat. |
These are the main trading settings; the parameter panel contains all 35 settings. Spread, total-cost, price-range, jump, session and opening/closing filters also restrict entries. Configure fees and latency for the actual accounts. Display rows, summary logs and statistics reset are maintenance settings. Statistics can be reset only without positions or unresolved orders and after accounting checks; model state is retained.
Operating Notes
- Reversion is a statistical assumption, with no guaranteed occurrence or deadline. Normal logic does not stop out on growing floating losses, and the holding-time setting does not force an exit. Positions may tie up margin for an extended period.
- Each exchange has separate margin. A profitable leg does not automatically cover losses on another venue. Divergence, mark-price differences, liquidation and auto-deleveraging can break the hedge. Lower leverage and entry cost checks do not replace margin monitoring.
- Expected net edge, estimated exit net returns and the strategy P&L curve use strategy fill prices and configured trading fees. They do not fully include funding, collateral or quote-currency differences, transfer costs or other account charges. Configured fees may differ from actual charges. Reconcile both venues' complete statements.
- Daily and cumulative loss limits use realized trading net P&L to block new entries. They are not account-equity stops, do not include floating losses and do not force existing positions closed at the configured loss amount.
- Market orders do not lock execution prices or guarantee simultaneous fills. Estimated trigger P&L can differ from realized P&L. Depth changes, slippage, rejections and partial fills may cause losses or one-sided exposure.
- Market-data outages while holding only warn and wait. Unresolved orders or reconciliation discrepancies require checking exchange orders, positions and funding records before resuming entries.
- Normal shutdown attempts to close positions, and startup first attempts to clear recorded residual positions. Crashes or unavailable exchanges can prevent cleanup. Check actual positions and outstanding orders after stopping.
/*
* 跨所币股价差回归套利
* 卡尔曼滤波估计跨所合理价差,以可成交 Z 值和扣费后预期收益筛选双腿交易。
* 常规出场采用止盈、回归或附带净收益条件的超时规则,不设价格止损。
* 费率须按账户实际 taker 费配置;资金费、抵押资产价差不计入策略净收益。
*/
// ======================== 常量 ========================
var VER = '2.0.0';
// 费率、延迟和 IOC 容差为估算初值;参数覆盖优先,费率须核对账户及具体市场的实际 taker 费。
var DFT_FEES = {Binance:4, OKX:5, Bybit:5.5, Bitget:6, Gate:5, MEXC:2, HTX:5, KuCoin:6, BingX:5, Bitmart:6, Phemex:6, CoinW:6, DeepCoin:5, BitMEX:7.5, Kraken:5, WhiteBIT:5.5, Backpack:5,
Aster:4, Hyperliquid:4.5, 'Hyperliquid(xyz)':1, Lighter:0, EdgeX:3.8, dYdX:5, WOOFi:5, Aevo:8, Paradex:0, Apex:5, Drift:3.5, Orderly:5};- 1