private double FloatingPut(double S, double X, double T, double r, double b, double sigma, double Smax) { double b1 = (Math.Log(S / Smax) + (b + sigma * sigma / 2.0) * T) / sigma / Math.Sqrt(T); double b2 = b1 - sigma * Math.Sqrt(T); double put = 0.0; if (b == 0.0) { put = -S *Math.Exp(-r *T) * NormalCdf.NormalCdfHart(-b1) + Smax * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(-b2) + S * Math.Exp(-r * T) * sigma * Math.Sqrt(T) * (NormalCdf.NormalPdf(b1) + b1 * NormalCdf.NormalCdfHart(b1)); } if (b != 0.0) { put = -S *Math.Exp((b - r) *T) * NormalCdf.NormalCdfHart(-b1) + Smax * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(-b2) + S * Math.Exp(-r * T) * sigma * sigma * 0.5 / b * (-Math.Pow(S / Smax, -2.0 * b / sigma / sigma) * NormalCdf.NormalCdfHart(b1 - 2.0 * b / sigma * Math.Sqrt(T)) + Math.Exp(b * T) * NormalCdf.NormalCdfHart(b1)); } return(put); }
//Payoff: //FloatingCall: S - S_min //FloatingPut: S_max - S private double FloatingCall(double S, double X, double T, double r, double b, double sigma, double Smin) { double a1 = (Math.Log(S / Smin) + (b + sigma * sigma / 2.0) * T) / sigma / Math.Sqrt(T); double a2 = a1 - sigma * Math.Sqrt(T); double call = 0.0; if (b == 0.0) { call = S * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(a1) - Smin * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(a2) + S * Math.Exp(-r * T) * sigma * Math.Sqrt(T) * (NormalCdf.NormalPdf(a1) + a1 * (NormalCdf.NormalCdfHart(a1) - 1)); } if (b != 0.0) { call = S * Math.Exp((b - r) * T) * NormalCdf.NormalCdfHart(a1) - Smin * Math.Exp(-r * T) * NormalCdf.NormalCdfHart(a2) + S * Math.Exp(-r * T) * sigma * sigma * 0.5 / b * (Math.Pow(S / Smin, -2.0 * b / sigma / sigma) * NormalCdf.NormalCdfHart(-a1 + 2.0 * b / sigma * Math.Sqrt(T)) - Math.Exp(b * T) * NormalCdf.NormalCdfHart(-a1)); } return(call); }