private IEnumerable <Yield> InitializeYield(DateTime date, CDI cdi, CopomMeeting[] copomMeetings, DI1[] di1s) { var i_d = 0; var i_c = 0; yield return(new Yield { Term = 0, Forward = cdi.TaxaCDI, SpotMtm = cdi.TaxaCDI, Spot = cdi.TaxaCDI, YieldType = YieldType.CDI, ForwardFactor = 1d, SpotFactor = 1d }); while (i_c < copomMeetings.Length && i_d < di1s.Length) { if (copomMeetings[i_c].Date < di1s[i_d].MaturityDate) { yield return(new Yield { Term = GetNetworkDays(date, copomMeetings[i_c].Date), YieldType = YieldType.COPOM }); i_c++; } else { yield return(new Yield { Term = GetNetworkDays(date, di1s[i_d].MaturityDate), YieldType = YieldType.DI1, SpotMtm = di1s[i_d].Spot }); i_d++; } } for (; i_c < copomMeetings.Length; i_c++) { yield return new Yield { Term = GetNetworkDays(date, copomMeetings[i_c].Date), YieldType = YieldType.COPOM } } ; for (; i_d < di1s.Length; i_d++) { yield return new Yield { Term = GetNetworkDays(date, di1s[i_d].MaturityDate), YieldType = YieldType.DI1, SpotMtm = di1s[i_d].Spot } } ; }
private IEnumerable <Yield> InitializeYield(DateTime date, CDI cdi, CopomMeeting[] copomMeetings, DI1[] di1s, HashSet <DateTime> holidays) { var i_d = 0; var i_c = 0; yield return(new Yield { Term = 0, Maturity = date, Forward = cdi.TaxaCDI, SpotMtm = cdi.TaxaCDI, Spot = cdi.TaxaCDI, YieldType = YieldType.CDI, ForwardFactor = 1d, SpotFactor = 1d }); while (i_c < copomMeetings.Length && i_d < di1s.Length) { if (copomMeetings[i_c].Date < di1s[i_d].MaturityDate) { yield return(new Yield { Term = GetNetworkDays(date, copomMeetings[i_c].Date, holidays), Maturity = copomMeetings[i_c].Date, YieldType = YieldType.COPOM }); i_c++; } else { yield return(new Yield { Term = GetNetworkDays(date, di1s[i_d].MaturityDate, holidays), Maturity = di1s[i_d].MaturityDate, YieldType = YieldType.DI1, SpotMtm = di1s[i_d].Spot, TotalTradesMtm = di1s[i_d].TotalTrades, SpotMtmFactor = Math.Pow(1d + di1s[i_d].Spot / 100d, GetNetworkDays(date, di1s[i_d].MaturityDate, holidays) / 252d) }); i_d++; } } for (; i_c < copomMeetings.Length; i_c++) { yield return new Yield { Term = GetNetworkDays(date, copomMeetings[i_c].Date, holidays), Maturity = copomMeetings[i_c].Date, YieldType = YieldType.COPOM } } ; for (; i_d < di1s.Length; i_d++) { yield return new Yield { Term = GetNetworkDays(date, di1s[i_d].MaturityDate, holidays), Maturity = di1s[i_d].MaturityDate, YieldType = YieldType.DI1, SpotMtm = di1s[i_d].Spot, TotalTradesMtm = di1s[i_d].TotalTrades, SpotMtmFactor = Math.Pow(1d + di1s[i_d].Spot / 100d, GetNetworkDays(date, di1s[i_d].MaturityDate, holidays) / 252d) } } ; }
public IEnumerable <Yield> BuildYield(DateTime date, CopomMeeting[] copomMeetings, DI1[] di1s, CDI cdi, HashSet <DateTime> holidays) { var clock = Stopwatch.StartNew(); var yields = InitializeYield(date, cdi, copomMeetings, di1s, holidays).ToArray(); for (var i = 1; i < yields.Length; i++) { yields[i].DeltaTerm = yields[i].Term - yields[i - 1].Term; } yields = yields.Where(y => y.YieldType != YieldType.DI1 || (y.DeltaTerm > 1 && y.TotalTradesMtm > 1)).ToArray(); var meetings = copomMeetings.Length; double bump = 0; var diArray = Enumerable.Range(0, yields.Length) .Where(i => yields[i].YieldType == YieldType.DI1) .Select(i => i).ToArray(); var copomArray = Enumerable.Range(0, yields.Length) .Where(i => yields[i].YieldType == YieldType.COPOM) .Select(i => i).ToArray(); var diPos = 0; var copomPos = 0; yields[0].Forward = yields.First(y => y.YieldType == YieldType.DI1).SpotMtm; var lastBump = 0d; for (var i = 1; i < yields.Length; i++) { yields[i].Forward = yields[i - 1].Forward + yields[i - 1].Bump; yields[i].ForwardFactor = GetFactor(yields[i].Forward, yields[i].Term - yields[i - 1].Term); yields[i].SpotFactor = yields[i - 1].SpotFactor * yields[i].ForwardFactor; yields[i].Spot = GetInterest(yields[i].SpotFactor, yields[i].Term); if (yields[i].YieldType == YieldType.COPOM) { meetings--; copomPos++; } else { diPos++; } var shouldBump = yields[i].YieldType == YieldType.COPOM || meetings == 0; if (shouldBump) { var nextDI = diPos < diArray.Length ? diArray[diPos] : -1; var nextNextDI = diPos + 1 < diArray.Length ? diArray[diPos + 1] : -1; var nextCOPOM = copomPos < copomArray.Length ? copomArray[copomPos] : -1; // não tem mais reunião do copom, portanto haverá bump no vencimento de DI1 if (meetings == 0) { if (i + 1 >= yields.Length) { continue; } var forwardFactor = GetFactor(yields[i + 1].SpotMtm, yields[i + 1].Term) / yields[i].SpotFactor; var forward = GetInterest(forwardFactor, yields[i + 1].Term - yields[i].Term); lastBump = yields[i].Bump = forward - yields[i].Forward; } // os dois próximos vértices são de DI1 else if (nextDI - i == 1 && nextDI == nextNextDI - 1) { // calculamos o bump considerando apenas o vencimento de DI1 mais longo var forwardFactor = GetFactor(yields[i + 2].SpotMtm, yields[i + 2].Term) / yields[i].SpotFactor; var forward = GetInterest(forwardFactor, yields[i + 2].Term - yields[i].Term); lastBump = yields[i].Bump = forward - yields[i].Forward; } // o próximo vértice é um DI1 seguido de um COPOM else if (nextCOPOM == nextDI + 1) { var forwardFactor = GetFactor(yields[i + 1].SpotMtm, yields[i + 1].Term) / yields[i].SpotFactor; var forward = GetInterest(forwardFactor, yields[i + 1].Term - yields[i].Term); lastBump = yields[i].Bump = forward - yields[i].Forward; } // os próximos n vértices são reuniôes do COPOM else { var ps = new List <Yield>(); var j = i + 1; while (j < yields.Length && yields[j].YieldType == YieldType.COPOM) { ps.Add(yields[j++]); } ps.Add(yields[j]); FindForwards( yields[i], ps.ToArray(), yields[j].SpotMtm, lastBump); yields[i].Bump = yields[i + 1].Forward - yields[i].Forward; for (i = i + 1; i < j; i++) { lastBump = yields[i].Bump = yields[i + 1].Forward - yields[i].Forward; yields[i].ForwardFactor = GetFactor(yields[i].Forward, yields[i].Term - yields[i - 1].Term); yields[i].SpotFactor = yields[i - 1].SpotFactor * yields[i].ForwardFactor; yields[i].Spot = GetInterest(yields[i].SpotFactor, yields[i].Term); meetings--; copomPos++; } i--; } } else { yields[i].Bump = 0; } } Console.WriteLine($"Interpolate yield={clock.ElapsedMilliseconds}"); return(yields); }
public IEnumerable <Yield> BuildYield2(DateTime date, CopomMeeting[] copomMeetings, DI1[] di1s, CDI cdi, HashSet <DateTime> holidays) { var clock = Stopwatch.StartNew(); var yields = InitializeYield(date, cdi, copomMeetings, di1s, holidays).ToArray(); for (var i = 1; i < yields.Length; i++) { yields[i].DeltaTerm = yields[i].Term - yields[i - 1].Term; } yields = yields.Where(y => y.YieldType != YieldType.DI1 || (y.DeltaTerm > 1 && y.TotalTradesMtm > 1)).ToArray(); var meetings = copomMeetings.Length; var diArray = Enumerable.Range(0, yields.Length) .Where(i => yields[i].YieldType == YieldType.DI1) .Select(i => i).ToArray(); var diPos = 0; var lastCOPOM = -1; for (var i = 1; i < yields.Length; i++) { if (yields[i].YieldType == YieldType.COPOM) { yields[i].IsSameForward = lastCOPOM != i - 1; lastCOPOM = i; meetings--; } else { diPos++; var nextDI = diPos < diArray.Length ? diArray[diPos] : -1; if (nextDI == i + 1 && meetings > 0) { yields[i].IsSameForward = true; } else { yields[i].IsSameForward = false; } } } Optimize(yields); Console.WriteLine($"Interpolate yield={clock.ElapsedMilliseconds}"); return(yields); }