diff --git a/src/node-binance-api.ts b/src/node-binance-api.ts index 4627a3fd..a7de03dd 100644 --- a/src/node-binance-api.ts +++ b/src/node-binance-api.ts @@ -735,6 +735,9 @@ export default class Binance { * @param {string} quantity - The quantity to buy or sell * @param {string} price - The price per unit to transact each unit at * @param {object} params - additional order settings + * @param {number} [params.quoteOrderQty] - The quote order quantity, used for MARKET orders + * @param {number} [params.stopPrice] - The stop price, used for STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT orders + * @param {number} [params.trailingDelta] - Delta price * @return {undefined} */ async order(type: OrderType, side: OrderSide, symbol: string, quantity: number, price?: number, params: Dict = {}): Promise { @@ -778,6 +781,15 @@ export default class Binance { request.newClientOrderId = this.SPOT_PREFIX + this.uuid22(); } + const allowedTypesForStopAndTrailing = ['STOP_LOSS', 'STOP_LOSS_LIMIT', 'TAKE_PROFIT', 'TAKE_PROFIT_LIMIT']; + if (params.trailingDelta) { + request.trailingDelta = params.trailingDelta; + + if (!allowedTypesForStopAndTrailing.includes(request.type)) { + throw Error('trailingDelta: Must set "type" to one of the following: STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT'); + } + } + /* * STOP_LOSS * STOP_LOSS_LIMIT @@ -788,7 +800,9 @@ export default class Binance { // if (typeof params.icebergQty !== 'undefined') request.icebergQty = params.icebergQty; if (params.stopPrice) { request.stopPrice = params.stopPrice; - if (request.type === 'LIMIT') throw Error('stopPrice: Must set "type" to one of the following: STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT'); + if (!allowedTypesForStopAndTrailing.includes(request.type)) { + throw Error('stopPrice: Must set "type" to one of the following: STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT'); + } } const response = await this.privateSpotRequest(endpoint, this.extend(request, params), 'POST'); // to do error handling diff --git a/tests/binance-class-live.test.ts b/tests/binance-class-live.test.ts index 4204bb9d..30c98088 100644 --- a/tests/binance-class-live.test.ts +++ b/tests/binance-class-live.test.ts @@ -272,7 +272,10 @@ describe('Limit buy Order', function () { assert(res['orderId'] !== undefined) spotOrderId = res['orderId']; } catch (e) { - assert(e.toString().includes('{"code":-2010,"msg":"Account has insufficient balance for requested action."}')); + const exceptionA = '{"code":-2010,"msg":"Account has insufficient balance for requested action."}'; + const exceptionB = '{"code":-2019,"msg":"Margin is insufficient."}' + const eStr = e.toString(); + assert(eStr.includes(exceptionA) || eStr.includes(exceptionB)); } } @@ -287,7 +290,10 @@ describe('MarketSell', function () { const res = await binance.marketSell('LTCUSDT', quantity) assert(res['orderId'] !== undefined) } catch (e) { - assert(e.toString().includes('{"code":-2010,"msg":"Account has insufficient balance for requested action."}')); + const exceptionA = '{"code":-2010,"msg":"Account has insufficient balance for requested action."}'; + const exceptionB = '{"code":-2019,"msg":"Margin is insufficient."}' + const eStr = e.toString(); + assert(eStr.includes(exceptionA) || eStr.includes(exceptionB)); } }).timeout(TIMEOUT); @@ -301,7 +307,10 @@ describe('Futures MarketBuy', function () { assert(res['orderId'] !== undefined) futuresOrderId = res['orderId']; } catch (e) { - assert(e.toString().includes('{"code":-2010,"msg":"Account has insufficient balance for requested action."}')); + const exceptionA = '{"code":-2010,"msg":"Account has insufficient balance for requested action."}'; + const exceptionB = '{"code":-2019,"msg":"Margin is insufficient."}' + const eStr = e.toString(); + assert(eStr.includes(exceptionA) || eStr.includes(exceptionB)); } }).timeout(TIMEOUT); @@ -309,20 +318,35 @@ describe('Futures MarketBuy', function () { describe('Futures Limit buy Order', function () { it('Attempt to buy ETH', async function () { - if (ethusdtPrice !== 0) { - let quantity = 0.1; - const res = await futuresBinance.futuresOrder('LIMIT', 'BUY', 'ETHUSDT', quantity, Math.round(ethusdtPrice * 0.8)) - assert(res['orderId'] !== undefined) - futuresOrderId = res['orderId']; + try { + if (ethusdtPrice !== 0) { + let quantity = 0.1; + const res = await futuresBinance.futuresOrder('LIMIT', 'BUY', 'ETHUSDT', quantity, Math.round(ethusdtPrice * 0.8)) + assert(res['orderId'] !== undefined) + futuresOrderId = res['orderId']; + } + } catch (e) { + const exceptionA = '{"code":-2010,"msg":"Account has insufficient balance for requested action."}'; + const exceptionB = '{"code":-2019,"msg":"Margin is insufficient."}' + const eStr = e.toString(); + assert(eStr.includes(exceptionA) || eStr.includes(exceptionB)); } + }).timeout(TIMEOUT); }); describe('Futures MarketSell', function () { it('futures Attempt to buy ETH at market price', async function () { - let quantity = 0.1; - const res = await futuresBinance.futuresMarketSell('ETHUSDT', quantity) - assert(res['orderId'] !== undefined) + try { + let quantity = 0.1; + const res = await futuresBinance.futuresMarketSell('ETHUSDT', quantity) + assert(res['orderId'] !== undefined) + } catch (e) { + const exceptionA = '{"code":-2010,"msg":"Account has insufficient balance for requested action."}'; + const exceptionB = '{"code":-2019,"msg":"Margin is insufficient."}' + const eStr = e.toString(); + assert(eStr.includes(exceptionA) || eStr.includes(exceptionB)); + } }).timeout(TIMEOUT); });