ccxt: Can't execute createMarketBuyOrder due to "insufficient balance" error
- OS: Windows 7
- Programming Language version: Javascript
- CCXT version: 1.13.19
- Exchange: Binance
- Method: createMarketBuyOrder
I executed the code below:
console.log(tradingPairs[BEST_TRADING_PAIR_INDEX][SYMBOL_INDEX], balance.USDT.free)
//above code print out "ETH/USDT 18.87629041"
exchange.createMarketBuyOrder (tradingPairs[BEST_TRADING_PAIR_INDEX][SYMBOL_INDEX], balance.USDT.free)
However, I got this error:
(node:12940) UnhandledPromiseRejectionWarning: Error: binance {"code":-2010,"msg":"Account has insufficient balance for requested action."}
at binance.handleErrors (C:\Users\workshop\node_modules\ccxt\js\binance.js:862:31)
at response.text.then (C:\Users\workshop\node_modules\ccxt\js\base\Exchange.js:513:18)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
(node:12940) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12940) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Any idea why? Is it related to the fee? I ran similar code with market sell order and there is no issue. Thanks in advance.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 1
- Comments: 18 (9 by maintainers)
It’s a bit more involved.
In general, your order is bound by:
market.limitsproperty)market.precisionsproperty)So first, you estimate your target amount with
balance / price.Then you truncate amount to the required precision with https://github.com/ccxt/ccxt/blob/334ebc682e9c5139ae5042434e437cadcefebebd/js/base/Exchange.js#L1012
If you take your price from orderbook then it’s ready to use. But if it’s the result of some calculation then you need to round it up or down (depending on your logic) to the precision… That’s a bit tricky as ccxt rounds it to the nearest neighbor with
priceToPrecision. Maybe guys will make it directional but at the moment you’ll need to enforce the direction by yourself.Then you calculate the cost (i.e.
truncated amount * rounded price).Then you check if all three (amount/price/cost) passes the limits.
Then you place your order!
It may sound scary but these are few lines of code in reality.
I wouldn’t say it’s tricky… Think of it from another perspective:
when you place a market order it’s said that you’re guaranteed time (immediate), amount (unless your order is so huge that eats up all the orderbook) but not price (in case someone jumps in front of you)
when you place a limit order it’s said that you’re guaranteed price but not time (you can wait forever until it’s executed)
Traders treat this base currency as inventory. They try to make money by managing this inventory. And they never want to have an unspecified amount of inventory. It’s just hard to manage.
Not only bid price may increase, bid amount may change too. It happens all the time and is called “slippage”.
I’d say yes because in general, it’s practical to be conscious about the price and amount.
I mean, I actually read your question as “I want to buy at any price for all available money” and this sounds a bit weird as to me.
Let’s say you want to make sausage and eggs breakfast and you need to buy some tomatoes for it… So you go to a farmer market, pick tomatoes you like, check the price and say smth like: “Hey, sell me these three tomatoes”. You never come to a random seller and say “Hey, I don’t care reading the price tag but here is my wallet, give me as many tomatoes as possible with that money in it”.
Likewise, when you buy inventory you probably want to buy it cheaper and to sell it with profit. And in order to “buy cheaper”, you need to be confident about the price. Put it in another way, if you don’t check the price how can you be sure you buy cheaper?
The problem with providing the amount of base currency in marketBuyOrder is that I might occasionally get an
InsufficientFundserror, because the orderbook bid price might increase before the order get submitted (due to network delay)… Any workaround for this issue? Should I just use limitBuyOrder, so I won’t get the error?Currently, I subtract the computed amount (USDT / bid price) with market.limits.amount.min, though it only works if there is only a very slight change on the bid price…
So all amounts are in base currency, all prices are in quote currency:
https://github.com/ccxt/ccxt/wiki/Manual#consistency-of-base-and-quote-currencies
This is a normal mode of operation of practically any FX system or crypto exchange. Some exchanges will allow to specify the money to spend in the quote currency, but most of them won’t. You need to consult their exchange-specific docs for that.
Hope this answers your questions. Let us know if not.
While your explanation is correct I didn’t mean that, actually. I didn’t touch how to come up with price and amount. I was talking about how to make sure your order hits orderbook once you have price and amount calculated. The issue is that if the order is under limits then it will trigger
InvalidOrderexception. If it exceeds your available balance it will triggerInsufficientFunds.Sure. It happens all the time.
No. The part that hits other orders will get executed immediately. The rest of your order will remain resting in the orderbook. So, technically, your order won’t fail, it will be just partly executed.
You may want to read more details here: https://github.com/ccxt/ccxt/wiki/Manual#how-orders-are-related-to-trades
Oh… I see, this is my first experience of using a library for trading… BTW, any suggestion on the best way to compute the amount of ETH when I want to buy using market buy method?
Currently, I did this:
I want to buy ETH with 18.87629041 USDT…
I found the problem, I thought the amount is in USDT which is incorrect… The weird part is that when I want to sell, say ETH to USDT, I just need to put the amount of ETH. However, if i want to buy ETH from USDT, I still need to put the amount of ETH. Shouldn’t I just need to put the USDT amount when I want to buy ETH? Because if I have to put the ETH amount, then I need to calculate the ETH amount that I can get with certain USDT amount, which so inconvenient. Is it possible to update the market buy method?