public static ConstructGen<double> getFilters(TraderArgs args_, List<DateTime> rebalDates_, IDictionary<ProductBase,List<DatedDataCollectionGen<double>>> resultsFilter_) { ConstructGen<double> ret = new ConstructGen<double>(args_.Products.Count); if (resultsFilter_==null || resultsFilter_.Count == 0) { ret.InitialiseToValue(rebalDates_, 1d); } else { for (int j = 0; j < args_.Products.Count; ++j) { DatedDataCollectionGen<double> dataForProductAndFilter = resultsFilter_[args_.Products[j]][0]; foreach (DateTime date in rebalDates_) { ret.SetValue( date, j, dataForProductAndFilter.ValueOnDate(date, args_.DayOffset)); } } } // use this opportunity to count out those products that are not valid on this date for (int j = 0; j < args_.Products.Count; ++j) { foreach (DateTime date in rebalDates_) { if (args_.Products[j].IsValid(date) == false) ret.SetValue(date, j, double.NaN); } } // ConstructDisplay.Show(ret, args_.Products.ToArray(), "Filter series"); return ret; }
private ConstructGen<double>[] getWeights(TraderArgs args_, List<DateTime> rebalDates_, ConstructGen<double> filter_) { if (m_resultsWts.Count == 0) return null; ConstructGen<double>[] allWts = new ConstructGen<double>[args_.WtIndicators.Count]; // go through all wtIndicators - will normally only be one for (int i = 0; i < args_.WtIndicators.Count; ++i) { ConstructGen<double> all_c,rebal_c; int length = args_.Products.Count; all_c = new ConstructGen<double>(length); rebal_c = new ConstructGen<double>(length); for (int j = 0; j < args_.Products.Count; ++j) { // extract the signal series for this wtIndicator and product DatedDataCollectionGen<double> dataForProductAndIndicator = m_resultsWts[args_.Products[j]][i]; // put the data in the contruct that represents the signal at every point for (int y = 0; y < dataForProductAndIndicator.Length; ++y) all_c.SetValue( dataForProductAndIndicator.Dates[y], j, dataForProductAndIndicator.Data[y]); // put the data in the construct that represents the signal just on rebal days // NOTE: is offset by 1 day so not in sample foreach (DateTime d in rebalDates_) { //if (d == new DateTime(2010, 3, 19)) // System.Diagnostics.Debugger.Break(); if (args_.Products[j].IsValid(d)) rebal_c.SetValue(d, j, dataForProductAndIndicator.ValueOnDate(d, args_.DayOffset)); } } // c is now a representation of the signal for all products on all days // do we want the product of the weights to determine which products can have positions on different days? if (args_.UseWeightsForFilter) { foreach (DateTime d in rebalDates_) { for (int ii = 0; ii < rebal_c.ArrayLength; ++ii) if (double.IsNaN(rebal_c.GetValue(d, ii))) filter_.SetValue(d, ii, double.NaN); } } // multiply it by the filter to get rid of non-eligible days rebal_c = multiply(rebal_c, filter_,false); //ConstructDisplay.Show(rebal_c, args_.Products.ToArray(), "raw signal * filter"); // now need to scale the weights based on the weighting scheme supplied on the signal indicator // create a construct which will be the multiple foreach (SI.Research.Backtest.Builder.Model.WtScheme transform in args_.WtIndicators[i].TransformList) { ConstructGen<double> wts = new ConstructGen<double>(length); wts.InitialiseToValue(rebalDates_,1d); transform.DoWeights(rebal_c, all_c, wts, args_.Products,filter_); wts = multiply(wts, filter_, true); rebal_c = wts; //ConstructDisplay.Show(rebal_c, args_.Products.ToArray(), "weights"); } //ConstructDisplay.Show(rebal_c, new object[] { "wts" }, "transformed weights"); allWts[i] = rebal_c; } return allWts; }
public override void DoWeights(ConstructGen<double> signalResults_, ConstructGen<double> fullSignalResults_, ConstructGen<double> wts_, List<ProductBase> products_, ConstructGen<double> filters_) { List<SortHelpClass> list = new List<SortHelpClass>(); // go through each rebal date foreach (DateTime date in wts_.Dates) { list.Clear(); // pull out values and put into the list to sort for (int i = 0; i < wts_.ArrayLength; ++i) { double val = signalResults_.GetValue(date, i); double filt = filters_.GetValue(date, i); // has been filtered out already? (indicated by NaN) if (double.IsNaN(filt) == false) { // filter out certain values? if (m_filterOutValues && (val >= m_lowerFilterOut && val <= m_higherFilterOut)) continue; list.Add(new SortHelpClass(val, i, m_abs, m_smallestTopWeight,ReverseNegativeOrder)); } } // sort the list QuickSort.Sort<SortHelpClass>(list); // initialise the values to zero wts_.InitialiseToValue(date, 0.0); // determine how many to select (can't selected more than number in list) int topCount = (m_topCount > list.Count) ? list.Count : m_topCount; int bottomCount = (m_bottomCount > list.Count) ? list.Count : m_bottomCount; if (topCount == 0) topCount = Convert.ToInt32(TopPercentage * Convert.ToDouble(list.Count)); if (bottomCount == 0) bottomCount = Convert.ToInt32(BottomPercentage * Convert.ToDouble(list.Count)); // ensure that, if doing top and bottom, there isn't overlap over the list if (m_doTop && m_doBottom && (topCount + bottomCount) > list.Count) { if (PickInLineWithSign) { int posCount = 0; int negCount = 0; foreach (SortHelpClass shc in list) { if (shc.Value > 0) ++posCount; else ++negCount; } topCount = posCount; bottomCount = negCount; } else { if (list.Count % 2 == 0) topCount = bottomCount = (list.Count / 2); else topCount = bottomCount = ((list.Count - 1) / 2); } } if (m_doTop) { for (int i = 0; i < topCount; ++i) { wts_.SetValue(date, list[i].ArrayIndex, getWeight(list[i].Value, i + 1, topCount, true)); } } if (m_doBottom) { for (int i = 0; i < bottomCount; ++i) { int index = list.Count - 1 - i; wts_.SetValue(date, list[index].ArrayIndex, getWeight(list[index].Value, i + 1, bottomCount, false)); } } } }