public Task <ExchangeTrade> MarketTrade(MarketTradeRequest request)
        {
            if (!Prices.TryGetValue(request.Market, out var price))
            {
                throw new Exception($"Cannot found MOCK price for {request.Market}");
            }


            var oppVol = double.Parse(((decimal)price * (decimal)request.Volume * -1m).ToString(CultureInfo.InvariantCulture));

            var trade = new ExchangeTrade()
            {
                Id             = Guid.NewGuid().ToString("N"),
                Price          = price,
                Side           = request.Side,
                Volume         = request.Volume,
                Market         = request.Market,
                OppositeVolume = oppVol,
                Timestamp      = DateTime.UtcNow,
                ReferenceId    = request.ReferenceId,
                Source         = Name,
            };

            Trades[Name].Add(trade);

            return(Task.FromResult(trade));
        }
Beispiel #2
0
        public async Task <ExchangeTrade> MarketTrade(MarketTradeRequest request)
        {
            try
            {
                using var action = MyTelemetry.StartActivity("FTX Market Trade");
                request.AddToActivityAsJsonTag("request");

                var refId = request.ReferenceId ?? Guid.NewGuid().ToString("N");

                refId.AddToActivityAsTag("reference-id");

                var size = (decimal)Math.Abs(request.Volume);

                var resp = await _restApi.PlaceOrderAsync(request.Market,
                                                          request.Side == OrderSide.Buy?SideType.buy : SideType.sell, 0, OrderType.market,
                                                          size, refId, true);

                resp.AddToActivityAsJsonTag("marketOrder-response");

                if (!resp.Success && resp.Error != "Duplicate client order ID")
                {
                    throw new Exception(
                              $"Cannot place marketOrder. Error: {resp.Error}. Request: {JsonConvert.SerializeObject(request)}. Reference: {refId}");
                }

                action?.AddTag("is-duplicate", resp.Error == "Duplicate client order ID");

                var tradeData = await _restApi.GetOrderStatusByClientIdAsync(refId);

                if (!tradeData.Success)
                {
                    throw new Exception(
                              $"Cannot get order state. Error: {resp.Error}. Request: {JsonConvert.SerializeObject(request)}. Reference: {refId}");
                }

                if (tradeData.Result.Status != "closed")
                {
                    await _restApi.CancelOrderByClientIdAsync(refId);
                }

                tradeData = await _restApi.GetOrderStatusByClientIdAsync(refId);

                tradeData.AddToActivityAsJsonTag("order-status-response");

                if (!tradeData.Success)
                {
                    throw new Exception(
                              $"Cannot get second order state. Error: {resp.Error}. Request: {JsonConvert.SerializeObject(request)}. Reference: {refId}");
                }

                size = tradeData.Result.FilledSize ?? 0;
                if (tradeData.Result.Side == "sell")
                {
                    size = size * -1;
                }

                var trade = new ExchangeTrade()
                {
                    Id          = (tradeData.Result.Id ?? 0).ToString(CultureInfo.InvariantCulture),
                    Market      = tradeData.Result.Market,
                    Side        = tradeData.Result.Side == "buy" ? OrderSide.Buy : OrderSide.Sell,
                    Price       = (double)(tradeData.Result.AvgFillPrice ?? 0),
                    ReferenceId = tradeData.Result.ClientId,
                    Source      = FtxConst.Name,
                    Volume      = (double)size,
                    Timestamp   = tradeData.Result.CreatedAt
                };

                trade.AddToActivityAsJsonTag("response");

                if (resp.Error == "Duplicate client order ID")
                {
                    _logger.LogInformation("Ftx trade is Duplicate. Request: {requestJson}. Trade: {tradeJson}",
                                           JsonConvert.SerializeObject(request), JsonConvert.SerializeObject(trade));
                }
                else
                {
                    _logger.LogInformation("Ftx trade is done. Request: {requestJson}. Trade: {tradeJson}",
                                           JsonConvert.SerializeObject(request), JsonConvert.SerializeObject(trade));
                }

                return(trade);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Cannot execute trade. Request: {requestJson}",
                                 JsonConvert.SerializeObject(request));
                throw;
            }
        }