klhztrader/KLHZ.Trader.Core.Math/Declisions/Utils/MovingAverage.cs

96 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
using KLHZ.Trader.Core.Math.Common;
namespace KLHZ.Trader.Core.Math.Declisions.Utils
{
public static class MovingAverage
{
internal static (DateTime time, decimal value) CalcTimeWindowAverageValue(DateTime[] timestamps, decimal[] values, int window, int shift = 0)
{
var sum = values[values.Length - 1 - shift];
var count = 1m;
var startTime = timestamps[timestamps.Length - 1 - shift];
for (int i = 2; i < values.Length && startTime - timestamps[values.Length - i - shift] < TimeSpan.FromSeconds(window); i++)
{
sum += values[values.Length - i - shift];
count++;
}
return (startTime, sum / count);
}
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 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 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 - 1 - shift;
var i2 = size - shift;
var isCrossing = Lines.IsLinesCrossing(
times[i1],
times[i2],
twavss[i1],
twavss[i2],
twavbs[i1],
twavbs[i2]);
if (shift == 1 && !isCrossing) //если нет пересечения скользящих средний с окном 120 и 15 секунд между
//текущей и предыдущей точкой - можно не продолжать выполнение.
{
break;
}
if (shift > 1 && isCrossing)
{
// если фильтрация окном 120 наползает на окно 15 сверху, потенциальное время открытия лонга и закрытия шорта
if (twavbs[size - 1] <= twavss[size - 1] && twavbs[size - 2] > twavss[size - 2])
{
if (pricesForFinalComparison[size - 1 - shift] - pricesForFinalComparison[size - 1] >= meanfullStep)
{
res |= TradingEvent.LongOpen;
res |= TradingEvent.ShortClose;
break;
}
}
// если фильтрация окном 15 наползает на окно 120 сверху, потенциальное время закрытия лонга и возможно открытия шорта
if (twavss[size - 1] <= twavbs[size - 1] && twavss[size - 2] > twavbs[size - 2])
{
if (pricesForFinalComparison[size - 1 - shift] - pricesForFinalComparison[size - 1] <= -meanfullStep)
{
res |= TradingEvent.LongClose;
res |= TradingEvent.ShortOpen;
break;
}
}
}
}
}
return res;
}
}
}