Beispiel #1
0
        public async Task <ResponseModel <MarketOrderResponseModel> > PlaceMarketOrderAsync(string clientId, AssetPair assetPair, OrderAction orderAction, decimal volume,
                                                                                            bool straight, double?reservedLimitVolume = null)
        {
            var fees = _calculateOrderFees
                ? await _feeCalculator.GetMarketOrderFees(clientId, assetPair, orderAction)
                : Array.Empty <MarketOrderFeeModel>();

            var order = new MarketOrderModel
            {
                Id                  = GetNextRequestId().ToString(),
                AssetPairId         = assetPair.Id,
                ClientId            = clientId,
                ReservedLimitVolume = reservedLimitVolume,
                Straight            = straight,
                Volume              = (double)Math.Abs(volume),
                OrderAction         = orderAction.ToMeOrderAction(),
                Fees                = fees
            };

            var response = await _matchingEngineClient.HandleMarketOrderAsync(order);

            CheckResponseAndThrowIfNull(response);

            var result = new MarketOrderResponseModel
            {
                Price = response.Price
            };

            return(ConvertToApiModel(response.Status, result));
        }
Beispiel #2
0
        public async Task ModifyPosition(MarketOrderModel oldOrder, MarketOrderModel newOrder, long accountId, bool isLive)
        {
            VerifyConnection();

            if (oldOrder.TradeData.TradeSide != newOrder.TradeSide)
            {
                await ClosePosition(oldOrder.Id, oldOrder.Volume, accountId, isLive);

                newOrder.Id = default;

                await CreateNewOrder(newOrder, accountId, isLive);
            }
            else
            {
                if (newOrder.Volume > oldOrder.Volume)
                {
                    newOrder.Volume = newOrder.Volume - oldOrder.Volume;

                    await CreateNewOrder(newOrder, accountId, isLive);
                }
                else
                {
                    if (newOrder.StopLossInPips != oldOrder.StopLossInPips || newOrder.TakeProfitInPips != oldOrder.TakeProfitInPips)
                    {
                        var amendPositionRequestMessage = new ProtoOAAmendPositionSLTPReq
                        {
                            PositionId          = oldOrder.Id,
                            CtidTraderAccountId = accountId,
                            GuaranteedStopLoss  = oldOrder.GuaranteedStopLoss,
                        };

                        if (newOrder.IsStopLossEnabled)
                        {
                            amendPositionRequestMessage.StopLoss = newOrder.StopLossInPrice;
                            amendPositionRequestMessage.StopLossTriggerMethod = oldOrder.StopTriggerMethod;
                            amendPositionRequestMessage.TrailingStopLoss      = newOrder.IsTrailingStopLossEnabled;
                        }

                        if (newOrder.IsTakeProfitEnabled)
                        {
                            amendPositionRequestMessage.TakeProfit = newOrder.TakeProfitInPrice;
                        }

                        var client = GetClient(isLive);

                        await client.SendMessage(amendPositionRequestMessage, ProtoOAPayloadType.ProtoOaAmendPositionSltpReq);
                    }

                    if (newOrder.Volume < oldOrder.Volume)
                    {
                        await ClosePosition(oldOrder.Id, oldOrder.Volume - newOrder.Volume, accountId, isLive);
                    }
                }
            }
        }
 public static MeMarketOrderModel ToMeModel(this MarketOrderModel model)
 {
     return(MeMarketOrderModel.Create(
                model.Id,
                model.ClientId,
                model.AssetPairId,
                model.OrderAction,
                model.Volume,
                model.Straight,
                model.ReservedLimitVolume,
                model.Fee?.ToMeModel(),
                model.Fees.Select(item => item.ToMeModel()).ToArray()));
 }
Beispiel #4
0
 ///<inheritdoc cref="IMatchingEngineClient"/>
 public Task <MarketOrderResponse> HandleMarketOrderAsync(MarketOrderModel model,
                                                          CancellationToken cancellationToken = default)
 {
     return(SendData(
                model.ToMeModel(),
                _marketOrderTasksManager,
                x => new MarketOrderResponse
     {
         Price = x.Price,
         Status = (MeStatusCodes)x.Status
     },
                _marketOrderResponsePolicy,
                cancellationToken,
                model.Id,
                $"{model.OrderAction} {model.AssetPairId}"
                ));
 }
        public async Task <IActionResult> PlaceMarketOrder(PlaceMarketOrderRequest request)
        {
            var result = await _validationService.ValidateMarketOrderAsync(request.AssetPairId, request.Volume);

            if (result != null)
            {
                throw HftApiException.Create(result.Code, result.Message).AddField(result.FieldName);
            }

            var walletId = User.GetWalletId();

            var order = new MarketOrderModel
            {
                Id          = Guid.NewGuid().ToString(),
                AssetPairId = request.AssetPairId,
                ClientId    = walletId,
                Volume      = (double)request.Volume,
                OrderAction = request.Side,
                Straight    = true
            };

            var response = await _matchingEngineClient.HandleMarketOrderAsync(order);

            if (response == null)
            {
                throw HftApiException.Create(HftApiErrorCode.MeRuntime, "ME not available");
            }

            (HftApiErrorCode code, string message) = response.Status.ToHftApiError();

            if (code == HftApiErrorCode.Success)
            {
                return(Ok(ResponseModel <MarketOrderResponse> .Ok(new MarketOrderResponse {
                    OrderId = order.Id, Price = (decimal)response.Price
                })));
            }

            throw HftApiException.Create(code, message);
        }
Beispiel #6
0
        public override async Task <MarketOrderResponse> PlaceMarketOrder(MarketOrderRequest request, ServerCallContext context)
        {
            var walletId = context.GetHttpContext().User.GetWalletId();

            var result = await _validationService.ValidateMarketOrderAsync(request.AssetPairId, Convert.ToDecimal(request.Volume));

            if (result != null)
            {
                return(new MarketOrderResponse
                {
                    Error = new Error
                    {
                        Code = (int)result.Code,
                        Message = result.Message
                    }
                });
            }

            var order = new MarketOrderModel
            {
                Id          = Guid.NewGuid().ToString(),
                AssetPairId = request.AssetPairId,
                ClientId    = walletId,
                Volume      = Math.Abs(Convert.ToDouble(request.Volume)),
                OrderAction = request.Side == Side.Buy ? OrderAction.Buy : OrderAction.Sell,
                Straight    = true
            };

            var response = await _matchingEngineClient.HandleMarketOrderAsync(order);

            if (response == null)
            {
                return(new MarketOrderResponse
                {
                    Error = new Error
                    {
                        Code = (int)HftApiErrorCode.MeRuntime,
                        Message = "ME not available"
                    }
                });
            }

            (HftApiErrorCode code, string message) = response.Status.ToHftApiError();

            if (code == HftApiErrorCode.Success)
            {
                return new MarketOrderResponse
                       {
                           Payload = new MarketOrderResponse.Types.MarketOrderPayload
                           {
                               OrderId = order.Id,
                               Price   = response.Price.ToString(CultureInfo.InvariantCulture)
                           }
                       }
            }
            ;

            return(new MarketOrderResponse
            {
                Error = new Error
                {
                    Code = (int)code,
                    Message = message
                }
            });
        }
        public async Task <IActionResult> PlaceMarketOrder([FromBody] MarketOrderRequest request)
        {
            var clientId = _requestContext.ClientId;

            var pair = await _assetsServiceWithCache.TryGetAssetPairAsync(request.AssetPairId);

            if (pair == null)
            {
                return(NotFound());
            }

            if (pair.IsDisabled)
            {
                return(BadRequest());
            }

            var baseAsset = await _assetsServiceWithCache.TryGetAssetAsync(pair.BaseAssetId);

            if (baseAsset == null)
            {
                return(NotFound());
            }

            var quotingAsset = await _assetsServiceWithCache.TryGetAssetAsync(pair.QuotingAssetId);

            if (quotingAsset == null)
            {
                return(BadRequest());
            }

            if (request.AssetId != baseAsset.Id && request.AssetId != baseAsset.Name &&
                request.AssetId != quotingAsset.Id && request.AssetId != quotingAsset.Name)
            {
                return(BadRequest());
            }

            var straight = request.AssetId == baseAsset.Id || request.AssetId == baseAsset.Name;
            var volume   =
                request.Volume.TruncateDecimalPlaces(straight ? baseAsset.Accuracy : quotingAsset.Accuracy);

            if (Math.Abs(volume) < double.Epsilon)
            {
                return(BadRequest(CreateErrorMessage("Required volume is less than asset accuracy")));
            }

            var order = new MarketOrderModel
            {
                Id                  = Guid.NewGuid().ToString(),
                AssetPairId         = pair.Id,
                ClientId            = clientId,
                ReservedLimitVolume = null,
                Straight            = straight,
                Volume              = Math.Abs(volume),
                OrderAction         = ToMeOrderAction(request.OrderAction)
            };

            if (_baseSettings.EnableFees)
            {
                order.Fees = new[]
                { await GetMarketOrderFee(clientId, request.AssetPairId, request.AssetId, request.OrderAction) }
            }
            ;

            var response = await _matchingEngineClient.HandleMarketOrderAsync(order);

            if (response == null)
            {
                throw new Exception("ME unavailable");
            }

            if (response.Status != MeStatusCodes.Ok)
            {
                return(BadRequest(CreateErrorMessage($"ME responded: {response.Status}")));
            }

            return(Ok(order.Id));
        }