public Exchange( string name, IExchangeAdapterClientFactory factory, IMarketInstrumentService marketInstrumentService) { Name = name; _client = factory.GetSpotController(name); _marketInstrumentService = marketInstrumentService; }
public async Task CancelLimitOrderAsync(string assetId) { ExternalOrder externalOrder = await _externalOrderRepository.GetAsync(Name, assetId); if (externalOrder == null) { return; } ISpotController spotController = _exchangeAdapterClientFactory.GetSpotController(Name); try { await spotController.CancelLimitOrderAsync(new CancelLimitOrderRequest { OrderId = externalOrder.Id }); HedgeLimitOrder hedgeLimitOrder = await _hedgeLimitOrderService.GetByIdAsync(externalOrder.HedgeLimitOrderId); OrderModel order = await spotController.LimitOrderStatusAsync(externalOrder.Id); if (order == null) { _log.WarningWithDetails("External order not found", externalOrder); return; } if (order.ExecutionStatus == OrderStatus.Fill || order.ExecutionStatus == OrderStatus.Canceled) { if (order.ExecutedVolume > 0) { await _positionService.UpdateAsync(hedgeLimitOrder.AssetId, hedgeLimitOrder.Exchange, hedgeLimitOrder.Type == LimitOrderType.Sell ?Domain.TradeType.Sell : Domain.TradeType.Buy, order.ExecutedVolume, order.ExecutedVolume *order.AvgExecutionPrice); await _externalTradeService.RegisterAsync(new ExternalTrade { Id = Guid.NewGuid().ToString("D"), Exchange = hedgeLimitOrder.Exchange, LimitOrderId = hedgeLimitOrder.Id, ExchangeOrderId = externalOrder.Id, AssetPairId = hedgeLimitOrder.AssetPairId, Type = hedgeLimitOrder.Type == LimitOrderType.Sell ? Domain.TradeType.Sell : Domain.TradeType.Buy, Timestamp = order.Timestamp, Price = order.AvgExecutionPrice, Volume = order.ExecutedVolume, Status = order.RemainingAmount > 0 ? TradeStatus.PartialFill : TradeStatus.Fill, OriginalVolume = order.OriginalVolume, RemainingVolume = order.RemainingAmount }); } await _externalOrderRepository.DeleteAsync(externalOrder.Exchange, externalOrder.Asset); _hedgeLimitOrderService.Close(hedgeLimitOrder); } else { _log.WarningWithDetails("Can not cancel external order in progress", externalOrder); } } catch (Exception exception) { _log.WarningWithDetails("An error occurred while canceling limit order", exception, externalOrder); } }
public async Task ExecuteLimitOrderAsync(HedgeLimitOrder hedgeLimitOrder) { await _hedgeLimitOrderService.AddAsync(hedgeLimitOrder); ExternalOrder externalOrder = await _externalOrderRepository.GetAsync(hedgeLimitOrder.Exchange, hedgeLimitOrder.AssetId); if (externalOrder != null) { hedgeLimitOrder.Error = LimitOrderError.Unknown; hedgeLimitOrder.ErrorMessage = "Already exists"; return; } AssetPairSettings assetPairSettings = await _instrumentService.GetAssetPairAsync(hedgeLimitOrder.AssetPairId, hedgeLimitOrder.Exchange); if (assetPairSettings == null) { hedgeLimitOrder.Error = LimitOrderError.Unknown; hedgeLimitOrder.ErrorMessage = "Instrument not configured"; _log.WarningWithDetails("No settings for instrument", hedgeLimitOrder); return; } decimal price = hedgeLimitOrder.Price .TruncateDecimalPlaces(assetPairSettings.PriceAccuracy, hedgeLimitOrder.Type == LimitOrderType.Sell); decimal volume = Math.Round(hedgeLimitOrder.Volume, assetPairSettings.VolumeAccuracy); if (volume < assetPairSettings.MinVolume) { hedgeLimitOrder.Error = LimitOrderError.TooSmallVolume; return; } ISpotController spotController = _exchangeAdapterClientFactory.GetSpotController(Name); try { var assetPair = assetPairSettings.AssetPairId; // TODO: Remove this workaround if (Name == "NettingEngineDefault") { assetPair = GetAssetPair(assetPair); } OrderIdResponse response = await spotController.CreateLimitOrderAsync(new LimitOrderRequest { Instrument = assetPair, TradeType = hedgeLimitOrder.Type == LimitOrderType.Sell ? TradeType.Sell : TradeType.Buy, Price = price, Volume = volume }); externalOrder = new ExternalOrder(response.OrderId, hedgeLimitOrder.Exchange, hedgeLimitOrder.AssetId, hedgeLimitOrder.Id); await _externalOrderRepository.InsertAsync(externalOrder); _log.InfoWithDetails("External order created", externalOrder); } catch (Exception exception) { hedgeLimitOrder.Error = LimitOrderError.Unknown; hedgeLimitOrder.ErrorMessage = exception.Message; _log.WarningWithDetails("An error occurred while creating external order", exception, hedgeLimitOrder); } }