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; }
public static double[] weightFX(double[] input_, CovarianceItem covar_, TraderArgs args_,double targetVol_) { double[] scaleThis = new double[covar_.ComponentIds.Count]; int[] indices = new int[input_.Length]; for (int i = 0; i < args_.Products.Count; ++i) { indices[i] = covar_.ComponentIds.IndexOf(((ProductFX)args_.Products[i]).CoreProduct.ID); scaleThis[indices[i]] = input_[i]; } double[] scaled = covar_.ScaleSeries(scaleThis, targetVol_,args_.ScaleUsingDiagMatrix); // contrains weights? if (args_.WtConstraints != null && args_.WtConstraints.Enabled) { bool cont = true; int iterationCount = 0; double tolerance = 0.05; // 5% tolerance on constraint int iterationMax = 100; while (cont && iterationCount < iterationMax) { cont = false; double upperLimit = args_.WtConstraints.UpperConstraint + Math.Abs(args_.WtConstraints.UpperConstraint * tolerance); double lowerLimit = args_.WtConstraints.LowerConstraint - Math.Abs(args_.WtConstraints.LowerConstraint * tolerance); for (int i = 0; i < scaled.Length; ++i) { if (scaled[i] < lowerLimit) { scaled[i] = args_.WtConstraints.LowerConstraint; } if (scaled[i] > upperLimit) { scaled[i] = args_.WtConstraints.UpperConstraint; } } if (args_.WtConstraints.ReScale) { scaled = covar_.ScaleSeries(scaled, targetVol_); cont = true; } ++iterationCount; } } // reshape into length of input products... double[] ret = new double[input_.Length]; for (int i = 0; i < input_.Length; ++i) ret[i] = scaled[indices[i]]; return ret; }
public void Go() { var allweights=new ConstructGen<WeightsLine>(Spreads.Length); // mark each of the individual spread weight entry/exit points in the construct - could well be different dates per spread... for(int i=0;i<Spreads.Length;++i) { var wts = Spreads[i].GenerateWeights(); foreach (var wt in wts) { if (wt.EntryDate <= DateTime.Today) allweights.SetValue(wt.EntryDate, i, wt); if (wt.ExitDate <= DateTime.Today) allweights.SetValue(wt.ExitDate, i, wt); } } allweights.SortKeys(); // on each date, note the positions that are carried over from an earlier trade on the same day, so that we have a // full picture of what is in play on that day WeightsLine[] prev = null; foreach (var date in allweights.Dates) { var todays = allweights.GetValues(date); if (prev != null) { for (int i = 0; i < todays.Length; ++i) { if (prev[i] != null && todays[i]==null && date <= prev[i].ExitDate) todays[i] = prev[i]; } } prev = todays; } if (allweights.NeedsToSortKeys()) allweights.SortKeys(); // go through each of the dates to generate a covariance and scale the positions foreach (DateTime date in allweights.Keys) { var arr = allweights.GetValues(date); // build up list of indicies that are live on the current date var liveIndicies = new List<int>(); for (int i = 0; i < arr.Length; ++i) if (arr[i] != null && arr[i].ExitDate > date) liveIndicies.Add(i); if (!liveIndicies.Any()) continue; var liveItems = liveIndicies.Select(x => arr[x]).ToArray(); // for all live items form an array of recent returns over of length 'NumDaysForCovariance' var returns = new double[NumDaysForCovariance, liveIndicies.Count()]; var rawSpreadWeights = new double[liveIndicies.Count()]; for (int i = 0; i < liveIndicies.Count; ++i) { var indexReturns = liveItems[i].GetAllSpreadReturns(); // have prices been updated? if (indexReturns.LastDate < date) continue; int indexOfDate = indexReturns.IndexOfElsePrevious(date); --indexOfDate; var slice = indexReturns.Data.Slice(indexOfDate - NumDaysForCovariance + 1, NumDaysForCovariance); rawSpreadWeights[i] = liveItems[i].SpreadWeight/Statistics.Stdev(slice); returns.SetColumn(i, slice); } // buil the covariance var covar = new CovarianceItem(Utils.CalculateCovariance(returns)); // vol bucketing var targetvol = liveItems.Length*0.02; // scale the weights var newwts = covar.ScaleSeries(rawSpreadWeights, targetvol); for (int i = 0; i < newwts.Length; ++i) liveItems[i].AddCombineWeight(date, newwts[i]); } }