рефакторинг
test / deploy_trader_prod (push) Successful in 10m34s Details

main
vlad zverzhkhovskiy 2025-10-20 17:23:10 +03:00
parent 4508e1f0df
commit 69cb165caf
10 changed files with 33 additions and 140 deletions

View File

@ -5,16 +5,16 @@ namespace KLHZ.Trader.Core.Tests
{ {
public class HistoryCacheUnit3Tests public class HistoryCacheUnit3Tests
{ {
private static PriceChange[] GetHistory(int count, string figi) private static Trade[] GetHistory(int count, string figi)
{ {
var res = new PriceChange[count]; var res = new Trade[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 PriceChange() res[i] = new Trade()
{ {
Figi = figi, Figi = figi,
Ticker = figi + "_ticker", Ticker = figi + "_ticker",

View File

@ -1,32 +0,0 @@
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
using KLHZ.Trader.Core.DataLayer.Entities.Orders.Enums;
using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Orders
{
[Table("orderbook_items")]
public class OrderbookItem : IOrderbookItem
{
[Column("id")]
public long Id { get; set; }
[Column("time")]
public DateTime Time { get; set; }
[Column("price")]
public decimal Price { get; set; }
[Column("count")]
public long Count { get; set; }
[Column("figi")]
public required string Figi { get; set; }
[Column("ticker")]
public required string Ticker { get; set; }
[Column("item_type")]
public OrderbookItemType ItemType { get; set; }
}
}

View File

@ -1,10 +0,0 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
{
[Table("price_changes")]
public class PriceChange : Trade
{
}
}

View File

@ -1,45 +0,0 @@
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
using System.ComponentModel.DataAnnotations.Schema;
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
{
[Table("experiment_results")]
public class ProcessedPrice : IProcessedPrice
{
[Column("id")]
public long Id { get; set; }
[Column("time")]
public DateTime Time { get; set; }
[Column("value")]
public decimal Price { get; set; }
[Column("figi")]
public required string Figi { get; set; }
[Column("ticker")]
public required string Ticker { get; set; }
public bool IsHistoricalData { get; set; }
[Column("processor")]
public required string Processor { get; set; }
[NotMapped]
public long Count { get; set; }
[NotMapped]
public int Direction { get; set; }
[NotMapped]
public decimal Value { get; set; }
[NotMapped]
public decimal Value2 { get; set; }
[NotMapped]
public AttachedInfo? AttachedInfo { get; private set; }
}
}

View File

@ -10,9 +10,7 @@ namespace KLHZ.Trader.Core.DataLayer
{ {
public DbSet<Declision> Declisions { get; set; } public DbSet<Declision> Declisions { get; set; }
public DbSet<Trade> Trades { 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<OrderbookItem> OrderbookItems { get; set; }
public DbSet<OrderbookElement> OrderbookElements { get; set; } public DbSet<OrderbookElement> OrderbookElements { get; set; }
public TraderDbContext(DbContextOptions<TraderDbContext> options) public TraderDbContext(DbContextOptions<TraderDbContext> options)
: base(options) : base(options)
@ -32,16 +30,6 @@ namespace KLHZ.Trader.Core.DataLayer
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
//modelBuilder.Entity<PriceChange>(entity =>
//{
// entity.HasKey(e1 => e1.Id);
// entity.Ignore(e1 => e1.IsHistoricalData);
// entity.Property(e => e.Time)
// .HasConversion(
// v => v.ToUniversalTime(),
// v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
//});
modelBuilder.Entity<Trade>(entity => modelBuilder.Entity<Trade>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => new { e1.Time, e1.Id });
@ -54,7 +42,7 @@ namespace KLHZ.Trader.Core.DataLayer
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
modelBuilder.Entity<ProcessedPrice>(entity => modelBuilder.Entity<ExperimentsResult>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => new { e1.Time, e1.Id });
entity.Ignore(e1 => e1.IsHistoricalData); entity.Ignore(e1 => e1.IsHistoricalData);
@ -66,15 +54,6 @@ namespace KLHZ.Trader.Core.DataLayer
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
modelBuilder.Entity<OrderbookItem>(entity =>
{
entity.HasKey(e1 => e1.Id);
entity.Property(e => e.Time)
.HasConversion(
v => v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
});
modelBuilder.Entity<OrderbookElement>(entity => modelBuilder.Entity<OrderbookElement>(entity =>
{ {
entity.HasKey(e1 => new { e1.Time, e1.Id }); entity.HasKey(e1 => new { e1.Time, e1.Id });
@ -85,16 +64,6 @@ namespace KLHZ.Trader.Core.DataLayer
v => v.ToUniversalTime(), v => v.ToUniversalTime(),
v => DateTime.SpecifyKind(v, DateTimeKind.Utc)); v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
}); });
//modelBuilder.Entity<ProcessedPrice>(entity =>
//{
// entity.HasKey(e1 => e1.Id);
// entity.Ignore(e1 => e1.IsHistoricalData);
// entity.Property(e => e.Time)
// .HasConversion(
// v => v.ToUniversalTime(),
// v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
//});
} }
} }
} }

View File

@ -137,7 +137,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
SubscribeOrderBookRequest = bookRequest SubscribeOrderBookRequest = bookRequest
}); });
var lastUpdateDict = new Dictionary<string, PriceChange>(); var lastUpdateDict = new Dictionary<string, Trade>();
var pricesBuffer = new List<Trade>(); var pricesBuffer = new List<Trade>();
var orderbookItemsBuffer = new List<OrderbookElement>(); var orderbookItemsBuffer = new List<OrderbookElement>();
var lastWrite = DateTime.UtcNow; var lastWrite = DateTime.UtcNow;

View File

@ -1,4 +1,5 @@
using KLHZ.Trader.Core.Contracts.Messaging.Dtos; using Google.Protobuf.WellKnownTypes;
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;
@ -10,6 +11,7 @@ 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;
@ -167,13 +169,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(ProcessedPrice price, bool saveImmediately) internal async Task LogPrice(ExperimentsResult 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.ProcessedPrices.AddRangeAsync(price); await context.ExperimentsResults.AddRangeAsync(price);
await context.SaveChangesAsync(); await context.SaveChangesAsync();
} }
else else
@ -198,7 +200,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 ProcessedPrice() await LogPrice(new ExperimentsResult()
{ {
Figi = message.Figi, Figi = message.Figi,
Ticker = message.Ticker, Ticker = message.Ticker,
@ -210,7 +212,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 ProcessedPrice() await LogPrice(new ExperimentsResult()
{ {
Figi = figi, Figi = figi,
Ticker = ticker, Ticker = ticker,
@ -222,6 +224,15 @@ 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,
@ -250,14 +261,14 @@ namespace KLHZ.Trader.Core.Exchange.Services
private async Task WritePricesTask() private async Task WritePricesTask()
{ {
var buffer1 = new List<ProcessedPrice>(); var buffer1 = new List<ExperimentsResult>();
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 ProcessedPrice price) if (obj is ExperimentsResult price)
{ {
buffer1.Add(price); buffer1.Add(price);
} }
@ -271,7 +282,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.ProcessedPrices.AddRangeAsync(buffer1); await context.ExperimentsResults.AddRangeAsync(buffer1);
} }
if (buffer2.Count > 0) if (buffer2.Count > 0)
{ {

View File

@ -76,7 +76,7 @@ namespace KLHZ.Trader.Core.Exchange.Utils
} }
else else
{ {
message = new PriceChange() message = new Trade()
{ {
Figi = message.Figi, Figi = message.Figi,
Ticker = message.Ticker, Ticker = message.Ticker,

View File

@ -43,7 +43,7 @@ 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.OrderbookItems var orderbooks = await context1.OrderbookElements
.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();
@ -77,7 +77,7 @@ namespace KLHZ.Trader.Service.Controllers
.OrderByDescending(o => o.Price) .OrderByDescending(o => o.Price)
.ToList(); .ToList();
var forRemove = new List<OrderbookItem>(); var forRemove = new List<OrderbookElement>();
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<OrderbookItem>(); var forRemove = new List<OrderbookElement>();
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.ProcessedPrice>(); var forSave = new List<Core.DataLayer.Entities.Prices.ExperimentsResult>();
time = time.AddMinutes(timeStep); time = time.AddMinutes(timeStep);
var figi1 = "FUTIMOEXF000"; var figi1 = "FUTIMOEXF000";
//var figi1 = "BBG004730N88"; //var figi1 = "BBG004730N88";
@ -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.ProcessedPrice() forSave.Add(new Core.DataLayer.Entities.Prices.ExperimentsResult()
{ {
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.ProcessedPrice() forSave.Add(new Core.DataLayer.Entities.Prices.ExperimentsResult()
{ {
Figi = price.Figi, Figi = price.Figi,
Processor = "support_level", Processor = "support_level",
@ -346,7 +346,7 @@ namespace KLHZ.Trader.Service.Controllers
} }
} }
await context1.ProcessedPrices.AddRangeAsync(forSave); await context1.ExperimentsResults.AddRangeAsync(forSave);
await context1.SaveChangesAsync(); await context1.SaveChangesAsync();
} }
} }