ccxt 4.2.34 → 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 +520 -182
- package/dist/ccxt.browser.min.js +3 -3
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +10 -2
- package/dist/cjs/src/base/ws/Client.js +5 -2
- package/dist/cjs/src/binance.js +335 -94
- package/dist/cjs/src/bitfinex.js +21 -0
- package/dist/cjs/src/bitfinex2.js +12 -1
- package/dist/cjs/src/bitget.js +28 -39
- package/dist/cjs/src/bithumb.js +14 -0
- package/dist/cjs/src/krakenfutures.js +25 -3
- package/dist/cjs/src/pro/binance.js +5 -5
- 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.js +10 -2
- package/js/src/base/ws/Client.js +5 -2
- package/js/src/binance.js +335 -94
- package/js/src/bitfinex.js +21 -0
- package/js/src/bitfinex2.js +12 -1
- package/js/src/bitget.js +28 -39
- package/js/src/bithumb.js +14 -0
- package/js/src/krakenfutures.js +25 -3
- package/js/src/pro/binance.js +5 -5
- package/js/src/woo.js +64 -35
- package/package.json +1 -1
package/dist/cjs/src/binance.js
CHANGED
|
@@ -3143,9 +3143,24 @@ class binance extends binance$1 {
|
|
|
3143
3143
|
let timestamp = undefined;
|
|
3144
3144
|
const isolated = marginMode === 'isolated';
|
|
3145
3145
|
const cross = (type === 'margin') || (marginMode === 'cross');
|
|
3146
|
-
if (
|
|
3146
|
+
if (type === 'papi') {
|
|
3147
|
+
for (let i = 0; i < response.length; i++) {
|
|
3148
|
+
const entry = response[i];
|
|
3149
|
+
const account = this.account();
|
|
3150
|
+
const currencyId = this.safeString(entry, 'asset');
|
|
3151
|
+
const code = this.safeCurrencyCode(currencyId);
|
|
3152
|
+
const borrowed = this.safeString(entry, 'crossMarginBorrowed');
|
|
3153
|
+
const interest = this.safeString(entry, 'crossMarginInterest');
|
|
3154
|
+
account['free'] = this.safeString(entry, 'crossMarginFree');
|
|
3155
|
+
account['used'] = this.safeString(entry, 'crossMarginLocked');
|
|
3156
|
+
account['total'] = this.safeString(entry, 'crossMarginAsset');
|
|
3157
|
+
account['debt'] = Precise["default"].stringAdd(borrowed, interest);
|
|
3158
|
+
result[code] = account;
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
else if (!isolated && ((type === 'spot') || cross)) {
|
|
3147
3162
|
timestamp = this.safeInteger(response, 'updateTime');
|
|
3148
|
-
const balances = this.
|
|
3163
|
+
const balances = this.safeList2(response, 'balances', 'userAssets', []);
|
|
3149
3164
|
for (let i = 0; i < balances.length; i++) {
|
|
3150
3165
|
const balance = balances[i];
|
|
3151
3166
|
const currencyId = this.safeString(balance, 'asset');
|
|
@@ -3162,13 +3177,13 @@ class binance extends binance$1 {
|
|
|
3162
3177
|
}
|
|
3163
3178
|
}
|
|
3164
3179
|
else if (isolated) {
|
|
3165
|
-
const assets = this.
|
|
3180
|
+
const assets = this.safeList(response, 'assets');
|
|
3166
3181
|
for (let i = 0; i < assets.length; i++) {
|
|
3167
3182
|
const asset = assets[i];
|
|
3168
|
-
const marketId = this.
|
|
3183
|
+
const marketId = this.safeString(asset, 'symbol');
|
|
3169
3184
|
const symbol = this.safeSymbol(marketId, undefined, undefined, 'spot');
|
|
3170
|
-
const base = this.
|
|
3171
|
-
const quote = this.
|
|
3185
|
+
const base = this.safeDict(asset, 'baseAsset', {});
|
|
3186
|
+
const quote = this.safeDict(asset, 'quoteAsset', {});
|
|
3172
3187
|
const baseCode = this.safeCurrencyCode(this.safeString(base, 'asset'));
|
|
3173
3188
|
const quoteCode = this.safeCurrencyCode(this.safeString(quote, 'asset'));
|
|
3174
3189
|
const subResult = {};
|
|
@@ -3178,7 +3193,7 @@ class binance extends binance$1 {
|
|
|
3178
3193
|
}
|
|
3179
3194
|
}
|
|
3180
3195
|
else if (type === 'savings') {
|
|
3181
|
-
const positionAmountVos = this.
|
|
3196
|
+
const positionAmountVos = this.safeList(response, 'positionAmountVos', []);
|
|
3182
3197
|
for (let i = 0; i < positionAmountVos.length; i++) {
|
|
3183
3198
|
const entry = positionAmountVos[i];
|
|
3184
3199
|
const currencyId = this.safeString(entry, 'asset');
|
|
@@ -3207,7 +3222,7 @@ class binance extends binance$1 {
|
|
|
3207
3222
|
else {
|
|
3208
3223
|
let balances = response;
|
|
3209
3224
|
if (!Array.isArray(response)) {
|
|
3210
|
-
balances = this.
|
|
3225
|
+
balances = this.safeList(response, 'assets', []);
|
|
3211
3226
|
}
|
|
3212
3227
|
for (let i = 0; i < balances.length; i++) {
|
|
3213
3228
|
const balance = balances[i];
|
|
@@ -3237,10 +3252,12 @@ class binance extends binance$1 {
|
|
|
3237
3252
|
* @see https://binance-docs.github.io/apidocs/futures/en/#account-information-v2-user_data // swap
|
|
3238
3253
|
* @see https://binance-docs.github.io/apidocs/delivery/en/#account-information-user_data // future
|
|
3239
3254
|
* @see https://binance-docs.github.io/apidocs/voptions/en/#option-account-information-trade // option
|
|
3255
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#account-balance-user_data // portfolio margin
|
|
3240
3256
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
3241
|
-
* @param {string} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot'
|
|
3257
|
+
* @param {string} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot' or 'papi'
|
|
3242
3258
|
* @param {string} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
|
|
3243
3259
|
* @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode
|
|
3260
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to fetch the balance for a portfolio margin account
|
|
3244
3261
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
3245
3262
|
*/
|
|
3246
3263
|
await this.loadMarkets();
|
|
@@ -3248,13 +3265,19 @@ class binance extends binance$1 {
|
|
|
3248
3265
|
let type = this.safeString(params, 'type', defaultType);
|
|
3249
3266
|
let subType = undefined;
|
|
3250
3267
|
[subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
|
|
3268
|
+
let isPortfolioMargin = undefined;
|
|
3269
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'fetchBalance', 'papi', 'portfolioMargin', false);
|
|
3251
3270
|
let marginMode = undefined;
|
|
3252
3271
|
let query = undefined;
|
|
3253
3272
|
[marginMode, query] = this.handleMarginModeAndParams('fetchBalance', params);
|
|
3254
3273
|
query = this.omit(query, 'type');
|
|
3255
3274
|
let response = undefined;
|
|
3256
3275
|
const request = {};
|
|
3257
|
-
if (
|
|
3276
|
+
if (isPortfolioMargin || (type === 'papi')) {
|
|
3277
|
+
type = 'papi';
|
|
3278
|
+
response = await this.papiGetBalance(this.extend(request, query));
|
|
3279
|
+
}
|
|
3280
|
+
else if (this.isLinear(type, subType)) {
|
|
3258
3281
|
type = 'linear';
|
|
3259
3282
|
response = await this.fapiPrivateV2GetAccount(this.extend(request, query));
|
|
3260
3283
|
}
|
|
@@ -3263,7 +3286,7 @@ class binance extends binance$1 {
|
|
|
3263
3286
|
response = await this.dapiPrivateGetAccount(this.extend(request, query));
|
|
3264
3287
|
}
|
|
3265
3288
|
else if (marginMode === 'isolated') {
|
|
3266
|
-
const paramSymbols = this.
|
|
3289
|
+
const paramSymbols = this.safeList(params, 'symbols');
|
|
3267
3290
|
query = this.omit(query, 'symbols');
|
|
3268
3291
|
if (paramSymbols !== undefined) {
|
|
3269
3292
|
let symbols = '';
|
|
@@ -3479,6 +3502,26 @@ class binance extends binance$1 {
|
|
|
3479
3502
|
// }
|
|
3480
3503
|
// ]
|
|
3481
3504
|
//
|
|
3505
|
+
// portfolio margin
|
|
3506
|
+
//
|
|
3507
|
+
// [
|
|
3508
|
+
// {
|
|
3509
|
+
// "asset": "USDT",
|
|
3510
|
+
// "totalWalletBalance": "66.9923261",
|
|
3511
|
+
// "crossMarginAsset": "35.9697141",
|
|
3512
|
+
// "crossMarginBorrowed": "0.0",
|
|
3513
|
+
// "crossMarginFree": "35.9697141",
|
|
3514
|
+
// "crossMarginInterest": "0.0",
|
|
3515
|
+
// "crossMarginLocked": "0.0",
|
|
3516
|
+
// "umWalletBalance": "31.022612",
|
|
3517
|
+
// "umUnrealizedPNL": "0.0",
|
|
3518
|
+
// "cmWalletBalance": "0.0",
|
|
3519
|
+
// "cmUnrealizedPNL": "0.0",
|
|
3520
|
+
// "updateTime": 0,
|
|
3521
|
+
// "negativeBalance": "0.0"
|
|
3522
|
+
// },
|
|
3523
|
+
// ]
|
|
3524
|
+
//
|
|
3482
3525
|
return this.parseBalanceCustom(response, type, marginMode);
|
|
3483
3526
|
}
|
|
3484
3527
|
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
@@ -4692,7 +4735,7 @@ class binance extends binance$1 {
|
|
|
4692
4735
|
}
|
|
4693
4736
|
request['price'] = this.priceToPrecision(symbol, price);
|
|
4694
4737
|
}
|
|
4695
|
-
if (timeInForceIsRequired) {
|
|
4738
|
+
if (timeInForceIsRequired && (this.safeString(params, 'timeInForce') === undefined)) {
|
|
4696
4739
|
request['timeInForce'] = this.options['defaultTimeInForce']; // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
|
4697
4740
|
}
|
|
4698
4741
|
if (stopPriceIsRequired) {
|
|
@@ -4997,18 +5040,128 @@ class binance extends binance$1 {
|
|
|
4997
5040
|
// "lastTrade": {"id":"69","time":"1676084430567","price":"24.9","qty":"1.00"},
|
|
4998
5041
|
// "mmp": false
|
|
4999
5042
|
// }
|
|
5000
|
-
//
|
|
5043
|
+
//
|
|
5001
5044
|
// cancelOrders/createOrders
|
|
5002
|
-
//
|
|
5003
|
-
//
|
|
5004
|
-
//
|
|
5045
|
+
//
|
|
5046
|
+
// {
|
|
5047
|
+
// "code": -4005,
|
|
5048
|
+
// "msg": "Quantity greater than max quantity."
|
|
5049
|
+
// }
|
|
5050
|
+
//
|
|
5051
|
+
// createOrder: portfolio margin linear swap and future
|
|
5052
|
+
//
|
|
5053
|
+
// {
|
|
5054
|
+
// "symbol": "BTCUSDT",
|
|
5055
|
+
// "side": "BUY",
|
|
5056
|
+
// "executedQty": "0.000",
|
|
5057
|
+
// "orderId": 258649539704,
|
|
5058
|
+
// "goodTillDate": 0,
|
|
5059
|
+
// "avgPrice": "0",
|
|
5060
|
+
// "origQty": "0.010",
|
|
5061
|
+
// "clientOrderId": "x-xcKtGhcu02573c6f15e544e990057b",
|
|
5062
|
+
// "positionSide": "BOTH",
|
|
5063
|
+
// "cumQty": "0.000",
|
|
5064
|
+
// "updateTime": 1707110415436,
|
|
5065
|
+
// "type": "LIMIT",
|
|
5066
|
+
// "reduceOnly": false,
|
|
5067
|
+
// "price": "35000.00",
|
|
5068
|
+
// "cumQuote": "0.00000",
|
|
5069
|
+
// "selfTradePreventionMode": "NONE",
|
|
5070
|
+
// "timeInForce": "GTC",
|
|
5071
|
+
// "status": "NEW"
|
|
5072
|
+
// }
|
|
5073
|
+
//
|
|
5074
|
+
// createOrder: portfolio margin inverse swap and future
|
|
5075
|
+
//
|
|
5076
|
+
// {
|
|
5077
|
+
// "symbol": "ETHUSD_PERP",
|
|
5078
|
+
// "side": "BUY",
|
|
5079
|
+
// "cumBase": "0",
|
|
5080
|
+
// "executedQty": "0",
|
|
5081
|
+
// "orderId": 71275227732,
|
|
5082
|
+
// "avgPrice": "0.00",
|
|
5083
|
+
// "origQty": "1",
|
|
5084
|
+
// "clientOrderId": "x-xcKtGhcuca5af3acfb5044198c5398",
|
|
5085
|
+
// "positionSide": "BOTH",
|
|
5086
|
+
// "cumQty": "0",
|
|
5087
|
+
// "updateTime": 1707110994334,
|
|
5088
|
+
// "type": "LIMIT",
|
|
5089
|
+
// "pair": "ETHUSD",
|
|
5090
|
+
// "reduceOnly": false,
|
|
5091
|
+
// "price": "2000",
|
|
5092
|
+
// "timeInForce": "GTC",
|
|
5093
|
+
// "status": "NEW"
|
|
5094
|
+
// }
|
|
5095
|
+
//
|
|
5096
|
+
// createOrder: portfolio margin linear swap and future conditional
|
|
5097
|
+
//
|
|
5098
|
+
// {
|
|
5099
|
+
// "newClientStrategyId": "x-xcKtGhcu27f109953d6e4dc0974006",
|
|
5100
|
+
// "strategyId": 3645916,
|
|
5101
|
+
// "strategyStatus": "NEW",
|
|
5102
|
+
// "strategyType": "STOP",
|
|
5103
|
+
// "origQty": "0.010",
|
|
5104
|
+
// "price": "35000.00",
|
|
5105
|
+
// "reduceOnly": false,
|
|
5106
|
+
// "side": "BUY",
|
|
5107
|
+
// "positionSide": "BOTH",
|
|
5108
|
+
// "stopPrice": "45000.00",
|
|
5109
|
+
// "symbol": "BTCUSDT",
|
|
5110
|
+
// "timeInForce": "GTC",
|
|
5111
|
+
// "bookTime": 1707112625879,
|
|
5112
|
+
// "updateTime": 1707112625879,
|
|
5113
|
+
// "workingType": "CONTRACT_PRICE",
|
|
5114
|
+
// "priceProtect": false,
|
|
5115
|
+
// "goodTillDate": 0,
|
|
5116
|
+
// "selfTradePreventionMode": "NONE"
|
|
5117
|
+
// }
|
|
5118
|
+
//
|
|
5119
|
+
// createOrder: portfolio margin inverse swap and future conditional
|
|
5120
|
+
//
|
|
5121
|
+
// {
|
|
5122
|
+
// "newClientStrategyId": "x-xcKtGhcuc6b86f053bb34933850739",
|
|
5123
|
+
// "strategyId": 1423462,
|
|
5124
|
+
// "strategyStatus": "NEW",
|
|
5125
|
+
// "strategyType": "STOP",
|
|
5126
|
+
// "origQty": "1",
|
|
5127
|
+
// "price": "2000",
|
|
5128
|
+
// "reduceOnly": false,
|
|
5129
|
+
// "side": "BUY",
|
|
5130
|
+
// "positionSide": "BOTH",
|
|
5131
|
+
// "stopPrice": "3000",
|
|
5132
|
+
// "symbol": "ETHUSD_PERP",
|
|
5133
|
+
// "timeInForce": "GTC",
|
|
5134
|
+
// "bookTime": 1707113098840,
|
|
5135
|
+
// "updateTime": 1707113098840,
|
|
5136
|
+
// "workingType": "CONTRACT_PRICE",
|
|
5137
|
+
// "priceProtect": false
|
|
5138
|
+
// }
|
|
5139
|
+
//
|
|
5140
|
+
// createOrder: portfolio margin spot margin
|
|
5141
|
+
//
|
|
5142
|
+
// {
|
|
5143
|
+
// "clientOrderId": "x-R4BD3S82e9ef29d8346440f0b28b86",
|
|
5144
|
+
// "cummulativeQuoteQty": "0.00000000",
|
|
5145
|
+
// "executedQty": "0.00000000",
|
|
5146
|
+
// "fills": [],
|
|
5147
|
+
// "orderId": 24684460474,
|
|
5148
|
+
// "origQty": "0.00100000",
|
|
5149
|
+
// "price": "35000.00000000",
|
|
5150
|
+
// "selfTradePreventionMode": "EXPIRE_MAKER",
|
|
5151
|
+
// "side": "BUY",
|
|
5152
|
+
// "status": "NEW",
|
|
5153
|
+
// "symbol": "BTCUSDT",
|
|
5154
|
+
// "timeInForce": "GTC",
|
|
5155
|
+
// "transactTime": 1707113538870,
|
|
5156
|
+
// "type": "LIMIT"
|
|
5157
|
+
// }
|
|
5005
5158
|
//
|
|
5006
5159
|
const code = this.safeString(order, 'code');
|
|
5007
5160
|
if (code !== undefined) {
|
|
5008
5161
|
// cancelOrders/createOrders might have a partial success
|
|
5009
5162
|
return this.safeOrder({ 'info': order, 'status': 'rejected' }, market);
|
|
5010
5163
|
}
|
|
5011
|
-
const status = this.parseOrderStatus(this.
|
|
5164
|
+
const status = this.parseOrderStatus(this.safeString2(order, 'status', 'strategyStatus'));
|
|
5012
5165
|
const marketId = this.safeString(order, 'symbol');
|
|
5013
5166
|
const marketType = ('closePosition' in order) ? 'contract' : 'spot';
|
|
5014
5167
|
const symbol = this.safeSymbol(marketId, market, undefined, marketType);
|
|
@@ -5035,11 +5188,9 @@ class binance extends binance$1 {
|
|
|
5035
5188
|
// Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
|
|
5036
5189
|
let cost = this.safeString2(order, 'cummulativeQuoteQty', 'cumQuote');
|
|
5037
5190
|
cost = this.safeString(order, 'cumBase', cost);
|
|
5038
|
-
const id = this.safeString(order, 'orderId');
|
|
5039
5191
|
let type = this.safeStringLower(order, 'type');
|
|
5040
5192
|
const side = this.safeStringLower(order, 'side');
|
|
5041
5193
|
const fills = this.safeValue(order, 'fills', []);
|
|
5042
|
-
const clientOrderId = this.safeString(order, 'clientOrderId');
|
|
5043
5194
|
let timeInForce = this.safeString(order, 'timeInForce');
|
|
5044
5195
|
if (timeInForce === 'GTX') {
|
|
5045
5196
|
// GTX means "Good Till Crossing" and is an equivalent way of saying Post Only
|
|
@@ -5062,8 +5213,8 @@ class binance extends binance$1 {
|
|
|
5062
5213
|
}
|
|
5063
5214
|
return this.safeOrder({
|
|
5064
5215
|
'info': order,
|
|
5065
|
-
'id':
|
|
5066
|
-
'clientOrderId': clientOrderId,
|
|
5216
|
+
'id': this.safeString2(order, 'orderId', 'strategyId'),
|
|
5217
|
+
'clientOrderId': this.safeString2(order, 'clientOrderId', 'newClientStrategyId'),
|
|
5067
5218
|
'timestamp': timestamp,
|
|
5068
5219
|
'datetime': this.iso8601(timestamp),
|
|
5069
5220
|
'lastTradeTimestamp': lastTradeTimestamp,
|
|
@@ -5177,50 +5328,105 @@ class binance extends binance$1 {
|
|
|
5177
5328
|
* @see https://binance-docs.github.io/apidocs/voptions/en/#new-order-trade
|
|
5178
5329
|
* @see https://binance-docs.github.io/apidocs/spot/en/#new-order-using-sor-trade
|
|
5179
5330
|
* @see https://binance-docs.github.io/apidocs/spot/en/#test-new-order-using-sor-trade
|
|
5331
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-um-order-trade
|
|
5332
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-cm-order-trade
|
|
5333
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-margin-order-trade
|
|
5334
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-um-conditional-order-trade
|
|
5335
|
+
* @see https://binance-docs.github.io/apidocs/pm/en/#new-cm-conditional-order-trade
|
|
5180
5336
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
5181
5337
|
* @param {string} type 'market' or 'limit' or 'STOP_LOSS' or 'STOP_LOSS_LIMIT' or 'TAKE_PROFIT' or 'TAKE_PROFIT_LIMIT' or 'STOP'
|
|
5182
5338
|
* @param {string} side 'buy' or 'sell'
|
|
5183
|
-
* @param {float} amount how much of
|
|
5184
|
-
* @param {float} [price] the price
|
|
5339
|
+
* @param {float} amount how much of you want to trade in units of the base currency
|
|
5340
|
+
* @param {float} [price] the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
5185
5341
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5342
|
+
* @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.
|
|
5186
5343
|
* @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
|
|
5187
5344
|
* @param {boolean} [params.sor] *spot only* whether to use SOR (Smart Order Routing) or not, default is false
|
|
5188
5345
|
* @param {boolean} [params.test] *spot only* whether to use the test endpoint or not, default is false
|
|
5189
5346
|
* @param {float} [params.trailingPercent] the percent to trail away from the current market price
|
|
5190
5347
|
* @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
|
|
5348
|
+
* @param {float} [params.triggerPrice] the price that a trigger order is triggered at
|
|
5349
|
+
* @param {float} [params.stopLossPrice] the price that a stop loss order is triggered at
|
|
5350
|
+
* @param {float} [params.takeProfitPrice] the price that a take profit order is triggered at
|
|
5351
|
+
* @param {boolean} [params.portfolioMargin] set to true if you would like to create an order in a portfolio margin account
|
|
5191
5352
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
5192
5353
|
*/
|
|
5193
5354
|
await this.loadMarkets();
|
|
5194
5355
|
const market = this.market(symbol);
|
|
5195
5356
|
const marketType = this.safeString(params, 'type', market['type']);
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5357
|
+
let marginMode = undefined;
|
|
5358
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
5359
|
+
let isPortfolioMargin = undefined;
|
|
5360
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'createOrder', 'papi', 'portfolioMargin', false);
|
|
5361
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
5362
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice');
|
|
5363
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
5364
|
+
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5365
|
+
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5366
|
+
const isStopLoss = stopLossPrice !== undefined;
|
|
5367
|
+
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5368
|
+
const isConditional = (triggerPrice !== undefined) || isTrailingPercentOrder || isStopLoss || isTakeProfit;
|
|
5369
|
+
const sor = this.safeBool2(params, 'sor', 'SOR', false);
|
|
5370
|
+
const test = this.safeBool(params, 'test', false);
|
|
5371
|
+
params = this.omit(params, ['sor', 'SOR', 'test']);
|
|
5372
|
+
if (isPortfolioMargin) {
|
|
5373
|
+
params['portfolioMargin'] = isPortfolioMargin;
|
|
5374
|
+
}
|
|
5199
5375
|
const request = this.createOrderRequest(symbol, type, side, amount, price, params);
|
|
5200
|
-
let
|
|
5201
|
-
if (
|
|
5202
|
-
|
|
5376
|
+
let response = undefined;
|
|
5377
|
+
if (market['option']) {
|
|
5378
|
+
response = await this.eapiPrivatePostOrder(request);
|
|
5379
|
+
}
|
|
5380
|
+
else if (sor) {
|
|
5381
|
+
if (test) {
|
|
5382
|
+
response = await this.privatePostSorOrderTest(request);
|
|
5383
|
+
}
|
|
5384
|
+
else {
|
|
5385
|
+
response = await this.privatePostSorOrder(request);
|
|
5386
|
+
}
|
|
5203
5387
|
}
|
|
5204
5388
|
else if (market['linear']) {
|
|
5205
|
-
|
|
5389
|
+
if (isPortfolioMargin) {
|
|
5390
|
+
if (isConditional) {
|
|
5391
|
+
response = await this.papiPostUmConditionalOrder(request);
|
|
5392
|
+
}
|
|
5393
|
+
else {
|
|
5394
|
+
response = await this.papiPostUmOrder(request);
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
else {
|
|
5398
|
+
response = await this.fapiPrivatePostOrder(request);
|
|
5399
|
+
}
|
|
5206
5400
|
}
|
|
5207
5401
|
else if (market['inverse']) {
|
|
5208
|
-
|
|
5402
|
+
if (isPortfolioMargin) {
|
|
5403
|
+
if (isConditional) {
|
|
5404
|
+
response = await this.papiPostCmConditionalOrder(request);
|
|
5405
|
+
}
|
|
5406
|
+
else {
|
|
5407
|
+
response = await this.papiPostCmOrder(request);
|
|
5408
|
+
}
|
|
5409
|
+
}
|
|
5410
|
+
else {
|
|
5411
|
+
response = await this.dapiPrivatePostOrder(request);
|
|
5412
|
+
}
|
|
5209
5413
|
}
|
|
5210
5414
|
else if (marketType === 'margin' || marginMode !== undefined) {
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5415
|
+
if (isPortfolioMargin) {
|
|
5416
|
+
response = await this.papiPostMarginOrder(request);
|
|
5417
|
+
}
|
|
5418
|
+
else {
|
|
5419
|
+
response = await this.sapiPostMarginOrder(request);
|
|
5420
|
+
}
|
|
5215
5421
|
}
|
|
5216
|
-
|
|
5217
|
-
if (market['spot'] || marketType === 'margin') {
|
|
5218
|
-
const test = this.safeBool(query, 'test', false);
|
|
5422
|
+
else {
|
|
5219
5423
|
if (test) {
|
|
5220
|
-
|
|
5424
|
+
response = await this.privatePostOrderTest(request);
|
|
5425
|
+
}
|
|
5426
|
+
else {
|
|
5427
|
+
response = await this.privatePostOrder(request);
|
|
5221
5428
|
}
|
|
5222
5429
|
}
|
|
5223
|
-
const response = await this[method](request);
|
|
5224
5430
|
return this.parseOrder(response, market);
|
|
5225
5431
|
}
|
|
5226
5432
|
createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
|
|
@@ -5228,16 +5434,13 @@ class binance extends binance$1 {
|
|
|
5228
5434
|
* @method
|
|
5229
5435
|
* @ignore
|
|
5230
5436
|
* @name binance#createOrderRequest
|
|
5231
|
-
* @description helper function to build request
|
|
5437
|
+
* @description helper function to build the request
|
|
5232
5438
|
* @param {string} symbol unified symbol of the market to create an order in
|
|
5233
|
-
* @param {string} type 'market' or 'limit'
|
|
5439
|
+
* @param {string} type 'market' or 'limit'
|
|
5234
5440
|
* @param {string} side 'buy' or 'sell'
|
|
5235
|
-
* @param {float} amount how much
|
|
5236
|
-
* @param {float
|
|
5237
|
-
* @param {object} params extra parameters specific to the exchange API endpoint
|
|
5238
|
-
* @param {string|undefined} params.marginMode 'cross' or 'isolated', for spot margin trading
|
|
5239
|
-
* @param {float} [params.trailingPercent] the percent to trail away from the current market price
|
|
5240
|
-
* @param {float} [params.trailingTriggerPrice] the price to trigger a trailing order, default uses the price argument
|
|
5441
|
+
* @param {float} amount how much you want to trade in units of the base currency
|
|
5442
|
+
* @param {float} [price] the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
|
5443
|
+
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
5241
5444
|
* @returns {object} request to be sent to the exchange
|
|
5242
5445
|
*/
|
|
5243
5446
|
const market = this.market(symbol);
|
|
@@ -5246,35 +5449,54 @@ class binance extends binance$1 {
|
|
|
5246
5449
|
const initialUppercaseType = type.toUpperCase();
|
|
5247
5450
|
const isMarketOrder = initialUppercaseType === 'MARKET';
|
|
5248
5451
|
const isLimitOrder = initialUppercaseType === 'LIMIT';
|
|
5249
|
-
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5250
|
-
const triggerPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
|
|
5251
|
-
const stopLossPrice = this.safeValue(params, 'stopLossPrice', triggerPrice); // fallback to stopLoss
|
|
5252
|
-
const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
|
|
5253
|
-
const trailingDelta = this.safeValue(params, 'trailingDelta');
|
|
5254
|
-
const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activationPrice', this.numberToString(price));
|
|
5255
|
-
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5256
|
-
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5257
|
-
const isStopLoss = stopLossPrice !== undefined || trailingDelta !== undefined;
|
|
5258
|
-
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5259
|
-
params = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent']);
|
|
5260
|
-
const [marginMode, query] = this.handleMarginModeAndParams('createOrder', params);
|
|
5261
5452
|
const request = {
|
|
5262
5453
|
'symbol': market['id'],
|
|
5263
5454
|
'side': side.toUpperCase(),
|
|
5264
5455
|
};
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5456
|
+
let isPortfolioMargin = undefined;
|
|
5457
|
+
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'createOrder', 'papi', 'portfolioMargin', false);
|
|
5458
|
+
let marginMode = undefined;
|
|
5459
|
+
[marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
|
|
5460
|
+
if ((marketType === 'margin') || (marginMode !== undefined) || market['option']) {
|
|
5461
|
+
// for swap and future reduceOnly is a string that cant be sent with close position set to true or in hedge mode
|
|
5462
|
+
const reduceOnly = this.safeBool(params, 'reduceOnly', false);
|
|
5463
|
+
params = this.omit(params, 'reduceOnly');
|
|
5464
|
+
if (market['option']) {
|
|
5465
|
+
request['reduceOnly'] = reduceOnly;
|
|
5466
|
+
}
|
|
5467
|
+
else {
|
|
5468
|
+
if (reduceOnly) {
|
|
5469
|
+
request['sideEffectType'] = 'AUTO_REPAY';
|
|
5470
|
+
}
|
|
5269
5471
|
}
|
|
5270
5472
|
}
|
|
5271
|
-
if (
|
|
5272
|
-
const
|
|
5273
|
-
if (
|
|
5274
|
-
|
|
5275
|
-
|
|
5473
|
+
if (!isPortfolioMargin) {
|
|
5474
|
+
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5475
|
+
if (market['spot'] || marketType === 'margin') {
|
|
5476
|
+
// only supported for spot/margin api (all margin markets are spot markets)
|
|
5477
|
+
if (postOnly) {
|
|
5478
|
+
type = 'LIMIT_MAKER';
|
|
5479
|
+
}
|
|
5480
|
+
if (marginMode === 'isolated') {
|
|
5481
|
+
request['isIsolated'] = true;
|
|
5482
|
+
}
|
|
5483
|
+
}
|
|
5484
|
+
if (market['contract'] && postOnly) {
|
|
5485
|
+
request['timeInForce'] = 'GTX';
|
|
5276
5486
|
}
|
|
5277
5487
|
}
|
|
5488
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
5489
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice', triggerPrice); // fallback to stopLoss
|
|
5490
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
5491
|
+
const trailingDelta = this.safeString(params, 'trailingDelta');
|
|
5492
|
+
const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activationPrice', this.numberToString(price));
|
|
5493
|
+
const trailingPercent = this.safeString2(params, 'trailingPercent', 'callbackRate');
|
|
5494
|
+
const isTrailingPercentOrder = trailingPercent !== undefined;
|
|
5495
|
+
const isStopLoss = stopLossPrice !== undefined || trailingDelta !== undefined;
|
|
5496
|
+
const isTakeProfit = takeProfitPrice !== undefined;
|
|
5497
|
+
const isTriggerOrder = triggerPrice !== undefined;
|
|
5498
|
+
const isConditional = isTriggerOrder || isTrailingPercentOrder || isStopLoss || isTakeProfit;
|
|
5499
|
+
const isPortfolioMarginConditional = (isPortfolioMargin && isConditional);
|
|
5278
5500
|
let uppercaseType = type.toUpperCase();
|
|
5279
5501
|
let stopPrice = undefined;
|
|
5280
5502
|
if (isTrailingPercentOrder) {
|
|
@@ -5304,24 +5526,14 @@ class binance extends binance$1 {
|
|
|
5304
5526
|
uppercaseType = market['contract'] ? 'TAKE_PROFIT' : 'TAKE_PROFIT_LIMIT';
|
|
5305
5527
|
}
|
|
5306
5528
|
}
|
|
5307
|
-
if (marginMode === 'isolated') {
|
|
5308
|
-
request['isIsolated'] = true;
|
|
5309
|
-
}
|
|
5310
|
-
if (clientOrderId === undefined) {
|
|
5311
|
-
const broker = this.safeValue(this.options, 'broker', {});
|
|
5312
|
-
const defaultId = (market['contract']) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
|
|
5313
|
-
const brokerId = this.safeString(broker, marketType, defaultId);
|
|
5314
|
-
request['newClientOrderId'] = brokerId + this.uuid22();
|
|
5315
|
-
}
|
|
5316
|
-
else {
|
|
5317
|
-
request['newClientOrderId'] = clientOrderId;
|
|
5318
|
-
}
|
|
5319
5529
|
if ((marketType === 'spot') || (marketType === 'margin')) {
|
|
5320
|
-
request['newOrderRespType'] = this.
|
|
5530
|
+
request['newOrderRespType'] = this.safeString(this.options['newOrderRespType'], type, 'RESULT'); // 'ACK' for order id, 'RESULT' for full order or 'FULL' for order with fills
|
|
5321
5531
|
}
|
|
5322
5532
|
else {
|
|
5323
5533
|
// swap, futures and options
|
|
5324
|
-
|
|
5534
|
+
if (!isPortfolioMargin) {
|
|
5535
|
+
request['newOrderRespType'] = 'RESULT'; // "ACK", "RESULT", default "ACK"
|
|
5536
|
+
}
|
|
5325
5537
|
}
|
|
5326
5538
|
if (market['option']) {
|
|
5327
5539
|
if (type === 'market') {
|
|
@@ -5329,7 +5541,7 @@ class binance extends binance$1 {
|
|
|
5329
5541
|
}
|
|
5330
5542
|
}
|
|
5331
5543
|
else {
|
|
5332
|
-
const validOrderTypes = this.
|
|
5544
|
+
const validOrderTypes = this.safeList(market['info'], 'orderTypes');
|
|
5333
5545
|
if (!this.inArray(uppercaseType, validOrderTypes)) {
|
|
5334
5546
|
if (initialUppercaseType !== uppercaseType) {
|
|
5335
5547
|
throw new errors.InvalidOrder(this.id + ' stopPrice parameter is not allowed for ' + symbol + ' ' + type + ' orders');
|
|
@@ -5339,7 +5551,18 @@ class binance extends binance$1 {
|
|
|
5339
5551
|
}
|
|
5340
5552
|
}
|
|
5341
5553
|
}
|
|
5342
|
-
|
|
5554
|
+
const clientOrderIdRequest = isPortfolioMarginConditional ? 'newClientStrategyId' : 'newClientOrderId';
|
|
5555
|
+
if (clientOrderId === undefined) {
|
|
5556
|
+
const broker = this.safeDict(this.options, 'broker', {});
|
|
5557
|
+
const defaultId = (market['contract']) ? 'x-xcKtGhcu' : 'x-R4BD3S82';
|
|
5558
|
+
const brokerId = this.safeString(broker, marketType, defaultId);
|
|
5559
|
+
request[clientOrderIdRequest] = brokerId + this.uuid22();
|
|
5560
|
+
}
|
|
5561
|
+
else {
|
|
5562
|
+
request[clientOrderIdRequest] = clientOrderId;
|
|
5563
|
+
}
|
|
5564
|
+
const typeRequest = isPortfolioMarginConditional ? 'strategyType' : 'type';
|
|
5565
|
+
request[typeRequest] = uppercaseType;
|
|
5343
5566
|
// additional required fields depending on the order type
|
|
5344
5567
|
let timeInForceIsRequired = false;
|
|
5345
5568
|
let priceIsRequired = false;
|
|
@@ -5367,9 +5590,9 @@ class binance extends binance$1 {
|
|
|
5367
5590
|
//
|
|
5368
5591
|
if (uppercaseType === 'MARKET') {
|
|
5369
5592
|
if (market['spot']) {
|
|
5370
|
-
const quoteOrderQty = this.
|
|
5593
|
+
const quoteOrderQty = this.safeBool(this.options, 'quoteOrderQty', true);
|
|
5371
5594
|
if (quoteOrderQty) {
|
|
5372
|
-
const quoteOrderQtyNew = this.
|
|
5595
|
+
const quoteOrderQtyNew = this.safeString2(params, 'quoteOrderQty', 'cost');
|
|
5373
5596
|
const precision = market['precision']['price'];
|
|
5374
5597
|
if (quoteOrderQtyNew !== undefined) {
|
|
5375
5598
|
request['quoteOrderQty'] = this.decimalToPrecision(quoteOrderQtyNew, number.TRUNCATE, precision, this.precisionMode);
|
|
@@ -5420,7 +5643,7 @@ class binance extends binance$1 {
|
|
|
5420
5643
|
priceIsRequired = true;
|
|
5421
5644
|
}
|
|
5422
5645
|
else if ((uppercaseType === 'STOP_MARKET') || (uppercaseType === 'TAKE_PROFIT_MARKET')) {
|
|
5423
|
-
const closePosition = this.
|
|
5646
|
+
const closePosition = this.safeBool(params, 'closePosition');
|
|
5424
5647
|
if (closePosition === undefined) {
|
|
5425
5648
|
quantityIsRequired = true;
|
|
5426
5649
|
}
|
|
@@ -5433,7 +5656,13 @@ class binance extends binance$1 {
|
|
|
5433
5656
|
}
|
|
5434
5657
|
}
|
|
5435
5658
|
if (quantityIsRequired) {
|
|
5436
|
-
|
|
5659
|
+
// portfolio margin has a different amount precision
|
|
5660
|
+
if (isPortfolioMargin) {
|
|
5661
|
+
request['quantity'] = this.parseToNumeric(amount);
|
|
5662
|
+
}
|
|
5663
|
+
else {
|
|
5664
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
5665
|
+
}
|
|
5437
5666
|
}
|
|
5438
5667
|
if (priceIsRequired) {
|
|
5439
5668
|
if (price === undefined) {
|
|
@@ -5444,9 +5673,6 @@ class binance extends binance$1 {
|
|
|
5444
5673
|
if (timeInForceIsRequired) {
|
|
5445
5674
|
request['timeInForce'] = this.options['defaultTimeInForce']; // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
|
5446
5675
|
}
|
|
5447
|
-
if (market['contract'] && postOnly) {
|
|
5448
|
-
request['timeInForce'] = 'GTX';
|
|
5449
|
-
}
|
|
5450
5676
|
if (stopPriceIsRequired) {
|
|
5451
5677
|
if (market['contract']) {
|
|
5452
5678
|
if (stopPrice === undefined) {
|
|
@@ -5463,11 +5689,26 @@ class binance extends binance$1 {
|
|
|
5463
5689
|
request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
|
|
5464
5690
|
}
|
|
5465
5691
|
}
|
|
5692
|
+
if (!isPortfolioMargin) {
|
|
5693
|
+
const postOnly = this.isPostOnly(isMarketOrder, initialUppercaseType === 'LIMIT_MAKER', params);
|
|
5694
|
+
if (market['spot'] || marketType === 'margin') {
|
|
5695
|
+
// only supported for spot/margin api (all margin markets are spot markets)
|
|
5696
|
+
if (postOnly) {
|
|
5697
|
+
type = 'LIMIT_MAKER';
|
|
5698
|
+
}
|
|
5699
|
+
if (marginMode === 'isolated') {
|
|
5700
|
+
request['isIsolated'] = true;
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
if (market['contract'] && postOnly) {
|
|
5704
|
+
request['timeInForce'] = 'GTX';
|
|
5705
|
+
}
|
|
5706
|
+
}
|
|
5466
5707
|
// remove timeInForce from params because PO is only used by this.isPostOnly and it's not a valid value for Binance
|
|
5467
5708
|
if (this.safeString(params, 'timeInForce') === 'PO') {
|
|
5468
|
-
params = this.omit(params,
|
|
5709
|
+
params = this.omit(params, 'timeInForce');
|
|
5469
5710
|
}
|
|
5470
|
-
const requestParams = this.omit(params, ['
|
|
5711
|
+
const requestParams = this.omit(params, ['type', 'newClientOrderId', 'clientOrderId', 'postOnly', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'triggerPrice', 'trailingTriggerPrice', 'trailingPercent', 'quoteOrderQty', 'cost', 'test']);
|
|
5471
5712
|
return this.extend(request, requestParams);
|
|
5472
5713
|
}
|
|
5473
5714
|
async createMarketOrderWithCost(symbol, side, cost, params = {}) {
|