Compare commits

...

2 Commits

Author SHA1 Message Date
vlad zverzhkhovskiy ab4375489a изменение стопов
test / deploy_trader_prod (push) Successful in 6m4s Details
2025-10-01 10:35:58 +03:00
vlad zverzhkhovskiy 69660230c2 изменение шагов 2025-10-01 10:31:55 +03:00
4 changed files with 106 additions and 25 deletions

View File

@ -1,4 +1,5 @@
using System; using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -8,6 +9,12 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
{ {
public static class Statistics public static class Statistics
{ {
public static decimal Mean(this CachedValue[] values)
{
return values.Sum(x => x.Value)/ values.Length;
}
private static (decimal mean, decimal std) CaclSigma(decimal[] values) private static (decimal mean, decimal std) CaclSigma(decimal[] values)
{ {
var mean = values.Sum() / values.Length; var mean = values.Sum() / values.Length;

View File

@ -227,7 +227,8 @@ namespace KLHZ.Trader.Core.Exchange.Services
AsksCount = asks.Length, AsksCount = asks.Length,
BidsCount = asks.Length, BidsCount = asks.Length,
}; };
await _tradeDataProvider.AddOrderbook(message);
await _eventBus.Broadcast(message);
} }
if (orderbookItemsBuffer.Count + pricesBuffer.Count > 100 || (DateTime.UtcNow - lastWrite).TotalSeconds > 5) if (orderbookItemsBuffer.Count + pricesBuffer.Count > 100 || (DateTime.UtcNow - lastWrite).TotalSeconds > 5)

View File

@ -38,6 +38,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
private readonly ConcurrentDictionary<string, TradingEvent> LastTradingEvents = new(); private readonly ConcurrentDictionary<string, TradingEvent> LastTradingEvents = new();
private readonly ConcurrentDictionary<string, TradingMode> TradingModes = new(); private readonly ConcurrentDictionary<string, TradingMode> TradingModes = new();
private readonly ConcurrentDictionary<string, IOrderbook> OrderBooks = new();
private readonly ConcurrentDictionary<string, DateTime> LongOpeningStops = new(); private readonly ConcurrentDictionary<string, DateTime> LongOpeningStops = new();
private readonly ConcurrentDictionary<string, DateTime> ShortOpeningStops = new(); private readonly ConcurrentDictionary<string, DateTime> ShortOpeningStops = new();
@ -55,6 +56,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
private readonly Channel<INewPrice> _pricesChannel = Channel.CreateUnbounded<INewPrice>(); private readonly Channel<INewPrice> _pricesChannel = Channel.CreateUnbounded<INewPrice>();
private readonly Channel<ITradeCommand> _commands = Channel.CreateUnbounded<ITradeCommand>(); private readonly Channel<ITradeCommand> _commands = Channel.CreateUnbounded<ITradeCommand>();
private readonly Channel<IOrderbook> _orderbooks = Channel.CreateUnbounded<IOrderbook>();
public Trader( public Trader(
ILogger<Trader> logger, ILogger<Trader> logger,
IOptions<ExchangeConfig> options, IOptions<ExchangeConfig> options,
@ -86,9 +88,10 @@ namespace KLHZ.Trader.Core.Exchange.Services
public Task StartAsync(CancellationToken cancellationToken) public Task StartAsync(CancellationToken cancellationToken)
{ {
_dataBus.AddChannel(nameof(Trader), _pricesChannel); _dataBus.AddChannel(nameof(Trader), _pricesChannel);
//_dataBus.AddChannel(nameof(Trader), _ordersbookChannel); _dataBus.AddChannel(nameof(Trader), _orderbooks);
_dataBus.AddChannel(nameof(Trader), _commands); _dataBus.AddChannel(nameof(Trader), _commands);
_ = ProcessPrices(); _ = ProcessPrices();
_ = ProcessOrderbooks();
_ = ProcessCommands(); _ = ProcessCommands();
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -246,6 +249,43 @@ namespace KLHZ.Trader.Core.Exchange.Services
} }
} }
private async Task ProcessOrderbooks()
{
while (await _orderbooks.Reader.WaitToReadAsync())
{
var message = await _orderbooks.Reader.ReadAsync();
await _tradeDataProvider.AddOrderbook(message);
//if (OrderBooks.TryGetValue(message.Figi, out var oldMessage))
//{
// if (message.Bids.Length > 0 && oldMessage.Bids.Length>0)
// {
// var val = message.Bids[0].Count - oldMessage.Bids[0].Count;
// await _tradeDataProvider.AddDataTo20SecondsWindowCache(message.Figi, "dbids0", new Contracts.Declisions.Dtos.CachedValue()
// {
// Time = message.Time,
// Value = val
// });
// if (val!=0)
// await LogPrice(message.Figi, message.Ticker, message.Time, val, "bids0");
// }
// if (message.Asks.Length > 0 && oldMessage.Asks.Length > 0)
// {
// var val = message.Asks[0].Count - oldMessage.Asks[0].Count;
// await _tradeDataProvider.AddDataTo20SecondsWindowCache(message.Figi, "dasks0", new Contracts.Declisions.Dtos.CachedValue()
// {
// Time = message.Time,
// Value = val
// });
// if (val != 0)
// await LogPrice(message.Figi, message.Ticker, message.Time, val, "asks0");
// }
//}
OrderBooks[message.Figi] = message;
}
}
private async Task ProcessPrices() private async Task ProcessPrices()
{ {
var pricesCache1 = new Dictionary<string, List<INewPrice>>(); var pricesCache1 = new Dictionary<string, List<INewPrice>>();
@ -600,9 +640,16 @@ namespace KLHZ.Trader.Core.Exchange.Services
if (changemodes.Length > 1) if (changemodes.Length > 1)
{ {
await LogPrice(message, "changemode", changemodes[changemodes.Length - 1].Value - changemodes[changemodes.Length - 2].Value); await LogPrice(message, "changemode", changeModIndicator);
} }
//var sells20 = await _tradeDataProvider.GetDataFrom20SecondsWindowCache(message.Figi, "2");
//var buys20 = await _tradeDataProvider.GetDataFrom20SecondsWindowCache(message.Figi, "1");
//if (sells20.Length>0)
// await LogPrice(message.Figi, message.Ticker, message.Time, sells20.Sum(v => v.Value), "sells20");
//if (buys20.Length > 0)
// await LogPrice(message.Figi, message.Ticker, message.Time, buys20.Sum(v => v.Value), "buys20");
//if (changemodes[changemodes.Length-1].Time - changemodes[0].Time > TimeSpan.FromMinutes(10)) //if (changemodes[changemodes.Length-1].Time - changemodes[0].Time > TimeSpan.FromMinutes(10))
//{ //{
// var diffs = SignalProcessing.CalcDiffs(changemodes.Select(c => c.Value).ToArray()); // var diffs = SignalProcessing.CalcDiffs(changemodes.Select(c => c.Value).ToArray());
@ -851,7 +898,7 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
// result = MergeResultsMax(result, getLocalTrendsModsTask.Result); // result = MergeResultsMax(result, getLocalTrendsModsTask.Result);
//result = MergeResultsMult(result, getFFTModsTask.Result); //result = MergeResultsMult(result, getFFTModsTask.Result);
//result = MergeResultsMult(result, getSellsDiffsModsTask.Result); //result = MergeResultsMult(result, getSellsDiffsModsTask.Result);
//result = MergeResultsMult(result, getTradingModeModsTask.Result); result = MergeResultsMult(result, getTradingModeModsTask.Result);
result = MergeResultsMult(result, getSpeedResultantModsTask.Result); result = MergeResultsMult(result, getSpeedResultantModsTask.Result);
if (result[TradingEvent.UptrendStart] >= Constants.UppingCoefficient if (result[TradingEvent.UptrendStart] >= Constants.UppingCoefficient
@ -970,6 +1017,18 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
}, false); }, false);
} }
private async Task LogPrice(string figi, string ticker,DateTime time, decimal value, string processor)
{
await _tradeDataProvider.LogPrice(new ProcessedPrice()
{
Figi = figi,
Ticker = ticker,
Processor = processor,
Time = time,
Value = value,
}, false);
}
private async Task LogDeclision(DeclisionTradeAction action, INewPrice message, decimal? profit = null) private async Task LogDeclision(DeclisionTradeAction action, INewPrice message, decimal? profit = null)
{ {
await _tradeDataProvider.LogDeclision(new Declision() await _tradeDataProvider.LogDeclision(new Declision()
@ -1110,23 +1169,23 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
{ {
case TradingMode.Stable: case TradingMode.Stable:
{ {
return (0.5m, -0.5m); return (-0.5m, 0.5m);
} }
case TradingMode.Dropping: case TradingMode.Dropping:
{ {
return (-1.5m, null); ; return (-1.5m, 0.5m); ;
} }
case TradingMode.SlowDropping: case TradingMode.SlowDropping:
{ {
return (-0.5m, null); return (-1m, 0.5m);
} }
case TradingMode.SlowGrowing: case TradingMode.SlowGrowing:
{ {
return (null, 0.5m); return (-0.5m, 1m);
} }
case TradingMode.Growing: case TradingMode.Growing:
{ {
return (null, 1.5m); return (-0.5m, 1.5m);
} }
default: default:
{ {
@ -1138,26 +1197,26 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
private (decimal stopLoss, decimal takeProfit) GetStops(INewPrice message, PositionType type) private (decimal stopLoss, decimal takeProfit) GetStops(INewPrice message, PositionType type)
{ {
var mode = TradingModes[message.Figi]; var mode = TradingModes[message.Figi];
decimal stopLossShift = 15; decimal stopLossShift = 1.5m;
decimal takeProfitShift = 6; decimal takeProfitShift = 6;
if (mode == TradingMode.Growing && type == PositionType.Long) if (mode == TradingMode.Growing && type == PositionType.Long)
{ {
takeProfitShift = 15; takeProfitShift = 15;
stopLossShift = 2; //stopLossShift = 2;
} }
if (mode == TradingMode.Growing && type == PositionType.Short) if (mode == TradingMode.Growing && type == PositionType.Short)
{ {
stopLossShift = 2; //stopLossShift = 2;
takeProfitShift = 2; takeProfitShift = 3m;
} }
if (mode == TradingMode.Stable && type == PositionType.Long) if (mode == TradingMode.Stable && type == PositionType.Long)
{ {
takeProfitShift = 2.5m; takeProfitShift = 3m;
} }
if (mode == TradingMode.Stable && type == PositionType.Short) if (mode == TradingMode.Stable && type == PositionType.Short)
{ {
takeProfitShift = 2.5m; takeProfitShift = 3m;
stopLossShift = 10; //stopLossShift = 10;
} }
if (mode == TradingMode.SlowDropping && type == PositionType.Short) if (mode == TradingMode.SlowDropping && type == PositionType.Short)
{ {
@ -1166,12 +1225,12 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
if (mode == TradingMode.SlowDropping && type == PositionType.Long) if (mode == TradingMode.SlowDropping && type == PositionType.Long)
{ {
takeProfitShift = 1.5m; takeProfitShift = 1.5m;
stopLossShift = 10; //stopLossShift = 10;
} }
if (mode == TradingMode.SlowGrowing && type == PositionType.Short) if (mode == TradingMode.SlowGrowing && type == PositionType.Short)
{ {
takeProfitShift = 1.5m; //takeProfitShift = 2.5m;
stopLossShift = 10; //stopLossShift = 10;
} }
if (mode == TradingMode.SlowGrowing && type == PositionType.Long) if (mode == TradingMode.SlowGrowing && type == PositionType.Long)
{ {
@ -1179,12 +1238,12 @@ INewPrice message, int windowMaxSize, decimal? uptrendStartingDetectionMeanfullS
if (mode == TradingMode.Dropping && type == PositionType.Short) if (mode == TradingMode.Dropping && type == PositionType.Short)
{ {
takeProfitShift = 15; takeProfitShift = 15;
stopLossShift = 2; //stopLossShift = 2;
} }
if (mode == TradingMode.Dropping && type == PositionType.Long) if (mode == TradingMode.Dropping && type == PositionType.Long)
{ {
stopLossShift = 2; //stopLossShift = 2;
takeProfitShift = 1.5m; takeProfitShift = 3m;
} }
return (stopLossShift, takeProfitShift); return (stopLossShift, takeProfitShift);
} }

View File

@ -42,7 +42,7 @@ namespace KLHZ.Trader.Service.Controllers
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
while (time1 < DateTime.UtcNow.Date) while (time1 < DateTime.UtcNow)
{ {
var data = new List<TimeSeriesData>(); var data = new List<TimeSeriesData>();
var data2 = new List<TimeSeriesData>(); var data2 = new List<TimeSeriesData>();
@ -197,13 +197,27 @@ namespace KLHZ.Trader.Service.Controllers
} }
} }
} }
else
{
var ob = data[i].Orderbook;
if (ob != null)
{
var d = new TimeSeriesData()
{
Figi = ob.Figi,
Orderbook = ob,
Time = ob.Time,
};
data2.Add(d);
}
}
} }
foreach (var mess in data2) foreach (var mess in data2)
{ {
if (mess.Orderbook != null) if (mess.Orderbook != null)
{ {
await _traderDataProvider.AddOrderbook(mess.Orderbook); await _dataBus.Broadcast(mess.Orderbook);
} }
if (mess.NewPrice != null) if (mess.NewPrice != null)
{ {