jaggedsoft / node-binance-api

Node Binance API is an asynchronous node.js library for the Binance API designed to be easy to use.
MIT License
1.58k stars 767 forks source link

Simple quantity question #136

Closed harryhorton closed 6 years ago

harryhorton commented 6 years ago

Is quantity always in the base asset (for ETHBTC, ETH)?

If so, how do you perform a market order if you can't calculate the base asset amount based on the price?

bkrypt commented 6 years ago

You'll find your answer in the order book, which can be acquired through binance.depth() / binance.websockets.depthCache(). If the order book has a maker ask at 0.09378BTC with a quantity of 3.100ETH. A market order of binance.marketBuy('ETHBTC', 3) will cost me 0.09378 * 3 = 0.28134BTC. If I exceeded the quantity, in my order, beyond the 3.100 offered by asker1, with let's say binance.marketBuy('ETHBTC', 4), I will buy all of asker1s stock of 3.1@0.9378 = 0.290718BTC and get the remaining 0.9ETH from asker2 at whatever their (higher) price is, if asker2 doesn't have 0.9ETH it will buy out that level and continue to fall through the book with that pattern until the quantity is 0.

https://github.com/jaggedsoft/node-binance-api#get-market-depth-for-a-symbol

// This will get you a snapshot of the order book at the time of the call
binance.depth('ETHBTC', (error, depth, symbol) => {
  console.log(symbol+" market depth", depth);
});

https://github.com/jaggedsoft/node-binance-api#maintain-market-depth-cache-locally-via-websocket

// This will get you a realtime feed of the order book
binance.websockets.depthCache('ETHBTC', (symbol, depth) => {
  let bids = binance.sortBids(depth.bids);
  let asks = binance.sortAsks(depth.asks);
  console.log(symbol+" depth cache update");
  console.log("bids", bids);
  console.log("asks", asks);
  console.log("best bid: "+binance.first(bids));
  console.log("best ask: "+binance.first(asks));
});
barhun commented 6 years ago

hi, @keith1024

the order book can and, in most cases, does change before the order we’ve issued is processed by the matching engine; so the method you proposed only works if there have been no other orders processed after we read the order book. i’d like to be able to issue orders with quantities set in the quote asset, but this seems impossible from both your exchange board and your api endpoints. as this is not the way we can issue orders, could you help us understand how the api’s order endpoint decides whether it should accept a market order or reject with an error that says ‘insufficient balance’?

jaggedsoft commented 6 years ago

can you please elaborate

barhun commented 6 years ago

someone has already elaborated the same situation for bitfinex’s api here: https://www.reddit.com/r/bitfinex/comments/7qhisi/api_question_about_placing_orders/

let me try and do my best explaining however: after reading the order book, i say ‘now, i know that i can buy 1000 iota with 560 usdt.” and send a request for the order accordingly to binance’s api. but i can never be sure that no orders by other traders have been sent to the api and then processed by the matching engine. the order book could and in most cases would change before my request is read by the api. is there a way to tell the api that i want to buy as much as my current balance of the quote asset? or how can i know if my order will be accepted by the api?

barhun commented 6 years ago

similar question here: https://www.reddit.com/r/BinanceExchange/comments/91hf0s/api_buy_market_order_quantity/

jaggedsoft commented 6 years ago

i see what you're saying

yeah you can buy your whole balance of the current asset, but it's much easier to do with market orders

barhun commented 6 years ago

well, i am trying to submit a market buy order but i don't know what the quantity field must be set to in order to use all of my balance?

jaggedsoft commented 6 years ago

@barhun https://github.com/jaggedsoft/node-binance-api/issues/297

in this thread I show an example how to grab exchangeInfo for all market symbols You need this information in order to call roundStep which rounds it to the precision binance requires for that symbol

Then there is an example for updating your balances every 5 seconds or however often you want to do it If you want to sell your whole balance for BNBBTC as an example, just market sell with the quantity global.balance.BNBBTC.available

barhun commented 6 years ago

thanks, that's really helpful! 👍

what if i want to buy BNB with all of my BTC balance? how can i calculate the quantity in this case? i assume a simple calculation like account.balances.BTC * prices.BNBBTC doesn't work here 'cause the order book will be pushed towards higher ask prices as orders are filled by me or anyone else who submitted an order request before mine, or does it?

jaggedsoft commented 6 years ago

Don't worry about it being pushed up by yourself, if you're doing a market order it's all executed at once and usually the only time you will have a problem is if your own balance changes.

let minNotional = global.minimums.BNBBTC.minNotional; // Default: The absolute minimum you can buy/sell of this asset
minNotional = global.balance.BTC.available; // Override the minimum BTC purchase amount to 100% of our balance in BTC.
// Note: when buying I set price to the 'ask' price and when selling I set it to the 'bid' price
if ( price * qty < minNotional ) {
    qty = minNotional / price;
}
barhun commented 6 years ago

thank you! (:

barhun commented 6 years ago

hi, again

it seems i have one more question, hopefully the last one here. (: let's consider a situation in which i have 2500 USDT and i want to buy BNB with a market order in BNBUSDT using only 1000 USDT. how can i achieve this? should i lock 1500 USDT submitting a limit order with a price too low for the current market and only then submit the actual market order? after market order has been successfully executed, i can delete my previous limit order so that 1500 USDT gets unlocked. do i make myself clear? or do i seem too stupid? (:

barhun commented 6 years ago

i thought locking 1500 USDT is a requirement 'cause my calculation of quantity * price for the market order might equal to more than i expected.

jaggedsoft commented 6 years ago
// Buy 1000 USDT worth of BNB
quantity = 1000 / global.ticker['BNBUSDT'].askPrice;
quantity = binance.roundStep(quantity, global.minimums['BNBUSDT'].stepSize);
binance.marketBuy('BNBUSDT', quantity, (error, response) => {
  if ( error ) return console.error(error.body);
  console.log("Market Buy response", response);
  console.log("order id: " + response.orderId);
  // Now you can limit sell with a stop loss, etc.
});
jaggedsoft commented 6 years ago

Here's an example of how to keep a ticker object that's updated for all symbols every second, and includes the best bid/ask price.

const Binance = require( 'node-binance-api' );
const binance = new Binance();
global.ticker = {};

// Show contents of BNBUSDT ticker object once per second
setInterval( () => {
    if ( !global.ticker.BNBUSDT ) return;
    console.log( global.ticker.BNBUSDT );
    console.log( `BNB ask: ${global.ticker.BNBUSDT.bestAsk} bid: ${global.ticker.BNBUSDT.bestBid}` );
}, 1000 );

// Get 24h price change statistics for all symbols
binance.websockets.prevDay( false, function ( error, obj ) {
    global.ticker[obj.symbol] = obj;
} );
Algo-Tradings commented 5 years ago

Hello fellows. Let me see:

//for 100% mount { let quantity = global.balance.ETHBTC.available; binance.marketBuy(ETHBTC,quantity); }

// and for 90%? { let quantity = global.balance.ETHBTC.available * 0.9; binance.marketBuy(ETHBTC,quantity); }

Am I in the right way? On both sides long/short the quantity expression are able? Thank you.

Algo-Tradings commented 5 years ago

Another doubt. Is necessary a callback for different pairs orders made in sequence? One after another.

Thank you