protected Extremum GetExtremum(IBaseTradeStatisticsWithKind tradeStatistics, IAggregatedHistogramBarsProvider aggregatedHistogramBarsProvider, int barIndex, ref double lastPrice) { var bars = aggregatedHistogramBarsProvider.GetAggregatedHistogramBars(barIndex); if (bars.Count == 0) { return(new Extremum(null, double.NaN, lastPrice)); } if (bars.Count == 1) { var bar = bars[0]; return(new Extremum(bar, Math.Abs(tradeStatistics.GetValue(bar)), lastPrice = bar.AveragePrice)); } IEnumerable <ITradeHistogramBar> orderedBars; switch (PriceMode) { case ExtremumPriceMode.Minimum: orderedBars = bars; break; case ExtremumPriceMode.Maximum: orderedBars = bars.Reverse(); break; default: throw new InvalidEnumArgumentException(nameof(PriceMode), (int)PriceMode, PriceMode.GetType()); } var extremumBar = orderedBars.First(); var extremumValue = Math.Abs(tradeStatistics.GetValue(extremumBar)); foreach (var bar in orderedBars.Skip(1)) { var value = Math.Abs(tradeStatistics.GetValue(bar)); if (extremumValue < value) { extremumBar = bar; extremumValue = value; } } return(new Extremum(extremumBar, extremumValue, lastPrice = extremumBar.AveragePrice)); }
private double GetPrice(IBaseTradeStatisticsWithKind tradeStatistics, int barIndex, double lastPrice) { var bars = tradeStatistics.GetAggregatedHistogramBars(barIndex); if (bars.Count == 0) { return(lastPrice); } var allValuesSum = bars.Sum(item => Math.Abs(tradeStatistics.GetValue(item))); if (allValuesSum == 0) { return(lastPrice); } var trimLevelPercent = TrimLevelPercent; if (trimLevelPercent == 0) { return(GetFirstPrice(bars)); } if (trimLevelPercent == 100) { return(GetLastPrice(bars)); } var edgeValuesSum = allValuesSum * trimLevelPercent / 100; foreach (var bar in GetOrderedBars(bars)) { var value = Math.Abs(tradeStatistics.GetValue(bar)); if (edgeValuesSum <= value) { var result = GetPrice(bar, edgeValuesSum / value); return(result); } edgeValuesSum -= value; } return(GetLastPrice(bars)); }
private static Func <ITradeHistogramBar, bool> GetIsInRangeFunc(IBaseTradeStatisticsWithKind tradeStatistics, TradeStatisticsKind tradeStatisticsKind, TrimContext trimContext) { var trimComparisonMode = trimContext.TrimComparisonMode; switch (trimComparisonMode) { case ComparisonMode.Greater: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) > trimContext.TrimValue); case ComparisonMode.GreaterOrEqual: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) >= trimContext.TrimValue); case ComparisonMode.Less: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) < trimContext.TrimValue); case ComparisonMode.LessOrEqual: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) <= trimContext.TrimValue); case ComparisonMode.AreEqual: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) == trimContext.TrimValue); case ComparisonMode.AreNotEqual: return(bar => tradeStatistics.GetValue(bar, tradeStatisticsKind) != trimContext.TrimValue); default: throw new InvalidEnumArgumentException(nameof(trimComparisonMode), (int)trimComparisonMode, trimComparisonMode.GetType()); } }
public IList <double> Execute(IBaseTradeStatisticsWithKind tradeStatistics, IList <double> prices) { var histograms = tradeStatistics.GetHistograms(); var tradeHistogramsCache = tradeStatistics.TradeHistogramsCache; const double DefaultValue = 0; var pricesCount = prices.Count; if (histograms.Count == 0 || histograms.All(item => item.Bars.Count == 0) || pricesCount == 0) { return(new ConstGenBase <double>(prices.Count, DefaultValue)); } double[] results = null; var runtime = Context?.Runtime; var canBeCached = tradeStatistics.HasStaticTimeline && tradeHistogramsCache.Bars.Count > 1 && pricesCount > 1 && runtime != null; string id = null, stateId = null; DerivativeTradeStatisticsCacheContext context = null; var cachedCount = 0; if (canBeCached) { id = string.Join(".", runtime.TradeName, runtime.IsAgentMode, VariableId); stateId = tradeStatistics.StateId; context = DerivativeTradeStatisticsCache.Instance.GetContext(id, stateId, tradeHistogramsCache); if (context != null) { var cachedResults = context.Values; cachedCount = Math.Min(cachedResults.Length, pricesCount) - 1; if (cachedResults.Length == pricesCount) { results = cachedResults; } else { Buffer.BlockCopy(cachedResults, 0, results = new double[pricesCount], 0, cachedCount * sizeof(double)); } } else { results = new double[pricesCount]; } } else { results = Context?.GetArray <double>(pricesCount) ?? new double[pricesCount]; } tradeStatistics.GetHistogramsBarIndexes(out var firstBarIndex, out var lastBarIndex); var iMax = Math.Min(firstBarIndex, pricesCount); for (var i = cachedCount; i < iMax; i++) { results[i] = DefaultValue; } iMax = Math.Min(lastBarIndex, pricesCount - 1); var aggregatedHistogramBarsProvider = tradeStatistics.CreateAggregatedHistogramBarsProvider(); for (var i = Math.Max(cachedCount, firstBarIndex); i <= iMax; i++) { var histogramBars = aggregatedHistogramBarsProvider.GetAggregatedHistogramBars(i); if (histogramBars.Count > 1) { var price = prices[i]; var lowPrice = histogramBars[0].LowPrice; var index = (int)((price - lowPrice) / tradeStatistics.PriceStep); if (price >= lowPrice + tradeStatistics.PriceStep * (index + 1)) // PROD-5600 { index++; // имеем погрешность примерно в 1e13 при делении, лечим проверкой } results[i] = index >= 0 && index < histogramBars.Count ? tradeStatistics.GetValue(histogramBars[index]) : DefaultValue; } else if (histogramBars.Count == 1) { var price = prices[i]; var histogramBar = histogramBars[0]; results[i] = price >= histogramBar.LowPrice && price < histogramBar.HighPrice ? tradeStatistics.GetValue(histogramBar) : DefaultValue; } else { results[i] = DefaultValue; } } for (var i = Math.Max(cachedCount, lastBarIndex + 1); i < pricesCount; i++) { results[i] = DefaultValue; } if (canBeCached) { DerivativeTradeStatisticsCache.Instance.SetContext(id, stateId, tradeHistogramsCache, results, context); } return(results); }
protected override double GetResult(IBaseTradeStatisticsWithKind tradeStatistics, IEnumerable <ITradeHistogramBar> bars) { return(bars.Sum(item => tradeStatistics.GetValue(item, Kind))); }
public IList <double> Execute(IBaseTradeStatisticsWithKind tradeStatistics) { var histograms = tradeStatistics.GetHistograms(); var tradeHistogramsCache = tradeStatistics.TradeHistogramsCache; var barsCount = tradeHistogramsCache.Bars.Count; const double DefaultValue = double.NaN; if (histograms.Count == 0 || histograms.All(item => item.Bars.Count == 0)) { return(new ConstGenBase <double>(barsCount, DefaultValue)); } double[] results = null; var runtime = Context?.Runtime; var canBeCached = tradeStatistics.HasStaticTimeline && barsCount > 1 && runtime != null; string id = null, stateId = null; DerivativeTradeStatisticsCacheContext context = null; var cachedCount = 0; var lastResult = DefaultValue; if (canBeCached) { id = string.Join(".", runtime.TradeName, runtime.IsAgentMode, VariableId); stateId = tradeStatistics.StateId; context = DerivativeTradeStatisticsCache.Instance.GetContext(id, stateId, tradeHistogramsCache); if (context != null) { var cachedResults = context.Values; cachedCount = Math.Min(cachedResults.Length, barsCount) - 1; if (cachedResults.Length == barsCount) { results = cachedResults; } else { Buffer.BlockCopy(cachedResults, 0, results = new double[barsCount], 0, cachedCount * sizeof(double)); } lastResult = results[cachedCount - 1]; } else { results = new double[barsCount]; } } else { results = Context?.GetArray <double>(barsCount) ?? new double[barsCount]; } tradeStatistics.GetHistogramsBarIndexes(out var firstBarIndex, out var lastBarIndex); for (var i = cachedCount; i < firstBarIndex; i++) { results[i] = lastResult; } lock (tradeStatistics.Source) { for (var i = Math.Max(cachedCount, firstBarIndex); i <= lastBarIndex; i++) { var bars = tradeStatistics.GetAggregatedHistogramBars(i); if (bars.Count > 0) { double maxValue, minValue; maxValue = minValue = tradeStatistics.GetValue(bars[0]); foreach (var bar in bars.Skip(1)) { var value = tradeStatistics.GetValue(bar); if (maxValue < value) { maxValue = value; } else if (minValue > value) { minValue = value; } } lastResult = Math.Abs(maxValue) >= Math.Abs(minValue) ? maxValue : minValue; } results[i] = lastResult; } } for (var i = Math.Max(cachedCount, lastBarIndex + 1); i < barsCount; i++) { results[i] = lastResult; } if (canBeCached) { DerivativeTradeStatisticsCache.Instance.SetContext(id, stateId, tradeHistogramsCache, results, context); } return(results); }