Пример #1
1
      public static void DeMarkSetupForChart(UltraChart chart, ConstructGen<double> candleData_, bool isDateChart, int openIndex_=0, int highIndex_=1, int lowIndex_=2, int closeIndex_=3,
                                                                            int setupLength_=9, int countdownLength_=13)
      {
          var closes = candleData_.GetColumnValuesAsDDC(closeIndex_);
          var range = closes.Data.Max() - closes.Data.Min();
          var cellHeight = range / 10d;



          var setupStarts = Analysis.GetSetups(candleData_, openIndex_, highIndex_, lowIndex_, closeIndex_, setupLength_);
          Analysis.AddCountdowns(candleData_, setupStarts, openIndex_, highIndex_, lowIndex_, closeIndex_, setupLength_, countdownLength_);

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

              var arr = candleData_.GetValues(date);
              //dt.LoadDataRow(new object[]
              //{
              //    date,
              //    arr[openIndex_],
              //    arr[highIndex_],
              //    arr[lowIndex_],
              //    arr[closeIndex_],
              //    0d
              //}, true);

              foreach (var mark in setupStarts)
              {
                  addAnnotations(chart, date, mark, i, cellHeight, arr, openIndex_, highIndex_, lowIndex_, closeIndex_);
              }
          }
      }
Пример #2
0
    public override void Create(ConstructGen<double> wts_, ConstructGen<double> c2v_, ConstructGen<double> perf_)
    {
      base.Create(wts_, c2v_, perf_);

      if(RegionBreakdown!=null && RegionBreakdown.Count>0)
        foreach (WtsAnalyzerFXGroup wa in RegionBreakdown)
          wa.Create(wts_, c2v_,perf_);

      NumRebals = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), ExtensionMethods.GenerateArrayAllOfValue<double>(1d, wts_.Dates.Count)), DataEncapsDispValueType.Sum, "NumRebals");
      Sharpe = (Statistics.Average(base.Return.Data.Data) * 252d) / (Statistics.Stdev(base.Return.Data.Data) * Math.Sqrt(252d));

      ConstructGen<double> ccyTCosts = getTCostForDates(wts_.Dates);
      double[] tCcosts = new double[wts_.Dates.Count];

      if (false)
      {
        int[] ndfIndincies =
          Singleton<FXIDs>.Instance.Where<Currency>(x => x.IsGroup(FXGroup.NDF))
            .Select<Currency, int>(x => x.ArrayIndex)
            .ToArray<int>();

        DatedDataCollectionGen<double> adjReturn = (DatedDataCollectionGen<double>) Return.Data.Clone();

        for (int i = 0; i < wts_.Dates.Count; ++i)
        {
          int indexOfReturn = adjReturn.IndexOf(wts_.Dates[i]);
          double dayAdj = 0d;

          double[] wtsToday = wts_.GetValues(wts_.Dates[i]);
          if (i == 0)
          {
            foreach (int ndfIndex in ndfIndincies)
              dayAdj += -Math.Abs(wtsToday[ndfIndex]*ccyTCosts.GetValue(wts_.Dates[i], ndfIndex));
          }
          else
          {
            double[] wtsYest = wts_.GetValues(wts_.Dates[i - 1]);

            foreach (int ndfIndex in ndfIndincies)
              dayAdj += -Math.Abs((wtsToday[ndfIndex] - wtsYest[ndfIndex])*ccyTCosts.GetValue(wts_.Dates[i], ndfIndex));
          }

          tCcosts[i] += dayAdj;

          if (indexOfReturn != -1)
            adjReturn.Data[indexOfReturn] += dayAdj;
        }
      }

      NDF_TCost = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray(), tCcosts), DataEncapsDispValueType.Sum, "NDF_TCosts");
      NetReturn = new DataEncapsValue(Return.Data,DataEncapsDispValueType.Sum, "AdjReturn");
    }
Пример #3
0
    public virtual void Create(ConstructGen<double> wts_, ConstructGen<double> c2v_, ConstructGen<double> perf_)
    {
      double[] dollWts = new double[wts_.Dates.Count];
      double[] turnover = new double[wts_.Dates.Count];
      double[] flow = new double[wts_.Dates.Count];
      double[] leverage = new double[wts_.Dates.Count];

      for(int i=0;i<wts_.Dates.Count;++i)
      {
        double[] todayWts = wts_.GetValues(wts_.Dates[i]);
        dollWts[i]=Statistics.Sum(todayWts);
        leverage[i] = Statistics.SumAbs(todayWts);

        if(i==0)
        {
          turnover[i] = flow[i]=dollWts[i];
        }
        else
        {
          double[] prevWts = wts_.GetValues(wts_.Dates[i-1]);

          double t = 0d;
          double f = 0d;

          for (int j = 0; j < prevWts.Length; ++j)
          {
            if (todayWts[j] == prevWts[j] && todayWts[j] == 0d) continue;
            t += prevWts[j]==0d ? todayWts[j] : Math.Abs((todayWts[j] - prevWts[j]) / prevWts[j]);
            f += Math.Abs(todayWts[j] - prevWts[j]);
          }

          flow[i] = f;
          turnover[i] = t;
        }
      }

      SumWt = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), dollWts),"SumWt");
      Turnover = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), turnover),"Turnover");
      Flow = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), flow),"Flow");
      Leverage = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), leverage),"Leverage");
      //C2V = new DataEncapsValue(new DatedDataCollectionGen<double>(wts_.Dates.ToArray<DateTime>(), ExtensionMethods.GenerateArrayAllOfValue<double>(1d, wts_.Dates.Count)),"C2V");

      double[] perf = new double[perf_.Dates.Count];
      for (int i = 0; i < perf_.Dates.Count; ++i)
        perf[i] = Statistics.Sum(perf_.GetValues(perf_.Dates[i]));
      Return = new DataEncapsValue(new DatedDataCollectionGen<double>(perf_.Dates.ToArray<DateTime>(), perf),DataEncapsDispValueType.Sum,"Return");

    }
Пример #4
0
    private ConstructGen<double> getConstructOfInvoiceSpreads()
    {
      var con = new ConstructGen<double>(Configs.Length);

      for (int i = 0; i < con.ArrayLength; ++i)
      {
        for (int j = 0; j < Collections[i].Lines.Count; ++j)
        {
          var date = Collections[i].Lines[j].Date;
          var val = Collections[i].Lines[j].InvoiceSpread;

          con.SetValue(date, i, val ?? double.PositiveInfinity);
        }
      }

      con.SortKeys();

      // feed forward missing values

      double[] before = null;

      foreach (var date in con.Dates)
      {
        var today = con.GetValues(date);
        if (before != null)
        {
          for(int i=0;i<today.Length;++i)
            if (double.IsInfinity(today[i]))
              today[i] = before[i];
        }
        before = today;
      }

      return con;
    }
Пример #5
0
    public void Create(ConstructGen<double> con_)
    {
      setupDataTable();

      double cumulative = 0d;

      foreach (var date in con_.Dates)
      {
        var values = con_.GetValues(date);

        var wt = values[(int)Headings.Weight];

        var dailyPnl = values[(int)Headings.Pnl];

        cumulative += dailyPnl;

        dt.LoadDataRow(new object[] 
        {
          date,
          cumulative,
          values[(int)Headings.Spot],
          wt > 0d ? wt : 0d,
          wt < 0d ? wt : 0d
          }, true);
      }

      m_con = con_;
    }
    public override void DoWeights(ConstructGen<double> signalResults_, ConstructGen<double> fullSignalResults_, ConstructGen<double> wts_, List<ProductBase> products_, ConstructGen<double> filters_)
    {
      double[] sigToday = new double[products_.Count];

      foreach (DateTime date in signalResults_.Dates)
      {
        double[] filterToday = filters_.GetValues(date);
        int productValidCount = 0;
        double sum = 0;

        for (int i = 0; i < sigToday.Length; ++i)
        {
          sigToday[i] = signalResults_.GetValue(date, i);
          if (double.IsNaN(filterToday[i]) == false && double.IsNaN(sigToday[i]) == false)
          {
            ++productValidCount;
            sum += sigToday[i];
          }
        }

        var avg = sum / Convert.ToDouble(productValidCount);

        for (int i = 0; i < sigToday.Length; ++i)
        {
          if (double.IsNaN(filterToday[i]) == false && double.IsNaN(sigToday[i]) == false)
            wts_.MultValue(date, i, sigToday[i] - avg);
        }
      }
    }
Пример #7
0
    public static ConstructGen<double> DoScaleWeights(ConstructGen<double> wts_, TraderArgs args_, Func<DateTime,double> getVolTargetForDate_)
    {
      if (wts_.ColumnHeadings == null)
        wts_.ColumnHeadings = args_.Products.Select(x => x.Name).ToArray();

      var logReturns = args_.AllProductPrices(fillInGapsWithPrevious_: true).ToLogReturns(
        args_.Products.Select(x => x.Convention).ToArray());

      var scaledWts = new ConstructGen<double>(wts_.ColumnHeadings);

      foreach (var date in wts_.Dates)
      {
        var wtArr = wts_.GetValues(date);

        for (int i = 0; i < wtArr.Length; ++i)
          if (double.IsInfinity(wtArr[i]))
            wtArr[i] = 0d;

        int indexOfDate = logReturns.FindIndexOfEffectiveDateOnDate(date);

        indexOfDate = (indexOfDate < 252) ? 252 : indexOfDate - 1; // note offset

        var subValues = logReturns.GetSubValues(logReturns.Dates[indexOfDate - 251], logReturns.Dates[indexOfDate]);

        var covArr = SI.Data.FXHistCovar.MatCovar(subValues.ToArray());

        var cov = new CovarianceItem(covArr);

        scaledWts.SetValues(date, cov.ScaleSeries(wtArr, getVolTargetForDate_(date)));
      }

      return scaledWts;
    }
Пример #8
0
    public void Refresh()
    {
      // going to get historical values from our database
      ConstructGen<double> hist = new ConstructGen<double>(m_tickers.Count<string>());

      for (int i = 0; i < m_tickers.Length; ++i)
      {
        var histvalues = BbgTalk.HistoryRequester.GetHistory(SI.Data.DataConstants.DATA_START, m_tickers[i],
          "PX_LAST", false, null);

        //histvalues = histvalues.unwind_1d();

        hist.SetColumnValues(i, histvalues);
      }

      hist.SortKeys();

      // initialise 'today's' values to previous day
      hist.SetValues(DateTime.Today, (double[])hist.GetValues(hist.LastDate).Clone());

      double[] avgs = new double[m_windowLength];

      // initialise the avgs array NOTE: today's value is in item with index 0
      for (int i = 0; i < m_windowLength; ++i)
        avgs[i] = hist.GetValues(hist.Dates[hist.Dates.Count - 1 - i]).Average();

      m_avgs = avgs;
      m_liveValues = hist.GetValues(DateTime.Today);
    }
Пример #9
0
    protected override ReturnsEval.DataSeriesEvaluator doPnl(TraderArgs args_, ConstructGen<double> wts_)
    {
      var priceReturns =
        args_.AllProductPrices(fillInGapsWithPrevious_: true)
          .ToReturns(args_.Products.Select(x => x.Convention).ToArray());


      var stratReturns = new ConstructGen<double>(priceReturns.ColumnHeadings);

      double[] appliedWeights = null;

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

        var priceReturnsArr = priceReturns.GetValues(date);

        if (appliedWeights != null)
        {
          for (int j = 0; j < priceReturnsArr.Length; ++j)
            stratReturns.SetValue(date, j, appliedWeights[j]*priceReturnsArr[j]);
        }

        if (wts_.Dates.Contains(date))
        {
          appliedWeights = wts_.GetValues(date);
        }
      }

      var eval = new ReturnsEval.DataSeriesEvaluator("Gen pnl from weights", ReturnsEval.DataSeriesType.Returns);
      eval.AddInnerSeries(stratReturns.Dates.ToArray(), stratReturns.ToArray(), stratReturns.ColumnHeadings);

      return eval;
    }
Пример #10
0
    public void Create(ConstructGen<double> candleData_, int openIndex_ = 0, int highIndex_ = 1, int lowIndex_ = 2, int closeIndex_ = 3, int setupLength_=9, int countdownLength_=13)
    {
      var dt = new DataTable();
      dt.Rows.Clear();
      dt.Columns.Clear();

      dt.Columns.Add("Date", typeof(DateTime));
      dt.Columns.Add("Open", typeof(double));
      dt.Columns.Add("High", typeof(double));
      dt.Columns.Add("Low", typeof(double));
      dt.Columns.Add("Close", typeof(double));
      dt.Columns.Add("Volume", typeof(double));

      ultraChart1.DataSource = dt;

      var closes = candleData_.GetColumnValuesAsDDC(closeIndex_);
      var range = closes.Data.Max() - closes.Data.Min();
      var cellHeight = range/10d;


      var setupStarts = DeMarkAnalysis.GetSetups(candleData_,openIndex_,highIndex_,lowIndex_,closeIndex_,setupLength_);
      DeMarkAnalysis.AddCountdowns(candleData_, setupStarts,openIndex_,highIndex_,lowIndex_,closeIndex_,setupLength_,countdownLength_);


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

        var arr = candleData_.GetValues(date);
        dt.LoadDataRow(new object[]
        {
          date,
          arr[openIndex_],
          arr[highIndex_],
          arr[lowIndex_],
          arr[closeIndex_],
          0d
        }, true);

        foreach(var mark in setupStarts)
        {
          addAnnotations(date, mark, i, cellHeight, arr,openIndex_,highIndex_,lowIndex_,closeIndex_);
        }
      }

      EstablishDefaultTooltip(hash =>
      {
        int rowNumber = (int) hash["DATA_ROW"];

        return string.Format("{0} Open: {1}, High: {2}, Low: {3}, Close: {4}",
          ((DateTime) dt.Rows[rowNumber]["Date"]).ToString("dd-MMM-yyyy"),
          ((double) dt.Rows[rowNumber]["Open"]).ToString(CultureInfo.InvariantCulture),
          ((double)dt.Rows[rowNumber]["High"]).ToString(CultureInfo.InvariantCulture),
          ((double)dt.Rows[rowNumber]["Low"]).ToString(CultureInfo.InvariantCulture),
          ((double)dt.Rows[rowNumber]["Close"]).ToString(CultureInfo.InvariantCulture)
          ).Replace(",", System.Environment.NewLine);

      });
    }
    private void loadListFromWeights(ConstructGen<double> wts_, IList<PositionLine<Currency>> list_)
    {
      var lastDate = wts_.Dates.Last();

      var wtsLast = wts_.GetValues(lastDate);

      for (int i = 0; i < wts_.ArrayLength; ++i)
        findIn(list_, Singleton<FXIDs>.Instance[i]).Position = wtsLast[i];
    }
Пример #12
0
    public void Create(ConstructGen<double> con_)
    {
      setupDataTable();

      double cumulative = 0d;

      Side lastSide = Side.None;

      foreach (var date in con_.Dates)
      {
        var values = con_.GetValues(date);

        var wt = values[(int)Headings.Weight];
        var dailyPnl = values[(int)Headings.Pnl];
        var ccyrate = values[(int)Headings.Spot];

        cumulative += dailyPnl;

        dt.LoadDataRow(new object[] { date, cumulative, ccyrate, wt }, true);

        if (wt > 0d)
        {
          if (lastSide != Side.Long)
          {
            dtLongPoints.LoadDataRow(new object[] { date, ccyrate }, true);
            lastSide = Side.Long;
          }
        }
        else if (wt < 0d)
        {
          if (lastSide != Side.Short)
          {
            dtShortPoints.LoadDataRow(new object[] { date, ccyrate }, true);
            lastSide = Side.Short;
          }
        }
        else
        {
          if (lastSide != Side.Flat)
          {
            dtFlatPoints.LoadDataRow(new object[] { date, ccyrate }, true);
            lastSide = Side.Flat;
          }
        }
      }

      {
        var ccyAxix = ultraChart.CompositeChart.ChartAreas[0].Axes.FromKey("y_axis_ccyRate");

        ccyAxix.RangeType = AxisRangeType.Custom;
        var ccyValues = con_.GetColumnValues((int)Headings.Spot);
        ccyAxix.RangeMin = ccyValues.Min();
        ccyAxix.RangeMax = ccyValues.Max();
      }

      m_con = con_;
    }
Пример #13
0
    public void Create(ConstructGen<double> con_)
    {
      setupDataTable();

      double cumulative = 0d;

      double? prevWt=null;

      foreach (var date in con_.Dates)
      {
        var values = con_.GetValues(date);

        var wt = values[(int)Headings.Weight];
        var dailyPnl = values[(int)Headings.Pnl];
        var ccyrate = values[(int)Headings.Spot];

        cumulative += dailyPnl;

        var objArr = new object[dt.Columns.Count];

        objArr[0] = date;
        objArr[1] = cumulative;

        var indexForWt = getIndexForWt(wt);
        objArr[indexForWt] = ccyrate;

        if (prevWt.HasValue)
        {
          var indexForPrevWt = getIndexForWt(prevWt.Value);

          if (indexForWt != indexForPrevWt)
            objArr[indexForPrevWt] = ccyrate;
        }


        objArr[5] = wt > 0d ? wt : 0d;
        objArr[6] = wt < 0d ? wt : 0d;

        dt.LoadDataRow(objArr, true);

        prevWt = wt;
      }

      {
        var ccyAxix = ultraChart.CompositeChart.ChartAreas[0].Axes.FromKey("y_axis_ccyRate");

        ccyAxix.RangeType = AxisRangeType.Custom;
        var ccyValues = con_.GetColumnValues((int)Headings.Spot);
        ccyAxix.RangeMin = ccyValues.Min();
        ccyAxix.RangeMax = ccyValues.Max();
      }

      m_con = con_;
    }
Пример #14
0
    public WtsSeriesAnalyzer(string name_, ConstructGen<double> wts_, ConstructGen<double> dailyReturns_, GetCov covDelegate_, bool addFXGroups_=true)
    {
      m_wts = wts_;
      m_perf = dailyReturns_;
      m_covDelegate=covDelegate_;
      Name=name_;

      m_c2v = new ConstructGen<double>(wts_.ArrayLength);
      m_c2v.ColumnHeadings = wts_.ColumnHeadings;
      foreach (DateTime date in wts_.Dates)
      {
        double[] dayWts = wts_.GetValues(date);
        if (Statistics.SumAbs(dayWts) == 0d  || covDelegate_==null)
          m_c2v.SetValues(date, new double[m_c2v.ArrayLength]);
        else
          m_c2v.SetValues(date, covDelegate_(date).GetContToVar(wts_.GetValues(date), false));
      }
      m_anal = new WtsAnalyzer(Name);

      if(addFXGroups_) m_anal.AddFXGroups();
      analyzePersistence();
      EvaluateAll();
    }
Пример #15
0
    public override void DoWeights(ConstructGen<double> signalResults_, ConstructGen<double> fullSignalResults_, ConstructGen<double> wts_, List<ProductBase> products_, ConstructGen<double> filters_)
    {
      double[] sigToday = new double[products_.Count];
      double sum;

      foreach (DateTime date in signalResults_.Dates)
      {
        double[] filterToday = filters_.GetValues(date);
        sum = 0;

        for (int i = 0; i < sigToday.Length; ++i)
          if(double.IsNaN(filterToday[i])==false)
            sum += signalResults_.GetValue(date, i);

        for (int i = 0; i < sigToday.Length; ++i)
          if(double.IsNaN(filterToday[i])==false)
            wts_.MultValue(date, i, signalResults_.GetValue(date, i) / sum, false);
      }

    }
Пример #16
0
    public void SaveWeights(ConstructGen<double> wts_, IProductID[] products_, bool obliterateCurrent_, bool overwrite_)
    {
      var sqls = new List<string>();

      if (obliterateCurrent_)
        sqls.Add(string.Format("delete from weights where signalID ={0}", OwningSignal.ID));

      var current = GetData(
        startDate_: DateTime.Today.AddMonths(-3),
        endDate_: DateTime.Today);

      foreach (var date in wts_.Dates)
      {
        if (!obliterateCurrent_ && current != null && current.Dates != null && current.Dates.Last() > date)
          continue;

        var dateWts = wts_.GetValues(date);

        if (!obliterateCurrent_ && overwrite_)
        {
          sqls.Add(string.Format("delete from weights where signalID={0} and markDate='{1}'", OwningSignal.ID,
            date.ToString("dd-MMM-yyyy")));
        }

        for (int i = 0; i < wts_.ArrayLength; ++i)
        {
          sqls.Add(string.Format("saveSignalWeights {0}, '{1}', {2}, {3}",
            OwningSignal.ID,
            date.ToString("dd-MMM-yyyy"),
            products_[i].ID,
            dateWts[i]
            ));
        }
      }

      Singleton<DB.ConnMngr>.Instance.ExecuteNonQuery(DBNames.SQLSERVER_DBAGHLA_HK, sqls);

    }
Пример #17
0
    public void Create(ConstructGen<double> candleData_, int openIndex_=0, int highIndex_=1, int lowIndex_=2, int closeIndex_=3)
    {
      dt.Rows.Clear();
      dt.Columns.Clear();

      dt.Columns.Add("Label", typeof (string));
      dt.Columns.Add("Date", typeof (DateTime));
      dt.Columns.Add("Open", typeof (double));
      dt.Columns.Add("High", typeof (double));
      dt.Columns.Add("Low", typeof (double));
      dt.Columns.Add("Close", typeof (double));

      foreach (var date in candleData_.Keys)
      {
        var arr = candleData_.GetValues(date);
        dt.LoadDataRow(new object[]
        {
          ((dt.Rows.Count+1) % 10).ToString(),
          date,
          arr[openIndex_],
          arr[highIndex_],
          arr[lowIndex_],
          arr[closeIndex_]
        },true);
      }

      CandleSeries cs = (CandleSeries) ultraChart.CompositeChart.Series[0];
      cs.Data.LabelColumn = "Label";
      cs.Data.LowColumn = "Low";
      cs.Data.HighColumn = "High";
      cs.Data.OpenColumn = "Open";
      cs.Data.CloseColumn = "Close";
      cs.Data.DateColumn = "Date";
      cs.Data.DataSource = dt;

      ultraChart.InvalidateLayers();

    }
Пример #18
0
    public static RVOlOptResult GetBackTestWeights(RVolOptArgs optArgs_)
    {
      TraderArgs args = new TraderArgs();

      Array.ForEach(Singleton<FXIDs>.Instance.ToArray(), x => args.Products.Add(ProductFX.GetCached(x)));

      args.RebalFrequency = optArgs_.Freq;
      args.DayOfWeek = DayOfWeek.Tuesday;
      args.ParticularDate = optArgs_.ParticularRebalDate;

      bool doNeg = false;

      List<DateTime> dates;
      if (optArgs_.Freq == RebalFreq.ParticularDate)
        dates = Trader.GenerateRebalDates(args.RebalFrequency, args.ParticularDate);
      else
        dates = Trader.GetRebalDates(args, MyCalendar.NextDayOfWeek(SI.Data.DataConstants.DATA_START, DayOfWeek.Tuesday));

      //ConstructGen<double> carryCon = Singleton<FXCarry>.Instance.GetAnnualizedCarry(MyCalendar.PrevWeekDay(dates[0].AddDays(-10d)), DateTime.Today, 5, false);
      var tranCosts = Singleton<FXTransactionCosts>.Instance.GetData(MyCalendar.PrevWeekDay(dates[0].AddDays(-10d)), DateTime.Today, false);
      var dxyScores = Singleton<DXYScore_21>.Instance.Scores;
      var vixScores = Singleton<VIXScore_21>.Instance.Scores;

      IList<string> exclude = new List<string>();
      {
        if (optArgs_.CcysToExclude != null)
          foreach (string s in optArgs_.CcysToExclude.ToUpper().Trim().Split(','))
            exclude.Add(s);
      }

      // set up scores
      switch (optArgs_.SwitchExpReturn)
      {
        case SwitchSignType.None:
          doNeg = false;
          break;
        case SwitchSignType.AlwaysNegative:
          doNeg = true;
          break;
        case SwitchSignType.DXY21:
          dxyScores = Singleton<DXYScore_21>.Instance.Scores;
          break;
        //case SwitchSignType.CustomDXY21:
        //  dxyScores = Singleton<QC.Common.CurrencyUniverseScore_21>.Instance.Scores;
        //  break;
        //case SwitchSignType.DXY_EMEA21:
        //  dxyScores = Singleton<QC.Common.CurrencyEMScore_21>.Instance.Scores;
        //  break;
        //case SwitchSignType.DXY_LATAM21:
        //  dxyScores = Singleton<QC.Common.CurrencyLATAMScore_21>.Instance.Scores;
        //  break;
        //case SwitchSignType.DXY_NJA21:
        //  dxyScores = Singleton<QC.Common.CurrencyNJAScore_21>.Instance.Scores;
        //  break;
        //case SwitchSignType.DXY_G1021:
        //  dxyScores = Singleton<QC.Common.CurrencyG10Score_21>.Instance.Scores;
        //  break;
        //case SwitchSignType.COTMonWts:
        //  {
        //    ConstructGen<double> cotWts = Backtests.getWE(Strat.COT1Mon).Key;
        //    dxyScores = cotWts.SumRows();
        //    dxyScores = dxyScores.MultiplyBy(-1d);
        //  }
        //  break;
        default:
          throw new Exception(string.Format("Need to code options for {0}", optArgs_.SwitchExpReturn.ToString()));
      }


      Logger.Info(string.Format("Switching threshold on scores is {0}", optArgs_.SwitchThreshold.ToString()), typeof(RVOLOpt));

      List<DateTime> triggerDates = new List<DateTime>();

      // do we want to look for trigger every day?
      if (optArgs_.SwitchDailyTrigger && !double.IsNaN(optArgs_.SwitchThreshold))
      {
        for (int i = 1 + Math.Abs(optArgs_.SwitchDayOffset); i < dxyScores.Length; ++i)
        {
          if (dates[0] > dxyScores.Dates[i]) continue;

          if (dxyScores.Dates[i].Month == 12 && (dxyScores.Dates[i].Day == 25 || dxyScores.Dates[i].Day == 26))
            continue;

          double dxyToday = dxyScores.Data[i + optArgs_.SwitchDayOffset];
          double dxyYest = dxyScores.Data[i + optArgs_.SwitchDayOffset - 1];

          if (dxyToday >= optArgs_.SwitchThreshold && dxyYest < optArgs_.SwitchThreshold)
          {
            if (dates.Contains(dxyScores.Dates[i]) == false)
            {
              dates.Add(dxyScores.Dates[i]);
              triggerDates.Add(dxyScores.Dates[i]);
            }
          }
          else if (dxyToday < optArgs_.SwitchThreshold && dxyYest >= optArgs_.SwitchThreshold)
          {
            if (dates.Contains(dxyScores.Dates[i]) == false)
            {
              dates.Add(dxyScores.Dates[i]);
              triggerDates.Add(dxyScores.Dates[i]);
            }
          }
        }
        QuickSort.Sort<DateTime>(dates);
      }
      //else if (optArgs_.SwitchExpReturn == SwitchSignType.COTMonWts)
      //{
      //  ConstructGen<double> cotWts = Backtests.getWE(Strat.COT1Mon).Key;
      //  dxyScores = cotWts.SumRows();
      //  dxyScores = dxyScores.MultiplyBy(-1d);
      //}

      int numCcys = Singleton<FXIDs>.Instance.Count;
      ConstructGen<double> wts = new ConstructGen<double>(Singleton<FXIDs>.Instance.ColumnHeadings);

      /* lincon */
      double[,] lincon = new double[6, numCcys + 1];

      /* minlincon & maxlincon */
      double[,] minlincon = new double[6, 1];
      double[,] maxlincon = new double[6, 1];
      {
        minlincon[0, 0] = 0d; minlincon[1, 0] = -10d; minlincon[2, 0] = 0d; minlincon[3, 0] = -10d; minlincon[4, 0] = 0d; minlincon[5, 0] = -10d;
        maxlincon[0, 0] = 10d; maxlincon[1, 0] = 0d; maxlincon[2, 0] = 10d; maxlincon[3, 0] = 0d; maxlincon[4, 0] = 10d; maxlincon[5, 0] = 0d;
      }

      /* opt horizon */
      string optHorizon = "2W";

      /* USD constraints */
      double usdMin = -5d;
      double usdMax = 5d;

      usdMax = Math.Abs(optArgs_.USDAbsLimit);
      usdMin = 1d - Math.Abs(optArgs_.USDAbsLimit - 1d);

      /* target vol */
      double targetVol = 0.012159;

      /* equal expected return */
      double[] eerPos = new double[numCcys];
      for (int i = 0; i < eerPos.Length; ++i) eerPos[i] = optArgs_.ReturnMagnitude == 0d ? 0.1 : Math.Abs(optArgs_.ReturnMagnitude);
      double[] eerNeg = new double[numCcys];
      for (int i = 0; i < eerNeg.Length; ++i) eerNeg[i] = optArgs_.ReturnMagnitude == 0d ? -0.1 : -Math.Abs(optArgs_.ReturnMagnitude);

      foreach (DateTime date in dates)
      {
        if (optArgs_.StartDate != null && date <= optArgs_.StartDate.Value)
          continue;

        Logger.Debug(string.Format("Generatig weights for {0}", date.ToString("dd-MMM-yyy")), typeof (RVOLOpt));

        /* covariance */

        CovarianceItem simCov = (optArgs_.SimCov == VolType.covar)
          ? Singleton<CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date)
          : Singleton<FXHistCovar>.Instance.FindForDate(date, optArgs_.HistCovarWindowLength);
        CovarianceItem scaleCov = (optArgs_.ScaleCov == VolType.covar)
          ? Singleton<CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date)
          : Singleton<FXHistCovar>.Instance.FindForDate(date, optArgs_.HistCovarWindowLength);



        /* tcosts */
        double[] tcosts = new double[numCcys];
        {
          if (optArgs_.IncludeTransactionsCosts)
          {
            int endIndex = tranCosts.Dates.Contains(date) ? tranCosts.Dates.IndexOf(date) - 1 : tranCosts.Dates.Count - 1;
            tcosts = tranCosts.GetValues(tranCosts.Dates[endIndex]);
          }
        }

        /* oldWts */
        double[] prevWts = new double[numCcys];
        {
          if (optArgs_.PrevWts != null)
            prevWts = optArgs_.PrevWts;
          else if (wts.Dates.Count > 0)
            prevWts = wts.GetValues(wts.Dates[wts.Dates.Count - 1]);
        }

        /* mins & maxs */
        double[] mins = new double[numCcys];
        double[] maxs = new double[numCcys];
        {
          for (int i = 0; i < numCcys; ++i)
          {
            Currency ccy = Singleton<FXIDs>.Instance[i];

            // must be zero for non-elegible currencies
            if (ccy.IsValid(date) == false) continue;

            // exclude this currency
            if (exclude.Contains(ccy.Code)) continue;

            //mins[i] = exclude.Contains(ccy.Code) ? 0d : !ccy.IsGroup(FXGroup.G10) ? -0.121591 : -0.3039775;
            //maxs[i] = exclude.Contains(ccy.Code) ? 0d : !ccy.IsGroup(FXGroup.G10) ? 0.121591 : 0.3039775;

            switch (optArgs_.WeightsSplitType)
            {
              case WtsSplitType.G10_EM:
                {
                  maxs[i] = ccy.IsGroup(FXGroup.G10) ? Math.Abs(optArgs_.G10MaxWeight) : Math.Abs(optArgs_.EMMaxWeight);
                }
                break;
              case WtsSplitType.G10_NDF_NonNDFEM:
                {
                  if (ccy.IsGroup(FXGroup.G10))
                    maxs[i] = Math.Abs(optArgs_.G10MaxWeight);
                  else if (ccy.IsGroup(FXGroup.NDF))
                    maxs[i] = Math.Abs(optArgs_.NDFMaxWeight);
                  else
                    maxs[i] = Math.Abs(optArgs_.NonNDFEMMaxWeight);
                }
                break;
              case WtsSplitType.Custom:
                {
                  maxs[i] = Math.Abs(optArgs_.CustomMaxMins[i]);
                }
                break;
            }

            mins[i] = -maxs[i];
          }
        }

        /* neg expected return or not */
        if (double.IsNaN(optArgs_.SwitchThreshold) == false)  // ... if we're looking for a threshold
        {
          double score = dxyScores.ValueOnDate(date, optArgs_.SwitchDayOffset);
          if (score > optArgs_.SwitchThreshold)
            doNeg = true;
          else
            doNeg = false;
        }

        /* go */
        //IMOptPortfolio(targetVol, cov, carry, tcosts, prevWts, mins, maxs, lincon, minlincon, maxlincon, optHorizon, lastArg);

        switch (optArgs_.ExpectedReturnType)
        {
          case ExpectedReturnType.Equal:
            // do nothing - is default option
            break;
          case ExpectedReturnType.OneOverVol:
          {
            double[] vols = simCov.IndividualVols;
            for (int i = 0; i < eerPos.Length; ++i)
            {
              eerPos[i] = 1d/vols[i];
              eerNeg[i] = -1d/vols[i];
            }
          }
            break;
          case ExpectedReturnType.EqualExceptLowestCorrel_1:
          case ExpectedReturnType.EqualExceptLowestCorrel_2:
          {
            var rankThreshold = 0d;

            switch (optArgs_.ExpectedReturnType)
            {
              case ExpectedReturnType.EqualExceptLowestCorrel_1:
                rankThreshold = 1.1d;
                break;
              case ExpectedReturnType.EqualExceptLowestCorrel_2:
                rankThreshold = 2.1d;
                break;
            }

            var corrRanks =
              Singleton<CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date, 5)
                .GetIndividualAverageCorrelations()
                .ToRanks(ascending_: true);

            for (int i = 0; i < eerPos.Length; ++i)
            {
              var rank = corrRanks[i];
              eerNeg[i] = (rank <= rankThreshold) ? 0.1 : -0.1;
              eerPos[i] = (rank <= rankThreshold) ? -0.1 : 0.1;
            }
          }
            break;
          case ExpectedReturnType.EqualExceptLowestCorrel_pct10:
          {
            var pctThreshold = 0.1d;

            var indivAvgCorrelations = Singleton<CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date, 5)
              .GetIndividualAverageCorrelations();

            double min = indivAvgCorrelations.Min();
            double max = indivAvgCorrelations.Max();

            double threshold = min + ((max - min)*pctThreshold);

            for (int i = 0; i < eerPos.Length; ++i)
            {
              eerNeg[i] = (indivAvgCorrelations[i] <= threshold) ? 0.1 : -0.1;
              eerPos[i] = (indivAvgCorrelations[i] <= threshold) ? -0.1 : 0.1;
            }
          }
            break;
        }

        if (optArgs_.OptType == OptimationType.Excel)
        {

          var result = Singleton<ExcelOptimizer>.Instance.DoIt(
            numCcys, targetVol, simCov.Data, doNeg ? eerNeg : eerPos, tcosts, prevWts, mins, maxs, usdMin, usdMax, optHorizon,
            date);

          //if (result.OptimizationResult != Optimizer.CarryOptResult.OptResult.OK_SolutionFoundAllConstraintsSatisfied)
          //  System.Diagnostics.Debugger.Break();

          double[] dateWts = result.Wts;

          if (result.Wts.SumAbs() == 0d)
            System.Diagnostics.Debugger.Break();

          // cross-sectional demean?
          if (optArgs_.CSDemean)
          {
            double sum = 0d;
            double count = 0d;
            for (int i = 0; i < dateWts.Length; ++i)
              if (dateWts[i] != 0d)
              {
                sum += dateWts[i];
                count += 1d;
              }
            double avg = sum/count;
            for (int i = 0; i < dateWts.Length; ++i)
              if (dateWts[i] != 0d)
                dateWts[i] -= avg;

            dateWts = scaleCov.ScaleSeries(dateWts, CovarianceItem.VolFromVaR(0.02));
          }

          wts.SetValues(date, dateWts);
        }
        else if (optArgs_.OptType == OptimationType.SolverFoundation)
        {
          var model = new RvolSolveModel(
            simCov,
            Singleton<FXIDs>.Instance.Select(
              (x, i) => new CurrencyLine(x, doNeg ? eerNeg[i] : eerPos[i], mins[i], maxs[i])).ToArray(),
            targetVol)
          {
            SumOfWeightsMin=0d,
            SumOfWeightsMax=0d
          };

          new RvolSolver().Solve(model);

          wts.SetValues(date, model.CurrencyLines.Select(x => x.Weight).ToArray());
        }
      }

      if(optArgs_.OptType==OptimationType.Excel)
        Singleton<ExcelOptimizer>.Instance.Dispose();

      return new RVOlOptResult()
      {
        TArgs = args,
        Weights = wts,
        TriggerDates = triggerDates
      };
      //return new KeyValuePair<TraderArgs, Construct>(args, wts);
    }
    public static ConstructGen<double> GetInvoiceSpreadsAsConstruct()
    {
      var configs = invoiceSpreadConfigs().ToArray();

      var con = new ConstructGen<double>(
        configs.Select(x => string.Format("{0}_{1}_{2}", x.Future, x.Series + 1, x.Curve.ToString())).ToArray());

      for (int i = 0; i < configs.Length; ++i)
      {
        var spreads = getInvoiceSpreadsCollectionFromMongo(configs[i]);
        con.SetColumnValues(i,
          new DatedDataCollectionGen<double>(spreads.Lines.Select(x => x.Date).ToArray(),
            spreads.Lines.Select(x => x.InvoiceSpread ?? 0d).ToArray()));
      }

      if (con.NeedsToSortKeys())
        con.SortKeys();

      // feed forward missing values
      {
        var values = con.GetValues(con.Dates[0]);

        for (int i = 1; i < con.Dates.Count; ++i)
        {
          var date = con.Dates[i];

          var todayValues = con.GetValues(date);

          for (int j = 0; j < todayValues.Length; ++j)
          {
            if (todayValues[j] == 0d)
              todayValues[j] = values[j];
          }

          values = todayValues;
        }
      }

      return con;
    }
    public void Create(ConstructGen<double> wts_, FXGroup[] groups_)
    {
      ConstructGen<double> groupConv = new ConstructGen<double>(groups_.Length);
      groupConv.ColumnHeadings = groups_.Select(x => x.ToString()).ToArray();
      Currency[] ccys = wts_.ColumnHeadings.Select(x => Singleton<FXIDs>.Instance[x]).ToArray();

      List<int[]> indicies =new List<int[]>();

      foreach(FXGroup group in groups_)
      {
        List<int> groupIndicies=new List<int>();
        for(int i=0;i<ccys.Length;++i)
          if(ccys[i].IsGroup(group))
            groupIndicies.Add(i);
        
        indicies.Add(groupIndicies.ToArray());
      }

      foreach (DateTime date in wts_.Dates)
      {
        double[] dateWeights = wts_.GetValues(date);
        double[] buckets = new double[groups_.Length];

        for(int g=0;g<groups_.Length;++g)
          foreach (int index in indicies[g])
            buckets[g] += dateWeights[index];

        groupConv.SetValues(date, buckets);
      }

      DataTable dt1 = groupConv.ToDataTable(groupConv.ColumnHeadings, "Date", "dd-MMM-yyyy");

      Chart.ChartType = Infragistics.UltraChart.Shared.Styles.ChartType.Composite;

      ChartArea area = new ChartArea();
      Chart.CompositeChart.ChartAreas.Add(area);

      AxisItem axisY = new AxisItem();
      axisY.Extent = 50;
      axisY.DataType = AxisDataType.Numeric;
      axisY.OrientationType = AxisNumber.Y_Axis;
      axisY.LineColor = Color.Blue;
      axisY.Labels.Visible = true;
      area.Axes.Add(axisY);

      AxisItem axisX = new AxisItem();
      axisX.DataType = AxisDataType.String;
      axisX.Extent = 80;
      axisX.SetLabelAxisType = Infragistics.UltraChart.Core.Layers.SetLabelAxisType.GroupBySeries;
      axisX.OrientationType = AxisNumber.X_Axis;
      axisX.LineColor = Color.Blue;
      axisX.Labels.Orientation = TextOrientation.VerticalLeftFacing;
      axisX.Labels.SeriesLabels.Orientation = TextOrientation.VerticalLeftFacing;
      area.Axes.Add(axisX);

      AxisItem axisX2 = new AxisItem();
      axisX2.DataType = AxisDataType.String;
      axisX2.Extent = 80;
      axisX2.OrientationType = AxisNumber.X_Axis;
      axisX2.LineColor = Color.Blue;
      axisX2.Labels.Orientation = TextOrientation.VerticalLeftFacing;
      axisX2.Labels.SeriesLabels.Orientation = TextOrientation.VerticalLeftFacing;
      axisX2.SetLabelAxisType = SetLabelAxisType.ContinuousData;
      area.Axes.Add(axisX2);

      ChartLayerAppearance myColumnLayer = new ChartLayerAppearance();
      myColumnLayer.ChartType = ChartType.StackColumnChart;
      myColumnLayer.ChartArea = area;

      foreach (FXGroup group in groups_)
      {
        NumericSeries series1 = new NumericSeries();
        series1.Key = group.ToString();
        series1.DataBind(dt1, group.ToString(), "Date");
        series1.PEs.Add(new PaintElement(ColorAttribute.GetAttribute(group).Color));
        myColumnLayer.Series.Add(series1);
        Chart.CompositeChart.Series.Add(series1);
      }

      DataTable dt2 = wts_.SumRows().ToDataTable(format_:"dd-MMM-yyyy");

      ChartLayerAppearance myColumnLayer2 = new ChartLayerAppearance();
      myColumnLayer2.ChartType = ChartType.LineChart;
      myColumnLayer2.ChartArea = area;

      NumericSeries seriesA = new NumericSeries();
      seriesA.Key = "Sum of Wts";
      seriesA.DataBind(dt2, "Value", "Date");
      seriesA.PEs.Add(new PaintElement(Color.Orange));
      myColumnLayer2.Series.Add(seriesA);
      Chart.CompositeChart.Series.Add(seriesA);


      LineChartAppearance la = new LineChartAppearance();
      la.Thickness = 4;
      myColumnLayer2.ChartTypeAppearance = la;


      myColumnLayer.AxisX = axisX;
      myColumnLayer.AxisY = axisY;

      myColumnLayer2.AxisX = axisX2;
      myColumnLayer2.AxisY = axisY;

      myColumnLayer.SwapRowsAndColumns = true;
      this.Chart.CompositeChart.ChartLayers.Add(myColumnLayer);
      this.Chart.CompositeChart.ChartLayers.Add(myColumnLayer2);

      EstablishDefaultTooltip();
      m_wts = wts_;
      m_groups = groups_;
      pbSplitIntoYears.BringToFront();
    }
    public void Go()
    {
      var allweights=new ConstructGen<WeightsLine>(Spreads.Length);

      // mark each of the individual spread weight entry/exit points in the construct - could well be different dates per spread...
      for(int i=0;i<Spreads.Length;++i)
      {
        var wts = Spreads[i].GenerateWeights();

        foreach (var wt in wts)
        {
          if (wt.EntryDate <= DateTime.Today) allweights.SetValue(wt.EntryDate, i, wt);
          if (wt.ExitDate <= DateTime.Today) allweights.SetValue(wt.ExitDate, i, wt);
        }
      }

      allweights.SortKeys();


      // on each date, note the positions that are carried over from an earlier trade on the same day, so that we have a
      // full picture of what is in play on that day
      WeightsLine[] prev = null;
      foreach (var date in allweights.Dates)
      {
        var todays = allweights.GetValues(date);
        if (prev != null)
        {
          for (int i = 0; i < todays.Length; ++i)
          {
            if (prev[i] != null && todays[i]==null && date <= prev[i].ExitDate)
              todays[i] = prev[i];
          }
        }

        prev = todays;
      }

      if (allweights.NeedsToSortKeys()) allweights.SortKeys();

      // go through each of the dates to generate a covariance and scale the positions 
      foreach (DateTime date in allweights.Keys)
      {
        var arr = allweights.GetValues(date);

        // build up list of indicies that are live on the current date
        var liveIndicies = new List<int>();

        for (int i = 0; i < arr.Length; ++i)
          if (arr[i] != null && arr[i].ExitDate > date)
            liveIndicies.Add(i);

        if (!liveIndicies.Any()) continue;

        var liveItems = liveIndicies.Select(x => arr[x]).ToArray();

        // for all live items form an array of recent returns over of length 'NumDaysForCovariance'
        var returns = new double[NumDaysForCovariance, liveIndicies.Count()];
        var rawSpreadWeights = new double[liveIndicies.Count()];

        for (int i = 0; i < liveIndicies.Count; ++i)
        {
          var indexReturns = liveItems[i].GetAllSpreadReturns();

          // have prices been updated?
          if (indexReturns.LastDate < date)
            continue;

          int indexOfDate = indexReturns.IndexOfElsePrevious(date);
          --indexOfDate;


          var slice = indexReturns.Data.Slice(indexOfDate - NumDaysForCovariance + 1, NumDaysForCovariance);
          rawSpreadWeights[i] = liveItems[i].SpreadWeight/Statistics.Stdev(slice);
          returns.SetColumn(i, slice);
        }

        // buil the covariance
        var covar = new CovarianceItem(Utils.CalculateCovariance(returns));

        // vol bucketing
        var targetvol = liveItems.Length*0.02;

        // scale the weights
        var newwts = covar.ScaleSeries(rawSpreadWeights, targetvol);

        for (int i = 0; i < newwts.Length; ++i)
          liveItems[i].AddCombineWeight(date, newwts[i]);
      }
    }
    public override void SaveWeights(ConstructGen<double> wts_, IProductID[] products_, bool obliterateCurrent_, bool overwrite_)
    {
      var sqls = new List<string>();

      if (obliterateCurrent_)
        sqls.Add(string.Format("delete from wts where signalID ={0}", OwningSignal.ID));

      foreach (var date in wts_.Dates)
      {
        var dateWts = wts_.GetValues(date);

        if (!obliterateCurrent_ && overwrite_)
        {
          sqls.Add(string.Format("delete from wts where signalID={0} and markDate='{1}'", OwningSignal.ID,
            date.ToString("dd-MMM-yyyy")));
        }

        for (int i = 0; i < wts_.ArrayLength; ++i)
        {
          var ccy = Singleton<FXIDs>.Instance[wts_.ColumnHeadings[i]];

          sqls.Add(string.Format("saveSignalWts '{0}', '{1}', {2}, {3}",
            OwningSignal.Name,
            date.ToString("dd-MMM-yyyy"),
            ccy.ID,
            dateWts[i]
            ));
        }
      }

      Singleton<DB.ConnMngr>.Instance.ExecuteNonQuery(DBNames.SQLSERVER_DBAGHLA_HK, sqls);

    }
Пример #23
0
    public static ConstructGen<double> DoBW(ComID[] coms_, ConstructGen<PairTrade> pairTrades_)
    {
      var conRets = new ConstructGen<double>(coms_.Select(x => x.Name).ToArray());

      for (int rebalIndex = 0; rebalIndex < pairTrades_.Dates.Count; ++rebalIndex)
      {
        var rebalDate = pairTrades_.Dates[rebalIndex];
        var tradeEndDate = (rebalIndex < (pairTrades_.Dates.Count - 1) ? pairTrades_.Dates[rebalIndex + 1] : DateTime.Today);

        var pairTradesOnDay = pairTrades_.GetValues(rebalDate);

        for (int i = 0; i < pairTradesOnDay.Length; ++i)
        {
          var pairTrade = pairTradesOnDay[i];

          if (pairTrade == null)
            continue;

          var rets = pairTrade.WeightedBackwardation.GetSubValues(rebalDate.AddDays(1d), tradeEndDate);

          rets = rets.DivideBy(pairTrade.GetStdev(rebalDate, 63) * 3000d);

          conRets.SetColumnValues(i, rets);
        }
      }

      conRets.SortKeys();

      conRets = conRets.ProcessEachCell(x => (double.IsNaN(x) || double.IsInfinity(x) || double.IsNegativeInfinity(x) ? 0d : x));

      return conRets;
    }
Пример #24
0
    public static ConstructGen<double> DoScaleWeights(ConstructGen<double> weights_, double targetVol_, TraderArgs args_)
    {
      //Singleton<Data.FXHistCovar>.Instance.Ensure(weights_.Dates.ToArray(),63);

      ConstructGen<double> ret = new ConstructGen<double>(weights_.ArrayLength);
      ret.ColumnHeadings = weights_.ColumnHeadings;

      foreach (DateTime date in weights_.Dates)
      {
        DateTime d = date;
        CovarianceItem covar = null;

        switch (args_.VolTypeForScaling)
        {
          case VolType.covar:

            covar = Singleton<SI.Data.CovarianceSource>.Instance.GetCovarianceForDateElesePrevious(d);
            //if (covar == null)
            //{
            //  DateTime prevTradingDate = MyCalendar.PrevTradeDate(date, "LNB");
            //  covar = Singleton<Data.FXHistCovar>.Instance[prevTradingDate, 252];
            //}
            break;

          //case Technicals.VolType.hist:
          //  covar = Singleton<Data.FXHistCovar>.Instance[d, args_.HistCovWindowLength];
          //  break;

          default:
            throw new Exception("voltype not implemented");
        }

        // extract and scale weights
        double[] weighted = weightFX(weights_.GetValues(date), covar, args_, targetVol_);

        ret.SetValues(date, weighted);
      }

      return ret;
    }
    public ConstructGen<double> AllConstantMaturityPrices()
    {
      if (m_allFuturePrices != null)
        return m_allFuturePrices;

      // get the quarterlyin contracts
      var allIMMs = Underlying.IMM_Contracts();

      // build up the list of prices for all contracts

      ConstructGen<double> subCon;
      {
        var con = new ConstructGen<double>(allIMMs.Select(x => x.SymmetryCode).ToArray());
        {
          for (int i = 0; i < con.ArrayLength; ++i)
            con.SetColumnValues(i, allIMMs[i].GetPrices(marketSnapCode_:MarketSnapCode,quoteSource_:QuoteSourceCode,priceType_:1));

          con.SortKeys();
        }

        var dates = SI.Strategy.RatesSpreads.DateHelper.GetBusinessDates(CurveNames.USD3M);

        subCon = new ConstructGen<double>(con.ColumnHeadings);

        foreach (var date in dates)
          if (con.Dates.Contains(date))
            subCon.SetValues(date, con.GetValues(date));
      }

      // create the construct that will hode the constant maturity prices
      // is NumContracts+1 as first column will be interest rate fixing

      m_allFuturePrices =
        new ConstructGen<double>(
          ExtensionMethods.CreateArrayRep(Underlying.FutureStart, NumContracts+1)
            .Select((x, i) => string.Format("{0}cm{1}", x.ToUpper(), i))
            .ToArray());

      foreach (var date in subCon.Dates)
      {
        // set the fixing
        m_allFuturePrices.SetValue(date, 0, Underlying.FixingInstrmnet.GetPrices().ValueOnDate(date)*100d);

        for (int pointIndex = 0; pointIndex < NumContracts; ++pointIndex)
        {
          var daysForward = Convert.ToDouble(pointIndex + 1)*DaysSpan;
          var forwardDate = date.AddDays(daysForward);

          int beforeIndex=-1, afterIndex=-1;
          for (int i = 0; i < allIMMs.Count-1; ++i)
          {
            if(allIMMs[i].Maturity.Value==forwardDate)
            {
              beforeIndex = i;
              afterIndex = i;
              break;
            }
            else if (allIMMs[i].Maturity.Value < forwardDate && allIMMs[i+1].Maturity.Value > forwardDate)
            {
              beforeIndex = i;
              afterIndex = i + 1;
            }
          }

          // were the indexes of the contract that straddle the forward date found?
          if (beforeIndex >= 0)
          {
            if (beforeIndex == afterIndex)
            {
              m_allFuturePrices.SetValue(date, pointIndex+1, 100d-subCon.GetValue(date, beforeIndex));
            }
            else
            {
              var beforeValue = subCon.GetValue(date, beforeIndex);
              var afterValue = subCon.GetValue(date, afterIndex);

              if (beforeValue == 0d || afterValue == 0d)
                continue;

              var width = allIMMs[afterIndex].Maturity.Value - allIMMs[beforeIndex].Maturity.Value;

              var w1 = forwardDate - allIMMs[beforeIndex].Maturity.Value;

              var propAfter = w1.TotalDays/width.TotalDays;

              var interpValue = (afterValue*propAfter) + (beforeValue*(1d - propAfter));

              m_allFuturePrices.SetValue(date, pointIndex+1, 100d-interpValue);
            }
          }
        }
      }

      return m_allFuturePrices;
    }
Пример #26
0
    public void Create(ConstructGen<double> candleData_, int openIndex_ = 0, int highIndex_ = 1, int lowIndex_ = 2, int closeIndex_ = 3)
    {
      var dt = new DataTable();
      dt.Rows.Clear();
      dt.Columns.Clear();

      dt.Columns.Add("Label", typeof(string));
      dt.Columns.Add("Date", typeof(DateTime));
      dt.Columns.Add("Open", typeof(double));
      dt.Columns.Add("High", typeof(double));
      dt.Columns.Add("Low", typeof(double));
      dt.Columns.Add("Close", typeof(double));
      dt.Columns.Add("Volume", typeof (double));

      CandleSeries cs = (CandleSeries)ultraChart1.CompositeChart.Series[0];

      var setupStarts = DeMarkAnalysis.GetSetups(candleData_);

      for(int i=0;i<candleData_.Dates.Count;++i)
      {
        var date = candleData_.Dates[i];
        var arr = candleData_.GetValues(date);
        dt.LoadDataRow(new object[]
        {
          ((dt.Rows.Count+1) % 10).ToString(),
          date,
          arr[openIndex_],
          arr[highIndex_],
          arr[lowIndex_],
          arr[closeIndex_],
          0d
        }, true);

        // any mark for this date?
        var mark = setupStarts.FirstOrDefault(x => x.Date == date);

        if (mark != null)
        {
          switch (mark.EventType)
          {
            case DeMarkEventType.BuySetupStart:
            {
              var annotation = createAnnotation("BuySetup", i + 0.5d, candleData_.GetValue(date, lowIndex_) - 1,
                Color.Green);
              ultraChart1.Annotations.Add(annotation);
            }
              break;
            case DeMarkEventType.SellSetupStart:
            {
              var annotatio = createAnnotation("SellSetup", i + 0.5d, candleData_.GetValue(date, highIndex_) + 1,
                Color.Red);
              ultraChart1.Annotations.Add(annotatio);
            }
              break;
          }
        }
      }

      cs.Data.LabelColumn = "Label";
      cs.Data.LowColumn = "Low";
      cs.Data.HighColumn = "High";
      cs.Data.OpenColumn = "Open";
      cs.Data.CloseColumn = "Close";
      cs.Data.DateColumn = "Date";
      cs.Data.VolumeColumn = "Volume";
      cs.Data.DataSource = dt;

      ultraChart1.InvalidateLayers();

      //EstablishDefaultTooltip((hash) =>
      //{
      //  return null;
      //});
    }
Пример #27
0
    private void buildData()
    {
      var pxDates = new List<DateTime>();
      var pxValues = new List<double>();

      for (int y = 2003;y <= DateTime.Now.Year; ++y)
      {
        // find the contracts
        var conLon = Long.Underlying.Futures.Where(x => x.Expiry.Year-Long.YearOffset == y && x.Expiry.Month == (int)Long.Month).FirstOrDefault();
        var conShort = Short.Underlying.Futures.Where(x => x.Expiry.Year-Short.YearOffset == y && x.Expiry.Month == (int)Short.Month).FirstOrDefault();

        if (conLon != null && conShort != null)
        {
          m_contractsLongShort.Add(y, new KeyValuePair<ComFutureMeta, ComFutureMeta>(conLon, conShort));

          // last trade of this pair is the earliest lastTrade date of the two
          var lastTrade = (conLon.LastTrade < conShort.LastTrade) ? conLon.LastLastDate : conShort.LastLastDate;
          var dataStart = lastTrade.AddYears(-1);

          if (MyCalendar.IsWeekend(dataStart)) dataStart = MyCalendar.NextWeekDay(dataStart);

          ConstructGen<double> con = new ConstructGen<double>(new string[] { conLon.Ticker, conShort.Ticker, "Diff", "Normalized" });

          con.SetColumnValues((int)dataColumns.Long, conLon.Prices.GetSubValues(dataStart, lastTrade));
          con.SetColumnValues((int)dataColumns.Short, conShort.Prices.GetSubValues(dataStart, lastTrade));

          if (con.NeedsToSortKeys()) con.SortKeys();

          if (con.Dates.Count == 0)
            continue;

          // calculate differences
          foreach (DateTime date in con.Keys)
          {
            double[] d = con.GetValues(date);

            // if we have a value for both contracts on this day
            if (d[(int)dataColumns.Long] != 0d && d[(int)dataColumns.Short] != 0d)
            {
              // save down the difference
              d[(int)dataColumns.Diff] = d[(int)dataColumns.Long] - d[(int)dataColumns.Short];

              if (date.Year == y)
              {
                pxDates.Add(date);
                pxValues.Add(d[2]);
              }
            }
          }

          // normalize differences
          {
            DatedDataCollectionGen<double> diffs = con.GetColumnValuesAsDDC((int)dataColumns.Diff);

            if (diffs==null || diffs.Length == 0)
              continue;

            var min = diffs.Data.Min();
            var max = diffs.Data.Max();

            var normArr = new double[diffs.Length];

            for (int i = 0; i < normArr.Length; ++i)
              normArr[i] = (diffs.Data[i] - min) / (max - min);

            con.SetColumnValues((int)dataColumns.NormalizedDiff, new DatedDataCollectionGen<double>(diffs.Dates, normArr));
          }


          m_yearToPxs.Add(y, con);
        }
      }
      m_hasBuiltData = true;
    }
Пример #28
0
    public static void processToTrigger(ConstructGen<double> wts_, TraderArgs args_, Trader trader_)
    {
      if (wts_.Dates.Count == 0)
        return;

      if (args_.TriggerArgs == null)
        return;

      List<int> datesIndicesToRemove=new List<int>();
      List<int> varContTopIndices = new List<int>();
      List<int> topWtPos = new List<int>();
      double[] before = wts_.GetValues(wts_.Dates[0]);
      double[] varContBefore = (args_.TriggerArgs.DoVarFlipsTrigger) ? trader_.GetContToVar(before, wts_.Dates[0], args_) : null;
      
      if (args_.TriggerArgs.DoVarFlipsTrigger)
        getTopVarIndicies(varContTopIndices, varContBefore, args_.TriggerArgs.VarFlipsTrigger.ConsiderTopVarNumber);
      if (args_.TriggerArgs.DoTopInSizeTrigger)
        getTopPosSizeIndicies(topWtPos, before, args_.TriggerArgs.TopInSizeTrigger.ConsiderTopInSizeNumber);

      List<DateTime> removeTheseDates = new List<DateTime>();
      int daysSinceRebal = 0;

      List<DateTime> includeTheseDates = new List<DateTime>();
      if (args_.TriggerArgs.AlwayRebalFrequencyEnabled)
      {
        // get the dates of rebal the rebalfrequency implies
        includeTheseDates = GenerateRebalDates(args_.TriggerArgs.AlwaysRebalFrequency, wts_.Dates[0]);
      }

      for (int i = 1; i < wts_.Dates.Count; ++i)
      {
        double[] wtsToday = wts_.GetValues(wts_.Dates[i]);
        bool remove=true;

        ++daysSinceRebal;

        // have we exceeded the maximum number of specified days without a rebal?
        if (remove && args_.TriggerArgs.MaxDaysWithoutRebalEnabled && args_.TriggerArgs.MaxDaysWithoutRebal <= daysSinceRebal)
        {
          remove = false;
        }

        // do we want to always rebal on a particular day of the week
        if (remove && args_.TriggerArgs.AlwaysRebalOnDayOfWeekEnabled && args_.TriggerArgs.AlwayRebalOnThisDayOfWeek == wts_.Dates[i].DayOfWeek)
        {
          remove = false;
        }

        // is the date in the list of dates that we always want to maintain
        if (remove && includeTheseDates.Contains(wts_.Dates[i]))
        {
          remove = false;
        }

        // positions that have changed signs must be greater than NUM_CHANGE_FREQ in order for the day to be kept

        if (remove && (args_.TriggerArgs.ChangeSignEnabled || args_.TriggerArgs.ChangeSignOnProportionEnabled))
        {
          int countChanged = 0;
          for (int j = 0; j < wts_.ArrayLength; ++j)
          {
            // change sign in position means keep
            if (Statistics.AreSameSign(before[j], wtsToday[j]) == false)
              ++countChanged;
          }

          int changeOnThisNumber = int.MaxValue;

          // if have decided to change on number of positions that have changed sign...
          if (args_.TriggerArgs.ChangeSignEnabled)
            changeOnThisNumber = Math.Min(changeOnThisNumber, args_.TriggerArgs.MinNumberOfItemsToChange);

          // if have decided to change on proportion of tradeable products to change sign
          if (args_.TriggerArgs.ChangeSignOnProportionEnabled)
          {
            int validCount = numValidProductsOnDate(wts_.Dates[i], args_);

            int numProp = Convert.ToInt32(Convert.ToDouble(validCount) * args_.TriggerArgs.ChangeSignOnThisProportion);

            changeOnThisNumber = Math.Min(changeOnThisNumber, numProp);
          }

          if (countChanged >= changeOnThisNumber)
            remove = false;
        }

        // proportion of portfolio turnover

        if (remove && args_.TriggerArgs.TurnoverEnabled)
        {
          double sumOfTurnover = 0.0;
          double sumOfPositions = 0.0;

          for (int j = 0; j < wts_.ArrayLength; ++j)
          {
            sumOfTurnover += Math.Abs(wtsToday[j] - (before[j]));
            sumOfPositions += Math.Abs(before[j]);
          }

          double propChanged = sumOfTurnover / sumOfPositions;

          if (propChanged >= args_.TriggerArgs.TurnoverThreshold/* TAG:MA32DaysMin && daysSinceRebal>1*/)
            remove = false;
        }

        // trade the flipped positions but don't re-scale everything else

        if (remove==false &&
          args_.TriggerArgs.DontTopLevelScaleIntraWeek == true &&
          args_.TriggerArgs.AlwaysRebalOnDayOfWeekEnabled && args_.TriggerArgs.AlwayRebalOnThisDayOfWeek != wts_.Dates[i].DayOfWeek)
        {
          double[] newArray = new double[before.Length];

          for (int j = 0; j < wts_.ArrayLength; ++j)
          {
            if (Statistics.AreSameSign(before[j], wtsToday[j]))
              newArray[j] = before[j];
            else
              newArray[j] = wtsToday[j];
          }

          wts_.SetValues(wts_.Dates[i], newArray);
          wtsToday = newArray;
        }

        // var flips
        if (remove &&
          args_.TriggerArgs.DoVarFlipsTrigger)
        {
          int numFlipped = 0;

          foreach (int index in varContTopIndices)
            if (Statistics.AreSameSign(before[index], wtsToday[index]) == false)
              ++numFlipped;

          if (numFlipped >= args_.TriggerArgs.VarFlipsTrigger.NumFlipsTrigger)
            remove = false;
        }

        // top in size flips
        if (remove &&
          args_.TriggerArgs.DoTopInSizeTrigger)
        {
          int numFlipped = 0;

          foreach (int index in topWtPos)
            if (Statistics.AreSameSign(before[index], wtsToday[index]) == false)
              ++numFlipped;

          if (numFlipped >= args_.TriggerArgs.TopInSizeTrigger.NumFlipsTrigger)
            remove = false;
        }

        if (remove)
        {
          removeTheseDates.Add(wts_.Dates[i]);
          ++daysSinceRebal;
        }
        else
        {
          before = wtsToday;
          //varContBefore = (trader_ == null || args_.TriggerArgs.VarFlipsTrigger == null || args_.TriggerArgs.VarFlipsTrigger.Enabled == false) ? null : trader_.GetContToVar(before, wts_.Dates[i], args_);
          daysSinceRebal = 0;
          if (args_.TriggerArgs.DoVarFlipsTrigger)
          {
            varContBefore = trader_.GetContToVar(before, wts_.Dates[i], args_);
            getTopVarIndicies(varContTopIndices, varContBefore, args_.TriggerArgs.VarFlipsTrigger.ConsiderTopVarNumber);
          }

          if (args_.TriggerArgs.DoTopInSizeTrigger)
            getTopPosSizeIndicies(topWtPos, before, args_.TriggerArgs.TopInSizeTrigger.ConsiderTopInSizeNumber);
        }
      }

      foreach (DateTime date in removeTheseDates)
        wts_.RemoveValues(date);
    }
Пример #29
0
    public static void Go()
    {
      // var is like 'dim'

      // make an array of size 10 - each initalized to the default double value i.e. 0d

      var arr = new double[10];

      // I could 'initialise' the values of this array in one call:

      arr = new double[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

      // an expanding construct is a list

      // make a list that I can only put doubles into

      var list = new List<double>();
      list.Add(1);
      list.Add(2);
      list.Add(3);

      // this is exactly the same as using an intializer:

      list = new List<double> {1, 2, 3};

      // I can use in built stuff to convert this to an array really easily

      double[] arr2 = list.ToArray();

      // dictionaries are lookups or hashmaps with types

      var birthdays = new Dictionary<string, DateTime>();
      birthdays.Add("Ben", new DateTime(1979, 12, 11));
      //or
      birthdays["Jess"] = new DateTime(1985, 1, 19);

      // note, the first method (.Add) will throw an exception if the item already exists, the second method will just overwrite

      // might be better to:
      if (birthdays.ContainsKey("Ben"))
        birthdays.Add("Ben", new DateTime(1979, 12, 11));

      // as we're dealing with time series a lot, I have created some classes that make it easier to work with dates and associated values

      // first of these is DatedDataCollection<T> where T is normally 'double'.

      // these are created with an array of Dates, and an array of 'Ts', which obviously must be of the same length, as the values correspond


      // NOTE: creating array on 1st, 3rd, 5th

      var dtsArray = new DateTime[] {new DateTime(2001, 1, 1), new DateTime(2001, 1, 3), new DateTime(2001, 1, 5)};
      var valuesArray = new double[] {1.21, 1.45, 1.65};

      var ddc = new DatedDataCollectionGen<double>(dtsArray, valuesArray);

      // obviously you wouldn't put normally create ddc like this - it normally gets populated from calls the the database or bbg initially, but we'll 
      // look at that later

      var date4th = new DateTime(2001, 1, 4);

      var value = ddc.ValueOnExactDate(date4th);  // this will fail as I'm insisting on the date being exact and there's nothing for 4th

      var value2 = ddc.ValueOnDate(date4th); // this will give me a value equal to that on the 3rd, since that is value for max date that is before 4th

      var value3 = ddc.ValueOnExactDate_Zero(date4th); // this won't fail but will pass back zero if there isn't an exact date

      // I've extended the classes to make it really easy to plot and see stuff

      ddc.DisplayColumnChart("Values in column chart");
      ddc.DisplayInGrid("values in grid");
      ddc.DisplayLineChart("Line chart");

      // this might be a bit of a leap, but I could very quickly extract EUR values from bloomberg in the following way, and display in a graph

      BbgTalk.HistoryRequester.GetHistory(new DateTime(2001, 1, 1),"EUR Curncy","PX_CLOSE",true)
        .DisplayLineChart("EUR from bbg from 2001");

      // what's this done?

      // BbgTalk.HistoryRequest knows how to connect to bloomberg and pulls out the series as a DatedDataCollection (so long as you're logged into bloomberg)

      DatedDataCollectionGen<double> euroSeries = BbgTalk.HistoryRequester.GetHistory(new DateTime(2001, 1, 1),
        "EUR Curncy", "PX_CLOSE", true);

      // then we displayed in a line chart:

      euroSeries.DisplayLineChart("EUR");

      // what else could we do with this euro series?

      // convert to returns:
      var euroReturns = euroSeries.ToReturns();
      var cumulative = euroReturns.ToCumulative();

      var stdFromMean = euroSeries.ToStdevFromMean(meanWindowLength_: 21, sdWindowLength_: 126);

      // I've also done a load of stuff to transform this series, take a look at HelperMethods.
      
      // often, we don't deal with individual price series, though we need inline data

      // for this I have made something called ConstructGen<T>, where again, T is normally a double

      var firstConstruct = new ConstructGen<double>(9);

      // this has made a construct that is set up to store dated values for 9 different variables

      // it's good to set the columnHeadings on the construct so you know what they refer to

      var headings = new string[] {"AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NOK", "NZD", "SEK"};
      firstConstruct.ColumnHeadings = headings;

      // (I'll show you how to do this more easily in a bit...

      // let's look at what we can do with construct and how we use it

      DateTime conDate = new DateTime(2014, 1, 1);

      firstConstruct.SetValue(conDate, 0, 100.2);

      // this has set the value for the first column (AUD) on the given Date

      // we get it out by:

      var v1 = firstConstruct.GetValue(conDate, 0);

      // set the second value:

      firstConstruct.SetValue(conDate, 1, 45.6);

      // this has set the value for the given date for 'CAD'

      // we could set all values at once using SetValues rather than SetValue

      firstConstruct.SetValues(conDate, new double[] {1, 2, 3, 4, 5, 6, 7, 8, 9});

      // and we could get them out using:

      double[] allValuesOnDate = firstConstruct.GetValues(conDate);

      // there are lots of methods on Construct<T> to make our life easier when dealing with data

      // we can fill it up randomly using the SetValues, and then just call SortKeys() to ensure teh dates are in order

      firstConstruct.SortKeys();

      // this means that we will be iterate over the dates in order when we go through it

      // e.g.

      foreach (DateTime date in firstConstruct.Dates)
      {
        var datesVAlues = firstConstruct.GetValues(date);

        // here we could process them...
      }

      // there are methods on ConstructGen<T> to make it easy to see what's in it.  e.g.

      firstConstruct.DisplayInGrid("Grid of construct values");
      firstConstruct.DisplayInDataCollectionDisplay("Display each column as a line in a chart");

      // there is also a useful method to get the column of values as a DatedDataCollection<T>

      DatedDataCollectionGen<double> firstColumn = firstConstruct.GetColumnValuesAsDDC(0);

      // this is an expensive operation FYI, so you wouldn't use this iterating over the dates within the ConstructGen<T> , but it is useful

      
      // ok, now, as we have a set universe of ccys, in the way I extract data from the database (prices / weights / carry / etc) I tend to pull
      // out in a standard way, making a ConstructGen<double> with a column for every currency in the universe

      // so, for example, if I wanted the spots from the database from 2013 onwards, I would call this

      SI.Data.FXSpots spotsProvider = new FXSpots();

      ConstructGen<double> spots = spotsProvider.GetData(new DateTime(2013, 1, 1), DateTime.Today);

      // this returns me a ConstructGen<double> with 27 columns, with each row being a date 

      // I can then use the spots values as I wish

      // similarly

      SI.Data.FXForwards1Wk fwdProvider = new FXForwards1Wk();

      ConstructGen<double> fwds = fwdProvider.GetData(new DateTime(2013, 1, 1), DateTime.Today);

      // within these classes, the data is cached, so that I don't call the database again if I don't need to

      // so if I call for the second time:

      var spots2 = spotsProvider.GetData(new DateTime(2013, 1, 1), DateTime.Today);

      // ... this won't have hit the database again, but will get from the cached data

      // but you'll notice that i have to have a reference to spotsProvider to benefit from the cached data.
      // if I was to make the same request from another point in my code, I would have to create a new FXSpots() instance and then call the method on it to get the data

      // it can be useful in this instance to make use of what's known as the 'Singleton' pattern.
      // This basically provides a means of referring to the same instance every time, in this case so that we make use of cached data

      // I have a Singleton<T> wrapper that wraps up a single instance of T so that I know I'm calling methods on the same instance every time

      // so I would usually get spots from the database wrapping FXSpots in this.  like:

      spots = Singleton<FXSpots>.Instance.GetData(new DateTime(2013, 1, 1), DateTime.Today);

      // now I could call the method on Singleton<FXSpots>.Instance from anywhere in my code and I would benefit from the caching

      // I do tend to use most of the classes that retrive from the database Within SI.Data wrapped in a Singleton

      // another example is the class that pulls information about signals

      var signals = Singleton<Signals>.Instance;

      // this is just a list of SI.Data.Signal classes

      

    }
Пример #30
0
    private static DatedDataCollectionGen<double> getIndexOfSorts(ConstructGen<double> prices_)
    {
      var returns = prices_.ToReturns();

      var indexLevels = new double[returns.Dates.Count];


      for (int i = 0; i < indexLevels.Length; ++i)
      {
        var todayReturns = returns.GetValues(returns.Dates[i]);

        var todayPrices = prices_.GetValues(returns.Dates[i]);

        // only use returns if the price series has started
        var usedReturns = todayReturns.Where((x, j) => todayPrices[j] > 1e-7);

        var avgReturn = !usedReturns.Any() ? 1d : 1d + usedReturns.Average();

        indexLevels[i] = (i == 0) ? 100d : indexLevels[i - 1] * avgReturn;
      }

      return new DatedDataCollectionGen<double>(prices_.Dates.ToArray(), indexLevels);
    }