public ADouble DepositNpvAD(Deposit deposit) { ADouble discFactor = ADDiscCurve.DiscFactor(deposit.AsOf, deposit.EndDate, deposit.DayCount, Interpolation); ADouble cvg = DateHandling.Cvg(deposit.StartDate, deposit.EndDate, deposit.DayCount); return(deposit.TradeSign * discFactor * deposit.Notional * (1.0 + deposit.FixedRate * cvg)); }
public ADouble ParDepositRateAD(Deposit deposit) { ADouble discFactor = ADDiscCurve.DiscFactor(deposit.StartDate, deposit.EndDate, deposit.DayCount, Interpolation); ADouble cvg = DateHandling.Cvg(deposit.StartDate, deposit.EndDate, deposit.DayCount); return(1.0 / cvg * (1.0 / discFactor - 1.0)); }
public double OisCompoundedRateAD(DateTime asOf, DateTime startDate, DateTime endDate, DayRule dayRule, DayCount dayCount, InterpMethod interpolation) { double CompoundedRate = 1; double CompoundedRate2 = 1; DateTime RollDate = startDate; while (RollDate.Date < endDate.Date) { DateTime NextBusinessDay = DateHandling.AddTenorAdjust(RollDate, "1B", DayRule.F); double Rate = ZeroRate(NextBusinessDay, interpolation); double fwdOisRate = FwdRate(asOf, RollDate, NextBusinessDay, DayRule.F, dayCount, interpolation); double disc1 = DiscFactor(asOf, RollDate, dayCount, interpolation); double disc2 = DiscFactor(asOf, NextBusinessDay, dayCount, interpolation); double Days = NextBusinessDay.Subtract(RollDate).TotalDays; double shortCvg = DateHandling.Cvg(RollDate, NextBusinessDay, dayCount); RollDate = NextBusinessDay; CompoundedRate *= (1 + fwdOisRate * shortCvg); CompoundedRate2 *= disc1 / disc2; } double coverage = DateHandling.Cvg(startDate, endDate, dayCount); return((CompoundedRate2 - 1) / coverage); }
public Schedule(DateTime asOf, string startTenor, string endTenor, DayCount dayCount, DayRule dayRule) { DateTime startDate = DateHandling.AddTenor(asOf, startTenor, dayRule); DateTime endDate = DateHandling.AddTenor(startDate, endTenor, dayRule); SetValues(asOf, startDate, endDate, dayCount, dayRule); }
public Fra(DateTime asOf, string startTenor, string endTenor, CurveTenor referenceIndex, DayCount dayCount, DayRule dayRule, double fixedRate, double notional, int tradeSign) { DateTime startDate = DateHandling.AddTenorAdjust(asOf, startTenor, dayRule); DateTime endDate = DateHandling.AddTenorAdjust(startDate, endTenor, dayRule); Initialize(asOf, startDate, endDate, referenceIndex, dayCount, dayRule, fixedRate, notional, tradeSign); }
public void AddRiskCalculation(CurveTenor curveTenor, DateTime curvePoint, double number) { string tenor = DateHandling.ConvertDateToTenorString(curvePoint, _asOf); string riskIdentifier = curveTenor.ToString() + "-" + curvePoint.ToString("dd/MM/yyyy"); RiskLookUp[riskIdentifier] = number; IdentifierToPoint[curvePoint] = riskIdentifier; }
public ADouble FwdRate(DateTime asOf, DateTime startDate, DateTime endDate, DayRule dayRule, DayCount dayCount, InterpMethod interpolation) { ADouble ps = DiscFactor(asOf, startDate, dayCount, interpolation); ADouble pe = DiscFactor(asOf, endDate, dayCount, interpolation); ADouble cvg = DateHandling.Cvg(startDate, endDate, dayCount); return((ps / pe - 1.0) / cvg); }
public ADouble FraNpvAD(Fra fra) { ADouble fraRate = ADFwdCurveCollection.GetCurve(fra.ReferenceIndex).FwdRate(fra.AsOf, fra.StartDate, fra.EndDate, fra.DayRule, fra.DayCount, Interpolation); ADouble notional = fra.Notional; ADouble discFactor = ADDiscCurve.DiscFactor(fra.AsOf, fra.EndDate, fra.DayCount, Interpolation); ADouble coverage = DateHandling.Cvg(fra.StartDate, fra.EndDate, fra.DayCount); return(fra.TradeSign * notional * discFactor * coverage * (fraRate - fra.FixedRate)); }
private double CalcSimpleConvexity(DateTime asOf, DateTime startDate, DateTime endDate, DayCount dayCount) { // i.e. Convexity Adjustment = 0.5*vol^2*T*(T+delta), T's measured in year fractions. // Source: Linderstrøm double cvgAsOfToStart = DateHandling.Cvg(asOf, startDate, dayCount); double cvgAsOfToEnd = DateHandling.Cvg(asOf, endDate, dayCount); return(0.5 * 0.0012 * 0.0012 * cvgAsOfToEnd * cvgAsOfToEnd); }
public double FraNpv(Fra fra) { double fraRate = FwdCurveCollection.GetCurve(fra.ReferenceIndex).FwdRate(fra.AsOf, fra.StartDate, fra.EndDate, fra.DayRule, fra.DayCount, Interpolation); double notional = fra.Notional; double discFactor = DiscCurve.DiscFactor(fra.AsOf, fra.StartDate, fra.DayCount, Interpolation); // Note from today and to startDate => Market FRA double coverage = DateHandling.Cvg(fra.StartDate, fra.EndDate, fra.DayCount); return(fra.TradeSign * notional * discFactor * coverage * (fraRate - fra.FixedRate)); }
public Deposit(DateTime asOf, string startTenor, string endTenor, string settlementLag, double fixedRate, DayCount dayCount, DayRule dayRule, double notional, int tradeSign) { AsOf = asOf; StartDate = DateHandling.AddTenorAdjust(asOf, startTenor, dayRule); StartDate = DateHandling.AddTenorAdjust(StartDate, settlementLag, dayRule); EndDate = DateHandling.AddTenor(StartDate, endTenor, dayRule); Notional = notional; TradeSign = tradeSign; FixedRate = fixedRate; DayRule = dayRule; DayCount = dayCount; }
private void ConstructFwdRates() { for (int i = 0; i < Dimension; i++) { DateTime startDate = Dates[i]; DateTime endDate = DateHandling.AddTenorAdjust(startDate, _tenorStr); double fwdRate = _zcbCurve.FwdRate(AsOf, startDate, endDate, _fwdDayRule, _fwdDayCount, _interpolation); Values.Add(fwdRate); } FwdCurve = new MasterThesis.Curve(Dates, Values); }
public Futures(DateTime asOf, string startTenor, string endTenor, CurveTenor referenceIndex, DayCount dayCount, DayRule dayRule, double fixedRate, double notional, int tradeSign, double?convexity = null) { DateTime startDate = DateHandling.AddTenorAdjust(asOf, startTenor, dayRule); DateTime endDate = DateHandling.AddTenorAdjust(startDate, endTenor, dayRule); FraSameSpec = new Fra(asOf, startDate, endDate, referenceIndex, dayCount, dayRule, fixedRate, notional, tradeSign); if (convexity == null) { Convexity = CalcSimpleConvexity(asOf, startDate, endDate, dayCount); } else { Convexity = (double)convexity; } }
public OisSwap(DateTime asOf, string startTenor, string endTenor, string settlementLag, DayCount dayCountFixed, DayCount dayCountFloat, DayRule dayRule, double notional, double fixedRate, int tradeSign) { DateTime startDate = DateHandling.AddTenorAdjust(asOf, startTenor, dayRule); startDate = DateHandling.AddTenorAdjust(startDate, settlementLag, dayRule); DateTime endDate = DateHandling.AddTenorAdjust(startDate, endTenor, dayRule); this.AsOf = asOf; this.StartDate = startDate; this.EndDate = endDate; this.FloatSchedule = new OisSchedule(asOf, startTenor, endTenor, settlementLag, dayCountFloat, dayRule); this.FixedSchedule = new OisSchedule(asOf, startTenor, endTenor, settlementLag, dayCountFixed, dayRule); this.Notional = notional; this.FixedRate = fixedRate; this.TradeSign = tradeSign; }
public ADouble OisRateAD(OisSwap swap, InterpMethod interpolation) { ADouble floatContribution = 0.0; ADouble annuity = OisAnnuityAD(swap.FixedSchedule, interpolation); DateTime asOf = swap.FloatSchedule.AsOf; for (int i = 0; i < swap.FloatSchedule.AdjEndDates.Count; i++) { DateTime startDate = swap.FloatSchedule.AdjStartDates[i]; DateTime endDate = swap.FloatSchedule.AdjEndDates[i]; ADouble compoundedRate = OisCompoundedRateAD(asOf, startDate, endDate, swap.FloatSchedule.DayRule, swap.FloatSchedule.DayCount, interpolation); ADouble discFactor = DiscFactor(asOf, endDate, swap.FixedSchedule.DayCount, interpolation); ADouble coverage = DateHandling.Cvg(startDate, endDate, swap.FloatSchedule.DayCount); floatContribution = floatContribution + discFactor * compoundedRate * coverage; } return(floatContribution / annuity); }
private void InterpretFuturesString(string instrumentString) { string identifier, type, currency, endTenor, settlementLag, floatPayFreq, floatFixingTenor, fwdTenor; DayRule dayRule; DayCount dayCount; CurveTenor curveTenor; string[] infoArray = instrumentString.Split(',').ToArray(); identifier = infoArray[0]; type = infoArray[1]; currency = infoArray[2]; endTenor = infoArray[3]; settlementLag = infoArray[4]; dayRule = StrToEnum.DayRuleConvert(infoArray[5]); floatPayFreq = infoArray[8]; floatFixingTenor = infoArray[9]; fwdTenor = infoArray[15]; dayCount = StrToEnum.DayCountConvert(infoArray[11]); DateTime startDate, endDate; try { startDate = Convert.ToDateTime(fwdTenor); endDate = DateHandling.AddTenorAdjust(startDate, floatPayFreq, dayRule); curveTenor = StrToEnum.CurveTenorFromSimpleTenor(floatPayFreq); Fra fra = new MasterThesis.Fra(AsOf, startDate, endDate, curveTenor, dayCount, dayRule, _defaultFixedRate, _defaultNotional, _defaultTradeSign); Futures[identifier] = new MasterThesis.Futures(fra, null); CurvePointMap[identifier] = fra.GetCurvePoint(); InstrumentTypeMap[identifier] = QuoteType.FuturesRate; InstrumentFormatTypeMap[identifier] = InstrumentFormatType.Futures; IdentifierStringMap[identifier] = instrumentString; } catch { // Ignore instrument } }
private void GenerateSchedule(DateTime asOf, DateTime startDate, DateTime endDate, DayCount dayCount, DayRule dayRule, CurveTenor tenor, StubPlacement stub = StubPlacement.NullStub) { // This only works for short stubs atm, although NullStub will generate a long stub DateTime AdjStart = DateHandling.AdjustDate(startDate, dayRule); DateTime AdjEnd = DateHandling.AdjustDate(endDate, dayRule); string tenorString = EnumToStr.CurveTenor(tenor); string TenorLetter = DateHandling.GetTenorLetterFromTenor(tenorString); double TenorNumber = DateHandling.GetTenorNumberFromTenor(tenorString); int periods = CalculatePeriods(startDate, endDate, tenor); // Create estimate of how long the schedule should be //double YearsUpper = DateHandling.Cvg(AdjStart, AdjEnd, dayCount); //double YearLower = DateHandling.Cvg(AsOf, AdjStart, dayCount); // Will be sorted at end (when coverages are also calculated) UnAdjStartDates.Add(StartDate); UnAdjEndDates.Add(EndDate); AdjStartDates.Add(AdjStart); AdjEndDates.Add(AdjEnd); //if (StrToEnum.ConvertTenorLetter(TenorLetter) == Tenor.M) //{ // periods = periodsInMonths / (int)TenorNumber; // //WholePeriods = periodsInMonths / (int) TenorNumber; // //double tempPeriods = YearsUpper * 12 / TenorNumber; // //WholePeriods = (int)Math.Truncate(tempPeriods); //} //else if (StrToEnum.ConvertTenorLetter(TenorLetter) == Tenor.Y) //{ // periods = periodsInMonths / (12 * (int)TenorNumber); // //WholePeriods = (int) Math.Truncate(YearsUpper); //} //else //{ // throw new ArgumentException("Can only roll out swap calender for month and year tenors"); //} if (stub == StubPlacement.Beginning) { periods += 1 * 12 / (int)Math.Round(TenorNumber); for (int i = 1; i < periods; i++) { UnAdjEndDates.Add(DateHandling.AddTenorAdjust(UnAdjEndDates[i - 1], "-" + tenorString)); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[i], DayRule)); UnAdjStartDates.Add(UnAdjEndDates[i]); AdjStartDates.Add(DateHandling.AdjustDate(UnAdjStartDates[i], DayRule)); } } else if (stub == StubPlacement.End) { periods += 1 * 12 / (int)Math.Round(TenorNumber); for (int i = 1; i < periods; i++) { UnAdjStartDates.Add(DateHandling.AddTenorAdjust(UnAdjStartDates[i - 1], tenorString)); AdjStartDates.Add(DateHandling.AdjustDate(UnAdjStartDates[i], DayRule)); UnAdjEndDates.Add(UnAdjStartDates[i]); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[i], DayRule)); } } else if (stub == StubPlacement.NullStub) { for (int i = 1; i < periods; i++) { UnAdjEndDates.Add(DateHandling.AddTenorAdjust(UnAdjEndDates[i - 1], "-" + tenorString)); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[i], DayRule)); UnAdjStartDates.Add(UnAdjEndDates[i]); AdjStartDates.Add(DateHandling.AdjustDate(UnAdjStartDates[i], DayRule)); } } // Sort dates according to date UnAdjStartDates.Sort(new Comparison <DateTime>((x, y) => x.CompareTo(y))); UnAdjEndDates.Sort(new Comparison <DateTime>((x, y) => x.CompareTo(y))); AdjStartDates.Sort(new Comparison <DateTime>((x, y) => x.CompareTo(y))); AdjEndDates.Sort(new Comparison <DateTime>((x, y) => x.CompareTo(y))); for (int i = 0; i < AdjStartDates.Count; i++) { Coverages.Add(DateHandling.Cvg(AdjStartDates[i], AdjEndDates[i], DayCount)); } }
// Ideally, this should be a derived class on SwapSchedule, since an // OIS schedule (in this context) is either a short period, or 1Y schedule with // a stub in the end. For our purpose, we just define a derived the class // that only works for our purpose (i.e. it's not general.) public OisSchedule(DateTime asOf, string startTenor, string endTenor, string settlementLag, DayCount dayCount, DayRule dayRule) : base(asOf, startTenor, endTenor, dayCount, dayRule) { Tenor startTenorEnum = GetLetterFromTenor(startTenor); Tenor endTenorEnum = GetLetterFromTenor(endTenor); UnAdjStartDates.Add(StartDate); AdjStartDates.Add(StartDate); // Just to make sure we compare with both "1Y" and "12M" (because i'm lazy in correcting for DayCount) if (CompareTenors(endTenor, "1Y") == false && CompareTenors(endTenor, "12M") == false) { // Simple OIS swap double cvg = DateHandling.Cvg(StartDate, EndDate, dayCount); UnAdjEndDates.Add(EndDate); AdjEndDates.Add(DateHandling.AdjustDate(EndDate)); Coverages.Add(cvg); return; } else { int months = 0; // 1Y periods + stub int periods, years; if (endTenorEnum == Tenor.Y) { periods = GetNumberFromTenor(endTenor); years = periods; } else if (endTenorEnum == Tenor.M) { years = (int)Math.Truncate(GetNumberFromTenor(endTenor) / 12.0); if (GetNumberFromTenor(endTenor) % 12 == 0) { months = 0; periods = years; } else { months = GetNumberFromTenor(endTenor) - 12 * years; periods = years + 1; } } else { throw new InvalidOperationException("OIS Schedule only works for Y,M endTenors"); } UnAdjEndDates.Add(DateHandling.AddTenorAdjust(StartDate, "1Y")); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[0], DayRule.N)); Coverages.Add(DateHandling.Cvg(AdjStartDates[0], AdjEndDates[0], DayCount)); // Generate Schedule // We start from 1 since first days are filled out // We only end here if we have more than 1 period for (int j = 1; j <= periods; j++) { if (periods > years && periods == j + 1) // In case we have tenor like "18M" and have to create a stub periods { string excessTenor = months.ToString() + "M"; UnAdjStartDates.Add(DateHandling.AddTenorAdjust(UnAdjStartDates[j - 1], "1Y", dayRule)); AdjStartDates.Add(DateHandling.AdjustDate(UnAdjStartDates[j], dayRule)); UnAdjEndDates.Add(DateHandling.AddTenorAdjust(UnAdjEndDates[j - 1], excessTenor, dayRule)); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[j], dayRule)); Coverages.Add(DateHandling.Cvg(AdjStartDates[j], AdjEndDates[j], DayCount)); } else { if (j < periods) { UnAdjStartDates.Add(DateHandling.AddTenorAdjust(UnAdjStartDates[j - 1], "1Y", dayRule)); AdjStartDates.Add(DateHandling.AdjustDate(UnAdjStartDates[j], dayRule)); UnAdjEndDates.Add(DateHandling.AddTenorAdjust(UnAdjEndDates[j - 1], "1Y", dayRule)); AdjEndDates.Add(DateHandling.AdjustDate(UnAdjEndDates[j], dayRule)); Coverages.Add(DateHandling.Cvg(AdjStartDates[j], AdjEndDates[j], DayCount)); } } } } }
public ADouble DiscFactor(DateTime asOf, DateTime date, DayCount dayCount, InterpMethod interpolation) { return(ADouble.Exp(-1.0 * ZeroRate(date, interpolation) * DateHandling.Cvg(asOf, date, dayCount))); }
private void InterpretSwapString(string instrumentString) { string identifier, type, currency, startTenor, endTenor, settlementLag, fixedFreq, floatFreq, referenceIndex; DayRule dayRule; DayCount floatDayCount, fixedDayCount; CurveTenor floatTenor, fixedTenor; string[] infoArray = instrumentString.Split(',').ToArray(); identifier = infoArray[0]; type = infoArray[1]; currency = infoArray[2]; startTenor = infoArray[3]; endTenor = infoArray[4]; settlementLag = infoArray[5]; dayRule = StrToEnum.DayRuleConvert(infoArray[6]); fixedFreq = infoArray[9]; floatFreq = infoArray[10]; referenceIndex = infoArray[12]; floatDayCount = StrToEnum.DayCountConvert(infoArray[14]); fixedDayCount = StrToEnum.DayCountConvert(infoArray[13]); floatTenor = StrToEnum.CurveTenorFromSimpleTenor(floatFreq); fixedTenor = StrToEnum.CurveTenorFromSimpleTenor(fixedFreq); DateTime startDate, endDate; // Make sure to get fwd starting stuff right here... if (DateHandling.StrIsConvertableToDate(startTenor)) { startDate = Convert.ToDateTime(startTenor); } else { startDate = DateHandling.AddTenorAdjust(AsOf, settlementLag, dayRule); } if (DateHandling.StrIsConvertableToDate(endTenor)) { endDate = Convert.ToDateTime(endTenor); } else { endDate = DateHandling.AddTenorAdjust(startDate, endTenor, dayRule); } try { if (referenceIndex == "EONIA") { // Handle OIS case // Error with endTenor here and string parsing // TEMPORARY //settlementLag = "0D"; //dayRule = DayRule.F; // This is a dirty hack to value deposits if (identifier == "EUREONON" || identifier == "EUREONTN") { Deposit deposit = new Deposit(AsOf, startTenor, endTenor, settlementLag, _defaultFixedRate, floatDayCount, dayRule, _defaultNotional, _defaultTradeSign); Deposits[identifier] = deposit; CurvePointMap[identifier] = deposit.GetCurvePoint(); InstrumentTypeMap[identifier] = QuoteType.Deposit; InstrumentFormatTypeMap[identifier] = InstrumentFormatType.Swaps; IdentifierStringMap[identifier] = instrumentString; } else { OisSwap oisSwap = new OisSwap(AsOf, startTenor, endTenor, settlementLag, fixedDayCount, floatDayCount, dayRule, _defaultNotional, _defaultFixedRate, _defaultTradeSign); OisSwaps[identifier] = oisSwap; CurvePointMap[identifier] = oisSwap.GetCurvePoint(); InstrumentTypeMap[identifier] = QuoteType.OisRate; InstrumentFormatTypeMap[identifier] = InstrumentFormatType.Swaps; IdentifierStringMap[identifier] = instrumentString; } } else { // Handle non-OIS case IrSwap swap = new IrSwap(AsOf, startDate, endDate, _defaultFixedRate, fixedTenor, floatTenor, fixedDayCount, floatDayCount, dayRule, dayRule, _defaultNotional, _defaultTradeSign, 0.0); IrSwaps[identifier] = swap; CurvePointMap[identifier] = swap.GetCurvePoint(); InstrumentTypeMap[identifier] = QuoteType.ParSwapRate; InstrumentFormatTypeMap[identifier] = InstrumentFormatType.Swaps; IdentifierStringMap[identifier] = instrumentString; } } catch { // Ignore instrument. } }