171 lines
6.1 KiB
C#
171 lines
6.1 KiB
C#
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
|
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
|
|
|
|
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
|
{
|
|
public static class SignalProcessing
|
|
{
|
|
public static (DateTime[] timestamps, decimal[] values) InterpolateData(DateTime[] timestamps, decimal[] values, TimeSpan timeStep)
|
|
{
|
|
var res = new List<decimal>();
|
|
var res2 = new List<DateTime>();
|
|
|
|
var startTime = new DateTime(timestamps[0].Year, timestamps[0].Month, timestamps[0].Day, 0, 0, 0, DateTimeKind.Utc);
|
|
var dt = timestamps[0] - startTime;
|
|
|
|
var totalSteps = System.Math.Ceiling((timestamps[timestamps.Length - 1] - timestamps[0]).TotalSeconds / timeStep.TotalSeconds);
|
|
var deltaSeconds = System.Math.Floor(dt.TotalSeconds / timeStep.TotalSeconds);
|
|
startTime = startTime.AddSeconds(deltaSeconds * timeStep.TotalSeconds);
|
|
|
|
var firstBound = startTime;
|
|
var secondBound = startTime + timeStep;
|
|
var bound = 0;
|
|
for (int i = 0; i < totalSteps; i++)
|
|
{
|
|
var count = 0;
|
|
var sum = 0m;
|
|
|
|
for (int i1 = bound; i1 < timestamps.Length; i1++)
|
|
{
|
|
if (timestamps[i1] > firstBound && timestamps[i1] <= secondBound)
|
|
{
|
|
count++;
|
|
sum += values[i1];
|
|
}
|
|
else if (count != 0)
|
|
{
|
|
bound = i1;
|
|
break;
|
|
}
|
|
}
|
|
if (count != 0)
|
|
{
|
|
res.Add(sum / count);
|
|
res2.Add(secondBound);
|
|
}
|
|
else if (bound < timestamps.Length - 2)
|
|
{
|
|
res.Add(values[bound]);
|
|
res2.Add(secondBound);
|
|
}
|
|
|
|
|
|
firstBound += timeStep;
|
|
secondBound += timeStep;
|
|
}
|
|
|
|
return (res2.ToArray(), res.ToArray());
|
|
}
|
|
|
|
public static ITradeDataItem[] InterpolateData(ITradeDataItem[] items, TimeSpan timeStep)
|
|
{
|
|
var result = new List<ITradeDataItem>();
|
|
|
|
var firstItem = items[0];
|
|
var startTime = new DateTime(firstItem.Time.Year, firstItem.Time.Month, firstItem.Time.Day, 0, 0, 0, DateTimeKind.Utc);
|
|
var dt = items[0].Time - startTime;
|
|
|
|
var totalSteps = System.Math.Ceiling((items[items.Length - 1].Time - firstItem.Time).TotalSeconds / timeStep.TotalSeconds);
|
|
var deltaSeconds = System.Math.Floor(dt.TotalSeconds / timeStep.TotalSeconds);
|
|
startTime = startTime.AddSeconds(deltaSeconds * timeStep.TotalSeconds);
|
|
|
|
var firstBound = startTime;
|
|
var secondBound = startTime + timeStep;
|
|
var boundD1 = 0;
|
|
var boundD2 = 0;
|
|
for (int i = 0; i < totalSteps; i++)
|
|
{
|
|
var countD1 = 0;
|
|
var sumD1 = 0m;
|
|
var cD1 = 0L;
|
|
|
|
var countD2 = 0;
|
|
var sumD2 = 0m;
|
|
var cD2 = 0L;
|
|
|
|
for (int i1 = boundD1; i1 < items.Length; i1++)
|
|
{
|
|
if (items[i1].Direction == 1)
|
|
{
|
|
if (items[i1].Time > firstBound && items[i1].Time <= secondBound)
|
|
{
|
|
countD1++;
|
|
sumD1 += items[i1].Price;
|
|
cD1 += items[i1].Count;
|
|
}
|
|
else if (countD1 != 0)
|
|
{
|
|
boundD1 = i1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i1 = boundD2; i1 < items.Length; i1++)
|
|
{
|
|
if (items[i1].Direction == 2)
|
|
{
|
|
if (items[i1].Time > firstBound && items[i1].Time <= secondBound)
|
|
{
|
|
countD2++;
|
|
sumD2 += items[i1].Price;
|
|
cD2 += items[i1].Count;
|
|
}
|
|
else if (countD2 != 0)
|
|
{
|
|
boundD2 = i1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (countD1 != 0)
|
|
{
|
|
result.Add(new TradeDataItem()
|
|
{
|
|
Figi = firstItem.Figi,
|
|
Ticker = firstItem.Ticker,
|
|
Price = sumD1 / countD1,
|
|
Time = secondBound,
|
|
IsHistoricalData = firstItem.IsHistoricalData,
|
|
Direction = 1,
|
|
Count = cD1
|
|
});
|
|
}
|
|
|
|
if (countD2 != 0)
|
|
{
|
|
result.Add(new TradeDataItem()
|
|
{
|
|
Figi = firstItem.Figi,
|
|
Ticker = firstItem.Ticker,
|
|
Price = sumD2 / countD2,
|
|
Time = secondBound,
|
|
IsHistoricalData = firstItem.IsHistoricalData,
|
|
Direction = 2,
|
|
Count = cD2
|
|
});
|
|
}
|
|
|
|
firstBound += timeStep;
|
|
secondBound += timeStep;
|
|
}
|
|
|
|
|
|
return result.OrderBy(r => r.Time).ToArray();
|
|
}
|
|
|
|
public static decimal[] CalcDiffs(decimal[] values)
|
|
{
|
|
if (values.Length < 1) throw new ArgumentException();
|
|
|
|
var resArray = new decimal[values.Length - 1];
|
|
for (int i = 1; i < values.Length; i++)
|
|
{
|
|
resArray[i - 1] = values[i] - values[i - 1];
|
|
}
|
|
return resArray;
|
|
}
|
|
}
|
|
}
|