108 lines
5.2 KiB
C#
108 lines
5.2 KiB
C#
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);
|
||
}
|
||
}
|
||
}
|