public double GetTheta(double S, double X, double q, double r, double sigma, double t, EPutCall PutCall) { double t_sqrt = Math.Sqrt(t); double sigma2 = sigma * sigma; double d1 = (Math.Log(S / X) + (r - q + sigma2 * 0.5) * t) / (t_sqrt * sigma); double d2 = d1 - t_sqrt * sigma; double part1 = S * sigma * Math.Exp(-q * t) * n(d1) / 2.0 / t_sqrt; double part2 = -q *S *Math.Exp(-q *t); double part3 = r * X * Math.Exp(-r * t); switch (PutCall) { case EPutCall.Call: return(-part1 - part2 * N(d1) - part3 * N(d2)); case EPutCall.Put: return(-part1 + part2 * N(-d1) + part3 * N(-d2)); default: return(0.0); } }
public double GetGamma(double S, double X, double q, double r, double sigma, double t, EPutCall PutCall) { double t_sqrt = Math.Sqrt(t); double sigma2 = sigma * sigma; double d1 = (Math.Log(S / X) + (r - q + sigma2 * 0.5) * t) / (t_sqrt * sigma); return(Math.Exp(-q * t) * n(d1) / S / t_sqrt / sigma); }
public static double MC(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double num1 = (r - 0.5 * s * s) * t; double num2 = s * Math.Sqrt(t); double num3 = 0.0; for (int index = 0; index < n; ++index) { num3 += FinMath.Payoff(S * Math.Exp(num1 + num2 * Random.Gaus()), X, PutCall); } return(FinMath.PV4(num3 / (double)n, r, t)); }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double F = 0.0; double x1 = u(t, s, n); double x2 = d(t, s, n); double p = FinMath.p(t, s, n, r); for (int m = 0; m <= n; ++m) { F += Binom(m, n, p) * Payoff(S * Pow(x1, m) * Pow(x2, n - m), X, PutCall); } return(PV4(F, r, t)); }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double F = 0.0; double x1 = FinMath.u(t, s, n); double x2 = FinMath.d(t, s, n); double p = FinMath.p(t, s, n, r); for (int m = 0; m <= n; ++m) { F += FinMath.Binom(m, n, p) * FinMath.Payoff(S * Math.Pow(x1, (double)m) * Math.Pow(x2, (double)(n - m)), X, PutCall); } return(FinMath.PV4(F, r, t)); }
private double Payoff(double S, double X, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(Call(S, X)); case EPutCall.Put: return(Put(S, X)); default: return(0.0); } }
public static double Theta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(-S *n(d1(S, X, t, s, r)) * s / (2.0 * Sqrt(t)) - r * X * Exp(-r * t) * N(d2(S, X, t, s, r))); case EPutCall.Put: return(-S *n(d1(S, X, t, s, r)) * s / (2.0 * Sqrt(t)) + r * X * Exp(-r * t) * N(-d2(S, X, t, s, r))); default: return(0.0); } }
public static double BS(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(S * N(d1(S, X, t, s, r)) - X * Exp(-r * t) * N(d2(S, X, t, s, r))); case EPutCall.Put: return(-S *N(-d1(S, X, t, s, r)) + X * Exp(-r * t) * N(-d2(S, X, t, s, r))); default: return(0.0); } }
public static double Delta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(FinMath.N(FinMath.d1(S, X, t, s, r))); case EPutCall.Put: return(FinMath.N(FinMath.d1(S, X, t, s, r)) - 1.0); default: return(0.0); } }
public static double Payoff(double s, double x, EPutCall putcall) { switch (putcall) { case EPutCall.Call: return(Call(s, x)); case EPutCall.Put: return(Put(s, x)); default: return(0.0); } }
public static double Payoff(double S, double X, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(FinMath.Call(S, X)); case EPutCall.Put: return(FinMath.Put(S, X)); default: return(0.0); } }
public static double Theta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(-S *FinMath.n(FinMath.d1(S, X, t, s, r)) * s / (2.0 * Math.Sqrt(t)) - r * X * Math.Exp(-r * t) * FinMath.N(FinMath.d2(S, X, t, s, r))); case EPutCall.Put: return(-S *FinMath.n(FinMath.d1(S, X, t, s, r)) * s / (2.0 * Math.Sqrt(t)) + r * X * Math.Exp(-r * t) * FinMath.N(-FinMath.d2(S, X, t, s, r))); default: return(0.0); } }
public static double Rho(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(X * t * Math.Exp(-r * t) * FinMath.N(FinMath.d2(S, X, t, s, r))); case EPutCall.Put: return(-X *t *Math.Exp(-r *t) * FinMath.N(-FinMath.d2(S, X, t, s, r))); default: return(0.0); } }
/// <summary> /// Constructor that takes all parameters used for calculatin option value using binomial tree /// </summary> /// <param name="assetPriceParam"></param> /// <param name="strikeParam"></param> /// <param name="timeStepParam"></param> /// <param name="volatilityParam"></param> /// <param name="riskFreeRateParam"></param> /// <param name="putCallParam"></param> /// <param name="optionStyleParam"></param> /// <param name="stepsParam"></param> public BinomialTree( double assetPriceParam, double strikeParam, double timeStepParam, double volatilityParam, double riskFreeRateParam, EPutCall putCallParam, int stepsParam) { assetPrice = assetPriceParam; strike = strikeParam; volatility = volatilityParam; timeStep = timeStepParam; riskFreeRate = riskFreeRateParam; putCall = putCallParam; steps = stepsParam; }
public double GetDelta(double S, double X, double q, double r, double sigma, double t, EPutCall PutCall) { double t_sqrt = Math.Sqrt(t); double sigma2 = sigma * sigma; double d1 = (Math.Log(S / X) + (r - q + sigma2 * 0.5) * t) / (t_sqrt * sigma); switch (PutCall) { case EPutCall.Call: return(Math.Exp(-q * t) * N(d1)); case EPutCall.Put: return(-Math.Exp(-q * t) * N(-d1)); default: return(0.0); } }
public double GetOptionValue(double S, double X, double q, double r, double sigma, double t, EPutCall PutCall) { double t_sqrt = Math.Sqrt(t); double sigma2 = sigma * sigma; double d1 = (Math.Log(S / X) + (r - q + sigma2 * 0.5) * t) / (t_sqrt * sigma); double d2 = d1 - t_sqrt * sigma; switch (PutCall) { case EPutCall.Call: return(S * Math.Exp(-q * t) * N(d1) - X * Math.Exp(-r * t) * N(d2)); case EPutCall.Put: return(-S *Math.Exp(-q *t) * N(-d1) + X * Math.Exp(-r * t) * N(-d2)); default: return(0.0); } }
public double GetImpliedVol(double S, double X, double q, double r, double optionPrice, double t, EPutCall PutCall, double accuracy, int maxIterations) { if (optionPrice < 0.99 * (S - X * Math.Exp(-r * t))) { return(0.0); } double t_sqrt = Math.Sqrt(t); double sigma = optionPrice / S / 0.398 / t_sqrt; for (int i = 0; i < maxIterations; i++) { double price = GetOptionValue(S, X, q, r, sigma, t, PutCall); double diff = optionPrice - price; if (Math.Abs(diff) < accuracy) { return(sigma); } double vega = GetVega(S, X, q, r, sigma, t, PutCall); sigma = sigma + diff / vega; } return(sigma); }
public static double MC(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double num1 = (r - 0.5 * s * s) * t; double num2 = s * Math.Sqrt(t); double num3 = 0.0; for (int index = 0; index < n; ++index) num3 += FinMath.Payoff(S * Math.Exp(num1 + num2 * Random.Gaus()), X, PutCall); return FinMath.PV4(num3 / (double)n, r, t); }
public static double Parity(double P, double S, double X, double t, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return P - (S - X * Math.Exp(-r * t)); case EPutCall.Put: return P + (S - X * Math.Exp(-r * t)); default: return 0.0; } }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double F = 0.0; double x1 = FinMath.u(t, s, n); double x2 = FinMath.d(t, s, n); double p = FinMath.p(t, s, n, r); for (int m = 0; m <= n; ++m) F += FinMath.Binom(m, n, p) * FinMath.Payoff(S * Math.Pow(x1, (double)m) * Math.Pow(x2, (double)(n - m)), X, PutCall); return FinMath.PV4(F, r, t); }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall) { return(BM(S, X, t, s, r, PutCall, 100)); }
public static double Payoff(double S, double X, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return FinMath.Call(S, X); case EPutCall.Put: return FinMath.Put(S, X); default: return 0.0; } }
public static double Payoff(double s, double x, EPutCall putcall) { switch (putcall) { case EPutCall.Call: return Call(s, x); case EPutCall.Put: return Put(s, x); default: return 0.0; } }
public static double Theta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return -S * n(d1(S, X, t, s, r)) * s / (2.0 * Sqrt(t)) - r * X * Exp(-r * t) * N(d2(S, X, t, s, r)); case EPutCall.Put: return -S * n(d1(S, X, t, s, r)) * s / (2.0 * Sqrt(t)) + r * X * Exp(-r * t) * N(-d2(S, X, t, s, r)); default: return 0.0; } }
public static double BS(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return S * N(d1(S, X, t, s, r)) - X * Exp(-r * t) * N(d2(S, X, t, s, r)); case EPutCall.Put: return -S * N(-d1(S, X, t, s, r)) + X * Exp(-r * t) * N(-d2(S, X, t, s, r)); default: return 0.0; } }
public static double Parity(double P, double S, double X, double t, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return(P - (S - X * Math.Exp(-r * t))); case EPutCall.Put: return(P + (S - X * Math.Exp(-r * t))); default: return(0.0); } }
public static double Theta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return -S * FinMath.n(FinMath.d1(S, X, t, s, r)) * s / (2.0 * Math.Sqrt(t)) - r * X * Math.Exp(-r * t) * FinMath.N(FinMath.d2(S, X, t, s, r)); case EPutCall.Put: return -S * FinMath.n(FinMath.d1(S, X, t, s, r)) * s / (2.0 * Math.Sqrt(t)) + r * X * Math.Exp(-r * t) * FinMath.N(-FinMath.d2(S, X, t, s, r)); default: return 0.0; } }
public static double ImpliedVolatility(double S, double X, double t, double r, double P, EOptionType OptionType, EPutCall PutCall, EOptionPrice Method, int n, double Eps) { double num1 = 0.0; double num2 = 10.0; double num3 = 0.0; double s = 0.0; while (Math.Abs(num2 - num1) > Eps) { s = num1 + (num2 - num1) / 2.0; switch (Method) { case EOptionPrice.BlackScholes: num3 = FinMath.BS(S, X, t, s, r, PutCall); break; case EOptionPrice.Binomial: num3 = FinMath.BM(S, X, t, s, r, PutCall, n); break; case EOptionPrice.MonteCarlo: num3 = FinMath.MC(S, X, t, s, r, PutCall, n); break; } if (num3 > P) num2 = s; else num1 = s; } return s; }
public static double MC(double S, double X, double t, double s, double r, EPutCall PutCall) { return FinMath.MC(S, X, t, s, r, PutCall, 100000); }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall, int n) { double F = 0.0; double x1 = u(t, s, n); double x2 = d(t, s, n); double p = FinMath.p(t, s, n, r); for (int m = 0; m <= n; ++m) F += Binom(m, n, p) * Payoff(S * Pow(x1, m) * Pow(x2, n - m), X, PutCall); return PV4(F, r, t); }
public static double Parity(double p, double s, double x, double t, double r, EPutCall putcall) { switch (putcall) { case EPutCall.Call: return(p - (s - x * Exp(-r * t))); case EPutCall.Put: return(p + (s - x * Exp(-r * t))); default: return(0.0); } }
public static double MC(double S, double X, double t, double s, double r, EPutCall PutCall) { return(FinMath.MC(S, X, t, s, r, PutCall, 100000)); }
public static double Parity(double p, double s, double x, double t, double r, EPutCall putcall) { switch (putcall) { case EPutCall.Call: return p - (s - x * Exp(-r * t)); case EPutCall.Put: return p + (s - x * Exp(-r * t)); default: return 0.0; } }
public static double Delta(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return FinMath.N(FinMath.d1(S, X, t, s, r)); case EPutCall.Put: return FinMath.N(FinMath.d1(S, X, t, s, r)) - 1.0; default: return 0.0; } }
public static double ImpliedVolatility(double S, double X, double t, double r, double P, EOptionType OptionType, EPutCall PutCall, EOptionPrice Method, int n, double Eps) { double num1 = 0.0; double num2 = 10.0; double num3 = 0.0; double s = 0.0; while (Math.Abs(num2 - num1) > Eps) { s = num1 + (num2 - num1) / 2.0; switch (Method) { case EOptionPrice.BlackScholes: num3 = FinMath.BS(S, X, t, s, r, PutCall); break; case EOptionPrice.Binomial: num3 = FinMath.BM(S, X, t, s, r, PutCall, n); break; case EOptionPrice.MonteCarlo: num3 = FinMath.MC(S, X, t, s, r, PutCall, n); break; } if (num3 > P) { num2 = s; } else { num1 = s; } } return(s); }
public static double Rho(double S, double X, double t, double s, double r, EPutCall PutCall) { switch (PutCall) { case EPutCall.Call: return X * t * Math.Exp(-r * t) * FinMath.N(FinMath.d2(S, X, t, s, r)); case EPutCall.Put: return -X * t * Math.Exp(-r * t) * FinMath.N(-FinMath.d2(S, X, t, s, r)); default: return 0.0; } }
public static double ImpliedVolatility(double S, double X, double t, double r, double P, EOptionType OptionType, EPutCall PutCall, EOptionPrice Method) { int n = 0; switch (Method) { case EOptionPrice.Binomial: n = 100; break; case EOptionPrice.MonteCarlo: n = 100000; break; } double Eps = 0.001; return(FinMath.ImpliedVolatility(S, X, t, r, P, OptionType, PutCall, Method, n, Eps)); }
public static double ImpliedVolatility(double S, double X, double t, double r, double P, EOptionType OptionType, EPutCall PutCall, EOptionPrice Method) { int n = 0; switch (Method) { case EOptionPrice.Binomial: n = 100; break; case EOptionPrice.MonteCarlo: n = 100000; break; } double Eps = 0.001; return FinMath.ImpliedVolatility(S, X, t, r, P, OptionType, PutCall, Method, n, Eps); }
public static double BM(double S, double X, double t, double s, double r, EPutCall PutCall) { return BM(S, X, t, s, r, PutCall, 100); }