node-binance-api
node-binance-api copied to clipboard
Futures trading placing a take profit and a stop loss
Hello everyone, I've been using node-binance-api
API for a long time.
On the spot market, i've been placing a base order and susequently placing an OCO order for my take profit & stop loss.
Base order
await binance.buy('ETHUSDT', 0.005, 3800,{
timeInForce: 'GTC'
});
Take profit & Stop Loss
await binance.sell('SELL', 'ETHUSDT', 0.005, 3900, {
type:'OCO',
stopLimitPrice: 3700,
stopPrice: 3700,
timeInForce: 'GTC'
});
However moving into the futures market, I can't seem to replicate this functionallity.
Base order:
await binance.futuresBuy('ETHUSDT',0.005,3800,{
timeInForce: 'GTC'
});
Stop loss order:
await binance.futuresSell('ETHUSDT',0.005,3700,{
timeInForce: 'GTC'
stopPrice: 3700
type: 'STOP'
});
Take profit order:
await binance.futuresSell('ETHUSDT',0.005,3900,{
timeInForce: 'GTC'
stopPrice: 3900
type: 'TAKE_PROFIT'
});
And I end up with this on Binance:
As you can see, the are stop loss & take profit orders are there, but they are in no way linked to one another (As shown in the position). And if one is executed, the other will persist (In this case acting as a short). I know I can close the other once one is executed, but I wanted to know i there is a right way to do this.
I don't see the option to open an OCO order in futures, am I missing something?
Is there a way to open a position with a stop loss and take profit?
I had the same doubt and opened an issue about it not too long ago. As far as I know there is not support for OCO order type in the binance futures API. I guess the work around is to use the socket streams to catch the changes.
Its kind of odd, because on Binance's GUI there is an option to set TP/SL for a position.
Anyway I have it working with this workaround for now. The position is closed whenever the TP/SL is reached, however, if TP was reached, the SL will stay open and if the price reaches it, a new position is opened, so I fear a bug on my could leave an open order unchecked, wich is preatty scray.
With OCO orders on the spot market, I can rest assure that no matter what happens on my side, the trade will play out as expected, with TP/SL executed.
If anyone knows a better way, any help is appreciated.
Its kind of odd, because on Binance's GUI there is an option to set TP/SL for a position.
Anyway I have it working with this workaround for now. The position is closed whenever the TP/SL is reached, however, if TP was reached, the SL will stay open and if the price reaches it, a new position is opened, so I fear a bug on my could leave an open order unchecked, wich is preatty scray.
With OCO orders on the spot market, I can rest assure that no matter what happens on my side, the trade will play out as expected, with TP/SL executed.
If anyone knows a better way, any help is appreciated.
Did you work with the spot API? I think the futures support is better. I am kinda struggling with execution of simple market orders in the spot API. Can you help me with that? I am trying just to market buy and sell (no limits / tp / sl...) for now. Can you send me a snippet of code of the implementation? I can't parse the error / response objects... I am available on Telegram if it more convenient for you.
Yes, I have the spot API working in production for a couple of months, I'm actually getting started in the futures market right now. I'll send you a full snippet of the Spot setup in a couple of minutes.
First we initialize de Binance client. I sugest you use async
await
, it will make your life much easier.
const Binance = require('node-binance-api');
const binance = new Binance().options({
APIKEY: 'YOUR API KEY',
APISECRET: 'YOUR API SECRET',
useServerTime: true,
recvWindow: 60000,
verbose: true
});
Then, we need some information about the pairs we'll be trading, like pricePrecision
, quantityPrecision
and minNotional
. This is because when we place an order to buy BTC with USDT, the quantity parameter for example can have up to 5 decimal places, the price parameter up to 2 decimal places, and the minimum order can be of 10 USDT. Each pair has its own parameters, so we call exchangeInfo
to extract that information. (If you don't follow this parameters, you'll end up with a lot of unwanted errors).
await binance.exchangeInfo();
//You'll actually need to dig through this to get the information needed
Then to place a order we just call binance.marketBuy
or binance.marketSell
to place a market order.
//BUY
await binance.marketBuy('BTCUSDT',0.00025);
//SELL
await binance.marketSell('BTCUSDT',0.00025);
You can set the request to a variable to see the output of the order (Don't forget the await
)
var order = await binance.marketBuy('BTCUSDT',0.00025);
console.log(order);
We can also call binance.buy
or binance.sell
to place a limit order. In this case our order will be executed when the price reaches 40.000.
//BUY
await binance.buy('BTCUSDT',0.00025,40000.00);
//SELL
await binance.sell('BTCUSDT',0.00025,40000.00);
OCO orders are a bit more complex, so I suggest you get started with this.
To catch the errors (And read them) I always envolve my funcions in a try catch like so:
try {
//Binancy code
} catch(error) {
//Some errors are illegible, I think the plugin uses axios
//So I check to see if the error has a body,
if (error.body) {
//If it does, I parse it and output it
error.body = JSON.parse(error.body);
console.log(error.body)
} else {
//If it does not, I just output the whole error
console.log(error)
}
}
Let me know how this goes!
First we initialize de Binance client. I sugest you use
async
await
, it will make your life much easier.const Binance = require('node-binance-api'); const binance = new Binance().options({ APIKEY: 'YOUR API KEY', APISECRET: 'YOUR API SECRET', useServerTime: true, recvWindow: 60000, verbose: true });
Then, we need some information about the pairs we'll be trading, like
pricePrecision
,quantityPrecision
andminNotional
. This is because when we place an order to buy BTC with USDT, the quantity parameter for example can have up to 5 decimal places, the price parameter up to 2 decimal places, and the minimum order can be of 10 USDT. Each pair has its own parameters, so we callexchangeInfo
to extract that information. (If you don't follow this parameters, you'll end up with a lot of unwanted errors).await binance.exchangeInfo(); //You'll actually need to dig through this to get the information needed
Then to place a order we just call
binance.marketBuy
orbinance.marketSell
to place a market order.//BUY await binance.marketBuy('BTCUSDT',0.00025); //SELL await binance.marketSell('BTCUSDT',0.00025);
You can set the request to a variable to see the output of the order (Don't forget the
await
)var order = await binance.marketBuy('BTCUSDT',0.00025); console.log(order);
We can also call
binance.buy
orbinance.sell
to place a limit order. In this case our order will be executed when the price reaches 40.000.//BUY await binance.buy('BTCUSDT',0.00025,40000.00); //SELL await binance.sell('BTCUSDT',0.00025,40000.00);
OCO orders are a bit more complex, so I suggest you get started with this.
To catch the errors (And read them) I always envolve my funcions in a try catch like so:
try { //Binancy code } catch(error) { //Some errors are illegible, I think the plugin uses axios //So I check to see if the error has a body, if (error.body) { //If it does, I parse it and output it error.body = JSON.parse(error.body); console.log(error.body) } else { //If it does not, I just output the whole error console.log(error) } }
Let me know how this goes!
Thanks a lot! I appreciate it. I will let you know if it goes well or not.
Hey again 👋. So I played with it a little bit. What do you think about my implementation of OCO order: Please let me know :)
const buy = async () => {
try {
const res = await binance.marketBuy('ADAUSDT', 10);
console.log(res)
} catch (error) {
if (error.body) {
error.body = JSON.parse(error.body);
console.log(error.body)
} else {
console.log(error)
}
}
}
const sellOco = async () => {
try {
const res = await binance.order('SELL', 'ADAUSDT', 10, 1.350, {
type: 'OCO',
stopPrice: 1.334,
stopLimitPrice: 1.335
})
console.log(res)
} catch (error) {
if (error.body) {
error.body = JSON.parse(error.body);
console.log(error.body)
} else {
console.log(error)
}
}
}
buy();
...waits for buy function to finish if no errors execute sellOco... (future logic just checking OCO now)
sellOco();
Hey there! Yes I have OCO orders working on the Spot Market, and your method is fine.
However I don't seem to find any documentation about them on the Futures Market.
Anyone managed to set TP/SL or place OCO orders on the Futures Market?
Not sure about OCO because i didn't use. But on futures, i can place a SL, and it correctly displayed on the desktop app.
Just use futuresBuy or futuresSell, with STOP_MARKET price, and it work. FOr me :
let params = {type:'STOP_MARKET',closePosition:true,stopPrice:price,positionSide:type,timeInForce:'GTC',newClientOrderId:orderID}
About TP it's probably same, with TAKE_PROFIT, but i didn't use, because i have several TP. and i think closePosition is required, because that's what desktop app do when you use this interface.
Here I wrote how I managed to set the limit and stop loss #786