public void MakeTheta() { var type = _propAssetTree.GetType(); var t1 = (ITree)Activator.CreateInstance(type); var t2 = (ITree)Activator.CreateInstance(type); t1.Tau = Expiry.Subtract(Today).Days / 365.0; t1.Gridsteps = Gridsteps; t1.Sig = Sig; t1.Spot = Spot; t1.MakeGrid(); _priceTree.MakeGrid(t1); double p1 = _priceTree.Price(); double tau = Expiry.Subtract(Today).Days / 365.0; double t = tau - 1.00 / 365.00; t2.Tau = t; t2.Gridsteps = Gridsteps; t2.Sig = Sig; t2.Spot = Spot; t2.MakeGrid(); _priceTree.MakeGrid(t2); double p2 = _priceTree.Price(); Theta = (p2 - p1); }
public void MakeDeltaGamma() { var type = _propAssetTree.GetType(); var treeD = (ITree)Activator.CreateInstance(type); double tau = Expiry.Subtract(Today).Days / 365.0; treeD.Gridsteps = Gridsteps + 2; treeD.Spot = Spot; treeD.Sig = Sig; treeD.Tau = tau * (1 + 2 / Gridsteps); treeD.MakeGrid(); _priceTree.MakeGrid(treeD); var s = new double[3]; var c = new double[3]; for (int i = 0; i <= 2; ++i) { s[i] = treeD.GetSpotMatrix(2, i); c[i] = _priceTree.GetPriceMatrix(2, i); } Delta = (s[0] * (2 * s[1] - s[0]) * (c[1] - c[2]) + (s[1] * s[1]) * (c[2] - c[0]) + s[2] * (2 * s[1] - s[2]) * (c[0] - c[1])) / (s[1] - s[0]) / (s[2] - s[0]) / (s[2] - s[1]); Gamma = 2 * (s[0] * (c[1] - c[2]) + s[1] * (c[2] - c[0]) + s[2] * (c[0] - c[1])) / (s[1] - s[0]) / (s[2] - s[0]) / (s[2] - s[1]); }
public double Price() { _propAssetTree.Spot = Spot; _propAssetTree.Sig = Sig; _propAssetTree.Tau = Expiry.Subtract(Today).Days / 365.0; _propAssetTree.Gridsteps = Gridsteps; _propAssetTree.MakeGrid(); //create PriceTree _priceTree = new PriceTree(Strike, Payoff, "Y", Style); _priceTree.MakeGrid(_propAssetTree); double pr = _priceTree.Price(); return(pr); }
public void Update(MarketDetailsResponse marketDetails) { Bid = Convert.ToDouble(marketDetails.snapshot.bid); Ask = Convert.ToDouble(marketDetails.snapshot.offer); Prime = (Bid + Ask) / 2; Spread = Ask - Bid; InterestRate = EuriborHelper.GetInterestRate(Expiry.Subtract(DateTime.Now)); CurrentPrice = Convert.ToDouble(marketDetails.snapshot.netChange); var isCall = Directions == OptionDirections.Call; var time = Expiry.Subtract(DateTime.Now).TotalDays / 365; var correctedPrime = Math.Min(Bid + Spread * (Bid / 20), Prime); Volatility = BlackScholesHelper.ImpliedVolatility(isCall, CurrentPrice, Strike, time, 0, correctedPrime); InterestRate = Math.Round(InterestRate * 100, 2); Volatility = Math.Round(Volatility * 100, 2); }
private double Bisection(double prem, double fwdPrice) { double right = 0.75; double left = 0.35; double mid; var cp = Payoff.ToLower() == "c" ? 1 : -1; int days = Expiry.Subtract(Today).Days; double t = days / 365.0; var priceClone = (AmOptionAnalytics)Clone(); if (fwdPrice <= 0 || Strike <= 0 || t <= 0 || prem <= 0) { return(0); } double df = Convert.ToDouble(RateCurve.GetDf(days)); if (prem < Math.Max(cp * df * (fwdPrice - priceClone.Strike), 0)) { throw new System.Exception("No solution for volatility"); } do { mid = (right + left) / 2; priceClone.Sig = left; double fleft = priceClone.Price() - prem; priceClone.Sig = right; double fright = priceClone.Price() - prem; priceClone.Sig = mid; double fmid = priceClone.Price() - prem; if (fleft * fmid < 0) { right = mid; } else if (fright * fmid < 0) { left = mid; } } while (Math.Abs(right - left) > 2 * Eps); return(mid); }
public OptionItem(MarketDetailsResponse marketDetails) { Epic = marketDetails.instrument.epic; Quantity = 1; Name = $"{marketDetails.instrument.name} ({marketDetails.instrument.expiry})"; var infos = marketDetails.instrument.name.Split(' '); var dir = infos[infos.Length - 1]; var strike = infos[infos.Length - 2]; Directions = dir.ToUpper() == "CALL" ? OptionDirections.Call : OptionDirections.Put; Strike = Convert.ToDouble(strike); Expiry = Convert.ToDateTime(marketDetails.instrument.expiryDetails.lastDealingDate, CultureInfo.GetCultureInfo("fr-FR")); Bid = Convert.ToDouble(marketDetails.snapshot.bid); Ask = Convert.ToDouble(marketDetails.snapshot.offer); Prime = (Bid + Ask) / 2; CurrentPrime = Prime; Spread = Ask - Bid; PrimeString = $"({Ask}/{Bid})"; InterestRate = EuriborHelper.GetInterestRate(Expiry.Subtract(DateTime.Now)); CurrentPrice = Convert.ToDouble(marketDetails.snapshot.netChange); var isCall = Directions == OptionDirections.Call; var time = Expiry.Subtract(DateTime.Now).TotalDays / 365; var correctedPrime = Math.Min(Bid + Spread * (Bid / 20), Prime); Volatility = BlackScholesHelper.ImpliedVolatility(isCall, CurrentPrice, Strike, time, 0, correctedPrime); InterestRate = Math.Round(InterestRate * 100, 2); Volatility = Math.Round(Volatility * 100, 2); }
private double Newton(double prem, double fwdPrice) { double dvol; var cp = Payoff.ToLower() == "c" ? 1 : -1; int days = Expiry.Subtract(Today).Days; double t = days / 365.0; var priceClone = (AmOptionAnalytics)Clone(); if (fwdPrice <= 0 || Strike <= 0 || t <= 0 || prem <= 0) { return(0); } //double df = Convert.ToDouble(_rateCurve.getDf(days)); if (prem < Math.Max(cp * (fwdPrice - priceClone.Strike), 0)) { throw new System.Exception("No solution for volatility"); } int idx = 0; do { var price = priceClone.Price(); priceClone.MakeVega(); var vega = priceClone.Vega; if (vega == 0 || idx > Maxits) { throw new System.Exception("No volatility solution"); } dvol = (price - prem) / (100 * vega); priceClone.Sig -= dvol; if (priceClone.Sig < 0) { priceClone.Sig = 0; } idx++; } while (Math.Abs(dvol) > Eps); return(priceClone.Sig); }
public void MakeVega() { var type = _propAssetTree.GetType(); double tau = Expiry.Subtract(Today).Days / 365.0; double sig1 = .99 * Sig; var t1 = (ITree)Activator.CreateInstance(type, tau, sig1, Spot, Gridsteps, true, Today, RateCurve, DivCurve); t1.MakeGrid(); _priceTree.MakeGrid(t1); double p1 = _priceTree.Price(); double sig2 = 1.01 * Sig; ITree t2 = t1; t2.Sig = sig2; t2.MakeGrid(); _priceTree.MakeGrid(t2); double p2 = _priceTree.Price(); if (Sig != 0) { Vega = 0.01 * (p2 - p1) / (2 * 0.01 * Sig); } }