ccxt 4.2.35 → 4.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/ccxt.browser.js +419 -165
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +3 -3
- package/dist/cjs/src/base/ws/Client.js +5 -2
- package/dist/cjs/src/binance.js +281 -83
- package/dist/cjs/src/bitfinex.js +21 -0
- package/dist/cjs/src/bitget.js +28 -39
- package/dist/cjs/src/bithumb.js +14 -0
- package/dist/cjs/src/pro/binance.js +2 -2
- package/dist/cjs/src/woo.js +64 -35
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/Exchange.d.ts +1 -0
- package/js/src/base/Exchange.js +3 -3
- package/js/src/base/ws/Client.js +5 -2
- package/js/src/binance.js +281 -83
- package/js/src/bitfinex.js +21 -0
- package/js/src/bitget.js +28 -39
- package/js/src/bithumb.js +14 -0
- package/js/src/pro/binance.js +2 -2
- package/js/src/woo.js +64 -35
- package/package.json +1 -1
package/js/src/binance.js
CHANGED
|
@@ -4738,7 +4738,7 @@ export default class binance extends Exchange {
|
|
|
4738
4738
|
}
|
|
4739
4739
|
request['price'] = this.priceToPrecision(symbol, price);
|
|
4740
4740
|
}
|
|
4741
|
-
if (timeInForceIsRequired) {
|
|
4741
|
+
if (timeInForceIsRequired && (this.safeString(params, 'timeInForce') === undefined)) {
|
|
4742
4742
|
request['timeInForce'] = this.options['defaultTimeInForce']; // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
|
4743
4743
|
}
|
|
4744
4744
|
if (stopPriceIsRequired) {
|
|
@@ -5043,18 +5043,128 @@ export default class binance extends Exchange {
|
|
|
5043
5043
|
// "lastTrade": {"id":"69","time":"1676084430567","price":"24.9","qty":"1.00"},
|
|
5044
5044
|
// "mmp": false
|
|
5045
5045
|
// }
|
|
5046
|
-
//
|
|
5046
|
+
//
|
|
5047
5047
|
// cancelOrders/createOrders
|
|
5048
|
-
//
|
|
5049
|
-
//
|
|
5050
|
-
//
|
|
5048
|
+
//
|
|
5049
|
+
// {
|
|
5050
|
+
// "code": -4005,
|
|
5051
|
+
// "msg": "Quantity greater than max quantity."
|
|
5052
|
+
// }
|
|
5053
|
+
//
|
|
5054
|
+
// createOrder: portfolio margin linear swap and future
|
|
5055
|
+
//
|
|
5056
|
+
// {
|
|
5057
|
+
// "symbol": "BTCUSDT",
|
|
5058
|
+
// "side": "BUY",
|
|
5059
|
+
// "executedQty": "0.000",
|
|
5060
|
+
// "orderId": 258649539704,
|
|
5061
|
+
// "goodTillDate": 0,
|
|
5062
|
+
// "avgPrice": "0",
|
|
5063
|
+
// "origQty": "0.010",
|
|
5064
|
+
// "clientOrderId": "x-xcKtGhcu02573c6f15e544e990057b",
|
|
5065
|
+
// "positionSide": "BOTH",
|
|
5066
|
+
// "cumQty": "0.000",
|
|
5067
|
+
// "updateTime": 1707110415436,
|
|
5068
|
+
// "type": "LIMIT",
|
|
5069
|
+
// "reduceOnly": false,
|
|
5070
|
+
// "price": "35000.00",
|
|
5071
|
+
// "cumQuote": "0.00000",
|
|
5072
|
+
// "selfTradePreventionMode": "NONE",
|
|
5073
|
+
// "timeInForce": "GTC",
|
|
5074
|
+
// "status": "NEW"
|
|
5075
|
+
// }
|
|
5076
|
+
//
|
|
5077
|
+
// createOrder: portfolio margin inverse swap and future
|
|
5078
|
+
//
|
|
5079
|
+
// {
|
|
5080
|
+
// "symbol": "ETHUSD_PERP",
|
|
5081
|
+
// "side": "BUY",
|
|
5082
|
+
// "cumBase": "0",
|
|
5083
|
+
// "executedQty": "0",
|
|
5084
|
+
// "orderId": 71275227732,
|
|
5085
|
+
// "avgPrice": "0.00",
|
|
5086
|
+
// "origQty": "1",
|
|
5087
|
+
// "clientOrderId": "x-xcKtGhcuca5af3acfb5044198c5398",
|
|
5088
|
+
// "positionSide": "BOTH",
|
|
5089
|
+
// "cumQty": "0",
|
|
5090
|
+
// "updateTime": 1707110994334,
|
|
5091
|
+
// "type": "LIMIT",
|
|
5092
|
+
// "pair": "ETHUSD",
|
|
5093
|
+
// "reduceOnly": false,
|
|
5094
|
+
// "price": "2000",
|
|
5095
|
+
// "timeInForce": "GTC",
|
|
5096
|
+
// "status": "NEW"
|
|
5097
|
+
// }
|
|
5098
|
+
//
|
|
5099
|
+
// createOrder: portfolio margin linear swap and future conditional
|
|
5100
|
+
//
|
|
5101
|
+
// {
|
|
5102
|
+
// "newClientStrategyId": "x-xcKtGhcu27f109953d6e4dc0974006",
|
|
5103
|
+
// "strategyId": 3645916,
|
|
5104
|
+
// "strategyStatus": "NEW",
|
|
5105
|
+
// "strategyType": "STOP",
|
|
5106
|
+
// "origQty": "0.010",
|
|
5107
|
+
// "price": "35000.00",
|
|
5108
|
+
// "reduceOnly": false,
|
|
5109
|
+
// "side": "BUY",
|
|
5110
|
+
// "positionSide": "BOTH",
|
|
5111
|
+
// "stopPrice": "45000.00",
|
|
5112
|
+
// "symbol": "BTCUSDT",
|
|
5113
|
+
// "timeInForce": "GTC",
|
|
5114
|
+
// "bookTime": 1707112625879,
|
|
5115
|
+
// "updateTime": 1707112625879,
|
|
5116
|
+
// "workingType": "CONTRACT_PRICE",
|
|
5117
|
+
// "priceProtect": false,
|
|
5118
|
+
// "goodTillDate": 0,
|
|
5119
|
+
// "selfTradePreventionMode": "NONE"
|
|
5120
|
+
// }
|
|
5121
|
+
//
|
|
5122
|
+
// createOrder: portfolio margin inverse swap and future conditional
|
|
5123
|
+
//
|
|
5124
|
+
// {
|
|
5125
|
+
// "newClientStrategyId": "x-xcKtGhcuc6b86f053bb34933850739",
|
|
5126
|
+
// "strategyId": 1423462,
|
|
5127
|
+
// "strategyStatus": "NEW",
|
|
5128
|
+
// "strategyType": "STOP",
|
|
5129
|
+
// "origQty": "1",
|
|
5130
|
+
// "price": "2000",
|
|
5131
|
+
// "reduceOnly": false,
|
|
5132
|
+
// "side": "BUY",
|
|
5133
|
+
// "positionSide": "BOTH",
|
|
5134
|
+
// "stopPrice": "3000",
|
|
5135
|
+
// "symbol": "ETHUSD_PERP",
|
|
5136
|
+
// "timeInForce": "GTC",
|
|
5137
|
+
// "bookTime": 1707113098840,
|
|
5138
|
+
// "updateTime": 1707113098840,
|
|
5139
|
+
// "workingType": "CONTRACT_PRICE",
|
|
5140
|
+
// "priceProtect": false
|
|
5141
|
+
// }
|
|
5142
|
+
//
|
|
5143
|
+
// createOrder: portfolio margin spot margin
|
|
5144
|
+
//
|
|
5145
|
+
// {
|
|
5146
|
+
// "clientOrderId": "x-R4BD3S82e9ef29d8346440f0b28b86",
|
|
5147
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
5148
|
+
// "executedQty": "0.00000000",
|
|
5149
|
+
// "fills": [],
|
|
5150
|
+
// "orderId": 24684460474,
|
|
5151
|
+
// "origQty": "0.00100000",
|
|
5152
|
+
// "price": "35000.00000000",
|
|
5153
|
+
// "selfTradePreventionMode": "EXPIRE_MAKER",
|
|
5154
|
+
// "side": "BUY",
|
|
5155
|
+
// "status": "NEW",
|
|
5156
|
+
// "symbol": "BTCUSDT",
|
|
5157
|
+
// "timeInForce": "GTC",
|
|
5158
|
+
// "transactTime": 1707113538870,
|
|
5159
|
+
// "type": "LIMIT"
|
|
5160
|
+
// }
|
|
5051
5161
|
//
|
|
5052
5162
|
const code = this.safeString(order, 'code');
|
|
5053
5163
|
if (code !== undefined) {
|
|
5054
5164
|
// cancelOrders/createOrders might have a partial success
|
|
5055
5165
|
return this.safeOrder({ 'info': order, 'status': 'rejected' }, market);
|
|
5056
5166
|
}
|
|
5057
|
-
const status = this.parseOrderStatus(this.
|
|
5167
|
+
const status = this.parseOrderStatus(this.safeString2(order, 'status', 'strategyStatus'));
|
|
5058
5168
|
const marketId = this.safeString(order, 'symbol');
|
|
5059
5169
|
const marketType = ('closePosition' in order) ? 'contract' : 'spot';
|
|
5060
5170
|
const symbol = this.safeSymbol(marketId, market, undefined, marketType);
|
|
@@ -5081,11 +5191,9 @@ export default class binance extends Exchange {
|
|
|
5081
5191
|
// Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
|
|
5082
5192
|
let cost = this.safeString2(order, 'cummulativeQuoteQty', 'cumQuote');
|
|
5083
5193
|
cost = this.safeString(order, 'cumBase', cost);
|
|
5084
|
-
const id = this.safeString(order, 'orderId');
|
|
5085
5194
|
let type = this.safeStringLower(order, 'type');
|
|
5086
5195
|
const side = this.safeStringLower(order, 'side');
|
|
5087
5196
|
const fills = this.safeValue(order, 'fills', []);
|
|
5088
|
-
const clientOrderId = this.safeString(order, 'clientOrderId');
|
|
5089
5197
|
let timeInForce = this.safeString(order, 'timeInForce');
|
|
5090
5198
|
if (timeInForce === 'GTX') {
|
|
5091
5199
|
// GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
|
@@ -5108,8 +5216,8 @@ export default class binance extends Exchange {
|
|
|
5108
5216
|
}
|
|
5109
5217
|
return this.safeOrder({
|
|
5110
5218
|
'info': order,
|
|
5111
|
-
'id':
|
|
5112
|
-
'clientOrderId': clientOrderId,
|
|
5219
|
+
'id': this.safeString2(order, 'orderId', 'strategyId'),
|
|
5220
|
+
'clientOrderId': this.safeString2(order, 'clientOrderId', 'newClientStrategyId'),
|
|
5113
5221
|
'timestamp': timestamp,
|
|
5114
5222
|
'datetime': this.iso8601(timestamp),
|
|
5115
5223
|
'lastTradeTimestamp': lastTradeTimestamp,
|
|
@@ -5223,50 +5331,105 @@ export default class binance extends Exchange {
|
|
|
5223
5331
|
* @see https://binance-docs.github.io/apidocs/voptions/en/#new-order-trade
|
|
5224
5332
|
* @see https://binance-docs.github.io/apidocs/spot/en/#new-order-using-sor-trade
|
|
5225
5333
|
* @see https://binance-docs.github.io/apidocs/spot/en/#test-new-order-using-sor-trade
|
|
5334
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-um-order-trade
|
|
5335
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-cm-order-trade
|
|
5336
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-margin-order-trade
|
|
5337
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-um-conditional-order-trade
|
|
5338
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-cm-conditional-order-trade
|
|
5226
5339
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
5227
5340
|
* @param {string} type 'market' or 'limit' or 'STOP_LOSS' or 'STOP_LOSS_LIMIT' or 'TAKE_PROFIT' or 'TAKE_PROFIT_LIMIT' or 'STOP'
|
|
5228
5341
|
* @param {string} side 'buy' or 'sell'
|
|
5229
|
-
* @param {float} amount how much of
|
|
5230
|
-
* @param {float} [price] the price
|
|
5342
|
+
* @param {float} amount how much of you want to trade in units of the base currency
|
|
5343
|
+
* @param {float} [price] the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
5231
5344
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5345
|
+
* @param {string} [params.reduceOnly] for swap and future reduceOnly is a string 'true' or 'false' that cant be sent with close position set to true or in hedge mode. For spot margin and option reduceOnly is a boolean.
|
|
5232
5346
|
* @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
|
|
5233
5347
|
* @param {boolean} [params.sor] *spot only* whether to use SOR (Smart Order Routing) or not, default is false
|
|
5234
5348
|
* @param {boolean} [params.test] *spot only* whether to use the test endpoint or not, default is false
|
|
5235
5349
|
* @param {float} [params.trailingPercent] the percent to trail away from the current market price
|
|
5236
5350
|
* @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
|
|
5351
|
+
* @param {float} [params.triggerPrice] the price that a trigger order is triggered at
|
|
5352
|
+
* @param {float} [params.stopLossPrice] the price that a stop loss order is triggered at
|
|
5353
|
+
* @param {float} [params.takeProfitPrice] the price that a take profit order is triggered at
|
|
5354
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to create an order in a portfolio margin account
|
|
5237
5355
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
5238
5356
|
*/
|
|
5239
5357
|
await this.loadMarkets();
|
|
5240
5358
|
const market = this.market(symbol);
|
|
5241
5359
|
const marketType = this.safeString(params, 'type', market['type']);
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5360
|
+
let marginMode = undefined;
|
|
5361
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
5362
|
+
let isPortfolioMargin = undefined;
|
|
5363
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'createOrder', 'papi', 'portfolioMargin', false);
|
|
5364
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
5365
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice');
|
|
5366
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
5367
|
+
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5368
|
+
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5369
|
+
const isStopLoss = stopLossPrice !== undefined;
|
|
5370
|
+
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5371
|
+
const isConditional = (triggerPrice !== undefined) || isTrailingPercentOrder || isStopLoss || isTakeProfit;
|
|
5372
|
+
const sor = this.safeBool2(params, 'sor', 'SOR', false);
|
|
5373
|
+
const test = this.safeBool(params, 'test', false);
|
|
5374
|
+
params = this.omit(params, ['sor', 'SOR', 'test']);
|
|
5375
|
+
if (isPortfolioMargin) {
|
|
5376
|
+
params['portfolioMargin'] = isPortfolioMargin;
|
|
5377
|
+
}
|
|
5245
5378
|
const request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
5246
|
-
let
|
|
5247
|
-
if (
|
|
5248
|
-
|
|
5379
|
+
let response = undefined;
|
|
5380
|
+
if (market['option']) {
|
|
5381
|
+
response = await this.eapiPrivatePostOrder(request);
|
|
5382
|
+
}
|
|
5383
|
+
else if (sor) {
|
|
5384
|
+
if (test) {
|
|
5385
|
+
response = await this.privatePostSorOrderTest(request);
|
|
5386
|
+
}
|
|
5387
|
+
else {
|
|
5388
|
+
response = await this.privatePostSorOrder(request);
|
|
5389
|
+
}
|
|
5249
5390
|
}
|
|
5250
5391
|
else if (market['linear']) {
|
|
5251
|
-
|
|
5392
|
+
if (isPortfolioMargin) {
|
|
5393
|
+
if (isConditional) {
|
|
5394
|
+
response = await this.papiPostUmConditionalOrder(request);
|
|
5395
|
+
}
|
|
5396
|
+
else {
|
|
5397
|
+
response = await this.papiPostUmOrder(request);
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
else {
|
|
5401
|
+
response = await this.fapiPrivatePostOrder(request);
|
|
5402
|
+
}
|
|
5252
5403
|
}
|
|
5253
5404
|
else if (market['inverse']) {
|
|
5254
|
-
|
|
5405
|
+
if (isPortfolioMargin) {
|
|
5406
|
+
if (isConditional) {
|
|
5407
|
+
response = await this.papiPostCmConditionalOrder(request);
|
|
5408
|
+
}
|
|
5409
|
+
else {
|
|
5410
|
+
response = await this.papiPostCmOrder(request);
|
|
5411
|
+
}
|
|
5412
|
+
}
|
|
5413
|
+
else {
|
|
5414
|
+
response = await this.dapiPrivatePostOrder(request);
|
|
5415
|
+
}
|
|
5255
5416
|
}
|
|
5256
5417
|
else if (marketType === 'margin' || marginMode !== undefined) {
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5418
|
+
if (isPortfolioMargin) {
|
|
5419
|
+
response = await this.papiPostMarginOrder(request);
|
|
5420
|
+
}
|
|
5421
|
+
else {
|
|
5422
|
+
response = await this.sapiPostMarginOrder(request);
|
|
5423
|
+
}
|
|
5261
5424
|
}
|
|
5262
|
-
|
|
5263
|
-
if (market['spot'] || marketType === 'margin') {
|
|
5264
|
-
const test = this.safeBool(query, 'test', false);
|
|
5425
|
+
else {
|
|
5265
5426
|
if (test) {
|
|
5266
|
-
|
|
5427
|
+
response = await this.privatePostOrderTest(request);
|
|
5428
|
+
}
|
|
5429
|
+
else {
|
|
5430
|
+
response = await this.privatePostOrder(request);
|
|
5267
5431
|
}
|
|
5268
5432
|
}
|
|
5269
|
-
const response = await this[method](request);
|
|
5270
5433
|
return this.parseOrder(response, market);
|
|
5271
5434
|
}
|
|
5272
5435
|
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
@@ -5274,16 +5437,13 @@ export default class binance extends Exchange {
|
|
|
5274
5437
|
* @method
|
|
5275
5438
|
* @ignore
|
|
5276
5439
|
* @name binance#createOrderRequest
|
|
5277
|
-
* @description helper function to build request
|
|
5440
|
+
* @description helper function to build the request
|
|
5278
5441
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
5279
|
-
* @param {string} type 'market' or 'limit'
|
|
5442
|
+
* @param {string} type 'market' or 'limit'
|
|
5280
5443
|
* @param {string} side 'buy' or 'sell'
|
|
5281
|
-
* @param {float} amount how much
|
|
5282
|
-
* @param {float
|
|
5283
|
-
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
5284
|
-
* @param {string|undefined} params.marginMode 'cross' or 'isolated', for spot margin trading
|
|
5285
|
-
* @param {float} [params.trailingPercent] the percent to trail away from the current market price
|
|
5286
|
-
* @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
|
|
5444
|
+
* @param {float} amount how much you want to trade in units of the base currency
|
|
5445
|
+
* @param {float} [price] the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
5446
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5287
5447
|
* @returns {object} request to be sent to the exchange
|
|
5288
5448
|
*/
|
|
5289
5449
|
const market = this.market(symbol);
|
|
@@ -5292,35 +5452,54 @@ export default class binance extends Exchange {
|
|
|
5292
5452
|
const initialUppercaseType = type.toUpperCase();
|
|
5293
5453
|
const isMarketOrder = initialUppercaseType === 'MARKET';
|
|
5294
5454
|
const isLimitOrder = initialUppercaseType === 'LIMIT';
|
|
5295
|
-
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5296
|
-
const triggerPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
|
|
5297
|
-
const stopLossPrice = this.safeValue(params, 'stopLossPrice', triggerPrice); // fallback to stopLoss
|
|
5298
|
-
const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
|
|
5299
|
-
const trailingDelta = this.safeValue(params, 'trailingDelta');
|
|
5300
|
-
const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activationPrice', this.numberToString(price));
|
|
5301
|
-
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5302
|
-
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5303
|
-
const isStopLoss = stopLossPrice !== undefined || trailingDelta !== undefined;
|
|
5304
|
-
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5305
|
-
params = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent']);
|
|
5306
|
-
const [marginMode, query] = this.handleMarginModeAndParams('createOrder', params);
|
|
5307
5455
|
const request = {
|
|
5308
5456
|
'symbol': market['id'],
|
|
5309
5457
|
'side': side.toUpperCase(),
|
|
5310
5458
|
};
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5459
|
+
let isPortfolioMargin = undefined;
|
|
5460
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'createOrder', 'papi', 'portfolioMargin', false);
|
|
5461
|
+
let marginMode = undefined;
|
|
5462
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
5463
|
+
if ((marketType === 'margin') || (marginMode !== undefined) || market['option']) {
|
|
5464
|
+
// for swap and future reduceOnly is a string that cant be sent with close position set to true or in hedge mode
|
|
5465
|
+
const reduceOnly = this.safeBool(params, 'reduceOnly', false);
|
|
5466
|
+
params = this.omit(params, 'reduceOnly');
|
|
5467
|
+
if (market['option']) {
|
|
5468
|
+
request['reduceOnly'] = reduceOnly;
|
|
5469
|
+
}
|
|
5470
|
+
else {
|
|
5471
|
+
if (reduceOnly) {
|
|
5472
|
+
request['sideEffectType'] = 'AUTO_REPAY';
|
|
5473
|
+
}
|
|
5315
5474
|
}
|
|
5316
5475
|
}
|
|
5317
|
-
if (
|
|
5318
|
-
const
|
|
5319
|
-
if (
|
|
5320
|
-
|
|
5321
|
-
|
|
5476
|
+
if (!isPortfolioMargin) {
|
|
5477
|
+
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5478
|
+
if (market['spot'] || marketType === 'margin') {
|
|
5479
|
+
// only supported for spot/margin api (all margin markets are spot markets)
|
|
5480
|
+
if (postOnly) {
|
|
5481
|
+
type = 'LIMIT_MAKER';
|
|
5482
|
+
}
|
|
5483
|
+
if (marginMode === 'isolated') {
|
|
5484
|
+
request['isIsolated'] = true;
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
if (market['contract'] && postOnly) {
|
|
5488
|
+
request['timeInForce'] = 'GTX';
|
|
5322
5489
|
}
|
|
5323
5490
|
}
|
|
5491
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
5492
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice', triggerPrice); // fallback to stopLoss
|
|
5493
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
5494
|
+
const trailingDelta = this.safeString(params, 'trailingDelta');
|
|
5495
|
+
const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activationPrice', this.numberToString(price));
|
|
5496
|
+
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5497
|
+
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5498
|
+
const isStopLoss = stopLossPrice !== undefined || trailingDelta !== undefined;
|
|
5499
|
+
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5500
|
+
const isTriggerOrder = triggerPrice !== undefined;
|
|
5501
|
+
const isConditional = isTriggerOrder || isTrailingPercentOrder || isStopLoss || isTakeProfit;
|
|
5502
|
+
const isPortfolioMarginConditional = (isPortfolioMargin && isConditional);
|
|
5324
5503
|
let uppercaseType = type.toUpperCase();
|
|
5325
5504
|
let stopPrice = undefined;
|
|
5326
5505
|
if (isTrailingPercentOrder) {
|
|
@@ -5350,24 +5529,14 @@ export default class binance extends Exchange {
|
|
|
5350
5529
|
uppercaseType = market['contract'] ? 'TAKE_PROFIT' : 'TAKE_PROFIT_LIMIT';
|
|
5351
5530
|
}
|
|
5352
5531
|
}
|
|
5353
|
-
if (marginMode === 'isolated') {
|
|
5354
|
-
request['isIsolated'] = true;
|
|
5355
|
-
}
|
|
5356
|
-
if (clientOrderId === undefined) {
|
|
5357
|
-
const broker = this.safeValue(this.options, 'broker', {});
|
|
5358
|
-
const defaultId = (market['contract']) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
|
|
5359
|
-
const brokerId = this.safeString(broker, marketType, defaultId);
|
|
5360
|
-
request['newClientOrderId'] = brokerId + this.uuid22();
|
|
5361
|
-
}
|
|
5362
|
-
else {
|
|
5363
|
-
request['newClientOrderId'] = clientOrderId;
|
|
5364
|
-
}
|
|
5365
5532
|
if ((marketType === 'spot') || (marketType === 'margin')) {
|
|
5366
|
-
request['newOrderRespType'] = this.
|
|
5533
|
+
request['newOrderRespType'] = this.safeString(this.options['newOrderRespType'], type, 'RESULT'); // 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
|
5367
5534
|
}
|
|
5368
5535
|
else {
|
|
5369
5536
|
// swap, futures and options
|
|
5370
|
-
|
|
5537
|
+
if (!isPortfolioMargin) {
|
|
5538
|
+
request['newOrderRespType'] = 'RESULT'; // "ACK", "RESULT", default "ACK"
|
|
5539
|
+
}
|
|
5371
5540
|
}
|
|
5372
5541
|
if (market['option']) {
|
|
5373
5542
|
if (type === 'market') {
|
|
@@ -5375,7 +5544,7 @@ export default class binance extends Exchange {
|
|
|
5375
5544
|
}
|
|
5376
5545
|
}
|
|
5377
5546
|
else {
|
|
5378
|
-
const validOrderTypes = this.
|
|
5547
|
+
const validOrderTypes = this.safeList(market['info'], 'orderTypes');
|
|
5379
5548
|
if (!this.inArray(uppercaseType, validOrderTypes)) {
|
|
5380
5549
|
if (initialUppercaseType !== uppercaseType) {
|
|
5381
5550
|
throw new InvalidOrder(this.id + ' stopPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders');
|
|
@@ -5385,7 +5554,18 @@ export default class binance extends Exchange {
|
|
|
5385
5554
|
}
|
|
5386
5555
|
}
|
|
5387
5556
|
}
|
|
5388
|
-
|
|
5557
|
+
const clientOrderIdRequest = isPortfolioMarginConditional ? 'newClientStrategyId' : 'newClientOrderId';
|
|
5558
|
+
if (clientOrderId === undefined) {
|
|
5559
|
+
const broker = this.safeDict(this.options, 'broker', {});
|
|
5560
|
+
const defaultId = (market['contract']) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
|
|
5561
|
+
const brokerId = this.safeString(broker, marketType, defaultId);
|
|
5562
|
+
request[clientOrderIdRequest] = brokerId + this.uuid22();
|
|
5563
|
+
}
|
|
5564
|
+
else {
|
|
5565
|
+
request[clientOrderIdRequest] = clientOrderId;
|
|
5566
|
+
}
|
|
5567
|
+
const typeRequest = isPortfolioMarginConditional ? 'strategyType' : 'type';
|
|
5568
|
+
request[typeRequest] = uppercaseType;
|
|
5389
5569
|
// additional required fields depending on the order type
|
|
5390
5570
|
let timeInForceIsRequired = false;
|
|
5391
5571
|
let priceIsRequired = false;
|
|
@@ -5413,9 +5593,9 @@ export default class binance extends Exchange {
|
|
|
5413
5593
|
//
|
|
5414
5594
|
if (uppercaseType === 'MARKET') {
|
|
5415
5595
|
if (market['spot']) {
|
|
5416
|
-
const quoteOrderQty = this.
|
|
5596
|
+
const quoteOrderQty = this.safeBool(this.options, 'quoteOrderQty', true);
|
|
5417
5597
|
if (quoteOrderQty) {
|
|
5418
|
-
const quoteOrderQtyNew = this.
|
|
5598
|
+
const quoteOrderQtyNew = this.safeString2(params, 'quoteOrderQty', 'cost');
|
|
5419
5599
|
const precision = market['precision']['price'];
|
|
5420
5600
|
if (quoteOrderQtyNew !== undefined) {
|
|
5421
5601
|
request['quoteOrderQty'] = this.decimalToPrecision(quoteOrderQtyNew, TRUNCATE, precision, this.precisionMode);
|
|
@@ -5466,7 +5646,7 @@ export default class binance extends Exchange {
|
|
|
5466
5646
|
priceIsRequired = true;
|
|
5467
5647
|
}
|
|
5468
5648
|
else if ((uppercaseType === 'STOP_MARKET') || (uppercaseType === 'TAKE_PROFIT_MARKET')) {
|
|
5469
|
-
const closePosition = this.
|
|
5649
|
+
const closePosition = this.safeBool(params, 'closePosition');
|
|
5470
5650
|
if (closePosition === undefined) {
|
|
5471
5651
|
quantityIsRequired = true;
|
|
5472
5652
|
}
|
|
@@ -5479,7 +5659,13 @@ export default class binance extends Exchange {
|
|
|
5479
5659
|
}
|
|
5480
5660
|
}
|
|
5481
5661
|
if (quantityIsRequired) {
|
|
5482
|
-
|
|
5662
|
+
// portfolio margin has a different amount precision
|
|
5663
|
+
if (isPortfolioMargin) {
|
|
5664
|
+
request['quantity'] = this.parseToNumeric(amount);
|
|
5665
|
+
}
|
|
5666
|
+
else {
|
|
5667
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
5668
|
+
}
|
|
5483
5669
|
}
|
|
5484
5670
|
if (priceIsRequired) {
|
|
5485
5671
|
if (price === undefined) {
|
|
@@ -5490,9 +5676,6 @@ export default class binance extends Exchange {
|
|
|
5490
5676
|
if (timeInForceIsRequired) {
|
|
5491
5677
|
request['timeInForce'] = this.options['defaultTimeInForce']; // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
|
5492
5678
|
}
|
|
5493
|
-
if (market['contract'] && postOnly) {
|
|
5494
|
-
request['timeInForce'] = 'GTX';
|
|
5495
|
-
}
|
|
5496
5679
|
if (stopPriceIsRequired) {
|
|
5497
5680
|
if (market['contract']) {
|
|
5498
5681
|
if (stopPrice === undefined) {
|
|
@@ -5509,11 +5692,26 @@ export default class binance extends Exchange {
|
|
|
5509
5692
|
request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
5510
5693
|
}
|
|
5511
5694
|
}
|
|
5695
|
+
if (!isPortfolioMargin) {
|
|
5696
|
+
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5697
|
+
if (market['spot'] || marketType === 'margin') {
|
|
5698
|
+
// only supported for spot/margin api (all margin markets are spot markets)
|
|
5699
|
+
if (postOnly) {
|
|
5700
|
+
type = 'LIMIT_MAKER';
|
|
5701
|
+
}
|
|
5702
|
+
if (marginMode === 'isolated') {
|
|
5703
|
+
request['isIsolated'] = true;
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
if (market['contract'] && postOnly) {
|
|
5707
|
+
request['timeInForce'] = 'GTX';
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5512
5710
|
// remove timeInForce from params because PO is only used by this.isPostOnly and it's not a valid value for Binance
|
|
5513
5711
|
if (this.safeString(params, 'timeInForce') === 'PO') {
|
|
5514
|
-
params = this.omit(params,
|
|
5712
|
+
params = this.omit(params, 'timeInForce');
|
|
5515
5713
|
}
|
|
5516
|
-
const requestParams = this.omit(params, ['
|
|
5714
|
+
const requestParams = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent', 'quoteOrderQty', 'cost', 'test']);
|
|
5517
5715
|
return this.extend(request, requestParams);
|
|
5518
5716
|
}
|
|
5519
5717
|
async createMarketOrderWithCost(symbol, side, cost, params = {}) {
|