фиксация экспериментов с FFT
parent
56a8b2534a
commit
cdc179b3a5
|
@ -5,6 +5,10 @@
|
||||||
None = 0,
|
None = 0,
|
||||||
Middle = 1,
|
Middle = 1,
|
||||||
UpperThen30Decil = 10,
|
UpperThen30Decil = 10,
|
||||||
LowerThenMediana = -50,
|
LowerThen30Decil = -0,
|
||||||
|
LowerThenMedianaGrowing = -50,
|
||||||
|
LowerThenMedianaFalling = -51,
|
||||||
|
Growing = -512,
|
||||||
|
Falling = -513,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
public decimal Min { get; init; }
|
public decimal Min { get; init; }
|
||||||
public decimal Mediana { get; init; }
|
public decimal Mediana { get; init; }
|
||||||
public decimal Upper30Decil { get; init; }
|
public decimal Upper30Decil { get; init; }
|
||||||
public decimal Lower20Decil { get; init; }
|
public decimal Lower30Decil { get; init; }
|
||||||
public int Length { get; init; }
|
public int Length { get; init; }
|
||||||
public DateTime LastTime { get; init; }
|
public DateTime LastTime { get; init; }
|
||||||
public DateTime StartTime { get; init; }
|
public DateTime StartTime { get; init; }
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using KLHZ.Trader.Core.Math.Declisions.Dtos.FFT.Enums;
|
using KLHZ.Trader.Core.Math.Declisions.Dtos.FFT.Enums;
|
||||||
using MathNet.Numerics;
|
using MathNet.Numerics;
|
||||||
using MathNet.Numerics.IntegralTransforms;
|
using MathNet.Numerics.IntegralTransforms;
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
{
|
{
|
||||||
|
@ -18,7 +17,47 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
}
|
}
|
||||||
else if (value < fftData.Mediana && System.Math.Sign(value2) >= 0)
|
else if (value < fftData.Mediana && System.Math.Sign(value2) >= 0)
|
||||||
{
|
{
|
||||||
return ValueAmplitudePosition.LowerThenMediana;
|
return ValueAmplitudePosition.LowerThenMedianaGrowing;
|
||||||
|
}
|
||||||
|
else if (value < fftData.Mediana && System.Math.Sign(value2) < 0)
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.LowerThenMedianaFalling;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.Middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueAmplitudePosition CheckExtremums(FFTAnalyzeResult fftData, DateTime timestamp)
|
||||||
|
{
|
||||||
|
var value = (decimal)CalcAmplitude(fftData.Harmonics, fftData.StartTime, timestamp);
|
||||||
|
var value2 = (decimal)CalcExtremum(fftData.Harmonics, fftData.StartTime, timestamp);
|
||||||
|
if (value > fftData.Upper30Decil && System.Math.Sign(value2) <= 0)
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.UpperThen30Decil;
|
||||||
|
}
|
||||||
|
else if (value < fftData.Lower30Decil && System.Math.Sign(value2) >= 0)
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.LowerThen30Decil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.Middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValueAmplitudePosition CheckSign(FFTAnalyzeResult fftData, DateTime timestamp)
|
||||||
|
{
|
||||||
|
var value = (decimal)CalcAmplitude(fftData.Harmonics, fftData.StartTime, timestamp);
|
||||||
|
var value2 = (decimal)CalcExtremum(fftData.Harmonics, fftData.StartTime, timestamp);
|
||||||
|
if (System.Math.Sign(value2) <= 0)
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.Falling;
|
||||||
|
}
|
||||||
|
else if (System.Math.Sign(value2) >= 0)
|
||||||
|
{
|
||||||
|
return ValueAmplitudePosition.Growing;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -49,7 +88,7 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
StartTime = startTime,
|
StartTime = startTime,
|
||||||
Mediana = newValues[newValues.Length / 2],
|
Mediana = newValues[newValues.Length / 2],
|
||||||
Upper30Decil = newValues[(int)(newValues.Length * 0.7)],
|
Upper30Decil = newValues[(int)(newValues.Length * 0.7)],
|
||||||
Lower20Decil = newValues[(int)(newValues.Length * 0.2)],
|
Lower30Decil = newValues[(int)(newValues.Length * 0.3)],
|
||||||
Max = newValues.Max(),
|
Max = newValues.Max(),
|
||||||
Min = newValues.Min(),
|
Min = newValues.Min(),
|
||||||
Length = values.Length,
|
Length = values.Length,
|
||||||
|
@ -91,7 +130,60 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
StartTime = result.StartTime,
|
StartTime = result.StartTime,
|
||||||
Mediana = newValues[newValues.Length / 2],
|
Mediana = newValues[newValues.Length / 2],
|
||||||
Upper30Decil = newValues[(int)(newValues.Length * 0.7)],
|
Upper30Decil = newValues[(int)(newValues.Length * 0.7)],
|
||||||
Lower20Decil = newValues[(int)(newValues.Length * 0.2)],
|
Lower30Decil = newValues[(int)(newValues.Length * 0.3)],
|
||||||
|
Max = newValues.Max(),
|
||||||
|
Min = newValues.Min(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FFTAnalyzeResult ReAnalyze(FFTAnalyzeResult result, string key, float energyPart, bool include)
|
||||||
|
{
|
||||||
|
var tmp = new List<Harmonic>();
|
||||||
|
var symmEnergy = result.Harmonics.Sum(h => h.Magnitude);
|
||||||
|
var tmpSumEnergy = 0f;
|
||||||
|
for (int i = 0; i < result.Harmonics.Length; i++)
|
||||||
|
{
|
||||||
|
tmpSumEnergy += result.Harmonics[i].Magnitude;
|
||||||
|
if (include)
|
||||||
|
{
|
||||||
|
if (tmpSumEnergy/ symmEnergy < energyPart)
|
||||||
|
{
|
||||||
|
tmp.Add(result.Harmonics[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tmpSumEnergy / symmEnergy >= energyPart)
|
||||||
|
{
|
||||||
|
tmp.Add(result.Harmonics[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var harms = tmp.ToArray();
|
||||||
|
var newValues = new decimal[result.Length];
|
||||||
|
var newValues2 = new decimal[result.Length];
|
||||||
|
var time = result.StartTime;
|
||||||
|
var dt = (result.LastTime - result.StartTime).TotalSeconds / result.Length;
|
||||||
|
for (int i = 0; i < result.Length; i++)
|
||||||
|
{
|
||||||
|
var currentTime = time.AddSeconds(i * dt);
|
||||||
|
newValues[i] = (decimal)CalcAmplitude(harms, result.StartTime, currentTime);
|
||||||
|
newValues2[i] = (decimal)CalcExtremum(harms, result.StartTime, currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
newValues = newValues.Order().ToArray();
|
||||||
|
var ma = newValues2.Max();
|
||||||
|
var mi = newValues2.Min();
|
||||||
|
return new FFTAnalyzeResult()
|
||||||
|
{
|
||||||
|
Key = key,
|
||||||
|
Harmonics = harms,
|
||||||
|
LastTime = result.LastTime,
|
||||||
|
StartTime = result.StartTime,
|
||||||
|
Mediana = newValues[newValues.Length / 2],
|
||||||
|
Upper30Decil = newValues[(int)(newValues.Length * 0.7)],
|
||||||
|
Lower30Decil = newValues[(int)(newValues.Length * 0.3)],
|
||||||
Max = newValues.Max(),
|
Max = newValues.Max(),
|
||||||
Min = newValues.Min(),
|
Min = newValues.Min(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,9 +92,9 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<(DateTime[] timestamps, decimal[] prices, bool isFullIntervalExists)> GetData(INewPrice message)
|
public async ValueTask<(DateTime[] timestamps, decimal[] prices, bool isFullIntervalExists)> GetData(INewPrice message, TimeSpan? windowSize = null)
|
||||||
{
|
{
|
||||||
var data2 = await _tradeDataProvider.GetData(message.Figi, TimeSpan.FromHours(1.5));
|
var data2 = await _tradeDataProvider.GetData(message.Figi, windowSize??TimeSpan.FromHours(1.5));
|
||||||
if (!data2.isFullIntervalExists)
|
if (!data2.isFullIntervalExists)
|
||||||
{
|
{
|
||||||
data2 = await _tradeDataProvider.GetData(message.Figi, TimeSpan.FromHours(1));
|
data2 = await _tradeDataProvider.GetData(message.Figi, TimeSpan.FromHours(1));
|
||||||
|
@ -111,30 +111,80 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
var currentTime = message.IsHistoricalData ? message.Time : DateTime.UtcNow;
|
var currentTime = message.IsHistoricalData ? message.Time : DateTime.UtcNow;
|
||||||
var position = ValueAmplitudePosition.None;
|
var position = ValueAmplitudePosition.None;
|
||||||
var fft = await _tradeDataProvider.GetFFtResult(message.Figi);
|
var fft = await _tradeDataProvider.GetFFtResult(message.Figi);
|
||||||
|
var fftFull = await _tradeDataProvider.GetFFtResult(message.Figi + "_full");
|
||||||
|
//var highFreq = await _tradeDataProvider.GetFFtResult(message.Figi + "_high_freq");
|
||||||
|
//var lowFreq = await _tradeDataProvider.GetFFtResult(message.Figi + "_low_freq");
|
||||||
var step = message.IsHistoricalData ? 5 : 5;
|
var step = message.IsHistoricalData ? 5 : 5;
|
||||||
if (fft.IsEmpty || (currentTime - fft.LastTime).TotalSeconds > step)
|
if (fft.IsEmpty || (currentTime - fft.LastTime).TotalSeconds > step)
|
||||||
{
|
{
|
||||||
if (data.isFullIntervalExists)
|
if (data.isFullIntervalExists)
|
||||||
{
|
{
|
||||||
var interpolatedData = SignalProcessing.InterpolateData(data.timestamps, data.prices, TimeSpan.FromSeconds(5));
|
var interpolatedData = SignalProcessing.InterpolateData(data.timestamps, data.prices, TimeSpan.FromSeconds(5));
|
||||||
var fftFull = FFT.Analyze(interpolatedData.timestamps, interpolatedData.values, message.Figi+"_full", TimeSpan.FromSeconds(15), TimeSpan.FromHours(24));
|
fftFull = FFT.Analyze(interpolatedData.timestamps, interpolatedData.values, message.Figi+"_full", TimeSpan.FromSeconds(120), TimeSpan.FromHours(24));
|
||||||
fft = FFT.ReAnalyze(fftFull, message.Figi, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(40));
|
fft = FFT.ReAnalyze(fftFull, message.Figi, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(40));
|
||||||
|
//highFreq = FFT.ReAnalyze(fftFull, message.Figi + "_low_freq", TimeSpan.FromMinutes(20), TimeSpan.FromMinutes(60));
|
||||||
|
//lowFreq = FFT.ReAnalyze(fftFull, message.Figi + "_high_freq", TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(20));
|
||||||
|
|
||||||
await _tradeDataProvider.SetFFtResult(fft);
|
await _tradeDataProvider.SetFFtResult(fft);
|
||||||
await _tradeDataProvider.SetFFtResult(fftFull);
|
//await _tradeDataProvider.SetFFtResult(fftFull);
|
||||||
|
//await _tradeDataProvider.SetFFtResult(lowFreq);
|
||||||
|
//await _tradeDataProvider.SetFFtResult(highFreq);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var highFreqData = await GetData(message, TimeSpan.FromMinutes(120));
|
||||||
|
|
||||||
|
//if (highFreqData.isFullIntervalExists)
|
||||||
|
//{
|
||||||
|
// var interpolatehighFreqData = SignalProcessing.InterpolateData(data.timestamps, data.prices, TimeSpan.FromSeconds(5));
|
||||||
|
// highFreq = FFT.Analyze(interpolatehighFreqData.timestamps, interpolatehighFreqData.values, message.Figi + "_high_freq", TimeSpan.FromSeconds(20), TimeSpan.FromMinutes(120));
|
||||||
|
// await _tradeDataProvider.SetFFtResult(highFreq);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
|
|
||||||
|
position = FFT.Check(fft, message.Time);
|
||||||
|
if (position == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.UpperThen30Decil)
|
||||||
{
|
{
|
||||||
position = FFT.Check(fft, message.Time);
|
await LogPrice(message, "upper30percent", message.Value);
|
||||||
if (position == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.UpperThen30Decil)
|
|
||||||
{
|
|
||||||
await LogPrice(message, "upper30percent", message.Value);
|
|
||||||
}
|
|
||||||
if (position == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.LowerThenMediana)
|
|
||||||
{
|
|
||||||
await LogPrice(message, "lower30percent", message.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (position == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.LowerThenMedianaGrowing)
|
||||||
|
{
|
||||||
|
await LogPrice(message, "lower30percent", message.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//var hposition = FFT.CheckExtremums(highFreq, message.Time);
|
||||||
|
//if (hposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.UpperThen30Decil)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "high_freq_high", message.Value);
|
||||||
|
//}
|
||||||
|
//if (hposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.LowerThen30Decil)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "high_freq_low", message.Value);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//var gposition = FFT.CheckSign(highFreq, message.Time);
|
||||||
|
//if (gposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.Growing)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "growing", message.Value);
|
||||||
|
//}
|
||||||
|
//if (gposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.Falling)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "falling", message.Value);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//var lposition = FFT.CheckExtremums(lowFreq, message.Time);
|
||||||
|
//if (lposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.UpperThen30Decil)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "low_freq_high", message.Value);
|
||||||
|
//}
|
||||||
|
//if (lposition == Math.Declisions.Dtos.FFT.Enums.ValueAmplitudePosition.LowerThen30Decil)
|
||||||
|
//{
|
||||||
|
// await LogPrice(message, "low_freq_low", message.Value);
|
||||||
|
//}
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
@ -821,7 +871,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
||||||
var res = GetInitDict(1);
|
var res = GetInitDict(1);
|
||||||
var position = await CheckHarmonicPosition(message);
|
var position = await CheckHarmonicPosition(message);
|
||||||
|
|
||||||
if (position == ValueAmplitudePosition.LowerThenMediana)
|
if (position == ValueAmplitudePosition.LowerThenMedianaGrowing)
|
||||||
{
|
{
|
||||||
//res[TradingEvent.UptrendStart] = Constants.UppingCoefficient;
|
//res[TradingEvent.UptrendStart] = Constants.UppingCoefficient;
|
||||||
res[TradingEvent.DowntrendEnd] = Constants.UppingCoefficient;
|
res[TradingEvent.DowntrendEnd] = Constants.UppingCoefficient;
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace KLHZ.Trader.Service.Controllers
|
||||||
})
|
})
|
||||||
.ToArrayAsync();
|
.ToArrayAsync();
|
||||||
|
|
||||||
|
|
||||||
foreach (var mess in data)
|
foreach (var mess in data)
|
||||||
{
|
{
|
||||||
await _dataBus.Broadcast(mess);
|
await _dataBus.Broadcast(mess);
|
||||||
|
|
Loading…
Reference in New Issue