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; }
private void buildCovariants(CovarianceItem cov_) { m_variant.Clear(); int num = cov_.Data.GetLength(0); for (int i = 0; i < num; ++i) for (int j = 0; j < num; ++j) { m_variant.Add(new Variant() { CcyI = i, CcyJ = j, Variance = cov_.Data[i, j] }); } }
public void Ensure(DateTime[] orderedDates_, int windowLength_) { // need to check if we have all of them already List<DateTime> missingDates = new List<DateTime>(); foreach (DateTime d in orderedDates_) { CacheKey k = new CacheKey(windowLength_, d); if (!m_list.ContainsKey(k)) missingDates.Add(k.Date); } if (missingDates.Count == 0) return; // get the spots for a year before the first date DateTime startDate = missingDates[0].AddYears(-2); var allReturns = Singleton<FXSpots>.Instance.GetData(startDate, DateTime.Today).ToLogReturns(Singleton<FXIDs>.Instance.Select(x=>(double)x.Convention).ToArray()); double[,] array; for (int i = 0; i < allReturns.Dates.Count; ++i) { // do we want a covariance matrix for this date? if (!missingDates.Contains(allReturns.Dates[i])) { continue; } // construct the array of returns over the window array = new double[windowLength_, allReturns.ArrayLength]; for (int j = 0; j < windowLength_; ++j) { var date = allReturns.Dates[i - windowLength_ + j]; var values = allReturns.GetValues(date); for (int y = 0; y < array.GetLength(1); ++y) array[j, y] = (values[y]); } double[,] covar = MatCovar(array); // calc the covariance matrix //NMathCore.DoubleMatrix m=NMathStats.StatsFunctions.CovarianceMatrix(new NMathCore.DoubleMatrix(array), NMathStats.BiasType.Biased); // store the value CacheKey key = new CacheKey(windowLength_, allReturns.Dates[i]); m_list[key] = new CovarianceItem(covar); } if (missingDates.Contains(DateTime.Today)) { array = new double[windowLength_, allReturns.ArrayLength]; for (int j = 0; j < windowLength_; ++j) { var date = allReturns.Dates.Last(); var values = allReturns.GetValues(date); for (int y = 0; y < values.Length; ++y) array[j, y] = values[y]; } double[,] covar = MatCovar(array); CacheKey key = new CacheKey(windowLength_, DateTime.Today); m_list[key] = new CovarianceItem(covar); } }
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]); } }