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

108 lines
5.2 KiB
C#
Raw Permalink 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 + shift < values.Length
&& startTime - timestamps[values.Length - i - shift] < TimeSpan.FromSeconds(window); i++)
{
var k = values.Length - i - shift;
sum += values[values.Length - i - shift];
count++;
}
return (startTime, sum / count);
}
public static (TradingEvent events, decimal bigWindowAv, decimal smallWindowAv) CheckByWindowAverageMean(DateTime[] timestamps, decimal[] prices, int size, int smallWindow, int bigWindow, decimal meanfullStep = 3m)
{
var res = TradingEvent.None;
var bigWindowAv = 0m;
var smallWindowAv = 0m;
var s = 0;
try
{
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 - 1 && shift < prices.Length - 1; shift++)
{
s = shift;
var i2 = size - 1 - shift;
var i1 = size - 2 - shift;
var twavs = CalcTimeWindowAverageValue(timestamps, prices, smallWindow, shift);
var twavb = CalcTimeWindowAverageValue(timestamps, prices, bigWindow, shift);
pricesForFinalComparison[i2] = prices[prices.Length - 1 - shift];
if (shift == 0)
{
bigWindowAv = twavb.value;
smallWindowAv = twavs.value;
}
twavss[i2] = twavs.value;
twavbs[i2] = twavb.value;
times[i2] = twavb.time;
if (System.Math.Abs(twavb.value - prices[prices.Length - 1]) > 2 * meanfullStep)
{
res |= TradingEvent.StopBuy;
return (res, bigWindowAv, smallWindowAv);
}
if (shift > 0)
{
var isCrossing = Lines.IsLinesCrossing(
times[i1 + 1],
times[i2 + 1],
twavss[i1 + 1],
twavss[i2 + 1],
twavbs[i1 + 1],
twavbs[i2 + 1]);
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[i2 + 1] - 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[i2 + 1] - pricesForFinalComparison[size - 1] <= -meanfullStep)
{
res |= TradingEvent.LongClose;
res |= TradingEvent.ShortOpen;
break;
}
}
}
}
}
}
catch (Exception ex)
{
}
return (res, bigWindowAv, smallWindowAv);
}
}
}