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); }
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; }
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; }
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) }; }
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(); }
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); }
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; }
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 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); }
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; }
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; }
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 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); }
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; }
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; //} }
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()); } }
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; }
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); }