Class: DhanHQ::Risk::PositionSizer
- Inherits:
-
Object
- Object
- DhanHQ::Risk::PositionSizer
- Defined in:
- lib/DhanHQ/risk.rb
Overview
Calculate optimal position size based on risk parameters.
Supports multiple sizing methods:
- Fixed risk percentage of account
- Kelly criterion
- Volatility-based sizing
Class Method Summary collapse
-
.calculate(account_balance:, risk_percent:, entry_price:, stop_loss_price:, lot_size: 1) ⇒ Integer
Calculate position size based on fixed risk percentage.
-
.kelly(win_rate:, avg_win:, avg_loss:, account_balance:, entry_price:, fraction: 0.5) ⇒ Integer
Calculate position size using Kelly Criterion.
-
.volatility_based(account_balance:, risk_percent:, entry_price:, atr:, atr_multiplier: 2.0, lot_size: 1) ⇒ Integer
Calculate position size based on volatility (ATR-based).
Class Method Details
.calculate(account_balance:, risk_percent:, entry_price:, stop_loss_price:, lot_size: 1) ⇒ Integer
Calculate position size based on fixed risk percentage.
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/DhanHQ/risk.rb', line 31 def self.calculate(account_balance:, risk_percent:, entry_price:, stop_loss_price:, lot_size: 1) return 0 if account_balance <= 0 || entry_price <= 0 || stop_loss_price <= 0 return 0 if entry_price == stop_loss_price risk_amount = account_balance * (risk_percent / 100.0) risk_per_share = (entry_price - stop_loss_price).abs return 0 if risk_per_share.zero? raw_shares = (risk_amount / risk_per_share).floor (raw_shares / lot_size).floor * lot_size end |
.kelly(win_rate:, avg_win:, avg_loss:, account_balance:, entry_price:, fraction: 0.5) ⇒ Integer
Calculate position size using Kelly Criterion.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/DhanHQ/risk.rb', line 53 def self.kelly(win_rate:, avg_win:, avg_loss:, account_balance:, entry_price:, fraction: 0.5) return 0 if account_balance <= 0 || entry_price <= 0 return 0 if avg_loss.zero? || win_rate <= 0 || win_rate >= 1 # Kelly formula: f = (bp - q) / b # where b = avg_win/avg_loss, p = win_rate, q = 1 - win_rate b = avg_win / avg_loss kelly_fraction = ((b * win_rate) - (1 - win_rate)) / b return 0 if kelly_fraction <= 0 # Apply fractional Kelly adjusted_fraction = kelly_fraction * fraction risk_amount = account_balance * adjusted_fraction shares = (risk_amount / entry_price).floor [shares, 0].max end |
.volatility_based(account_balance:, risk_percent:, entry_price:, atr:, atr_multiplier: 2.0, lot_size: 1) ⇒ Integer
Calculate position size based on volatility (ATR-based).
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/DhanHQ/risk.rb', line 81 def self.volatility_based(account_balance:, risk_percent:, entry_price:, atr:, atr_multiplier: 2.0, lot_size: 1) return 0 if account_balance <= 0 || entry_price <= 0 || atr <= 0 stop_distance = atr * atr_multiplier stop_loss_price = entry_price - stop_distance calculate( account_balance: account_balance, risk_percent: risk_percent, entry_price: entry_price, stop_loss_price: stop_loss_price, lot_size: lot_size ) end |