public static double GetATMfwd(ZeroCurve myZero, DivList myDivList, double spot, double t) { double spotstar = spot; //compute the discounted dividends and take off spot if ((myDivList != null) && (myZero != null)) { for (int idx = 0; idx < myDivList.Divpoints; idx++) { if (myDivList.GetT(idx) <= t) { double d1 = myDivList.GetD(idx); double r1 = myZero.LinInterp(myDivList.GetT(idx)); double t1 = Math.Exp(-r1 * myDivList.GetT(idx)); spotstar -= d1 * t1; } } } //gross up to expiry to get atfwd if (myZero != null) { double r = myZero.LinInterp(t); return(spotstar * Math.Exp(r * t)); } return(0); }
//public spotStar private void MakeDivArray(ZeroCurve myZero, DivList myDivList) { double dt = Tau / Gridsteps; if ((myDivList != null) && (myZero != null)) { for (int idx = 0; idx < Gridsteps; idx++) { double temp = 0.0; for (int kdx = 0; kdx < myDivList.Divpoints; kdx++) { if ((myDivList.GetT(kdx) > idx * dt) && (myDivList.GetT(kdx) < Tau)) { temp += myDivList.GetD(kdx) * Math.Exp(-myZero.ForwardRate(idx * dt, myDivList.GetT(kdx)) * (myDivList.GetT(kdx) - idx * dt)); } } set_div(idx, temp, dt * idx); } } else //missing either div or zero, load in 0 for _div on tree { for (int idx = 0; idx <= Gridsteps; idx++) { set_div(idx, 0.0, dt * idx); } } }
//compute Sstar for the BC's private double ComputeDiscDiv(double tTemp, double T, ZeroCurve myZero, DivList mydiv) { double temp = 0.0; for (int idx = 0; idx < mydiv.Divpoints; idx++) { if ((tTemp < mydiv.GetT(idx)) && (mydiv.GetT(idx) < T)) { double fwdRate = myZero.ForwardRate(tTemp, mydiv.GetT(idx)); temp += mydiv.GetD(idx) * Math.Exp(-fwdRate * (mydiv.GetT(idx) - tTemp)); } } return(temp); }
//determine if dt needs adjusted because a div occurs in proposed interval private double CheckBetweenDiv(double t1, double t2, ref double discDiv, DivList myDiv) //t1 & t2 are real times { double temp = t2 - t1; for (int idx = 0; idx < myDiv.Divpoints; idx++) { if ((t1 <= myDiv.GetT(idx)) && (t2 > myDiv.GetT(idx))) { temp = t2 - myDiv.GetT(idx); discDiv = myDiv.GetD(idx); break; } } return(temp); }
//public spotStar private void MakeSpotStar(ZeroCurve myZero, DivList myDivList) { Spotstar = Spot; if ((myDivList != null) && (myZero != null)) { for (int idx = 0; idx < myDivList.Divpoints; idx++) { if (myDivList.GetT(idx) <= Tau) { double d1 = myDivList.GetD(idx); double r1 = myZero.LinInterp(myDivList.GetT(idx)); double t1 = Math.Exp(-r1 * myDivList.GetT(idx)); Spotstar -= d1 * t1; } } } }
/// <summary> /// /// </summary> /// <param name="today"></param> /// <param name="spot"></param> /// <param name="strike"></param> /// <param name="sig"></param> /// <param name="dexp"></param> /// <param name="sPay"></param> /// <param name="sStyle"></param> /// <param name="nGrid"></param> /// <param name="tStep"></param> /// <param name="iNum"></param> /// <param name="divamsAsArray"></param> /// <param name="divdatesAsArray"></param> /// <param name="zeramsAsArray"></param> /// <param name="zerdatesAsArray"></param> /// <returns></returns> public double GetEquityGreeks(DateTime today, double spot, double strike, double sig, DateTime dexp, string sPay, string sStyle, int nGrid, double tStep, int iNum, Excel.Range divamsAsArray, Excel.Range divdatesAsArray, Excel.Range zeramsAsArray, Excel.Range zerdatesAsArray ) { //Map the ranges var divams = DataRangeHelper.StripDoubleRange(divamsAsArray); var divdates = DataRangeHelper.StripDateTimeRange(divamsAsArray); var zerams = DataRangeHelper.StripDoubleRange(zeramsAsArray); var zerdates = DataRangeHelper.StripDateTimeRange(zerdatesAsArray); //set up the DivList int nd = divdates.Count; //GetUpperBound(0) + 1; var myDiv = new DivList { Divpoints = nd }; myDiv.MakeArrays(); for (int idx = 0; idx != nd; idx++) { double r = divams[idx]; DateTime dp = divdates[idx]; TimeSpan ts = dp - today; myDiv.SetD(idx, r, ts.Days / 365.0); } //set up the zero int nz = zerdates.Count;//GetUpperBound(0) + 1; var myZero = new ZeroCurve { Ratepoints = nz }; myZero.MakeArrays(); for (int idx = 0; idx != nz; idx++) { double r = zerams[idx]; DateTime dp = zerdates[idx]; TimeSpan ts = dp - today; myZero.SetR(idx, r, ts.Days / 365.0); } //compute the discounted dividends to expiry and work out continuous TimeSpan tsE = dexp - today; double texp = tsE.Days / 365.0; for (int idx = 0; idx != nd; idx++) { if (myDiv.GetT(idx) <= texp) { double d = myDiv.GetD(idx) * Math.Exp(-myDiv.GetT(idx) * myZero.LinInterp(myDiv.GetT(idx))); } } //double qc = -Math.Log((spot - sum) / spot) / texp; //double rc = myZero.linInterp(texp); var myG = new Grid { XL = Math.Log(spot) - 8.0 * sig * Math.Sqrt(texp), Xu = Math.Log(spot) + 8.0 * sig * Math.Sqrt(texp), Steps = nGrid, Strike = strike, Spot = spot, SPay = sPay, SStyle = sStyle, T = texp }; myG.NTsteps = Convert.ToInt32(myG.T / tStep); myG.Sig = sig; var greeks = new double[4]; double price = myG.Pricer(myZero, myDiv, ref greeks, true); myG.Sig += 0.01; double priceUp = myG.Pricer(myZero, myDiv, ref greeks, false); greeks[3] = priceUp - price; return(greeks[iNum]); }