рефакторинг: вынос контрактов в отдельный проект
test / deploy_trader_prod (push) Successful in 2m42s
Details
test / deploy_trader_prod (push) Successful in 2m42s
Details
parent
f6b98e949d
commit
2d6bc10ed8
|
@ -0,0 +1,16 @@
|
|||
namespace KLHZ.Trader.Core.Contracts.Declisions.Dtos
|
||||
{
|
||||
public readonly struct TradingEventsDto
|
||||
{
|
||||
public readonly bool LongClose;
|
||||
public readonly bool LongOpen;
|
||||
|
||||
public TradingEventsDto(bool longClose, bool longOpen)
|
||||
{
|
||||
LongClose = longClose;
|
||||
LongOpen = longOpen;
|
||||
}
|
||||
|
||||
public readonly static TradingEventsDto Empty = new TradingEventsDto(false, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Contracts.Declisions.Interfaces
|
||||
{
|
||||
public interface IPriceHistoryCacheUnit
|
||||
{
|
||||
public string Figi { get; }
|
||||
public ValueTask AddData(INewPriceMessage priceChange);
|
||||
|
||||
public ValueTask<(DateTime[] timestamps, float[] prices)> GetData();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
|
||||
|
||||
namespace KLHZ.Trader.Core.Contracts.Declisions.Interfaces
|
||||
{
|
||||
public interface ITradingEventsDetector
|
||||
{
|
||||
public ValueTask<TradingEventsDto> Detect(IPriceHistoryCacheUnit unit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -1,4 +1,4 @@
|
|||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages.Enums
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums
|
||||
{
|
||||
public enum TradeCommandType
|
||||
{
|
|
@ -0,0 +1,7 @@
|
|||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces
|
||||
{
|
||||
public interface IMessage
|
||||
{
|
||||
public string Text { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces
|
||||
{
|
||||
public interface INewCandle
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces
|
||||
{
|
||||
public interface INewPriceMessage
|
||||
{
|
|
@ -0,0 +1,9 @@
|
|||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
||||
{
|
||||
public class MessageForAdmin : IMessage
|
||||
{
|
||||
public required string Text { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
||||
{
|
||||
public class NewPriceMessage : INewPriceMessage
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums;
|
||||
|
||||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
||||
{
|
||||
public class TradeCommand
|
||||
{
|
|
@ -1,22 +1,17 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Interfaces
|
||||
{
|
||||
public interface IDataBus
|
||||
{
|
||||
public bool AddChannel(string key, Channel<INewPriceMessage> channel);
|
||||
|
||||
public bool AddChannel(string key, Channel<TradeCommand> channel);
|
||||
public bool AddChannel(string key, Channel<IMessage> channel);
|
||||
public bool AddChannel(string key, Channel<INewCandle> channel);
|
||||
|
||||
public bool AddChannel(Channel<MessageForAdmin> channel);
|
||||
|
||||
public Task BroadcastNewPrice(INewPriceMessage newPriceMessage);
|
||||
|
||||
public Task BroadcastCommand(TradeCommand command);
|
||||
|
||||
public Task BroadcastCommand(MessageForAdmin command);
|
||||
public Task BroadcastNewCandle(INewCandle command);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
||||
using KLHZ.Trader.Core.Declisions.Models;
|
||||
using KLHZ.Trader.Core.Declisions.Services;
|
||||
|
||||
namespace KLHZ.Trader.Core.Tests
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count);
|
||||
Assert.That(data.timestamps.Length == count);
|
||||
|
@ -47,7 +47,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count);
|
||||
Assert.That(data.timestamps.Length == count);
|
||||
|
@ -65,7 +65,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count);
|
||||
Assert.That(data.timestamps.Length == count);
|
||||
|
@ -84,7 +84,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count);
|
||||
Assert.That(data.timestamps.Length == count);
|
||||
|
@ -104,7 +104,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count - shift);
|
||||
Assert.That(data.timestamps.Length == count - shift);
|
||||
|
@ -128,7 +128,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count - shift);
|
||||
Assert.That(data.timestamps.Length == count - shift);
|
||||
|
@ -152,7 +152,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count - shift);
|
||||
Assert.That(data.timestamps.Length == count - shift);
|
||||
|
@ -176,7 +176,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var figi = "figi";
|
||||
var hist = GetHistory(count, figi);
|
||||
var cacheUnit = new PriceHistoryCacheUnit("", hist);
|
||||
var data = cacheUnit.GetData();
|
||||
var data = cacheUnit.GetData().Result;
|
||||
|
||||
Assert.That(data.prices.Length == count);
|
||||
Assert.That(data.timestamps.Length == count);
|
||||
|
@ -191,7 +191,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
cacheUnit.AddData(newData1);
|
||||
|
||||
var data2 = cacheUnit.GetData();
|
||||
var data2 = cacheUnit.GetData().Result;
|
||||
Assert.IsTrue(data2.prices[data2.prices.Length - 1] == (float)newData1.Value);
|
||||
Assert.IsTrue(data2.timestamps[data2.timestamps.Length - 1] == newData1.Time);
|
||||
|
||||
|
@ -199,7 +199,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
cacheUnit.AddData(newData2);
|
||||
|
||||
var data3 = cacheUnit.GetData();
|
||||
var data3 = cacheUnit.GetData().Result;
|
||||
Assert.IsTrue(data3.prices[data3.prices.Length - 1] == (float)newData2.Value);
|
||||
Assert.IsTrue(data3.timestamps[data3.timestamps.Length - 1] == newData2.Time);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
||||
using KLHZ.Trader.Core.Declisions.Models;
|
||||
using KLHZ.Trader.Core.Declisions.Services;
|
||||
using KLHZ.Trader.Core.Declisions.Utils;
|
||||
|
||||
namespace KLHZ.Trader.Core.Tests
|
||||
|
@ -38,7 +38,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var startValue = 10;
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -72,7 +72,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
var startValue = 10;
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -107,7 +107,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -142,7 +142,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -177,7 +177,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -212,7 +212,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
var unit = new PriceHistoryCacheUnit(figi, GetHistory(count, figi, startDate, startValue, step));
|
||||
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var endDate = startDate.AddSeconds(count);
|
||||
Assert.IsTrue(data.timestamps.Last() == endDate);
|
||||
Assert.IsTrue(data.prices.Last() == startValue + step * count);
|
||||
|
@ -238,7 +238,7 @@ namespace KLHZ.Trader.Core.Tests
|
|||
|
||||
|
||||
var unit2 = new PriceHistoryCacheUnit(figi);
|
||||
var data2 = unit.GetData();
|
||||
var data2 = unit.GetData().Result;
|
||||
for (int i = 0; i < data2.prices.Length; i++)
|
||||
{
|
||||
var value = (decimal)data2.prices[i];
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
namespace KLHZ.Trader.Core.Common.Messaging.Contracts.Messages
|
||||
{
|
||||
public class MessageForAdmin
|
||||
{
|
||||
public required string Text { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Channels;
|
||||
|
||||
|
@ -7,14 +8,14 @@ namespace KLHZ.Trader.Core.Common.Messaging.Services
|
|||
{
|
||||
public class DataBus : IDataBus
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, Channel<IMessage>> _messagesChannels = new();
|
||||
private readonly ConcurrentDictionary<string, Channel<INewCandle>> _candlesChannels = new();
|
||||
private readonly ConcurrentDictionary<string, Channel<INewPriceMessage>> _priceChannels = new();
|
||||
private readonly ConcurrentDictionary<string, Channel<TradeCommand>> _commandChannels = new();
|
||||
private readonly ConcurrentDictionary<string, Channel<MessageForAdmin>> _chatMessages = new();
|
||||
|
||||
public bool AddChannel(Channel<MessageForAdmin> channel)
|
||||
public bool AddChannel(string key, Channel<IMessage> channel)
|
||||
{
|
||||
return _chatMessages.TryAdd(Guid.NewGuid().ToString(), channel);
|
||||
return _messagesChannels.TryAdd(key, channel);
|
||||
}
|
||||
|
||||
public bool AddChannel(string key, Channel<INewPriceMessage> channel)
|
||||
|
@ -55,13 +56,5 @@ namespace KLHZ.Trader.Core.Common.Messaging.Services
|
|||
await channel.Writer.WriteAsync(command);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task BroadcastCommand(MessageForAdmin message)
|
||||
{
|
||||
foreach (var channel in _chatMessages.Values)
|
||||
{
|
||||
await channel.Writer.WriteAsync(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace KLHZ.Trader.Core.Declisions.Models
|
||||
namespace KLHZ.Trader.Core.Declisions.Dtos
|
||||
{
|
||||
public readonly struct PeriodPricesInfo
|
||||
internal readonly struct PeriodPricesInfoDto
|
||||
{
|
||||
public readonly int Start;
|
||||
public readonly int End;
|
||||
|
@ -12,7 +12,7 @@
|
|||
public readonly bool Success;
|
||||
public readonly TimeSpan Period;
|
||||
|
||||
public PeriodPricesInfo(bool success, float firstPrice, float lastPrice, float periodDiff, float periodMin, float periodMax, TimeSpan period, int start, int end)
|
||||
public PeriodPricesInfoDto(bool success, float firstPrice, float lastPrice, float periodDiff, float periodMin, float periodMax, TimeSpan period, int start, int end)
|
||||
{
|
||||
Success = success;
|
||||
LastPrice = lastPrice;
|
|
@ -1,6 +1,6 @@
|
|||
namespace KLHZ.Trader.Core.Declisions.Models
|
||||
namespace KLHZ.Trader.Core.Declisions.Dtos
|
||||
{
|
||||
public readonly struct TwoPeriodsProcessingData
|
||||
internal readonly struct TwoPeriodsProcessingDto
|
||||
{
|
||||
public readonly int Start;
|
||||
public readonly int Bound;
|
||||
|
@ -11,7 +11,7 @@
|
|||
public readonly TimeSpan PeriodStart;
|
||||
public readonly TimeSpan PeriodEnd;
|
||||
|
||||
public TwoPeriodsProcessingData(bool success, float diffStart, float diffEnd, int start, int bound, int end,
|
||||
public TwoPeriodsProcessingDto(bool success, float diffStart, float diffEnd, int start, int bound, int end,
|
||||
TimeSpan periodStart, TimeSpan periodEnd)
|
||||
{
|
||||
Success = success;
|
|
@ -1,12 +1,13 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Declisions.Models
|
||||
namespace KLHZ.Trader.Core.Declisions.Services
|
||||
{
|
||||
public class PriceHistoryCacheUnit
|
||||
public class PriceHistoryCacheUnit : IPriceHistoryCacheUnit
|
||||
{
|
||||
public const int ArrayMaxLength = 500;
|
||||
|
||||
public readonly string Figi;
|
||||
public string Figi { get; init; }
|
||||
|
||||
private readonly object _locker = new();
|
||||
private readonly float[] Prices = new float[ArrayMaxLength];
|
||||
|
@ -14,7 +15,7 @@ namespace KLHZ.Trader.Core.Declisions.Models
|
|||
|
||||
private int Length = 0;
|
||||
|
||||
public void AddData(INewPriceMessage priceChange)
|
||||
public ValueTask AddData(INewPriceMessage priceChange)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
|
@ -29,9 +30,10 @@ namespace KLHZ.Trader.Core.Declisions.Models
|
|||
Length++;
|
||||
}
|
||||
}
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public (DateTime[] timestamps, float[] prices) GetData()
|
||||
public ValueTask<(DateTime[] timestamps, float[] prices)> GetData()
|
||||
{
|
||||
var prices = new float[Length];
|
||||
var timestamps = new DateTime[Length];
|
||||
|
@ -39,7 +41,7 @@ namespace KLHZ.Trader.Core.Declisions.Models
|
|||
{
|
||||
Array.Copy(Prices, Prices.Length - Length, prices, 0, prices.Length);
|
||||
Array.Copy(Timestamps, Prices.Length - Length, timestamps, 0, timestamps.Length);
|
||||
return (timestamps, prices);
|
||||
return ValueTask.FromResult((timestamps, prices));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using KLHZ.Trader.Core.Common;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using KLHZ.Trader.Core.DataLayer.Entities.Declisions;
|
||||
using KLHZ.Trader.Core.Declisions.Models;
|
||||
using KLHZ.Trader.Core.Declisions.Utils;
|
||||
using KLHZ.Trader.Core.Exchange;
|
||||
using KLHZ.Trader.Core.Exchange.Extentions;
|
||||
|
@ -30,6 +30,8 @@ namespace KLHZ.Trader.Core.Declisions.Services
|
|||
private readonly IDbContextFactory<TraderDbContext> _dbContextFactory;
|
||||
private readonly ConcurrentDictionary<string, ManagedAccount> Accounts = new();
|
||||
private readonly ConcurrentDictionary<string, PriceHistoryCacheUnit> _historyCash = new();
|
||||
private readonly ITradingEventsDetector _tradingEventsDetector;
|
||||
|
||||
|
||||
private readonly decimal _futureComission;
|
||||
private readonly decimal _shareComission;
|
||||
|
@ -41,6 +43,7 @@ namespace KLHZ.Trader.Core.Declisions.Services
|
|||
private readonly Channel<INewPriceMessage> _pricesChannel = Channel.CreateUnbounded<INewPriceMessage>();
|
||||
|
||||
public Trader(
|
||||
ITradingEventsDetector tradingEventsDetector,
|
||||
BotModeSwitcher botModeSwitcher,
|
||||
IServiceProvider provider,
|
||||
IOptions<ExchangeConfig> options,
|
||||
|
@ -48,6 +51,7 @@ namespace KLHZ.Trader.Core.Declisions.Services
|
|||
IDbContextFactory<TraderDbContext> dbContextFactory,
|
||||
InvestApiClient investApiClient)
|
||||
{
|
||||
_tradingEventsDetector = tradingEventsDetector;
|
||||
_botModeSwitcher = botModeSwitcher;
|
||||
_dataBus = dataBus;
|
||||
_provider = provider;
|
||||
|
@ -100,59 +104,11 @@ namespace KLHZ.Trader.Core.Declisions.Services
|
|||
data = new PriceHistoryCacheUnit(message.Figi, message);
|
||||
_historyCash.TryAdd(message.Figi, data);
|
||||
}
|
||||
|
||||
float meanfullDiff;
|
||||
if (message.Figi == "BBG004730N88")
|
||||
{
|
||||
meanfullDiff = 0.05f;
|
||||
}
|
||||
else if (message.Figi == "FUTIMOEXF000")
|
||||
{
|
||||
meanfullDiff = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var result = await _tradingEventsDetector.Detect(data);
|
||||
|
||||
try
|
||||
{
|
||||
//var downtrendStarts = data.CheckDowntrendStarting(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(7), meanfullDiff);
|
||||
var uptrendStarts = data.CheckLongOpen(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(7), meanfullDiff, 8, 3);
|
||||
var uptrendStarts2 = data.CheckLongOpen(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(3), meanfullDiff, 15, 2);
|
||||
var downtrendEnds = data.CheckLongOpen(TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(10), meanfullDiff, 15, 5);
|
||||
uptrendStarts |= downtrendEnds;
|
||||
uptrendStarts |= uptrendStarts2;
|
||||
//var downtrendEnds = data.CheckDowntrendEnding(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(15), meanfullDiff);
|
||||
|
||||
var uptrendEnds = data.CheckLongClose(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), meanfullDiff * 1.5f, 8, 8);
|
||||
var uptrendEnds2 = data.CheckLongClose(TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(30), meanfullDiff, 15, 8);
|
||||
uptrendEnds |= uptrendEnds2;
|
||||
|
||||
//var uptrendEnds2 = data.CheckUptrendEnding(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(20), meanfullDiff);
|
||||
|
||||
//var uptrendEnds = uptrendEnds1 || uptrendEnds2;
|
||||
|
||||
var declisionAction = DeclisionTradeAction.Unknown;
|
||||
|
||||
//if (downtrendStarts)
|
||||
//{
|
||||
// //declisionAction = DeclisionTradeAction.OpenShort;
|
||||
//}
|
||||
if (uptrendStarts)
|
||||
{
|
||||
declisionAction = DeclisionTradeAction.OpenLong;
|
||||
}
|
||||
//else if (downtrendEnds)
|
||||
//{
|
||||
// //declisionAction = DeclisionTradeAction.CloseShort;
|
||||
//}
|
||||
else if (uptrendEnds)
|
||||
{
|
||||
declisionAction = DeclisionTradeAction.CloseLong;
|
||||
}
|
||||
|
||||
if (declisionAction != DeclisionTradeAction.Unknown)
|
||||
if (result.LongOpen)
|
||||
{
|
||||
using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
|
@ -163,7 +119,22 @@ namespace KLHZ.Trader.Core.Declisions.Services
|
|||
Ticker = message.Ticker,
|
||||
Price = message.Value,
|
||||
Time = message.IsHistoricalData ? message.Time : DateTime.UtcNow,
|
||||
Action = declisionAction,
|
||||
Action = DeclisionTradeAction.OpenLong,
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
if (result.LongClose)
|
||||
{
|
||||
using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
await context.Declisions.AddAsync(new Declision()
|
||||
{
|
||||
AccountId = string.Empty,
|
||||
Figi = message.Figi,
|
||||
Ticker = message.Ticker,
|
||||
Price = message.Value,
|
||||
Time = message.IsHistoricalData ? message.Time : DateTime.UtcNow,
|
||||
Action = DeclisionTradeAction.CloseLong,
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer.Entities.Declisions;
|
||||
using KLHZ.Trader.Core.Declisions.Utils;
|
||||
|
||||
namespace KLHZ.Trader.Core.Declisions.Services
|
||||
{
|
||||
public class TradingEventsDetector : ITradingEventsDetector
|
||||
{
|
||||
public async ValueTask<TradingEventsDto> Detect(IPriceHistoryCacheUnit data)
|
||||
{
|
||||
await Task.Delay(0);
|
||||
float meanfullDiff;
|
||||
if (data.Figi == "BBG004730N88")
|
||||
{
|
||||
meanfullDiff = 0.05f;
|
||||
}
|
||||
else if (data.Figi == "FUTIMOEXF000")
|
||||
{
|
||||
meanfullDiff = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TradingEventsDto.Empty;
|
||||
}
|
||||
|
||||
//var downtrendStarts = data.CheckDowntrendStarting(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(7), meanfullDiff);
|
||||
var uptrendStarts = data.CheckLongOpen(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(7), meanfullDiff, 8, 3);
|
||||
var uptrendStarts2 = data.CheckLongOpen(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(3), meanfullDiff, 15, 2);
|
||||
var downtrendEnds = data.CheckLongOpen(TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(10), meanfullDiff, 15, 5);
|
||||
uptrendStarts |= downtrendEnds;
|
||||
uptrendStarts |= uptrendStarts2;
|
||||
//var downtrendEnds = data.CheckDowntrendEnding(TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(15), meanfullDiff);
|
||||
|
||||
var uptrendEnds = data.CheckLongClose(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(20), meanfullDiff * 1.5f, 8, 8);
|
||||
var uptrendEnds2 = data.CheckLongClose(TimeSpan.FromSeconds(120), TimeSpan.FromSeconds(30), meanfullDiff, 15, 8);
|
||||
uptrendEnds |= uptrendEnds2;
|
||||
|
||||
//var uptrendEnds2 = data.CheckUptrendEnding(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(20), meanfullDiff);
|
||||
|
||||
//var uptrendEnds = uptrendEnds1 || uptrendEnds2;
|
||||
|
||||
var declisionAction = DeclisionTradeAction.Unknown;
|
||||
|
||||
//if (downtrendStarts)
|
||||
//{
|
||||
// //declisionAction = DeclisionTradeAction.OpenShort;
|
||||
//}
|
||||
if (uptrendStarts)
|
||||
{
|
||||
declisionAction = DeclisionTradeAction.OpenLong;
|
||||
}
|
||||
//else if (downtrendEnds)
|
||||
//{
|
||||
// //declisionAction = DeclisionTradeAction.CloseShort;
|
||||
//}
|
||||
else if (uptrendEnds)
|
||||
{
|
||||
declisionAction = DeclisionTradeAction.CloseLong;
|
||||
}
|
||||
return new TradingEventsDto(uptrendEnds, uptrendStarts);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
using KLHZ.Trader.Core.Declisions.Models;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.Declisions.Dtos;
|
||||
using KLHZ.Trader.Core.Declisions.Services;
|
||||
|
||||
namespace KLHZ.Trader.Core.Declisions.Utils
|
||||
{
|
||||
internal static class HistoryProcessingInstruments
|
||||
{
|
||||
internal static PeriodPricesInfo GetPriceDiffForTimeSpan(this PriceHistoryCacheUnit unit, TimeSpan timeShift, TimeSpan timeSpan, int? pointsShift = null)
|
||||
internal static PeriodPricesInfoDto GetPriceDiffForTimeSpan(this IPriceHistoryCacheUnit unit, TimeSpan timeShift, TimeSpan timeSpan, int? pointsShift = null)
|
||||
{
|
||||
var res = new PeriodPricesInfo(false, 0, 0, 0, 0, 0, timeSpan, 0, 0);
|
||||
var data = unit.GetData();
|
||||
var res = new PeriodPricesInfoDto(false, 0, 0, 0, 0, 0, timeSpan, 0, 0);
|
||||
var data = unit.GetData().Result;
|
||||
var times = data.timestamps;
|
||||
var prices = data.prices;
|
||||
if (times.Length < 2) return res;
|
||||
|
@ -47,7 +49,7 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
|
||||
if (intervaStartIndex >= 0 && intervaEndIndex >= 0)
|
||||
{
|
||||
res = new PeriodPricesInfo(
|
||||
res = new PeriodPricesInfoDto(
|
||||
true,
|
||||
prices[intervaStartIndex],
|
||||
prices[intervaEndIndex],
|
||||
|
@ -62,31 +64,31 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return res;
|
||||
}
|
||||
|
||||
internal static bool CheckStable(this PeriodPricesInfo data, float meanfullDiff)
|
||||
internal static bool CheckStable(this PeriodPricesInfoDto data, float meanfullDiff)
|
||||
{
|
||||
meanfullDiff = Math.Abs(meanfullDiff);
|
||||
return data.Success && Math.Abs(data.PeriodDiff) < 1.5 * meanfullDiff && Math.Abs(data.PeriodMax - data.PeriodMin) < 2 * meanfullDiff;
|
||||
}
|
||||
|
||||
internal static bool CheckGrowing(this PeriodPricesInfo data, float meanfullDiff)
|
||||
internal static bool CheckGrowing(this PeriodPricesInfoDto data, float meanfullDiff)
|
||||
{
|
||||
return meanfullDiff > 0 && data.Success && data.PeriodDiff > meanfullDiff && Math.Abs(data.PeriodMax - data.PeriodMin) < 3 * Math.Abs(data.PeriodDiff);
|
||||
}
|
||||
|
||||
internal static bool CheckFalling(this PeriodPricesInfo data, float meanfullDiff)
|
||||
internal static bool CheckFalling(this PeriodPricesInfoDto data, float meanfullDiff)
|
||||
{
|
||||
meanfullDiff = -meanfullDiff;
|
||||
return meanfullDiff < 0 && data.Success && data.PeriodDiff < meanfullDiff && Math.Abs(data.PeriodMax - data.PeriodMin) < 3 * Math.Abs(data.PeriodDiff);
|
||||
}
|
||||
|
||||
internal static float CalcTrendRelationAbs(PeriodPricesInfo first, PeriodPricesInfo second)
|
||||
internal static float CalcTrendRelationAbs(PeriodPricesInfoDto first, PeriodPricesInfoDto second)
|
||||
{
|
||||
var k1 = Math.Abs(first.PeriodDiff) / Math.Abs(first.Period.TotalSeconds);
|
||||
var k2 = Math.Abs(second.PeriodDiff) / Math.Abs(second.Period.TotalSeconds);
|
||||
if (k2 == 0 && k1 != 0) return 1000;
|
||||
return (float)(k1 / k2);
|
||||
}
|
||||
internal static float CalcTrendRelationAbs(TwoPeriodsProcessingData data)
|
||||
internal static float CalcTrendRelationAbs(TwoPeriodsProcessingDto data)
|
||||
{
|
||||
var k1 = Math.Abs(data.DiffStart) / Math.Abs(data.PeriodStart.TotalSeconds);
|
||||
var k2 = Math.Abs(data.DiffEnd) / Math.Abs(data.PeriodEnd.TotalSeconds);
|
||||
|
@ -94,7 +96,7 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return (float)(k1 / k2);
|
||||
}
|
||||
|
||||
internal static bool CheckDowntrendEnding(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
internal static bool CheckDowntrendEnding(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
{
|
||||
var totalDiff = unit.GetPriceDiffForTimeSpan(TimeSpan.Zero, firstPeriod + secondPeriod);
|
||||
var startDiff = unit.GetPriceDiffForTimeSpan(secondPeriod, firstPeriod);
|
||||
|
@ -114,7 +116,7 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return res;
|
||||
}
|
||||
|
||||
internal static bool CheckUptrendEnding(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
internal static bool CheckUptrendEnding(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
{
|
||||
var totalDiff = unit.GetPriceDiffForTimeSpan(TimeSpan.Zero, firstPeriod + secondPeriod);
|
||||
var startDiff = unit.GetPriceDiffForTimeSpan(secondPeriod, firstPeriod);
|
||||
|
@ -178,9 +180,9 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return res;
|
||||
}
|
||||
|
||||
internal static TwoPeriodsProcessingData GetTwoPeriodsProcessingData(this (DateTime[] timestamps, float[] prices) data, TimeSpan shift, int shiftPointsStart, int shiftPointsEnd, TimeSpan firstPeriod, float meanfullDiff)
|
||||
internal static TwoPeriodsProcessingDto GetTwoPeriodsProcessingData(this (DateTime[] timestamps, float[] prices) data, TimeSpan shift, int shiftPointsStart, int shiftPointsEnd, TimeSpan firstPeriod, float meanfullDiff)
|
||||
{
|
||||
var res = new TwoPeriodsProcessingData(success: false, 0, 0, 0, 0, 0, TimeSpan.Zero, TimeSpan.Zero);
|
||||
var res = new TwoPeriodsProcessingDto(success: false, 0, 0, 0, 0, 0, TimeSpan.Zero, TimeSpan.Zero);
|
||||
var time = data.timestamps;
|
||||
var prices = data.prices;
|
||||
int count = -1;
|
||||
|
@ -210,14 +212,14 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
{
|
||||
var diff1 = prices[bound] - prices[start];
|
||||
var diff2 = prices[end] - prices[bound];
|
||||
res = new TwoPeriodsProcessingData(true, diff1, diff2, start, bound, end, time[bound] - time[start], time[end] - time[bound]);
|
||||
res = new TwoPeriodsProcessingDto(true, diff1, diff2, start, bound, end, time[bound] - time[start], time[end] - time[bound]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
internal static bool CheckLongClose(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff, int pointsStart, int pointsEnd)
|
||||
internal static bool CheckLongClose(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff, int pointsStart, int pointsEnd)
|
||||
{
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var periodStat = data.GetTwoPeriodsProcessingData(secondPeriod, pointsStart, pointsEnd, firstPeriod, meanfullDiff);
|
||||
var trendRelation = CalcTrendRelationAbs(periodStat);
|
||||
var isStartOk = periodStat.Success && periodStat.DiffStart > 0 && periodStat.DiffStart > 1.5 * meanfullDiff;
|
||||
|
@ -240,9 +242,9 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return isStartOk && isEndOk && (data.prices[periodStat.End] - data.prices[periodStat.Start] >= meanfullDiff);
|
||||
}
|
||||
|
||||
internal static bool CheckUptrendStarting2(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
internal static bool CheckUptrendStarting2(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
{
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var periodStat = data.GetTwoPeriodsProcessingData(secondPeriod, 15, 2, firstPeriod, meanfullDiff);
|
||||
var trendRelation = CalcTrendRelationAbs(periodStat);
|
||||
var isStartOk = periodStat.Success && periodStat.DiffStart < -meanfullDiff;
|
||||
|
@ -265,9 +267,9 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
return isStartOk && isEndOk;
|
||||
}
|
||||
|
||||
internal static bool _CheckUptrendStarting2(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
internal static bool _CheckUptrendStarting2(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff)
|
||||
{
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var periodStat = data.GetTwoPeriodsProcessingData(secondPeriod, 15, 1, firstPeriod, meanfullDiff);
|
||||
var trendRelation = CalcTrendRelationAbs(periodStat);
|
||||
var isStartOk = periodStat.Success && periodStat.DiffStart < -meanfullDiff;
|
||||
|
@ -291,9 +293,9 @@ namespace KLHZ.Trader.Core.Declisions.Utils
|
|||
}
|
||||
|
||||
|
||||
internal static bool CheckLongOpen(this PriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff, int pointsStart, int pointsEnd)
|
||||
internal static bool CheckLongOpen(this IPriceHistoryCacheUnit unit, TimeSpan firstPeriod, TimeSpan secondPeriod, float meanfullDiff, int pointsStart, int pointsEnd)
|
||||
{
|
||||
var data = unit.GetData();
|
||||
var data = unit.GetData().Result;
|
||||
var periodStat = data.GetTwoPeriodsProcessingData(secondPeriod, pointsStart, pointsEnd, firstPeriod, meanfullDiff);
|
||||
var trendRelation = CalcTrendRelationAbs(periodStat);
|
||||
var isStartOk = periodStat.Success && periodStat.DiffStart < -meanfullDiff;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Grpc.Core;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using KLHZ.Trader.Core.DataLayer.Entities.Prices;
|
||||
using KLHZ.Trader.Core.Exchange.Extentions;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using KLHZ.Trader.Core.Exchange.Extentions;
|
||||
using KLHZ.Trader.Core.Exchange.Models;
|
||||
|
|
|
@ -14,4 +14,8 @@
|
|||
<PackageReference Include="Tinkoff.InvestApi" Version="0.6.17" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\KLHZ.Trader.Core.Contracts\KLHZ.Trader.Core.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using KLHZ.Trader.Core.Common;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Collections.Immutable;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Intarfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Collections.Immutable;
|
||||
|
@ -13,14 +13,14 @@ namespace KLHZ.Trader.Core.TG.Services
|
|||
{
|
||||
private readonly TelegramBotClient _botClient;
|
||||
private readonly IUpdateHandler _updateHandler;
|
||||
private readonly Channel<MessageForAdmin> _messages = Channel.CreateUnbounded<MessageForAdmin>();
|
||||
private readonly Channel<IMessage> _messages = Channel.CreateUnbounded<IMessage>();
|
||||
private readonly ImmutableArray<long> _admins = [];
|
||||
|
||||
public BotStarter(IOptions<TgBotConfig> cfg, IUpdateHandler updateHandler, IDataBus dataBus, IOptions<TgBotConfig> options)
|
||||
{
|
||||
_botClient = new TelegramBotClient(cfg.Value.Token);
|
||||
_updateHandler = updateHandler;
|
||||
dataBus.AddChannel(_messages);
|
||||
dataBus.AddChannel("", _messages);
|
||||
_admins = ImmutableArray.CreateRange(options.Value.Admins);
|
||||
_ = ProcessMessages();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts.Messages;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using KLHZ.Trader.Core.Common;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Contracts;
|
||||
using KLHZ.Trader.Core.Common.Messaging.Services;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using KLHZ.Trader.Core.Declisions.Services;
|
||||
using KLHZ.Trader.Core.Exchange;
|
||||
|
@ -49,6 +50,7 @@ builder.Services.AddHostedService<Trader>();
|
|||
builder.Services.AddSingleton<IUpdateHandler, BotMessagesHandler>();
|
||||
builder.Services.AddSingleton<BotModeSwitcher>();
|
||||
builder.Services.AddSingleton<IDataBus, DataBus>();
|
||||
builder.Services.AddSingleton<ITradingEventsDetector, TradingEventsDetector>();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deploy", "deploy", "{9DE95D
|
|||
build-docker-compose.yml = build-docker-compose.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KLHZ.Trader.Core.Contracts", "KLHZ.Trader.Core.Contracts\KLHZ.Trader.Core.Contracts.csproj", "{C1ADC79B-ADDB-435D-A453-9D1623D144C4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -66,6 +68,10 @@ Global
|
|||
{9BF1E4ED-CCD5-401B-9F1C-3B7625258F7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9BF1E4ED-CCD5-401B-9F1C-3B7625258F7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9BF1E4ED-CCD5-401B-9F1C-3B7625258F7E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C1ADC79B-ADDB-435D-A453-9D1623D144C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C1ADC79B-ADDB-435D-A453-9D1623D144C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C1ADC79B-ADDB-435D-A453-9D1623D144C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C1ADC79B-ADDB-435D-A453-9D1623D144C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue