Унификация используемых моделей
parent
41d33356dd
commit
584e378990
|
@ -1,4 +1,4 @@
|
|||
namespace KLHZ.Trader.Core.Exchange.Models.AssetsAccounting
|
||||
namespace KLHZ.Trader.Core.Contracts.Common.Enums
|
||||
{
|
||||
public enum PositionType
|
||||
{
|
|
@ -1,4 +1,4 @@
|
|||
namespace KLHZ.Trader.Core.Common
|
||||
namespace KLHZ.Trader.Core.Contracts.Common.Enums
|
||||
{
|
||||
public enum TradeDirection
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
namespace KLHZ.Trader.Core.Contracts.Declisions.Dtos
|
||||
{
|
||||
public class CachedValue //: ICachedValue
|
||||
public class CachedValue
|
||||
{
|
||||
public DateTime Time { get; init; }
|
||||
public long Count { get; init; }
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
|
||||
|
||||
namespace KLHZ.Trader.Core.Contracts.Declisions.Interfaces
|
||||
{
|
||||
internal interface ICachedValue : ITradeDataItem
|
||||
{
|
||||
public decimal Value { get; }
|
||||
public decimal Value2 { get; }
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces
|
||||
{
|
||||
public interface ILockableObject
|
||||
{
|
||||
public Task<bool> Lock(TimeSpan duration);
|
||||
|
||||
public void Unlock();
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces
|
||||
{
|
||||
public interface INewCandle
|
||||
{
|
||||
public bool IsHistoricalData { get; set; }
|
||||
public decimal Open { get; set; }
|
||||
public decimal Close { get; set; }
|
||||
public decimal High { get; set; }
|
||||
public decimal Low { get; set; }
|
||||
public decimal Volume { get; set; }
|
||||
public string Figi { get; set; }
|
||||
public string Ticker { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
|
@ -12,6 +12,5 @@ namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces
|
|||
public string AccountId { get; }
|
||||
public string? OrderId { get; }
|
||||
public bool EnableMargin { get; }
|
||||
public ILockableObject? ExchangeObject { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
|||
public long Count { get; init; }
|
||||
public required string AccountId { get; init; }
|
||||
public bool EnableMargin { get; init; } = true;
|
||||
public ILockableObject? ExchangeObject { get; init; }
|
||||
public string? OrderId { get; init; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace KLHZ.Trader.Core.Contracts.Messaging.Dtos
|
||||
{
|
||||
public class NewTrade : ITradeDataItem
|
||||
public class TradeDataItem : ITradeDataItem
|
||||
{
|
||||
public decimal Price { get; set; }
|
||||
public required string Figi { get; set; }
|
|
@ -1,224 +0,0 @@
|
|||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
|
||||
using KLHZ.Trader.Core.Math.Declisions.Dtos;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace KLHZ.Trader.Core.Math.Declisions.Services.Cache
|
||||
{
|
||||
public class PriceHistoryCacheUnit3 : IPriceHistoryCacheUnit
|
||||
{
|
||||
public const int CacheMaxLength = 30000;
|
||||
private const int _arrayMaxLength = 60000;
|
||||
|
||||
public string Figi { get; init; }
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public decimal AsksCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return _asksCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public decimal BidsCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return _bidsCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly object _locker = new();
|
||||
private readonly decimal[] Prices = new decimal[_arrayMaxLength];
|
||||
private readonly DateTime[] Timestamps = new DateTime[_arrayMaxLength];
|
||||
private readonly ConcurrentDictionary<string, TimeWindowCacheItem> _20_secTimeWindows = new();
|
||||
private readonly ConcurrentDictionary<string, TimeWindowCacheItem> _1_minTimeWindows = new();
|
||||
private readonly ConcurrentDictionary<string, TimeWindowCacheItem> _5_minTimeWindows = new();
|
||||
private readonly ConcurrentDictionary<string, TimeWindowCacheItem> _15_minTimeWindows = new();
|
||||
|
||||
private int _length = 0;
|
||||
private int _pointer = -1;
|
||||
|
||||
private long _asksCount = 1;
|
||||
private long _bidsCount = 1;
|
||||
|
||||
public ValueTask AddDataToTimeWindowCache(string key, CachedValue data, TimeWindowCacheType timeWindowCacheType)
|
||||
{
|
||||
var dict = GetDict(timeWindowCacheType);
|
||||
if (!dict.TryGetValue(key, out var cahcheItem))
|
||||
{
|
||||
dict.TryAdd(key, new TimeWindowCacheItem(key, timeWindowCacheType));
|
||||
}
|
||||
dict[key].AddData(data);
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask<CachedValue[]> GetDataFromTimeWindowCache(string key, TimeWindowCacheType timeWindowCacheType)
|
||||
{
|
||||
var dict = GetDict(timeWindowCacheType);
|
||||
if (dict.TryGetValue(key, out var cahcheItem))
|
||||
{
|
||||
return cahcheItem.GetValues();
|
||||
}
|
||||
return ValueTask.FromResult(Array.Empty<CachedValue>());
|
||||
}
|
||||
|
||||
private ConcurrentDictionary<string, TimeWindowCacheItem> GetDict(TimeWindowCacheType timeWindowCacheType)
|
||||
{
|
||||
switch (timeWindowCacheType)
|
||||
{
|
||||
case TimeWindowCacheType._5_Minutes:
|
||||
{
|
||||
return _5_minTimeWindows;
|
||||
}
|
||||
case TimeWindowCacheType._15_Minutes:
|
||||
{
|
||||
return _15_minTimeWindows;
|
||||
}
|
||||
case TimeWindowCacheType._20_Seconds:
|
||||
{
|
||||
return _20_secTimeWindows;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return _1_minTimeWindows; ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask AddData(ITradeDataItem priceChange)
|
||||
{
|
||||
if (priceChange.Figi != Figi) return ValueTask.CompletedTask;
|
||||
lock (_locker)
|
||||
{
|
||||
_pointer++;
|
||||
Prices[_pointer] = priceChange.Price;
|
||||
Timestamps[_pointer] = priceChange.Time;
|
||||
if (_length < CacheMaxLength)
|
||||
{
|
||||
_length++;
|
||||
}
|
||||
|
||||
if (_pointer == _arrayMaxLength - 1)
|
||||
{
|
||||
Array.Copy(Prices, Prices.Length - CacheMaxLength, Prices, 0, CacheMaxLength);
|
||||
Array.Copy(Timestamps, Timestamps.Length - CacheMaxLength, Timestamps, 0, CacheMaxLength);
|
||||
_pointer = CacheMaxLength - 1;
|
||||
}
|
||||
}
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask<(DateTime[] timestamps, decimal[] prices)> GetData(int? length = null)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
if (_pointer < 0)
|
||||
{
|
||||
return ValueTask.FromResult((Array.Empty<DateTime>(), Array.Empty<decimal>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
var dataLength = length.HasValue ? System.Math.Min(length.Value, _length) : _length;
|
||||
var prices = new decimal[dataLength];
|
||||
var timestamps = new DateTime[dataLength];
|
||||
var index = 1 + _pointer - dataLength;
|
||||
Array.Copy(Prices, index, prices, 0, prices.Length);
|
||||
Array.Copy(Timestamps, index, timestamps, 0, timestamps.Length);
|
||||
return ValueTask.FromResult((timestamps, prices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask AddOrderbook(IOrderbook orderbook)
|
||||
{
|
||||
if (orderbook.Figi != Figi) return ValueTask.CompletedTask;
|
||||
lock (_locker)
|
||||
{
|
||||
_asksCount = orderbook.AsksCount;
|
||||
_bidsCount = orderbook.BidsCount;
|
||||
}
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask<(DateTime time, decimal price)> GetLastValues()
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
return _pointer >= 0 ? ValueTask.FromResult((Timestamps[_pointer], Prices[_pointer])) : ValueTask.FromResult((DateTime.UtcNow, 0m));
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask<(DateTime[] timestamps, decimal[] prices, bool isFullIntervalExists)> GetData(TimeSpan period)
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
if (_pointer < 0)
|
||||
{
|
||||
return ValueTask.FromResult((Array.Empty<DateTime>(), Array.Empty<decimal>(), false));
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = _pointer;
|
||||
var lastTime = Timestamps[i];
|
||||
for (i = _pointer - 1; i >= 0; i--)
|
||||
{
|
||||
var currentTime = Timestamps[i];
|
||||
if (lastTime - currentTime >= period)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var dataLength = _pointer - i;
|
||||
var prices = new decimal[dataLength];
|
||||
var timestamps = new DateTime[dataLength];
|
||||
var index = 1 + _pointer - dataLength;
|
||||
Array.Copy(Prices, index, prices, 0, prices.Length);
|
||||
Array.Copy(Timestamps, index, timestamps, 0, timestamps.Length);
|
||||
return ValueTask.FromResult((timestamps, prices, i + 1 != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PriceHistoryCacheUnit3(string figi, params ITradeDataItem[] priceChanges)
|
||||
{
|
||||
Figi = figi;
|
||||
|
||||
|
||||
if (priceChanges.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedPriceChanges = priceChanges
|
||||
.OrderBy(pc => pc.Time)
|
||||
.Skip(priceChanges.Length - CacheMaxLength)
|
||||
.ToArray();
|
||||
|
||||
foreach (var pc in selectedPriceChanges)
|
||||
{
|
||||
AddData(pc).AsTask().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,10 +5,5 @@
|
|||
Unknown = 0,
|
||||
Ask = 1,
|
||||
Bid = 2,
|
||||
AsksSummary10 = 3,
|
||||
BidsSummary10 = 4,
|
||||
AsksSummary4 = 5,
|
||||
BidsSummary4 = 6,
|
||||
BidsAsksSummary4_2min = 7,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
||||
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
||||
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace KLHZ.Trader.Core.Exchange.Interfaces
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace KLHZ.Trader.Core.Exchange.Models.AssetsAccounting
|
||||
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
||||
|
||||
namespace KLHZ.Trader.Core.Exchange.Models.AssetsAccounting
|
||||
{
|
||||
public class Asset
|
||||
{
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
namespace KLHZ.Trader.Core.Exchange.Models.AssetsAccounting
|
||||
{
|
||||
public enum DealDirection
|
||||
{
|
||||
Unknown = 0,
|
||||
Buy = 1,
|
||||
Sell = 2
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
using KLHZ.Trader.Core.Common.Extentions;
|
||||
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
||||
using KLHZ.Trader.Core.DataLayer;
|
||||
using KLHZ.Trader.Core.Exchange.Extentions;
|
||||
using KLHZ.Trader.Core.Exchange.Interfaces;
|
||||
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
||||
using KLHZ.Trader.Core.Exchange.Models.Configs;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using KLHZ.Trader.Core.Common;
|
||||
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
|
||||
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Enums;
|
||||
|
@ -6,6 +7,7 @@ using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
|
|||
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
|
||||
using KLHZ.Trader.Core.DataLayer.Entities.Declisions.Enums;
|
||||
using KLHZ.Trader.Core.Exchange.Interfaces;
|
||||
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
||||
using KLHZ.Trader.Core.Exchange.Models.Configs;
|
||||
using KLHZ.Trader.Core.Exchange.Models.Trading;
|
||||
using KLHZ.Trader.Core.Exchange.Utils;
|
||||
|
@ -19,9 +21,6 @@ using System.Collections.Immutable;
|
|||
using System.Security.Cryptography;
|
||||
using System.Threading.Channels;
|
||||
using Tinkoff.InvestApi;
|
||||
using Asset = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.Asset;
|
||||
using AssetType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.AssetType;
|
||||
using PositionType = KLHZ.Trader.Core.Exchange.Models.AssetsAccounting.PositionType;
|
||||
|
||||
namespace KLHZ.Trader.Core.Exchange.Services
|
||||
{
|
||||
|
@ -80,7 +79,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
if (command.CommandType == TradeCommandType.OpenLong
|
||||
|| command.CommandType == TradeCommandType.OpenShort)
|
||||
{
|
||||
var fakeMessage = new NewTrade() { Figi = command.Figi, Ticker = "", Count = command.Count, Direction = 1, IsHistoricalData = false, Time = DateTime.UtcNow, Price = command.RecomendPrice ?? 0m };
|
||||
var fakeMessage = new TradeDataItem() { Figi = command.Figi, Ticker = "", Count = command.Count, Direction = 1, IsHistoricalData = false, Time = DateTime.UtcNow, Price = command.RecomendPrice ?? 0m };
|
||||
var positionType = command.CommandType == TradeCommandType.OpenLong ? PositionType.Long : PositionType.Short;
|
||||
var stops = GetStops(fakeMessage, positionType);
|
||||
var accounts = _portfolioWrapper.Accounts
|
||||
|
@ -92,7 +91,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
}
|
||||
else
|
||||
{
|
||||
var fakeMessage = new NewTrade() { Figi = command.Figi, Ticker = "", Count = command.Count, Direction = 1, IsHistoricalData = false, Time = DateTime.UtcNow, Price = command.RecomendPrice ?? 0m };
|
||||
var fakeMessage = new TradeDataItem() { Figi = command.Figi, Ticker = "", Count = command.Count, Direction = 1, IsHistoricalData = false, Time = DateTime.UtcNow, Price = command.RecomendPrice ?? 0m };
|
||||
var assetsForClose = _portfolioWrapper.Accounts
|
||||
.SelectMany(a => a.Value.Assets.Values)
|
||||
.Where(a => a.Figi == fakeMessage.Figi)
|
||||
|
|
|
@ -236,7 +236,7 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
|||
var data = await context1.PriceChanges
|
||||
.Where(c => _instrumentsFigis.Contains(c.Figi) && c.Time >= time)
|
||||
.OrderBy(c => c.Time)
|
||||
.Select(c => new NewTrade()
|
||||
.Select(c => new TradeDataItem()
|
||||
{
|
||||
Figi = c.Figi,
|
||||
Ticker = c.Ticker,
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace KLHZ.Trader.Service.Controllers
|
|||
var prices = await context1.PriceChanges
|
||||
.Where(c => (c.Figi == figi1 || c.Figi == figi2) && c.Time >= time1 && c.Time < time2)
|
||||
.OrderBy(c => c.Time)
|
||||
.Select(c => new NewTrade()
|
||||
.Select(c => new TradeDataItem()
|
||||
{
|
||||
Figi = c.Figi,
|
||||
Ticker = c.Ticker,
|
||||
|
|
Loading…
Reference in New Issue