Ejemplo n.º 1
0
        //------------------------------------------------------------------------------------------------
        public static double calcFwdBondMeasure(string measure, 
                                        AnalyticsBondStaticData bondstatic, 
                                        double fwdPrice, 
                                        DateTime asofDate, DateTime settle, 
                                        SpreadConventions convs,
                                        SortedDictionary<DateTime,DiscountFactors> ForecastCurves,
                                        SortedDictionary<DateTime, DiscountFactors> DiscountCurves,
                                        List<DateTime> hols,
                                        Tuple<DateTime,double> previous = null)
        //------------------------------------------------------------------------------------------------
        {

            //string identifier = bondstatic.Id;

            // Setup Params
            DateTime FwdDate = settle;
            DateTime effectiveDate = bondstatic.EffectiveDate;
            DateTime firstCpnDate = bondstatic.FirstCouponDate;
            DateTime maturity = bondstatic.MaturityDate; 

            double coupon = bondstatic.Coupon;

            long bondCpnFreq = bondstatic.CpnFreq;
            long fixedFreq = convs.SwapFixedFrequency;
            long floatFreq = convs.SwapFloatFrequency;
            BondAnalytics.Country eCountry = bondstatic.Country;
            BondAnalytics.DayCountType dct = convs.DayCount;
            bool bOIS = !convs.bForecastCurve;

            int blendIdx = convs.BlendIndex;

            double output = double.NaN;
            switch (measure)
            {
                case "Yield":
                    {

                        output = 10000.0 * BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[0];

                        break;
                    }
                case "TrueSpread":
                    {

                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        DiscountFactors curve = ForecastCurves[asofDate];
                        DateTime[] dfDates = curve.CurveDates;
                        double[] dfs = curve.Dfs;

                        //  Check. Sometimes (holidays) the first date on the curve can be repeated, which will cause an exception in the pricer.
                        if (dfDates[0] == dfDates[1])
                        {
                            dfDates = dfDates.GetSubArray(1, dfDates.GetLength(0)).ToArray();
                            dfs = dfs.GetSubArray(1, dfs.GetLength(0)).ToArray();
                        }
                        output = -10000.0 * BondAnalytics.SolveZSpread(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq, dfDates, dfs, hols);
                        break;

                    }
                case "MMS":
                    {
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[asofDate];
                        var forecastCurve = ForecastCurves[asofDate];

                        DateTime[] discDfDates = discountCurve.CurveDates;
                        DateTime[] fcstDfDates = forecastCurve.CurveDates;
                        double[] discDfs = discountCurve.Dfs;
                        double[] fcstDfs = forecastCurve.Dfs;

                        //double mms = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discDfDates, discDfs, fcstDfDates, fcstDfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);
                        var mms = SwapAnalytics.CalcSwapRate(FwdDate, maturity, 0.0, dct, fixedFreq, dct, floatFreq, discDfDates,
                            discDfs, fcstDfDates, fcstDfs, hols, 0.0, blendIdx, bOIS ? blendIdx : 0);
                        output = 10000.0 * mms;
                        break;

                    }
                case "Spread":
                    {
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[asofDate];
                        var forecastCurve = ForecastCurves[asofDate];

                        DateTime[] discDfDates = discountCurve.CurveDates;
                        DateTime[] fcstDfDates = forecastCurve.CurveDates;
                        double[] discDfs = discountCurve.Dfs;
                        double[] fcstDfs = forecastCurve.Dfs;

                        var mms = SwapAnalytics.CalcSwapRate(FwdDate, maturity, 0.0, dct, fixedFreq, dct, floatFreq, discDfDates,
                            discDfs, fcstDfDates, fcstDfs, hols, 0.0, blendIdx, bOIS ? blendIdx : 0);
                        double yield = 0.0;

                        yield = BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[0];

                        output = 10000.0 * (mms - yield);
                        break;

                    }

                case "FuturesDV01":
                    {

                        double previous_price = double.NaN;
                        if (previous != null)
                        {
                            previous_price = previous.Item2;
                        }


                        // Get the CTD Bond DV01 here
                        double dv01 = BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[1] / 1000000 * 100;

                        // Get next price
                        output = dv01;
                        break;
                    }

                case "MMSDV01":
                    {
                        // Setup current swap curve
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[asofDate];
                        var forecastCurve = ForecastCurves[asofDate];

                        double rate = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates, forecastCurve.Dfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);

                        // Get Current DV01
                        double dv01 = SwapAnalytics.CalcSwapDv01(FwdDate, maturity, 1, rate, dct, dct, fixedFreq,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // DV01 adjusted PnL
                        output = dv01 * 100; // 100 Notional Terms here

                        break;
                    }


                case "FuturesPnlDV01Adj":
                    {

                        double previous_fwdprice = double.NaN;
                        if (previous != null)
                        {
                            previous_fwdprice = previous.Item2;
                        }


                        // Get the CTD Bond DV01 here
                        double dv01 = BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[1] / 1000000 * 100;

                        // Get next price
                        output = (fwdPrice - previous_fwdprice)  / Math.Abs(dv01); //Normalise into 100 par terms

                        break;
                    }
                case "FuturesPnl":
                    {

                        double previous_fwdprice = double.NaN;
                        if (previous != null)
                        {
                            previous_fwdprice = previous.Item2;
                        }

                        // PnL in notional terms
                        output = fwdPrice - previous_fwdprice; // Actual pnl is given by price change of the CTD bond

                        break;
                    }
                case "SwapPnl":
                    {
                        // Previous date, curve to get original MMS rate
                        DateTime previousDate = DateTime.MinValue;
                        if (previous != null)
                        {
                            previousDate = previous.Item1;
                        }

                        if (!ForecastCurves.ContainsKey(previousDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[previousDate];
                        var forecastCurve = ForecastCurves[previousDate];

                        double previouRate = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates, forecastCurve.Dfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);
                        previouRate *= 100; // For cents
                        // Setup current swap curve
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        discountCurve = DiscountCurves[asofDate];
                        forecastCurve = ForecastCurves[asofDate];

                        // Get PnL of rate
                        //priceSwap(DateTime startDate, DateTime endDate, int payRec, double fixedRate, BondAnalytics.DayCountType fixedDctType, long fixedFreq, double floatSpread, BondAnalytics.DayCountType floatDctType, long floatFreq, DateTime[] discCurveDates, double[] discDfs, DateTime[] fcstCurveDates, double[] fcstDfs, List<DateTime> holidays, double lastFixing = 0.0, int blendIndexD = 0, int blendIndexF = 0, bool incPrin = false)
                        double pnl = SwapAnalytics.PriceSwap(FwdDate, maturity, 1, previouRate, dct, fixedFreq, 0.0, dct,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // Raw PnL innotional terms
                        output = pnl * 100;  // pnl in cents

                        break;
                    }

                case "SwapPnlDV01Adj":
                    {

                        // Previous date, curve to get original MMS rate
                        DateTime previousDate = DateTime.MinValue;
                        if (previous != null)
                        {
                            previousDate = previous.Item1;
                        }

                        if (!ForecastCurves.ContainsKey(previousDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[previousDate];
                        var forecastCurve = ForecastCurves[previousDate];

                        double previousRate = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates, forecastCurve.Dfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);

                        previousRate *= 100; // To put this into cents

                        // Setup current swap curve
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        discountCurve = DiscountCurves[asofDate];
                        forecastCurve = ForecastCurves[asofDate];

                        // Get PnL of rate
                        double pnl = SwapAnalytics.PriceSwap(FwdDate, maturity, 1, previousRate, dct, fixedFreq, 0.0, dct,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // Get Current DV01
                        double dv01 = SwapAnalytics.CalcSwapDv01(FwdDate, maturity, 1, previousRate, dct, dct, fixedFreq,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // DV01 adjusted PnL
                        output = pnl / Math.Abs(dv01); // 100 Notional Terms here

                        break;
                    }
                case "SpreadPnlDV01Adj":
                    {
                        // FUTURES.
                        double previous_fwdprice = double.NaN;
                        if (previous != null)
                        {
                            previous_fwdprice = previous.Item2;
                        }


                        // Get the CTD Bond DV01 here
                        double dv01 = BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[1] / 1000000 * 100;

                        // Get next price
                        double futures01AdjPnl = (fwdPrice - previous_fwdprice) / Math.Abs(dv01);

                        // SWAP.
                        // Previous date, curve to get original MMS rate
                        DateTime previousDate = DateTime.MinValue;
                        if (previous != null)
                        {
                            previousDate = previous.Item1;
                        }

                        if (!ForecastCurves.ContainsKey(previousDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[previousDate];
                        var forecastCurve = ForecastCurves[previousDate];

                        double previousRate = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates, forecastCurve.Dfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);
                        previousRate *= 100; // To put in cents

                        // Setup current swap curve
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        discountCurve = DiscountCurves[asofDate];
                        forecastCurve = ForecastCurves[asofDate];

                        // Get PnL of rate
                        double pnl = SwapAnalytics.PriceSwap(FwdDate, maturity, 1, previousRate, dct, fixedFreq, 0.0, dct,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // Get Current DV01
                        dv01 = SwapAnalytics.CalcSwapDv01(FwdDate, maturity, 1, previousRate, dct, dct, fixedFreq,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);

                        // DV01 adjusted PnL
                        double swap01AdjPnl = pnl / Math.Abs(dv01); // Notional Terms here

                        output = swap01AdjPnl - futures01AdjPnl;

                        break;
                    }
                case "SpreadHedgeRatio":
                    {

                        // Get Bond DV01
                        double previous_price = double.NaN;
                        if (previous != null)
                        {
                            previous_price = previous.Item2;
                        }


                        // Get the CTD Bond DV01 here
                        double futuresDv01 = BondAnalytics.SolveYield(eCountry, FwdDate, fwdPrice, effectiveDate, firstCpnDate, maturity, coupon, bondCpnFreq)[1] / 1000000;// Match futures notional (1mil notional. prices in cents)
                        // Setup current swap curve
                        if (!ForecastCurves.ContainsKey(asofDate))
                        {
                            output = double.NaN;
                            break;
                        }

                        var discountCurve = DiscountCurves[asofDate];
                        var forecastCurve = ForecastCurves[asofDate];

                        double mms = BondAnalytics.CalcMMS(FwdDate, maturity, dct, fixedFreq, floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates, forecastCurve.Dfs, hols, null, null, null, null, null, firstCpnDate, blendIdx);
                        mms *= 100;

                        // Get Swap DV01
                        double swapDv01 = SwapAnalytics.CalcSwapDv01(FwdDate, maturity, 1, mms, dct, dct, fixedFreq,
                            floatFreq, discountCurve.CurveDates, discountCurve.Dfs, forecastCurve.CurveDates,
                            forecastCurve.Dfs, hols);


                        output = Math.Abs(futuresDv01) / Math.Abs(swapDv01);

                        break;
                    }
            }

            return output;

        }
Ejemplo n.º 2
0
        //------------------------------------------------------------------------------------------------
        public static double calcFwdBondMeasure(string measure,
            AnalyticsBondStaticData bondstatic,
            double fwdPrice,
            DateTime asofDate, DateTime settle,
            SpreadConventions convs,
            SortedDictionary<DateTime, Tuple<DateTime,double>[]> ForecastCurves,
            SortedDictionary<DateTime, Tuple<DateTime, double>[]> DiscountCurves,
            List<DateTime> hols,
            Tuple<DateTime, double> previous = null)
            //------------------------------------------------------------------------------------------------
        {

            // Cast forecast and discount curves
            var newForecastCurves = new SortedDictionary<DateTime, DiscountFactors>(
                ForecastCurves.ToDictionary(kvp => kvp.Key, kvp => new DiscountFactors(kvp.Value)));
            var newDiscountCurves = new SortedDictionary<DateTime, DiscountFactors>(
                DiscountCurves.ToDictionary(kvp => kvp.Key, kvp => new DiscountFactors(kvp.Value)));

            // Run them through original code
            return calcFwdBondMeasure(measure,bondstatic,fwdPrice,asofDate,settle,convs,newForecastCurves,newDiscountCurves,hols,previous);

        }
Ejemplo n.º 3
0
        private static string GetBondPriceSnapSource(AnalyticsBondStaticData bondData)
        {
            switch (bondData.Country)
            {
                case BondAnalytics.Country.US:
                    return "snaps-nyk";
                case BondAnalytics.Country.JP:
                    return "snaps-jpy";
                case BondAnalytics.Country.AU:
                    return "snaps-aus";
                default:
                    return "snaps-ldn";

            }
        }
Ejemplo n.º 4
0
        //  Retrieve historical bond prices from Symmetry.TS
        public static double[] GetHistoricPrices(this ICarbonClient client, AnalyticsBondStaticData bondData, List<DateTime> dateSeries)
        {
            double[] result = new double[dateSeries.Count];

            for (int i = 0; i < dateSeries.Count; i++)
            {
                object o = null;
                try
                {
                    var snapSource = GetBondPriceSnapSource(bondData);
                    o = client.GetCbnTimeSeriesDataCell(bondData.Id, snapSource, dateSeries[i], "close");
                }
                catch
                {
                    //  Missing data
                }
                if (o is double)
                {
                    result[i] = (double)o;
                }
            }
            return result;
        }
Ejemplo n.º 5
0
        private static IReadOnlyDictionary<string, IReadOnlyDictionary<DateTime, double>> BulkGetHistoricPricesFromCarbonOneBond(ICarbonClient client,
            AnalyticsBondStaticData bondData,
            List<DateTime> dateSeries)
        {
            var dict = new Dictionary<DateTime, double>();
            var dates = new List<DateTime>();

            if (bondData != null)
            {
                foreach (var date in dateSeries)
                {
                    var d = GetBondPricesFromCache(bondData.Id, date);
                    if (d.HasValue)
                    {
                        dict[date] = d.Value;
                    }
                    else if (date <= DateTime.Today)
                    {
                        dates.Add(date);
                    }
                }

                if (dates.Count > 0)
                {
                    var inputDateKind = dateSeries.FirstOrDefault().Kind;

                    var snapSource = GetBondPriceSnapSource(bondData);
                    var end = dates.Max();
                    var start = dates.Min();

                    SLog.log.InfoFormat("Request bond price for {0} days", dates.Count);

                    start = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0, DateTimeKind.Utc);
                    end = new DateTime(end.Year, end.Month, end.Day, 0, 0, 0, DateTimeKind.Utc);

                    var datas = client.GetTimeSeriesData(bondData.Id, snapSource, start, end, "close");
                    if (datas != null)
                    {
                        foreach (var data in datas)
                        {
                            try
                            {
                                var close = data.Value.AsDouble();
                                var date = new DateTime(data.Key.Year, data.Key.Month, data.Key.Day, 0, 0, 0, inputDateKind);
                                dict[date] = close;
                                AddBondPricesToCache(bondData.Id, date, close);
                            }
                            catch (Exception ex)
                            {
                                SLog.log.ErrorFormat("Failed to convert close price for {0} : {1}", bondData.Id, ex);
                            }
                        }
                    }
                }
            }

            return new Dictionary<string, IReadOnlyDictionary<DateTime, double>> { { bondData.Id, dict } };
        }
Ejemplo n.º 6
0
        private static AnalyticsBondStaticData ConvertCarbonBondStaticToAnalyticBondStatic(ICarbonClient client, ITimeSeries data)
        {
            var result = new AnalyticsBondStaticData
            {
                Id = client.GetSingleStaticDataInternal<string>(data, "isin"),
                MaturityDate = client.GetSingleStaticDataInternal<DateTime>(data, "maturityDt"),
                EffectiveDate = client.GetSingleStaticDataInternal<DateTime>(data, "effectiveDt")
            };

            //  Check if there is a more recent effective date due to subsequent auctions.
            DateTime latestEffectiveDate;
            object o = data.GetCarbonBondMostRecentEffectiveDate();
            if (o is DateTime)
                latestEffectiveDate = (DateTime)o;
            else
                latestEffectiveDate = result.EffectiveDate;
            result.FirstCouponDate = client.GetSingleStaticDataInternal<DateTime>(data, "firstCpnDt");
            result.Coupon = client.GetSingleStaticDataInternal<double>(data, "cpnRate");

            return DecorateAnalyticsBondStaticData(result, latestEffectiveDate);
        }
Ejemplo n.º 7
0
        private static AnalyticsBondStaticData DecorateAnalyticsBondStaticData(AnalyticsBondStaticData result, DateTime latestEffectiveDate)
        {
            if (!result.MaturityDate.IsValidDate() || !result.EffectiveDate.IsValidDate() || !result.FirstCouponDate.IsValidDate())
            {
                return null;
            }

            if (result.Id.Substring(0, 2) == "US")
            {
                //  This is relevant for US bonds where there are standard maturities for new issuance - eg. 2,3,5,7,10,30yr tenors.
                double yrs = (result.MaturityDate - latestEffectiveDate).TotalDays / 365.25;
                if (yrs < 2.5)
                    result.Series = 2;
                else if (yrs < 4)
                    result.Series = 3;
                else if (yrs < 6)
                    result.Series = 5;
                else if (yrs < 8.5)
                    result.Series = 7;
                else if (yrs < 20)
                    result.Series = 10;
                else
                    result.Series = 30;
            }
            else
                result.Series = 0;

            BondAnalytics.Country eCountry;
            //  Map to country using first two characters of ISIN
            BondAnalytics.CountryMappings.TryGetValue(result.Id.Substring(0, 2), out eCountry);
            result.Country = eCountry;
            result.CpnFreq = 6;
            switch (eCountry)
            {
                case BondAnalytics.Country.US:
                    result.Ccy = "USD";
                    result.SettleDelay = 1;
                    break;
                case BondAnalytics.Country.BE:
                case BondAnalytics.Country.DE:
                case BondAnalytics.Country.ES:
                case BondAnalytics.Country.FR:
                case BondAnalytics.Country.IT:
                    result.Ccy = "EUR";
                    result.CpnFreq = (eCountry == BondAnalytics.Country.IT ? 6 : 12);
                    result.SettleDelay = 2;
                    break;
                case BondAnalytics.Country.UK:
                    result.Ccy = "GBP";
                    result.SettleDelay = 1;
                    break;
                case BondAnalytics.Country.CA:
                    result.Ccy = "CAD";
                    result.SettleDelay = 1;
                    break;
                case BondAnalytics.Country.JP:
                    result.Ccy = "JPY";
                    result.SettleDelay = 2;
                    break;
            }

            return result;

        }
Ejemplo n.º 8
0
        private static AnalyticsBondStaticData ConvertCarbonBondToAnalyticsBondStaticData(CarbonBond bond)
        {
            var result = new AnalyticsBondStaticData
            {
                Id = bond.Isin,
                MaturityDate = bond.Maturity.ToDateTime(),
                EffectiveDate = bond.EffectiveDate.HasValue ? bond.EffectiveDate.Value.ToDateTime() : default(DateTime),
                FirstCouponDate = bond.FirstCouponDate.HasValue ? bond.FirstCouponDate.Value.ToDateTime() : default(DateTime),
                Coupon = bond.Coupon ?? default(double)
            };

            var latestEffectiveDate = result.EffectiveDate;

            if (bond.Auctions != null && bond.Auctions.Count > 0)
            {
                var effectiveDates =
                    bond.Auctions.Where(a => a.EffectiveDate.HasValue)
                        .Select(a => a.EffectiveDate.Value.ToDateTime())
                        .ToList();
                if (effectiveDates.Count > 0)
                {
                    latestEffectiveDate = effectiveDates.Max();
                }
            }
            return DecorateAnalyticsBondStaticData(result, latestEffectiveDate);
        }
Ejemplo n.º 9
0
        //------------------------------------------------------------------------------------------------
        public double calcFuturesMeasure(string measure, string identifier, double price, DateTime asofDate,
            Tuple<DateTime, double> previous = null)
        //------------------------------------------------------------------------------------------------
        {
            // Get conventions
            var staticRow = CombinedStatic.Rows.TryGet(identifier).ValueOrDefault;

            //staticRow.Print();

            if (staticRow == null) return double.NaN;

            // Setup Params
            DateTime FwdDate = staticRow.GetAs<DateTime>("fut_dlv_dt_last");

            // Bond static
            var bondstatic = new AnalyticsBondStaticData();
            bondstatic.EffectiveDate = TimeSeriesUtilities.LazySafeTryGetAs(staticRow, "EffectiveDate", DateTime.MinValue);  //staticRow.TryGetAs<DateTime>("EffectiveDate")      .OrDefault(DateTime.MinValue);
            bondstatic.FirstCouponDate = TimeSeriesUtilities.LazySafeTryGetAs(staticRow, "FirstCouponDate", DateTime.MinValue); //staticRow.TryGetAs<DateTime>("FirstCouponDate", ConversionKind.Exact).ValueOrDefault;
            bondstatic.MaturityDate = TimeSeriesUtilities.LazySafeTryGetAs(staticRow, "Maturity", DateTime.MinValue); //staticRow.TryGetAs<DateTime>("Maturity").OrDefault(DateTime.MinValue);
            bondstatic.Coupon = staticRow.GetAs<double>("Coupon");
            bondstatic.Country = Conv_.Country;
            bondstatic.Id = identifier;
            bondstatic.CpnFreq = Conv_.BondCouponFrequency;

            // Prices - adjusted into forward prices
            double convFactor = staticRow.TryGetAs<double>("fut_cnvs_factor").OrDefault(double.NaN);
            double fwdPrice = convFactor * price;
            var previousFwd = previous == null
                ? null
                : new Tuple<DateTime, double>(previous.Item1, convFactor*previous.Item2); 

            // Main loop
            if (measure == "Price") return price;

            double metric = MeasureCalculator.calcFwdBondMeasure(measure, bondstatic, fwdPrice, asofDate, FwdDate, Conv_,
                ForecastCurves, DiscountCurves, Holidays_, previousFwd);
            
            return metric;
        }