protected RateCurveBase(
      string name_,
      CurveIDs forecastCurve_,
      CurveIDs discountCurve_,
      string otHolidayCode_,
      int daysToSpot_,
      int maxTenor_,
      long fixedFreq_,
      long floatFreq_,
      BondAnalytics.DayCountType fixedDC_,
      BondAnalytics.DayCountType floatDC_
      )
    {
      CurveName = name_;

      OTHolidayCode = otHolidayCode_;

      ForecastCurve = forecastCurve_;
      DiscountCurve = discountCurve_;

      DaysToSpot = daysToSpot_;
      MaxTenor = maxTenor_;

      FixedFreq = fixedFreq_;
      FloatFreq = floatFreq_;

      FixedDayCount = fixedDC_;
      FloatDayCount = floatDC_;
    }
      public async Task<DFs> BackFillFromSymmetryTS(string holidayCode_, int spotStart_, CurveIDs curve_)
      {
        if (string.IsNullOrEmpty(curve_.SymmetryTSName))
        {
          Logger.Error(string.Format("Cannot backfill {0} as SymmetryTS moniker name not set", curve_.CarbonCurveName),
            typeof (DFsWorker));
          return null;
        }
        else
          Logger.Info(string.Format("Backfilling {0} using symmetryTS discount curves", curve_.CarbonCurveName),
            typeof (DFsWorker));

        // first we need to get the list of dates for the given holidaycode
        var datesRecord =
          TenorDatesCache.Instance()
            .InnerList.FirstOrDefault(
              x =>
                x.SpotStart == spotStart_ &&
                string.Compare(holidayCode_, x.HolidayCode, StringComparison.OrdinalIgnoreCase) == 0);

        if (datesRecord == null)
        {
          Logger.Error(
            string.Format("cannot update DFs as can't find a calendar object with params [spotStart={0},Calendar={1}]",
              spotStart_, holidayCode_), typeof(DFsWorker));
          return null;
        }

        var record = DFsCache.Instance().InnerList.FirstOrDefault(x =>
          String.Compare(x.Curvename, curve_.CarbonCurveName, StringComparison.OrdinalIgnoreCase) == 0);

        // if we haven't got a current record, then nothing to 'backfill' as such, so just exit
        if(record==null)
        {
          Logger.Info(string.Format("Could not find a document to update for {0}", curve_.CarbonCurveName),
            typeof (DFsWorker));
          return null;
        }

        var updated = false;
        var firstDateForWhichWeHaveDFs = record.DFValues.FirstDate;

        for (int i = 0; i < datesRecord.Dates.Keys.Count && datesRecord.Dates.Keys[i] < DateTime.Today; ++i)
        {
          var date = datesRecord.Dates.Keys[i];

          var df = SObjectManager.Instance().LoadSObject<DiscountCurve>(new Moniker()
          {
            Close="mlp",
            Source="mlp",
            Name=curve_.SymmetryTSName.ToLower(),
            Type="discountcurve",
            Date=date
          });

          if (df == null)
          {
            Logger.Error(
              string.Format("Cannot get discount curve for {0} for date {1}", curve_.SymmetryTSName,
                date.ToString("dd-MMM-yyyy")), typeof(DFsWorker));
            continue;
          }
          else
          {
            Logger.Info(
              string.Format("Pulled DFs for {0} on {1}", curve_.CarbonCurveName, date.ToString("dd-MMM-yyyy")),
              typeof (DFsWorker));
          }

          var dbls = df.AsDoubleArray();

          var dates = dbls.SliceColumn(0).Select(x => DateTime.FromOADate(x)).ToList();
          var values = dbls.SliceColumn(1).ToList();

          // ensure first date is in place with value = 1d
          if (dates.Count>0 && dates.First() > date)
          {
            dates.Insert(0, date);
            values.Insert(0, 1d);
          }

          updated = true;
          record.DFValues.SetValueOnDate(date, new DatedDataCollectionGen<double>(dates.ToArray(), values.ToArray()));
        }

        if (updated)
        {
          Logger.Info(string.Format("Writing {0} DFs to mongo...", curve_.CarbonCurveName), typeof (DFsWorker));
          await DFsCache.Instance().AddOrUpdateDefinition(record);
        }

        return record;
      }
      public async Task<DFs> GoAll(string holidayCode_, int spotStart_, CurveIDs curve_, CarbonClient cc_, bool forceReRead_=false)
      {
        Logger.Info(string.Format("Considering {0} DFs...", curve_.CarbonCurveName), typeof (DFsWorker));

        // first we need to get the list of dates for the given holidaycode
        var datesRecord =
          TenorDatesCache.Instance()
            .InnerList.FirstOrDefault(
              x =>
                x.SpotStart == spotStart_ &&
                string.Compare(holidayCode_, x.HolidayCode, StringComparison.OrdinalIgnoreCase) == 0);

        if (datesRecord == null)
        {
          Logger.Error(
            string.Format("cannot update DFs as can't find a calendar object with params [spotStart={0},Calendar={1}]",
              spotStart_, holidayCode_), typeof (DFsWorker));
          return null;
        }

        var taDFs = DFsCache.Instance().InnerList.FirstOrDefault(x =>
          String.Compare(x.Curvename, curve_.CarbonCurveName, StringComparison.OrdinalIgnoreCase) == 0);

        if (taDFs == null)
        {
          taDFs = new DFs()
          {
            Curvename=curve_.CarbonCurveName,
          };
        }

        var carbonDFs = await CarbonCurveRetriever.Instance().GetDailyCurveDFs(cc_, datesRecord, curve_.CarbonCurveName);

        if (carbonDFs == null)
        {
          Logger.Error(string.Format("Did not successfully retrieve DFs for {0} from carbon", curve_.CarbonCurveName),
            typeof (DFsWorker));
          return null;
        }

        bool updated = false;

        if (taDFs.DFValues == null || forceReRead_)
        {
          updated = true;
          taDFs.DFValues = carbonDFs;
        }
        else
        {
          foreach (var date in carbonDFs.Dates)
          {
            bool needToSet = !taDFs.DFValues.HasDate(date);

            if (!needToSet && date>DateTime.Today.AddMonths(-1))
            {
              needToSet = true;

              var current = taDFs.DFValues.ValueOnExactDate(date);
              var carbon = carbonDFs.ValueOnExactDate(date);

              if (current!=null && carbon!=null && current.Data!=null && carbon.Data!=null && (current.Data.Sum() - carbon.Data.Sum()).IsZero())
              {
                needToSet = false;
              }
              else
                Logger.Debug(
                  string.Format("Going to update dfs for {0} on {1}", curve_.CarbonCurveName, date.ToString("dd-MMM-yyyy")),
                  typeof(DFsWorker));
            }

            if (!needToSet) continue;

            Logger.Debug(
              string.Format("Adding in dfs for {0} on {1}", curve_.CarbonCurveName, date.ToString("dd-MMM-yyyy")),
              typeof (DFsWorker));
            updated = true;
            taDFs.DFValues.SetValueOnDate(date, carbonDFs.ValueOnDate(date));
          }
        }

        // persist the fixings if the curve has details

        if (!string.IsNullOrEmpty(curve_.CurveFixingTicker))
        {
          var pxs = new SymmetryTSInstrument(curve_.CurveFixingTicker).GetPrices();

          if (pxs != null)
          {
            if (taDFs.FixingValues == null ||
              (taDFs.FixingValues.LastDate < pxs.LastDate))
            {
              taDFs.FixingValues = pxs.GetValuesBetweenDates(datesRecord.Dates.Keys[0],DateTime.Today);
              updated = true;
            }
          }
        }


        if (updated)
        {
          var result = await DFsCache.Instance().AddOrUpdateDefinition(taDFs);
          Logger.Info(string.Format("Updated DFs on server for {0}. Result = {1}", curve_.CarbonCurveName, result),
            typeof (DFsWorker));
        }
        else
          Logger.Info(string.Format("Not updating {0} DFs as nothing changed", curve_.CarbonCurveName),
            typeof(DFsWorker));



        return taDFs;
      }