/** * Advanced Risk Management Examples * Demonstrates orderbook analytics, portfolio risk, and bet sizing */ import { OrderbookAnalyzer, RiskAnalyzer, TradingEngine } from '@stock-bot/engine'; import { getLogger } from '@stock-bot/logger'; const logger = getLogger('AdvancedRiskExample'); // Example 1: Orderbook Analytics async function orderbookAnalyticsExample() { console.log('\n=== Orderbook Analytics Example ==='); const engine = new TradingEngine('paper', { startingCapital: 100000 }); const obAnalyzer = new OrderbookAnalyzer(); // Update orderbook with some data const symbol = 'AAPL'; engine.updateQuote(symbol, 149.95, 150.05, 1000, 1200); engine.updateQuote(symbol, 149.90, 150.10, 800, 900); engine.updateQuote(symbol, 149.85, 150.15, 600, 700); // Get orderbook snapshot const snapshotJson = engine.getOrderbookSnapshot(symbol, 10); const snapshot = JSON.parse(snapshotJson); // Analyze orderbook const analyticsJson = obAnalyzer.analyzeOrderbook(snapshotJson); const analytics = JSON.parse(analyticsJson); console.log('Orderbook Analytics:'); console.log(` Spread: $${analytics.spread.toFixed(2)} (${analytics.spread_bps.toFixed(1)} bps)`); console.log(` Mid Price: $${analytics.mid_price.toFixed(2)}`); console.log(` Micro Price: $${analytics.micro_price.toFixed(2)}`); console.log(` Imbalance: ${(analytics.imbalance * 100).toFixed(1)}%`); console.log(` Liquidity Score: ${analytics.liquidity_score.toFixed(2)}`); // Calculate liquidity profile const profileJson = obAnalyzer.calculateLiquidityProfile(snapshotJson); const profile = JSON.parse(profileJson); console.log('\nLiquidity Profile:'); console.log(` Total Bid Depth: $${profile.total_bid_depth.toFixed(2)}`); console.log(` Total Ask Depth: $${profile.total_ask_depth.toFixed(2)}`); // Calculate market impact for a $10,000 buy order const impactJson = obAnalyzer.calculateMarketImpact(snapshotJson, 10000, true); const impact = JSON.parse(impactJson); console.log('\nMarket Impact ($10k buy):'); console.log(` Avg Execution Price: $${impact.avg_execution_price.toFixed(2)}`); console.log(` Price Impact: ${(impact.price_impact * 100).toFixed(2)}%`); console.log(` Slippage: $${impact.slippage.toFixed(2)}`); console.log(` Levels Consumed: ${impact.levels_consumed}`); } // Example 2: Portfolio Risk Analysis async function portfolioRiskExample() { console.log('\n=== Portfolio Risk Analysis Example ==='); const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252); // $100k, 2% risk, 252 days lookback // Update historical returns for portfolio symbols const symbols = ['AAPL', 'GOOGL', 'MSFT', 'AMZN', 'META']; // Simulate some returns data (in practice, load from historical data) for (const symbol of symbols) { const returns = generateRandomReturns(252); riskAnalyzer.updateReturns(symbol, returns); } // Current positions const positions = [ { symbol: 'AAPL', quantity: 100, avgPrice: 150 }, { symbol: 'GOOGL', quantity: 50, avgPrice: 140 }, { symbol: 'MSFT', quantity: 75, avgPrice: 380 }, { symbol: 'AMZN', quantity: 40, avgPrice: 170 }, { symbol: 'META', quantity: 60, avgPrice: 480 } ]; // Current prices const prices = { AAPL: 155, GOOGL: 145, MSFT: 390, AMZN: 175, META: 490 }; // Calculate portfolio risk const riskJson = riskAnalyzer.calculatePortfolioRisk( JSON.stringify(positions.map(p => [p.symbol, p.quantity, p.avgPrice])), JSON.stringify(prices) ); const risk = JSON.parse(riskJson); console.log('Portfolio Risk Metrics:'); console.log(` VaR (95%): $${risk.total_var_95.toFixed(2)}`); console.log(` VaR (99%): $${risk.total_var_99.toFixed(2)}`); console.log(` CVaR (95%): $${risk.total_cvar_95.toFixed(2)}`); console.log('\nConcentration Metrics:'); console.log(` Herfindahl Index: ${risk.concentration_risk.herfindahl_index.toFixed(3)}`); console.log(` Effective Positions: ${risk.concentration_risk.effective_number_of_positions.toFixed(1)}`); console.log(` Top 5 Concentration: ${(risk.concentration_risk.top_5_concentration * 100).toFixed(1)}%`); console.log('\nCorrelation Analysis:'); console.log(` Average Correlation: ${risk.correlation_matrix.average_correlation.toFixed(3)}`); console.log(` Max Correlation: ${risk.correlation_matrix.max_correlation[0]} vs ${risk.correlation_matrix.max_correlation[1]} = ${risk.correlation_matrix.max_correlation[2].toFixed(3)}`); console.log(` Clustering Score: ${risk.correlation_matrix.clustering_score.toFixed(3)}`); console.log('\nStress Test Results:'); for (const [scenario, loss] of Object.entries(risk.stress_test_results)) { console.log(` ${scenario}: $${(loss as number).toFixed(2)}`); } } // Example 3: Dynamic Bet Sizing async function betSizingExample() { console.log('\n=== Dynamic Bet Sizing Example ==='); const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252); // Scenario 1: Strong signal in trending market console.log('\nScenario 1: Strong Signal, Trending Market'); let positionSize = riskAnalyzer.calculatePositionSize( 0.8, // signal_strength 0.9, // signal_confidence 0.015, // volatility (1.5% daily) 0.8, // liquidity_score 0.02, // current_drawdown (2%) 150, // price 145, // stop_loss 'trending' ); let size = JSON.parse(positionSize); console.log(` Shares: ${size.shares}`); console.log(` Notional Value: $${size.notional_value.toFixed(2)}`); console.log(` % of Capital: ${(size.percent_of_capital * 100).toFixed(2)}%`); console.log(' Adjustments:'); for (const adj of size.adjustments) { console.log(` ${adj.reason}: ${adj.factor.toFixed(2)}x`); } // Scenario 2: Weak signal in high volatility console.log('\nScenario 2: Weak Signal, High Volatility'); positionSize = riskAnalyzer.calculatePositionSize( 0.3, // signal_strength 0.5, // signal_confidence 0.03, // volatility (3% daily) 0.6, // liquidity_score 0.15, // current_drawdown (15%) 150, // price null, // no stop_loss 'high_volatility' ); size = JSON.parse(positionSize); console.log(` Shares: ${size.shares}`); console.log(` Notional Value: $${size.notional_value.toFixed(2)}`); console.log(` % of Capital: ${(size.percent_of_capital * 100).toFixed(2)}%`); // Calculate optimal stop loss const supportLevels = [148, 145, 142, 140]; const optimalStop = riskAnalyzer.calculateOptimalStopLoss( 150, // entry_price 0.015, // volatility supportLevels, 2.5, // atr true // is_long ); console.log(`\nOptimal Stop Loss: $${optimalStop.toFixed(2)}`); } // Example 4: Integrated Risk Management in Trading async function integratedTradingExample() { console.log('\n=== Integrated Risk Management Example ==='); const engine = new TradingEngine('backtest', { startTime: Date.now() - 30 * 24 * 60 * 60 * 1000, // 30 days ago endTime: Date.now(), speedMultiplier: 1 }); const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252); const obAnalyzer = new OrderbookAnalyzer(); // Simulate a trading decision const symbol = 'AAPL'; // 1. Check orderbook liquidity engine.updateQuote(symbol, 149.95, 150.05, 5000, 5500); const snapshot = engine.getOrderbookSnapshot(symbol, 10); const analytics = JSON.parse(obAnalyzer.analyzeOrderbook(snapshot)); console.log('Pre-trade Analysis:'); console.log(` Liquidity Score: ${analytics.liquidity_score.toFixed(2)}`); console.log(` Spread: ${analytics.spread_bps.toFixed(1)} bps`); console.log(` Orderbook Imbalance: ${(analytics.imbalance * 100).toFixed(1)}%`); // 2. Calculate position size based on current conditions const positionSizeJson = riskAnalyzer.calculatePositionSize( 0.7, // signal_strength 0.8, // signal_confidence 0.018, // volatility analytics.liquidity_score, // from orderbook 0.05, // current_drawdown 150, // price 147, // stop_loss 'trending' ); const positionSize = JSON.parse(positionSizeJson); console.log(`\nPosition Sizing:`); console.log(` Recommended Shares: ${positionSize.shares}`); console.log(` Risk-Adjusted Size: ${(positionSize.risk_adjusted_size * 100).toFixed(2)}%`); // 3. Check market impact before placing order const orderValue = positionSize.shares * 150; const impact = JSON.parse(obAnalyzer.calculateMarketImpact(snapshot, orderValue, true)); console.log(`\nExpected Market Impact:`); console.log(` Price Impact: ${(impact.price_impact * 100).toFixed(3)}%`); console.log(` Expected Fill Price: $${impact.avg_execution_price.toFixed(2)}`); // 4. Risk check const riskCheck = engine.checkRisk({ id: '123', symbol: symbol, side: 'buy', quantity: positionSize.shares, orderType: 'market', timeInForce: 'DAY' }); const riskResult = JSON.parse(riskCheck); console.log(`\nRisk Check: ${riskResult.passed ? 'PASSED' : 'FAILED'}`); if (!riskResult.passed) { console.log(' Violations:', riskResult.violations); } } // Helper function to generate random returns function generateRandomReturns(length: number): number[] { const returns: number[] = []; for (let i = 0; i < length; i++) { // Generate returns with mean 0.0005 (0.05%) and std dev 0.02 (2%) const return_ = (Math.random() - 0.5) * 0.04 + 0.0005; returns.push(return_); } return returns; } // Run all examples async function runExamples() { try { await orderbookAnalyticsExample(); await portfolioRiskExample(); await betSizingExample(); await integratedTradingExample(); } catch (error) { console.error('Error running examples:', error); } } // Execute if running directly if (require.main === module) { runExamples(); }