MarkFix Mean Revert
A basis arbitrage strategy that fades sustained mark-index price dislocations in perpetual futures, capturing convergence as the gap closes.
Visual Overview
Key Concept: When perp and spot prices diverge significantly, fade the gap expecting convergence to index price.
Strategy Logic
Overview
Monitors the gap between perpetual futures mark price and spot index price. When the gap persists for several minutes in quiet market conditions, the strategy fades the dislocation expecting mean reversion. This exploits temporary pricing inefficiencies between perp and spot markets.
Entry Conditions
- Mark-index gap exceeds entry threshold (20-40 bps)
- Gap persists for minimum duration (3-5 minutes)
- Low volatility environment (below 60th percentile)
- No event tape or rapid repricing in progress
- Gap is not widening (stable or narrowing)
- Sufficient liquidity in both mark and index markets
Gap Calculation:
gap = (mark_price - index_price) / index_priceEntry Logic:
- Long Perp: gap < -20 bps for 3+ minutes (perp trading below index)
- Short Perp: gap > +20 bps for 3+ minutes (perp trading above index)
Position Sizing
- Small positions: 1-2% of portfolio
- Maximum 25% allocation per position
- Maximum leverage: 2x
- Conservative sizing due to quick invalidation
Exit Conditions
- Gap closes to exit threshold (5-10 bps)
- Gap widens beyond 2x entry threshold (invalidation)
- Volatility regime flips: Realized vol exceeds 80th percentile
- Event tape detected: Breaking news or rapid repricing
- Time stop reached: 20 minutes without convergence
- Stop loss: 1% from entry
Risk Management
Stop Loss
- Hard stop: 1% from entry price
- Gap widening stop: Exit if gap exceeds 2x entry threshold
- Time stop: 20 minutes maximum hold
Take Profit
- Primary target: Gap closes to 5-10 bps
- Partial exit: 50% at 10 bps, 50% at 5 bps
Position Management
- Enter with taker orders once confirmation met
- Add with maker orders if gap persists and widens slightly
- Quick exit on invalidation signals
Execution Strategy
- Entry: Taker orders for immediate execution
- Adds: Maker orders if gap remains favorable
- Exit: Taker orders on target or invalidation
Performance Expectations
- Win Rate: 70-80%
- Average Hold Time: 10-20 minutes (minimum 30 minutes)
- Profit Factor: 1.8-2.5
- Max Drawdown: 6-10%
- Expected Switching Cost: 22 bps per trade
- Best Regimes: Range-bound, Carry-friendly
Configuration
Strategy parameters:
toml
[strategy.markfix-mean-revert]
enabled = true
max_allocation = 0.25
max_leverage = 2.0
risk_per_trade = 0.015 # 1.5% risk
# Gap parameters
gap_entry_bps = 25 # 25 bps entry threshold
gap_exit_bps = 8 # 8 bps exit threshold
gap_invalidation_multiple = 2.0 # Exit if gap exceeds 2x entry
# Timing parameters
min_persistence_minutes = 4
time_stop_minutes = 20
# Volatility filters
max_volatility_percentile = 60
volatility_spike_percentile = 80
# Risk parameters
stop_loss_pct = 0.01Technical Parameters
Gap Analysis
- Entry Threshold: 20-40 bps
- Exit Threshold: 5-10 bps
- Persistence: 3-5 minutes minimum
- Invalidation: Gap > 2x entry threshold
Volatility Filters
- Entry Filter: Volatility < 60th percentile
- Exit Filter: Volatility > 80th percentile (regime flip)
Risk Metrics
- Stop Loss: 1% from entry
- Time Stop: 20 minutes
- Gap Stop: 2x entry threshold
Regime Compatibility
Compatible Regimes
- Range-bound: Gaps more likely to mean revert
- Carry-friendly: Stable funding environment
Avoid Regimes
- Event-risk: News can cause sustained dislocations
- Trending: Strong trends can maintain gaps
Example Trade
Setup: BTC perp trading above index in quiet conditions
- Mark Price: $43,550
- Index Price: $43,440
- Gap: +25.3 bps (perp premium)
- Persistence: 4 minutes at this level
- Volatility: 42nd percentile (low)
- Entry: Short perp at $43,545
- Stop Loss: $43,980 (1% = $435)
- Target: $43,475 (gap closes to 8 bps)
- Outcome: Gap converged in 12 minutes. Mark price dropped to $43,475 while index stayed at $43,440. Exited at $43,475 for +$70 profit (+0.16%)
Monitoring
Key metrics to track:
- Mark-index gap in real-time
- Gap persistence duration
- Volatility regime
- Event calendar and news flow
- Liquidity in both markets
- Gap convergence speed
- Win rate by gap size
Risk Warnings
- Event Risk: News can cause sustained dislocations
- Liquidity Risk: Thin markets can have persistent gaps
- Volatility Risk: Sudden vol spikes can widen gaps
- Execution Risk: Slippage on taker orders can erode edge
- Funding Risk: Extreme funding can maintain gaps
- Correlation: Multiple mark-index trades can correlate
Backtest Outline
python
# Pseudocode for backtesting
def calculate_gap(mark_price, index_price):
return (mark_price - index_price) / index_price
gap = calculate_gap(mark_price, index_price)
gap_history = []
# Track gap persistence
gap_history.append(gap)
if len(gap_history) > persistence_minutes:
gap_history.pop(0)
# Check entry conditions
if len(gap_history) >= persistence_minutes:
avg_gap = mean(gap_history)
volatility = calculate_realized_vol()
if abs(avg_gap) > gap_entry_bps / 10000 and volatility < 60th_percentile:
if not event_tape_detected():
if avg_gap > 0:
# Perp trading above index → Short perp
enter_short()
set_stop_loss(entry * 1.01)
set_target(entry * (1 - gap_exit_bps / 10000))
set_time_stop(20_minutes)
elif avg_gap < 0:
# Perp trading below index → Long perp
enter_long()
set_stop_loss(entry * 0.99)
set_target(entry * (1 + gap_exit_bps / 10000))
set_time_stop(20_minutes)
# Exit management
current_gap = calculate_gap(mark_price, index_price)
if abs(current_gap) < gap_exit_bps / 10000:
exit_position() # Gap closed
elif abs(current_gap) > 2.0 * gap_entry_bps / 10000:
exit_position() # Gap widening (invalidation)
elif volatility > 80th_percentile:
exit_position() # Volatility spike
elif event_tape_detected():
exit_position()
elif time_stop_reached():
exit_position()Why This Suits Small Capital + LLM Latency
- Signal requires persistence: 3-5 minute confirmation, not instant
- No need to be first: Gap convergence is gradual
- Clear entry/exit: Gap thresholds are unambiguous
- Quick trades: Typically resolved in 10-20 minutes
- Low frequency: Only trades when clear dislocations occur
- Tolerates latency: Minutes-scale response time acceptable