Risk Management¶
Overview¶
Comprehensive risk management tools including VaR, position sizing, and risk metrics.
Value at Risk (VaR)¶
Calculate potential losses at specified confidence level:
require 'sqa'
prices = stock.df["adj_close_price"].to_a
returns = prices.each_cons(2).map { |a, b| (b - a) / a }
# 95% confidence VaR
var_95 = SQA::RiskManager.var(returns, confidence: 0.95, method: :historical)
puts "VaR (95%): #{(var_95 * 100).round(2)}%"
# Conditional VaR (Expected Shortfall)
cvar_95 = SQA::RiskManager.cvar(returns, confidence: 0.95)
puts "CVaR (95%): #{(cvar_95 * 100).round(2)}%"
Position Sizing¶
Kelly Criterion¶
# Optimal position size based on win rate and payoffs
position = SQA::RiskManager.kelly_criterion(
win_rate: 0.60, # 60% win rate
avg_win: 0.10, # Average 10% gain
avg_loss: 0.05, # Average 5% loss
capital: 10_000
)
puts "Kelly Position: $#{position}"
Fixed Fractional¶
# Risk fixed % of capital per trade
position = SQA::RiskManager.fixed_fractional(
capital: 10_000,
risk_percent: 0.02, # Risk 2% per trade
stop_loss_percent: 0.05 # 5% stop loss
)
shares = (position / current_price).to_i
Percent Volatility¶
# Size based on volatility
position = SQA::RiskManager.percent_volatility(
capital: 10_000,
target_volatility: 0.02, # 2% target vol
price_volatility: 0.25 # Stock's 25% annualized vol
)
Risk Metrics¶
Sharpe Ratio¶
sharpe = SQA::RiskManager.sharpe_ratio(returns, risk_free_rate: 0.02)
puts "Sharpe Ratio: #{sharpe.round(2)}"
# > 1.0 = Good
# > 2.0 = Very Good
# > 3.0 = Excellent
Sortino Ratio¶
# Like Sharpe but only penalizes downside volatility
sortino = SQA::RiskManager.sortino_ratio(returns, risk_free_rate: 0.02)
puts "Sortino Ratio: #{sortino.round(2)}"
Calmar Ratio¶
# Annual return / Maximum drawdown
prices = stock.df["adj_close_price"].to_a
calmar = SQA::RiskManager.calmar_ratio(prices)
puts "Calmar Ratio: #{calmar.round(2)}"
Maximum Drawdown¶
Monte Carlo Simulation¶
# Simulate potential outcomes
simulations = SQA::RiskManager.monte_carlo_simulation(
returns: returns,
initial_value: 10_000,
periods: 252, # 1 year
num_simulations: 1000
)
# Analyze results
outcomes = simulations.map(&:last).sort
percentile_5 = outcomes[(outcomes.size * 0.05).to_i]
percentile_95 = outcomes[(outcomes.size * 0.95).to_i]
puts "5th percentile: $#{percentile_5.round(2)}"
puts "95th percentile: $#{percentile_95.round(2)}"
Complete Example¶
# Comprehensive risk assessment
class RiskAssessment
def initialize(stock)
@stock = stock
@prices = stock.df["adj_close_price"].to_a
@returns = calculate_returns
end
def assess
{
var_95: SQA::RiskManager.var(@returns, confidence: 0.95),
cvar_95: SQA::RiskManager.cvar(@returns, confidence: 0.95),
sharpe: SQA::RiskManager.sharpe_ratio(@returns),
sortino: SQA::RiskManager.sortino_ratio(@returns),
max_dd: SQA::RiskManager.max_drawdown(@prices),
volatility: @returns.standard_deviation
}
end
def position_size(capital, method: :kelly)
case method
when :kelly
SQA::RiskManager.kelly_criterion(
win_rate: calculate_win_rate,
avg_win: calculate_avg_win,
avg_loss: calculate_avg_loss,
capital: capital
)
when :fixed
SQA::RiskManager.fixed_fractional(
capital: capital,
risk_percent: 0.02,
stop_loss_percent: 0.05
)
end
end
private
def calculate_returns
@prices.each_cons(2).map { |a, b| (b - a) / a }
end
def calculate_win_rate
wins = @returns.count { |r| r > 0 }
wins.to_f / @returns.size
end
def calculate_avg_win
wins = @returns.select { |r| r > 0 }
wins.sum / wins.size
end
def calculate_avg_loss
losses = @returns.select { |r| r < 0 }
losses.sum.abs / losses.size
end
end
# Usage
assessment = RiskAssessment.new(stock)
metrics = assessment.assess
position = assessment.position_size(10_000, method: :kelly)
puts "Risk Metrics:"
puts " VaR (95%): #{(metrics[:var_95] * 100).round(2)}%"
puts " Sharpe: #{metrics[:sharpe].round(2)}"
puts " Max DD: #{(metrics[:max_dd] * 100).round(2)}%"
puts "\nRecommended Position: $#{position.round(2)}"
Best Practices¶
- Diversify: Don't risk more than 2-5% per trade
- Use Stop Losses: Always define maximum acceptable loss
- Monitor Correlations: Avoid correlated positions
- Regular Reassessment: Update risk metrics monthly
- Stress Testing: Run Monte Carlo simulations
Related¶
- Portfolio Optimizer - Optimal allocation
- FPOP - Risk/reward analysis
- Backtesting - Test risk management rules