public override double TheoreticalOptionPrice(Option.OptionT type, double p, double s, double d, double r, double v, double t, out double delta) { if (t <= 0) { if (type == Option.OptionT.Call) { delta = 0; return(Math.Max(p - s, 0)); } else { delta = 0; return(Math.Max(s - p, 0)); } } else { assetPrice = p * Math.Exp(-d * t); // factor stock-price with dividen yield strike = s; timeStep = t; volatility = v; riskFreeRate = r; putCall = type; // calculate delta delta = Delta(type, p, s, r, d, v, t); // calculate option value return(OptionValue()); } }
public virtual double ImpliedVolatility(Option.OptionT type, double o, double p, double s, double r, double d, double t) { // check incoming variables if (t <= 0 || double.IsNaN(o) || double.IsNaN(p) || double.IsNaN(s) || double.IsNaN(r) || double.IsNaN(t)) { return(double.NaN); } int i; double min = MIN_VOLATILITY, max = MAX_VOLATILITY; double x, e, v = double.NaN, delta; for (i = 0; i < VOLATILITY_ITERATIONS; i++) { // calculate option price with guessed volatility v = (min + max) * 0.5; x = TheoreticalOptionPrice(type, p, s, r, d, v, t, out delta); // check result accuracy e = o - x; if (Math.Abs(e) < VOLATILITY_ACCURACY) { if (v < 0.01) { return(double.NaN); } else { return(v); } } // set if (e > 0) { min = v; } else { max = v; } } if (v < 0.01 || i == VOLATILITY_ITERATIONS) { return(double.NaN); } else { return(v); } }
public override double TheoreticalOptionPrice(Option.OptionT type, double p, double s, double r, double d, double v, double t, out double delta) { if (type == Option.OptionT.Call) { if (t <= 0) { delta = 0; return(Math.Max(p - s, 0)); } else { double d1, d2; D(p, s, r, d, v, t, out d1, out d2); if (double.IsInfinity(d1)) { delta = 0; return(Math.Max(p - s * Math.Exp(-r * t), 0)); } else { delta = Math.Exp(-d * t) * nd.CDF(d1); return(p * delta - s * Math.Exp(-r * t) * nd.CDF(d2)); } } } else { if (t <= 0) { delta = 0; return(Math.Max(s - p, 0)); } else { double d1, d2; D(p, s, r, d, v, t, out d1, out d2); if (double.IsInfinity(d1)) { delta = 0; return(Math.Max(s * Math.Exp(-r * t) - p, 0)); } else { delta = -Math.Exp(-d * t) * nd.CDF(-d1); return(s * Math.Exp(-r * t) * nd.CDF(-d2) + p * delta); } } } }
private double Payoff(double S, double X, Option.OptionT PutCall) { switch (PutCall) { case Option.OptionT.Call: return(Call(S, X)); case Option.OptionT.Put: return(Put(S, X)); default: return(0.0); } }
public virtual double Delta(Option.OptionT type, double p, double s, double r, double d, double v, double t) { if (t <= 0) { return(1); } double d1, d2; D(p, s, r, d, v, t, out d1, out d2); if (type == Option.OptionT.Call) { return(Math.Exp(-d * t) * nd.CDF(d1)); } else { return(-Math.Exp(-d * t) * nd.CDF(-d1)); } }
public virtual double Rho(Option.OptionT type, double p, double s, double r, double d, double v, double t) { if (t <= 0) { return(0); } double d1, d2; D(p, s, r, d, v, t, out d1, out d2); if (type == Option.OptionT.Call) { return(s * t * Math.Exp(-r * t) * nd.CDF(d2)); } else { return(s * t * Math.Exp(-r * t) * nd.CDF(-d2)); } }
public virtual double Theta(Option.OptionT type, double p, double s, double r, double d, double v, double t) { if (t <= 0) { return(0); } double d1, d2; D(p, s, r, d, v, t, out d1, out d2); if (type == Option.OptionT.Call) { return(-(p * Math.Exp(-d * t) * nd.PDF(d1) * v) / (2 * Math.Sqrt(t)) - r * s * Math.Exp(-r * t) * nd.CDF(d2) - d * p * Math.Exp(-d * t) * nd.CDF(d1)); } else { return(-(p * Math.Exp(-d * t) * nd.PDF(d1) * v) / (2 * Math.Sqrt(t)) + r * s * Math.Exp(-r * t) * nd.CDF(-d2) + d * p * Math.Exp(-d * t) * nd.CDF(-d1)); } }
public virtual double StockPrice(Option.OptionT type, double o, double s, double r, double d, double v, double t) { // check incoming variables if (t <= 0 || double.IsNaN(o) || double.IsNaN(v) || double.IsNaN(s) || double.IsNaN(r) || double.IsNaN(t)) { return(double.NaN); } int i; double min = MIN_STOCKPRICE, max = Math.Max(10 * s, MAX_STOCKPRICE); double x, e, p = double.NaN, delta; for (i = 0; i < STOCKPRICE_ITERATIONS; i++) { // calculate option price with guessed volatility p = (min + max) * 0.5; x = TheoreticalOptionPrice(type, p, s, r, d, v, t, out delta); // check result accuracy e = o - x; if (Math.Abs(e) < STOCKPRICE_ACCURACY) { if (p < 0.01) { return(double.NaN); } else { return(p); } } // set new area if (type == Option.OptionT.Call) { if (e > 0) { min = p; } else { max = p; } } else { if (e > 0) { max = p; } else { min = p; } } } if (p < 0.01 || i == STOCKPRICE_ITERATIONS) { return(double.NaN); } else { return(p); } }
public abstract double TheoreticalOptionPrice(Option.OptionT type, double p, double s, double r, double d, double v, double t, out double delta);