добавил анализ скользящими средними
test / deploy_trader_prod (push) Successful in 19m5s Details

main
vlad zverzhkhovskiy 2025-09-02 23:51:10 +03:00
parent d0786cfe19
commit 6884407f12
3 changed files with 28 additions and 51 deletions

View File

@ -18,41 +18,44 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
return (startTime, sum / count); 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; var res = TradingEvent.None;
if (timestamps.Length < size) if (timestamps.Length < size)
{ {
return res; return res;
} }
var twav15s = new decimal[size]; var pricesForFinalComparison = new decimal[size];
var twav120s = new decimal[size]; var twavss = new decimal[size];
var twavbs = new decimal[size];
var times = new DateTime[size]; var times = new DateTime[size];
for (int shift = 0; shift < size; shift++) for (int shift = 0; shift < size; shift++)
{ {
var twav15 = CalcTimeWindowAverageValue(timestamps, prices, 15, shift); var twavs = CalcTimeWindowAverageValue(timestamps, prices, smallWindow, shift);
var twav120 = CalcTimeWindowAverageValue(timestamps, prices, 120, shift); var twavb = CalcTimeWindowAverageValue(timestamps, prices, bigWindow, shift);
twav15s[size - 1 - shift] = twav15.value; pricesForFinalComparison[size - 1 - shift] = prices[prices.Length - 1 - shift];
twav120s[size - 1 - shift] = twav120.value; twavss[size - 1 - shift] = twavs.value;
times[size - 1 - shift] = twav120.time; twavbs[size - 1 - shift] = twavb.value;
if (System.Math.Abs(twav120.value - prices[prices.Length - 1]) > 3 * meanfullStep) times[size - 1 - shift] = twavb.time;
if (System.Math.Abs(twavb.value - prices[prices.Length - 1]) > 2 * meanfullStep)
{ {
res |= TradingEvent.StopBuy; res |= TradingEvent.StopBuy;
return res; return res;
} }
if (shift > 0) if (shift > 0)
{ {
var i1 = size - shift; var i1 = size - 1 - shift;
var i2 = size - 1 - shift; var i2 = size - shift;
var isCrossing = Lines.IsLinesCrossing( var isCrossing = Lines.IsLinesCrossing(
times[i1], times[i1],
times[i2], times[i2],
twav15s[i1], twavss[i1],
twav15s[i2], twavss[i2],
twav120s[i1], twavbs[i1],
twav120s[i2]); twavbs[i2]);
if (shift == 1 && !isCrossing) //если нет пересечения скользящих средний с окном 120 и 15 секунд между if (shift == 1 && !isCrossing) //если нет пересечения скользящих средний с окном 120 и 15 секунд между
//текущей и предыдущей точкой - можно не продолжать выполнение. //текущей и предыдущей точкой - можно не продолжать выполнение.
{ {
@ -61,9 +64,9 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
if (shift > 1 && isCrossing) if (shift > 1 && isCrossing)
{ {
// если фильтрация окном 120 наползает на окно 15 сверху, потенциальное время открытия лонга и закрытия шорта // если фильтрация окном 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.LongOpen;
res |= TradingEvent.ShortClose; res |= TradingEvent.ShortClose;
@ -72,9 +75,9 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
} }
// если фильтрация окном 15 наползает на окно 120 сверху, потенциальное время закрытия лонга и возможно открытия шорта // если фильтрация окном 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.LongClose;
res |= TradingEvent.ShortOpen; res |= TradingEvent.ShortOpen;

View File

@ -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);
}
}
}
}
}

View File

@ -139,10 +139,12 @@ namespace KLHZ.Trader.Core.Exchange.Services
{ {
continue; 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) 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); BuyStops.AddOrUpdate(message.Figi, stopTo, (k, v) => stopTo);
declisionsForSave.Add(new Declision() declisionsForSave.Add(new Declision()
{ {
@ -160,7 +162,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
{ {
if (BuyStops.TryGetValue(message.Figi, out var dt)) if (BuyStops.TryGetValue(message.Figi, out var dt))
{ {
if (dt > DateTime.UtcNow) if (dt > (message.IsHistoricalData ? message.Time : DateTime.UtcNow))
{ {
continue; continue;
} }
@ -169,8 +171,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
BuyStops.TryRemove(message.Figi, out _); BuyStops.TryRemove(message.Figi, out _);
} }
} }
var stopTo = DateTime.UtcNow.AddMinutes(_buyStopLength);
BuyStops.AddOrUpdate(message.Figi, stopTo, (k, v) => stopTo);
declisionsForSave.Add(new Declision() declisionsForSave.Add(new Declision()
{ {
AccountId = string.Empty, AccountId = string.Empty,