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);
    }
Example #2
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;
    }
Example #3
0
    protected override ConstructGen<double> getData(DateTime startDate_, DateTime endDate_, bool forceRefresh_)
    {
      var con = new ConstructGen<double>(Singleton<FXIDs>.Instance.ColumnHeadings);

      var spots = Singleton<FXSpots>.Instance.GetData(startDate_, endDate_, forceRefresh_);
      var fwds = Singleton<FXForwards1Wk>.Instance.GetData(startDate_, endDate_, forceRefresh_);

      var conventions = Singleton<FXIDs>.Instance.ConventionsDs;

      var divisor = 5d;

      foreach (var date in spots.Dates)
      {
        var spotsD = spots.GetValues(date);
        var fwdsD = fwds.GetValues(date);
        var cryD = new double[fwdsD.Length];

        for (int i = 0; i < cryD.Length; ++i)
          if (spotsD[i] != 0d && fwdsD[i] != 0d)
          {
            cryD[i] = (Math.Pow(spotsD[i] / fwdsD[i], conventions[i]) - 1d) * (252d/divisor);
          }

        con.SetValues(date, cryD);
      }

      return con;
    }
Example #4
0
    private ConstructGen<double> extractDataFromDataset(DataSet ds_)
    {
      ConstructGen<double> con = new ConstructGen<double>(1);

      foreach (DataRow row in ds_.Tables[0].Rows)
      {
        var r = extractPrice(row);
        con.SetValues(r.Item1, new double[] { r.Item2 }, ConstructGenGen<DateTime, double>.KeyOptionsWhenAdding.AddEveryTime);
      }

      return con;
    }
    public static ReturnsFromWeightsResult DoIt_DailyWeights(ConstructGen<double> dailyWts_, DateTime? maxPnlDate_=null)
    {
      var wts = (ConstructGen<double>)dailyWts_.Clone();

      var indexPrices = Singleton<ComIndexPrices>.Instance.GetData(DataConstants.DATA_START, DateTime.Today, false);
      var indexReturns = indexPrices.ToReturns().GetSubValues(dailyWts_.Dates.First(),DateTime.Today);


      var coms = Singleton<ComIDs>.Instance.ToArray();

      var spotPnl = new ConstructGen<double>(wts.ColumnHeadings) {Name = wts.Name};
      var dollImpWts = new ConstructGen<double>(wts.ColumnHeadings);

      double[] currentWts = Utils.GetArrayOfValue(0d, wts.ArrayLength);

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

        if (maxPnlDate_.HasValue && date > maxPnlDate_.Value)
          break;

        var todayIndexReturns = indexReturns.GetValues(date);
        var todayStratReturns=new double[wts.ArrayLength];

        for (int j = 0; j < todayStratReturns.Length; ++j)
        {
          // set today's strat returns
          todayStratReturns[j] = currentWts[j]*todayIndexReturns[j];

          // dollar impact weights
          currentWts[j] *= (1d + todayStratReturns[j]);
        }

        spotPnl.SetValues(date, todayStratReturns);

        // if the weights have change at the end of today, update currentWts so they affect tomorrows pnl
        if (wts.Dates.Contains(indexReturns.Dates[i]))
          currentWts = wts.GetValues(indexReturns.Dates[i]);

        dollImpWts.SetValues(date, (double[]) currentWts.Clone());
      }

      return new ReturnsFromWeightsResult(dailyWts_.Name)
      {
        SpotPnl = spotPnl,
        OriginalWts = dailyWts_,
        DailyDollarImpactedWeights = dollImpWts,
        SpotsUsed = indexPrices.GetSubValues(dailyWts_.Dates.First(),DateTime.Today)
      };
    }
Example #6
0
    public override System.Collections.Generic.KeyValuePair<ConstructGen<double>, ReturnsEval.DataSeriesEvaluator> Run()
    {
      var dates = SI.Research.Backtest.Trader.GenerateRebalDates(Backtest.RebalFreq.Monthly,
        MyCalendar.NextWeekDay(new System.DateTime(2006, 3, 1)));

      var wts = new ConstructGen<double>(Singleton<ComIDs>.Instance.ColumnHeadings);

      Func<ComID, bool> smallerPositionFunc =
  (x) => x.Name.Equals("Lead") || x.Sector.Equals("Meats") || x.Sector.Equals("Softs");

      var volTarget = 0.06d;
      var limit = 0.3d;

      var expReturns = ExtensionMethods.CreateArrayRep<double>(0.1d, wts.ArrayLength);
      var lowerLimit = Singleton<ComIDs>.Instance.Select(x => smallerPositionFunc(x) ? -limit / 2d : -limit).ToArray();
      var upperLimit = Singleton<ComIDs>.Instance.Select(x => smallerPositionFunc(x) ? limit / 2d : limit).ToArray();
      var tcosts = ExtensionMethods.CreateArrayRep<double>(0d, wts.ArrayLength);
      var oldwts = ExtensionMethods.CreateArrayRep(0d, wts.ArrayLength);

      using (var opt = new SI.Research.ExcelOpt.ExcelOptimizer())
      {
        foreach (var date in dates)
        {
          var cov = Singleton<ComCovarianceSource>.Instance.GetCovarianceForDateElesePrevious(date, 30);

          var result =
            opt.DoIt(
              numCcys_: expReturns.Length,
              targetVol_: volTarget,
              covariance_: cov.Data,
              eer_: expReturns,
              tcosts_: tcosts,
              oldwts_: oldwts,
              mins_: lowerLimit,
              maxs_: upperLimit,
              usdMin_: -100d,
              usdMax_: 100d,
              optHorizon_: "2W",
              currentDate_: date);

          if (result != null && result.Wts != null)
            wts.SetValues(date, result.Wts);
        }
      }

      var eval = BacktestHelper.DoCommodsPnl(wts,"Scratchpad");

      return new System.Collections.Generic.KeyValuePair<ConstructGen<double>, ReturnsEval.DataSeriesEvaluator>(wts,
        eval);
    }
    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();
    }
Example #8
0
    private void lblScore_Click(object sender, EventArgs e)
    {
      var we = SI.Research.FXStrat.BacktestHelper.getWE(Research.FXStrat.Strat.RVOL).Key;

      var lastWeights = we.GetValues(we.LastDate);

      var mult = Singleton<SI.Research.LiveIndicators.BreakoutStrategy.ParameterSets>.Instance.AvgAllocation;

      var newWeights = lastWeights.MultiplyBy(mult*6d/1.215914d);

      var sig = Singleton<SI.Data.Signals>.Instance.First(x => x.Name.StartsWith("Break"));

      var con = new ConstructGen<double>(we.ColumnHeadings);
      con.SetValues(DateTime.Today, newWeights);

      sig.SaveWeightsToDB(wts_: con, obliterateCurrent_: false, overwrite_: true);
    }
Example #9
0
    public static ConstructGen<double> GetData()
    {
      const string pathToConstruct = @"E:\CSI\EquityData.con";

      if (File.Exists(pathToConstruct))
        return Singleton<DiscCache>.Instance.ReadFromGivenFilePath<ConstructGen<double>>(pathToConstruct,true);

      const string pathToCSV = @"E:\CSI\EquityData.csv";

      var ret = new ConstructGen<double>(new string[] {"Open", "High", "Low", "Close"});

      foreach (var v in CsvFile.Read<RowItem>(pathToCSV))
      {
        ret.SetValues(v.Date, new double[] {v.Open, v.High, v.Low, v.Close});
      }

      Singleton<DiscCache>.Instance.WriteToGivenFilePath(pathToConstruct, ret);

      return ret;
    }
Example #10
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);
    }
Example #11
0
    public static Tuple<ConstructGen<double>, int, DateTime> TransformToCompoChartDataAndShift(DataAroundEvent[] data_, int numberAroundEvents_, DataAroundEventField field_)
    {
        ConstructGen<double> ret = new ConstructGen<double>(numberAroundEvents_  + 1);
        ret.ColumnHeadings = new string[ret.ArrayLength];
        //ret.ColumnHeadings[0] = DateTime.Today.ToString("dd-MMM-yyyy");
        for (int i = 0; i <= numberAroundEvents_; ++i)
        {            
            ret.ColumnHeadings[i] = i.ToString();
        }
        var headings = new List<string>(ret.ColumnHeadings);


        int dayShift=0;
        DateTime closestEvent=DateTime.MinValue;
        if (data_ != null)
        {
            var eventdates = data_.Select(d => d.EventDate).ToArray();
            // first find out any events falls within next 15 days
            var maxAllowEventDate = DateTime.Today.AddDays(numberAroundEvents_);
            var includeEvents = eventdates
                .Where(newEvent => newEvent >= DateTime.Today && newEvent <= maxAllowEventDate);

            
            if (includeEvents.Any())
            {
                closestEvent = includeEvents.OrderBy(e => e).First();
                dayShift = (int)(closestEvent -DateTime.Today).TotalDays;
                int firstDataIndex = numberAroundEvents_ - dayShift;


                foreach (var eve in data_.OrderBy(x => x.EventDate))
                {
                    // initialise to NaN
                    ret.SetValues(eve.EventDate, Utils.GetArrayOfValue<double>(double.NaN, ret.ArrayLength));
                    var subData = eve[field_];
                    if (subData != null)
                        for (int i = 0; i <= numberAroundEvents_; i++)
                        {
                            if (firstDataIndex + i > subData.Data.Length -1) continue;
                            if (subData.Data[firstDataIndex+i] == null) continue;
                            ret.SetValue(eve.EventDate, i, subData.Data[firstDataIndex+i].Value);
                        }
                }
            }

            
        }
        return new Tuple<ConstructGen<double>, int, DateTime>(ret, dayShift, closestEvent);
    }
Example #12
0
    public static ConstructGen<double> TransformToCon(DataAroundEvent[] data_, int numberAroundEvents_, DataAroundEventField field_)
    {
      ConstructGen<double> ret = new ConstructGen<double>((numberAroundEvents_ * 2) + 1);
        ret.ColumnHeadings = new string[ret.ArrayLength];
        ret.ColumnHeadings[numberAroundEvents_] = "0";
        for (int i = 1; i <= numberAroundEvents_; ++i)
        {
          ret.ColumnHeadings[numberAroundEvents_ - i] = (-i).ToString();
          ret.ColumnHeadings[numberAroundEvents_ + i] = i.ToString();
        }
        var headings = new List<string>(ret.ColumnHeadings);

        if(data_!=null)
          foreach (var eve in data_.OrderBy(x => x.EventDate))
          {
            // initialise to NaN
            ret.SetValues(eve.EventDate, Utils.GetArrayOfValue<double>(double.NaN, ret.ArrayLength));
            var subData = eve[field_];
            if(subData!=null)
              foreach (var point in subData.Data)
              {
                if (point == null) continue;
                var index = headings.IndexOf((point.Index - data_.First().Offset).ToString());
                ret.SetValue(eve.EventDate, index, point.Value);
              }
          }
      return ret;
    }
    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 ConstructGen<double> WhatIfTradingRestrictions(WtRestriction[] wtsFlowMaxs_)
    {
      System.Diagnostics.Debug.Assert(wtsFlowMaxs_.Length == SourceWts.ArrayLength, "Need wtsFlowMaxs_ length to match the ArrayLength of the weights in question, else don't know how to restrict the flow");

      ConstructGen<double> ret = new ConstructGen<double>(SourceWts.ArrayLength);
      ret.ColumnHeadings = SourceWts.ColumnHeadings;
      ConstructGen<double> workingSourceWts = (ConstructGen<double>)SourceWts.Clone();

      DateTime currentDate = workingSourceWts.Dates[0];
      double[] priorWeights = ExtensionMethods.CreateArrayRep<double>(0d, ret.ArrayLength);

      while (currentDate <= DateTime.Today)
      {
        // do we have new target weights for today?
        if (workingSourceWts.Dates.Contains(currentDate) == false)
        {
          currentDate = MyCalendar.NextWeekDay(currentDate);
          continue;
        }

        double[] targetWeights = workingSourceWts.GetValues(currentDate);

        // check the movement on all weights to ensure that they're within tolerance
        bool needToTradeResidualTomorrow = false;

        double[] newWeights = new double[ret.ArrayLength];
        for (int i = 0; i < targetWeights.Length; ++i)
        {
          double targetWeight = targetWeights[i];
          double allowedTargetWeight = wtsFlowMaxs_[i].GetNewWeight(oldWeight_: priorWeights[i], targetWeight_: targetWeights[i]);

          if (allowedTargetWeight != targetWeights[i])
            if (!(wtsFlowMaxs_[i].MaxSize != null && wtsFlowMaxs_[i].MaxSize == Math.Abs(allowedTargetWeight)))
              needToTradeResidualTomorrow = true;

          newWeights[i] = allowedTargetWeight;
        }

        ret.SetValues(currentDate, newWeights);
        priorWeights = newWeights;

        // if we haven't successed to reach the target weights then we need to try and get there tomorrow...
        if (needToTradeResidualTomorrow)
        {
          workingSourceWts.SetValues(MyCalendar.NextWeekDay(currentDate), targetWeights);
        }

        currentDate = MyCalendar.NextWeekDay(currentDate);
      }

      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;
    }
Example #16
0
    private ConstructGen<double> getTCostForDates(IEnumerable<DateTime> dates_)
    {
      ConstructGen<double> asks = Singleton<FXSpots>.Instance.GetData(dates_.First<DateTime>(), DateTime.Today);
      ConstructGen<double> bids = Singleton<FXSpots>.Instance.GetData(dates_.First<DateTime>(), DateTime.Today);

      ConstructGen<double> ret = new ConstructGen<double>(Singleton<FXIDs>.Instance.Count);

      foreach (DateTime date in dates_)
      {
        double[] tCostToday = new double[ret.ArrayLength];
        ret.SetValues(date, tCostToday);

        if (date == DateTime.Today) continue;

        double[] bidsToday = bids.GetValues_Previous(date);
        double[] askToday = asks.GetValues_Previous(date);
        for (int i = 0; i < ret.ArrayLength; ++i)
          tCostToday[i] = (askToday[i] - bidsToday[i]) / (askToday[i] + bidsToday[i]);
      }

      return ret;
    }
Example #17
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;
    }
Example #18
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);
    }
Example #19
0
    public ConstructGen<double> GetWeights(TraderArgs args_)
    {
      generateRawResults(args_);

      // generate all indicators
      List<DateTime> rebalDates = getRebalDates(args_);

      // save them so we can use them later
      args_.RebalDates = rebalDates;

      // get the filter construct first
      ConstructGen<double> filter = getFilters(args_, rebalDates, m_resultsFilter);

      //ConstructDisplay.Show(filter, args_.Products.ToArray(), "Filter Values");

      // get the wts 
      ConstructGen<double>[] wts = getWeights(args_, rebalDates, filter);

      if (wts.Length > 0 && args_.CombineWeightArgs != null)
      {
        // do we want to scale each signal before combining?
        if (args_.CombineWeightArgs.ScaleBeforeCombine)
          for (int i = 0; i < wts.Length; ++i)
            wts[i] = ScaleWeights(wts[i], args_.ScaleToThisVol, args_);

        // do we want to scale the allocation to each signal?
        if (args_.CombineWeightArgs.ScaleWeightSignalsEnabled)
        {
          double currAlloc = args_.CombineWeightArgs.StratWeightStartAlloc;

          for (int i = 0; i < wts.Length; ++i)
          {
            wts[i] = wts[i].MultiplyBy(currAlloc);

            currAlloc += args_.CombineWeightArgs.StratWeightAllocIncrement;
          }
        }
      }

      // combine the different signals
      ConstructGen<double> c = wts[0];
      if (args_.CombineWeightArgs != null && args_.CombineWeightArgs.CombineMethod == StratCombineMethod.MULT)
      {
        c = wts[0];
        for (int i = 1; i < wts.Length; ++i)
          c = multiply(c, wts[i], false);
      }
      else if (args_.CombineWeightArgs != null && args_.CombineWeightArgs.CombineMethod == StratCombineMethod.AGREE)
      {
        c = wts[0];
        for (int i = 1; i < wts.Length; ++i)
          c = agreeSign(c, wts[i]);
      }
      else if (args_.CombineWeightArgs != null && args_.CombineWeightArgs.CombineMethod == StratCombineMethod.ADD)
      {
        c = wts[0];
        for (int i = 1; i < wts.Length; ++i)
          c = c.Plus(wts[i]);
      }
      else if (args_.CombineWeightArgs != null && args_.CombineWeightArgs.CombineMethod == StratCombineMethod.LIST)
      {
        System.Diagnostics.Debug.Assert(args_.CombineWeightArgs.AllocList != null, "Combine method has been set to 'LIST' but no allocation list has been set");

        System.Diagnostics.Debug.Assert(args_.CombineWeightArgs.AllocList.ArrayLength == wts.Length, "Set of weights to combine doesn't match arraylength of ConstructGen<double> that has been set to express the allocations.");

        // get a list of common dates
        List<DateTime> commondates = new List<DateTime>();
        foreach (DateTime date in wts[0].Dates)
        {
          for (int i = 1; i < wts.Length; ++i)
            if (wts[i].Dates.Contains(date) == false)
              continue;

          commondates.Add(date);
        }

        ConstructGen<double> comb = new ConstructGen<double>(wts[0].ArrayLength);

        for (int i = 0; i < wts.Length; ++i)
        {
          foreach (DateTime date in commondates)
          {
            if(comb.Dates.Contains(date)==false)
              comb.SetValues(date,new double[comb.ArrayLength]);

            double alloc = args_.CombineWeightArgs.AllocList.GetValue(date, i);

            for (int j = 0; j < comb.ArrayLength; ++j)
              comb.AddValue(date, j, alloc * wts[i].GetValue(date, j));
          }
        }

        c = comb;

      }
      else if (args_.CombineWeightArgs == null && wts.Length > 1)
        throw new Exception("Don't know how to combine the signals into one.");
      else if (args_.CombineWeightArgs != null)
        throw new Exception("Strategy combine method not implemented");

      // scale to the target vol
      if (args_.ScaleToVol)
        c = ScaleWeights(c, args_.ScaleToThisVol, args_);

      // if we want to 
      if (args_.RebalFrequency == RebalFreq.Trigger)
        processToTrigger(c, args_, this);


      //ConstructDisplay.Show(c, args_.Products.ToArray(), "final wts");

      c.ColumnHeadings = args_.Products.Select<ProductBase, string>(x => x.ToString()).ToArray<string>();

      return c;
    }
Example #20
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

      

    }
    private static void loadCon(string directory_, string ticker_, int pricingYear_, int pricingMonth_, Func<DateTime, bool> isCloseMinute_, ConstructGen<double> loadThis_)
    {
      var ddcase =
        getDDC(directory_, ticker_, pricingYear_, pricingMonth_, isCloseMinute_);

      if (ddcase == null)
        return;

      foreach (var v in ddcase.Data)
      {
        loadThis_.SetValues(v.Date, new[] {v.Open, v.High, v.Low, v.Close});
      }

      //Logger.Info(string.Format("Doing {0}  {1}  {2}", ticker_, pricingYear_, pricingMonth_), typeof(DB_FX_SWAPS_Extract));
      //var files = Directory.GetFiles(directory_, string.Format("*{0}-{1}-{2}.csv", pricingYear_, pricingMonth_.ToString("00"), ticker_));
      //if (files.Length == 0)
      //{
      //  Logger.Error("Couldn't find file", typeof (DB_FX_SWAPS_Extract));
      //  return;
      //}

      //DateTime openDate = DateTime.MinValue;
      //double? open = null;
      //double high = double.MinValue;
      //double low = double.MaxValue;

      //foreach (var line in FuturesIntradaySaver.ReadFile(files[0]))
      //{
      //  if (!line.gmtDate.HasValue) continue;

      //  high = Math.Max(high, line.HighMid);
      //  low = Math.Min(low, line.LowMid);
      //  if (!open.HasValue || openDate.Date != line.londonTime.Date)
      //  {
      //    open = line.OpenMid;
      //    openDate = line.londonTime;
      //  }

      //  if (!isCloseMinute_(line.londonTime)) continue;

      //  // commit
      //  loadThis_.SetValues(line.londonTime, new[] { open.Value, high, low, line.CloseMid }, ConstructGenGen<DateTime, double>.KeyOptionsWhenAdding.AddEveryTime);
      //  open = null;
      //  high = double.MinValue;
      //  low = double.MaxValue;
      //}

    }
Example #22
0
    public static void Go()
    {
      //var group = Singleton<IntradayFutureGroups>.Instance.FirstOrDefault(
      //  x => x.BbgStart.Equals("ES") && String.Compare("Index", x.Suffix, StringComparison.OrdinalIgnoreCase) == 0);

      var eventRel = EventRelative.Post;

      var pointsAroundEvent = 60;
      var pointOfFirstPeriod = 10;

      var listOfFutures = new List<Tuple<string, string>>();
      listOfFutures.Add(new Tuple<string, string>("ED", "Comdty"));
      listOfFutures.Add(new Tuple<string, string>("TY", "Comdty"));
      listOfFutures.Add(new Tuple<string, string>("ES", "Index"));

      var listOfEvents = new string[] {"FOMC", "NFP"};

      foreach (var futureStartEnd in listOfFutures)
      {
        var futureGroup = Singleton<IntradayFutureGroups>.Instance.FirstOrDefault(
          x => x.BbgStart.Equals(futureStartEnd.Item1) && String.Compare(futureStartEnd.Item2, x.Suffix, StringComparison.OrdinalIgnoreCase) == 0);

        var dict = new Dictionary<string, System.Windows.Forms.Control>();

        foreach (var evCode in listOfEvents)
        {
          var eventDef =
            Singleton<EventDefs>.Instance.FirstOrDefault(
              x => string.Compare(evCode, x.EventCode, StringComparison.OrdinalIgnoreCase) == 0);

          var rangeLength = Convert.ToInt32((pointsAroundEvent)/2);

          var hArgs = new SI.Strategy.SeasonalityAnalysis.HelperRequestArgs()
          {
            EventDates = eventDef.GetEvents(TZ.LN, new CarbonClient("uat")).Result.Where(x => x.Year <= 2014 && x.Year >= 2012).ToArray(),
            FrequencyOfPricing = new TimeSpan(0, 1, 0),
            FutureGroup = futureGroup,
            NumDataPointsAroundEvent = pointsAroundEvent,
            Timezone = TZ.LN
          };

          var eventStudies = SI.Strategy.SeasonalityAnalysis.Helper.Go(hArgs).ToArray();

          var con = new ConstructGen<double>(new[] {"Period1", "Period2"});

          foreach (var studay in eventStudies)
          {
            if (studay.RawRawDataAroundEvent == null)
              continue;

            int firstStartIndex, firstEndIndex, secondStartIndex, secondEndIndex;

            {
              firstStartIndex = 0;
              firstEndIndex = pointOfFirstPeriod;
              secondStartIndex = pointOfFirstPeriod + 1;
              secondEndIndex = pointsAroundEvent - 1;
            }

            if(eventRel==EventRelative.Post)
            {
              firstStartIndex += (rangeLength*2) + 1;
              firstEndIndex += (rangeLength * 2) + 1;
              secondStartIndex += (rangeLength * 2) + 1;
              secondEndIndex += (rangeLength * 2) + 1;
            }

            try
            {
              var first = studay.RawRawDataAroundEvent.Data[firstEndIndex].Value -
                          studay.RawRawDataAroundEvent.Data[firstStartIndex].Value;
              var second = studay.RawRawDataAroundEvent.Data[secondEndIndex].Value -
                           studay.RawRawDataAroundEvent.Data[secondStartIndex].Value;

              if (first == 0d || second == 0d)
                continue;

              con.SetValues(studay.EventDate.Date, new[] {first, second});
            }
            catch
            {
            }
          }

          if (con.Dates.Any() == false)
            continue;

          var chart = new SI.Controls.SimpleStackedColumnChart();
          chart.Create(values_: con, datesAlongBottom_: true);

          var title = string.Format("{0} - {1} ({2})", futureGroup, evCode, pointsAroundEvent);

          dict.Add(title, chart);
        }

        dict.DisplayInShowForm(futureGroup.ToString());
      }

    }
Example #23
0
    public ConstructGen<double> GiveMeProcessedWeights()
    {
      KeyValuePair<ConstructGen<double>, ReturnsEval.DataSeriesEvaluator> kvp = SI.Research.FXStrat.BacktestHelper.getWE(Strat);
      ConstructGen<double> oldWts = kvp.Key;
      DatedDataCollectionGen<double> mults = GetMults();

      double lastMult = 1d;

      List<DateTime> eventDates = new List<DateTime>();
      eventDates.AddRange(oldWts.Dates);

      for (int i = 1; i < mults.Length; ++i)
      {
        if (mults.Data[i] != mults.Data[i - 1])
          eventDates.Add(mults.Dates[i]);
      }
      QuickSort.Sort<DateTime>(eventDates);

      ConstructGen<double> newwts = new ConstructGen<double>(oldWts.ArrayLength);
      newwts.ColumnHeadings = oldWts.ColumnHeadings;

      for (int i = 0; i < eventDates.Count; ++i)
      {
        // change in mult?
        if (mults.HasDate(eventDates[i]))
          lastMult = mults.Data[mults.IndexOf(eventDates[i])];

        int oldWtsDateIndex = oldWts.FindIndexOfEffectiveDateOnDate(eventDates[i]);

        if (oldWtsDateIndex == -1) continue;
        
        newwts.SetValues(eventDates[i], oldWts.GetValues(oldWts.Dates[oldWtsDateIndex]).MultiplyBy(lastMult));
      }

      //mults.DisplayLineChart(string.Format("{0} percentage of risk",strat_.ToString()));

      return newwts;
    }
Example #24
0
    public static KeyValuePair<TraderArgs, ConstructGen<double>> GetBackTestWeights(CarryOptARgs args_)
    {
      TraderArgs args = new TraderArgs();

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

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

      var dates = args_.Freq == RebalFreq.ParticularDate
        ? Trader.GenerateRebalDates(args.RebalFrequency, args.ParticularDate)
        : Trader.GetRebalDates(args, MyCalendar.NextDayOfWeek(SI.Data.DataConstants.DATA_START, DayOfWeek.Tuesday));

      var carryCon =
        Singleton<FXCarry>.Instance.GetData(
          startDate_: MyCalendar.PrevWeekDay(dates[0].AddDays(-2d*args_.DaysToAverageCarryNDF)),
          endDate_: DateTime.Today);

      var tranCosts = Singleton<FXTransactionCosts>.Instance.GetData(MyCalendar.PrevWeekDay(dates[0].AddDays(-10d)), DateTime.Today, false);
      var dxyScores = Singleton<DXYScore_21>.Instance.Scores;

      DatedDataCollectionGen<double> outScores = null;
      double outthreshold = 0d;

      switch (args_.OutMethod)
      {
        case CarryOptARgs.CarryOutMethod.ATMVolsPercentileAbove50:
          outScores = Singleton<ATMVolsRank>.Instance.ATM_1W_o1Y;
          outthreshold = 0.5;
          break;
        case CarryOptARgs.CarryOutMethod.MOVEIndexPercentilAbove50:
          outScores = Singleton<MOVEScore_21>.Instance.Pxs.ToPercentileRanked(252);
          outthreshold = 0.5;
          break;
        default:
          outScores = null;
          outthreshold = 0d;
          break;
      }


      int numCcys = args.Products.Count;

      var 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 = 1d;
      double usdMax = 1d;

      /* target vol */
      double targetVol = args_.TargetVol;

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

        var simCov = getCovarianceItem(date, args_.SimCov, args_.HistCovarWindowLength);
        var scaleCov = (args_.ScaleCov == args_.SimCov) ? simCov : getCovarianceItem(date, args_.ScaleCov, args_.HistCovarWindowLength);

        /* covariance */
        double[,] cov = simCov.Data;

        /* carry */
        double[] carry = new double[numCcys];
        {
          // need to take 5 day average starting on the day before the date we're rebalancing
          int endIndex = carryCon.Dates.Contains(date) ? carryCon.Dates.IndexOf(date) - 1 : carryCon.Dates.Count - 1;
          for (int i = 0; i < carryCon.ArrayLength; ++i)
          {
            // currency isn't valid = carry stays at zero
            if (Singleton<FXIDs>.Instance[i].IsValid(date) == false)
              continue;

            var cryLength = Singleton<FXIDs>.Instance[i].IsGroup(FXGroup.NDF)
              ? args_.DaysToAverageCarryNDF
              : args_.DaysToAverageCarry;

            double sum = 0d;
            for (int j = 0; j < cryLength; ++j)
              sum += carryCon.GetValue(carryCon.Dates[endIndex - j], i);

            carry[i] = sum / Convert.ToDouble(cryLength);

            Logger.Debug(
              string.Format("Carry of {0} over {1} = {2}", Singleton<FXIDs>.Instance[i], cryLength, carry[i]),
              typeof (Carry));
          }
        }

        /* tcosts */
        double[] tcosts = new double[numCcys];
        {
          if (args_.IncludeTranCosts)
          {
            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 (args_.PrevWeights != null)
            prevWts = args_.PrevWeights;
          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;

            mins[i] = !args_.ShouldIncludeCurrency(date,ccy) ? 0d : -args_.GetWeightConstraint(ccy); 
            maxs[i] = !args_.ShouldIncludeCurrency(date, ccy) ? 0d : args_.GetWeightConstraint(ccy); 
          }
        }

        switch (args_.USDConstraints)
        {
          case CarryOptARgs.DXYConstraint.Dynamic:
          {
            /* USD min max */
            double score = (args_.DXYScore != 0d) ? args_.DXYScore : dxyScores.ValueOnDate(date, -1);
            if (score > 1d)
            {
              usdMin = 1d;
              usdMax = 5d;
            }
            else if (score < -1d)
            {
              usdMin = -5d;
              usdMax = 1d;
            }
            else
            {
              usdMin = 1d;
              usdMax = 1d;
            }
          }
            break;
          case CarryOptARgs.DXYConstraint.Flat:
          {
            usdMin = 1d;
            usdMax = 1d;
          }
            break;
          case CarryOptARgs.DXYConstraint.None:
          {
            usdMin = -5d;
            usdMax = 5d;
          }
            break;
        }

        var result = Singleton<ExcelOptimizer>.Instance.DoIt(
          numCcys, targetVol, cov, carry, tcosts, prevWts, mins, maxs, usdMin, usdMax, optHorizon, date);

        double[] optWts = result.Wts;

        if (args_.ScaleCov != args_.SimCov)
          optWts = scaleCov.ScaleSeries(optWts, targetVol);

        if (outScores != null && outScores.ValueOnDate(date) > outthreshold)
          optWts = new double[optWts.Length];

        wts.SetValues(date, optWts);
      }

      Singleton<ExcelOptimizer>.Instance.Dispose();

      return new KeyValuePair<TraderArgs, ConstructGen<double>>(args, wts);
    }