From 1c3c4f6e97203cbb58f535d03c65f2aa9e33256b Mon Sep 17 00:00:00 2001 From: vlad zverzhkhovskiy Date: Mon, 29 Sep 2025 14:51:50 +0300 Subject: [PATCH] =?UTF-8?q?=D1=84=D0=B8=D0=BA=D1=81=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs | 52 +++++++++++++++++++ KLHZ.Trader.Core.Tests/FFTTests.cs | 21 ++++++++ 2 files changed, 73 insertions(+) diff --git a/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs b/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs index 1301c70..9ef1b2f 100644 --- a/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs +++ b/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs @@ -65,6 +65,58 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils } } + internal static (DateTime[] timestamps, decimal[] values) TrimValues(DateTime[] timestamps, decimal[] values, TimeSpan period) + { + int i = 0; + var lastTime = timestamps[timestamps.Length - 1]; + for (i=0;i< timestamps.Length; i++) + { + if ((lastTime - timestamps[timestamps.Length - i-1]) > period) + { + break; + } + } + + var resDt = new DateTime[i]; + var resVs = new decimal[i]; + + Array.Copy(timestamps, timestamps.Length - i, resDt, 0, i); + Array.Copy(values, values.Length - i, resVs, 0, i); + + return (resDt, resVs); + } + + public static FFTAnalyzeResult GetMainHarmonic(DateTime[] timestamps, decimal[] values, string key, TimeSpan minPeriod, TimeSpan maxPeriod) + { + + var harmonics = GetHarmonics(values, timestamps[timestamps.Length - 1] - timestamps[0], minPeriod, maxPeriod); + var newValues = new decimal[timestamps.Length]; + var newValues2 = new decimal[timestamps.Length]; + var startTime = timestamps[0]; + for (int i = 0; i < timestamps.Length; i++) + { + newValues[i] = (decimal)CalcAmplitude(harmonics, startTime, timestamps[i]); + newValues2[i] = (decimal)CalcExtremum(harmonics, startTime, timestamps[i]); + } + + newValues = newValues.Order().ToArray(); + var ma = newValues2.Max(); + var mi = newValues2.Min(); + return new FFTAnalyzeResult() + { + Key = key, + Harmonics = harmonics, + LastTime = timestamps[timestamps.Length - 1], + StartTime = startTime, + Mediana = newValues[newValues.Length / 2], + Upper30Decil = newValues[(int)(newValues.Length * 0.7)], + Lower30Decil = newValues[(int)(newValues.Length * 0.3)], + Max = newValues.Max(), + Min = newValues.Min(), + Length = values.Length, + }; + } + public static FFTAnalyzeResult Analyze(DateTime[] timestamps, decimal[] values, string key, TimeSpan minPeriod, TimeSpan maxPeriod) { var harmonics = GetHarmonics(values, timestamps[timestamps.Length - 1] - timestamps[0], minPeriod, maxPeriod); diff --git a/KLHZ.Trader.Core.Tests/FFTTests.cs b/KLHZ.Trader.Core.Tests/FFTTests.cs index f0e77e9..19ba7d5 100644 --- a/KLHZ.Trader.Core.Tests/FFTTests.cs +++ b/KLHZ.Trader.Core.Tests/FFTTests.cs @@ -219,5 +219,26 @@ namespace KLHZ.Trader.Core.Tests Assert.IsTrue(res.max > System.Math.PI / 2); Assert.IsTrue(res.max < System.Math.PI / 2 * 1.1); } + + [Test] + public static void TrimValues_Test1() + { + var da = new List(); + var dates = new List(); + var dt = DateTime.UtcNow; + var dt1 = dt; + var dt2 = dt.AddSeconds(3600); + var i = 0; + while (dt < dt2) + { + da.Add(i); + dates.Add(dt); + dt = dt.AddSeconds(1); + i++; + } + + var res = FFT.TrimValues(dates.ToArray(), da.ToArray(), TimeSpan.FromSeconds(30)); + var res2 = FFT.TrimValues(dates.ToArray(), da.ToArray(), TimeSpan.FromSeconds(4011)); + } } }