77 lines
3.8 KiB
C#
77 lines
3.8 KiB
C#
using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
|
||
using KLHZ.Trader.Core.Math.Common;
|
||
|
||
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||
{
|
||
public static class MovingAverage
|
||
{
|
||
private static (DateTime time, float value) CalcTimeWindowAverageValue(DateTime[] timestamps, float[] values, int window, int shift = 0)
|
||
{
|
||
var sum = values[values.Length - 1 - shift];
|
||
var count = 1;
|
||
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 TradingEventsDto CheckByWindowAverageMean(DateTime[] timestamps, float[] prices, int size, float meanfullStep = 3f)
|
||
{
|
||
var twav15s = new float[size];
|
||
var twav120s = new float[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 (shift > 0)
|
||
{
|
||
var isCrossing = Lines.IsLinesCrossing(
|
||
times[size - 1 - shift],
|
||
times[size - 2 - shift],
|
||
twav15s[size - 1 - shift],
|
||
twav15s[size - 2 - shift],
|
||
twav120s[size - 1 - shift],
|
||
twav120s[size - 2 - shift]);
|
||
if (shift == 1 && !isCrossing) //если нет пересечения скользящих средний с окном 120 и 15 секунд между
|
||
//текущей и предыдущей точкой - можно не продолжать выполнение.
|
||
{
|
||
break;
|
||
}
|
||
if (shift > 1 && isCrossing)
|
||
{
|
||
// если фильтрация окном 120 наползает на окно 15 сверху, потенциальное время открытия лонга и закрытия шорта
|
||
if (twav120s[size - 1] <= twav15s[size - 1] && twav120s[size - 2] > twav15s[size - 2])
|
||
{
|
||
if (twav15s[size - 1 - shift] - twav15s[size - 1] >= meanfullStep)
|
||
{
|
||
return new TradingEventsDto(false, true);
|
||
}
|
||
}
|
||
|
||
// если фильтрация окном 15 наползает на окно 120 сверху, потенциальное время закрытия лонга и возможно открытия шорта
|
||
if (twav15s[size - 1] <= twav120s[size - 1] && twav15s[size - 2] > twav120s[size - 2])
|
||
{
|
||
if (twav15s[size - 1 - shift] - twav15s[size - 1] <= -meanfullStep)
|
||
{
|
||
return new TradingEventsDto(true, false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return new TradingEventsDto(false, false);
|
||
}
|
||
|
||
}
|
||
}
|