"""Portfolio Risk Management Example. Demonstrates portfolio-level risk controls including position limits, drawdown control, and VaR calculations. """ from openclaw.portfolio.risk import ( PortfolioRiskManager, PositionConcentrationLimit, DrawdownController, PortfolioVaR, ) from datetime import datetime def main(): """Run the portfolio risk example.""" print("=" * 60) print("OpenClaw Trading - Portfolio Risk Management") print("=" * 60) # 1. Initialize risk manager print("\n1. Initializing risk manager...") manager = PortfolioRiskManager( portfolio_id="demo_portfolio", max_concentration_pct=0.20, # Max 20% per position max_drawdown_pct=0.10, # Max 10% drawdown ) print(f" Max Position: {manager.concentration_limit.max_concentration_pct:.0%}") print(f" Max Drawdown: {manager.drawdown_monitor.max_drawdown_threshold:.0%}") # 2. Position concentration check print("\n2. Position Concentration Checks:") print("-" * 60) test_positions = [ ("AAPL", 1500.0, 10000.0), # 15% - OK ("TSLA", 2500.0, 10000.0), # 25% - Too high ("GOOGL", 800.0, 10000.0), # 8% - OK ] for symbol, position_value, portfolio_value in test_positions: concentration = position_value / portfolio_value result = manager.check_position_limit( symbol=symbol, position_value=position_value, total_portfolio_value=portfolio_value ) status = "✓ ALLOWED" if result.is_allowed else "✗ BLOCKED" print(f"\n {symbol}: ${position_value:,.2f} ({concentration:.1%})") print(f" Status: {status}") if not result.is_allowed: print(f" Reason: {result.message}") # 3. Drawdown control print("\n3. Drawdown Control:") print("-" * 60) controller = DrawdownController(max_drawdown_threshold=0.10) # Simulate portfolio values values = [ (10000.0, "Start"), (10500.0, "Peak"), (10200.0, "Small drop"), (9500.0, "5% drawdown"), (8800.0, "12% drawdown - ALERT!"), ] peak = 10000.0 for value, label in values: controller.update_portfolio_value(value) drawdown = (peak - value) / peak if value < peak else 0 if value > peak: peak = value blocked = controller.is_drawdown_exceeded() block_status = "BLOCKED" if blocked else "OK" print(f" {label}: ${value:,.2f} ({drawdown:.1%} drawdown) - {block_status}") # 4. VaR Calculation print("\n4. Value at Risk (VaR) Calculation:") print("-" * 60) var_calc = PortfolioVaR( confidence_level=0.95, var_limit_pct=0.05, ) # Simulate different volatility scenarios scenarios = [ ("Low Volatility", [0.01, -0.005, 0.008, -0.003, 0.005]), ("Medium Volatility", [0.02, -0.015, 0.018, -0.012, 0.015]), ("High Volatility", [0.05, -0.04, 0.06, -0.05, 0.045]), ] portfolio_value = 10000.0 for name, returns in scenarios: var_result = var_calc.calculate_var( portfolio_value=portfolio_value, returns=returns ) var_pct = var_result.var_amount / portfolio_value within_limit = var_result.is_within_limit status = "OK" if within_limit else "EXCEEDED" print(f"\n {name}:") print(f" VaR (95%): ${var_result.var_amount:,.2f} ({var_pct:.2%})") print(f" Status: {status}") # 5. Risk alerts print("\n5. Risk Alert System:") print("-" * 60) from openclaw.portfolio.risk import RiskAlert, RiskAlertLevel alerts = [ RiskAlert( timestamp=datetime.now(), alert_type="position_concentration", level=RiskAlertLevel.WARNING, message="AAPL position exceeds 20% limit", symbol="AAPL", current_value=0.25, threshold=0.20, action_taken="blocked", ), RiskAlert( timestamp=datetime.now(), alert_type="drawdown", level=RiskAlertLevel.CRITICAL, message="Portfolio drawdown exceeds 10%", symbol=None, current_value=0.12, threshold=0.10, action_taken="trading_blocked", ), ] for alert in alerts: emoji = "⚠️" if alert.level == RiskAlertLevel.WARNING else "🚨" print(f"\n {emoji} {alert.level.value.upper()}") print(f" Type: {alert.alert_type}") print(f" Message: {alert.message}") print(f" Current: {alert.current_value:.1%}, Threshold: {alert.threshold:.1%}") print(f" Action: {alert.action_taken}") print("\n" + "=" * 60) print("Portfolio risk example complete!") print("=" * 60) if __name__ == "__main__": main()