фиксация первой версии

main
vlad zverzhkhovskiy 2025-09-05 13:12:43 +03:00
parent 9114dda27f
commit 81d772fea9
1 changed files with 74 additions and 33 deletions

View File

@ -1,6 +1,7 @@
using KLHZ.Trader.Core.Common;
using KLHZ.Trader.Core.Contracts.Declisions.Dtos.Enums;
using KLHZ.Trader.Core.Contracts.Declisions.Interfaces;
using KLHZ.Trader.Core.Contracts.Messaging.Dtos;
using KLHZ.Trader.Core.Contracts.Messaging.Dtos.Interfaces;
using KLHZ.Trader.Core.Contracts.Messaging.Interfaces;
using KLHZ.Trader.Core.DataLayer;
@ -125,7 +126,31 @@ namespace KLHZ.Trader.Core.Exchange.Services
DeferredLongOpens.TryRemove(message.Figi, out _);
if (message.Value - longOpen.Price < 1)
{
LogDeclision(declisionsForSave, DeclisionTradeAction.OpenLong, message);
if (!message.IsHistoricalData)
{
var accounts = _tradeDataProvider.Accounts
.Where(a => !a.Value.Assets.ContainsKey(message.Figi))
.ToArray();
foreach (var acc in accounts)
{
if (IsBuyAllowed(acc.Value, message.Value, 1))
{
await _dataBus.Broadcast(new TradeCommand()
{
AccountId = acc.Value.AccountId,
Figi = message.Figi,
CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.MarketBuy,
Count = 1,
RecomendPrice = null,
});
LogDeclision(declisionsForSave, DeclisionTradeAction.OpenLong, message);
}
}
}
else
{
LogDeclision(declisionsForSave, DeclisionTradeAction.OpenLong, message);
}
}
}
}
@ -139,7 +164,44 @@ namespace KLHZ.Trader.Core.Exchange.Services
DeferredLongCloses.TryRemove(message.Figi, out _);
if (longClose.Price - message.Value < 1)
{
LogDeclision(declisionsForSave, DeclisionTradeAction.CloseLong, message);
if (!message.IsHistoricalData)
{
var assetsForClose = _tradeDataProvider.Accounts
.SelectMany(a => a.Value.Assets.Values)
.Where(a => a.Figi == message.Figi && a.Count > 0)
.ToArray();
foreach (var asset in assetsForClose)
{
var profit = 0m;
var assetType = _tradeDataProvider.GetAssetTypeByFigi(message.Figi);
if (assetType == AssetType.Common && asset.Count > 0)
{
profit = TradingCalculator.CaclProfit(asset.BoughtPrice, message.Value,
GetComission(assetType), 1, false);
}
if (assetType == AssetType.Futures)
{
profit = TradingCalculator.CaclProfit(asset.BoughtPrice, message.Value,
GetComission(assetType), GetLeverage(message.Figi, asset.Count < 0), asset.Count < 0);
}
if (profit > 0)
{
await _dataBus.Broadcast(new TradeCommand()
{
AccountId = asset.AccountId,
Figi = message.Figi,
CommandType = Contracts.Messaging.Dtos.Enums.TradeCommandType.MarketSell,
Count = (long)asset.Count,
RecomendPrice = null,
});
LogDeclision(declisionsForSave, DeclisionTradeAction.CloseLong, message);
}
}
}
else
{
LogDeclision(declisionsForSave, DeclisionTradeAction.CloseLong, message);
}
}
}
}
@ -333,46 +395,25 @@ namespace KLHZ.Trader.Core.Exchange.Services
}
}
private decimal CalcProfit(string accountId, string figi, decimal closePrice)
private decimal GetLeverage(string figi, bool isShort)
{
if (_tradeDataProvider.Accounts.TryGetValue(accountId, out var account))
var res = 1m;
if (Leverages.TryGetValue(figi, out var leverage))
{
if (account.Assets.TryGetValue(figi, out var asset))
{
var leverageValue = 1m;
var isShort = asset.Position == PositionType.Short;
if (Leverages.TryGetValue(figi, out var leverage))
{
if (asset.Type == AssetType.Futures && !isShort)
{
leverageValue = leverage.LongLeverage;
}
else if (isShort)
{
leverageValue = leverage.ShortLeverage;
}
}
return TradingCalculator.CaclProfit(asset.BoughtPrice, closePrice, GetComission(asset.Type), leverageValue, isShort);
}
res = isShort ? leverage.ShortLeverage : leverage.LongLeverage;
}
return 0;
return res;
}
private decimal GetCount(string accountId, decimal boutPrice)
{
var balance = _tradeDataProvider.Accounts[accountId].Balance;
return System.Math.Floor(balance * _defaultBuyPartOfAccount / boutPrice);
}
private bool IsBuyAllowed(string accountId, decimal boutPrice, decimal count, bool needBigCash)
private bool IsBuyAllowed(ManagedAccount account, decimal boutPrice, decimal count)
{
if (!_botModeSwitcher.CanPurchase()) return false;
var balance = _tradeDataProvider.Accounts[accountId].Balance;
var total = _tradeDataProvider.Accounts[accountId].Total;
var balance = account.Balance;
var total = account.Total;
var futures = _tradeDataProvider.Accounts[accountId].Assets.Values.FirstOrDefault(v => v.Type == AssetType.Futures);
if (futures != null || needBigCash)
var futures = account.Assets.Values.FirstOrDefault(v => v.Type == AssetType.Futures);
if (futures != null)
{
if ((balance - boutPrice * count) / total < _accountCashPartFutures) return false;
}