financial_news_bot / examples /advanced_portfolio_example.py
Dmitry Beresnev
add advanced portfolio analyzer
09cafdd
"""
Advanced Portfolio Analyzer - Usage Examples
Demonstrates factor-based portfolio analysis with HRP and clustering.
"""
import asyncio
from src.core.portfolio.advanced_portfolio_analyzer import AdvancedPortfolioAnalyzer
from src.core.portfolio.advanced_portfolio_analyzer.visualizer import PortfolioVisualizer
async def example_1_basic_usage():
"""Example 1: Basic factor-based analysis."""
print("\n=== Example 1: Basic Factor-Based Analysis ===\n")
# Define portfolio
tickers = ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"]
# Define factors (themes)
factors = {
"AI": "BOTZ", # AI & Robotics ETF
"Cloud": "SKYY", # Cloud Computing ETF
"Tech": "QQQ", # Nasdaq-100 (tech proxy)
}
# Initialize analyzer
analyzer = AdvancedPortfolioAnalyzer(
tickers=tickers,
factors=factors,
lookback_days=504 # 2 years
)
# Run analysis
result = await analyzer.analyze_portfolio()
# Display summary
print(analyzer.format_summary(result))
async def example_2_with_current_weights():
"""Example 2: Analyze existing portfolio and get recommendations."""
print("\n=== Example 2: Rebalancing Recommendations ===\n")
tickers = ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"]
factors = {
"AI": "BOTZ",
"Cloud": "SKYY",
}
# Current portfolio weights (example: concentrated in NVDA)
current_weights = {
"AAPL": 0.15,
"MSFT": 0.15,
"NVDA": 0.50, # Very concentrated
"GOOGL": 0.10,
"AMZN": 0.10,
}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors)
result = await analyzer.analyze_portfolio(current_weights=current_weights)
# Show recommendations
print("Rebalancing Recommendations:")
print("-" * 70)
for rec in result.recommendations:
if rec.action != "HOLD":
symbol = "↑" if rec.action == "INCREASE" else "↓"
print(f"{symbol} {rec.ticker}:")
print(f" Current: {rec.current_weight:.1%}")
print(f" Target: {rec.target_weight:.1%}")
print(f" Reason: {rec.reason}")
print()
async def example_3_factor_exposure():
"""Example 3: Analyze factor exposures."""
print("\n=== Example 3: Factor Exposure Analysis ===\n")
tickers = ["NVDA", "AMD", "ASML", "TSM"] # Semiconductor stocks
factors = {
"AI": "BOTZ",
"Semiconductors": "SOXX",
"Technology": "QQQ",
}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors)
result = await analyzer.analyze_portfolio()
# Display factor exposures
print("Individual Asset Factor Exposures:")
print("-" * 70)
for fe in result.factor_exposures:
print(f"\n{fe.ticker}:")
for factor, beta in fe.exposures.items():
print(f" {factor:15s} {beta:+.2f}")
print(f" R²: {fe.r_squared:.2%}")
print("\n" + "=" * 70)
print("Portfolio-Level Factor Exposure:")
print("-" * 70)
for factor, exposure in result.factor_portfolio_exposure.items():
print(f" {factor:15s} {exposure:+.2f}")
async def example_4_clustering():
"""Example 4: Correlation clustering."""
print("\n=== Example 4: Correlation Clustering ===\n")
# Mix of different sectors
tickers = [
"AAPL", "MSFT", # Tech
"JPM", "BAC", # Financials
"JNJ", "PFE", # Healthcare
"XOM", "CVX", # Energy
]
factors = {"Tech": "QQQ", "Finance": "XLF"}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors)
result = await analyzer.analyze_portfolio(n_clusters=4)
# Show clusters
print("Identified Clusters:")
print("-" * 70)
for cluster_id, cluster_tickers in result.cluster_result.clusters.items():
print(f"\nCluster {cluster_id}: {', '.join(cluster_tickers)}")
# Show correlation matrix
print("\n" + "=" * 70)
print("Correlation Matrix:")
print(result.cluster_result.correlation_matrix.round(2))
async def example_5_hrp_details():
"""Example 5: HRP allocation details."""
print("\n=== Example 5: HRP Allocation Details ===\n")
tickers = ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"]
factors = {"AI": "BOTZ", "Cloud": "SKYY"}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors)
result = await analyzer.analyze_portfolio()
# Compare with equal weight
comparison = analyzer.hrp_allocator.compare_with_equal_weight(
result.hrp_weights,
result.covariance_matrix.values
)
print("HRP vs Equal Weight Comparison:")
print("-" * 70)
print(f"Equal Weight Volatility: {comparison['equal_weight_volatility']:.2%}")
print(f"HRP Volatility: {comparison['hrp_volatility']:.2%}")
print(f"Volatility Reduction: {comparison['volatility_reduction']:.1f}%")
print(f"EW Diversification Ratio: {comparison['equal_weight_diversification_ratio']:.2f}")
print(f"HRP Diversification Ratio:{comparison['hrp_diversification_ratio']:.2f}")
print("\n" + "=" * 70)
print("Risk Contributions (HRP):")
print("-" * 70)
for ticker, rc in sorted(
result.hrp_weights.risk_contributions.items(),
key=lambda x: x[1],
reverse=True
):
print(f" {ticker:6s} {rc:6.1%}")
async def example_6_visualization():
"""Example 6: Create visualizations."""
print("\n=== Example 6: Creating Visualizations ===\n")
tickers = ["AAPL", "MSFT", "NVDA", "GOOGL", "AMZN"]
factors = {"AI": "BOTZ", "Cloud": "SKYY"}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors)
result = await analyzer.analyze_portfolio()
# Create visualizer
visualizer = PortfolioVisualizer()
# Create individual plots
print("Creating correlation heatmap...")
visualizer.plot_correlation_heatmap(
result.cluster_result,
save_path="correlation_heatmap.png"
)
print("Creating dendrogram...")
visualizer.plot_dendrogram(
result.cluster_result,
save_path="dendrogram.png"
)
print("Creating weight comparison...")
visualizer.plot_weight_comparison(
result,
save_path="weight_comparison.png"
)
print("Creating risk contribution chart...")
visualizer.plot_risk_contribution(
result,
save_path="risk_contribution.png"
)
print("Creating factor exposure heatmap...")
visualizer.plot_factor_exposure(
result,
save_path="factor_exposure.png"
)
# Create comprehensive dashboard
print("Creating comprehensive dashboard...")
visualizer.create_dashboard(
result,
save_path="portfolio_dashboard.png"
)
print("\n✓ All visualizations saved!")
print(" - correlation_heatmap.png")
print(" - dendrogram.png")
print(" - weight_comparison.png")
print(" - risk_contribution.png")
print(" - factor_exposure.png")
print(" - portfolio_dashboard.png")
async def example_7_custom_factors():
"""Example 7: Custom factor definitions."""
print("\n=== Example 7: Custom Thematic Factors ===\n")
# Tech portfolio
tickers = ["AAPL", "MSFT", "NVDA", "AMD", "INTC", "QCOM"]
# Custom factors
factors = {
"AI": "BOTZ", # AI & Robotics
"Semiconductors": "SOXX", # Semiconductor
"Cloud": "SKYY", # Cloud Computing
"Cybersecurity": "HACK", # Cybersecurity
}
analyzer = AdvancedPortfolioAnalyzer(tickers, factors, lookback_days=252)
result = await analyzer.analyze_portfolio()
print("Portfolio Factor Exposure (Custom Themes):")
print("-" * 70)
for factor, exposure in result.factor_portfolio_exposure.items():
status = "✓ Strong" if abs(exposure) > 1.0 else "○ Moderate"
print(f" {status} {factor:15s} {exposure:+.2f}")
async def main():
"""Run all examples."""
examples = [
example_1_basic_usage,
example_2_with_current_weights,
example_3_factor_exposure,
example_4_clustering,
example_5_hrp_details,
example_6_visualization,
example_7_custom_factors,
]
for example in examples:
try:
await example()
except Exception as e:
print(f"\n✗ Example failed: {e}")
import traceback
traceback.print_exc()
print("\n" + "=" * 70 + "\n")
if __name__ == "__main__":
# Run single example
# asyncio.run(example_1_basic_usage())
# Or run all examples
asyncio.run(main())