//************************************************************************************** /// <summary> /// Calculates average precision as seen by implied simulation. /// </summary> private static float CalculateAveragePrecision(List <WekaClassifier> iClassifiers) { var weight = new List <float>(iClassifiers.Count); var precisions = new List <float>(); var classfiers = WekaClassifier.SplitByProfitTime(iClassifiers); foreach (KeyValuePair <int, List <WekaClassifier> > pair in classfiers) { var p = WekaClassifier.GetAveragePrecision(pair.Value); precisions.Add(p); weight.Add((float)(Math.Pow(p, 6) / Math.Pow(pair.Value[0].GetProfitsStdDev(), 6))); } return(Statistics.WeightedArithmeticMean(precisions.ToArray(), Statistics.Normalize(weight.ToArray()))); }
//************************************************************************************** /// <summary> /// Starts simulation starting from the end of historical candlesticksm and up to prediction duration. /// </summary> private static void Start(CandlestickCollection iHistoricalCandlesticks, CandlestickCollection iCandlesticks, List <WekaClassifier> iClassifiers, int iPredictionDuration) { var index = new CandlestickIndexCollection(); var candlesticks = iCandlesticks; var classfiers = WekaClassifier.SplitByProfitTime(iClassifiers); var initialCount = candlesticks[WekaClassifier.kTrainingPeriod].Count; var startIndex = Math.Max(initialCount - classfiers.Keys.Max() - 1, 1); var endIndex = initialCount + iPredictionDuration - 1; var priceDiffStdDev = Statistics.StandardDeviation(Statistics.CalculateDifferences(iHistoricalCandlesticks[WekaClassifier.kTrainingPeriod].Select(x => x.MedianPrice).ToArray())); var wfp = new SortedDictionary <int, List <float> >(); var weight = new List <float>(classfiers.Count); foreach (KeyValuePair <int, List <WekaClassifier> > pair in classfiers) { wfp.Add(pair.Key, new List <float>()); var precision = WekaClassifier.GetAveragePrecision(pair.Value); weight.Add((float)(Math.Pow(precision, 6) / Math.Pow(pair.Value[0].GetProfitsStdDev(), 6.0f))); } weight = Statistics.Normalize(weight.ToArray()).ToList(); for (int i = startIndex; i <= endIndex; i++) { // Update indexes for (int k = (int)WekaClassifier.kTrainingPeriod; k >= 0; k--) { index[k] = Math.Max(0, Math.Min(candlesticks[k].Count - 1, Candlestick.FindIndex(candlesticks[k], candlesticks[WekaClassifier.kTrainingPeriod][i].StartTime, index[k]) - 1)); } // Extract current price var p = candlesticks[WekaClassifier.kTrainingPeriod][i].MedianPrice; // Calculate WFP foreach (KeyValuePair <int, List <WekaClassifier> > pair in classfiers) { if (i >= initialCount - pair.Key - 1) { var predictionsNow = WekaClassifier.PredictFP(pair.Value, p, candlesticks, index); var wfpNow = WekaClassifier.FPToWFP(pair.Value, predictionsNow); wfp[pair.Key].Add(wfpNow); } } // Future if (i + 1 >= initialCount) { var lastCandle = candlesticks[WekaClassifier.kTrainingPeriod][candlesticks[WekaClassifier.kTrainingPeriod].Count - 1]; var estimatedPrices = new List <float>(classfiers.Count); foreach (KeyValuePair <int, List <WekaClassifier> > pair in classfiers) { estimatedPrices.Add(EstimatePrice(pair.Key, wfp[pair.Key], candlesticks[WekaClassifier.kTrainingPeriod])); } var targetPrice = Statistics.WeightedArithmeticMean(estimatedPrices.ToArray(), weight.ToArray()); targetPrice = Statistics.Clamp(targetPrice, lastCandle.MedianPrice * (1.0f - 3.0f * priceDiffStdDev), lastCandle.MedianPrice * (1.0f + 3.0f * priceDiffStdDev)); var candle = new Candlestick(lastCandle.EndTime, lastCandle.EndTime + 86400000 / (ulong)Candlestick.PeriodToDaily(Candlestick.Period.H1), lastCandle.ClosePrice, targetPrice, Math.Max(lastCandle.ClosePrice, targetPrice), Math.Min(lastCandle.ClosePrice, targetPrice), targetPrice); candlesticks.Add(candle, WekaClassifier.kTrainingPeriod); } } }