using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.RootFinding;
namespace OptionModels
{
// https://en.wikipedia.org/wiki/Greeks_(finance)
using GS.Options;
public partial class BlackModel
{
public static double D1(double F, double K, double T, double sigma)
{
return (Math.Log(F / K) + 0.5 * sigma * sigma * T) / (sigma * Math.Sqrt(T));
}
public static double D2(double F, double K, double T, double sigma)
{
return (Math.Log(F / K) - 0.5 * sigma * sigma * T) / (sigma * Math.Sqrt(T));
}
public static double D2(double T, double sigma, double d1)
{
return d1 - sigma * Math.Sqrt(T);
}
public static double PremiumCall(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var nd1 = Normal.CDF(0, 1.0, d1);
var nd2 = Normal.CDF(0, 1.0, d2);
var price = Math.Exp(-r * T) * (F * nd1 - K * nd2);
if (price < 0d) price = 0d;
return price;
}
public static double PremiumPut(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var nminusd1 = Normal.CDF(0, 1.0, -d1);
var nminusd2 = Normal.CDF(0, 1.0, -d2);
var price = Math.Exp(-r * T) * (K * nminusd2 - F * nminusd1);
if (price < 0d) price = 0d;
return price;
}
public static double DeltaCall(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var value = Math.Exp(-r * T) * Normal.CDF(0, 1, d1);
return value;
}
public static double DeltaPut(double F, double K, double T, double sigma, double r)
{
double d1 = D1(F, K, T, sigma);
var value = - Math.Exp(-r * T) * Normal.CDF(0, 1, -d1);
return value;
}
public static double DeltaCall(double deltaPut)
{
return 1.0 + deltaPut;
}
public static double DeltaPut(double deltaCall)
{
return deltaCall - 1.0;
}
public static double Vega(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var vega = F * Math.Exp(-r * T) * Normal.PDF(0, 1, d1) * Math.Sqrt(T);
return vega / 100.0;
}
public static double VegaTest(double F, double K, double T, double sigma, double r)
{
var d2 = D2(F, K, T, sigma);
var vega = K * Math.Exp(-r * T) * Normal.PDF(0, 1, d2) * Math.Sqrt(T);
return vega / 100.0;
}
public static double ThetaCall(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var expMinusRT = Math.Exp(-r * T);
var theta = -(F * expMinusRT * Normal.PDF(0, 1, d1) * sigma) / (2.0 * Math.Sqrt(T))
- r * K * expMinusRT * Normal.CDF(0, 1, d2)
+ r * F * expMinusRT * Normal.CDF(0, 1, d1);
return theta / 365.0;
}
public static double ThetaPut(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var expMinusRT = Math.Exp(-r * T);
var theta = -(F * expMinusRT * Normal.PDF(0, 1, d1) * sigma) / (2.0 * Math.Sqrt(T))
+ r * K * expMinusRT * Normal.CDF(0, 1, -d2)
- r * F * expMinusRT * Normal.CDF(0, 1, -d1);
return theta / 365.0;
}
// BlackScholes Model
public static double RhoCall(double F, double K, double T, double sigma, double r)
{
var d2 = D2(F,K,T,sigma);
var rho = K * T * Math.Exp(-r * T) * Normal.CDF(0.0, 1.0, d2);
return rho / 100.0;
}
public static double RhoPut(double F, double K, double T, double sigma, double r)
{
var d2 = D2(F, K, T, sigma);
var rho = - K * T * Math.Exp(-r * T) * Normal.CDF(0.0, 1.0, -d2);
return rho / 100.0;
}
// Black Model
public static double RhoCall1(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var rho = -T * Math.Exp(-r * T) *
(F * Normal.CDF(0.0, 1.0, d1) - K * Normal.CDF(0.0, 1.0, d2));
return rho;
}
public static double RhoPut1(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
var rho = -T * Math.Exp(-r * T) *
(-F * Normal.CDF(0.0, 1.0, -d1) + K * Normal.CDF(0.0, 1.0, -d2));
return rho;
}
public static double Gamma(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var g = Math.Exp(-r * T) * (Normal.PDF(0.0, 1.0, d1) / (F * sigma * Math.Sqrt(T)));
return g; // * 100.0;
}
public static double GammaTest(double F, double K, double T, double sigma, double r)
{
var d2 = D2(F, K, T, sigma);
var g = K * Math.Exp(-r * T) * (Normal.PDF(0.0,1.0,d2) / (F * F * sigma * Math.Sqrt(T)));
return g; // * 100.0;
}
public static double TestFK(double F, double K, double T, double sigma, double r)
{
var d1 = D1(F, K, T, sigma);
var d2 = D2(T, sigma, d1);
return F * Normal.PDF(0.0, 1.0, d1) - K * Normal.PDF(0.0, 1.0, d2);
}
}
}