Compare commits

..

No commits in common. "main" and "dev" have entirely different histories.
main ... dev

13 changed files with 84 additions and 157 deletions

View File

@ -5,16 +5,16 @@ namespace KLHZ.Trader.Core.Tests
{ {
public class HistoryCacheUnit3Tests public class HistoryCacheUnit3Tests
{ {
private static Trade[] GetHistory(int count, string figi) private static PriceChange[] GetHistory(int count, string figi)
{ {
var res = new Trade[count]; var res = new PriceChange[count];
if (count != 0) if (count != 0)
{ {
var startDt = DateTime.UtcNow.AddSeconds(-count); var startDt = DateTime.UtcNow.AddSeconds(-count);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
startDt = startDt.AddSeconds(1); startDt = startDt.AddSeconds(1);
res[i] = new Trade() res[i] = new PriceChange()
{ {
Figi = figi, Figi = figi,
Ticker = figi + "_ticker", Ticker = figi + "_ticker",

View File

@ -3,43 +3,43 @@
public static class BotModeSwitcher public static class BotModeSwitcher
{ {
private readonly static object _locker = new(); private readonly static object _locker = new();
private static bool _canClose = true; private static bool _canSell = true;
private static bool _canOpen = false; private static bool _canPurchase = true;
public static bool CanClose() public static bool CanSell()
{ {
lock (_locker) lock (_locker)
return _canClose; return _canSell;
} }
public static bool CanOpen() public static bool CanPurchase()
{ {
lock (_locker) lock (_locker)
return _canOpen; return _canPurchase;
} }
public static void StopClosing() public static void StopSelling()
{ {
lock (_locker) lock (_locker)
_canClose = false; _canSell = false;
} }
public static void StopOpening() public static void StopPurchase()
{ {
lock (_locker) lock (_locker)
_canOpen = false; _canPurchase = false;
} }
public static void StartClosing() public static void StartSelling()
{ {
lock (_locker) lock (_locker)
_canClose = true; _canSell = true;
} }
public static void StartOpening() public static void StartPurchase()
{ {
lock (_locker) lock (_locker)
_canOpen = true; _canPurchase = true;
} }
} }
} }

View File

@ -9,15 +9,11 @@
public const string DisableTrading = "Стоп торги"; public const string DisableTrading = "Стоп торги";
public const string EnableTrading = "Старт торги"; public const string EnableTrading = "Старт торги";
public const string DisableClosing = "Выключить продажи"; public const string DisableSelling = "Выключить продажи";
public const string DisableClosing2 = "Выключить закрытия"; public const string EnableSelling = "Включить продажи";
public const string EnableClosing = "Включить продажи";
public const string EnableClosing2 = "Включить закрытия";
public const string DisableOpening = "Выключить покупки"; public const string DisablePurchases = "Выключить покупки";
public const string DisableOpening2 = "Выключить открытия"; public const string EnablePurchases = "Включить покупки";
public const string EnableOpening = "Включить покупки";
public const string EnableOpening2 = "Включить открытия";
} }
} }
} }

View File

@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Orders namespace KLHZ.Trader.Core.DataLayer.Entities.Orders
{ {
[Table("orderbook_elements")] [Table("orderbook_items")]
public class OrderbookElement : IOrderbookItem public class OrderbookItem : IOrderbookItem
{ {
[Column("id")] [Column("id")]
public long Id { get; set; } public long Id { get; set; }

View File

@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
{ {
[Table("trades")] [Table("price_changes")]
public class Trade : ITradeDataItem public class PriceChange : ITradeDataItem
{ {
[Column("id")] [Column("id")]
public long Id { get; set; } public long Id { get; set; }

View File

@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
{ {
[Table("experiment_results")] [Table("processed_prices")]
public class ExperimentsResult : IProcessedPrice public class ProcessedPrice : IProcessedPrice
{ {
[Column("id")] [Column("id")]
public long Id { get; set; } public long Id { get; set; }

View File

@ -9,9 +9,9 @@ namespace KLHZ.Trader.Core.DataLayer
public class TraderDbContext : DbContext public class TraderDbContext : DbContext
{ {
public DbSet<Declision> Declisions { get; set; } public DbSet<Declision> Declisions { get; set; }
public DbSet<Trade> Trades { get; set; } public DbSet<PriceChange> PriceChanges { get; set; }
public DbSet<ExperimentsResult> ExperimentsResults { get; set; } public DbSet<ProcessedPrice> ProcessedPrices { get; set; }
public DbSet<OrderbookElement> OrderbookElements { get; set; } public DbSet<OrderbookItem> OrderbookItems { get; set; }
public TraderDbContext(DbContextOptions<TraderDbContext> options) public TraderDbContext(DbContextOptions<TraderDbContext> options)
: base(options) : base(options)
{ {
@ -30,35 +30,29 @@ namespace KLHZ.Trader.Core.DataLayer
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
modelBuilder.Entity<Trade>(entity => modelBuilder.Entity<PriceChange>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => e1.Id);
entity.Ignore(e1 => e1.IsHistoricalData); entity.Ignore(e1 => e1.IsHistoricalData);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
entity.Property(e => e.Time) entity.Property(e => e.Time)
.HasConversion( .HasConversion(
v => v.ToUniversalTime(), v => v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
modelBuilder.Entity<ExperimentsResult>(entity => modelBuilder.Entity<OrderbookItem>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => e1.Id);
entity.Ignore(e1 => e1.IsHistoricalData);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
entity.Property(e => e.Time) entity.Property(e => e.Time)
.HasConversion( .HasConversion(
v => v.ToUniversalTime(), v => v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
modelBuilder.Entity<OrderbookElement>(entity => modelBuilder.Entity<ProcessedPrice>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => e1.Id);
entity.Property(p => p.Id) entity.Ignore(e1 => e1.IsHistoricalData);
.ValueGeneratedOnAdd();
entity.Property(e => e.Time) entity.Property(e => e.Time)
.HasConversion( .HasConversion(
v => v.ToUniversalTime(), v => v.ToUniversalTime(),

View File

@ -13,7 +13,6 @@ using Microsoft.Extensions.Options;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Tinkoff.InvestApi; using Tinkoff.InvestApi;
using Tinkoff.InvestApi.V1; using Tinkoff.InvestApi.V1;
using Trade = KLHZ.Trader.Core.DataLayer.Entities.Prices.Trade;
namespace KLHZ.Trader.Core.Exchange.Services namespace KLHZ.Trader.Core.Exchange.Services
{ {
@ -137,15 +136,15 @@ namespace KLHZ.Trader.Core.Exchange.Services
SubscribeOrderBookRequest = bookRequest SubscribeOrderBookRequest = bookRequest
}); });
var lastUpdateDict = new Dictionary<string, Trade>(); var lastUpdateDict = new Dictionary<string, PriceChange>();
var pricesBuffer = new List<Trade>(); var pricesBuffer = new List<PriceChange>();
var orderbookItemsBuffer = new List<OrderbookElement>(); var orderbookItemsBuffer = new List<OrderbookItem>();
var lastWrite = DateTime.UtcNow; var lastWrite = DateTime.UtcNow;
await foreach (var response in stream.ResponseStream.ReadAllAsync()) await foreach (var response in stream.ResponseStream.ReadAllAsync())
{ {
if (response.Trade != null) if (response.Trade != null)
{ {
var message = new Trade() var message = new PriceChange()
{ {
Figi = response.Trade.Figi, Figi = response.Trade.Figi,
Ticker = _tradeDataProvider.GetTickerByFigi(response.Trade.Figi), Ticker = _tradeDataProvider.GetTickerByFigi(response.Trade.Figi),
@ -162,7 +161,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
if (response.Orderbook != null) if (response.Orderbook != null)
{ {
var asks = response.Orderbook.Asks.Take(4).Select(a => new OrderbookElement() var asks = response.Orderbook.Asks.Take(4).Select(a => new OrderbookItem()
{ {
Count = a.Quantity, Count = a.Quantity,
Price = a.Price, Price = a.Price,
@ -172,7 +171,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
Time = response.Orderbook.Time.ToDateTime().ToUniversalTime(), Time = response.Orderbook.Time.ToDateTime().ToUniversalTime(),
}).ToArray(); }).ToArray();
var bids = response.Orderbook.Bids.Take(4).Select(a => new OrderbookElement() var bids = response.Orderbook.Bids.Take(4).Select(a => new OrderbookItem()
{ {
Count = a.Quantity, Count = a.Quantity,
Price = a.Price, Price = a.Price,
@ -204,16 +203,16 @@ namespace KLHZ.Trader.Core.Exchange.Services
try try
{ {
using var context = await _dbContextFactory.CreateDbContextAsync(); using var context = await _dbContextFactory.CreateDbContextAsync();
//context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
lastWrite = DateTime.UtcNow; lastWrite = DateTime.UtcNow;
if (orderbookItemsBuffer.Count > 0) if (orderbookItemsBuffer.Count > 0)
{ {
await context.OrderbookElements.AddRangeAsync(orderbookItemsBuffer); await context.OrderbookItems.AddRangeAsync(orderbookItemsBuffer);
orderbookItemsBuffer.Clear(); orderbookItemsBuffer.Clear();
} }
if (pricesBuffer.Count > 0) if (pricesBuffer.Count > 0)
{ {
await context.Trades.AddRangeAsync(pricesBuffer); await context.PriceChanges.AddRangeAsync(pricesBuffer);
pricesBuffer.Clear(); pricesBuffer.Clear();
} }
await context.SaveChangesAsync(); await context.SaveChangesAsync();

View File

@ -719,7 +719,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
{ {
var stops = st.GetStops(PositionType.Long); var stops = st.GetStops(PositionType.Long);
if (!message.IsHistoricalData && BotModeSwitcher.CanOpen()) if (!message.IsHistoricalData && BotModeSwitcher.CanPurchase())
{ {
var accounts = _portfolioWrapper.Accounts var accounts = _portfolioWrapper.Accounts
.Where(a => !a.Value.Assets.ContainsKey(message.Figi)) .Where(a => !a.Value.Assets.ContainsKey(message.Figi))
@ -740,7 +740,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
) )
{ {
var stops = st.GetStops(PositionType.Short); var stops = st.GetStops(PositionType.Short);
if (!message.IsHistoricalData && BotModeSwitcher.CanOpen()) if (!message.IsHistoricalData && BotModeSwitcher.CanPurchase())
{ {
var accounts = _portfolioWrapper.Accounts var accounts = _portfolioWrapper.Accounts
.Where(a => !a.Value.Assets.ContainsKey(message.Figi)) .Where(a => !a.Value.Assets.ContainsKey(message.Figi))
@ -758,7 +758,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
} }
if (result[TradingEvent.CloseLong] >= Constants.UppingCoefficient) if (result[TradingEvent.CloseLong] >= Constants.UppingCoefficient)
{ {
if (!message.IsHistoricalData && BotModeSwitcher.CanClose()) if (!message.IsHistoricalData && BotModeSwitcher.CanSell())
{ {
var assetsForClose = _portfolioWrapper.Accounts var assetsForClose = _portfolioWrapper.Accounts
.SelectMany(a => a.Value.Assets.Values) .SelectMany(a => a.Value.Assets.Values)
@ -772,7 +772,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
if (result[TradingEvent.CloseShort] >= Constants.UppingCoefficient) if (result[TradingEvent.CloseShort] >= Constants.UppingCoefficient)
{ {
if (!message.IsHistoricalData && BotModeSwitcher.CanClose()) if (!message.IsHistoricalData && BotModeSwitcher.CanPurchase())
{ {
var assetsForClose = _portfolioWrapper.Accounts var assetsForClose = _portfolioWrapper.Accounts
.SelectMany(a => a.Value.Assets.Values) .SelectMany(a => a.Value.Assets.Values)

View File

@ -1,5 +1,4 @@
using Google.Protobuf.WellKnownTypes; using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces; using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
using KLHZ.Trader.Core.DataLayer; using KLHZ.Trader.Core.DataLayer;
using KLHZ.Trader.Core.DataLayer.Entities.Declisions; using KLHZ.Trader.Core.DataLayer.Entities.Declisions;
@ -11,7 +10,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading.Channels; using System.Threading.Channels;
using Tinkoff.InvestApi; using Tinkoff.InvestApi;
using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType; using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType;
@ -132,7 +130,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
var time = DateTime.UtcNow.AddHours(-20); var time = DateTime.UtcNow.AddHours(-20);
using var context1 = await _dbContextFactory.CreateDbContextAsync(); using var context1 = await _dbContextFactory.CreateDbContextAsync();
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var data = await context1.Trades var data = await context1.PriceChanges
.Where(c => _tradingInstrumentsFigis.Contains(c.Figi) && c.Time >= time) .Where(c => _tradingInstrumentsFigis.Contains(c.Figi) && c.Time >= time)
.OrderBy(c => c.Time) .OrderBy(c => c.Time)
.Select(c => new TradeDataItem() .Select(c => new TradeDataItem()
@ -169,13 +167,13 @@ namespace KLHZ.Trader.Core.Exchange.Services
{ {
return _assetTypesCache.TryGetValue(figi, out var t) ? t : AssetType.Unknown; return _assetTypesCache.TryGetValue(figi, out var t) ? t : AssetType.Unknown;
} }
internal async Task LogPrice(ExperimentsResult price, bool saveImmediately) internal async Task LogPrice(ProcessedPrice price, bool saveImmediately)
{ {
if (saveImmediately) if (saveImmediately)
{ {
using var context = await _dbContextFactory.CreateDbContextAsync(); using var context = await _dbContextFactory.CreateDbContextAsync();
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
await context.ExperimentsResults.AddRangeAsync(price); await context.ProcessedPrices.AddRangeAsync(price);
await context.SaveChangesAsync(); await context.SaveChangesAsync();
} }
else else
@ -200,7 +198,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
internal async Task LogPrice(ITradeDataItem message, string processor, decimal value) internal async Task LogPrice(ITradeDataItem message, string processor, decimal value)
{ {
await LogPrice(new ExperimentsResult() await LogPrice(new ProcessedPrice()
{ {
Figi = message.Figi, Figi = message.Figi,
Ticker = message.Ticker, Ticker = message.Ticker,
@ -212,7 +210,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
internal async Task LogPrice(string figi, string ticker, DateTime time, decimal value, string processor) internal async Task LogPrice(string figi, string ticker, DateTime time, decimal value, string processor)
{ {
await LogPrice(new ExperimentsResult() await LogPrice(new ProcessedPrice()
{ {
Figi = figi, Figi = figi,
Ticker = ticker, Ticker = ticker,
@ -224,15 +222,6 @@ namespace KLHZ.Trader.Core.Exchange.Services
internal async Task LogDeclision(DeclisionTradeAction action, ITradeDataItem message, decimal? profit = null) internal async Task LogDeclision(DeclisionTradeAction action, ITradeDataItem message, decimal? profit = null)
{ {
await LogPrice(new ExperimentsResult()
{
Figi = message.Figi,
Ticker = message.Ticker,
Processor = action.ToString(),
Time = message.Time,
Price = message.Price,
}, false);
await LogDeclision(new Declision() await LogDeclision(new Declision()
{ {
AccountId = string.Empty, AccountId = string.Empty,
@ -261,14 +250,14 @@ namespace KLHZ.Trader.Core.Exchange.Services
private async Task WritePricesTask() private async Task WritePricesTask()
{ {
var buffer1 = new List<ExperimentsResult>(); var buffer1 = new List<ProcessedPrice>();
var buffer2 = new List<Declision>(); var buffer2 = new List<Declision>();
while (await _forSave.Reader.WaitToReadAsync()) while (await _forSave.Reader.WaitToReadAsync())
{ {
try try
{ {
var obj = await _forSave.Reader.ReadAsync(); var obj = await _forSave.Reader.ReadAsync();
if (obj is ExperimentsResult price) if (obj is ProcessedPrice price)
{ {
buffer1.Add(price); buffer1.Add(price);
} }
@ -282,7 +271,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
if (buffer1.Count > 0) if (buffer1.Count > 0)
{ {
await context.ExperimentsResults.AddRangeAsync(buffer1); await context.ProcessedPrices.AddRangeAsync(buffer1);
} }
if (buffer2.Count > 0) if (buffer2.Count > 0)
{ {

View File

@ -42,7 +42,7 @@ namespace KLHZ.Trader.Core.Exchange.Utils
internal static bool IsOperationAllowed(IManagedAccount account, decimal boutPrice, decimal count, internal static bool IsOperationAllowed(IManagedAccount account, decimal boutPrice, decimal count,
decimal accountCashPartFutures, decimal accountCashPart) decimal accountCashPartFutures, decimal accountCashPart)
{ {
if (!BotModeSwitcher.CanOpen()) return false; if (!BotModeSwitcher.CanPurchase()) return false;
var balance = account.Balance; var balance = account.Balance;
var total = account.Total; var total = account.Total;
@ -76,7 +76,7 @@ namespace KLHZ.Trader.Core.Exchange.Utils
} }
else else
{ {
message = new Trade() message = new PriceChange()
{ {
Figi = message.Figi, Figi = message.Figi,
Ticker = message.Ticker, Ticker = message.Ticker,

View File

@ -45,39 +45,35 @@ namespace KLHZ.Trader.Core.TG.Services
case "/start": case "/start":
{ {
var replyKeyboardMarkup = new ReplyKeyboardMarkup(new[] { var replyKeyboardMarkup = new ReplyKeyboardMarkup(new[] {
new KeyboardButton[] { Constants.BotCommandsButtons.EnableClosing2, Constants.BotCommandsButtons.DisableClosing2}, new KeyboardButton[] { Constants.BotCommandsButtons.EnableSelling, Constants.BotCommandsButtons.DisableSelling},
new KeyboardButton[] { Constants.BotCommandsButtons.EnableOpening2, Constants.BotCommandsButtons.EnableOpening2}}); new KeyboardButton[] { Constants.BotCommandsButtons.EnablePurchases, Constants.BotCommandsButtons.DisablePurchases}});
await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup); await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup);
break; break;
} }
case Constants.BotCommandsButtons.EnableClosing: case Constants.BotCommandsButtons.EnableSelling:
case Constants.BotCommandsButtons.EnableClosing2:
{ {
BotModeSwitcher.StartClosing(); BotModeSwitcher.StartSelling();
await botClient.SendMessage(update.Message.Chat, "Закрытия разрешены!"); await botClient.SendMessage(update.Message.Chat, "Продажи начаты!");
break; break;
} }
case Constants.BotCommandsButtons.DisableClosing: case Constants.BotCommandsButtons.DisableSelling:
case Constants.BotCommandsButtons.DisableClosing2:
{ {
BotModeSwitcher.StopClosing(); BotModeSwitcher.StopSelling();
await botClient.SendMessage(update.Message.Chat, "Закрытия запрещены!"); await botClient.SendMessage(update.Message.Chat, "Продажи остановлены!");
break; break;
} }
case Constants.BotCommandsButtons.EnableOpening: case Constants.BotCommandsButtons.EnablePurchases:
case Constants.BotCommandsButtons.EnableOpening2:
{ {
BotModeSwitcher.StartOpening(); BotModeSwitcher.StartPurchase();
await botClient.SendMessage(update.Message.Chat, "Открытия начаты!"); await botClient.SendMessage(update.Message.Chat, "Покупки начаты!");
break; break;
} }
case Constants.BotCommandsButtons.DisableOpening: case Constants.BotCommandsButtons.DisablePurchases:
case Constants.BotCommandsButtons.DisableOpening2:
{ {
BotModeSwitcher.StopOpening(); BotModeSwitcher.StopPurchase();
await botClient.SendMessage(update.Message.Chat, "Открытия остановлены!"); await botClient.SendMessage(update.Message.Chat, "Покупки остановлены!");
break; break;
} }
case "скинуть IMOEXF": case "скинуть IMOEXF":

View File

@ -43,11 +43,11 @@ namespace KLHZ.Trader.Service.Controllers
var data = new List<TimeSeriesData>(); var data = new List<TimeSeriesData>();
var data2 = new List<TimeSeriesData>(); var data2 = new List<TimeSeriesData>();
var time2 = time1.AddHours(1); var time2 = time1.AddHours(1);
var orderbooks = await context1.OrderbookElements var orderbooks = await context1.OrderbookItems
.Where(oi => (oi.Figi == figi1 || oi.Figi == figi2) && oi.Time >= time1 && oi.Time < time2) .Where(oi => (oi.Figi == figi1 || oi.Figi == figi2) && oi.Time >= time1 && oi.Time < time2)
.OrderBy(c => c.Time) .OrderBy(c => c.Time)
.ToArrayAsync(); .ToArrayAsync();
var prices = await context1.Trades var prices = await context1.PriceChanges
.Where(c => (c.Figi == figi1 || c.Figi == figi2) && c.Time >= time1 && c.Time < time2) .Where(c => (c.Figi == figi1 || c.Figi == figi2) && c.Time >= time1 && c.Time < time2)
.OrderBy(c => c.Time) .OrderBy(c => c.Time)
.Select(c => new TradeDataItem() .Select(c => new TradeDataItem()
@ -77,7 +77,7 @@ namespace KLHZ.Trader.Service.Controllers
.OrderByDescending(o => o.Price) .OrderByDescending(o => o.Price)
.ToList(); .ToList();
var forRemove = new List<OrderbookElement>(); var forRemove = new List<OrderbookItem>();
if (asks.Count > 4 || bids.Count > 4) if (asks.Count > 4 || bids.Count > 4)
{ {
@ -124,7 +124,7 @@ namespace KLHZ.Trader.Service.Controllers
.Where(i => i.ItemType == Core.DataLayer.Entities.Orders.Enums.OrderbookItemType.Bid) .Where(i => i.ItemType == Core.DataLayer.Entities.Orders.Enums.OrderbookItemType.Bid)
.OrderByDescending(o => o.Price) .OrderByDescending(o => o.Price)
.ToList(); .ToList();
var forRemove = new List<OrderbookElement>(); var forRemove = new List<OrderbookItem>();
if (asks.Count > 4 || bids.Count > 4) if (asks.Count > 4 || bids.Count > 4)
{ {
@ -242,7 +242,7 @@ namespace KLHZ.Trader.Service.Controllers
var time = DateTime.UtcNow.AddDays(-shift ?? -7).Date; var time = DateTime.UtcNow.AddDays(-shift ?? -7).Date;
while (time < DateTime.UtcNow) while (time < DateTime.UtcNow)
{ {
var forSave = new List<Core.DataLayer.Entities.Prices.ExperimentsResult>(); var forSave = new List<Core.DataLayer.Entities.Prices.ProcessedPrice>();
time = time.AddMinutes(timeStep); time = time.AddMinutes(timeStep);
var figi1 = "FUTIMOEXF000"; var figi1 = "FUTIMOEXF000";
//var figi1 = "BBG004730N88"; //var figi1 = "BBG004730N88";
@ -255,7 +255,7 @@ namespace KLHZ.Trader.Service.Controllers
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var time1 = time2.AddHours(-3); var time1 = time2.AddHours(-3);
var prices = await context1.Trades var prices = await context1.PriceChanges
.Where(c => (c.Figi == figi1 || c.Figi == figi2) && c.Time >= time1 && c.Time < time2 && c.Direction == 1) .Where(c => (c.Figi == figi1 || c.Figi == figi2) && c.Time >= time1 && c.Time < time2 && c.Direction == 1)
.OrderBy(c => c.Time) .OrderBy(c => c.Time)
.Select(c => new TradeDataItem() .Select(c => new TradeDataItem()
@ -273,7 +273,7 @@ namespace KLHZ.Trader.Service.Controllers
if (pricesToSave.Any()) if (pricesToSave.Any())
{ {
var p1 = pricesToSave.Last(); var p1 = pricesToSave.Last();
forSave.Add(new Core.DataLayer.Entities.Prices.ExperimentsResult() forSave.Add(new Core.DataLayer.Entities.Prices.ProcessedPrice()
{ {
Figi = p1.Figi, Figi = p1.Figi,
Processor = "support_level_calc", Processor = "support_level_calc",
@ -332,7 +332,7 @@ namespace KLHZ.Trader.Service.Controllers
{ {
if (price.Price >= p.left && price.Price <= p.right) if (price.Price >= p.left && price.Price <= p.right)
{ {
forSave.Add(new Core.DataLayer.Entities.Prices.ExperimentsResult() forSave.Add(new Core.DataLayer.Entities.Prices.ProcessedPrice()
{ {
Figi = price.Figi, Figi = price.Figi,
Processor = "support_level", Processor = "support_level",
@ -346,57 +346,10 @@ namespace KLHZ.Trader.Service.Controllers
} }
} }
await context1.ExperimentsResults.AddRangeAsync(forSave); await context1.ProcessedPrices.AddRangeAsync(forSave);
await context1.SaveChangesAsync(); await context1.SaveChangesAsync();
} }
} }
} }
[HttpGet]
public async Task MigrateData()
{
try
{
using var context1 = await _dbContextFactory.CreateDbContextAsync();
context1.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var figis = context1.Trades.Select(p => p.Figi).Distinct().ToArray();
foreach (var f in figis)
{
try
{
var time1 = new DateTime(2025, 8, 25, 0, 0, 0, DateTimeKind.Utc);
while (time1 < DateTime.UtcNow)
{
var time2 = time1.AddDays(7);
var prices = await context1.Trades
.Where(c => (c.Figi == f) && c.Time >= time1 && c.Time < time2)
.OrderBy(c => c.Time)
.ToArrayAsync();
await context1.Trades.AddRangeAsync(prices);
await context1.SaveChangesAsync();
time1 = time2;
}
}
catch (Exception ex)
{
}
}
}
catch (Exception ex)
{
}
}
} }
} }