Exemple #1
0
    private async Task populateDates(CarbonClient cc_)
    {
      var yesterday = await cc_.RollDateAsync(
  date: DateTime.Today.ToNodaLocalDate(),
  count: -1,
  unit: Symmetry.Carbon.Model.DateUnit.Bd,
  convention: Symmetry.Carbon.Model.BusinessDayConvention.Following,
  calendar: Market.HolidayCode());

      var spotSettle = await cc_.RollDateAsync(
  date: DateTime.Today.ToNodaLocalDate(),
  count: Market.DaysToSpot(),
  unit: Symmetry.Carbon.Model.DateUnit.Bd,
  convention: Symmetry.Carbon.Model.BusinessDayConvention.Following,
  calendar: Market.HolidayCode());

      var yesterdaySettle = await cc_.RollDateAsync(
        date: yesterday,
        count: Market.DaysToSpot(),
        unit: Symmetry.Carbon.Model.DateUnit.Bd,
        convention: Symmetry.Carbon.Model.BusinessDayConvention.Following,
        calendar: Market.HolidayCode());


      Today = new AsOfAndSpotSettle(DateTime.Today, spotSettle.ToDateTime());
      Yesterday = new AsOfAndSpotSettle(yesterday.ToDateTime(), yesterdaySettle.ToDateTime());


    }
Exemple #2
0
    private static DateTime Roll(DateTime date_, int units_, DateUnit unit_, BusinessDayConvention convention_, string otCalendar_, CarbonClient client_, ThrowBehavior behavior_=ThrowBehavior.DontThrow)
    {
      try
      {
        string key = getKey(date_, units_, unit_, convention_, otCalendar_);

        if (_cache.ContainsKey(key))
          return _cache[key];

        var result = client_.RollDateAsync(date_.ToNodaLocalDate(), units_, unit_, convention_, otCalendar_).Result.ToDateTime();

        _cache[key] = result;

        return result;
      }
      catch (Exception ex_)
      {
        Exceptions.Rethrow("Error rolling date", behavior_, ex_);
      }
      return DateTime.MinValue;
    }
Exemple #3
0
    protected void getCalcs()
    {
      var conf = CountryConfig.GetCountryConfig(Market);

      if (Values == null)
        Values =
          new ConstructGen<double>(
            ((ColPosition[]) Enum.GetValues(typeof (ColPosition))).Select(x => x.ToString()).ToArray());

      var crv = Singleton<CMTCurveCache>.Instance.Get(
        market_: Market,
        series_: CMTSeriesNumber,
        curve_: conf.OISCurve,
        focus_: Focus.ASW,
        createIfNotThere_: true);

      if (crv == null || crv.Data == null) return;

      // need to find the indexof of the tenor points in the data construct
      int pointIndex = -1;

      for (int i = 0; i < crv.Data.ArrayLength && (pointIndex == -1); ++i)
      {
        var asDbl = double.Parse(crv.Data.ColumnHeadings[i]);

        if (Math.Abs(asDbl - Tenor) < 1e-7)
          pointIndex = i;
      }

      var startDate = new DateTime(2010, 1, 1);


      Values.SetColumnValues((int)ColPosition.CMT_OIS, crv.Data.GetColumnValuesAsDDC(pointIndex).GetValuesBetweenDates(startDate, DateTime.Today).MultiplyBy(-100d));
      Values.SetColumnValues((int)ColPosition.GC, BbgTalk.HistoryRequester.GetHistory(startDate, conf.CollateralTicker, "PX_LAST", false));
      Values.SetColumnValues((int)ColPosition.OIS, BbgTalk.HistoryRequester.GetHistory(startDate, conf.OISTicker, "PX_LAST", false));

      Values.SortKeys();

      using (var cc = new CarbonClient("PRD"))
      {
        var fillCols = new[] { ColPosition.CMT_OIS, ColPosition.GC, ColPosition.OIS };

        for (int i = 0; i < Values.Dates.Count; ++i)
        {
          var date = Values.Dates[i];
          var vals = Values.GetValues(Values.Dates[i]);

          // fill in zeros as unlikely all series will line up
          if (i > 0)
          {
            foreach (var col in fillCols)
            {
              if (vals[(int)col].IsZero())
                vals[(int)col] = Values.GetValues(Values.Dates[i - 1])[(int)col];
            }
          }

          vals[(int)ColPosition.GCminusOIS] = vals[(int)ColPosition.GC] - vals[(int)ColPosition.OIS];


          bool needToMakeCall = true;

          {
            var currentValue = Values.GetValue(date.Date, (int) ColPosition.SwapValue);
            if (!currentValue.IsZero())
              needToMakeCall = false;
          }

          if (needToMakeCall)
          {
            Logger.Info(string.Format("Making calls for {0}.{1}.{2} carry calc on {3}",Market,Tenor,CMTSeriesNumber, date.ToString("dd-MMM-yyyy")),
              typeof(CMTCarry));


            var settleDate = cc.RollDateAsync(date.ToNodaLocalDate(), 2, Symmetry.Carbon.Model.DateUnit.Bd,
              Symmetry.Carbon.Model.BusinessDayConvention.Following, conf.HolidayCalendar).Result;

            var swapDate =
              cc.RollDateAsync(settleDate, Tenor, Symmetry.Carbon.Model.DateUnit.Y,
                Symmetry.Carbon.Model.BusinessDayConvention.Following, conf.HolidayCalendar).Result;

            var swapResult = cc.PriceSwapAsync(
              curveName: conf.OTSwapName,
              startDate: settleDate,
              endDate: swapDate,
              asof: date.Date.AddHours(23),
              pricingSetup: "Symmetry").Result;

            if (swapResult == null) continue;

            foreach (var v in swapResult.Results)
            {
              switch (v.Key)
              {
                case "BreakEven Rate":
                  vals[(int)ColPosition.SwapValue] = v.Value;
                  break;
                case "PV01":
                  vals[(int)ColPosition.SwapDuration] = v.Value;
                  break;
              }
            }
            m_changed = true;
          }
        }

        if (Values.NeedsToSortKeys())
          Values.SortKeys();
        // 20 day moving average of difference
        {
          var series = Values.GetColumnValuesAsDDC((int)ColPosition.GCminusOIS);
          Values.SetColumnValues((int)ColPosition.GCminusOIS_MA20, HelperMethods.GetMA(series, 20));
        }

        // calculate carry
        {
          var mustNotBeZero = new[]
          {
            ColPosition.CMT_OIS,
            ColPosition.GCminusOIS_MA20,
            ColPosition.SwapDuration
          };

          foreach (var date in Values.Dates)
          {
            var series = Values.GetValues(date);

            foreach(var col in mustNotBeZero)
              if (series[(int) col].IsZero())
                continue;

            series[(int) ColPosition.Carry] = (series[(int) ColPosition.CMT_OIS] - series[(int) ColPosition.GCminusOIS_MA20])/
                                         series[(int) ColPosition.SwapDuration]*10000d;
          }
        }
      }
    }
    public static DateTime RollDate(CarbonClient client_, DateTime date_, int units_, DateUnit unit_, BusinessDayConvention conv_, string calendar_)
    {
      var key = getDateKey(date_, units_, unit_, conv_, calendar_);

      if (_dateCache.ContainsKey(key))
        return _dateCache[key];

      var date = client_.RollDateAsync(
        date: DateConversions.ToNodaLocalDate(date_.Date),
        count: units_,
        unit: unit_,
        convention: conv_,
        calendar: calendar_).Result;

      _dateCache[key] = date.ToDateTime();

      return _dateCache[key];
    }
    /// <summary>
    /// Calculate the bondspreads for the given bond over the given swap curve
    /// </summary>
    /// <param name="bond_"></param>
    /// <param name="priceType_">either yield or price</param>
    /// <param name="priceValue_">if price, then pass 100.3 rather than 1.003</param>
    /// <param name="curveType_">the swap curve</param>
    /// <param name="country_">JB's country definitions</param>
    /// <param name="asOf_">the date of the price. will determine the date of the curves that are used</param>
    /// <param name="client_">carbon client to get holidays</param>
    /// <param name="quoteSource_">mlp/sym</param>
    /// <param name="snapCode_">mlp/nyk/ldn</param>
    /// <param name="behavior_">whether you want exceptions to be swallowed or not</param>
    /// <returns></returns>
    public static async Task<BondSpreadResult> GetSpreads(
      Symmetry.Data.FIBond bond_, 
      QuoteValueType priceType_, 
      double priceValue_, 
      SwapCurveType curveType_,
      BondAnalytics.Country country_,
      DateTime asOf_, 
      CarbonClient client_,
      string quoteSource_,
      string snapCode_,
      ThrowBehavior behavior_ = ThrowBehavior.DontThrow)
    {
      try
      {
        var mapping = CurveMappings.GetMapping(curveType_);

        var settleDate = await client_.RollDateAsync(
          date: asOf_.Date.ToNodaLocalDate(),
          count: country_.SettleDateDays(),
          unit: DateUnit.Bd,
          convention: BusinessDayConvention.Following,
          calendar: country_.OTHolidayCode());

        var holidays = CalendarRetriever.GetCalendar(country_.OTHolidayCode(), client_).ToList();

        var startDate = bond_.EffectiveDate.Value;

        var firstCpnDate = bond_.Coupon==0 ? bond_.IssueDate.Value : bond_.FirstCouponDate.Value;

        var maturity = bond_.FI.Maturity;

        var coupon = Convert.ToDouble(bond_.Coupon);

        // get the persisted discount curves for the fixed and floating legs
        var discCurve = SObjectManager.Instance().LoadSObject<DiscountCurve>(new Moniker()
        {
          Close = snapCode_,
          Source = quoteSource_,
          Name = KnownCurveHelpers.GetKnownCurveCode(mapping.DiscountCurve),
          Type = "discountcurve",
          Date = asOf_.Date
        });

        if (discCurve == null)
        {
          SLog.log.ErrorFormat("Could not load {0} discount curve from database for {1}", mapping.DiscountCurve, asOf_.Date);
          return null;
        }

        var fcstCurve = SObjectManager.Instance().LoadSObject<DiscountCurve>(new Moniker()
        {
          Close = snapCode_,
          Source = quoteSource_,
          Name = KnownCurveHelpers.GetKnownCurveCode(mapping.ForecastCurve),
          Type = "discountcurve",
          Date = asOf_.Date
        });

        if (fcstCurve == null)
        {
          SLog.log.ErrorFormat("Could not load {0} discount curve from database for {1}", mapping.ForecastCurve, asOf_.Date);
          return null;
        }

        double price=0, yield=0;

        switch (priceType_)
        {
          case QuoteValueType.Price:
            price = priceValue_;

            yield = BondAnalytics.SolveYield(
              country: country_,
              settleDate: settleDate.ToDateTime(),
              cleanPrice: price,
              startDate: startDate,
              firstCpnDate: firstCpnDate,
              maturityDate: maturity.Value,
              coupon: coupon,
              freq: country_.BondFreq())[0];

            break;
          case QuoteValueType.Yield:
            yield = priceValue_;
            price = BondAnalytics.PriceFromYield(
              country: country_,
              settleDate: settleDate.ToDateTime(),
              yield: priceValue_,
              startDate: startDate,
              firstCpnDate: firstCpnDate,
              maturityDate: maturity.Value,
              coupon: coupon,
              freq: country_.BondFreq())[0];
              break;
        }

        var mms = BondAnalytics.CalcMMS(
          startDate: settleDate.ToDateTime(),
          maturityDate: maturity.Value,
          dctType: mapping.DayCountType,
          fixedFreq: (long) mapping.FixedFreq,
          floatFreq: (long) mapping.FloatFreq,
          discCurveDates: discCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(),
          discDfs: discCurve.AsDoubleArray().SliceColumn(1),
          fcstCurveDates: fcstCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(),
          fcstDfs: fcstCurve.AsDoubleArray().SliceColumn(1),
          holidays: holidays,
          stubExpiries: null,
          stubTenors: null,
          stubValues: null,
          fixingTenors: null,
          fixings: null,
          firstCpnDate: firstCpnDate
          );

        var truespread = BondAnalytics.SolveZSpread(
          country: country_,
          settleDate: settleDate.ToDateTime(),
          cleanPrice: price,
          startDate: startDate,
          firstCpnDate: firstCpnDate,
          maturityDate: maturity.Value,
          coupon: coupon,
          freq: country_.BondFreq(),
          curveDates: fcstCurve.AsDoubleArray().SliceColumn(0).Select(DateTime.FromOADate).ToArray(),
          dfs: fcstCurve.AsDoubleArray().SliceColumn(1),
          holidays: holidays);

        return new BondSpreadResult
        {
          Price = price,
          Spreads = new BondSpread
          {
            Yield=yield,
            MMS=mms,
            TrueSpread=truespread * -1d,
            Spread = mms-yield,
          }
        };
      }
      catch (Exception ex_)
      {
        Exceptions.Rethrow("Error calculating bondspread", behavior_, ex_);
        return null;
      }
    }
      private async Task<TenorDates> GoDate(DateTime date_, TenorDates record, CarbonClient cc_, bool force_ = true, bool persistToServer_ = true)
      {
        if (record == null)
          throw new ArgumentNullException("record");

        if (record != null && record.Dates != null && record.Dates.HasKey(date_) && !force_)
          return record;

        Logger.Info(
          string.Format("Generating tenor Dates for [Cal={0}, SpotDays={1}, Date={2}]", record.HolidayCode,
            record.SpotStart,
            date_.ToString("dd-MMM-yyyy")), typeof(DatesWorker));

        var allTenors = (CurveDateIndex[])Enum.GetValues(typeof(CurveDateIndex));

        if (record.Dates == null) // this shouldnt' happen
          record.Dates = new ConstructGenGen<DateTime, DateTime>(allTenors.Select(x => x.ToString()).ToArray());

        // need to get the spot date first as all other dates are calculated off this

        var spot = await cc_.RollDateAsync(
          date: date_.ToNodaLocalDate(),
          count: record.SpotStart,
          unit: Symmetry.Carbon.Model.DateUnit.Bd,
          convention: Symmetry.Carbon.Model.BusinessDayConvention.Following,
          calendar: record.HolidayCode);

        record.Dates.SetValue(date_, (int)CurveDateIndex.Spot, spot.ToDateTime());


        // then work out each tenor date and store in record

        foreach (var tenor in allTenors.Where(x => x != CurveDateIndex.Spot))
        {
          var fwdDate = spot.ToDateTime().AddYears((int) tenor);

          //var fwdDate = await cc_.RollDateAsync(
          //  date: spot,
          //  count: (int)tenor,
          //  unit: Symmetry.Carbon.Model.DateUnit.Y,
          //  convention: Symmetry.Carbon.Model.BusinessDayConvention.Following,
          //  calendar: record.HolidayCode);

          record.Dates.SetValue(date_, (int)tenor, fwdDate);
        }

        if (persistToServer_)
          await TenorDatesCache.Instance().AddOrUpdateDefinition(record);

        return record;
      }
      public async Task<TenorDates> GoAll(string otHolidayCode_, int daysToSpot_, CarbonClient cc_, bool force_ = false)
      {
        var date = START_DATE;

        var record =
          TenorDatesCache.Instance()
            .InnerList.FirstOrDefault(
              x =>
                x.SpotStart == daysToSpot_ &&
                string.Compare(otHolidayCode_, x.HolidayCode, StringComparison.OrdinalIgnoreCase) == 0);

        var allTenors = (CurveDateIndex[])Enum.GetValues(typeof(CurveDateIndex));

        var updated = false;

        if (record == null)
        {
          record = new TenorDates()
          {
            HolidayCode = otHolidayCode_,
            SpotStart = daysToSpot_,
            Dates =
              new ConstructGenGen<DateTime, DateTime>(allTenors.Select(x => x.ToString()).ToArray())
          };
          record.Dates.Name = string.Format("{0} tenor dates with spotStart={1}", otHolidayCode_, daysToSpot_);
        }
        else
        {
          // if we're not forcing a rebuild, then we can move the date to the last date in the series
          if(!force_)
            date = record.Dates.Keys.Last();
        }

        while (date < END_DATE)
        {
          updated = true;
          await GoDate(
            date_: date,
            record: record,
            cc_: cc_,
            force_: force_,
            persistToServer_: false);

          var plusOne = await cc_.RollDateAsync(date.ToNodaLocalDate(), 1, Symmetry.Carbon.Model.DateUnit.Bd,
                Symmetry.Carbon.Model.BusinessDayConvention.Following, otHolidayCode_);

          date = plusOne.ToDateTime();
        }

        try
        {
          if (updated)
          {
            var result = await TenorDatesCache.Instance().AddOrUpdateDefinition(record);
            Logger.Info(
              string.Format("Updated cache for {0} with {1}. Result = {2}", otHolidayCode_, daysToSpot_, result),
              typeof(DatesWorker));
          }
          else
          {
            Logger.Info(
              string.Format("Not updating dates cache {0}.{1} as already up to date", otHolidayCode_, daysToSpot_),
              typeof (DatesWorker));
          }
        }
        catch (Exception ex_)
        {
          Logger.Error("Error updating cache", typeof(DatesWorker), ex_);
        }

        return record;
      }