Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ https://t.me/nodebinanceapi
Actively maintained, typed, and safe SDK for the Binance REST APIs and Websockets. Supports ESM and CJS out of the box.

### Features
- Spot, Margin, Futures and Delivery API
- Spot, Margin, Futures and Delivery API (including the new algoOrder service)
- Demo trading support
- Testnet support (deprecated)
- Proxy support (REST and WS)
Expand Down
141 changes: 141 additions & 0 deletions src/node-binance-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1187,9 +1187,70 @@ export default class Binance {
if (!params.newClientOrderId) {
params.newClientOrderId = this.CONTRACT_PREFIX + this.uuid22();
}
// check if it is algoOrder
const conditionalTypes = [
'STOP',
'STOP_MARKET',
'TAKE_PROFIT',
'TAKE_PROFIT_MARKET',
'TRAILING_STOP_MARKET',
];
const typeUpperCase = type.toUpperCase();
if (typeUpperCase && conditionalTypes.includes(typeUpperCase)) {
const algoPayload = { ...params };
if (!algoPayload.clientAlgoId) {
algoPayload.clientAlgoId = this.CONTRACT_PREFIX + this.uuid22();
}
delete algoPayload.newClientOrderId;
algoPayload.algoType = 'CONDITIONAL';
if (algoPayload.stopPrice && !algoPayload.triggerPrice) {
algoPayload.triggerPrice = algoPayload.stopPrice;
delete algoPayload.stopPrice;
}
return await this.privateFuturesRequest('v1/algoOrder', algoPayload, 'POST');
}
return await this.privateFuturesRequest('v1/order', params, 'POST');
}

// Futures internal functions
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment "// Futures internal functions" is redundant as it's already declared at line 1158. This appears to be a copy-paste error and should be removed.

Suggested change
// Futures internal functions

Copilot uses AI. Check for mistakes.
/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/New-Algo-Order
* @param type
* @param side
* @param symbol symbol if the market
* @param quantity
* @param price
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresAlgoOrder(type: OrderType, side: string, symbol: string, quantity: number, price?: number, params: Dict = {}): Promise<FuturesOrder> {
params.symbol = symbol;
params.side = side;
params.type = type;
if (quantity) params.quantity = quantity;
// if in the binance futures setting Hedged mode is active, positionSide parameter is mandatory
if (!params.positionSide && this.Options.hedgeMode) {
params.positionSide = side === 'BUY' ? 'LONG' : 'SHORT';
}
// LIMIT STOP MARKET STOP_MARKET TAKE_PROFIT TAKE_PROFIT_MARKET
// reduceOnly stopPrice
if (price) {
params.price = price;
}
if (!params.timeInForce && (params.type.includes('LIMIT') || params.type === 'STOP' || params.type === 'TAKE_PROFIT')) {
params.timeInForce = 'GTX'; // Post only by default. Use GTC for limit orders.
}

if (!params.clientAlgoId) {
params.clientAlgoId = this.CONTRACT_PREFIX + this.uuid22();
}

if (!params.algoType) {
params.algoType = 'CONDITIONAL';
}
return await this.privateFuturesRequest('v1/algoOrder', params, 'POST');
}

/**
* @see https://developers.binance.com/docs/derivatives/option/trade/New-Order
* @param type type of order to create
Expand Down Expand Up @@ -4502,39 +4563,92 @@ export default class Binance {

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Order
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Algo-Order
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @param params.conditional set to true to query algo order
* @returns
*/
async futuresOrderStatus(symbol: string, params: Dict = {}): Promise<FuturesOrder> { // Either orderId or origClientOrderId must be sent
params.symbol = symbol;
if ('conditional' in params) {
delete params.conditional;
return await this.privateFuturesRequest('v1/algoOrder', params);
}
return await this.privateFuturesRequest('v1/order', params);
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-Algo-Order
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresAlgoOrderStatus(symbol: string, params: Dict = {}): Promise<FuturesOrder> { // Either orderId or origClientOrderId must be sent
params.symbol = symbol;
return await this.privateFuturesRequest('v1/algoOrder', params);
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Order
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Algo-Order
* @param symbol symbol if the market
* @param orderId
* @param params.conditional set to true to cancel algo order
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresCancel(symbol: string, orderId?: number | string, params: Dict = {}): Promise<CancelOrder> { // Either orderId or origClientOrderId must be sent
params.symbol = symbol;
if ('conditional' in params) {
delete params.conditional;
if (orderId) params.algoid = orderId;
return await this.privateFuturesRequest('v1/algoOrder', params, 'DELETE');
}
if (orderId) params.orderId = orderId;
return await this.privateFuturesRequest('v1/order', params, 'DELETE');
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-Algo-Order
* @param symbol symbol if the market
* @param orderId
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresCancelAlgoOrder(symbol: string, orderId?: number | string, params: Dict = {}): Promise<CancelOrder> { // Either orderId or origClientOrderId must be sent
params.symbol = symbol;
if (orderId) params.algoid = orderId;
return await this.privateFuturesRequest('v1/algoOrder', params, 'DELETE');
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-All-Open-Orders
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @param params.conditional set to true to cancel algo order
* @returns
*/
async futuresCancelAll(symbol: string, params: Dict = {}): Promise<Response> {
params.symbol = symbol;
if ('conditional' in params) {
delete params.conditional;
return await this.privateFuturesRequest('v1/algoOpenOrders', params, 'DELETE');
}
return await this.privateFuturesRequest('v1/allOpenOrders', params, 'DELETE');
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Cancel-All-Algo-Open-Orders
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresCancelAllAlgo(symbol: string, params: Dict = {}): Promise<Response> {
params.symbol = symbol;
return await this.privateFuturesRequest('v1/algoOpenOrders', params, 'DELETE');
}

/**
*
* @param symbol symbol if the market
Expand All @@ -4552,13 +4666,29 @@ export default class Binance {
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Current-All-Open-Orders
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @param params.conditional set to true to query algo open orders
* @returns
*/
async futuresOpenOrders(symbol?: string, params: Dict = {}): Promise<FuturesOrder[]> {
if (symbol) params.symbol = symbol;
if ('conditional' in params) {
delete params.conditional;
return await this.privateFuturesRequest('v1/algoOpenOrders', params);
}
return await this.privateFuturesRequest('v1/openOrders', params);
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Current-All-Algo-Open-Orders
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresOpenAlgoOrders(symbol?: string, params: Dict = {}): Promise<FuturesOrder[]> {
if (symbol) params.symbol = symbol;
return await this.privateFuturesRequest('v1/openAlgoOrders', params);
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/All-Orders
* @param symbol symbol if the market
Expand All @@ -4570,6 +4700,17 @@ export default class Binance {
return await this.privateFuturesRequest('v1/allOrders', params);
}

/**
* @see https://developers.binance.com/docs/derivatives/usds-margined-futures/trade/rest-api/Query-All-Algo-Orders
* @param symbol symbol if the market
* @param params extra parameters to be sent in the request
* @returns
*/
async futuresAllAlgoOrders(symbol?: string, params: Dict = {}): Promise<FuturesOrder[]> { // Get all account orders; active, canceled, or filled.
if (symbol) params.symbol = symbol;
return await this.privateFuturesRequest('v1/allAlgoOrders', params);
}

/**
*
* @param params extra parameters to be sent in the request
Expand Down
48 changes: 31 additions & 17 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,42 @@ export interface Order {
}

export interface FuturesOrder {
clientOrderId: string
cumQty: string
cumQuote: string
executedQty: string
orderId: number
avgPrice: string
origQty: string
clientOrderId?: string
cumQty?: string
cumQuote?: string
executedQty?: string
orderId?: number
avgPrice?: string
origQty?: string
price: string
reduceOnly: boolean
side: OrderSide
positionSide: PositionSide
status: OrderStatus
stopPrice: string
closePosition: boolean
status?: OrderStatus
stopPrice?: string
closePosition?: boolean
symbol: string
timeInForce: TimeInForce
type: OrderType
origType: OrderType
activatePrice: string
priceRate: string
updateTime: number
workingType: WorkingType
timeInForce?: TimeInForce
type?: OrderType
origType?: OrderType
activatePrice?: string
priceRate?: string
updateTime?: number
workingType?: WorkingType
// algo orders fields
algoId?: number;
triggerPrice?: string;
orderStatus?: string;
clientAlgoId?: string;
algoStatus?: string;
actualOrderId?: string;
actualPrice?: string;
tpTriggerPrice?: string;
tpPrice?: string;
slTriggerPrice?: string;
slPrice?: string;
tpOrderType?: string;
slOrderType?: string;
}

export type PositionSide = 'BOTH' | 'SHORT' | 'LONG'
Expand Down
24 changes: 24 additions & 0 deletions tests/binance-class-static.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,30 @@ describe( 'Static tests', async function () {
assert(obj.newClientOrderId.startsWith(CONTRACT_PREFIX))
})

it( 'Futures Limit trigger Buy', async function ( ) {
await binance.futuresOrder('STOP', 'BUY', 'LTCUSDT', 0.5, 100, {'triggerPrice': 90} )
assert.isTrue( interceptedUrl.startsWith('https://fapi.binance.com/fapi/v1/algoOrder' ))
const obj = urlToObject( interceptedUrl.replace('https://fapi.binance.com/fapi/v1/algoOrder?', '') )
assert.equal( obj.symbol, 'LTCUSDT' )
assert.equal( obj.side, 'BUY' )
assert.equal( obj.type, 'STOP' )
assert.equal( obj.algoType, 'CONDITIONAL')
assert.equal( obj.quantity, 0.5 )
assert(obj.clientAlgoId.startsWith(CONTRACT_PREFIX))
})

it( 'Futures Limit trigger Buy using dedicated endpoint', async function ( ) {
await binance.futuresAlgoOrder('STOP', 'BUY', 'LTCUSDT', 0.5, 100, {'triggerPrice': 90} )
assert.isTrue( interceptedUrl.startsWith('https://fapi.binance.com/fapi/v1/algoOrder' ))
const obj = urlToObject( interceptedUrl.replace('https://fapi.binance.com/fapi/v1/algoOrder?', '') )
assert.equal( obj.symbol, 'LTCUSDT' )
assert.equal( obj.side, 'BUY' )
assert.equal( obj.type, 'STOP' )
assert.equal( obj.algoType, 'CONDITIONAL')
assert.equal( obj.quantity, 0.5 )
assert(obj.clientAlgoId.startsWith(CONTRACT_PREFIX))
})

it( 'Futures LimitSell', async function ( ) {
await binance.futuresOrder('LIMIT', 'SELL', 'LTCUSDT', 0.5, 100 )
assert.isTrue( interceptedUrl.startsWith('https://fapi.binance.com/fapi/v1/order' ))
Expand Down
Loading