добавил анализ скользящими средними
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);
}
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;

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;
}
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,