Strategies
DOGE Bybit–OKX Perpetual Dislocation
Outcome: Abandoned
DogeBybitOkxOuDislocation
Outcome Summary
DogeBybitOkxOuDislocation tested a QuantConnect-style Ornstein-Uhlenbeck pairs mechanism on DOGE perpetuals quoted on Bybit and OKX. After 5 iterations it produced clean, fully aligned data and accounting, but over about five years only 15 pairs fired, for a 0.23 Sharpe whose confidence interval spans zero and a 0.0277% average per-trade return. Impact and commissions used up almost all of the gross profit. The analyst abandoned it at backtest review because no parameter tuning could make spreads this small cover the cost of the trades, so optimization, analysis and risk review never ran.
Hypothesis
Test QuantConnect's Ornstein–Uhlenbeck pairs mechanism on the same asset across two venues. Fit the log price spread using the preceding 30 days of synchronized 1-hour bars, updating daily. Fix the hedge at equal DOGE quantities and use only completed bars.
fee_edge / negative_expectancy (first measured report). Over 1905 days the per-leg avg_trade_return_pct is 0.0277%. The single-leg futures floor is 0.15%, and the leg-scaled floor (L127) for a four-fill Bybit+OKX pair is about 0.63%. Impact consumes 79% of gross, PF is 1.027, Sharpe is 0.23 with a CI straddling 0 (PSR 0.52), and signal IC is -0.015 (rejected). Only 15 pair entries fired, against the roughly 100 needed for a meaningful optimization or holdout (L178). Optimizing entry_z, exit_z or min_edge cannot lift a same-asset cross-venue spread whose typical dislocation is smaller than four taker fills plus impact. Raising min_edge removes the few remaining trades, and lowering it adds fee-negative ones. QA's edge concern is borne out at full history: fewer than 30 pairs, with a net per-pair edge far below cost. A re-proposal is only worth it with maker/passive execution on both venues, and it would need to pre-register at least 0.6% net per pair after impact.
Implementation
Same-asset cross-venue OU pairs trade: log(DOGE Bybit close / DOGE OKX close) on completed, timestamp-aligned 1H bars. Once per UTC day an AR(1)/OU model is fitted on the preceding 30 days of synchronized spreads (mean, stationary sigma). The signal is the z-score of the current spread. Above +entry_z (and >= min_edge_bps away from the mean) it shorts Bybit and buys OKX in equal DOGE quantity; below -entry_z it does the reverse. Exit when z crosses back inside exit_z, at the stop_z adverse stop, or if the model becomes invalid. Each leg is sized at leg_fraction of equity, with no leverage.
Verification Results
Consider raising min_edge_bps into the optimizer's range (for example 35-80), or entering with passive limit orders, so that captured convergence is clearly larger than 21 bp plus impact.
Fee viability is marginal. Entry needs |spread - OU mean| >= 35 bp and z >= 2. Two round trips cost about 21 bp of one-leg notional in taker fees, plus modelled impact, which was large in the smoke test. Measured on total two-leg notional, net per-trade return will be well below the analyst's 0.15% per-trade floor even if the spread converges fully. This passes check 8 because 0.35% is above 0.15%, but it is close to the limit.
Include Bybit and OKX funding in PnL when it becomes available, or record how many pairs were held across a funding stamp.
The cross-venue funding differential is not modelled: the backtest reports funding_folded=false and funding_events_available=0. Average holding is only about 2 hours, so the effect is small, but a pair held across an 8-hour funding stamp pays or receives the difference between the two venues' rates.
No change to the strategy is needed. The catalog query path (glob/walk over about 372k directories) should be referred to engineering.
Runtime: the sandbox took 275 s against a 300 s limit, and the full-history projection is about 630 s. The strategy's own per-bar work is O(1): one deque append, bounded with maxlen=744. The daily AR(1) fit is O(720). The developer's profiling attributes the time to ParquetDataCatalog file discovery, which would make this a platform problem, not a strategy problem. Note that 1H bars on 2 instruments over about 1904 days is roughly 46k bars per leg.
Derive _entry_direction from the side of the open Bybit position inside should_exit, rather than from instance state.
_submit_entry is overridden so that it opens both legs atomically. It calls super()._submit_entry and then _submit_entry_instrument for OKX with the same quantity and the opposite side. While the pair is being built, _opening_pair blocks re-entrant reconciliation, and orphan or mismatched legs are aborted. This looks correct. However, _entry_direction is held in memory and is not restored after a restart, so should_exit's mean-cross and stop tests would be inactive (direction 0) for a pair inherited after a restart. The exit would then depend on the model or OKX-leg checks.
This edge is thin compared with the cost of trading four legs. A round trip on both legs costs about 0.21% of one-leg notional in taker fees (Bybit 0.055% x2 plus OKX 0.05% x2). The 35 bp min_edge entry filter, exiting at 0.25 sigma, therefore leaves roughly 10 bp net per pair before impact. In the smoke test, impact took 64% of gross, commissions took a further 22%, and the average was only 0.034% per leg position over 4 closed positions (2 pairs) in 834 days. That sample is far too small to judge. The full backtest should report per-pair net return after impact. It should also report the funding differential between Bybit and OKX DOGE perps, which is not modelled here (funding_folded=false, 0 events). If the 1904-day history also produces fewer than about 30 pairs, the result cannot be relied on.
Backtest Review
- Sharpe
- 0.23
- Total return
- 0.10%
- Max drawdown
- 1.99%
- Trades
- 30
- Win rate
- 43.3%
- Profit factor
- 1.03
Data and accounting are clean: both legs are aligned with no missing bars, accounting_valid is true, end_unrealized is 0%, and there are no liquidations.
Drawdown is small (1.99%), and the trades are balanced long/short, which fits a market-neutral spread design.
Per-trade edge is below costs. avg_trade_return_pct is 0.0277% per leg position. The single-leg Bybit/OKX futures floor is 0.15%. Under L127's leg-scaled rule the floor is about 3 x 0.21% = 0.63%, because each pair pays four taker fills. The edge is roughly 5-20x below the floor.
Modeled impact takes 79.5% of gross (the soft floor is 50%), and commissions take another 10.9%. Net PF is 1.027, which is barely above 1.
The sample is too small. Only 15 pair entries (30 closed leg positions) fired in 1905 days, against about 100 needed (L178). The holdout would see about 3 pairs, short of the 10 it needs.
There is no significance. Sharpe is 0.23 with a 95% CI of -0.55 to 1.25, PSR is 0.52 and Calmar is 0.0096. The signal-research IC is -0.015 (rejected_no_information), with a net forecast edge of -0.04%.
Time in market is about 0.1%, and the max-drawdown duration is 1560 days, so calendar Sharpe cannot approach 1.0 (L165). 2023 has zero trades, which shows the cross-venue DOGE spread rarely dislocates by more than 35 bp.
Analysis
Backtest gate: - metrics unreliable: Incoherent: Sharpe -0.05 disagrees in sign with total_return 0.10% — the Sharpe is computed from the mtm_equity_curve series while the return comes from the equity curve. Judge on the equity curve.
Iteration History
Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] The 25 bp minimum modeled convergence leaves little room beyond approximately 21 bp in four taker fees, before slippage and funding. The four-trade sandbox cannot establish an edge. - [critical] should_enter() submits the OKX order before the base class checks and submits the Bybit order. If the Bybit order is rejected or deferred, OKX can fill alone. (line 113) — fix: Track both orders and fills as a pair; promptly flatten either leg if its counterpart fails. - [critical] The base class calls should_exit() only when a Bybit position is open. An OKX-only position therefore has no exit path and can remain unhedged indefinitely. (line 116) — fix: Check both venue positions on every processed bar and flatten any unmatched leg.
Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] The four-trade sandbox cannot establish profitability; its equity metrics are marked unreliable. - [critical] The absolute z-score exit can miss a crossing of the OU mean. A pair entered at positive z remains open if the spread jumps to a negative z beyond the exit band, leaving the original trade open after its mean-reversion target has been crossed. (line 215) — fix: Record the entry direction and exit when the spread crosses that direction's mean-side threshold. Keep the adverse-move stop separate.
sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (833 days of DOGEUSDT.BYBIT-1-HOUR-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).
Outcome Summary
A dislocation between the same asset on two venues is usually smaller than four taker fills plus impact. A re-proposal only makes sense with maker/passive execution on both venues and a pre-registered net edge of at least 0.6% per pair after impact.
The analyst abandoned it at backtest review, before optimization, for fee_edge / negative_expectancy. The per-leg edge of 0.0277% was far below the 0.15% single-leg floor and the roughly 0.63% leg-scaled floor for a pair that pays four taker fills. The sample was too small (15 pairs against about 100 needed), and the signal IC of -0.015 was rejected as carrying no information.
It traded mean reversion in the log price spread between DOGE perpetuals on Bybit and OKX. Each day it refit an Ornstein-Uhlenbeck model on the previous 30 days of synchronized 1-hour bars, then traded equal-quantity hedged pairs when the spread's z-score passed 2.0.
Across 1905 days it opened only 15 pairs (30 closed leg positions), and the overall result was close to flat. Sharpe was 0.23 (95% CI -0.55 to 1.25), profit factor 1.027 and max drawdown 1.99%. The average trade returned 0.0277% of notional, and modeled impact took 79.5% of gross profit.
Analysis
Optimal Pairs Trading
Backtest and paper results are hypothetical. Trading involves risk of loss.