Пример #1
0
        protected Extremum GetExtremum(IBaseTradeStatisticsWithKind tradeStatistics, int barIndex, ref double lastPrice)
        {
            var bars = tradeStatistics.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));
        }
        public IList <double> Execute(IBaseTradeStatisticsWithKind tradeStatistics)
        {
            var          histograms           = tradeStatistics.GetHistograms();
            var          tradeHistogramsCache = tradeStatistics.TradeHistogramsCache;
            var          barsCount            = tradeHistogramsCache.Bars.Count;
            var          trimLevel            = TrimValue;
            const double DefaultValue         = 0;

            if (histograms.Count == 0 || histograms.All(item => item.Bars.Count == 0) || double.IsNaN(trimLevel))
            {
                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;

            if (canBeCached)
            {
                id      = string.Join(".", runtime.TradeName, runtime.IsAgentMode, VariableId);
                stateId = string.Join(".", TrimValue, TrimComparisonMode, 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));
                    }
                }
                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] = DefaultValue;
            }

            var isInRangeFunc = GetIsInRangeFunc();

            lock (tradeStatistics.Source)
            {
                for (var i = Math.Max(cachedCount, firstBarIndex); i <= lastBarIndex; i++)
                {
                    var bars = tradeStatistics.GetAggregatedHistogramBars(i);
                    results[i] = GetResult(tradeStatistics, bars.Where(item => isInRangeFunc(tradeStatistics, item)));
                }
            }
            for (var i = Math.Max(cachedCount, lastBarIndex + 1); i < barsCount; i++)
            {
                results[i] = DefaultValue;
            }

            if (canBeCached)
            {
                DerivativeTradeStatisticsCache.Instance.SetContext(id, stateId, tradeHistogramsCache, results, context);
            }

            return(results);
        }
        protected IList <double> Execute(
            IBaseTradeStatisticsWithKind tradeStatistics,
            TrimContext tradesCountTrimContext,
            TrimContext quantityTrimContext,
            TrimContext askQuantityTrimContext,
            TrimContext bidQuantityTrimContext,
            TrimContext deltaAskBidQuantityTrimContext,
            TrimContext relativeDeltaAskBidQuantityPercentTrimContext)
        {
            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) ||
                IsInvalid(tradesCountTrimContext) ||
                IsInvalid(quantityTrimContext) ||
                IsInvalid(askQuantityTrimContext) ||
                IsInvalid(bidQuantityTrimContext) ||
                IsInvalid(deltaAskBidQuantityTrimContext) ||
                IsInvalid(relativeDeltaAskBidQuantityPercentTrimContext))
            {
                return(new ConstGenBase <double>(barsCount, DefaultValue));
            }
            var isInRangeFuncs = new List <Func <ITradeHistogramBar, bool> >();

            if (tradesCountTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.TradesCount, tradesCountTrimContext));
            }

            if (quantityTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.Quantity, quantityTrimContext));
            }

            if (askQuantityTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.AskQuantity, askQuantityTrimContext));
            }

            if (bidQuantityTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.BidQuantity, bidQuantityTrimContext));
            }

            if (deltaAskBidQuantityTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.DeltaAskBidQuantity, deltaAskBidQuantityTrimContext));
            }

            if (relativeDeltaAskBidQuantityPercentTrimContext.UseTrimValue)
            {
                isInRangeFuncs.Add(GetIsInRangeFunc(tradeStatistics, TradeStatisticsKind.RelativeDeltaAskBidQuantityPercent, relativeDeltaAskBidQuantityPercentTrimContext));
            }

            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;

            if (canBeCached)
            {
                id      = string.Join(".", runtime.TradeName, runtime.IsAgentMode, VariableId);
                stateId = GetParametersStateId() + "." + 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));
                    }
                }
                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] = DefaultValue;
            }

            lock (tradeStatistics.Source)
            {
                for (var i = Math.Max(cachedCount, firstBarIndex); i <= lastBarIndex; i++)
                {
                    var bars         = tradeStatistics.GetAggregatedHistogramBars(i);
                    var selectedBars = isInRangeFuncs.Count > 0
                        ? bars.Where(bar => isInRangeFuncs.All(item => item(bar)))
                        : bars;

                    results[i] = GetResult(tradeStatistics, selectedBars);
                }
            }
            for (var i = Math.Max(cachedCount, lastBarIndex + 1); i < barsCount; i++)
            {
                results[i] = DefaultValue;
            }

            if (canBeCached)
            {
                DerivativeTradeStatisticsCache.Instance.SetContext(id, stateId, tradeHistogramsCache, results, context);
            }

            return(results);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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;
            }

            lock (tradeStatistics.Source)
            {
                iMax = Math.Min(lastBarIndex, pricesCount - 1);
                for (var i = Math.Max(cachedCount, firstBarIndex); i <= iMax; i++)
                {
                    var histogramBars = tradeStatistics.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);
        }