/// <summary> /// Gets the price. /// </summary> /// <returns></returns> public double GetPrice() { int numresets = _resetDays.Length; int readings = _resetAmts.Count(item => (item > 0)); if (readings == numresets) { double av = _resetAmts.Average(); double df = EquityAnalytics.GetDFCCLin365(0, _tau, _rtdays, _rtamts); return((av - _strike) * df); } double newstrike = TransformStrike(numresets, readings); int nleft = numresets - readings; int[] reset_days = new int[nleft]; double[] vols = new double[nleft]; for (int idx = 0; idx < nleft; idx++) { reset_days[idx] = _resetDays[idx + readings]; vols[idx] = _vols[idx + readings]; } double newprice = GetPrice(newstrike, numresets - readings, reset_days, vols); return(newprice * (numresets - readings) / numresets); }
/// <summary> /// Gets the price. /// </summary> /// <returns></returns> public double GetPrice() { double fwd = EquityAnalytics.GetForwardCCLin365(_spot, _tau, _divdays, _divamts, _rtdays, _rtamts); double rate = EquityAnalytics.GetRateCCLin365(0, _tau, _rtdays, _rtamts); return(BSprice(fwd, _tau, _strike, rate, _vol, _isCall)); }
/// <summary> /// Gets the price. /// </summary> /// <param name="strike">The strike.</param> /// <param name="numResets">The num_resets.</param> /// <param name="resetDays"></param> /// <param name="vols">The vols.</param> /// <returns></returns> public double GetPrice(double strike, int numResets, int[] resetDays, double[] vols) { double bond = 0.0; int numVols = _vols.Length; double[] covxxi; double[] varlogs; double[] forwards = new double[numResets]; double mu = CalcMu(ref forwards, resetDays, vols); double sigma = CalcSigma(resetDays, vols); varlogs = CalcVarLogs(resetDays, vols); covxxi = CalcCovXXI(varlogs, vols.Length); if (strike <= 0) { bond = System.Math.Abs(strike); strike = cEpsilon; } double z0 = (mu - System.Math.Log(strike)) / sigma; double i1 = 0.0; for (int idx = 0; idx < numResets; idx++) { double x1 = z0 + (covxxi[idx] / sigma); double n1 = _nd.CumulativeDistribution(x1); i1 += n1 * forwards[idx] / (double)numResets; } double i2 = strike * _nd.CumulativeDistribution(z0); double prem = i1 - i2; double df = EquityAnalytics.GetDFCCLin365(0, _tau, _rtdays, _rtamts); return((prem + bond) * df); }
/// <summary> /// Gets the vega. /// </summary> /// <returns></returns> public double GetVega() { double q = EquityAnalytics.GetYieldCCLin365(_spot, 0, _tau, _divdays, _divamts, _rtdays, _rtamts); double fwd = EquityAnalytics.GetForwardCCLin365(_spot, _tau, _divdays, _divamts, _rtdays, _rtamts); double d1 = (Math.Log(fwd / _strike) + _vol * _vol * _tau / 2) / _vol / Math.Sqrt(_tau); double lhs = _spot * Math.Sqrt(_tau) * _nd.ProbabilityDensity(d1) * 0.01 * Math.Exp(-q * _tau); return(lhs); }
/// <summary> /// Gets the gamma. /// </summary> /// <returns></returns> public double GetGamma() { double q = EquityAnalytics.GetYieldCCLin365(_spot, 0, _tau, _divdays, _divamts, _rtdays, _rtamts); double fwd = EquityAnalytics.GetForwardCCLin365(_spot, _tau, _divdays, _divamts, _rtdays, _rtamts); double d1 = (Math.Log(fwd / _strike) + _vol * _vol * _tau / 2) / _vol / Math.Sqrt(_tau); var temp = _nd.ProbabilityDensity(d1); return(Math.Exp(q * _tau) * temp / _spot / _vol / Math.Sqrt(_tau)); }
/// <summary> /// Forwards the rate. /// </summary> /// <param name="yearFraction1">The t1.</param> /// <param name="yearFraction2">The t2.</param> /// <returns></returns> private double ForwardRate(double yearFraction1, double yearFraction2) { return(EquityAnalytics.GetRateCCLin365(yearFraction1, yearFraction2, _rateDays, _rateAmts)); //double rt1 = _rateInterp.ValueAt(yearFraction1, false); //double rt2 = _rateInterp.ValueAt(yearFraction2, false); //if (yearFraction2 > yearFraction1) // return (rt2 * yearFraction2 - rt1 * yearFraction1) / (yearFraction2 - yearFraction1); //else // return 0; }
/// <summary> /// Calcs the mu. /// </summary> /// <param name="resetDays"></param> /// <param name="vols">The vols.</param> /// <param name="forwards">The forwards.</param> /// <returns></returns> private double CalcMu(ref double[] forwards, int[] resetDays, double[] vols) { double musum = 0; int numresets = resetDays.Length; for (int idx = 0; idx < numresets; idx++) { double dt0 = Convert.ToDouble(resetDays[idx]) / daybasis; double r0 = EquityAnalytics.GetRateCCLin365(0, dt0, _rtdays, _rtamts); double q0 = EquityAnalytics.GetYieldCCLin365(_spot, 0, dt0, _divdays, _divamts, _rtdays, _rtamts); musum += System.Math.Log(_spot) + (r0 - q0) * dt0 - vols[idx] * vols[idx] * dt0 / 2; forwards[idx] = _spot * System.Math.Exp((r0 - q0) * dt0); } return(musum / numresets); }
/// <summary> /// Gets the delta. /// </summary> /// <returns></returns> public double GetDelta() { double q = EquityAnalytics.GetYieldCCLin365(_spot, 0, _tau, _divdays, _divamts, _rtdays, _rtamts); double fwd = EquityAnalytics.GetForwardCCLin365(_spot, _tau, _divdays, _divamts, _rtdays, _rtamts); double d1 = (Math.Log(fwd / _strike) + _vol * _vol * _tau / 2) / _vol / Math.Sqrt(_tau); double temp; if (!_isCall) { temp = BasicMath.Ndist(d1) - 1; } else { temp = BasicMath.Ndist(d1); } return(Math.Exp(-q * _tau) * temp); }
/// <summary> /// Gets the price. /// </summary> /// <returns></returns> public double GetPrice() { double fwd = EquityAnalytics.GetForwardCCLin365(_Spot, _tau, _divdays, _divamts, _ratedays, _rateamts); double r = EquityAnalytics.GetRateCCLin365(0, _tau, _ratedays, _rateamts); double q = EquityAnalytics.GetYieldCCLin365(_Spot, 0, _tau, _divdays, _divamts, _ratedays, _rateamts); double df = EquityAnalytics.GetDFCCLin365(0, _tau, _ratedays, _rateamts); double flatskewPrice = df * FlatSkewPrice(fwd, r, q); double[] res = OptionAnalytics.OptWithGreeks(true, fwd, _Strike, _vol, _tau); double callvega = res[3]; double price; if (_isCall) { price = flatskewPrice - _skew * df * callvega; } else { price = flatskewPrice + _skew * df * callvega; } return(price); }
/// <summary> /// Gets the theta. /// </summary> /// <returns></returns> public double GetTheta() { double q = EquityAnalytics.GetYieldCCLin365(_spot, 0, _tau, _divdays, _divamts, _rtdays, _rtamts); double fwd = EquityAnalytics.GetForwardCCLin365(_spot, _tau, _divdays, _divamts, _rtdays, _rtamts); double d1 = (Math.Log(fwd / _strike) + _vol * _vol * _tau / 2) / _vol / Math.Sqrt(_tau); double rate = EquityAnalytics.GetRateCCLin365(0, _tau, _rtdays, _rtamts); double d2 = d1 - _vol * Math.Sqrt(_tau); double rhs1 = -Math.Exp(-q * _tau) * _spot * _nd.ProbabilityDensity(d1) * _vol / 2 / Math.Sqrt(_tau); double rhs3 = 0; if (_isCall) { double rhs2 = -rate *_strike *Math.Exp(-rate *_tau) * _nd.CumulativeDistribution(d2); //rhs3 = q * _spot * System.Math.Exp(-q * _tau) * _nd.CumulativeDistribution(d1); return((rhs1 + rhs2 + rhs3) / 365.0); } else { double rhs2 = rate * _strike * Math.Exp(-rate * _tau) * _nd.CumulativeDistribution(-d2); //rhs3 = -q * _spot * System.Math.Exp(-q * _tau) * _nd.CumulativeDistribution(-d1); return((rhs1 + rhs2 + rhs3) / 365.0); } }
//compute Sstar for the BC's /// <summary> /// Computes the disc div. /// </summary> /// <param name="tTemp">The t temp.</param> /// <param name="T">The T.</param> /// <param name="ratedays">The ratedays.</param> /// <param name="rateamts">The rateamts.</param> /// <param name="divdays">The divdays.</param> /// <param name="divamts">The divamts.</param> /// <returns></returns> private double ComputeDiscDiv(double tTemp, double T, int[] ratedays, double[] rateamts, int[] divdays, double[] divamts) { return(EquityAnalytics.GetPVDivsCCLin365(tTemp, T, divdays, divamts, ratedays, rateamts)); }
/// <summary> /// Gets the AT MFWD. /// </summary> /// <param name="ratedays">The ratedays.</param> /// <param name="rateamts">The rateamts.</param> /// <param name="divdays">The divdays.</param> /// <param name="divamts">The divamts.</param> /// <param name="t">The t.</param> /// <returns></returns> public double GetATMfwd(int[] ratedays, double[] rateamts, int[] divdays, double[] divamts, double t) { return(EquityAnalytics.GetForwardCCLin365(_spot, t, divdays, divamts, ratedays, rateamts)); }
public double[] GetPriceAndGreeks() { double[] greeks = new double[3]; double[] res = new double[4]; _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) < -0.001 * _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, divdays, divamts); //compute the real time and backward time tau tTemp -= dt; tau = _T - tTemp; //compute the increment forward rate _domR = EquityAnalytics.GetRateCCLin365(tTemp, tTemp + dt, ratedays, rateamts); _forR = 0.0; //compute the forward rate from real time tTemp to expiry for the BC'c double domRbc = EquityAnalytics.GetRateCCLin365(tTemp, _T, ratedays, rateamts); //compute discounted dividends for the bc's double DiscDiv = ComputeDiscDiv(tTemp, _T, ratedays, rateamts, divdays, divamts); //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(ratedays, rateamts, divdays, divamts, 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; 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 + 2]); 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); */ res[0] = temp; res[1] = greeks[0]; res[2] = greeks[1]; res[3] = greeks[2]; return(res); }
/// <summary> /// PVs the divs. /// </summary> /// <param name="yearFraction1">The year fraction1.</param> /// <param name="yearFraction2">The year fraction2.</param> /// <returns></returns> private double PVDivs(double yearFraction1, double yearFraction2) { double res = EquityAnalytics.GetPVDivsCCLin365(yearFraction1, yearFraction2, _divDays, _divAmts, _rateDays, _rateAmts); return(res); }
/// <summary> /// Gets the yield. /// </summary> /// <param name="yearFraction">The year fraction.</param> /// <returns></returns> private double GetYield(double yearFraction) { return(EquityAnalytics.GetYieldCCLin365(_spot, 0, yearFraction, _divDays, _divAmts, _rateDays, _rateAmts)); }