private List <decimal> CalculateRateAdjustments(RateCurve initialCurve, List <RateCurve> curves, List <DateTime> fraStartDates, List <DateTime> fraEndDates, IList <decimal> differences) { Matrix partialDerivatives = CalculatePartialDerivatives(initialCurve, curves, fraStartDates, fraEndDates); Matrix partialDerivativesInverse = CalculateInverseOfPartialDerivatives(partialDerivatives); int row = partialDerivativesInverse.ColumnCount; if (row != differences.Count) { throw new System.Exception(); } var diff = new Matrix(row, 1); for (int i = 0; i < row; ++i) { diff.SetValue(Convert.ToDouble(differences[i]), i, 0); } var adjustments = partialDerivativesInverse * diff; var adj = new List <decimal>(); for (int i = 0; i < row; ++i) { adj.Add(Convert.ToDecimal(adjustments[i, 0])); } return(adj); }
public void TestVega() { DateTime date0 = DateTime.Today; DateTime exp = date0.AddDays(90); DateTime ex = date0.AddDays(20); double spot = 100; double strike = 100; double vol = 0.50; string paystyle = "C"; string exercise = "E"; DateTime[] dates = { date0, exp }; double[] rates = { 0.05, 0.05 }; RateCurve rc = new RateCurve("AUD", "Continuous", date0, dates, rates); List <Dividend> divs = new List <Dividend> { new Dividend(ex, 20) }; AmOptionAnalytics utils = new AmOptionAnalytics(date0, exp, spot, strike, vol, exercise, paystyle, rc, divs, 120); double pr = Math.Round(utils.Price(), 7); utils.MakeVega(); double vega = Math.Round(utils.Vega, 7); Assert.AreEqual(0.1223754, vega); }
public DiscountCurveSolver(ILogger logger, ICoreCache cache, string nameSpace, DateTime baseDate, NamedValueSet properties, IEnumerable <Triplet <string, decimal, int> > assets, decimal[] adjustments, string spreadAssetId, BasicAssetValuation spreadAssetValuation, int spreadDays, double spread, int spreadStartIndex, int spreadEndIndex, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { _nameSpace = nameSpace; _properties = properties; _spreadAssetId = spreadAssetId; _spreadAssetValuation = spreadAssetValuation; _baseDate = baseDate; _spread = spread; _spreadStartIndex = spreadStartIndex; _spreadEndIndex = spreadEndIndex; _adjustments = adjustments; var enumerable = assets as Triplet <string, decimal, int>[] ?? assets.ToArray(); _instruments = enumerable.Select(a => a.First).ToArray(); _rates = enumerable.Select(a => a.Second).ToArray(); _days = enumerable.Select(a => a.Third).ToArray(); _spreadDays = spreadDays; _logger = logger; _cache = cache; _fixingCalendar = fixingCalendar; _rollCalendar = rollCalendar; // Calculate the function value for zero spread decimal[] zeroAdjustments = adjustments.Select(a => 0m).ToArray(); _valueForZeroAdjustment = RateCurve.CalculateImpliedQuote(_logger, _cache, _nameSpace, _baseDate, _properties, _instruments, _rates, zeroAdjustments, _spreadAssetId, _spreadAssetValuation, _fixingCalendar, _rollCalendar); }
private void Initialize(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties, IRateCurve baseCurve, IRateCurve quoteCurve, string[] instruments, decimal[] values, FxCurve fxCurve, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { var curveId = (RateCurveIdentifier)PricingStructureIdentifier; BaseCurve = baseCurve; QuoteCurve = quoteCurve; //Holder = new PricingStructureAlgorithmsHolder(logger, cache, curveId.PricingStructureType, curveId.Algorithm); Initialize(properties, Holder); var currency = properties.GetValue <string>(CurveProp.Currency1); if (fxCurve != null && baseCurve == null) { var holder = new GenericRateCurveAlgorithmHolder(logger, cache, nameSpace); // Create discount factors, without any input points RateCurve basisAdjustedDiscountCurve = CreateBasisAdjustedDiscountCurve(fxCurve, quoteCurve, currency, curveId.BaseDate, holder); TermCurve discountCurve = ((YieldCurveValuation)basisAdjustedDiscountCurve.PricingStructureValuation).discountFactorCurve; CreateYieldCurve(); GetYieldCurveValuation().discountFactorCurve = discountCurve; SetInterpolator(discountCurve, curveId.Algorithm, PricingStructureTypeEnum.RateSpreadCurve); // Put FX curve into inputs var assetQuotes = new List <BasicAssetValuation>(); BasicAssetValuation[] fxAssetQuotes = ((FxCurveValuation)fxCurve.GetFpMLData().Second).spotRate.assetQuote; foreach (BasicAssetValuation assetQuote in fxAssetQuotes) { BasicAssetValuation clonedAssetQuote = XmlSerializerHelper.Clone(assetQuote); clonedAssetQuote.definitionRef = FxCurveName; assetQuotes.Add(clonedAssetQuote); } AddQuoteCurveInputs(assetQuotes); ((YieldCurveValuation)PricingStructureValuation).inputs = new QuotedAssetSet { assetQuote = assetQuotes.ToArray() }; } else { List <IPriceableRateAssetController> swaps = PriceableAssetFactory.CreatePriceableRateAssets(logger, cache, nameSpace, curveId.BaseDate, instruments, values, null, fixingCalendar, rollCalendar); if (fxCurve == null) { // only use the input swaps PriceableRateAssets = swaps; } else { var holder = new GenericRateCurveAlgorithmHolder(logger, cache, nameSpace); // Add synthetic input points RateCurve basisAdjustedDiscountCurve = CreateBasisAdjustedDiscountCurve(fxCurve, quoteCurve, currency, curveId.BaseDate, holder); //TODO Add some extra short end point: 1D and 1W string[] syntheticSwapPoints = { "1M", "2M", "3M", "6M", "9M" }; PriceableRateAssets = CreateSyntheticSwaps(logger, cache, nameSpace, BaseCurve, basisAdjustedDiscountCurve, currency, curveId.BaseDate, syntheticSwapPoints, fixingCalendar, rollCalendar); PriceableRateAssets.AddRange(swaps); } // bootstrap to create the discount factors PriceableRateAssets = PriceableRateAssets.OrderBy(a => a.GetRiskMaturityDate()).ToList(); Bootstrap((YieldCurveValuation)GetFpMLData().Second); } }
private static RateCurve CreateRateCurve() { DateTime[] dates = new[] { new DateTime(2009, 9, 10), new DateTime(2009, 10, 10), new DateTime(2009, 12, 10), new DateTime(2010, 3, 10), new DateTime(2010, 9, 10), new DateTime(2011, 3, 10) }; double[] rates = new[] { 0.03, 0.035, 0.04, 0.04, 0.045, 0.05 }; RateCurve rc = new RateCurve("AUD", "Semi-Annual", new DateTime(2009, 9, 9), dates, rates); return(rc); }
public decimal GetTailedFutures(int numBasket, int daysToExpiry) { DateTime[] dates = { new DateTime(2009, 9, 10), new DateTime(2009, 10, 10), new DateTime(2009, 12, 10), new DateTime(2010, 3, 10), new DateTime(2010, 9, 10), new DateTime(2011, 3, 10) }; double[] rates = { 0.03, 0.035, 0.04, 0.04, 0.045, 0.05 }; RateCurve rc = new RateCurve("AUD", "Semi-Annual", new DateTime(2009, 9, 9), dates, rates); decimal df = rc.GetDf(daysToExpiry); return(df * Convert.ToDecimal(numBasket)); }
public BillSwapPricer2SwapParRateObjectiveFunction(DateTime valuationDate, List <AmortisingResultItem> fixedCFs, List <AmortisingResultItem> floatCFs, RateCurve curve, IDayCounter dayCounter, double floatRateMargin, DateTime bulletPaymentDate, double bulletPaymentValue) { _fixedCFs = fixedCFs; _floatCFs = floatCFs; _curve = curve; _dayCounter = dayCounter; _floatRateMargin = floatRateMargin; _valuationDate = valuationDate; _bulletPaymentDate = bulletPaymentDate; _bulletPaymentValue = bulletPaymentValue; }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="rateCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<returns></returns> public static double CalculateFixedSidePV(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve rateCurve, DateTime bulletPaymentDate, double bulletPaymentValue) { // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); double fixedSidePV = GetFixedSidePV(valuationDate, payRolls, receiveRolls, dayCounter, rateCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); return(fixedSidePV); }
public static double GetFixedSideSensitivity(DateTime valuationDate, List <AmortisingResultItem> fixedCFs, List <AmortisingResultItem> floatCFs, IDayCounter dayCounter, RateCurve originalCurve, RateCurve perturbedCurve, double floatRateMargin, double fixedRate, DateTime bulletPaymentDate, double bulletPaymentValue) { // solve for the fixed rate // var objectiveFunction = new BillSwapPricer2SwapParRateObjectiveFunction(valuationDate, fixedCFs, floatCFs, originalCurve, dayCounter, floatRateMargin, bulletPaymentDate, bulletPaymentValue); double originalPV = objectiveFunction.Value(fixedRate); var objectiveFunctionWithPerturbedCurve = new BillSwapPricer2SwapParRateObjectiveFunction(valuationDate, fixedCFs, floatCFs, perturbedCurve, dayCounter, floatRateMargin, bulletPaymentDate, bulletPaymentValue); double perturbedPV = objectiveFunctionWithPerturbedCurve.Value(fixedRate); return(perturbedPV - originalPV); }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="originalReceiveCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<param name="listInstrumentIdAndQuotes"></param> ///<param name="listPerturbations"></param> ///<param name="filterByInstruments"></param> ///<returns></returns> public static double CalculateFixedSideDelta(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve originalReceiveCurve, DateTime bulletPaymentDate, double bulletPaymentValue, List <InstrumentIdAndQuoteRangeItem> listInstrumentIdAndQuotes, List <DoubleRangeItem> listPerturbations, string filterByInstruments) { if (null == listPerturbations) { listPerturbations = new List <DoubleRangeItem>(); foreach (InstrumentIdAndQuoteRangeItem item in listInstrumentIdAndQuotes) { item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); var defaultPerturbationAmount = new DoubleRangeItem { Value = GetDefaultPerturbationAmount(item.InstrumentId) }; listPerturbations.Add(defaultPerturbationAmount); } } var perturbationArray = new List <Pair <string, decimal> >(); for (int i = 0; i < listInstrumentIdAndQuotes.Count; i++) { InstrumentIdAndQuoteRangeItem item = listInstrumentIdAndQuotes[i]; item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); DoubleRangeItem perturbItem = listPerturbations[i]; if (!String.IsNullOrEmpty(filterByInstruments)) { if (item.InstrumentId.StartsWith(filterByInstruments, true, null)) { perturbationArray.Add(new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value)); } } else { perturbationArray.Add(new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value)); } } //var perturbedCurveId = originalReceiveCurve.PerturbCurve(perturbationArray); // Perturb the curve // //Curves.RateCurve perturbedReceiveCurve = RateCurveInMemoryCollection.Instance.Get(perturbedCurveId); var perturbedReceiveCurve = (RateCurve)originalReceiveCurve.PerturbCurve(perturbationArray); //ObjectCacheHelper.GetPricingStructureFromSerialisable(perturbedCurveId); // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); double sensitivity = GetFixedSideSensitivity(valuationDate, payRolls, receiveRolls, dayCounter, originalReceiveCurve, perturbedReceiveCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); return(sensitivity); }
public AmOptionAnalytics(DateTime today, DateTime expiry, double spot, double strike, double vol, string paystyle, string payoff, RateCurve rateCurve, List <Dividend> divCurve, int gridSteps) { Spot = spot; Strike = strike; Sig = vol; Today = today; Expiry = expiry; Payoff = payoff; Style = paystyle; RateCurve = rateCurve; DivCurve = divCurve; Gridsteps = gridSteps; double tau = Expiry.Subtract(Today).Days / 365.0; _propAssetTree = new PropAssetTree(tau, Sig, Spot, Gridsteps, true, Today, RateCurve, DivCurve); }
/// <summary> /// /// </summary> /// <param name="t"></param> /// <param name="vol"></param> /// <param name="spot"></param> /// <param name="steps"></param> /// <param name="flag"></param> /// <param name="today"></param> /// <param name="zeroCurve"></param> /// <param name="divs"></param> public PropAssetTree(double t, double vol, double spot, int steps, bool flag, DateTime today, RateCurve zeroCurve, IEnumerable <Dividend> divs) { Tau = t; Sig = vol; Spot = spot; Gridsteps = steps; FlatFlag = flag; _rawZero = zeroCurve; _rawDivs = PreProcessDivs(today, divs); _today = today; EmptyArrays(); MakeArrays(); MakeSpotZero(); MakeDivArray(); FillForwardRate(); }
public void TestRateCurve() { DateTime[] dates = { new DateTime(2009, 9, 10), new DateTime(2009, 10, 10), new DateTime(2009, 12, 10), new DateTime(2010, 3, 10), new DateTime(2010, 9, 10), new DateTime(2011, 3, 10) }; double[] rates = { 0.03, 0.035, 0.04, 0.04, 0.045, 0.05 }; RateCurve rc0 = new RateCurve("AUD", "Semi-Annual", new DateTime(2009, 9, 9), dates, rates); double rf0 = Convert.ToDouble(rc0.ForwardRate(0, 365)); double df0 = Convert.ToDouble(rc0.GetDf(101)); Assert.AreEqual(0.98910057, df0, 0.0001); Assert.AreEqual(Math.Pow(1 + 0.044973 / 2, 2) - 1, rf0, 0.0001); RateCurve rc1 = new RateCurve("AUD", "Continuous", new DateTime(2009, 9, 9), dates, rates); double rf1 = Convert.ToDouble(rc1.ForwardRate(0, 365)); double df1 = Convert.ToDouble(rc1.GetDf(101)); Assert.AreEqual(0.98899254, df1, 0.0001); Assert.AreEqual(Math.Exp(0.044973) - 1, rf1, 0.0001); }
public void TestHistoricalExtrapolate() { IStock stockASXParent = LoadStock("AGK"); IVolatilitySurface stockASXChild = CreateNullVolSurface(); IVolatilitySurface targetChild = CreateNullVolSurface(); IStock stockSDParent = LoadStock("AGK"); stockASXParent.Valuations.Add(new Valuation(new DateTime(2008, 8, 28), 1208)); stockASXParent.Valuations.Add(new Valuation(new DateTime(2008, 8, 29), 1221)); stockASXParent.Valuations.Add(new Valuation(new DateTime(2008, 8, 30), 1218)); stockASXParent.Valuations.Add(new Valuation(new DateTime(2008, 8, 31), 1207)); stockASXParent.Valuations.Add(new Valuation(new DateTime(2008, 9, 1), 1250)); RateCurve rateCurve = CreateRateCurve(); List <Dividend> divCurve = CreateDividends(); IStock nullASXChild = new Stock(new DateTime(2009, 9, 9), 200.0M, "ZZZ", "ZZZ", rateCurve, divCurve); nullASXChild.VolatilitySurface = stockASXChild; nullASXChild.Valuations.Add(new Valuation(new DateTime(2008, 12, 12), 208)); nullASXChild.Valuations.Add(new Valuation(new DateTime(2008, 12, 13), 221)); nullASXChild.Valuations.Add(new Valuation(new DateTime(2008, 12, 14), 218)); nullASXChild.Valuations.Add(new Valuation(new DateTime(2008, 12, 15), 207)); nullASXChild.Valuations.Add(new Valuation(new DateTime(2008, 12, 16), 201)); ExtrapolationHelper extrap = new ExtrapolationHelper(); decimal histvol1 = extrap.DoHistVolCalc(stockASXParent); decimal histvol2 = extrap.DoHistVolCalc(nullASXChild); Assert.AreEqual(0.375846, Convert.ToDouble(histvol1), 0.0001); Assert.AreEqual(0.770018, Convert.ToDouble(histvol2), 0.0001); extrap.PopulateHistoricalVols(stockASXParent, nullASXChild, targetChild); double scalFactor = Convert.ToDouble(extrap.GetHistoricalScalFactor(stockASXParent, nullASXChild)); Assert.AreEqual(scalFactor, 2.0487573, 0.0001); //Spreadsheet fit SD parent to (5d, 1.000 * F) point, flatline endpoints. decimal SDParentVol0 = 0.296175M; // Spreadsheet fit SD parent to (7d,0.867 * F) point decimal SDParentVol1 = 0.320240M; // Spreadsheet fit SD parent to (21d,1.00 * F) point decimal SDParentVol2 = 0.287656M; double childExtrapVol0 = scalFactor * Convert.ToDouble(SDParentVol0); double childExtrapVol1 = scalFactor * Convert.ToDouble(SDParentVol1); double childExtrapVol2 = scalFactor * Convert.ToDouble(SDParentVol2); Assert.AreEqual(Convert.ToDouble(SDParentVol0 * histvol2 / histvol1), childExtrapVol0, 0.001); Assert.AreEqual(Convert.ToDouble(SDParentVol1 * histvol2 / histvol1), childExtrapVol1, 0.001); Assert.AreEqual(Convert.ToDouble(SDParentVol2 * histvol2 / histvol1), childExtrapVol2, 0.001); }
///<summary> ///</summary> ///<param name="valuationDate"></param> ///<param name="floatMargin"></param> ///<param name="fixedRate"></param> ///<param name="payTerms"></param> ///<param name="payRolls"></param> ///<param name="receiveTerms"></param> ///<param name="receiveRolls"></param> ///<param name="originalCurve"></param> ///<param name="bulletPaymentDate"></param> ///<param name="bulletPaymentValue"></param> ///<param name="listInstrumentIdAndQuotes"></param> ///<param name="listPerturbations"></param> ///<returns></returns> public static List <DoubleRangeItem> CalculateFixedSideSensitivity2(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve originalCurve, DateTime bulletPaymentDate, double bulletPaymentValue, List <InstrumentIdAndQuoteRangeItem> listInstrumentIdAndQuotes, List <DoubleRangeItem> listPerturbations) { var result = new List <DoubleRangeItem>(); if (null == listPerturbations) { listPerturbations = new List <DoubleRangeItem>(); foreach (InstrumentIdAndQuoteRangeItem item in listInstrumentIdAndQuotes) { item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); var defaultPerturbationAmount = new DoubleRangeItem { Value = GetDefaultPerturbationAmount(item.InstrumentId) }; listPerturbations.Add(defaultPerturbationAmount); } } for (int i = 0; i < listInstrumentIdAndQuotes.Count; i++) { InstrumentIdAndQuoteRangeItem item = listInstrumentIdAndQuotes[i]; item.InstrumentId = RemoveExtraInformationFromInstrumentId(item.InstrumentId); DoubleRangeItem perturbItem = listPerturbations[i]; // pay == fixed. // IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); var perturbationArray = new List <Pair <string, decimal> > { new Pair <string, decimal>(item.InstrumentId, (decimal)perturbItem.Value) }; //var perturbedCurveId = ObjectCacheHelper.PerturbRateCurve(curveId, perturbationArray); // Perturb the curve // var perturbedReceiveCurve = (RateCurve)originalCurve.PerturbCurve(perturbationArray); double sensitivity = GetFixedSideSensitivity(valuationDate, payRolls, receiveRolls, dayCounter, originalCurve, perturbedReceiveCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); var bucketSensitivityItem = new DoubleRangeItem { Value = sensitivity }; result.Add(bucketSensitivityItem); } return(result); }
/// <summary> /// Calculate the fra value from the given curve /// </summary> /// <param name="rateCurve">rate curve</param> /// <param name="fraStartDates">List of fra start dates</param> /// <param name="fraEndDates">List of fra end dates</param> /// <returns></returns> public List <decimal> CalculateFraValuesFromCurve(RateCurve rateCurve, List <DateTime> fraStartDates, List <DateTime> fraEndDates) { var calculatedFraRates = new List <decimal>(); int len = fraStartDates.Count; for (int i = 0; i < len; ++i) { decimal df1 = Convert.ToDecimal(rateCurve.GetDiscountFactor(fraStartDates[i])); decimal df2 = Convert.ToDecimal(rateCurve.GetDiscountFactor(fraEndDates[i])); double period = DayCounter.YearFraction(fraStartDates[i], fraEndDates[i]); decimal fraRate = CalculateForwardRate(df1, df2, (decimal)period); calculatedFraRates.Add(fraRate); } return(calculatedFraRates); }
public static Stock CreateStock(EquityVolCalcTestData.Stock stock) { DateTime today = XmlGetDate(stock.Date); decimal spot = Convert.ToDecimal(stock.Spot); DateTime baseDate = XmlGetDate(stock.RateCurve.BaseDate); DateTime[] rateDates = XmlGetDateArray(stock.RateCurve.DateArray); //Load rate curve String tp = stock.RateCurve.RateType; var rc = new RateCurve(stock.RateCurve.Ccy, tp, baseDate, rateDates, stock.RateCurve.RateArray); // Load dividends var divs = (from div in stock.Dividends let exDate = XmlGetDate(div.ExDate) select new Dividend(exDate, Convert.ToDecimal(div.Amount))).ToList(); //Load stock object var stock0 = new Stock(today, spot, stock.AssetId, stock.Name, rc, divs); var vol0 = new VolatilitySurface(stock.AssetId, spot, today); //Load vols stock0.VolatilitySurface = vol0; foreach (StockVolatilitySurfaceForwardExpiry exp in stock.VolatilitySurface.Expiries) { DateTime expDate = XmlGetDate(exp.ExpiryDate); Decimal fwd = Convert.ToDecimal(exp.FwdPrice); var exp0 = new ForwardExpiry(expDate, fwd); // exp0.NodalPoint = System.Convert.ToBoolean(exp.NodalPoint); vol0.AddExpiry(exp0); foreach (StockVolatilitySurfaceForwardExpiryStrike str in exp.Strikes) { var call = new OptionPosition(); var put = new OptionPosition(); double strikeprice0 = Convert.ToDouble(str.StrikePrice); var str0 = new Strike(strikeprice0, call, put, Units.Cents) { Moneyness = Convert.ToDouble(str.Moneyness) }; exp0.AddStrike(str0, true); var vp = new VolatilityPoint(); decimal vol = Convert.ToDecimal(str.Volatility.Value); vp.SetVolatility(vol, VolatilityState.Default()); str0.SetVolatility(vp); } } return(stock0); }
private void SetFraDates(ICoreCache cache, string nameSpace, RateCurve initialCurve, IEnumerable <int> instrumentIndicies) { FraStartDates = new List <DateTime>(); FraEndDates = new List <DateTime>(); foreach (int i in instrumentIndicies) { CheckDepositInstrument(i); var rateAssetController = (PriceableDeposit)initialCurve.PriceableRateAssets[i]; DateTime startDate = CalculateFraStartTime(rateAssetController); FraStartDates.Add(startDate); var deposit = rateAssetController; //BusinessDayConventionEnum adjustment = deposit.BusinessDayAdjustments.businessDayConvention; BusinessCenters bs = deposit.SpotDateOffset.businessCenters; var calendar = BusinessCenterHelper.ToBusinessCalendar(cache, bs, nameSpace); DateTime endDate = CalculateFraEndTime(calendar, rateAssetController); FraEndDates.Add(endDate); } }
private static List <RateCurve> SetShockedCurves(ILogger logger, ICoreCache cache, string nameSpace, IList <NamedValueSet> properties, List <string> instruments, List <decimal> rates, IList <int> indexOfShockedInstruments) { if (properties.Count != indexOfShockedInstruments.Count) { throw new ArgumentException( "The number of properties and index of shocked instruments are not the same."); } var shockedCurves = new List <RateCurve>(); int len = indexOfShockedInstruments.Count; for (int i = 0; i < len; ++i) { RateCurve shockedCurve = CreateShockedCurve(logger, cache, nameSpace, properties[i], instruments.ToArray(), rates.ToArray(), indexOfShockedInstruments[i]); shockedCurves.Add(shockedCurve); } return(shockedCurves); }
public double LongEndTargetFunction(double zeroRateSpread) { DateTime baseDate = _baseCurve.GetBaseDate(); DateTime maturityDate = _asset.GetRiskMaturityDate(); _zeroRateSpreads[maturityDate] = zeroRateSpread; decimal dfMaturityBasisAdjustCurve = (decimal)RateBootstrapperNewtonRaphson.GetAdjustedDiscountFactor(baseDate, maturityDate, _dayCounter, zeroRateSpread, _baseCurve); UpdateDiscountFactors(baseDate); if (_items.ContainsKey(maturityDate)) { _items[maturityDate].Second = dfMaturityBasisAdjustCurve; } else { Pair <string, decimal> pair = new Pair <string, decimal>("", dfMaturityBasisAdjustCurve); _items.Add(maturityDate, pair); } List <DateTime> dates = _items.Keys.ToList(); List <decimal> rates = _items.Values.Select(a => a.Second).ToList(); RateCurve discountCurve = new RateCurve(_properties, _algorithm, dates, rates); double sum = 0; for (int i = 0; i < _assetDates.Count - 1; i++) { DateTime date0 = _assetDates[i]; DateTime date1 = _assetDates[i + 1]; double d0 = _baseCurve.GetDiscountFactor(date0); double d1 = _baseCurve.GetDiscountFactor(date1); double y = _dayCounter.YearFraction(date0, date1); double projectedRate = 1 / y * (d0 / d1 - 1); double basisAdjustedDf = discountCurve.GetDiscountFactor(date1); double subSum = basisAdjustedDf * y * (projectedRate + (double)_asset.MarketQuote.value); sum += subSum; } double discountFactor = discountCurve.GetDiscountFactor(_assetDates.First()); double result = -discountFactor + (double)dfMaturityBasisAdjustCurve + sum; return(result); }
public void TestImpliedVol4() { DateTime today = new DateTime(2010, 07, 14); RateCurve rc = new RateCurve("AUD", "Continuous", DateTime.Parse("14-Jul-2010"), new[] { DateTime.Parse("14-Jul-2010"), DateTime.Parse("28-Jun-2012") }, new[] { 0.045507, 0.050645 }); Dividend d1 = new Dividend(DateTime.Parse("6-9-2010"), 49.90M); Dividend d2 = new Dividend(DateTime.Parse("28-2-2011"), 54.43M); Dividend d3 = new Dividend(DateTime.Parse("5-9-2011"), 58.97M); Dividend d4 = new Dividend(DateTime.Parse("27-2-2012"), 61.24M); Dividend d5 = new Dividend(DateTime.Parse("3-9-2012"), 65.78M); Dividend d6 = new Dividend(DateTime.Parse("25-2-2013"), 68.05M); Dividend d7 = new Dividend(DateTime.Parse("2-9-2013"), 72.58M); Dividend d8 = new Dividend(DateTime.Parse("2-9-2013"), 72.58M); Dividend d9 = new Dividend(DateTime.Parse("24-2-2014"), 73.72M); Dividend d10 = new Dividend(DateTime.Parse("1-9-2014"), 75.99M); List <Dividend> divCurve = new List <Dividend>() { d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 }; var stockObject0 = new Stock(today, 3840, "BHP12JUN4100P.WY", "BHP_Vanilla_ETO_Jun12_41.00_Put", rc, divCurve); double vol = OptionHelper.GetImpliedVol(stockObject0, DateTime.Parse("28-Jun-2012"), 4100, false, "American", 719, 120); }
/// <summary> /// Calculate the matrix of partial derivatives from the /// List of shocked curves /// </summary> /// <param name="shockedCurves"></param> /// <param name="fraStartDates">List of fra start dates</param> /// <param name="fraEndDates">List of fra end dates</param> /// <param name="initialCurve"></param> /// <returns></returns> public Matrix CalculatePartialDerivatives(RateCurve initialCurve, List <RateCurve> shockedCurves, List <DateTime> fraStartDates, List <DateTime> fraEndDates) { int len = fraStartDates.Count; var partialDerivative = new Matrix(len, len); List <decimal> initialFraRates = CalculateFraValuesFromCurve(initialCurve, fraStartDates, fraEndDates); for (int i = 0; i < shockedCurves.Count; ++i) { List <decimal> fraRates = CalculateFraValuesFromCurve(shockedCurves[i], fraStartDates, fraEndDates); for (int j = 0; j < len; ++j) { partialDerivative.SetValue(Convert.ToDouble(fraRates[j] - initialFraRates[j]) * 10000, j, i); } } return(partialDerivative); }
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); }
/// <summary> /// Creates synthetic swaps from FX curve for period under 1 year /// </summary> /// <param name="cache">The cache.</param> /// <param name="logger">The logger.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="baseCurve"></param> /// <param name="basisAdjustedDiscountCurve"></param> /// <param name="currency"></param> /// <param name="baseDate"></param> /// <param name="swapsRequired">Array of the names of the swaps required</param> /// <returns></returns> public static List <IPriceableRateAssetController> CreateSyntheticSwaps(ILogger logger, ICoreCache cache, string nameSpace, IRateCurve baseCurve, RateCurve basisAdjustedDiscountCurve, string currency, DateTime baseDate, string[] swapsRequired, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { var dummyRates = new decimal[5]; string[] swapIds = swapsRequired.Select(a => currency + "-XccySwap-" + a).ToArray(); List <IPriceableRateAssetController> priceableRateAssets = PriceableAssetFactory.CreatePriceableRateAssets(logger, cache, nameSpace, baseDate, swapIds, dummyRates, null, fixingCalendar, rollCalendar); foreach (var priceableRateAssetController in priceableRateAssets) { var swap = (PriceableSimpleIRSwap)priceableRateAssetController; DateTime date0 = swap.AdjustedStartDate; DateTime date1 = swap.GetRiskMaturityDate(); IDayCounter dayCounter = DayCounterHelper.Parse(swap.DayCountFraction.Value); double adjustedDiscountFactorStart = basisAdjustedDiscountCurve.GetDiscountFactor(date0); double adjustedDiscountFactorEnd = basisAdjustedDiscountCurve.GetDiscountFactor(date1); double term3 = 0; double term4 = 0; for (int i = 0; i < swap.AdjustedPeriodDates.Count - 1; i++) { DateTime startDate = swap.AdjustedPeriodDates[i]; DateTime endDate = swap.AdjustedPeriodDates[i + 1]; if (startDate == endDate) { throw new InvalidOperationException("StartDate and EndDate cannot be the same"); } double adjustedDiscountFactor = basisAdjustedDiscountCurve.GetDiscountFactor(endDate); double baseDiscountFactorStart = baseCurve.GetDiscountFactor(startDate); double baseDiscountFactorEnd = baseCurve.GetDiscountFactor(endDate); double yearFraction = dayCounter.YearFraction(startDate, endDate); double baseForwardRate = (1 / yearFraction) * (baseDiscountFactorStart / baseDiscountFactorEnd - 1); term3 += yearFraction * adjustedDiscountFactor * baseForwardRate; term4 += yearFraction * adjustedDiscountFactor; } swap.MarketQuote.value = (decimal)((adjustedDiscountFactorStart - adjustedDiscountFactorEnd - term3) / term4); swap.BasicAssetValuation.quote[0].value = swap.MarketQuote.value; } return(priceableRateAssets); }
public static double CalculateFixedSideSensitivity(DateTime valuationDate, double floatMargin, double fixedRate, BillsSwapPricer2TermsRange payTerms, List <AmortisingResultItem> payRolls, BillsSwapPricer2TermsRange receiveTerms, List <AmortisingResultItem> receiveRolls, RateCurve rateCurve, DateTime bulletPaymentDate, double bulletPaymentValue, string curveInstrumentId, double perturbationAmount) { // pay == fixed. var perturbationArray = new List <Pair <string, decimal> > { new Pair <string, decimal>(curveInstrumentId, (decimal)perturbationAmount) }; IDayCounter dayCounter = DayCounterHelper.Parse(payTerms.DayCountConvention); //var originalCurve = (RateCurve)cache.LoadObject(curveId); var perturbedCurve = rateCurve.PerturbCurve(perturbationArray) as RateCurve; // Perturb the curve // //var perturbedReceiveCurve = (RateCurve)ObjectCacheHelper.GetPricingStructureFromSerialisable(perturbedCurveId); double sensitivity = GetFixedSideSensitivity(valuationDate, payRolls, receiveRolls, dayCounter, rateCurve, perturbedCurve, floatMargin, fixedRate, bulletPaymentDate, bulletPaymentValue); return(sensitivity); }
public double Value(double trialAdjustment) { // Set the adjustments // Adjust the rates with the answer if (_spreadStartIndex == 0) { for (int i = 0; i <= _spreadEndIndex; i++) { _adjustments[i] = (decimal)trialAdjustment; } } else { int startDays = _days[_spreadStartIndex - 1]; // if there is only one point then don't interpolate if (_spreadDays == startDays) { _adjustments[_spreadStartIndex] = (decimal)trialAdjustment; } else { var x = new double[] { startDays, _spreadDays }; var y = new[] { (double)_adjustments[_spreadStartIndex - 1], trialAdjustment }; var interpolation = new LinearInterpolation(); interpolation.Initialize(x, y); for (int i = _spreadStartIndex; i <= _spreadEndIndex; i++) { int days = _days[i]; _adjustments[i] = (decimal)interpolation.ValueAt(days, false); } } } double valueForAdjustment = RateCurve.CalculateImpliedQuote(_logger, _cache, _nameSpace, _baseDate, _properties, _instruments, _rates, _adjustments, _spreadAssetId, _spreadAssetValuation, _fixingCalendar, _rollCalendar); return(valueForAdjustment - _valueForZeroAdjustment - _spread); }
public void TestITMPrice() { DateTime date0 = DateTime.Today; DateTime exp = date0.AddDays(90); DateTime ex = date0.AddDays(20); double spot = 100; double strike = 50; double vol = 0.50; string paystyle = "C"; string exercise = "A"; DateTime[] dates = { date0, exp }; double[] rates = { 0.05, 0.05 }; RateCurve rc = new RateCurve("AUD", "Continuous", date0, dates, rates); List <Dividend> divs = new List <Dividend> { new Dividend(ex, 20) }; AmOptionAnalytics utils = new AmOptionAnalytics(date0, exp, spot, strike, vol, exercise, paystyle, rc, divs, 120); double pr = Math.Round(utils.Price(), 7); Debug.Print("Price is {0}", pr); Assert.AreEqual(50.1333834, pr); }
public void TestImpliedVolPut() { DateTime date0 = DateTime.Today; DateTime exp = date0.AddDays(90); DateTime ex = date0.AddDays(20); double spot = 100; double strike = 100; double vol = 0.50; string paystyle = "P"; DateTime[] dates = { date0, exp }; double[] rates = { 0.05, 0.05 }; RateCurve rc = new RateCurve("AUD", "Continuous", date0, dates, rates); List <Dividend> divs = new List <Dividend> { new Dividend(ex, 20) }; AmOptionAnalytics amInstr = new AmOptionAnalytics(date0, exp, spot, strike, vol, "A", paystyle, rc, divs, 120); AmOptionAnalytics euInstr = new AmOptionAnalytics(date0, exp, spot, strike, 2 * vol, "E", paystyle, rc, divs, 120); double am = amInstr.Price(); double eu = euInstr.Price(); AmOptionAnalytics amInstr0 = new AmOptionAnalytics(date0, exp, spot, strike, 0.20, "A", paystyle, rc, divs, 120); AmOptionAnalytics euInstr0 = new AmOptionAnalytics(date0, exp, spot, strike, 0.80, "E", paystyle, rc, divs, 120); double avol0 = amInstr0.OptSolveVol(am, 100); double evol0 = euInstr0.OptSolveVol(eu, 100); Stock stock = new Stock(date0, 100, "dummy", "BHP", rc, divs); double vol1 = OptionHelper.GetImpliedVol(stock, exp, strike, false, "A", am, 120); double vol11 = OptionHelper.GetImpliedVol(stock, exp, strike, false, "American", am, 120); double vol0 = OptionHelper.GetImpliedVol(stock, exp, strike, false, "E", eu, 120); double vol00 = OptionHelper.GetImpliedVol(stock, exp, strike, false, "European", eu, 120); Assert.AreEqual(avol0, 0.50, 0.001); Assert.AreEqual(evol0, 1.00, 0.001); Assert.AreEqual(vol1, avol0, 0.001); Assert.AreEqual(vol11, avol0, 0.001); Assert.AreEqual(vol0, evol0, 0.001); Assert.AreEqual(vol00, evol0, 0.001); }
internal static TermCurve ConstructDiscountFactors(ILogger logger, ICoreCache cache, string nameSpace, TermCurve inputCurve, DateTime baseDate, string currency) { List <DateTime> dates = inputCurve.point.Select(a => (DateTime)a.term.Items[0]).ToList(); List <decimal> values = inputCurve.point.Select(a => a.mid).ToList(); var properties = new NamedValueSet(); properties.Set(CurveProp.PricingStructureType, PricingStructureTypeEnum.RateCurve.ToString()); properties.Set(CurveProp.Market, "ConstructDiscountFactors"); properties.Set(CurveProp.IndexTenor, "0M"); properties.Set(CurveProp.Currency1, currency); properties.Set(CurveProp.IndexName, "XXX-XXX"); properties.Set(CurveProp.Algorithm, "FastLinearZero"); properties.Set(CurveProp.BaseDate, baseDate); var curveId = new RateCurveIdentifier(properties); var algorithmHolder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, curveId.PricingStructureType, curveId.Algorithm); var curve = new RateCurve(properties, algorithmHolder, dates, values); var termPoints = new List <TermPoint>(); for (DateTime date = dates.First(); date <= dates.Last(); date = date.AddMonths(1)) { var discountFactor = (decimal)curve.GetDiscountFactor(date); var timeDimension = new TimeDimension(); XsdClassesFieldResolver.TimeDimensionSetDate(timeDimension, date); var termPoint = new TermPoint { mid = discountFactor, midSpecified = true, term = timeDimension }; termPoints.Add(termPoint); } var termCurve = new TermCurve { point = termPoints.ToArray() }; return(termCurve); }
/// <summary> /// Initializes a new instance of the <see cref="RateXccySpreadCurve"/> class, /// by applying spreads to an existing RateCurve. Using FX Curve to create synthetic swaps /// for the period under 1Y. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="properties">The properties of the new curve. One of the mandatory properties for this curve type: /// CutOverTerm, is the tenor at which point all Fx Curve points are removed form the RateXccyCurve bootstrap. /// Normally this is 1Y.</param> /// <param name="currency1Curve">The base zero curve.</param> /// <param name="fxCurve">The FX curve, used for constructing synthetic deposits. The fx points map from the base curve to the non-base curve.</param> /// <param name="currency2Curve">The non-Base Curve.</param> /// <param name="spreadInstruments">The spread instruments and their values.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> public RateXccySpreadCurve(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, RateCurve currency1Curve, IFxCurve fxCurve, RateCurve currency2Curve, QuotedAssetSet spreadInstruments, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) : base(logger, cache, nameSpace, new RateCurveIdentifier(properties)) { //Set the base curve. BaseCurve = currency1Curve; ReferenceCurveId = BaseCurve.GetPricingStructureId(); //PricingStructureIdentifier = new RateCurveIdentifier(properties); Currency2Curve = currency2Curve; //Get the cut-over date. var cutOverTerm = properties.GetValue <string>("CutOverTerm"); if (cutOverTerm != null) { CutOverTerm = PeriodHelper.Parse(cutOverTerm); } //set the fx curve. ReferenceFxCurve = fxCurve; IsCurrency1RateCurve = properties.GetValue <bool>("Currency1RateCurve"); //Check the pricing structure type. var pricingStructureId = (RateCurveIdentifier)PricingStructureIdentifier; if (pricingStructureId.PricingStructureType != PricingStructureTypeEnum.RateXccyCurve || ReferenceFxCurve == null) { return; } //There must be a valid quoted asset set in order to bootstrap. if (!XsdClassesFieldResolver.QuotedAssetSetIsValid(spreadInstruments)) { return; } PriceableRateSpreadAssets = PriceableAssetFactory.CreatePriceableRateSpreadAssets(logger, cache, nameSpace, pricingStructureId.BaseDate, spreadInstruments, fixingCalendar, rollCalendar); Build(logger, cache, nameSpace, fixingCalendar, rollCalendar); }