diff --git a/KLHZ.Trader.Core.Math/Declisions/Utils/MovingAverage.cs b/KLHZ.Trader.Core.Math/Declisions/Utils/MovingAverage.cs index aa33551..7c76e29 100644 --- a/KLHZ.Trader.Core.Math/Declisions/Utils/MovingAverage.cs +++ b/KLHZ.Trader.Core.Math/Declisions/Utils/MovingAverage.cs @@ -18,41 +18,44 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils return (startTime, sum / count); } - public static TradingEvent CheckByWindowAverageMean(DateTime[] timestamps, decimal[] prices, int size, decimal meanfullStep = 3m) + public static TradingEvent CheckByWindowAverageMean(DateTime[] timestamps, decimal[] prices, int size,int smallWindow, int bigWindow, decimal meanfullStep = 3m) { var res = TradingEvent.None; if (timestamps.Length < size) { return res; } - var twav15s = new decimal[size]; - var twav120s = new decimal[size]; + var pricesForFinalComparison = new decimal[size]; + var twavss = new decimal[size]; + var twavbs = new decimal[size]; var times = new DateTime[size]; for (int shift = 0; shift < size; shift++) { - var twav15 = CalcTimeWindowAverageValue(timestamps, prices, 15, shift); - var twav120 = CalcTimeWindowAverageValue(timestamps, prices, 120, shift); - twav15s[size - 1 - shift] = twav15.value; - twav120s[size - 1 - shift] = twav120.value; - times[size - 1 - shift] = twav120.time; - if (System.Math.Abs(twav120.value - prices[prices.Length - 1]) > 3 * meanfullStep) + var twavs = CalcTimeWindowAverageValue(timestamps, prices, smallWindow, shift); + var twavb = CalcTimeWindowAverageValue(timestamps, prices, bigWindow, shift); + pricesForFinalComparison[size - 1 - shift] = prices[prices.Length - 1 - shift]; + twavss[size - 1 - shift] = twavs.value; + twavbs[size - 1 - shift] = twavb.value; + times[size - 1 - shift] = twavb.time; + if (System.Math.Abs(twavb.value - prices[prices.Length - 1]) > 2 * meanfullStep) { res |= TradingEvent.StopBuy; return res; } if (shift > 0) { - var i1 = size - shift; - var i2 = size - 1 - shift; + var i1 = size - 1 - shift; + var i2 = size - shift; var isCrossing = Lines.IsLinesCrossing( times[i1], times[i2], - twav15s[i1], - twav15s[i2], - twav120s[i1], - twav120s[i2]); + twavss[i1], + twavss[i2], + twavbs[i1], + twavbs[i2]); + if (shift == 1 && !isCrossing) //если нет пересечения скользящих средний с окном 120 и 15 секунд между //текущей и предыдущей точкой - можно не продолжать выполнение. { @@ -61,9 +64,9 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils if (shift > 1 && isCrossing) { // если фильтрация окном 120 наползает на окно 15 сверху, потенциальное время открытия лонга и закрытия шорта - if (twav120s[size - 1] <= twav15s[size - 1] && twav120s[size - 2] > twav15s[size - 2]) + if (twavbs[size - 1] <= twavss[size - 1] && twavbs[size - 2] > twavss[size - 2]) { - if (twav15s[size - 1 - shift] - twav15s[size - 1] >= meanfullStep) + if (pricesForFinalComparison[size - 1 - shift] - pricesForFinalComparison[size - 1] >= meanfullStep) { res |= TradingEvent.LongOpen; res |= TradingEvent.ShortClose; @@ -72,9 +75,9 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils } // если фильтрация окном 15 наползает на окно 120 сверху, потенциальное время закрытия лонга и возможно открытия шорта - if (twav15s[size - 1] <= twav120s[size - 1] && twav15s[size - 2] > twav120s[size - 2]) + if (twavss[size - 1] <= twavbs[size - 1] && twavss[size - 2] > twavbs[size - 2]) { - if (twav15s[size - 1 - shift] - twav15s[size - 1] <= -meanfullStep) + if (pricesForFinalComparison[size - 1 - shift] - pricesForFinalComparison[size - 1] <= -meanfullStep) { res |= TradingEvent.LongClose; res |= TradingEvent.ShortOpen; diff --git a/KLHZ.Trader.Core.Tests/MovingAverageTests.cs b/KLHZ.Trader.Core.Tests/MovingAverageTests.cs deleted file mode 100644 index 1680478..0000000 --- a/KLHZ.Trader.Core.Tests/MovingAverageTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using KLHZ.Trader.Core.DataLayer.Entities.Prices; -using KLHZ.Trader.Core.Math.Common; -using KLHZ.Trader.Core.Math.Declisions.Services.Cache; -using KLHZ.Trader.Core.Math.Declisions.Utils; - -namespace KLHZ.Trader.Core.Tests -{ - public class MovingAverageTests - { - [Test] - public void Test1() - { - var cacheUnit = new PriceHistoryCacheUnit2(""); - for (int i = 0; i < 5 * PriceHistoryCacheUnit2.CacheMaxLength; i++) - { - cacheUnit.AddData(new PriceChange() { Figi = "", Ticker = "", Value = i, Time = DateTime.UtcNow }); - if (i >= 500) - { - var data = cacheUnit.GetData().Result; - Assert.IsTrue(data.prices.Length == PriceHistoryCacheUnit2.CacheMaxLength); - Assert.IsTrue(data.prices.Last() == i); - var res = MovingAverage.CheckByWindowAverageMean(data.timestamps, data.prices, 100); - } - } - } - } -} \ No newline at end of file diff --git a/KLHZ.Trader.Core/Exchange/Services/Trader.cs b/KLHZ.Trader.Core/Exchange/Services/Trader.cs index 3f06c09..ef8e063 100644 --- a/KLHZ.Trader.Core/Exchange/Services/Trader.cs +++ b/KLHZ.Trader.Core/Exchange/Services/Trader.cs @@ -139,10 +139,12 @@ namespace KLHZ.Trader.Core.Exchange.Services { continue; } - var result = MovingAverage.CheckByWindowAverageMean(data.timestamps, data.prices, 100, 2m); + + + var result = MovingAverage.CheckByWindowAverageMean(data.timestamps, data.prices, 100,15,120); if ((result & TradingEvent.StopBuy) == TradingEvent.StopBuy) { - var stopTo = DateTime.UtcNow.AddMinutes(_buyStopLength); + var stopTo = (message.IsHistoricalData?message.Time: DateTime.UtcNow).AddMinutes(_buyStopLength); BuyStops.AddOrUpdate(message.Figi, stopTo, (k, v) => stopTo); declisionsForSave.Add(new Declision() { @@ -160,7 +162,7 @@ namespace KLHZ.Trader.Core.Exchange.Services { if (BuyStops.TryGetValue(message.Figi, out var dt)) { - if (dt > DateTime.UtcNow) + if (dt > (message.IsHistoricalData ? message.Time : DateTime.UtcNow)) { continue; } @@ -169,8 +171,7 @@ namespace KLHZ.Trader.Core.Exchange.Services BuyStops.TryRemove(message.Figi, out _); } } - var stopTo = DateTime.UtcNow.AddMinutes(_buyStopLength); - BuyStops.AddOrUpdate(message.Figi, stopTo, (k, v) => stopTo); + declisionsForSave.Add(new Declision() { AccountId = string.Empty,