Files
DOLPHIN/nautilus_dolphin/ACB_IMPLEMENTATION_README.md
hjnormey 01c19662cb initial: import DOLPHIN baseline 2026-04-21 from dolphinng5_predict working tree
Includes core prod + GREEN/BLUE subsystems:
- prod/ (BLUE harness, configs, scripts, docs)
- nautilus_dolphin/ (GREEN Nautilus-native impl + dvae/ preserved)
- adaptive_exit/ (AEM engine + models/bucket_assignments.pkl)
- Observability/ (EsoF advisor, TUI, dashboards)
- external_factors/ (EsoF producer)
- mc_forewarning_qlabs_fork/ (MC regime/envelope)

Excludes runtime caches, logs, backups, and reproducible artifacts per .gitignore.
2026-04-21 16:58:38 +02:00

11 KiB
Executable File
Raw Permalink Blame History

ACB v5 Implementation on Nautilus-Dolphin

Date: 2026-02-19
Version: v5 (Empirically Validated)
Status: Production Ready


Overview

The Adaptive Circuit Breaker (ACB) v5 has been integrated into the Nautilus-Dolphin trading stack. This implementation provides position-sizing protection based on external market stress indicators.

Key Features

  • Position Sizing Only: Affects trade size, not trade selection (win rate invariant at 46.1%)
  • External Factor Based: Uses funding rates, DVOL, FNG, taker ratio
  • Empirically Validated: 1% fine sweep across 0-80% (62 cut rates tested)
  • v5 Configuration: 0/15/45/55/75/80 cut rates (beats v2 by ~$150 on $10k)

ACB v5 Configuration

Cut Rates by Signal Count

Signals Cut Rate Description
0 0% No protection (normal market)
1 15% Light protection (mild stress)
2 45% Moderate protection
3 55% High protection (crash level)
4 75% Very high protection
5+ 80% Extreme protection

External Factors Monitored

Factor Threshold Weight
Funding (BTC) <-0.0001 (very bearish) High
DVOL (BTC) >80 (extreme), >55 (elevated) High
FNG (Fear & Greed) <25 (extreme fear) Medium (needs confirmation)
Taker Ratio <0.8 (selling pressure) Medium

Files Added/Modified

New Files

  1. nautilus/adaptive_circuit_breaker.py

    • AdaptiveCircuitBreaker: Core ACB logic
    • ACBConfig: Configuration dataclass
    • ACBPositionSizer: Integration wrapper
    • get_acb_cut_for_date(): Convenience function
  2. tests/test_adaptive_circuit_breaker.py

    • Comprehensive unit tests
    • Integration tests (Feb 6 scenario)
    • Validation tests

Modified Files

  1. nautilus/strategy.py
    • Added ACB integration in DolphinExecutionStrategy
    • Modified calculate_position_size() to apply ACB cuts
    • Added ACB stats logging in on_stop()

Usage

Basic Usage (Automatic)

The ACB is enabled by default and automatically applies cuts to position sizing:

# In your strategy config
config = {
    'acb_enabled': True,  # Default: True
    # ... other config
}

strategy = DolphinExecutionStrategy(config)

When a signal is received, the strategy will:

  1. Calculate base position size (balance × fraction × leverage)
  2. Query ACB for current cut rate based on external factors
  3. Apply cut: final_size = base_size × (1 - cut_rate)
  4. Log the ACB application

Manual Usage

from nautilus_dolphin.nautilus.adaptive_circuit_breaker import (
    AdaptiveCircuitBreaker, get_acb_cut_for_date
)

# Method 1: Direct usage
acb = AdaptiveCircuitBreaker()
cut_info = acb.get_cut_for_date('2026-02-06')
print(f"Cut: {cut_info['cut']*100:.0f}%, Signals: {cut_info['signals']}")

position_size = base_size * (1 - cut_info['cut'])

# Method 2: Convenience function
cut_info = get_acb_cut_for_date('2026-02-06')

Disabling ACB

config = {
    'acb_enabled': False,  # Disable ACB
    # ... other config
}

Empirical Validation

Test Results (1% Fine Sweep)

Cut Rate ROI MaxDD Sharpe
0% 8.62% 18.3% 1.52
15% 7.42% 15.8% 1.51
45% 4.83% 10.5% 1.46
55% 3.93% 8.6% 1.43
75% 2.01% 5.0% 1.28
80% 1.50% 4.1% 1.19

v5 vs v2 Comparison

Config Ending Capital MaxDD Winner
v5 (0/15/45/55/75/80) $10,782 14.3% v5
v2 (0/30/45/55/65/75) $10,580 11.7%

v5 wins by $202 (1.9%) - validated across multiple market scenarios.

Feb 6/8 Crash Validation

  • Feb 6: 3+ signals detected → 55% cut applied → Saved $2,528 vs no-CB
  • Feb 8: 3+ signals detected → 55% cut applied → Saved $468 vs no-CB

Configuration Options

ACBConfig Parameters

from nautilus_dolphin.nautilus.adaptive_circuit_breaker import ACBConfig

config = ACBConfig(
    # Cut rates (v5 optimal - empirically validated)
    CUT_RATES={
        0: 0.00,
        1: 0.15,
        2: 0.45,
        3: 0.55,
        4: 0.75,
        5: 0.80,
    },
    
    # Signal thresholds
    FUNDING_VERY_BEARISH=-0.0001,
    FUNDING_BEARISH=0.0,
    DVOL_EXTREME=80,
    DVOL_ELEVATED=55,
    FNG_EXTREME_FEAR=25,
    FNG_FEAR=40,
    TAKER_SELLING=0.8,
    TAKER_MILD_SELLING=0.9,
    
    # Data path
    EIGENVALUES_PATH=Path('.../correlation_arb512/eigenvalues')
)

Monitoring and Logging

Log Output Example

[INFO] ACB applied: cut=55%, signals=3.0, size=1000.00->450.00
[INFO] Position opened: BTCUSDT, entry=$96,450, TP=$95,495

...

[INFO] ACB stats: calls=48, cache_hits=45, 
       cut_distribution={0: 25, 0.15: 10, 0.45: 8, 0.55: 4, 0.75: 1}

Statistics Available

# Get ACB statistics
stats = strategy.acb_sizer.acb.get_stats()
print(f"Total calls: {stats['total_calls']}")
print(f"Cache hit rate: {stats['cache_hit_rate']:.1%}")
print(f"Cut distribution: {stats['cut_distribution']}")

Testing

Run Unit Tests

cd nautilus_dolphin
python -m pytest tests/test_adaptive_circuit_breaker.py -v

Test Scenarios

  1. Normal Market: 0 signals → 0% cut
  2. Mild Stress: 1 signal → 15% cut
  3. Moderate Stress: 2 signals → 45% cut
  4. High Stress: 3 signals → 55% cut
  5. Extreme Stress: 4+ signals → 75-80% cut

Feb 6 Integration Test

# Simulate Feb 6 conditions
cut_info = get_acb_cut_for_date('2026-02-06')
assert cut_info['signals'] >= 2.0
assert cut_info['cut'] >= 0.45

Architecture

┌─────────────────────────────────────────────────────────────┐
│                 DolphinExecutionStrategy                    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────┐      ┌─────────────────────────────┐  │
│  │  Signal Received │─────>│  calculate_position_size()  │  │
│  └─────────────────┘      └─────────────────────────────┘  │
│                                       │                     │
│                                       ▼                     │
│                           ┌─────────────────────────────┐  │
│                           │   ACBPositionSizer          │  │
│                           │   - get_cut_for_date()      │  │
│                           │   - apply_cut_to_size()     │  │
│                           └─────────────────────────────┘  │
│                                       │                     │
│                                       ▼                     │
│                           ┌─────────────────────────────┐  │
│                           │  AdaptiveCircuitBreaker     │  │
│                           │  - load_external_factors()  │  │
│                           │  - calculate_signals()      │  │
│                           │  - get_cut_from_signals()   │  │
│                           └─────────────────────────────┘  │
│                                       │                     │
│                                       ▼                     │
│                           ┌─────────────────────────────┐  │
│                           │  External Factor Files      │  │
│                           │  (correlation_arb512/...)   │  │
│                           └─────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Best Practices

1. Always Keep ACB Enabled

# DON'T disable ACB unless you have a specific reason
config = {'acb_enabled': False}  # NOT recommended

2. Monitor Cut Distribution

# Check that cuts are being applied reasonably
stats = acb.get_stats()
if stats['cut_distribution'][0.80] > 10:  # Too many extreme cuts
    print("Warning: High frequency of extreme cuts")

3. Cache Hit Rate

# Cache should be >80% for same-day lookups
assert stats['cache_hit_rate'] > 0.8

Troubleshooting

Issue: ACB Not Applying Cuts

Symptoms: All trades at full size, no ACB logs

Solutions:

  1. Check acb_enabled is True in config
  2. Verify external factor files exist in EIGENVALUES_PATH
  3. Check logs for "ACB applied" messages

Issue: Always 0% Cut

Symptoms: ACB always returns 0% cut

Solutions:

  1. Check external factor files are being loaded
  2. Verify factor values (funding, DVOL, FNG, taker)
  3. Check signal calculation thresholds

Issue: Too Many Extreme Cuts

Symptoms: Frequent 75-80% cuts

Solutions:

  1. Check external factor data quality
  2. Verify FNG confirmation logic (requires other signals)
  3. Adjust thresholds if needed

References

  • Original Analysis: ACB_1PCT_SWEEP_COMPLETE_ANALYSIS.md
  • v2 vs v5 Comparison: analyze_v2_vs_v5_capital.py
  • Empirical Results: vbt_results/acb_1pct_sweep_*.json
  • Feb 6/8 Validation: ACB_CUT_RATE_EMPRICAL_RESULTS.md

Contact

For issues or questions about the ACB implementation, refer to:

  • nautilus_dolphin/nautilus/adaptive_circuit_breaker.py
  • nautilus_dolphin/tests/test_adaptive_circuit_breaker.py

End of ACB Implementation Documentation