diff --git a/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs b/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs index 141d90e..88c9f23 100644 --- a/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs +++ b/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs @@ -10,7 +10,7 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils var da = new List(); for (int i = 0; i < 1000; i++) { - da.Add((float)System.Math.Sin(0.01 * i)); + da.Add((float)System.Math.Sin(0.01 * i)+ (float)System.Math.Cos(0.01 * i)); } var start = da.ToArray(); @@ -25,5 +25,46 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils var d = res[i] - start[i]; } } + + public static TimeSpan CaclHarmonycPeriod(TimeSpan signalLength, int signalLengthItems, int harmonyNumber) + { + var fdiscretisation = signalLengthItems /signalLength.TotalSeconds ; + var fharm = harmonyNumber * fdiscretisation / signalLengthItems; + return TimeSpan.FromSeconds(1/fharm); + } + + public static double CalcCurrentPhase(Complex32[] spectr, int harmonyNumber) + { + var item = spectr[harmonyNumber]; + return System.Math.Atan(item.Imaginary / item.Real); + } + + public static (double min, double max) CalcPhaseRange(double aSin, double aCos, double initPhase, double maxLevel) + { + var x = new List(); + var x2 = new List(); + var y = new List(); + for (double i = 0; i <= 10 * System.Math.PI; i += 0.0001) + { + var _2pi = 2 * System.Math.PI; + var df = ((i / _2pi) % 1) * _2pi; + x.Add(df); + y.Add(aSin * System.Math.Sin(i + initPhase) + aCos * System.Math.Cos(i + initPhase)); + } + + var prevI = -1; + var max = y.Max(); + for (int i = 0; i < y.Count; i++) + { + if (y[i] > (1 - maxLevel) * max && (i - prevI == 1 || prevI < 0)) + { + x2.Add(x[i]); + prevI = i; + } + } + var minPhase = x2.Min(); + var maxPhase = x2.Max(); + return (minPhase, maxPhase); + } } } diff --git a/KLHZ.Trader.Core.Tests/FFTTests.cs b/KLHZ.Trader.Core.Tests/FFTTests.cs index 59ac4b3..361c7bd 100644 --- a/KLHZ.Trader.Core.Tests/FFTTests.cs +++ b/KLHZ.Trader.Core.Tests/FFTTests.cs @@ -1,4 +1,5 @@ -using MathNet.Numerics; +using KLHZ.Trader.Core.Math.Declisions.Utils; +using MathNet.Numerics; using MathNet.Numerics.IntegralTransforms; using System.Security.Cryptography; @@ -12,13 +13,14 @@ namespace KLHZ.Trader.Core.Tests var da = new List(); for (int i = 0; i < 100; i++) { - da.Add((float)System.Math.Sin(0.5 * i) + (float)(RandomNumberGenerator.GetInt32(0, 100)) / 300); + da.Add((float)System.Math.Sin(0.5 * i)+(float)System.Math.Cos(0.5 * i)); } var start = da.ToArray(); var arrv = da.Select(d => new Complex32(d, 0)).ToArray(); Fourier.Forward(arrv); - + var tem = arrv.Select(a => Complex32.Abs(a)).ToArray(); + var s = tem.Sum(); Fourier.Inverse(arrv); var res = arrv.Select(a => a.Real).ToArray(); @@ -27,5 +29,25 @@ namespace KLHZ.Trader.Core.Tests var d = res[i] - start[i]; } } + + [Test] + public static void CalcHarmonyPeriodTest1() + { + var period1 = FFT.CaclHarmonycPeriod(TimeSpan.FromHours(1), 1000, 1); + var period2 = FFT.CaclHarmonycPeriod(TimeSpan.FromHours(1), 1000, 2); + var period3 = FFT.CaclHarmonycPeriod(TimeSpan.FromHours(1), 1000, 3); + var period4 = FFT.CaclHarmonycPeriod(TimeSpan.FromHours(1), 1000, 4); + } + + + [Test] + public static void CalcPhaseRange() + { + var res = FFT.CalcPhaseRange(1, 0, 0, 0.001); + Assert.IsTrue(res.min < System.Math.PI / 2); + Assert.IsTrue(res.min > System.Math.PI / 2 * 0.9); + Assert.IsTrue(res.max > System.Math.PI / 2); + Assert.IsTrue(res.max < System.Math.PI / 2 * 1.1); + } } }