# MAMBA-2 State-Space Dynamics Analysis Framework **Purpose**: Analyze state-space hyperparameter impact on HFT performance **Post-Tuning**: Run after 40-trial Optuna study completes **Created**: 2025-10-14 --- ## 🎯 Research Questions ### 1. State Size vs Performance **Question**: How does state dimensionality (d_state) impact Sharpe ratio and memory usage? **Hypothesis**: - State size 8: Insufficient for HFT complexity (Sharpe < 1.55) - State size 16: Optimal balance (Sharpe 1.65-1.75) - State size 32: Diminishing returns (Sharpe 1.70-1.80, but 2x memory) **Expected Finding**: **State size 16 is sweet spot** (best Sharpe per GB VRAM) **Visualization**: ```python import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # Load tuning results df = pd.read_json('results/mamba2_tuning_results.json') # Plot state size vs Sharpe ratio plt.figure(figsize=(10, 6)) sns.boxplot(data=df, x='state_size', y='sharpe_ratio') plt.axhline(y=1.50, color='r', linestyle='--', label='DQN Baseline') plt.title('MAMBA-2: State Size vs Sharpe Ratio') plt.xlabel('State Size (d_state)') plt.ylabel('Sharpe Ratio') plt.legend() plt.savefig('analysis/state_size_vs_sharpe.png') # Memory vs Accuracy scatter plt.figure(figsize=(10, 6)) df['memory_gb'] = df['vram_usage_mb'] / 1024 scatter = plt.scatter(df['memory_gb'], df['sharpe_ratio'], c=df['state_size'], cmap='viridis', s=100, alpha=0.6) plt.colorbar(scatter, label='State Size') plt.axhline(y=1.50, color='r', linestyle='--', label='DQN Baseline') plt.xlabel('VRAM Usage (GB)') plt.ylabel('Sharpe Ratio') plt.title('MAMBA-2: Memory vs Accuracy Tradeoff') plt.legend() plt.savefig('analysis/memory_vs_sharpe.png') ``` **Expected Output**: ``` State Size 8: Sharpe 1.48 ± 0.08, VRAM 1.2GB State Size 16: Sharpe 1.72 ± 0.06, VRAM 2.1GB ⭐ OPTIMAL State Size 32: Sharpe 1.76 ± 0.05, VRAM 3.8GB (marginal gain) ``` --- ### 2. Expansion Factor Impact **Question**: Does expansion_factor=4 justify 2x memory cost vs expansion_factor=2? **Hypothesis**: **expansion_factor=2 sufficient** for HFT patterns (diminishing returns at 4) **Analysis**: ```python # Group by expansion factor expansion_analysis = df.groupby('expansion_factor').agg({ 'sharpe_ratio': ['mean', 'std', 'max'], 'memory_gb': 'mean', 'inference_latency_us': 'mean' }) print("Expansion Factor Analysis:") print(expansion_analysis) # Statistical significance test (t-test) from scipy.stats import ttest_ind expand_2 = df[df['expansion_factor'] == 2]['sharpe_ratio'] expand_4 = df[df['expansion_factor'] == 4]['sharpe_ratio'] t_stat, p_value = ttest_ind(expand_2, expand_4) print(f"\nt-test: t={t_stat:.3f}, p={p_value:.4f}") if p_value < 0.05: print("Expansion factor 4 significantly better (p < 0.05)") else: print("No significant difference (p >= 0.05) - use expand=2 for efficiency") ``` **Expected Output**: ``` Expansion Factor 2: Sharpe 1.70 ± 0.07, VRAM 2.0GB, Latency 82μs Expansion Factor 4: Sharpe 1.73 ± 0.06, VRAM 3.2GB, Latency 115μs t-test: t=1.245, p=0.219 Conclusion: No significant difference (p >= 0.05) - use expand=2 ⭐ ``` --- ### 3. Time-Step Dynamics Optimization **Question**: What dt_min/dt_max range captures optimal tick-level + trend dynamics? **Hypothesis**: - **dt_min ~0.001** (1ms tick-level) - **dt_max ~0.05-0.10** (50-100ms trend) - Narrow range (dt_max/dt_min < 10) may underperform **Visualization**: ```python # Heatmap of dt_min vs dt_max pivot = df.pivot_table(values='sharpe_ratio', index='dt_min', columns='dt_max', aggfunc='mean') plt.figure(figsize=(10, 8)) sns.heatmap(pivot, annot=True, fmt='.2f', cmap='RdYlGn', center=1.60) plt.title('MAMBA-2: Time-Step Dynamics (dt_min vs dt_max)') plt.xlabel('dt_max (max time-step)') plt.ylabel('dt_min (min time-step)') plt.savefig('analysis/dt_dynamics_heatmap.png') # Time-step range analysis df['dt_range'] = df['dt_max'] / df['dt_min'] plt.figure(figsize=(10, 6)) plt.scatter(df['dt_range'], df['sharpe_ratio'], alpha=0.6) plt.axhline(y=1.50, color='r', linestyle='--', label='DQN Baseline') plt.xlabel('Time-Step Range (dt_max / dt_min)') plt.ylabel('Sharpe Ratio') plt.title('MAMBA-2: Time-Step Range Impact') plt.xscale('log') plt.legend() plt.savefig('analysis/dt_range_impact.png') ``` **Expected Output**: ``` Optimal dt_min: 0.001 (1ms tick capture) Optimal dt_max: 0.08 (80ms trend capture) Optimal range: 80x (multi-scale modeling) Narrow range (<10x): Sharpe 1.52 ± 0.09 (underperforms) Medium range (10-100x): Sharpe 1.72 ± 0.06 ⭐ OPTIMAL Wide range (>100x): Sharpe 1.65 ± 0.08 (noisy) ``` --- ### 4. Advanced Feature Impact **Question**: Do use_ssd and use_selective_state justify added complexity? **Hypothesis**: - **use_selective_state=true**: +5-15% Sharpe (critical for regime changes) - **use_ssd=true**: +2-5% Sharpe + 10-30% speedup **Analysis**: ```python # Feature ablation analysis feature_analysis = df.groupby(['use_ssd', 'use_selective_state']).agg({ 'sharpe_ratio': ['mean', 'std', 'count'], 'inference_latency_us': 'mean' }) print("Feature Ablation Analysis:") print(feature_analysis) # Baseline: Both disabled baseline = df[(df['use_ssd'] == False) & (df['use_selective_state'] == False)]['sharpe_ratio'].mean() # SSD only ssd_only = df[(df['use_ssd'] == True) & (df['use_selective_state'] == False)]['sharpe_ratio'].mean() # Selective state only selective_only = df[(df['use_ssd'] == False) & (df['use_selective_state'] == True)]['sharpe_ratio'].mean() # Both enabled both = df[(df['use_ssd'] == True) & (df['use_selective_state'] == True)]['sharpe_ratio'].mean() print(f"\nFeature Impact:") print(f"Baseline (both off): {baseline:.3f}") print(f"SSD only: {ssd_only:.3f} ({100*(ssd_only/baseline-1):.1f}% lift)") print(f"Selective state only: {selective_only:.3f} ({100*(selective_only/baseline-1):.1f}% lift)") print(f"Both on: {both:.3f} ({100*(both/baseline-1):.1f}% lift)") ``` **Expected Output**: ``` Feature Ablation: Baseline (both off): Sharpe 1.52, Latency 95μs SSD only: Sharpe 1.57 (3.3% lift), Latency 72μs (24% faster) Selective state only: Sharpe 1.68 (10.5% lift), Latency 88μs Both on: Sharpe 1.74 (14.5% lift), Latency 68μs ⭐ OPTIMAL Conclusion: Both features critical for HFT performance ``` --- ### 5. Hyperparameter Correlation Analysis **Question**: Which hyperparameters most strongly influence Sharpe ratio? **Visualization**: ```python # Correlation heatmap numeric_cols = ['learning_rate', 'batch_size', 'hidden_dim', 'state_size', 'num_layers', 'expansion_factor', 'dropout', 'grad_clip', 'weight_decay', 'warmup_steps', 'dt_min', 'dt_max', 'sharpe_ratio', 'memory_gb', 'inference_latency_us'] corr = df[numeric_cols].corr() plt.figure(figsize=(14, 12)) sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0, square=True, linewidths=1, cbar_kws={"shrink": 0.8}) plt.title('MAMBA-2: Hyperparameter Correlation Matrix') plt.tight_layout() plt.savefig('analysis/correlation_heatmap.png', dpi=150) # Feature importance (Sharpe correlation) sharpe_corr = corr['sharpe_ratio'].drop('sharpe_ratio').sort_values(ascending=False) print("Top Sharpe Ratio Correlations:") print(sharpe_corr) plt.figure(figsize=(10, 6)) sharpe_corr.plot(kind='barh', color=['g' if x > 0 else 'r' for x in sharpe_corr]) plt.xlabel('Correlation with Sharpe Ratio') plt.title('MAMBA-2: Feature Importance') plt.axvline(x=0, color='k', linestyle='-', linewidth=0.5) plt.tight_layout() plt.savefig('analysis/feature_importance.png') ``` **Expected Output**: ``` Top Sharpe Correlations: use_selective_state: +0.42 ⭐ Most important state_size: +0.31 ⭐ Critical learning_rate: -0.28 (lower is better) use_ssd: +0.24 hidden_dim: +0.18 dt_max: +0.15 warmup_steps: +0.12 batch_size: -0.09 expansion_factor: +0.04 (marginal) ``` --- ## 📊 Model Comparison Framework ### DQN vs PPO vs MAMBA-2 ```python # Load baseline results baselines = { 'DQN': {'sharpe': 1.50, 'win_rate': 0.52, 'max_dd': -0.15, 'latency': 120, 'vram': 1.2}, 'PPO': {'sharpe': 1.30, 'win_rate': 0.50, 'max_dd': -0.18, 'latency': 180, 'vram': 1.8}, } # MAMBA-2 best trial mamba2_best = df.loc[df['sharpe_ratio'].idxmax()] comparison = pd.DataFrame({ 'DQN': baselines['DQN'], 'PPO': baselines['PPO'], 'MAMBA-2': { 'sharpe': mamba2_best['sharpe_ratio'], 'win_rate': mamba2_best['win_rate'], 'max_dd': mamba2_best['max_drawdown'], 'latency': mamba2_best['inference_latency_us'], 'vram': mamba2_best['memory_gb'] } }) print("Model Performance Comparison:") print(comparison.T) # Relative improvement print("\nMAMBA-2 vs DQN (best baseline):") for metric in ['sharpe', 'win_rate']: improvement = (comparison.loc[metric, 'MAMBA-2'] / comparison.loc[metric, 'DQN'] - 1) * 100 print(f"{metric}: {improvement:+.1f}% improvement") # Visualization comparison_plot = comparison.T[['sharpe', 'win_rate']].copy() comparison_plot['win_rate'] *= 100 # Convert to percentage fig, axes = plt.subplots(1, 2, figsize=(14, 6)) # Sharpe ratio axes[0].bar(comparison_plot.index, comparison_plot['sharpe'], color=['#1f77b4', '#ff7f0e', '#2ca02c']) axes[0].axhline(y=1.50, color='r', linestyle='--', label='DQN Baseline') axes[0].set_ylabel('Sharpe Ratio') axes[0].set_title('Sharpe Ratio Comparison') axes[0].legend() # Win rate axes[1].bar(comparison_plot.index, comparison_plot['win_rate'], color=['#1f77b4', '#ff7f0e', '#2ca02c']) axes[1].axhline(y=52, color='r', linestyle='--', label='DQN Baseline') axes[1].set_ylabel('Win Rate (%)') axes[1].set_title('Win Rate Comparison') axes[1].legend() plt.tight_layout() plt.savefig('analysis/model_comparison.png') ``` **Expected Output**: ``` Model Performance Comparison: Sharpe Win Rate Max DD Latency VRAM DQN 1.50 52% -15% 120μs 1.2GB PPO 1.30 50% -18% 180μs 1.8GB MAMBA-2 1.74 56% -12% 68μs 2.2GB ⭐ BEST MAMBA-2 vs DQN: sharpe: +16.0% improvement ⭐ win_rate: +7.7% improvement latency: -43.3% improvement (faster) ``` --- ## 🎯 Optimal Configuration (Expected) Based on state-space dynamics analysis, the optimal MAMBA-2 config is expected to be: ```yaml # MAMBA-2 Optimal Hyperparameters (Post-Tuning Expected) model: MAMBA_2 epochs: 500 # Final training architecture: hidden_dim: 256 # d_model (balanced capacity) state_size: 16 # d_state (optimal state dynamics) num_layers: 4 # Balanced depth expansion_factor: 2 # Efficient inner dimension dropout: 0.15 # Moderate regularization state_space_dynamics: dt_min: 0.001 # 1ms tick-level capture dt_max: 0.08 # 80ms trend capture use_ssd: true # Structured State Duality (3% Sharpe lift + 24% speedup) use_selective_state: true # Context-aware transitions (10% Sharpe lift) hardware_aware: true # RTX 3050 Ti optimizations training: learning_rate: 0.0001 # Conservative for state-space stability batch_size: 32 # Balanced throughput vs memory grad_clip: 1.25 # Prevent gradient explosion weight_decay: 0.0005 # L2 regularization warmup_steps: 800 # Gradual learning rate ramp performance: sharpe_ratio: 1.74 # 16% improvement over DQN win_rate: 56% # 4% absolute improvement max_drawdown: -12% # 3% risk reduction inference_latency: 68μs # 43% faster than DQN vram_usage: 2.2GB # Fits RTX 3050 Ti comfortably ``` --- ## 📁 Analysis Scripts ### 1. Generate Full Analysis Report ```bash # After tuning completes python scripts/analyze_mamba2_tuning.py \ --results results/mamba2_tuning_results.json \ --output analysis/mamba2_report.pdf ``` ### 2. Export Best Config for Production ```bash # Extract best hyperparameters tli tune best --job-id > mamba2_production_config.yaml # Validate config tli config validate --file mamba2_production_config.yaml ``` ### 3. State-Space Dynamics Deep Dive ```python # scripts/mamba2_state_space_analysis.py import json import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # Load results with open('results/mamba2_tuning_results.json') as f: results = json.load(f) df = pd.DataFrame(results['trials']) # Run all analysis plots analyze_state_size_impact(df) analyze_expansion_factor(df) analyze_dt_dynamics(df) analyze_feature_importance(df) compare_with_baselines(df) print("Analysis complete: analysis/*.png") ``` --- ## ✅ Success Validation Checklist After tuning completes, validate: - [ ] **Best Sharpe > 1.60** (10%+ improvement over DQN) - [ ] **State size 16 is optimal** (best Sharpe per GB) - [ ] **use_selective_state=true provides lift** (5-15% Sharpe gain) - [ ] **use_ssd=true improves speed** (10-30% latency reduction) - [ ] **Optimal dt range identified** (tick + trend capture) - [ ] **No training instability** (no NaN losses, gradient explosions) - [ ] **Memory constraints respected** (<3.5GB VRAM) - [ ] **Clear hyperparameter trends** (interpretable results) --- ## 🚀 Next Steps 1. **Run 40-trial tuning** (6-10 hours): ```bash tli tune start --model MAMBA_2 --trials 40 --watch ``` 2. **Execute analysis scripts**: ```bash python scripts/analyze_mamba2_tuning.py ``` 3. **Extract best config**: ```bash tli tune best --job-id > mamba2_best.yaml ``` 4. **Train final model** (2-3 days): ```bash tli train --model MAMBA_2 --config mamba2_best.yaml --epochs 500 ``` 5. **Backtest on holdout data** (30 days): ```bash tli backtest --model MAMBA_2 --checkpoint mamba2_final.safetensors ``` 6. **Production deployment decision**: - If Sharpe > 1.70: Deploy to production ensemble - If Sharpe 1.50-1.70: Use as diversification model - If Sharpe < 1.50: Investigate failure modes, re-tune with broader search space --- **Document Version**: 1.0 **Status**: ✅ READY FOR POST-TUNING ANALYSIS **Created**: 2025-10-14 **Dependencies**: Requires completed 40-trial MAMBA-2 tuning run