Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
|
69cb165caf | |
|
4508e1f0df | |
|
f49d4a9134 | |
|
9a5fedb41c | |
|
e3ad8b214a | |
|
61b98e88f7 |
|
@ -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",
|
||||||
|
|
|
@ -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 _canSell = true;
|
private static bool _canClose = true;
|
||||||
private static bool _canPurchase = true;
|
private static bool _canOpen = false;
|
||||||
|
|
||||||
public static bool CanSell()
|
public static bool CanClose()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
return _canSell;
|
return _canClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanPurchase()
|
public static bool CanOpen()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
return _canPurchase;
|
return _canOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopSelling()
|
public static void StopClosing()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
_canSell = false;
|
_canClose = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopPurchase()
|
public static void StopOpening()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
_canPurchase = false;
|
_canOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartSelling()
|
public static void StartClosing()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
_canSell = true;
|
_canClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartPurchase()
|
public static void StartOpening()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
_canPurchase = true;
|
_canOpen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,15 @@
|
||||||
public const string DisableTrading = "Стоп торги";
|
public const string DisableTrading = "Стоп торги";
|
||||||
public const string EnableTrading = "Старт торги";
|
public const string EnableTrading = "Старт торги";
|
||||||
|
|
||||||
public const string DisableSelling = "Выключить продажи";
|
public const string DisableClosing = "Выключить продажи";
|
||||||
public const string EnableSelling = "Включить продажи";
|
public const string DisableClosing2 = "Выключить закрытия";
|
||||||
|
public const string EnableClosing = "Включить продажи";
|
||||||
|
public const string EnableClosing2 = "Включить закрытия";
|
||||||
|
|
||||||
public const string DisablePurchases = "Выключить покупки";
|
public const string DisableOpening = "Выключить покупки";
|
||||||
public const string EnablePurchases = "Включить покупки";
|
public const string DisableOpening2 = "Выключить открытия";
|
||||||
|
public const string EnableOpening = "Включить покупки";
|
||||||
|
public const string EnableOpening2 = "Включить открытия";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_items")]
|
[Table("orderbook_elements")]
|
||||||
public class OrderbookItem : IOrderbookItem
|
public class OrderbookElement : IOrderbookItem
|
||||||
{
|
{
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
|
@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
||||||
{
|
{
|
||||||
[Table("processed_prices")]
|
[Table("experiment_results")]
|
||||||
public class ProcessedPrice : IProcessedPrice
|
public class ExperimentsResult : IProcessedPrice
|
||||||
{
|
{
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
|
@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
namespace KLHZ.Trader.Core.DataLayer.Entities.Prices
|
||||||
{
|
{
|
||||||
[Table("price_changes")]
|
[Table("trades")]
|
||||||
public class PriceChange : ITradeDataItem
|
public class Trade : ITradeDataItem
|
||||||
{
|
{
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
|
@ -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<PriceChange> PriceChanges { get; set; }
|
public DbSet<Trade> Trades { get; set; }
|
||||||
public DbSet<ProcessedPrice> ProcessedPrices { get; set; }
|
public DbSet<ExperimentsResult> ExperimentsResults { get; set; }
|
||||||
public DbSet<OrderbookItem> OrderbookItems { get; set; }
|
public DbSet<OrderbookElement> OrderbookElements { get; set; }
|
||||||
public TraderDbContext(DbContextOptions<TraderDbContext> options)
|
public TraderDbContext(DbContextOptions<TraderDbContext> options)
|
||||||
: base(options)
|
: base(options)
|
||||||
{
|
{
|
||||||
|
@ -30,29 +30,35 @@ namespace KLHZ.Trader.Core.DataLayer
|
||||||
v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
|
v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<PriceChange>(entity =>
|
modelBuilder.Entity<Trade>(entity =>
|
||||||
{
|
{
|
||||||
entity.HasKey(e1 => e1.Id);
|
entity.HasKey(e1 => new { e1.Time, 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<OrderbookItem>(entity =>
|
modelBuilder.Entity<ExperimentsResult>(entity =>
|
||||||
{
|
{
|
||||||
entity.HasKey(e1 => e1.Id);
|
entity.HasKey(e1 => new { e1.Time, 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<ProcessedPrice>(entity =>
|
modelBuilder.Entity<OrderbookElement>(entity =>
|
||||||
{
|
{
|
||||||
entity.HasKey(e1 => e1.Id);
|
entity.HasKey(e1 => new { e1.Time, 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(),
|
||||||
|
|
|
@ -13,6 +13,7 @@ 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
|
||||||
{
|
{
|
||||||
|
@ -136,15 +137,15 @@ 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<PriceChange>();
|
var pricesBuffer = new List<Trade>();
|
||||||
var orderbookItemsBuffer = new List<OrderbookItem>();
|
var orderbookItemsBuffer = new List<OrderbookElement>();
|
||||||
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 PriceChange()
|
var message = new Trade()
|
||||||
{
|
{
|
||||||
Figi = response.Trade.Figi,
|
Figi = response.Trade.Figi,
|
||||||
Ticker = _tradeDataProvider.GetTickerByFigi(response.Trade.Figi),
|
Ticker = _tradeDataProvider.GetTickerByFigi(response.Trade.Figi),
|
||||||
|
@ -161,7 +162,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 OrderbookItem()
|
var asks = response.Orderbook.Asks.Take(4).Select(a => new OrderbookElement()
|
||||||
{
|
{
|
||||||
Count = a.Quantity,
|
Count = a.Quantity,
|
||||||
Price = a.Price,
|
Price = a.Price,
|
||||||
|
@ -171,7 +172,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 OrderbookItem()
|
var bids = response.Orderbook.Bids.Take(4).Select(a => new OrderbookElement()
|
||||||
{
|
{
|
||||||
Count = a.Quantity,
|
Count = a.Quantity,
|
||||||
Price = a.Price,
|
Price = a.Price,
|
||||||
|
@ -203,16 +204,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.OrderbookItems.AddRangeAsync(orderbookItemsBuffer);
|
await context.OrderbookElements.AddRangeAsync(orderbookItemsBuffer);
|
||||||
orderbookItemsBuffer.Clear();
|
orderbookItemsBuffer.Clear();
|
||||||
}
|
}
|
||||||
if (pricesBuffer.Count > 0)
|
if (pricesBuffer.Count > 0)
|
||||||
{
|
{
|
||||||
await context.PriceChanges.AddRangeAsync(pricesBuffer);
|
await context.Trades.AddRangeAsync(pricesBuffer);
|
||||||
pricesBuffer.Clear();
|
pricesBuffer.Clear();
|
||||||
}
|
}
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
|
|
|
@ -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.CanPurchase())
|
if (!message.IsHistoricalData && BotModeSwitcher.CanOpen())
|
||||||
{
|
{
|
||||||
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.CanPurchase())
|
if (!message.IsHistoricalData && BotModeSwitcher.CanOpen())
|
||||||
{
|
{
|
||||||
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.CanSell())
|
if (!message.IsHistoricalData && BotModeSwitcher.CanClose())
|
||||||
{
|
{
|
||||||
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.CanPurchase())
|
if (!message.IsHistoricalData && BotModeSwitcher.CanClose())
|
||||||
{
|
{
|
||||||
var assetsForClose = _portfolioWrapper.Accounts
|
var assetsForClose = _portfolioWrapper.Accounts
|
||||||
.SelectMany(a => a.Value.Assets.Values)
|
.SelectMany(a => a.Value.Assets.Values)
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -130,7 +132,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.PriceChanges
|
var data = await context1.Trades
|
||||||
.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()
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.CanPurchase()) return false;
|
if (!BotModeSwitcher.CanOpen()) 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 PriceChange()
|
message = new Trade()
|
||||||
{
|
{
|
||||||
Figi = message.Figi,
|
Figi = message.Figi,
|
||||||
Ticker = message.Ticker,
|
Ticker = message.Ticker,
|
||||||
|
|
|
@ -45,35 +45,39 @@ namespace KLHZ.Trader.Core.TG.Services
|
||||||
case "/start":
|
case "/start":
|
||||||
{
|
{
|
||||||
var replyKeyboardMarkup = new ReplyKeyboardMarkup(new[] {
|
var replyKeyboardMarkup = new ReplyKeyboardMarkup(new[] {
|
||||||
new KeyboardButton[] { Constants.BotCommandsButtons.EnableSelling, Constants.BotCommandsButtons.DisableSelling},
|
new KeyboardButton[] { Constants.BotCommandsButtons.EnableClosing2, Constants.BotCommandsButtons.DisableClosing2},
|
||||||
new KeyboardButton[] { Constants.BotCommandsButtons.EnablePurchases, Constants.BotCommandsButtons.DisablePurchases}});
|
new KeyboardButton[] { Constants.BotCommandsButtons.EnableOpening2, Constants.BotCommandsButtons.EnableOpening2}});
|
||||||
|
|
||||||
|
|
||||||
await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup);
|
await botClient.SendMessage(update.Message.Chat, "Принято!", replyMarkup: replyKeyboardMarkup);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constants.BotCommandsButtons.EnableSelling:
|
case Constants.BotCommandsButtons.EnableClosing:
|
||||||
|
case Constants.BotCommandsButtons.EnableClosing2:
|
||||||
{
|
{
|
||||||
BotModeSwitcher.StartSelling();
|
BotModeSwitcher.StartClosing();
|
||||||
await botClient.SendMessage(update.Message.Chat, "Продажи начаты!");
|
await botClient.SendMessage(update.Message.Chat, "Закрытия разрешены!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constants.BotCommandsButtons.DisableSelling:
|
case Constants.BotCommandsButtons.DisableClosing:
|
||||||
|
case Constants.BotCommandsButtons.DisableClosing2:
|
||||||
{
|
{
|
||||||
BotModeSwitcher.StopSelling();
|
BotModeSwitcher.StopClosing();
|
||||||
await botClient.SendMessage(update.Message.Chat, "Продажи остановлены!");
|
await botClient.SendMessage(update.Message.Chat, "Закрытия запрещены!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constants.BotCommandsButtons.EnablePurchases:
|
case Constants.BotCommandsButtons.EnableOpening:
|
||||||
|
case Constants.BotCommandsButtons.EnableOpening2:
|
||||||
{
|
{
|
||||||
BotModeSwitcher.StartPurchase();
|
BotModeSwitcher.StartOpening();
|
||||||
await botClient.SendMessage(update.Message.Chat, "Покупки начаты!");
|
await botClient.SendMessage(update.Message.Chat, "Открытия начаты!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constants.BotCommandsButtons.DisablePurchases:
|
case Constants.BotCommandsButtons.DisableOpening:
|
||||||
|
case Constants.BotCommandsButtons.DisableOpening2:
|
||||||
{
|
{
|
||||||
BotModeSwitcher.StopPurchase();
|
BotModeSwitcher.StopOpening();
|
||||||
await botClient.SendMessage(update.Message.Chat, "Покупки остановлены!");
|
await botClient.SendMessage(update.Message.Chat, "Открытия остановлены!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "скинуть IMOEXF":
|
case "скинуть IMOEXF":
|
||||||
|
|
|
@ -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.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();
|
||||||
var prices = await context1.PriceChanges
|
var prices = await context1.Trades
|
||||||
.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<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";
|
||||||
|
@ -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.PriceChanges
|
var prices = await context1.Trades
|
||||||
.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.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,10 +346,57 @@ namespace KLHZ.Trader.Service.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await context1.ProcessedPrices.AddRangeAsync(forSave);
|
await context1.ExperimentsResults.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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue