Есть несколько проблем, связанных с подходом к размещению заказа с использованием 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