← Back to list

funding_carry_trade VALIDATED FAIL

Auto-discovered strategy

Symbol: BTC | Exchange: Bitfinex | Role: carry

3/6
Profitable Years
+51.8%
Total Return
26.7%
Avg Win Rate
-0.10
Avg Sharpe

Year-by-Year Results

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

Performance Chart

Loading chart...

Walk-Forward Validation FAIL

0/1 Windows Profitable
-0.5% OOS Return
0.00 Median Sharpe
0.000 Score
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

AI Review

Not yet reviewed. Run: ./review_strategy.sh funding_carry_trade

Source Code

"""
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%)
"""