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(); var res2 = new List(); 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(); 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; } } }