Ejemplo n.º 1
0
        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);
        }