public async Task CreateLimitOrderAsync(string assetId, string exchange, LimitOrderType limitOrderType, decimal price, decimal volume, string userId) { AssetHedgeSettings assetHedgeSettings = await _assetHedgeSettingsService.GetByAssetIdAsync(assetId, exchange); if (assetHedgeSettings == null) { throw new InvalidOperationException("Asset hedge settings not found"); } if (assetHedgeSettings.Mode != AssetHedgeMode.Manual) { throw new InvalidOperationException("Asset hedge settings mode should be 'Manual'"); } if (!_exchangeAdapters.TryGetValue(assetHedgeSettings.Exchange, out IExchangeAdapter exchangeAdapter)) { throw new InvalidOperationException("There is no exchange provider"); } HedgeLimitOrder hedgeLimitOrder = HedgeLimitOrder.Create(assetHedgeSettings.Exchange, assetHedgeSettings.AssetId, assetHedgeSettings.AssetPairId, limitOrderType, PriceType.Limit, price, volume); hedgeLimitOrder.Context = new { price, volume, userId }.ToJson(); _log.InfoWithDetails("Manual hedge limit order created", new { hedgeLimitOrder, userId }); await exchangeAdapter.ExecuteLimitOrderAsync(hedgeLimitOrder); }
public LimitOrder(decimal price, decimal volume, LimitOrderType type) { Id = Guid.NewGuid().ToString("D"); Price = price; Volume = volume; Type = type; }
private static LimitOrder Create(decimal price, decimal volume, LimitOrderType type) => new LimitOrder { Id = Guid.NewGuid().ToString("D"), Price = price, Volume = volume, Type = type };
public PlacedOrderReport(Guid id, long orderBookUpdateReportId, LimitOrderType type, decimal price, decimal volume, decimal levelMarkup) { Id = id; OrderBookUpdateReportId = orderBookUpdateReportId; Type = type; Price = price; Volume = volume; LevelMarkup = levelMarkup; }
public async Task ClosePositionAsync(string assetId, string exchange, string userId) { Position position = await _positionService.GetByAssetIdAsync(assetId, exchange); if (position == null) { throw new InvalidOperationException("Position not found"); } AssetHedgeSettings assetHedgeSettings = await _assetHedgeSettingsService.GetByAssetIdAsync(assetId, exchange); if (assetHedgeSettings == null) { throw new InvalidOperationException("Asset hedge settings not found"); } if (assetHedgeSettings.Mode == AssetHedgeMode.Auto) { throw new InvalidOperationException("Can not close position while asset hedge settings mode is 'Auto'"); } if (!_exchangeAdapters.TryGetValue(assetHedgeSettings.Exchange, out IExchangeAdapter exchangeAdapter)) { throw new InvalidOperationException("There is no exchange provider"); } Quote quote = _quoteService.GetByAssetPairId(assetHedgeSettings.Exchange, assetHedgeSettings.AssetPairId); if (quote == null) { throw new InvalidOperationException("No quote"); } LimitOrderType limitOrderType = position.Volume > 0 ? LimitOrderType.Sell : LimitOrderType.Buy; decimal price = limitOrderType == LimitOrderType.Sell ? quote.Ask : quote.Bid; decimal volume = Math.Abs(position.Volume); HedgeLimitOrder hedgeLimitOrder = HedgeLimitOrder.Create(assetHedgeSettings.Exchange, assetHedgeSettings.AssetId, assetHedgeSettings.AssetPairId, limitOrderType, PriceType.Limit, price, volume); hedgeLimitOrder.Context = new { userId }.ToJson(); _log.InfoWithDetails("Manual hedge limit order created to closed position", new { hedgeLimitOrder, userId }); await exchangeAdapter.ExecuteLimitOrderAsync(hedgeLimitOrder); }
public LimitOrderCreateModel(Guid?id, string assetPair, decimal price, decimal volume, ulong accountId, ulong walletId, LimitOrderType type, bool cancelPrevious) { Id = id; AssetPair = assetPair; Price = price; Volume = volume; AccountId = accountId; WalletId = walletId; Type = type; CancelPrevious = cancelPrevious; }
public InternalOrder(string walletId, string assetPairId, LimitOrderType type, decimal price, decimal volume, bool fullExecution) : this() { WalletId = walletId; AssetPairId = assetPairId; Type = type; Price = price; Volume = volume; FullExecution = fullExecution; Status = InternalOrderStatus.New; CreatedDate = DateTime.UtcNow; }
public static OrderAction ToOrderAction(this LimitOrderType limitOrderType) { if (limitOrderType == LimitOrderType.Buy) { return(OrderAction.Buy); } if (limitOrderType == LimitOrderType.Sell) { return(OrderAction.Sell); } throw new InvalidEnumArgumentException(nameof(limitOrderType), (int)limitOrderType, typeof(TradeType)); }
public static HedgeLimitOrder Create(string exchange, string assetId, string assetPairId, LimitOrderType limitOrderType, PriceType priceType, decimal price, decimal volume) { return(new HedgeLimitOrder { Id = Guid.NewGuid().ToString("D"), Exchange = exchange, AssetId = assetId, AssetPairId = assetPairId, Type = limitOrderType, PriceType = priceType, Timestamp = DateTime.UtcNow, Price = price, Volume = volume }); }
private async Task <IReadOnlyCollection <HedgeLimitOrder> > CreateLimitOrdersAsync( IEnumerable <AssetInvestment> assetInvestments) { HedgeSettings hedgeSettings = await _hedgeSettingsService.GetAsync(); var hedgeLimitOrders = new List <HedgeLimitOrder>(); foreach (AssetInvestment assetInvestment in assetInvestments) { AssetHedgeSettings assetHedgeSettings = await _assetHedgeSettingsService.EnsureAsync(assetInvestment.AssetId); LimitOrderType limitOrderType = assetInvestment.RemainingAmount > 0 ? LimitOrderType.Sell : LimitOrderType.Buy; if (!CanCreateHedgeLimitOrder(assetInvestment, assetHedgeSettings, hedgeSettings, limitOrderType)) { continue; } decimal commonThresholdUp = limitOrderType == LimitOrderType.Buy ? hedgeSettings.ThresholdUpBuy : hedgeSettings.ThresholdUpSell; LimitOrderPrice limitOrderPrice = LimitOrderPriceCalculator.Calculate(assetInvestment.Quote, Math.Abs(assetInvestment.RemainingAmount), limitOrderType, assetHedgeSettings.ThresholdUp ?? commonThresholdUp, hedgeSettings.MarketOrderMarkup); decimal price = limitOrderPrice.Price; decimal volume = Math.Abs(assetInvestment.RemainingAmount / assetInvestment.Quote.Mid); HedgeLimitOrder hedgeLimitOrder = HedgeLimitOrder.Create(assetHedgeSettings.Exchange, assetHedgeSettings.AssetId, assetHedgeSettings.AssetPairId, limitOrderType, limitOrderPrice.Type, price, volume); hedgeLimitOrder.Context = assetInvestment.ToJson(); hedgeLimitOrders.Add(hedgeLimitOrder); } return(hedgeLimitOrders); }
public static LimitOrderPrice Calculate(Quote quote, decimal volume, LimitOrderType limitOrderType, decimal thresholdUp, decimal marketOrderMarkup) { if (volume < thresholdUp) { decimal price = limitOrderType == LimitOrderType.Sell ? quote.Ask : quote.Bid; return(new LimitOrderPrice(price, PriceType.Limit)); } else { decimal price = limitOrderType == LimitOrderType.Sell ? quote.Bid * (1 - marketOrderMarkup) : quote.Ask * (1 + marketOrderMarkup); return(new LimitOrderPrice(price, PriceType.Market)); } }
public void Calculate_Buy_Limit_Price() { // arrange var quote = new Quote("BTCUSD", DateTime.UtcNow, 6000, 5000, "source"); decimal volume = 2000; LimitOrderType limitOrderType = LimitOrderType.Buy; decimal thresholdUp = 5000; decimal marketOrderMarkup = .1m; // act LimitOrderPrice limitOrderPrice = LimitOrderPriceCalculator.Calculate(quote, volume, limitOrderType, thresholdUp, marketOrderMarkup); // assert Assert.IsTrue(limitOrderPrice.Price == quote.Bid && limitOrderPrice.Type == PriceType.Limit); }
public Task <ExternalTrade> ExecuteLimitOrderAsync(string assetPairId, decimal volume, decimal price, LimitOrderType limitOrderType) => ExecuteLimitOrderAsync(assetPairId, volume, price, limitOrderType == LimitOrderType.Sell ? Side.Sell : Side.Buy);
private static bool CanCreateHedgeLimitOrder(AssetInvestment assetInvestment, AssetHedgeSettings assetHedgeSettings, HedgeSettings hedgeSettings, LimitOrderType limitOrderType) { if (assetInvestment.IsDisabled) { return(false); } decimal absoluteRemainingAmount = Math.Abs(assetInvestment.RemainingAmount); if (absoluteRemainingAmount <= 0) { return(false); } decimal thresholdCritical = assetHedgeSettings.ThresholdCritical ?? hedgeSettings.ThresholdCritical; if (0 < thresholdCritical && thresholdCritical <= absoluteRemainingAmount) { return(false); } decimal commonThresholdDown = limitOrderType == LimitOrderType.Buy ? hedgeSettings.ThresholdDownBuy : hedgeSettings.ThresholdDownSell; decimal thresholdDown = assetHedgeSettings.ThresholdDown ?? commonThresholdDown; if (assetHedgeSettings.Exchange != ExchangeNames.Virtual && absoluteRemainingAmount < thresholdDown) { return(false); } if (assetHedgeSettings.Mode != AssetHedgeMode.Auto && assetHedgeSettings.Mode != AssetHedgeMode.Idle) { return(false); } if (assetInvestment.Quote == null) { return(false); } return(true); }
public async Task <string> CreateOrderAsync(string walletId, string assetPairId, LimitOrderType type, decimal price, decimal volume, bool fullExecution) { var internalOrder = new InternalOrder(walletId, assetPairId, type, price, volume, fullExecution); await _internalOrderRepository.InsertAsync(internalOrder); return(internalOrder.Id); }