Compare commits
2 Commits
bf3e6ec220
...
ac7c985019
Author | SHA1 | Date |
---|---|---|
|
ac7c985019 | |
|
3afd839265 |
|
@ -9,6 +9,7 @@
|
|||
public decimal Mediana { get; init; }
|
||||
public decimal Upper30Decil { get; init; }
|
||||
public decimal Lower20Decil { get; init; }
|
||||
public int Length { get; init; }
|
||||
public DateTime LastTime { get; init; }
|
||||
public DateTime StartTime { get; init; }
|
||||
public bool IsEmpty => this == Empty;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using KLHZ.Trader.Core.Math.Declisions.Dtos.FFT.Enums;
|
||||
using MathNet.Numerics;
|
||||
using MathNet.Numerics.IntegralTransforms;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||
{
|
||||
|
@ -51,6 +52,48 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
|||
Lower20Decil = newValues[(int)(newValues.Length * 0.2)],
|
||||
Max = newValues.Max(),
|
||||
Min = newValues.Min(),
|
||||
Length = values.Length,
|
||||
};
|
||||
}
|
||||
|
||||
public static FFTAnalyzeResult ReAnalyze(FFTAnalyzeResult result, string key, TimeSpan minPeriod, TimeSpan maxPeriod)
|
||||
{
|
||||
var tmp = new List<Harmonic>();
|
||||
for (int i = 0; i < result.Harmonics.Length; i++)
|
||||
{
|
||||
var per = CaclHarmonycPeriod(result.LastTime - result.StartTime, result.Length, i);
|
||||
if (per >= minPeriod && per <= maxPeriod)
|
||||
{
|
||||
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)],
|
||||
Lower20Decil = newValues[(int)(newValues.Length * 0.2)],
|
||||
Max = newValues.Max(),
|
||||
Min = newValues.Min(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
internal const decimal PowerUppingCoefficient = 1.69m;
|
||||
internal const decimal UppingCoefficient = 1.3m;
|
||||
internal const decimal LowingCoefficient = .77m;
|
||||
internal const decimal PowerLowingCoefficient = .6m;
|
||||
internal const decimal BlockingCoefficient = 0.1m;
|
||||
internal const decimal LowingCoefficient = .76m;
|
||||
internal const decimal PowerLowingCoefficient = .59m;
|
||||
internal const decimal BlockingCoefficient = 0m;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ using System.Collections.Concurrent;
|
|||
using System.Collections.Immutable;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Channels;
|
||||
using Telegram.Bot.Types;
|
||||
using Tinkoff.InvestApi;
|
||||
using Asset = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.Asset;
|
||||
using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType;
|
||||
|
@ -118,8 +117,10 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
if (data.isFullIntervalExists)
|
||||
{
|
||||
var interpolatedData = SignalProcessing.InterpolateData(data.timestamps, data.prices, TimeSpan.FromSeconds(5));
|
||||
fft = FFT.Analyze(interpolatedData.timestamps, interpolatedData.values, message.Figi, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(40));
|
||||
var fftFull = FFT.Analyze(interpolatedData.timestamps, interpolatedData.values, message.Figi+"_full", TimeSpan.FromSeconds(15), TimeSpan.FromHours(24));
|
||||
fft = FFT.ReAnalyze(fftFull, message.Figi, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(40));
|
||||
await _tradeDataProvider.SetFFtResult(fft);
|
||||
await _tradeDataProvider.SetFFtResult(fftFull);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -168,7 +169,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
await ClosePositions(assetsForClose, fakeMessage, false);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -283,7 +284,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
}
|
||||
#endregion
|
||||
if (_tradingInstrumentsFigis.Contains(message.Figi) && message.Figi == "FUTIMOEXF000" && message.Direction==1)
|
||||
if (_tradingInstrumentsFigis.Contains(message.Figi) && message.Figi == "FUTIMOEXF000" && message.Direction == 1)
|
||||
{
|
||||
var currentTime = message.IsHistoricalData ? message.Time : DateTime.UtcNow;
|
||||
try
|
||||
|
@ -308,11 +309,11 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
if (newMod == TradingMode.Growing && newMod != oldMod && !LongOpeningStops.ContainsKey(message.Figi))
|
||||
{
|
||||
changeMods[TradingEvent.UptrendStart] = Constants.PowerUppingCoefficient;
|
||||
//changeMods[TradingEvent.UptrendStart] = Constants.PowerUppingCoefficient;
|
||||
}
|
||||
if (newMod == TradingMode.Dropping && newMod != oldMod && !ShortOpeningStops.ContainsKey(message.Figi))
|
||||
{
|
||||
changeMods[TradingEvent.DowntrendStart] = Constants.PowerUppingCoefficient;
|
||||
//changeMods[TradingEvent.DowntrendStart] = Constants.PowerUppingCoefficient;
|
||||
}
|
||||
TradingModes[message.Figi] = newMod;
|
||||
if (oldMod != newMod)
|
||||
|
@ -383,7 +384,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
|
||||
private async Task<Dictionary<TradingEvent, decimal>> GetWindowAverageStartData((DateTime[] timestamps, decimal[] prices) data, int smallWindow, int bigWindow,
|
||||
INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullStep = 0m, decimal uptrendEndingDetectionMeanfullStep = 3m, decimal initValue = 1)
|
||||
INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullStep = 0m, decimal uptrendEndingDetectionMeanfullStep = 3m)
|
||||
{
|
||||
var resultMoveAvFull = MovingAverage.CheckByWindowAverageMean2(data.timestamps, data.prices,
|
||||
windowMaxSize, smallWindow, bigWindow, uptrendStartingDetectionMeanfullStep, uptrendEndingDetectionMeanfullStep);
|
||||
|
@ -397,13 +398,13 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
res[TradingEvent.UptrendEnd] = Constants.PowerLowingCoefficient;
|
||||
if ((resultMoveAvFull.events & TradingEvent.UptrendStart) == TradingEvent.UptrendStart)
|
||||
{
|
||||
res[TradingEvent.UptrendStart] = initValue;
|
||||
res[TradingEvent.DowntrendEnd] = initValue;
|
||||
res[TradingEvent.UptrendStart] = Constants.PowerUppingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.PowerUppingCoefficient;
|
||||
}
|
||||
if ((resultMoveAvFull.events & TradingEvent.UptrendEnd) == TradingEvent.UptrendEnd)
|
||||
{
|
||||
res[TradingEvent.UptrendEnd] = initValue;
|
||||
res[TradingEvent.DowntrendStart] = initValue;
|
||||
res[TradingEvent.UptrendEnd] = Constants.PowerUppingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.PowerUppingCoefficient;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -459,7 +460,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
}
|
||||
if (profit > 0)
|
||||
{
|
||||
profit= System.Math.Round(profit, 2);
|
||||
profit = System.Math.Round(profit, 2);
|
||||
assetsForClose.Add(asset);
|
||||
messages.Add($"Закрываю позицию {asset.Figi} ({(asset.Count > 0 ? "лонг" : "шорт")}) на счёте {_portfolioWrapper.Accounts[asset.AccountId].AccountName}. Количество {(long)asset.Count}, цена ~{price}, профит {profit}");
|
||||
if (loggedDeclisions == 0)
|
||||
|
@ -497,7 +498,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
{
|
||||
Text = $"Открываю позицию {message.Figi} ({(positionType == PositionType.Long ? "лонг" : "шорт")}) " +
|
||||
$"на счёте {acc.AccountName}. Количество {(positionType == PositionType.Long ? "" : "-")}{count}, " +
|
||||
$"цена ~{System.Math.Round(message.Value,2)}. Стоп лосс: {(positionType == PositionType.Long ? "-" : "+")}{stopLossShift}. " +
|
||||
$"цена ~{System.Math.Round(message.Value, 2)}. Стоп лосс: {(positionType == PositionType.Long ? "-" : "+")}{stopLossShift}. " +
|
||||
$"Тейк профит: {(positionType == PositionType.Long ? "+" : "-")}{takeProfitShift}"
|
||||
});
|
||||
}
|
||||
|
@ -520,7 +521,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
return;
|
||||
}
|
||||
//var resTask1 = GetWindowAverageStartData(data, 30, 180, message, windowMaxSize, -2m, 2m,3);
|
||||
var resTask1 = GetWindowAverageStartData(data, 30, 180, message, windowMaxSize, 0m, 0.5m, 2*Constants.PowerUppingCoefficient);
|
||||
var resTask1 = GetWindowAverageStartData(data, 30, 180, message, windowMaxSize, 0m, 0.5m);
|
||||
//var resTask3 = GetWindowAverageStartData(data, 30, 180, message, windowMaxSize, 0, 0,0.7m);
|
||||
var getFFTModsTask = GetFFTMods(message);
|
||||
//var getAreasModsTask = GetAreasMods(data, message);
|
||||
|
@ -539,9 +540,9 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
//result = MergeResults(result, resTask2.Result.ToImmutableDictionary());
|
||||
//result = MergeResults(result, resTask3.Result.ToImmutableDictionary());
|
||||
result = MergeResultsMax(result, changeModeData);
|
||||
result = MergeResultsMult(result, getFFTModsTask.Result);
|
||||
////result = MergeResults(result, getAreasModsTask.Result);
|
||||
result = MergeResultsMult(result, getSellsDiffsModsTask.Result);
|
||||
//result = MergeResultsMult(result, getFFTModsTask.Result);
|
||||
//////result = MergeResults(result, getAreasModsTask.Result);
|
||||
//result = MergeResultsMult(result, getSellsDiffsModsTask.Result);
|
||||
result = MergeResultsMult(result, getTradingModeModsTask.Result);
|
||||
|
||||
if (result[TradingEvent.UptrendStart] > Constants.UppingCoefficient
|
||||
|
@ -565,7 +566,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
await LogDeclision(DeclisionTradeAction.ResetStopsLong, message.Value + stops.takeProfit, message.Time.AddMilliseconds(-RandomNumberGenerator.GetInt32(300, 1000)), message);
|
||||
await LogDeclision(DeclisionTradeAction.ResetStopsLong, message.Value - stops.stopLoss, message.Time.AddMilliseconds(RandomNumberGenerator.GetInt32(300, 1000)), message);
|
||||
}
|
||||
if (result[TradingEvent.DowntrendStart] > Constants.PowerUppingCoefficient
|
||||
if (result[TradingEvent.DowntrendStart] > Constants.UppingCoefficient
|
||||
&& !ShortOpeningStops.ContainsKey(message.Figi)
|
||||
&& state == ExchangeState.Open
|
||||
)
|
||||
|
@ -725,6 +726,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
if (!largeData.isFullIntervalExists && smallData.isFullIntervalExists)
|
||||
{
|
||||
largeData = await _tradeDataProvider.GetData(figi, TimeSpan.FromMinutes(30));
|
||||
smallData = await _tradeDataProvider.GetData(figi, TimeSpan.FromMinutes(10));
|
||||
}
|
||||
if (!largeData.isFullIntervalExists && smallData.isFullIntervalExists)
|
||||
{
|
||||
|
@ -743,11 +745,11 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
{
|
||||
res = TradingMode.SlowDropping;
|
||||
}
|
||||
if ((largeDataRes > 5 && smallDataRes > 0)||smallDataRes>7)
|
||||
if ((largeDataRes > 5 && smallDataRes > 0) || smallDataRes > 7)
|
||||
{
|
||||
res = TradingMode.Growing;
|
||||
}
|
||||
if ((largeDataRes < -5 && smallDataRes < 0)|| smallDataRes<-7)
|
||||
if ((largeDataRes < -5 && smallDataRes < 0) || smallDataRes < -7)
|
||||
{
|
||||
res = TradingMode.Dropping;
|
||||
}
|
||||
|
@ -810,11 +812,10 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
var res = GetInitDict(1);
|
||||
var position = await CheckHarmonicPosition(message);
|
||||
|
||||
|
||||
if (position == ValueAmplitudePosition.LowerThenMediana)
|
||||
{
|
||||
//res[TradingEvent.UptrendStart] = Constants.UppingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.PowerUppingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.UppingCoefficient;
|
||||
//res[TradingEvent.UptrendEnd] = Constants.LowingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.BlockingCoefficient;
|
||||
}
|
||||
|
@ -823,7 +824,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
res[TradingEvent.UptrendStart] = Constants.BlockingCoefficient;
|
||||
//res[TradingEvent.DowntrendEnd] = Constants.LowingCoefficient;
|
||||
//res[TradingEvent.UptrendEnd] = Constants.UppingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.PowerUppingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.UppingCoefficient;
|
||||
}
|
||||
return res.ToImmutableDictionary();
|
||||
}
|
||||
|
@ -890,8 +891,8 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
{
|
||||
uptrendStartMode *= Constants.UppingCoefficient;
|
||||
downstartMode *= Constants.UppingCoefficient;
|
||||
uptrendEndMode *=Constants.BlockingCoefficient;
|
||||
downtrendEndMode *= Constants.BlockingCoefficient;
|
||||
uptrendEndMode *= Constants.LowingCoefficient;
|
||||
downtrendEndMode *= Constants.LowingCoefficient;
|
||||
}
|
||||
//else if (System.Math.Abs(bys_rel) <= 0.2m && System.Math.Abs(sells_rel) <= 0.2m)
|
||||
//{
|
||||
|
@ -920,23 +921,23 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
}
|
||||
if (mode == TradingMode.Growing)
|
||||
{
|
||||
res[TradingEvent.UptrendEnd] = Constants.PowerLowingCoefficient;
|
||||
res[TradingEvent.UptrendStart] = 10;
|
||||
res[TradingEvent.UptrendEnd] = Constants.LowingCoefficient;
|
||||
res[TradingEvent.UptrendStart] = Constants.UppingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.BlockingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.PowerUppingCoefficient;
|
||||
}
|
||||
if (mode == TradingMode.Stable)
|
||||
{
|
||||
res[TradingEvent.UptrendEnd] = 1;
|
||||
//res[TradingEvent.UptrendStart] = Constants.UppingCoefficient;
|
||||
//res[TradingEvent.UptrendEnd] = 1;
|
||||
res[TradingEvent.UptrendStart] = Constants.LowingCoefficient;
|
||||
//res[TradingEvent.DowntrendEnd] = Constants.UppingCoefficient;
|
||||
// res[TradingEvent.DowntrendStart] = Constants.BlockingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.LowingCoefficient;
|
||||
}
|
||||
if (mode == TradingMode.SlowDropping)
|
||||
{
|
||||
//res[TradingEvent.UptrendEnd] = Constants.PowerUppingCoefficient;
|
||||
//res[TradingEvent.UptrendStart] = Constants.PowerLowingCoefficient;
|
||||
//res[TradingEvent.DowntrendStart] = Constants.UppingCoefficient;
|
||||
res[TradingEvent.UptrendStart] = Constants.LowingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.UppingCoefficient;
|
||||
//res[TradingEvent.DowntrendEnd] = Constants.UppingCoefficient;
|
||||
}
|
||||
if (mode == TradingMode.Dropping)
|
||||
|
@ -944,7 +945,7 @@ INewPrice message, int windowMaxSize, decimal uptrendStartingDetectionMeanfullSt
|
|||
res[TradingEvent.UptrendEnd] = Constants.PowerUppingCoefficient;
|
||||
res[TradingEvent.UptrendStart] = Constants.BlockingCoefficient;
|
||||
res[TradingEvent.DowntrendStart] = Constants.UppingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.PowerLowingCoefficient;
|
||||
res[TradingEvent.DowntrendEnd] = Constants.LowingCoefficient;
|
||||
}
|
||||
return Task.FromResult(res.ToImmutableDictionary());
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace KLHZ.Trader.Service.Controllers
|
|||
//var figi1 = "BBG004730N88";
|
||||
var figi2 = "BBG004730N88";
|
||||
//var figi2 = "FUTIMOEXF000";
|
||||
//var time1 = DateTime.UtcNow.AddDays(-shift ?? -7).Date;
|
||||
var time1 = new DateTime(2025, 9, 24, 7, 00, 0, DateTimeKind.Utc);
|
||||
var time1 = DateTime.UtcNow.AddDays(-shift ?? -7).Date;
|
||||
//var time1 = new DateTime(2025, 9, 24, 7, 00, 0, DateTimeKind.Utc);
|
||||
//var time2 = DateTime.UtcNow.AddMinutes(18);
|
||||
using var context1 = await _dbContextFactory.CreateDbContextAsync();
|
||||
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
|
|
Loading…
Reference in New Issue