258 lines
10 KiB
Plaintext
258 lines
10 KiB
Plaintext
|
|
import pandas as pd
|
|||
|
|
import numpy as np
|
|||
|
|
from typing import Dict, Tuple
|
|||
|
|
import matplotlib.pyplot as plt
|
|||
|
|
|
|||
|
|
class MultiAssetRCDDAnalyzer:
|
|||
|
|
"""
|
|||
|
|
Enhance DOLPHIN with multi-asset RCDD analysis for better correlation weighting
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(self, rcdd_analyzer):
|
|||
|
|
self.rcdd_analyzer = rcdd_analyzer
|
|||
|
|
|
|||
|
|
def compute_drawdown_correlations(self,
|
|||
|
|
price_data: pd.DataFrame,
|
|||
|
|
entry_prices: Dict[str, float]) -> pd.DataFrame:
|
|||
|
|
"""
|
|||
|
|
Compute correlations between assets based on their RCDD characteristics
|
|||
|
|
"""
|
|||
|
|
rcdd_metrics = {}
|
|||
|
|
|
|||
|
|
# Calculate RCDD for each asset
|
|||
|
|
for asset in price_data.columns:
|
|||
|
|
if asset in entry_prices:
|
|||
|
|
metrics = self.rcdd_analyzer.recursive_conditional_drawdown(
|
|||
|
|
price_data[asset], entry_prices[asset]
|
|||
|
|
)
|
|||
|
|
rcdd_metrics[asset] = {
|
|||
|
|
'avg_drawdown': metrics.avg_drawdown,
|
|||
|
|
'max_drawdown': metrics.max_drawdown,
|
|||
|
|
'recovery_probability': metrics.recovery_probability,
|
|||
|
|
'recovery_time': metrics.avg_recovery_time,
|
|||
|
|
'confidence_width': metrics.confidence_interval[1] - metrics.confidence_interval[0]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Create DataFrame of RCDD characteristics
|
|||
|
|
rcdd_df = pd.DataFrame(rcdd_metrics).T
|
|||
|
|
|
|||
|
|
# Compute correlations between RCDD characteristics
|
|||
|
|
correlations = {}
|
|||
|
|
|
|||
|
|
for char in rcdd_df.columns:
|
|||
|
|
corr_matrix = rcdd_df[[char]].corrwith(rcdd_df, axis=0)
|
|||
|
|
correlations[f'{char}_correlation'] = corr_matrix
|
|||
|
|
|
|||
|
|
return pd.DataFrame(correlations)
|
|||
|
|
|
|||
|
|
def enhanced_pair_weighting(self,
|
|||
|
|
asset1: str,
|
|||
|
|
asset2: str,
|
|||
|
|
price_data: pd.DataFrame,
|
|||
|
|
entry_prices: Dict[str, float]) -> Dict:
|
|||
|
|
"""
|
|||
|
|
Enhanced weighting that combines price correlation with RCDD analysis
|
|||
|
|
"""
|
|||
|
|
# Traditional price correlation
|
|||
|
|
price_corr = price_data[asset1].corr(price_data[asset2])
|
|||
|
|
|
|||
|
|
# RCDD-based analysis
|
|||
|
|
metrics1 = self.rcdd_analyzer.recursive_conditional_drawdown(
|
|||
|
|
price_data[asset1], entry_prices[asset1]
|
|||
|
|
)
|
|||
|
|
metrics2 = self.rcdd_analyzer.recursive_conditional_drawdown(
|
|||
|
|
price_data[asset2], entry_prices[asset2]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Drawdown behavior similarity
|
|||
|
|
dd_similarity = 1 - abs(metrics1.avg_drawdown - metrics2.avg_drawdown) / \
|
|||
|
|
max(metrics1.avg_drawdown, metrics2.avg_drawdown, 0.01)
|
|||
|
|
|
|||
|
|
recovery_similarity = 1 - abs(metrics1.recovery_probability - metrics2.recovery_probability)
|
|||
|
|
|
|||
|
|
# Confidence reliability
|
|||
|
|
conf_width1 = metrics1.confidence_interval[1] - metrics1.confidence_interval[0]
|
|||
|
|
conf_width2 = metrics2.confidence_interval[1] - metrics2.confidence_interval[0]
|
|||
|
|
|
|||
|
|
# Lower confidence width = more reliable
|
|||
|
|
reliability1 = 1 / (1 + conf_width1)
|
|||
|
|
reliability2 = 1 / (1 + conf_width2)
|
|||
|
|
combined_reliability = (reliability1 + reliability2) / 2
|
|||
|
|
|
|||
|
|
# Enhanced weighting formula
|
|||
|
|
# Independence factor (lower correlation = higher weight)
|
|||
|
|
independence_factor = 1 - abs(price_corr)
|
|||
|
|
|
|||
|
|
# Behavior diversity factor (different RCDD behavior = higher weight)
|
|||
|
|
diversity_factor = 1 - (dd_similarity + recovery_similarity) / 2
|
|||
|
|
|
|||
|
|
# Reliability factor (more reliable RCDD = higher weight)
|
|||
|
|
|
|||
|
|
# Combined weight
|
|||
|
|
enhanced_weight = (independence_factor * 0.4 +
|
|||
|
|
diversity_factor * 0.3 +
|
|||
|
|
combined_reliability * 0.3)
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
'price_correlation': price_corr,
|
|||
|
|
'drawdown_similarity': dd_similarity,
|
|||
|
|
'recovery_similarity': recovery_similarity,
|
|||
|
|
'combined_reliability': combined_reliability,
|
|||
|
|
'independence_factor': independence_factor,
|
|||
|
|
'diversity_factor': diversity_factor,
|
|||
|
|
'enhanced_weight': enhanced_weight,
|
|||
|
|
'traditional_weight': independence_factor, # For comparison
|
|||
|
|
'weight_improvement': enhanced_weight - independence_factor
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def demonstrate_concept():
|
|||
|
|
"""
|
|||
|
|
Demonstrate how multi-asset RCDD analysis enhances DOLPHIN weighting
|
|||
|
|
"""
|
|||
|
|
print("🐬 MULTI-ASSET RCDD ENHANCEMENT FOR DOLPHIN")
|
|||
|
|
print("="*55)
|
|||
|
|
|
|||
|
|
# Create sample data with different correlation and RCDD patterns
|
|||
|
|
np.random.seed(42)
|
|||
|
|
dates = pd.date_range('2023-01-01', periods=200, freq='1H')
|
|||
|
|
|
|||
|
|
# Simulate different asset types
|
|||
|
|
assets = {
|
|||
|
|
'BTC': {'base_price': 50000, 'volatility': 0.03, 'trend': 0.001},
|
|||
|
|
'ETH': {'base_price': 3000, 'volatility': 0.035, 'trend': 0.0012}, # Similar to BTC
|
|||
|
|
'GOLD': {'base_price': 2000, 'volatility': 0.015, 'trend': 0.0002}, # Different behavior
|
|||
|
|
'SPY': {'base_price': 400, 'volatility': 0.02, 'trend': 0.0008}, # Different again
|
|||
|
|
'BONDS': {'base_price': 100, 'volatility': 0.008, 'trend': -0.0001} # Very different
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
price_data = {}
|
|||
|
|
entry_prices = {}
|
|||
|
|
|
|||
|
|
for asset, params in assets.items():
|
|||
|
|
returns = np.random.normal(params['trend'], params['volatility'], len(dates))
|
|||
|
|
|
|||
|
|
# Add some correlation between BTC and ETH
|
|||
|
|
if asset == 'ETH':
|
|||
|
|
btc_returns = np.array(list(price_data.values())[0]) if price_data else returns
|
|||
|
|
returns = 0.7 * returns + 0.3 * np.random.normal(0, 0.01, len(dates))
|
|||
|
|
|
|||
|
|
prices = params['base_price'] * np.exp(np.cumsum(returns))
|
|||
|
|
price_data[asset] = prices
|
|||
|
|
entry_prices[asset] = prices[50] # Entry point after some history
|
|||
|
|
|
|||
|
|
price_df = pd.DataFrame(price_data, index=dates)
|
|||
|
|
|
|||
|
|
print("📊 Sample Data Created:")
|
|||
|
|
print(f"Assets: {list(price_df.columns)}")
|
|||
|
|
print(f"Entry points: {entry_prices}")
|
|||
|
|
|
|||
|
|
# Simulate basic RCDD analyzer for demo
|
|||
|
|
class MockRCDDAnalyzer:
|
|||
|
|
def recursive_conditional_drawdown(self, price_series, entry_price):
|
|||
|
|
from dataclasses import dataclass
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class MockMetrics:
|
|||
|
|
avg_drawdown: float
|
|||
|
|
max_drawdown: float
|
|||
|
|
recovery_probability: float
|
|||
|
|
avg_recovery_time: float
|
|||
|
|
confidence_interval: Tuple[float, float]
|
|||
|
|
|
|||
|
|
# Simulate RCDD metrics based on price characteristics
|
|||
|
|
volatility = price_series.pct_change().std()
|
|||
|
|
recent_drawdown = max(0, entry_price - price_series.min())
|
|||
|
|
|
|||
|
|
return MockMetrics(
|
|||
|
|
avg_drawdown=recent_drawdown * 0.7,
|
|||
|
|
max_drawdown=recent_drawdown,
|
|||
|
|
recovery_probability=max(0.3, min(0.9, 1 - volatility * 10)),
|
|||
|
|
avg_recovery_time=volatility * 100,
|
|||
|
|
confidence_interval=(recent_drawdown * 0.5, recent_drawdown * 1.2)
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Initialize analyzer
|
|||
|
|
mock_rcdd = MockRCDDAnalyzer()
|
|||
|
|
multi_asset_analyzer = MultiAssetRCDDAnalyzer(mock_rcdd)
|
|||
|
|
|
|||
|
|
print("\n🔍 ANALYZING ASSET PAIRS:")
|
|||
|
|
print("="*40)
|
|||
|
|
|
|||
|
|
# Analyze key pairs
|
|||
|
|
test_pairs = [
|
|||
|
|
('BTC', 'ETH'), # High price correlation, similar RCDD
|
|||
|
|
('BTC', 'GOLD'), # Low price correlation, different RCDD
|
|||
|
|
('BTC', 'BONDS'), # Very different everything
|
|||
|
|
('ETH', 'SPY'), # Medium correlation, different RCDD
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
results = []
|
|||
|
|
|
|||
|
|
for asset1, asset2 in test_pairs:
|
|||
|
|
analysis = multi_asset_analyzer.enhanced_pair_weighting(
|
|||
|
|
asset1, asset2, price_df, entry_prices
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
results.append({
|
|||
|
|
'pair': f'{asset1}-{asset2}',
|
|||
|
|
**analysis
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
print(f"\n{asset1} vs {asset2}:")
|
|||
|
|
print(f" Price Correlation: {analysis['price_correlation']:.3f}")
|
|||
|
|
print(f" Drawdown Similarity: {analysis['drawdown_similarity']:.3f}")
|
|||
|
|
print(f" Recovery Similarity: {analysis['recovery_similarity']:.3f}")
|
|||
|
|
print(f" Combined Reliability: {analysis['combined_reliability']:.3f}")
|
|||
|
|
print(f" Traditional Weight: {analysis['traditional_weight']:.3f}")
|
|||
|
|
print(f" Enhanced Weight: {analysis['enhanced_weight']:.3f}")
|
|||
|
|
print(f" Improvement: {analysis['weight_improvement']:+.3f}")
|
|||
|
|
|
|||
|
|
# Summary comparison
|
|||
|
|
results_df = pd.DataFrame(results)
|
|||
|
|
|
|||
|
|
print(f"\n📈 WEIGHT COMPARISON SUMMARY:")
|
|||
|
|
print("="*35)
|
|||
|
|
print(f"Average Traditional Weight: {results_df['traditional_weight'].mean():.3f}")
|
|||
|
|
print(f"Average Enhanced Weight: {results_df['enhanced_weight'].mean():.3f}")
|
|||
|
|
print(f"Pairs with Improvement: {(results_df['weight_improvement'] > 0).sum()}/{len(results_df)}")
|
|||
|
|
|
|||
|
|
# Identify best and worst pairs
|
|||
|
|
best_pair = results_df.loc[results_df['enhanced_weight'].idxmax()]
|
|||
|
|
worst_pair = results_df.loc[results_df['enhanced_weight'].idxmin()]
|
|||
|
|
|
|||
|
|
print(f"\n🏆 HIGHEST WEIGHTED PAIR: {best_pair['pair']}")
|
|||
|
|
print(f" Enhanced Weight: {best_pair['enhanced_weight']:.3f}")
|
|||
|
|
print(f" Why: Independent price movement + diverse RCDD behavior")
|
|||
|
|
|
|||
|
|
print(f"\n⚠️ LOWEST WEIGHTED PAIR: {worst_pair['pair']}")
|
|||
|
|
print(f" Enhanced Weight: {worst_pair['enhanced_weight']:.3f}")
|
|||
|
|
print(f" Why: Correlated prices + similar RCDD behavior")
|
|||
|
|
|
|||
|
|
print(f"\n💡 KEY INSIGHTS:")
|
|||
|
|
print("="*20)
|
|||
|
|
print("✅ Enhanced weighting considers:")
|
|||
|
|
print(" • Price correlation (independence)")
|
|||
|
|
print(" • RCDD behavior diversity")
|
|||
|
|
print(" • Prediction reliability")
|
|||
|
|
print(" • Multi-dimensional asset relationships")
|
|||
|
|
|
|||
|
|
print("\n✅ Benefits for DOLPHIN:")
|
|||
|
|
print(" • More nuanced pair weighting")
|
|||
|
|
print(" • Better regime detection accuracy")
|
|||
|
|
print(" • Reduced false signals from correlated behavior")
|
|||
|
|
print(" • Adaptive to changing market structures")
|
|||
|
|
|
|||
|
|
print(f"\n🔧 PRACTICAL IMPLEMENTATION:")
|
|||
|
|
print("="*30)
|
|||
|
|
print("1. Calculate RCDD for all assets in universe")
|
|||
|
|
print("2. Compute enhanced weights for all pairs")
|
|||
|
|
print("3. Use enhanced weights in DOLPHIN algorithm")
|
|||
|
|
print("4. Monitor weight stability over time")
|
|||
|
|
print("5. Recalibrate periodically")
|
|||
|
|
|
|||
|
|
return results_df, price_df
|
|||
|
|
|
|||
|
|
# Run the demonstration
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
results, data = demonstrate_concept()
|