Skip to content

Instantly share code, notes, and snippets.

@valachi
Last active December 16, 2015 10:19
Show Gist options
  • Save valachi/5419778 to your computer and use it in GitHub Desktop.
Save valachi/5419778 to your computer and use it in GitHub Desktop.
class BlackScholesAlgorithm
def initialize(option_grant)
@option_grant = option_grant
@stock_price = @option_grant.stock_price
@exercise_price = @option_grant.exercise_price
@term = @option_grant.expected_term
@grant_date = @option_grant.grant_date
company = @option_grant.equity_plan.company
@public_companies_tickers = company.public_companies.map(&:ticker)
end
def fair_value
(@stock_price * normal_distribution(d1)) -
(@exercise_price * Math.exp(-annual_risk_free_rate * @term) * normal_distribution(d2))
end
private
def volatility
@volatility ||= @public_companies_tickers.map {|ticker| Yahoo::Finance.new(ticker).volatility(@term*365)}.average
@volatility || 0.1
end
def annual_risk_free_rate
RiskFree.new(@grant_date).get_date(@grant_date).get_rate(@term)
end
def d2
d1 - (volatility * (@term**0.5))
end
def d1
raise "stock_price is empty for option_grant #{@option_grant.id}" unless @stock_price
raise "exercise_price is empty for option_grant #{@option_grant.id}" unless @exercise_price
(Math.log(@stock_price / @exercise_price) +
((annual_risk_free_rate + ((volatility**2) / 2)) * @term)) / (volatility * (@term**0.5))
end
def normal_distribution(x)
return 1.0 if (x > 6.0)
return 0.0 if (x < -6.0)
b1 = 0.31938153;
b2 = -0.356563782;
b3 = 1.781477937;
b4 = -1.821255978;
b5 = 1.330274429;
p = 0.2316419;
c2 = 0.3989423;
a = x.abs;
t = 1.0 / (1.0 + a * p);
b = c2*Math.exp((-x)*(x/2.0));
n = ((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
n = 1.0-b*n;
if ( x < 0.0 )
n = 1.0 - n
end
return n;
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment