чистка мусора + доработка вывода результатов
test / deploy_trader_prod (push) Successful in 11m24s
Details
test / deploy_trader_prod (push) Successful in 11m24s
Details
parent
b3b7807249
commit
6770d12640
|
@ -82,7 +82,6 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
return (resDt, resVs);
|
return (resDt, resVs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static (DateTime[] timestamps, decimal[] values) TrimValues(DateTime[] timestamps, decimal[] values, TimeSpan leftBound, TimeSpan rightBound)
|
public static (DateTime[] timestamps, decimal[] values) TrimValues(DateTime[] timestamps, decimal[] values, TimeSpan leftBound, TimeSpan rightBound)
|
||||||
{
|
{
|
||||||
var resDt = new List<DateTime>();
|
var resDt = new List<DateTime>();
|
||||||
|
|
|
@ -232,7 +232,7 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (TradingEvent events, decimal bigWindowAv, decimal smallWindowAv) CheckByWindowAverageMean2(ITradeDataItem[] data, int size, int smallWindow, int bigWindow,
|
public static (TradingEvent events, decimal bigWindowAv, decimal smallWindowAv) CheckByWindowAverageMean2(ITradeDataItem[] data, int size, int smallWindow, int bigWindow,
|
||||||
decimal? uptrendStartingDetectionMeanfullStep = null, decimal? uptrendEndingDetectionMeanfullStep = null)
|
decimal? uptrendStartingDetectionMeanfullStep = null, decimal? uptrendEndingDetectionMeanfullStep = null)
|
||||||
{
|
{
|
||||||
var res = TradingEvent.None;
|
var res = TradingEvent.None;
|
||||||
var bigWindowAv = 0m;
|
var bigWindowAv = 0m;
|
||||||
|
|
|
@ -5,7 +5,6 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
{
|
{
|
||||||
public static class Statistics
|
public static class Statistics
|
||||||
{
|
{
|
||||||
|
|
||||||
public static decimal MeanCount(this ITradeDataItem[] values)
|
public static decimal MeanCount(this ITradeDataItem[] values)
|
||||||
{
|
{
|
||||||
return values.Sum(x => x.Count) / values.Length;
|
return values.Sum(x => x.Count) / values.Length;
|
||||||
|
@ -197,25 +196,5 @@ namespace KLHZ.Trader.Core.Math.Declisions.Utils
|
||||||
}
|
}
|
||||||
return Array.Empty<ConvolutionResult>();
|
return Array.Empty<ConvolutionResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MergeConvolutionResults(List<ConvolutionResult> results, List<ConvolutionResult> mergedResults)
|
|
||||||
{
|
|
||||||
if (results.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var resultsOrdered = results.OrderBy(r => r.Sum).ToList();
|
|
||||||
var res = resultsOrdered[0];
|
|
||||||
var b1 = res.Shift - res.Leverage;
|
|
||||||
var b2 = res.Shift + res.Leverage;
|
|
||||||
var forMerge = results.Where(r => r.Shift >= b1 && r.Shift <= b2).ToList();
|
|
||||||
res.Sum = forMerge.Sum(r => r.Sum);
|
|
||||||
foreach (var m in forMerge)
|
|
||||||
{
|
|
||||||
results.Remove(m);
|
|
||||||
}
|
|
||||||
mergedResults.Add(res);
|
|
||||||
MergeConvolutionResults(results, mergedResults);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
using KLHZ.Trader.Core.Contracts.Common.Enums;
|
||||||
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
using KLHZ.Trader.Core.Exchange.Models.AssetsAccounting;
|
||||||
|
using KLHZ.Trader.Core.Exchange.Models.Trading;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace KLHZ.Trader.Core.Exchange.Interfaces
|
namespace KLHZ.Trader.Core.Exchange.Interfaces
|
||||||
|
@ -14,8 +15,8 @@ namespace KLHZ.Trader.Core.Exchange.Interfaces
|
||||||
Task Init(string accountId, string? accountName = null);
|
Task Init(string accountId, string? accountName = null);
|
||||||
Task LoadPortfolio();
|
Task LoadPortfolio();
|
||||||
ImmutableDictionary<string, Asset> Assets { get; }
|
ImmutableDictionary<string, Asset> Assets { get; }
|
||||||
public Task OpenPosition(string figi, PositionType positionType, decimal stopLossShift, decimal takeProfitShift, long count = 1);
|
public Task<TradeResult> OpenPosition(string figi, PositionType positionType, decimal stopLossShift, decimal takeProfitShift, long count = 1, decimal pointPrice = 1);
|
||||||
public Task ClosePosition(string figi);
|
public Task<TradeResult> ClosePosition(string figi);
|
||||||
public Task ResetStops(string figi, decimal stopLossShift, decimal takeProfitShift);
|
public Task ResetStops(string figi, decimal stopLossShift, decimal takeProfitShift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
public required string Figi { get; init; }
|
public required string Figi { get; init; }
|
||||||
public decimal ShortLeverage { get; init; }
|
public decimal ShortLeverage { get; init; }
|
||||||
public decimal LongLeverage { get; init; }
|
public decimal LongLeverage { get; init; }
|
||||||
public decimal PriceToRubConvertationCoefficient { get; init; } = 1;
|
public decimal PointPriceRub { get; init; } = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace KLHZ.Trader.Core.Exchange.Models.Trading
|
||||||
|
{
|
||||||
|
public class TradeResult
|
||||||
|
{
|
||||||
|
public bool Success { get; init; }
|
||||||
|
public decimal ExecutedPrice { get; init; }
|
||||||
|
public decimal Comission { get; init; }
|
||||||
|
public long Count { get; init; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
namespace KLHZ.Trader.Core.Exchange.Models.Trading
|
|
||||||
{
|
|
||||||
public enum TradingMode
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Stable = 1,
|
|
||||||
SlowDropping = -1,
|
|
||||||
SlowGrowing = 2,
|
|
||||||
Growing = 3,
|
|
||||||
Dropping = -2,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ using KLHZ.Trader.Core.DataLayer;
|
||||||
using KLHZ.Trader.Core.Exchange.Extentions;
|
using KLHZ.Trader.Core.Exchange.Extentions;
|
||||||
using KLHZ.Trader.Core.Exchange.Interfaces;
|
using KLHZ.Trader.Core.Exchange.Interfaces;
|
||||||
using KLHZ.Trader.Core.Exchange.Models.Configs;
|
using KLHZ.Trader.Core.Exchange.Models.Configs;
|
||||||
|
using KLHZ.Trader.Core.Exchange.Models.Trading;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
@ -164,8 +165,9 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
Balance = portfolio.TotalAmountCurrencies;
|
Balance = portfolio.TotalAmountCurrencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OpenPosition(string figi, PositionType positionType, decimal stopLossShift, decimal takeProfitShift, long count = 1)
|
public async Task<TradeResult> OpenPosition(string figi, PositionType positionType, decimal stopLossShift, decimal takeProfitShift, long count = 1, decimal pointPrice = 1)
|
||||||
{
|
{
|
||||||
|
TradeResult? result = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _semaphore.WaitAsync2(_defaultLockTimeSpan);
|
await _semaphore.WaitAsync2(_defaultLockTimeSpan);
|
||||||
|
@ -186,58 +188,54 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
var res = await _investApiClient.Orders.PostOrderAsync(req);
|
var res = await _investApiClient.Orders.PostOrderAsync(req);
|
||||||
|
|
||||||
_usedOrderIds.TryAdd(res.OrderId, DateTime.UtcNow);
|
_usedOrderIds.TryAdd(res.OrderId, DateTime.UtcNow);
|
||||||
var executedPrice = res.ExecutedOrderPrice / 10;
|
var executedPrice = res.ExecutedOrderPrice / pointPrice;
|
||||||
|
|
||||||
await Task.Delay(1000);
|
if (stopLossShift != 0)
|
||||||
|
|
||||||
if (stopLossShift == 0)
|
|
||||||
{
|
{
|
||||||
stopLossShift = 0.002m * executedPrice;
|
var pricesl = positionType == PositionType.Long ? executedPrice - stopLossShift : executedPrice + stopLossShift;
|
||||||
|
var slReq = new PostStopOrderRequest()
|
||||||
|
{
|
||||||
|
AccountId = AccountId,
|
||||||
|
ConfirmMarginTrade = false,
|
||||||
|
InstrumentId = figi,
|
||||||
|
Direction = stopOrdersDirection,
|
||||||
|
PriceType = PriceType.Point,
|
||||||
|
Quantity = count,
|
||||||
|
StopOrderType = StopOrderType.StopLoss,
|
||||||
|
StopPrice = pricesl,
|
||||||
|
ExchangeOrderType = ExchangeOrderType.Market,
|
||||||
|
ExpirationType = StopOrderExpirationType.GoodTillCancel,
|
||||||
|
};
|
||||||
|
var slOrderRes = await _investApiClient.StopOrders.PostStopOrderAsync(slReq);
|
||||||
}
|
}
|
||||||
if (takeProfitShift == 0)
|
|
||||||
|
if (takeProfitShift != 0)
|
||||||
{
|
{
|
||||||
takeProfitShift = 0.01m * executedPrice;
|
var pricetp = positionType == PositionType.Long ? executedPrice + takeProfitShift : executedPrice - takeProfitShift;
|
||||||
|
var tpReq = new PostStopOrderRequest()
|
||||||
|
{
|
||||||
|
AccountId = AccountId,
|
||||||
|
ConfirmMarginTrade = false,
|
||||||
|
InstrumentId = figi,
|
||||||
|
Direction = stopOrdersDirection,
|
||||||
|
PriceType = PriceType.Point,
|
||||||
|
Quantity = count,
|
||||||
|
StopOrderType = StopOrderType.TakeProfit,
|
||||||
|
StopPrice = pricetp,
|
||||||
|
ExchangeOrderType = ExchangeOrderType.Market,
|
||||||
|
ExpirationType = StopOrderExpirationType.GoodTillCancel,
|
||||||
|
};
|
||||||
|
var tpOrderRes = await _investApiClient.StopOrders.PostStopOrderAsync(tpReq);
|
||||||
}
|
}
|
||||||
takeProfitShift = takeProfitShift * 2;
|
|
||||||
takeProfitShift = System.Math.Round(takeProfitShift);
|
|
||||||
takeProfitShift = takeProfitShift / 2;
|
|
||||||
|
|
||||||
stopLossShift = stopLossShift * 2;
|
|
||||||
stopLossShift = System.Math.Round(stopLossShift);
|
|
||||||
stopLossShift = stopLossShift / 2;
|
|
||||||
|
|
||||||
var pricesl = positionType == PositionType.Long ? executedPrice - stopLossShift : executedPrice + stopLossShift;
|
|
||||||
var pricetp = positionType == PositionType.Long ? executedPrice + takeProfitShift : executedPrice - takeProfitShift;
|
|
||||||
var slReq = new PostStopOrderRequest()
|
|
||||||
{
|
|
||||||
AccountId = AccountId,
|
|
||||||
ConfirmMarginTrade = false,
|
|
||||||
InstrumentId = figi,
|
|
||||||
Direction = stopOrdersDirection,
|
|
||||||
PriceType = PriceType.Point,
|
|
||||||
Quantity = count,
|
|
||||||
StopOrderType = StopOrderType.StopLoss,
|
|
||||||
StopPrice = pricesl,
|
|
||||||
ExchangeOrderType = ExchangeOrderType.Market,
|
|
||||||
ExpirationType = StopOrderExpirationType.GoodTillCancel,
|
|
||||||
};
|
|
||||||
var slOrderRes = await _investApiClient.StopOrders.PostStopOrderAsync(slReq);
|
|
||||||
|
|
||||||
var tpReq = new PostStopOrderRequest()
|
|
||||||
{
|
|
||||||
AccountId = AccountId,
|
|
||||||
ConfirmMarginTrade = false,
|
|
||||||
InstrumentId = figi,
|
|
||||||
Direction = stopOrdersDirection,
|
|
||||||
PriceType = PriceType.Point,
|
|
||||||
Quantity = count,
|
|
||||||
StopOrderType = StopOrderType.TakeProfit,
|
|
||||||
StopPrice = pricetp,
|
|
||||||
ExchangeOrderType = ExchangeOrderType.Market,
|
|
||||||
ExpirationType = StopOrderExpirationType.GoodTillCancel,
|
|
||||||
};
|
|
||||||
var tpOrderRes = await _investApiClient.StopOrders.PostStopOrderAsync(tpReq);
|
|
||||||
await LoadPortfolioNolock();
|
await LoadPortfolioNolock();
|
||||||
|
result = new TradeResult()
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Comission = res.ExecutedCommission,
|
||||||
|
Count = res.LotsExecuted,
|
||||||
|
ExecutedPrice = res.ExecutedOrderPrice,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
|
@ -247,6 +245,8 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
_semaphore.Release();
|
_semaphore.Release();
|
||||||
|
result ??= new TradeResult();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ResetStops(string figi, decimal stopLossShift, decimal takeProfitShift)
|
public async Task ResetStops(string figi, decimal stopLossShift, decimal takeProfitShift)
|
||||||
|
@ -317,8 +317,9 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
_semaphore.Release();
|
_semaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ClosePosition(string figi)
|
public async Task<TradeResult> ClosePosition(string figi)
|
||||||
{
|
{
|
||||||
|
TradeResult? result = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _semaphore.WaitAsync2(_defaultLockTimeSpan);
|
await _semaphore.WaitAsync2(_defaultLockTimeSpan);
|
||||||
|
@ -355,6 +356,13 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
await LoadPortfolioNolock();
|
await LoadPortfolioNolock();
|
||||||
|
result = new TradeResult()
|
||||||
|
{
|
||||||
|
Success = true,
|
||||||
|
Comission = res.ExecutedCommission,
|
||||||
|
Count = res.LotsExecuted,
|
||||||
|
ExecutedPrice = res.ExecutedOrderPrice,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException) { }
|
catch (TaskCanceledException) { }
|
||||||
|
@ -364,6 +372,8 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
_semaphore.Release();
|
_semaphore.Release();
|
||||||
|
result ??= new TradeResult();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CyclingOperations()
|
private async Task CyclingOperations()
|
||||||
|
|
|
@ -32,12 +32,10 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
private readonly ExchangeConfig _exchangeConfig;
|
private readonly ExchangeConfig _exchangeConfig;
|
||||||
private readonly ILogger<Trader> _logger;
|
private readonly ILogger<Trader> _logger;
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, TradingMode> TradingModes = new();
|
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, DeferredDeclision> DeferredDeclisions = new();
|
private readonly ConcurrentDictionary<string, DeferredDeclision> DeferredDeclisions = new();
|
||||||
private readonly ConcurrentDictionary<string, SupportLevel[]> SupportLevels = new();
|
private readonly ConcurrentDictionary<string, SupportLevel[]> SupportLevels = new();
|
||||||
private readonly ConcurrentDictionary<string, decimal> _pirsonValues = new();
|
private readonly ConcurrentDictionary<string, decimal> _pirsonValues = new();
|
||||||
private readonly ConcurrentDictionary<string, decimal> _dpirsonValues = new();
|
|
||||||
private readonly ConcurrentDictionary<string, DateTime> _supportLevelsCalculationTimes = new();
|
private readonly ConcurrentDictionary<string, DateTime> _supportLevelsCalculationTimes = new();
|
||||||
private readonly ConcurrentDictionary<string, DateTime> _usedSupportLevels = new();
|
private readonly ConcurrentDictionary<string, DateTime> _usedSupportLevels = new();
|
||||||
private readonly ConcurrentDictionary<string, DateTime> _usedSupportLevelsForClosing = new();
|
private readonly ConcurrentDictionary<string, DateTime> _usedSupportLevelsForClosing = new();
|
||||||
|
@ -59,10 +57,6 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_dataBus = dataBus;
|
_dataBus = dataBus;
|
||||||
_exchangeConfig = options.Value;
|
_exchangeConfig = options.Value;
|
||||||
foreach (var f in _exchangeConfig.TradingInstrumentsFigis)
|
|
||||||
{
|
|
||||||
TradingModes[f] = TradingMode.None;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
@ -481,32 +475,27 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
{
|
{
|
||||||
Asset? assetForClose = null;
|
Asset? assetForClose = null;
|
||||||
string? mess = null;
|
string? mess = null;
|
||||||
|
var profit = 0m;
|
||||||
if (withProfitOnly)
|
if (withProfitOnly)
|
||||||
{
|
{
|
||||||
var profit = 0m;
|
if (_tradeDataProvider.Orderbooks.TryGetValue(message.Figi, out var orderbook))
|
||||||
|
|
||||||
if (assetType == AssetType.Futures)
|
|
||||||
{
|
{
|
||||||
if (_tradeDataProvider.Orderbooks.TryGetValue(message.Figi, out var orderbook))
|
if (asset.Count < 0 && orderbook.Asks.Length > 0)
|
||||||
{
|
{
|
||||||
if (asset.Count < 0 && orderbook.Asks.Length > 0)
|
price = orderbook.Asks[0].Price;
|
||||||
{
|
}
|
||||||
price = orderbook.Asks[0].Price;
|
else if (orderbook.Bids.Length > 0)
|
||||||
}
|
{
|
||||||
else if (orderbook.Bids.Length > 0)
|
price = orderbook.Bids[0].Price;
|
||||||
{
|
|
||||||
price = orderbook.Bids[0].Price;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
profit = TradingCalculator.CaclProfit(asset.BoughtPrice, price,
|
|
||||||
GetComission(assetType), GetLeverage(message.Figi, asset.Count < 0), asset.Count < 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profit = TradingCalculator.CaclProfit(asset.BoughtPrice, price,
|
||||||
|
GetComission(assetType), GetLeverage(message.Figi, asset.Count < 0), asset.Count < 0);
|
||||||
if (profit > 0)
|
if (profit > 0)
|
||||||
{
|
{
|
||||||
profit = System.Math.Round(profit, 2);
|
profit = System.Math.Round(profit, 2);
|
||||||
assetForClose = asset;
|
assetForClose = asset;
|
||||||
mess = $"Закрываю позицию {asset.Figi} ({(asset.Count > 0 ? "лонг" : "шорт")}) на счёте {_portfolioWrapper.Accounts[asset.AccountId].AccountName}. Количество {(long)asset.Count}, цена ~{price}, профит {profit}";
|
|
||||||
if (loggedDeclisions == 0)
|
if (loggedDeclisions == 0)
|
||||||
{
|
{
|
||||||
loggedDeclisions++;
|
loggedDeclisions++;
|
||||||
|
@ -516,13 +505,23 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mess = $"Закрываю позицию {asset.Figi} ({(asset.Count > 0 ? "лонг" : "шорт")}) на счёте {_portfolioWrapper.Accounts[asset.AccountId].AccountName}. Количество {(long)asset.Count}, цена ~{price}";
|
|
||||||
assetForClose = asset;
|
assetForClose = asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assetForClose != null && mess != null)
|
if (assetForClose != null)
|
||||||
{
|
{
|
||||||
await _portfolioWrapper.Accounts[asset.AccountId].ClosePosition(message.Figi);
|
var settings = _exchangeConfig.InstrumentsSettings.FirstOrDefault(l => l.Figi == message.Figi);
|
||||||
|
var closingResult = await _portfolioWrapper.Accounts[asset.AccountId].ClosePosition(message.Figi);
|
||||||
|
if (closingResult.Success)
|
||||||
|
{
|
||||||
|
var profitText = profit == 0 ? string.Empty : ", профит {profit}";
|
||||||
|
mess = $"Закрываю позицию {asset.Figi} ({(asset.Count > 0 ? "лонг" : "шорт")}) на счёте {_portfolioWrapper.Accounts[asset.AccountId].AccountName}. Количество {(long)asset.Count}, цена ~{closingResult.ExecutedPrice / (settings?.PointPriceRub ?? 1)}, комиссия {closingResult.Comission}" + profitText;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mess = $"Закрытие позиции прошло с ошибками.";
|
||||||
|
}
|
||||||
|
|
||||||
await _dataBus.Broadcast(new MessageForAdmin() { Text = mess });
|
await _dataBus.Broadcast(new MessageForAdmin() { Text = mess });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,12 +536,20 @@ namespace KLHZ.Trader.Core.Exchange.Services
|
||||||
{
|
{
|
||||||
if (TraderUtils.IsOperationAllowed(acc, message.Price, count, _exchangeConfig.AccountCashPartFutures, _exchangeConfig.AccountCashPart))
|
if (TraderUtils.IsOperationAllowed(acc, message.Price, count, _exchangeConfig.AccountCashPartFutures, _exchangeConfig.AccountCashPart))
|
||||||
{
|
{
|
||||||
await acc.OpenPosition(message.Figi, positionType, stopLossShift, takeProfitShift, count);
|
var settings = _exchangeConfig.InstrumentsSettings.FirstOrDefault(l => l.Figi == message.Figi);
|
||||||
|
takeProfitShift = takeProfitShift * 2;
|
||||||
|
takeProfitShift = System.Math.Round(takeProfitShift);
|
||||||
|
takeProfitShift = takeProfitShift / 2;
|
||||||
|
|
||||||
|
stopLossShift = stopLossShift * 2;
|
||||||
|
stopLossShift = System.Math.Round(stopLossShift);
|
||||||
|
stopLossShift = stopLossShift / 2;
|
||||||
|
var openingResult = await acc.OpenPosition(message.Figi, positionType, stopLossShift, takeProfitShift, count, settings?.PointPriceRub ?? 1);
|
||||||
await _dataBus.Broadcast(new MessageForAdmin()
|
await _dataBus.Broadcast(new MessageForAdmin()
|
||||||
{
|
{
|
||||||
Text = $"Открываю позицию {message.Figi} ({(positionType == PositionType.Long ? "лонг" : "шорт")}) " +
|
Text = $"Открываю позицию {message.Figi} ({(positionType == PositionType.Long ? "лонг" : "шорт")}) " +
|
||||||
$"на счёте {acc.AccountName}. Количество {(positionType == PositionType.Long ? "" : "-")}{count}, " +
|
$"на счёте {acc.AccountName}. Количество {(positionType == PositionType.Long ? "" : "-")}{openingResult.Count}, " +
|
||||||
$"цена ~{System.Math.Round(message.Price, 2)}. Стоп лосс: {(positionType == PositionType.Long ? "-" : "+")}{stopLossShift}. " +
|
$"цена ~{System.Math.Round(openingResult.ExecutedPrice / (settings?.PointPriceRub ?? 1), 2)}. Комиссия:{System.Math.Round(openingResult.Comission, 2)}. Стоп лосс: {(positionType == PositionType.Long ? "-" : "+")}{stopLossShift}. " +
|
||||||
$"Тейк профит: {(positionType == PositionType.Long ? "+" : "-")}{takeProfitShift}"
|
$"Тейк профит: {(positionType == PositionType.Long ? "+" : "-")}{takeProfitShift}"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"Figi": "FUTIMOEXF000",
|
"Figi": "FUTIMOEXF000",
|
||||||
"LongLeverage": 10.3,
|
"LongLeverage": 10.3,
|
||||||
"ShortLeverage": 7.9,
|
"ShortLeverage": 7.9,
|
||||||
"PriceToRubConvertationCoefficient" : 1
|
"PointPriceRub": 10
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue