Class: DhanHQ::OptionAnalytics::BlackScholes
- Inherits:
-
Object
- Object
- DhanHQ::OptionAnalytics::BlackScholes
- Defined in:
- lib/DhanHQ/option_analytics/black_scholes.rb
Overview
Black-Scholes option pricing model for calculating theoretical option prices and Greeks.
Class Method Summary collapse
-
.greeks(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) ⇒ Hash
Calculate option Greeks (Delta, Gamma, Theta, Vega, Rho).
-
.implied_volatility(market_price:, spot:, strike:, time_to_expiry:, risk_free_rate:, option_type:, tolerance: 0.0001, max_iterations: 100) ⇒ Float
Calculate implied volatility using Newton-Raphson method.
-
.price(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) ⇒ Float
Calculate theoretical option price using Black-Scholes model.
Class Method Details
.greeks(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) ⇒ Hash
Calculate option Greeks (Delta, Gamma, Theta, Vega, Rho).
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/DhanHQ/option_analytics/black_scholes.rb', line 50 def self.greeks(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) return empty_greeks if time_to_expiry <= 0 d1 = calculate_d1(spot, strike, time_to_expiry, risk_free_rate, volatility) d2 = calculate_d2(d1, time_to_expiry, volatility) gamma = normal_pdf(d1) / (spot * volatility * Math.sqrt(time_to_expiry)) theta = if option_type == :call calculate_call_theta(spot, strike, time_to_expiry, risk_free_rate, volatility, d1, d2) else calculate_put_theta(spot, strike, time_to_expiry, risk_free_rate, volatility, d1, d2) end vega = spot * normal_pdf(d1) * Math.sqrt(time_to_expiry) / 100 rho = if option_type == :call calculate_call_rho(spot, strike, time_to_expiry, risk_free_rate, d2) else calculate_put_rho(spot, strike, time_to_expiry, risk_free_rate, d2) end { delta: calculate_delta(spot, strike, time_to_expiry, risk_free_rate, volatility, option_type), gamma: gamma, theta: theta / 365.0, # Daily theta vega: vega, rho: rho / 100.0 } end |
.implied_volatility(market_price:, spot:, strike:, time_to_expiry:, risk_free_rate:, option_type:, tolerance: 0.0001, max_iterations: 100) ⇒ Float
Calculate implied volatility using Newton-Raphson method.
rubocop:disable Metrics/ParameterLists
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/DhanHQ/option_analytics/black_scholes.rb', line 93 def self.implied_volatility(market_price:, spot:, strike:, time_to_expiry:, risk_free_rate:, option_type:, tolerance: 0.0001, max_iterations: 100) # rubocop:enable Metrics/ParameterLists return 0.0 if time_to_expiry <= 0 || market_price <= 0 # Initial guess iv = 0.2 max_iterations.times do theoretical_price = price( spot: spot, strike: strike, time_to_expiry: time_to_expiry, risk_free_rate: risk_free_rate, volatility: iv, option_type: option_type ) diff = theoretical_price - market_price return iv if diff.abs < tolerance # Vega for Newton-Raphson vega = spot * normal_pdf(calculate_d1(spot, strike, time_to_expiry, risk_free_rate, iv)) * Math.sqrt(time_to_expiry) return iv if vega < 1e-10 iv -= diff / vega iv = [iv, 0.001].max # Prevent negative volatility end iv end |
.price(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) ⇒ Float
Calculate theoretical option price using Black-Scholes model.
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/DhanHQ/option_analytics/black_scholes.rb', line 28 def self.price(spot:, strike:, time_to_expiry:, risk_free_rate:, volatility:, option_type:) return 0.0 if time_to_expiry <= 0 d1 = calculate_d1(spot, strike, time_to_expiry, risk_free_rate, volatility) d2 = calculate_d2(d1, time_to_expiry, volatility) if option_type == :call (spot * normal_cdf(d1)) - (strike * Math.exp(-risk_free_rate * time_to_expiry) * normal_cdf(d2)) else (strike * Math.exp(-risk_free_rate * time_to_expiry) * normal_cdf(-d2)) - (spot * normal_cdf(-d1)) end end |