Ejemplo n.º 1
0
        public async Task <IActionResult> TradeMarket(string storeId, string accountId,
                                                      TradeRequestData request, CancellationToken cancellationToken = default)
        {
            // TODO add SATS check everywhere. We cannot change to 'BTC' ourselves because the qty / price would be different too.
            if ("SATS".Equals(request.FromAsset) || "SATS".Equals(request.ToAsset))
            {
                return(this.CreateAPIError(400, "use-asset-synonym",
                                           $"Please use 'BTC' instead of 'SATS'."));
            }

            var custodianAccount = await GetCustodianAccount(storeId, accountId);

            var custodian = GetCustodianByCode(custodianAccount.CustodianCode);

            if (custodian is ICanTrade tradableCustodian)
            {
                decimal Qty;
                if (request.Qty.EndsWith("%", StringComparison.InvariantCultureIgnoreCase))
                {
                    // Qty is a percentage of current holdings
                    var percentage       = Decimal.Parse(request.Qty.Substring(0, request.Qty.Length - 1), CultureInfo.InvariantCulture);
                    var config           = custodianAccount.GetBlob();
                    var balances         = custodian.GetAssetBalancesAsync(config, cancellationToken).Result;
                    var fromAssetBalance = balances[request.FromAsset];
                    var priceQuote       =
                        await tradableCustodian.GetQuoteForAssetAsync(request.FromAsset, request.ToAsset, config, cancellationToken);

                    Qty = fromAssetBalance / priceQuote.Ask * percentage / 100;
                }
                else
                {
                    // Qty is an exact amount
                    Qty = Decimal.Parse(request.Qty, CultureInfo.InvariantCulture);
                }

                var result = await tradableCustodian.TradeMarketAsync(request.FromAsset, request.ToAsset, Qty,
                                                                      custodianAccount.GetBlob(), cancellationToken);

                return(Ok(ToModel(result, accountId, custodianAccount.CustodianCode)));
            }

            return(this.CreateAPIError(400, "market-trade-not-supported",
                                       $"Placing market orders on \"{custodian.Name}\" is not supported."));
        }
        public virtual async Task <MarketTradeResponseData> TradeMarket(string storeId, string accountId, TradeRequestData request, CancellationToken token = default)
        {
            var response = await _httpClient.SendAsync(CreateHttpRequest($"api/v1/stores/{storeId}/custodian-accounts/{accountId}/trades/market", bodyPayload : request, method : HttpMethod.Post), token);

            return(await HandleResponse <MarketTradeResponseData>(response));
        }