public void MakeVega(Tree SpotT, Pricer PriceT, ZeroCurve myZero, DivList myDiv) { SetParam(SpotT, PriceT); Tree T1 = new Tree(), T2 = new Tree(); T1.Tau = tau; T1.Gridsteps = Gridsteps; T1.Sig = .99 * sig; T1.Spot = spot; T1.MakeGrid(myZero, myDiv); PriceT.MakeGrid(T1); double P1 = PriceT.Price(); T2.Tau = tau; T2.Gridsteps = Gridsteps; T2.Sig = 1.01 * sig; T2.Spot = spot; T2.MakeGrid(myZero, myDiv); PriceT.MakeGrid(T2); double P2 = PriceT.Price(); if (sig != 0) { Vega = 0.01 * (P2 - P1) / (2 * 0.01 * sig); } }
public void MakeTheta(Tree SpotT, Pricer PriceT, ZeroCurve myZero, DivList myDiv) { SetParam(SpotT, PriceT); Tree T1 = new Tree(), T2 = new Tree(); T1.Tau = tau; T1.Gridsteps = Gridsteps; T1.Sig = sig; T1.Spot = spot; T1.MakeGrid(myZero, myDiv); PriceT.MakeGrid(T1); double P1 = PriceT.Price(); double t = tau - 1.00 / 365.00; T2.Tau = t; T2.Gridsteps = Gridsteps; T2.Sig = sig; T2.Spot = spot; T2.MakeGrid(myZero, myDiv); PriceT.MakeGrid(T2); double P2 = PriceT.Price(); Theta = (P2 - P1); }
public void MakeDeltaGamma(Tree spotT, Pricer priceT, ZeroCurve myZero, DivList myDiv) { SetParam(spotT, priceT); Tree treeD = new Tree { GridSteps = GridSteps + 2, Spot = Spot, Sig = Sigma, Tau = Tau * (1 + 2 / GridSteps) }; treeD.MakeGrid(myZero, myDiv); priceT.MakeGrid(treeD); double[] s = new double[3]; double[] c = new double[3]; for (int i = 0; i <= 2; ++i) { s[i] = treeD.GetSpotMatrix(2, i); c[i] = priceT.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 void MakeDeltaGamma(Tree SpotT, Pricer PriceT, ZeroCurve myZero, DivList myDiv) { SetParam(SpotT, PriceT); Tree treeD = new Tree { Gridsteps = Gridsteps + 2, Spot = spot, Sig = sig, Tau = tau * (1 + 2 / Gridsteps) }; treeD.MakeGrid(myZero, myDiv); PriceT.MakeGrid(treeD); double[] S = new double[3]; double[] C = new double[3]; for (int i = 0; i <= 2; ++i) { S[i] = treeD.GetSpotMatrix(2, i); C[i] = PriceT.Get_PriceMatrix(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 void MakeVega(Tree spotT, Pricer priceT, ZeroCurve myZero, DivList myDiv) { SetParam(spotT, priceT); Tree t1 = new Tree(), t2 = new Tree(); t1.Tau = Tau; t1.GridSteps = GridSteps; t1.Sig = .99 * Sigma; t1.Spot = Spot; t1.MakeGrid(myZero, myDiv); priceT.MakeGrid(t1); double p1 = priceT.Price(); t2.Tau = Tau; t2.GridSteps = GridSteps; t2.Sig = 1.01 * Sigma; t2.Spot = Spot; t2.MakeGrid(myZero, myDiv); priceT.MakeGrid(t2); double p2 = priceT.Price(); if (Sigma != 0) { Vega = 0.01 * (p2 - p1) / (2 * 0.01 * Sigma); } }
//public MakeGrid public void MakeGrid(ZeroCurve myZero, DivList myDivList) { EmptyArrays(); MakeArrays(); MakeSpotStar(myZero, myDivList); MakeDivArray(myZero, myDivList); FillForwardRate(myZero); FillUpDown(Sig); //make the spot grid double sv = Spotstar; SetSpotMatrix(0, 0, sv + get_div(0)); //now march forward in time for (int idx = 1; idx <= Gridsteps; idx++) { for (int jdx = 0; jdx <= idx; jdx++) { sv = Spotstar * Math.Pow(get_up(idx - 1), jdx) * Math.Pow(get_dn(idx - 1), idx - jdx); sv += (idx == Gridsteps) ? 0.0 : get_div(idx); //get_div(idx); SetSpotMatrix(idx, jdx, sv); } } }
public static ZeroCurve as_zerocurve(YieldTermStructure curve) { ZeroCurve ret = new ZeroCurve(NQuantLibcPINVOKE.as_zerocurve(YieldTermStructure.getCPtr(curve)), true); if (NQuantLibcPINVOKE.SWIGPendingException.Pending) { throw NQuantLibcPINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
//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; }
public void NonFlatRates() { ZeroCurve myZero = new ZeroCurve(); myZero.Ratepoints = 2; myZero.MakeArrays(); myZero.SetR(0, 0.05, 1.0); myZero.SetR(1, 0.075, 2.0); //test interpolation priot to point 0 double tTime = 0.5; double val = myZero.LinInterp(tTime); Assert.IsTrue(val > 0.0499999999); Assert.IsTrue(val < 0.050000001); //test interpolation prior to point 1 tTime = 1.5; val = myZero.LinInterp(tTime); Assert.IsTrue(val > 0.062499999999); Assert.IsTrue(val < 0.06250000001); //test interpolation post point 1 tTime = 2.5; val = myZero.LinInterp(tTime); Assert.IsTrue(val > 0.07499999999); Assert.IsTrue(val < 0.0750000001); //test forward rates //test interpolation priot to point 0 double tl = 0.25; tTime = 0.5; val = myZero.ForwardRate(tl, tTime); Assert.IsTrue(val > 0.0499999999); Assert.IsTrue(val < 0.050000001); //test interpolation prior to point 1 tTime = 1.5; val = myZero.ForwardRate(tl, tTime); Assert.IsTrue(val > 0.06499999); /// 0.065 Assert.IsTrue(val < 0.065000001); //test interpolation post point 1 tTime = 2.5; val = myZero.ForwardRate(tl, tTime); ///0.077778 Assert.IsTrue(val > 0.0777777); Assert.IsTrue(val < 0.07777778); }
public void NonFlatRates() { ZeroCurve myZero = new ZeroCurve(); myZero.ratepoints = 2; myZero.makeArrays(); myZero.set_r(0, 0.05, 1.0); myZero.set_r(1, 0.075, 2.0); //test interpolation priot to point 0 double tTime = 0.5; double val = myZero.linInterp(tTime); Assert.Greater(val, 0.0499999999); Assert.Less(val, 0.050000001); //test interpolation prior to point 1 tTime = 1.5; val = myZero.linInterp(tTime); Assert.Greater(val, 0.062499999999); Assert.Less(val, 0.06250000001); //test interpolation post point 1 tTime = 2.5; val = myZero.linInterp(tTime); Assert.Greater(val, 0.07499999999); Assert.Less(val, 0.0750000001); //test forward rates //test interpolation priot to point 0 double tl = 0.25; tTime = 0.5; val = myZero.forwardRate(tl, tTime); Assert.Greater(val, 0.0499999999); Assert.Less(val, 0.050000001); //test interpolation prior to point 1 tTime = 1.5; val = myZero.forwardRate(tl, tTime); Assert.Greater(val, 0.06499999); /// 0.065 Assert.Less(val, 0.065000001); //test interpolation post point 1 tTime = 2.5; val = myZero.forwardRate(tl, tTime); ///0.077778 Assert.Greater(val, 0.0777777); Assert.Less(val, 0.07777778); }
//fill grid forward rates private void FillForwardRate(ZeroCurve myZero) { double dt = Tau / Gridsteps; if (myZero != null) { if (flatFlag) { flatRate = myZero.LinInterp(Tau); } for (int idx = 0; idx < Gridsteps; idx++) { SetR(idx, flatFlag ? flatRate : myZero.ForwardRate(idx * dt, (idx + 1) * dt)); } } }
private void MakeSpotStar(ZeroCurve myZero, DivList myDivList) { SpotStart = 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)); SpotStart -= d1 * t1; } } } }
public void ADivSlopingZero() { DivList mydiv = new DivList(); mydiv.Divpoints = 1; mydiv.MakeArrays(); mydiv.SetD(0, 5, 0.5); ZeroCurve myZero = new ZeroCurve(); myZero.Ratepoints = 2; myZero.MakeArrays(); myZero.SetR(0, 0.075, 0.5); myZero.SetR(1, 0.05, 2); //create the tree Tree myTree = new Tree(); myTree.Gridsteps = 100; myTree.Tau = 1.0; myTree.Sig = 0.25; myTree.Spot = 100.0; //myTree.flatFlag = false; myTree.MakeGrid(myZero, mydiv); //create pricer Pricer myPrice = new Pricer(); myPrice.Strike = 100; myPrice.Payoff = "c"; myPrice.Smoothing = "y"; myPrice.Style = "a"; myPrice.MakeGrid(myTree); double prc = myPrice.Price(); myPrice.Payoff = "p"; myPrice.MakeGrid(myTree); double prp = myPrice.Price(); Assert.IsTrue(prc > 10.37); //Orc pr = 10.38 Assert.IsTrue(prc < 10.39); Assert.IsTrue(prp > 9.42); //Orc pr = 9.43 Assert.IsTrue(prp < 9.44); }
public void EDivFlatZero() { DivList mydiv = new DivList(); mydiv.Divpoints = 1; mydiv.MakeArrays(); mydiv.SetD(0, 5, 0.5); ZeroCurve myZero = new ZeroCurve(); myZero.Ratepoints = 1; myZero.MakeArrays(); myZero.SetR(0, 0.05, 1.0); //create the tree Tree myTree = new Tree(); myTree.Gridsteps = 100; myTree.Tau = 1.0; myTree.Sig = 0.25; myTree.Spot = 100.0; //myTree.flatFlag = false; myTree.MakeGrid(myZero, mydiv); //create pricer Pricer myPrice = new Pricer(); myPrice.Strike = 100; myPrice.Payoff = "c"; myPrice.Smoothing = "y"; myPrice.Style = "e"; myPrice.MakeGrid(myTree); double prc = myPrice.Price(); myPrice.Payoff = "p"; myPrice.MakeGrid(myTree); double prp = myPrice.Price(); Assert.IsTrue(prc > 9.455); //BS pr = 9.46277 Assert.IsTrue(prc < 9.475); Assert.IsTrue(prp > 9.462); //BS pr = 9.46226 Assert.IsTrue(prp < 9.475); }
public void ANoDivFlatZero() { DivList mydiv = new DivList(); mydiv.Divpoints = 1; mydiv.MakeArrays(); mydiv.SetD(0, 0.0, 1.0); ZeroCurve myZero = new ZeroCurve(); myZero.Ratepoints = 1; myZero.MakeArrays(); myZero.SetR(0, 0.05, 1.0); //create the tree Tree myTree = new Tree(); myTree.Gridsteps = 100; myTree.Tau = 1.0; myTree.Sig = 0.25; myTree.Spot = 100.0; //myTree.flatFlag = false; myTree.MakeGrid(myZero, mydiv); //create pricer Pricer myPrice = new Pricer(); myPrice.Strike = 100; myPrice.Payoff = "c"; myPrice.Smoothing = "y"; myPrice.Style = "a"; myPrice.MakeGrid(myTree); double prc = myPrice.Price(); myPrice.Payoff = "p"; myPrice.MakeGrid(myTree); double prp = myPrice.Price(); Assert.IsTrue(prc > 12.33); //Orc pr = 12.34 Assert.IsTrue(prc < 12.35); Assert.IsTrue(prp > 7.98); //Orc pr = 7.99 Assert.IsTrue(prp < 8.00); }
public void DivFlatZero() { DivList mydiv = new DivList(); mydiv.divpoints = 1; mydiv.makeArrays(); mydiv.set_d(0, 5, 0.5); ZeroCurve myZero = new ZeroCurve(); myZero.ratepoints = 1; myZero.makeArrays(); myZero.set_r(0, 0.05, 1.0); //create the tree DiscreteTree myTree = new DiscreteTree(); myTree.Gridsteps = 100; myTree.tau = 1.0; myTree.sig = 0.25; myTree.Spot = 100.0; //myTree.flatFlag = false; myTree.MakeGrid(myZero, mydiv); //create pricer Pricer myPrice = new Pricer(); myPrice.Strike = 100; myPrice.Payoff = "c"; myPrice.Smoothing = "y"; myPrice.Style = "e"; myPrice.MakeGrid(myTree); double prc = myPrice.Price(); myPrice.Payoff = "p"; myPrice.MakeGrid(myTree); double prp = myPrice.Price(); Assert.Greater(prc, 9.455); //BS pr = 9.46277 Assert.Less(prc, 9.475); Assert.Greater(prp, 9.462); //BS pr = 9.46226 Assert.Less(prp, 9.475); }
/// <summary> /// /// </summary> /// <param name="price"></param> /// <param name="myZero"></param> /// <param name="myDiv"></param> /// <returns></returns> public double ImpVol(double price, ZeroCurve myZero, DivList myDiv) { double[] greeks = new double[4]; double temp = Pricer(myZero, myDiv, ref greeks, false); for (int idx = 0; idx < 20; idx++) { temp = Pricer(myZero, myDiv, ref greeks, false); if (Math.Abs(temp - price) < 0.0001) break; double sigold = Sig; double dsig = 0.01 * Sig; Sig += dsig; double tempUp = Pricer(myZero, myDiv, ref greeks, false); sigold -= (temp - price) * dsig / (tempUp - temp); Sig = sigold; } return Sig; }
public void MakeTheta(Tree spotT, Pricer priceT, ZeroCurve myZero, DivList myDiv) { SetParam(spotT, priceT); Tree t1 = new Tree(), t2 = new Tree(); t1.Tau = Tau; t1.GridSteps = GridSteps; t1.Sig = Sigma; t1.Spot = Spot; t1.MakeGrid(myZero, myDiv); priceT.MakeGrid(t1); double p1 = priceT.Price(); double t = Tau - 1.00 / 365.00; t2.Tau = t; t2.GridSteps = GridSteps; t2.Sig = Sigma; t2.Spot = Spot; t2.MakeGrid(myZero, myDiv); priceT.MakeGrid(t2); double p2 = priceT.Price(); Theta = (p2 - p1); }
/// <summary> /// main pricer /// </summary> /// <param name="myZero"></param> /// <param name="myDiv"></param> /// <param name="greeks"></param> /// <param name="bGreeks"></param> /// <returns></returns> public double Pricer(ZeroCurve myZero, DivList myDiv, ref double[] greeks, bool bGreeks) { _x = new List<double>(); _v = new List<double>(); double tTemp = T; //real time double tau = 0.0; //backward time double dtnom = T / (double) NTsteps; double dt = dtnom; double tempInt=0.0; //start the pricer CreateGrid(); TerminalCondition(); while( tau < T) { //set the increment double t1 = tTemp - dtnom; t1 = (t1 >= 0.0) ? t1 : 0.0; //make sure t1 >= 0.0 double divPay = 0.0; dt = CheckBetweenDiv(t1, tTemp, ref divPay, myDiv); //compute the real time and backward time tau tTemp -= dt; tau = T - tTemp; //compute the increment forward rate _domR = myZero.ForwardRate(tTemp, tTemp + dt); _forR = 0.0; //compute the forward rate from real time tTemp to expiry for the BC'c double domRbc = myZero.ForwardRate(tTemp, T); //compute discounted dividends for the bc's double DiscDiv = ComputeDiscDiv(tTemp, T, myZero, myDiv); //save the value at the spot for use in theta calcuation int nKeyInt = (int)((Math.Log(Spot) - XL) / _dx); double fracInt = (Math.Log(Spot) - _x[nKeyInt]) / (_x[nKeyInt + 1] - _x[nKeyInt]); tempInt = _v[nKeyInt] * (1.0 - fracInt) + _v[nKeyInt + 1] * fracInt; //get the fwd _lnfwd = Math.Log(GetATMfwd(myZero, myDiv, tTemp)); //build the matrix OneStepSetUp(dt, tTemp); //compute the q vec MakeQVec(); if (SStyle.ToUpper().Equals("E")) { // set the exlicit BC _v[0] = MakeLowerBC(tau, Math.Exp(_x[0]), domRbc, DiscDiv); _v[Steps - 1] = MakeUpperBC(tau, Math.Exp(_x[Steps - 1]), domRbc, DiscDiv); SORmethod(); //subract from q(1) and q(_steps-2) for explicit BC //'_q[1] -= _SubDiagL[0] * _v[0]; //'_q[_msteps - 1] -= _SuperDiagL[_steps - 1] * _v[_steps - 1]; //this commented out info is used for the zero curvature condition //_DiagL[1] += 2.0 * _SubDiagL[1]; //_SuperDiagL[1] -= _SubDiagL[1]; //_DiagL[_steps - 2] += 2.0 * _SuperDiagL[_steps - 2]; //_SubDiagL[_steps - 2] -= _SuperDiagL[_steps - 2]; //call LU decomp //LUDecomp(); //Call the LU sOlver //LUSolution(); //for zero curvature //_v[0] = 2.0 * _v[1] - _v[2]; //_v[_steps - 1] = 2.0 * _v[_steps - 2] - _v[_steps - 3]; } else { _v[0] = MakeLowerBC(tau, Math.Exp(_x[0]), domRbc, DiscDiv); _v[Steps - 1] = MakeUpperBC(tau, Math.Exp(_x[Steps - 1]), domRbc, DiscDiv); SORmethod(); } //after having incremented back, apply a grid shift if needed if (divPay != 0.0) { ApplyGridShift(tau, divPay, domRbc, DiscDiv); } } int nKey = (int) ((Math.Log(Spot) - XL) / _dx); double frac = (Math.Log(Spot) - _x[nKey])/ (_x[nKey+1] - _x[nKey]); double temp = _v[nKey] * (1.0 - frac) + _v[nKey+1] * frac; if (bGreeks) { double[,] a = new double[4, 4]; double[] b = new double[4]; a[0,0] = 1.0; a[1,0] = 1.0; a[2,0] = 1.0; a[3,0] = 1.0; a[0, 1] = Math.Exp(_x[nKey-1]); a[1, 1] = Math.Exp(_x[nKey]); a[2, 1] = Math.Exp(_x[nKey +1]); a[3, 1] = Math.Exp(_x[nKey +2]); a[0, 2] = Math.Exp(_x[nKey - 1]) * Math.Exp(_x[nKey - 1]); a[1, 2] = Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]); a[2, 2] = Math.Exp(_x[nKey + 1])*Math.Exp(_x[nKey + 1]); a[3, 2] = Math.Exp(_x[nKey + 2]) * Math.Exp(_x[nKey + 1]); a[0, 3] = Math.Exp(_x[nKey - 1])*Math.Exp(_x[nKey - 1])*Math.Exp(_x[nKey - 1]); a[1, 3] = Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]) * Math.Exp(_x[nKey]); a[2, 3] = Math.Exp(_x[nKey + 1]) * Math.Exp(_x[nKey + 1]) * Math.Exp(_x[nKey +1]); a[3, 3] = Math.Exp(_x[nKey + 2] )* Math.Exp(_x[nKey + 2] )* Math.Exp(_x[nKey + 2]); b[0] = _v[nKey-1]; b[1] = _v[nKey]; b[2] = _v[nKey+1]; b[3] = _v[nKey+2]; int info = NewtonGauss(4, ref a, ref b); greeks[0] = b[1] + 2.0 * b[2] * Spot +3.0 * b[3] * Spot * Spot; greeks[1] =2.0*b[2] +6.0* b[3] * Spot ; greeks[2] = (tempInt - temp) / (365.0 * dt); /* nKey = (int)((Math.Log(_spot) * 1.001 - _xl) / _dx); frac = (Math.Log(_spot )* 1.001 - _x[nKey]) / (_x[nKey + 1] - _x[nKey]); double tempUp = _v[nKey] * (1.0 - frac) + _v[nKey + 1] * frac; nKey = (int)((Math.Log(_spot) * 0.999 - _xl) / _dx); frac = (Math.Log(_spot) * 0.999 - _x[nKey]) / (_x[nKey + 1] - _x[nKey]); double tempDn = _v[nKey] * (1.0 - frac) + _v[nKey + 1] * frac; greeks[0] = (tempUp - tempDn) / (0.002 *Math.Log(spot))/spot ; greeks[1] = (tempUp + tempDn - 2.0 * temp) / Math.Pow(0.001 * _spot * Math.Log(_spot), 2.0) - greeks[0]/_spot; greeks[2] = (tempInt - temp) / (365.0 * dt); */ } return temp; }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ZeroCurve obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ZeroCurve obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }