Как разместить заказ на Binance через R

Я пытаюсь разместить новый заказ через R studio, пакет Binancer, я правильно подключился к Binance Api (я добавил ключ и секрет в Binancer :: credentials), но когда я набираю это:

binancer::binance_new_order(symbol="WAVESBTC",side="BUY",type="MARKET",quantity = 1)

Я получаю эту ошибку: Ошибка в binancer :: binance_new_order (symbol = WAVESBTC, side = BUY,: abs (quot - round (quot)) ‹1e-10 НЕ ИСТИНА

Я пытался изменить количество и указать количество волн, которые я хочу купить, или количество BTC, которое я хочу потратить, но я всегда получаю эту ошибку. Я хотел бы потратить 100% своих биткойнов на Waves в этом порядке, где я ошибаюсь? Есть ли другой способ разместить заказ на Binance через R?


person Gloria Dalla Costa    schedule 10.01.2021    source источник
comment
Вы уже нашли для этого решение?   -  person roelofco    schedule 21.02.2021


Ответы (2)


Есть несколько проблем, связанных с подходом к размещению заказа с использованием binanceR. В отличие от самого Binance, вы не можете указать, какой процент вашего кошелька вы хотите потратить на криптовалюту, вам нужно рассчитать точную сумму криптовалюты. Это очень просто и делается так:

#Fetching the current price of crypto of interest
curr_price <- binance_ticker_price("WAVEBTC")
curr_price <- curr_price$price
#Fetch your wallet balances
avail_btc <- binance_balances()
avail_btc <- filter(avail_btc, asset == "BTC")
avail_btc <- as.numeric(avail_usdt$free)
#Calculate possible coin quantity
buy_quantity<- avail_btc/curr_price

В этом случае мы использовали всю доступную криптовалюту нашего кошелька (100%+/-) для расчета количества криптовалюты, которое мы хотим купить, то есть количества. Вы можете выбрать меньшую часть своего кошелька, разделив то, что вам нужно (например, 50% кошелька avail_btc/2).

#Reduce quantity of coins by 0.5% to avoid insufficient balance error NBNB!!
calc_price <- function(price, growth) {
  new_price <- (price*growth)+price
  return(new_price)
}
buy_quantity <- calc_price(buy_quantity, -0.005)

Есть способы упростить процесс, но, на мой взгляд, для устранения неполадок лучше использовать пошаговые инструкции.

Теперь, когда мы установили правильное количество, мы можем разместить заказ:

binance_new_order("WAVEBTC", 
    side = "BUY", 
    type = "LIMIT", 
    quantity = buy_quantity, 
    price = b_price, 
    time_in_force = "GTC", 
    test = FALSE) 

Но получаем очень досадную ошибку: Error in binance_new_order("WAVEBTC", side = "BUY", type = "LIMIT", quantity = buy_quant, : abs(quot - round(quot)) < 1e-10 is not TRUE

Это происходит потому, что все монеты имеют ограничения на размер количества ИЛИ цены, которую вы хотите передать Binance. Я не уверен, но Binance решает это за вас, поэтому вы никогда не сталкиваетесь с этим там. Например: WAVEBTC будет принимать количество 3.2234, но не 3.223456, вы видите дополнительные два десятичных знака ... Вы можете вручную попытаться угадать правильный формат количества или цены, но для автоматизации это боль.

Решение простое, но не очевидное. Мне пришлось перейти к исходному коду для binanceR и найти разделы, в которых возникают ошибки. Вот они для количества и цены соответственно:

#Price
quot <- (price - filters[filterType == 'PRICE_FILTER', minPrice]) / filters[filterType == 'PRICE_FILTER', tickSize]
            stopifnot(abs(quot - round(quot)) < 1e-10)

#Quantity
quot <- (buy_quantity - filters[filterType == 'LOT_SIZE', minQty]) / filters[filterType == 'LOT_SIZE', stepSize]
    stopifnot(abs(quot - round(quot)) < 1e-10)

Эти фрагменты кода в основном проверяют, есть ли какие-либо нежелательные десятичные дроби в вашем количестве или цене. Если мы запустим это на примере с ONTUSDT, вы увидите, что если мы используем buy_quantity из 332.44543 и вычислим quot, мы получим значение 33243.54. Если мы запустим stopifnot(abs(quot - round(quot)) < 1e-10), мы получим ошибку. Но почему? Какое значение abs(quot - round(quot): 0.457 не соответствует критериям кода ошибки и поэтому мы получаем ошибку. Если мы изменим buy_quantity на 332.44, мы не получим сообщение об ошибке, потому что наше значение abs(quot - round(quot) равно 0. Это ключ к решению!

Что нам нужно сделать, так это определить правильное количество десятичных знаков для рассматриваемых монет. Для этого мы собираемся использовать простую функцию для вычисления десятичных позиций для чисел и / или символов (вы увидите, почему):

decimalplaces <- function(x) {
  if (class(x)=="character") {
    x<-gsub("(.*)(\\.)|([0]*$)","",x)
    nchar(x)
  } else if (abs(x - round(x)) > .Machine$double.eps^0.5) {
    nchar(strsplit(sub('0+$', '', as.character(x)), ".", fixed = TRUE)[[1]][[2]])
  } else {
    return(0)
  }
}

Затем нам нужно получить фильтры, используемые этими фрагментами кода, чтобы определить, верны ли наши количества или цены:

filters <- binance_filters("WAVEBTC")

Теперь нам нужно переформатировать уравнение для quot, чтобы мы вычислили неизвестную величину, которая будет выглядеть следующим образом (помните, что нам нужно quot со значением 0):

quantity <- (quot*filters[filterType == 'LOT_SIZE', stepSize])+filters[filterType == 'LOT_SIZE', minQty])
#Remember to change quot to 0
quantity <- (0*filters[filterType == 'LOT_SIZE', stepSize])+filters[filterType == 'LOT_SIZE', minQty])
#Since anything * by 0 = 0, our final equation is: 
quantity <- filters[filterType == 'LOT_SIZE', minQty]

Снова используя ONTUSDT в качестве примера, значение quantity будет 0.01. Это количество десятичных знаков, которое должно быть в вашем buy_quantity. Так просто:

#Sometimes the value will be in scientific notation, so we convert it which creates a character string and this is why the decimalplaces function accommodates numbers and character strings.  
t <- format(quantity, scientific = FALSE)
dec <- decimalplaces(t)
buy_quantity<- round(buy_quantity, digits = dec)

NB! Следуйте тому же процессу для своей цены!

Если мы используем buy_quantity в коде ошибки, вы увидите, что мы не получаем сообщение об ошибке и размещение заказа работает!

binance_new_order("WAVEBTC", 
                  side = "BUY", 
                  type = "LIMIT", 
                  quantity = buy_quantity, 
                  price = b_price, 
                  time_in_force = "GTC", 
                  test = TRUE)

Удачи и безопасной торговли!

person roelofco    schedule 21.02.2021

В этом случае я думаю, что проблема заключается в фильтрах type="MARKET", в большинстве случаев quot окончательные значения Inf, поэтому он не проходит binance_new_order условие для этого типа.

person Nacho    schedule 07.06.2021