Auto-discovered strategy
Symbol: BTC | Exchange: Bitfinex | Role: carry
Click a year to view chart
| Year | Return | Win Rate | Trades | Max DD | Sharpe |
|---|---|---|---|---|---|
| 2020 | +0.0% | 0.0% | 0 | 0.0% | 0.00 |
| 2021 | -4.2% | 25.0% | 4 | 4.1% | -2.00 |
| 2022 | -4.7% | 33.3% | 3 | 4.7% | -1.32 |
| 2023 | +5.4% | 33.3% | 24 | 11.5% | 0.38 |
| 2024 | +50.0% | 40.7% | 27 | 7.2% | 1.93 |
| 2025 | +5.2% | 27.8% | 18 | 11.6% | 0.39 |
| Window | Train Period | Val Period | Val Return | Val | Test Period | Test Return | Status |
|---|---|---|---|---|---|---|---|
| WF-1 | 2024-01→2025-06 | 2025-07→2025-12 | -0.5% | FAIL | 2026-01→ongoing | +0.0% | FAIL |
Not yet reviewed. Run: ./review_strategy.sh funding_carry_trade
"""
Funding Carry Trade Strategy
=============================
CASH-AND-CARRY CONCEPT:
This strategy exploits the funding rate premium in perpetual futures.
When funding rates are high, it indicates strong long demand in perps,
creating an arbitrage opportunity:
- Long spot (or long-only exposure)
- Collect implied funding premium through price appreciation
The strategy trades only in sustained bull markets (golden cross held
for 50+ bars) and requires high funding rates as entry confirmation.
KEY BEAR MARKET PROTECTION:
- Sustained golden cross filter (EMA50 > EMA200 for 50+ consecutive bars)
- Price must be above EMA50 and EMA200
- EMA50 must be rising
- Immediate exit on any bear signal
ENTRY CONDITIONS (ALL required):
1. Sustained golden cross: EMA50 > EMA200 for 50 consecutive bars
2. Price above EMA50 and EMA200
3. EMA50 rising over 20 bars
4. Price above EMA20 (short-term momentum)
5. Average funding rate > 25% APR (20-bar MA)
6. Current funding rate > 15% APR
7. Price not extended (< 108% of EMA50)
8. Low volatility (ATR < 4% of price)
EXIT CONDITIONS (ANY triggers):
1. Golden cross breaks (instant exit)
2. Average funding < 10% APR
3. Price closes below EMA50
4. Two consecutive closes below EMA20
PARAMETERS (all round numbers for robustness):
- EMA periods: 20, 50, 200
- Golden cross bars: 50
- Funding entry: 25% APR
- Funding exit: 10% APR
- Stop loss: 3%
- Take profit: 10%
Train Performance (2024-01-01 to 2025-06-30):
2024: +50.0% | 27 trades | 41% WR | DD 7.2% | Sharpe 1.93
2025 (partial): +6.6% | 7 trades | 43% WR | DD 2.8% | Sharpe 0.96
Total: +56.5% | Max DD < 10%
Historical Performance (out-of-sample check):
2020: +0.0% (no trades - no sustained bull)
2021: -4.2% | DD 4.1%
2022: -4.7% | DD 4.7% (survived bear market!)
2023: +5.4% | DD 11.5%
"""
import sys
sys.path.insert(0, '/root/trade_rules')
from lib import ema, atr
def init_strategy():
return {
'name': 'funding_carry_trade',
'role': 'carry',
'warmup': 250, # EMA200 + golden cross check
'subscriptions': [
{'symbol': 'tBTCUSD', 'exchange': 'bitfinex', 'timeframe': '4h'},
],
'parameters': {
# Funding thresholds (round numbers)
'funding_entry_threshold': 0.25, # 25% APR
'funding_exit_threshold': 0.10, # 10% APR
'funding_ma_period': 20, # 20-bar MA
# Regime EMAs (round numbers)
'ema_short': 50,
'ema_long': 200,
'ema_trend': 20,
# Sustained golden cross requirement (round number)
'golden_cross_bars': 50, # 50 bars (~8 days at 4h)
# Risk management (round numbers)
'stop_loss_pct': 3.0, # 3%
'take_profit_pct': 10.0, # 10%
}
}
def process_time_step(ctx):
key = ('tBTCUSD', 'bitfinex')
bars = ctx['bars'][key]
i = ctx['i']
positions = ctx['positions']
params = ctx['parameters']
# warmup=250 ensures enough bars for EMA200 + golden cross check
# Extract price data
closes = [b.close for b in bars]
funding_rates = [b.funding_apr for b in bars]
highs = [b.high for b in bars]
lows = [b.low for b in bars]
# Calculate EMAs
ema50 = ema(closes, params['ema_short'])
ema200 = ema(closes, params['ema_long'])
ema20 = ema(closes, params['ema_trend'])
if ema50[i] is None or ema200[i] is None or ema20[i] is None:
return []
# Calculate funding rate moving average
funding_ma_period = params['funding_ma_period']
recent_funding = funding_rates[i-funding_ma_period+1:i+1]
avg_funding = sum(recent_funding) / len(recent_funding) if recent_funding else 0
current_funding = funding_rates[i]
# =========================================================
# SUSTAINED GOLDEN CROSS - PRIMARY BEAR MARKET FILTER
# Must be golden cross for N consecutive bars
# This filters out brief false crosses in bear markets
# =========================================================
gc_bars = params['golden_cross_bars']
sustained_golden = True
for j in range(i - gc_bars, i + 1):
if ema50[j] is None or ema200[j] is None or ema50[j] <= ema200[j]:
sustained_golden = False
break
if not sustained_golden:
# Not in sustained bull market - exit any positions, no new entries
if key in positions:
return [{
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
}]
return []
# =========================================================
# SECONDARY BULL CONFIRMATION
# =========================================================
price_above_ema50 = closes[i] > ema50[i]
price_above_ema200 = closes[i] > ema200[i]
ema50_rising = ema50[i] > ema50[i-20] if ema50[i-20] else False
price_above_ema20 = closes[i] > ema20[i]
bull_confirmed = (price_above_ema50 and price_above_ema200 and
ema50_rising and price_above_ema20)
# Volatility filter (avoid choppy markets)
atr_vals = atr(highs, lows, closes, 20)
if atr_vals[i] is not None:
atr_pct = atr_vals[i] / closes[i] * 100
low_volatility = atr_pct < 4.0
else:
low_volatility = True
actions = []
if key not in positions:
# =========================================================
# ENTRY: Sustained bull + high funding + confirmed trend
# =========================================================
funding_entry = params['funding_entry_threshold']
funding_attractive = avg_funding > funding_entry
funding_current_ok = current_funding > 0.15
not_extended = closes[i] < ema50[i] * 1.08 # Max 8% above EMA50
if (bull_confirmed and funding_attractive and funding_current_ok and
low_volatility and not_extended):
actions.append({
'action': 'open_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
'size': 1.0,
'stop_loss_pct': params['stop_loss_pct'],
'take_profit_pct': params['take_profit_pct']
})
else:
# =========================================================
# EXIT: Funding weak OR price breakdown
# Note: sustained_golden exit already handled above
# =========================================================
funding_exit = params['funding_exit_threshold']
funding_weak = avg_funding < funding_exit
price_below_ema50 = closes[i] < ema50[i]
price_momentum_lost = closes[i] < ema20[i] and closes[i-1] < ema20[i-1]
if funding_weak or price_below_ema50 or price_momentum_lost:
actions.append({
'action': 'close_long',
'symbol': 'tBTCUSD',
'exchange': 'bitfinex',
})
return actions
# Entry/Exit logic descriptions for documentation
ENTRY_LOGIC = """
BEAR MARKET FILTER (ABSOLUTE):
- Sustained Golden Cross: EMA50 > EMA200 for 50+ consecutive bars
ENTRY SIGNALS (ALL required):
- Price > EMA50, EMA200, and EMA20
- EMA50 rising over 20 bars
- Average funding rate (20-bar MA) > 25% APR
- Current funding rate > 15% APR
- Price < 108% of EMA50 (not overextended)
- ATR < 4% of price (low volatility)
"""
EXIT_LOGIC = """
EXIT when ANY:
- Golden cross breaks (EMA50 crosses below EMA200) - INSTANT EXIT
- Average funding drops below 10% APR
- Price closes below EMA50
- Two consecutive closes below EMA20
- Stop loss hit (3%)
- Take profit hit (10%)
"""