ccxt 4.1.49 → 4.1.50

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/js/src/htx.js CHANGED
@@ -41,6 +41,7 @@ export default class htx extends Exchange {
41
41
  'cancelOrders': true,
42
42
  'createDepositAddress': undefined,
43
43
  'createOrder': true,
44
+ 'createOrders': true,
44
45
  'createReduceOnlyOrder': false,
45
46
  'createStopLimitOrder': true,
46
47
  'createStopMarketOrder': true,
@@ -635,7 +636,7 @@ export default class htx extends Exchange {
635
636
  // Future Trade Interface
636
637
  'api/v1/contract-cancel-after': 1,
637
638
  'api/v1/contract_order': 1,
638
- 'v1/contract_batchorder': 1,
639
+ 'api/v1/contract_batchorder': 1,
639
640
  'api/v1/contract_cancel': 1,
640
641
  'api/v1/contract_cancelall': 1,
641
642
  'api/v1/contract_switch_lever_rate': 1,
@@ -4708,7 +4709,41 @@ export default class htx extends Exchange {
4708
4709
  // "trade_partition": "USDT"
4709
4710
  // }
4710
4711
  //
4711
- const id = this.safeString2(order, 'id', 'order_id_str');
4712
+ // spot: createOrders
4713
+ //
4714
+ // [
4715
+ // {
4716
+ // "order-id": 936847569789079,
4717
+ // "client-order-id": "AA03022abc3a55e82c-0087-4fc2-beac-112fdebb1ee9"
4718
+ // },
4719
+ // {
4720
+ // "client-order-id": "AA03022abcdb3baefb-3cfa-4891-8009-082b3d46ca82",
4721
+ // "err-code": "account-frozen-balance-insufficient-error",
4722
+ // "err-msg": "trade account balance is not enough, left: `89`"
4723
+ // }
4724
+ // ]
4725
+ //
4726
+ // swap and future: createOrders
4727
+ //
4728
+ // [
4729
+ // {
4730
+ // "index": 2,
4731
+ // "err_code": 1047,
4732
+ // "err_msg": "Insufficient margin available."
4733
+ // },
4734
+ // {
4735
+ // "order_id": 1172923090632953857,
4736
+ // "index": 1,
4737
+ // "order_id_str": "1172923090632953857"
4738
+ // }
4739
+ // ]
4740
+ //
4741
+ const rejectedCreateOrders = this.safeString2(order, 'err_code', 'err-code');
4742
+ let status = this.parseOrderStatus(this.safeString2(order, 'state', 'status'));
4743
+ if (rejectedCreateOrders !== undefined) {
4744
+ status = 'rejected';
4745
+ }
4746
+ const id = this.safeStringN(order, ['id', 'order_id_str', 'order-id']);
4712
4747
  let side = this.safeString(order, 'direction');
4713
4748
  let type = this.safeString(order, 'order_price_type');
4714
4749
  if ('type' in order) {
@@ -4716,7 +4751,6 @@ export default class htx extends Exchange {
4716
4751
  side = orderType[0];
4717
4752
  type = orderType[1];
4718
4753
  }
4719
- const status = this.parseOrderStatus(this.safeString2(order, 'state', 'status'));
4720
4754
  const marketId = this.safeString2(order, 'contract_code', 'symbol');
4721
4755
  market = this.safeMarket(marketId, market);
4722
4756
  const timestamp = this.safeIntegerN(order, ['created_at', 'created-at', 'create_date']);
@@ -4759,7 +4793,10 @@ export default class htx extends Exchange {
4759
4793
  const average = this.safeString(order, 'trade_avg_price');
4760
4794
  const trades = this.safeValue(order, 'trades');
4761
4795
  const reduceOnlyInteger = this.safeInteger(order, 'reduce_only');
4762
- const reduceOnly = (reduceOnlyInteger === 0) ? false : true;
4796
+ let reduceOnly = undefined;
4797
+ if (reduceOnlyInteger !== undefined) {
4798
+ reduceOnly = (reduceOnlyInteger === 0) ? false : true;
4799
+ }
4763
4800
  return this.safeOrder({
4764
4801
  'info': order,
4765
4802
  'id': id,
@@ -4786,61 +4823,20 @@ export default class htx extends Exchange {
4786
4823
  'trades': trades,
4787
4824
  }, market);
4788
4825
  }
4789
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
4826
+ async createSpotOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
4790
4827
  /**
4791
4828
  * @method
4792
- * @name huobi#createOrder
4793
- * @description create a trade order
4794
- * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order // spot, margin
4795
- * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order // coin-m swap
4796
- * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order // coin-m swap trigger
4797
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order // usdt-m swap cross
4798
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order // usdt-m swap cross trigger
4799
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order // usdt-m swap isolated
4800
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order // usdt-m swap isolated trigger
4801
- * @see https://huobiapi.github.io/docs/dm/v1/en/#place-an-order // coin-m futures
4802
- * @see https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order // coin-m futures contract trigger
4803
- * @param {string} symbol unified symbol of the market to create an order in
4804
- * @param {string} type 'market' or 'limit'
4805
- * @param {string} side 'buy' or 'sell'
4806
- * @param {float} amount how much of currency you want to trade in units of base currency
4807
- * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4808
- * @param {object} [params] extra parameters specific to the huobi api endpoint
4809
- * @param {float} [params.stopPrice] the price a trigger order is triggered at
4810
- * @param {string} [params.triggerType] *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
4811
- * @param {float} [params.stopLossPrice] *contract only* the price a stop-loss order is triggered at
4812
- * @param {float} [params.takeProfitPrice] *contract only* the price a take-profit order is triggered at
4813
- * @param {string} [params.operator] *spot and margin only* gte or lte, trigger price condition
4814
- * @param {string} [params.offset] *contract only* 'open', 'close', or 'both', required in hedge mode
4815
- * @param {bool} [params.postOnly] *contract only* true or false
4816
- * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
4817
- * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4818
- * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4819
- */
4820
- await this.loadMarkets();
4821
- const market = this.market(symbol);
4822
- const [marketType, query] = this.handleMarketTypeAndParams('createOrder', market, params);
4823
- if (marketType === 'spot') {
4824
- return await this.createSpotOrder(symbol, type, side, amount, price, query);
4825
- }
4826
- else {
4827
- return await this.createContractOrder(symbol, type, side, amount, price, query);
4828
- }
4829
- }
4830
- async createSpotOrder(symbol, type, side, amount, price = undefined, params = {}) {
4831
- /**
4832
4829
  * @ignore
4833
- * @method
4834
- * @name huobi#createSpotOrder
4835
- * @description create a spot trade order
4836
- * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order
4830
+ * @name htx#createSpotOrderRequest
4831
+ * @description helper function to build request
4837
4832
  * @param {string} symbol unified symbol of the market to create an order in
4838
4833
  * @param {string} type 'market' or 'limit'
4839
4834
  * @param {string} side 'buy' or 'sell'
4840
- * @param {float} amount how much of currency you want to trade in units of base currency
4835
+ * @param {float} amount how much you want to trade in units of the base currency
4841
4836
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4842
- * @param {object} params extra parameters specific to the huobi api endpoint
4843
- * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4837
+ * @param {object} [params] extra parameters specific to the htx api endpoint
4838
+ * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4839
+ * @returns {object} request to be sent to the exchange
4844
4840
  */
4845
4841
  await this.loadMarkets();
4846
4842
  await this.loadAccounts();
@@ -4942,52 +4938,22 @@ export default class htx extends Exchange {
4942
4938
  request['price'] = this.priceToPrecision(symbol, price);
4943
4939
  }
4944
4940
  params = this.omit(params, ['stopPrice', 'stop-price', 'clientOrderId', 'client-order-id', 'operator', 'timeInForce']);
4945
- const response = await this.spotPrivatePostV1OrderOrdersPlace(this.extend(request, params));
4946
- //
4947
- // spot
4948
- //
4949
- // {"status":"ok","data":"438398393065481"}
4950
- //
4951
- const id = this.safeString(response, 'data');
4952
- return this.safeOrder({
4953
- 'info': response,
4954
- 'id': id,
4955
- 'timestamp': undefined,
4956
- 'datetime': undefined,
4957
- 'lastTradeTimestamp': undefined,
4958
- 'status': undefined,
4959
- 'symbol': undefined,
4960
- 'type': type,
4961
- 'side': side,
4962
- 'price': price,
4963
- 'amount': amount,
4964
- 'filled': undefined,
4965
- 'remaining': undefined,
4966
- 'cost': undefined,
4967
- 'trades': undefined,
4968
- 'fee': undefined,
4969
- 'clientOrderId': undefined,
4970
- 'average': undefined,
4971
- }, market);
4941
+ return this.extend(request, params);
4972
4942
  }
4973
- async createContractOrder(symbol, type, side, amount, price = undefined, params = {}) {
4943
+ createContractOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
4974
4944
  /**
4975
- * @ignore
4976
4945
  * @method
4977
- * @name huobi#createContractOrder
4978
- * @description create a contract trade order
4979
- * @see https://huobiapi.github.io/docs/dm/v1/en/#place-an-order
4980
- * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order
4981
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order
4982
- * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order
4946
+ * @ignore
4947
+ * @name htx#createContractOrderRequest
4948
+ * @description helper function to build request
4983
4949
  * @param {string} symbol unified symbol of the market to create an order in
4984
4950
  * @param {string} type 'market' or 'limit'
4985
4951
  * @param {string} side 'buy' or 'sell'
4986
- * @param {float} amount how much of currency you want to trade in units of base currency
4952
+ * @param {float} amount how much you want to trade in units of the base currency
4987
4953
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
4988
- * @param {object} params extra parameters specific to the huobi api endpoint
4954
+ * @param {object} [params] extra parameters specific to the htx api endpoint
4989
4955
  * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
4990
- * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
4956
+ * @returns {object} request to be sent to the exchange
4991
4957
  */
4992
4958
  const market = this.market(symbol);
4993
4959
  const request = {
@@ -5059,63 +5025,117 @@ export default class htx extends Exchange {
5059
5025
  request['lever_rate'] = leverRate;
5060
5026
  request['order_price_type'] = type;
5061
5027
  }
5062
- params = this.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce']);
5063
5028
  const broker = this.safeValue(this.options, 'broker', {});
5064
5029
  const brokerId = this.safeString(broker, 'id');
5065
5030
  request['channel_code'] = brokerId;
5031
+ params = this.omit(params, ['reduceOnly', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'triggerType', 'leverRate', 'timeInForce']);
5032
+ return this.extend(request, params);
5033
+ }
5034
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
5035
+ /**
5036
+ * @method
5037
+ * @name huobi#createOrder
5038
+ * @description create a trade order
5039
+ * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-new-order // spot, margin
5040
+ * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-an-order // coin-m swap
5041
+ * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-trigger-order // coin-m swap trigger
5042
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-an-order // usdt-m swap cross
5043
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-trigger-order // usdt-m swap cross trigger
5044
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-an-order // usdt-m swap isolated
5045
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-trigger-order // usdt-m swap isolated trigger
5046
+ * @see https://huobiapi.github.io/docs/dm/v1/en/#place-an-order // coin-m futures
5047
+ * @see https://huobiapi.github.io/docs/dm/v1/en/#place-trigger-order // coin-m futures contract trigger
5048
+ * @param {string} symbol unified symbol of the market to create an order in
5049
+ * @param {string} type 'market' or 'limit'
5050
+ * @param {string} side 'buy' or 'sell'
5051
+ * @param {float} amount how much you want to trade in units of the base currency
5052
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
5053
+ * @param {object} [params] extra parameters specific to the huobi api endpoint
5054
+ * @param {float} [params.stopPrice] the price a trigger order is triggered at
5055
+ * @param {string} [params.triggerType] *contract trigger orders only* ge: greater than or equal to, le: less than or equal to
5056
+ * @param {float} [params.stopLossPrice] *contract only* the price a stop-loss order is triggered at
5057
+ * @param {float} [params.takeProfitPrice] *contract only* the price a take-profit order is triggered at
5058
+ * @param {string} [params.operator] *spot and margin only* gte or lte, trigger price condition
5059
+ * @param {string} [params.offset] *contract only* 'open', 'close', or 'both', required in hedge mode
5060
+ * @param {bool} [params.postOnly] *contract only* true or false
5061
+ * @param {int} [params.leverRate] *contract only* required for all contract orders except tpsl, leverage greater than 20x requires prior approval of high-leverage agreement
5062
+ * @param {string} [params.timeInForce] supports 'IOC' and 'FOK'
5063
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
5064
+ */
5065
+ await this.loadMarkets();
5066
+ const market = this.market(symbol);
5067
+ const triggerPrice = this.safeNumber2(params, 'stopPrice', 'trigger_price');
5068
+ const stopLossTriggerPrice = this.safeNumber2(params, 'stopLossPrice', 'sl_trigger_price');
5069
+ const takeProfitTriggerPrice = this.safeNumber2(params, 'takeProfitPrice', 'tp_trigger_price');
5070
+ const isStop = triggerPrice !== undefined;
5071
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
5072
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
5066
5073
  let response = undefined;
5067
- if (market['linear']) {
5068
- let marginMode = undefined;
5069
- [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
5070
- marginMode = (marginMode === undefined) ? 'cross' : marginMode;
5071
- if (marginMode === 'isolated') {
5072
- if (isStop) {
5073
- response = await this.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(this.extend(request, params));
5074
- }
5075
- else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5076
- response = await this.contractPrivatePostLinearSwapApiV1SwapTpslOrder(this.extend(request, params));
5077
- }
5078
- else {
5079
- response = await this.contractPrivatePostLinearSwapApiV1SwapOrder(this.extend(request, params));
5080
- }
5081
- }
5082
- else if (marginMode === 'cross') {
5083
- if (isStop) {
5084
- response = await this.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(this.extend(request, params));
5085
- }
5086
- else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5087
- response = await this.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(this.extend(request, params));
5088
- }
5089
- else {
5090
- response = await this.contractPrivatePostLinearSwapApiV1SwapCrossOrder(this.extend(request, params));
5091
- }
5092
- }
5074
+ if (market['spot']) {
5075
+ const spotRequest = await this.createSpotOrderRequest(symbol, type, side, amount, price, params);
5076
+ response = await this.spotPrivatePostV1OrderOrdersPlace(spotRequest);
5093
5077
  }
5094
- else if (market['inverse']) {
5095
- if (market['swap']) {
5096
- if (isStop) {
5097
- response = await this.contractPrivatePostSwapApiV1SwapTriggerOrder(this.extend(request, params));
5098
- }
5099
- else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5100
- response = await this.contractPrivatePostSwapApiV1SwapTpslOrder(this.extend(request, params));
5078
+ else {
5079
+ const contractRequest = this.createContractOrderRequest(symbol, type, side, amount, price, params);
5080
+ if (market['linear']) {
5081
+ let marginMode = undefined;
5082
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
5083
+ marginMode = (marginMode === undefined) ? 'cross' : marginMode;
5084
+ if (marginMode === 'isolated') {
5085
+ if (isStop) {
5086
+ response = await this.contractPrivatePostLinearSwapApiV1SwapTriggerOrder(contractRequest);
5087
+ }
5088
+ else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5089
+ response = await this.contractPrivatePostLinearSwapApiV1SwapTpslOrder(contractRequest);
5090
+ }
5091
+ else {
5092
+ response = await this.contractPrivatePostLinearSwapApiV1SwapOrder(contractRequest);
5093
+ }
5101
5094
  }
5102
- else {
5103
- response = await this.contractPrivatePostSwapApiV1SwapOrder(this.extend(request, params));
5095
+ else if (marginMode === 'cross') {
5096
+ if (isStop) {
5097
+ response = await this.contractPrivatePostLinearSwapApiV1SwapCrossTriggerOrder(contractRequest);
5098
+ }
5099
+ else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5100
+ response = await this.contractPrivatePostLinearSwapApiV1SwapCrossTpslOrder(contractRequest);
5101
+ }
5102
+ else {
5103
+ response = await this.contractPrivatePostLinearSwapApiV1SwapCrossOrder(contractRequest);
5104
+ }
5104
5105
  }
5105
5106
  }
5106
- else if (market['future']) {
5107
- if (isStop) {
5108
- response = await this.contractPrivatePostApiV1ContractTriggerOrder(this.extend(request, params));
5109
- }
5110
- else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5111
- response = await this.contractPrivatePostApiV1ContractTpslOrder(this.extend(request, params));
5107
+ else if (market['inverse']) {
5108
+ if (market['swap']) {
5109
+ if (isStop) {
5110
+ response = await this.contractPrivatePostSwapApiV1SwapTriggerOrder(contractRequest);
5111
+ }
5112
+ else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5113
+ response = await this.contractPrivatePostSwapApiV1SwapTpslOrder(contractRequest);
5114
+ }
5115
+ else {
5116
+ response = await this.contractPrivatePostSwapApiV1SwapOrder(contractRequest);
5117
+ }
5112
5118
  }
5113
- else {
5114
- response = await this.contractPrivatePostApiV1ContractOrder(this.extend(request, params));
5119
+ else if (market['future']) {
5120
+ if (isStop) {
5121
+ response = await this.contractPrivatePostApiV1ContractTriggerOrder(contractRequest);
5122
+ }
5123
+ else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
5124
+ response = await this.contractPrivatePostApiV1ContractTpslOrder(contractRequest);
5125
+ }
5126
+ else {
5127
+ response = await this.contractPrivatePostApiV1ContractOrder(contractRequest);
5128
+ }
5115
5129
  }
5116
5130
  }
5117
5131
  }
5118
5132
  //
5133
+ // spot
5134
+ //
5135
+ // {"status":"ok","data":"438398393065481"}
5136
+ //
5137
+ // swap and future
5138
+ //
5119
5139
  // {
5120
5140
  // "status": "ok",
5121
5141
  // "data": {
@@ -5141,7 +5161,29 @@ export default class htx extends Exchange {
5141
5161
  //
5142
5162
  let data = undefined;
5143
5163
  let result = undefined;
5144
- if (isStopLossTriggerOrder) {
5164
+ if (market['spot']) {
5165
+ return this.safeOrder({
5166
+ 'info': response,
5167
+ 'id': this.safeString(response, 'data'),
5168
+ 'timestamp': undefined,
5169
+ 'datetime': undefined,
5170
+ 'lastTradeTimestamp': undefined,
5171
+ 'status': undefined,
5172
+ 'symbol': undefined,
5173
+ 'type': type,
5174
+ 'side': side,
5175
+ 'price': price,
5176
+ 'amount': amount,
5177
+ 'filled': undefined,
5178
+ 'remaining': undefined,
5179
+ 'cost': undefined,
5180
+ 'trades': undefined,
5181
+ 'fee': undefined,
5182
+ 'clientOrderId': undefined,
5183
+ 'average': undefined,
5184
+ }, market);
5185
+ }
5186
+ else if (isStopLossTriggerOrder) {
5145
5187
  data = this.safeValue(response, 'data', {});
5146
5188
  result = this.safeValue(data, 'sl_order', {});
5147
5189
  }
@@ -5154,6 +5196,142 @@ export default class htx extends Exchange {
5154
5196
  }
5155
5197
  return this.parseOrder(result, market);
5156
5198
  }
5199
+ async createOrders(orders, params = {}) {
5200
+ /**
5201
+ * @method
5202
+ * @name htx#createOrders
5203
+ * @description create a list of trade orders
5204
+ * @see https://huobiapi.github.io/docs/spot/v1/en/#place-a-batch-of-orders
5205
+ * @see https://huobiapi.github.io/docs/dm/v1/en/#place-a-batch-of-orders
5206
+ * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#place-a-batch-of-orders
5207
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#isolated-place-a-batch-of-orders
5208
+ * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#cross-place-a-batch-of-orders
5209
+ * @param {array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
5210
+ * @param {object} [params] extra parameters specific to the htx api endpoint
5211
+ * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
5212
+ */
5213
+ await this.loadMarkets();
5214
+ const ordersRequests = [];
5215
+ let symbol = undefined;
5216
+ let market = undefined;
5217
+ let marginMode = undefined;
5218
+ for (let i = 0; i < orders.length; i++) {
5219
+ const rawOrder = orders[i];
5220
+ const marketId = this.safeString(rawOrder, 'symbol');
5221
+ if (symbol === undefined) {
5222
+ symbol = marketId;
5223
+ }
5224
+ else {
5225
+ if (symbol !== marketId) {
5226
+ throw new BadRequest(this.id + ' createOrders() requires all orders to have the same symbol');
5227
+ }
5228
+ }
5229
+ const type = this.safeString(rawOrder, 'type');
5230
+ const side = this.safeString(rawOrder, 'side');
5231
+ const amount = this.safeValue(rawOrder, 'amount');
5232
+ const price = this.safeValue(rawOrder, 'price');
5233
+ const orderParams = this.safeValue(rawOrder, 'params', {});
5234
+ const marginResult = this.handleMarginModeAndParams('createOrders', orderParams);
5235
+ const currentMarginMode = marginResult[0];
5236
+ if (currentMarginMode !== undefined) {
5237
+ if (marginMode === undefined) {
5238
+ marginMode = currentMarginMode;
5239
+ }
5240
+ else {
5241
+ if (marginMode !== currentMarginMode) {
5242
+ throw new BadRequest(this.id + ' createOrders() requires all orders to have the same margin mode (isolated or cross)');
5243
+ }
5244
+ }
5245
+ }
5246
+ market = this.market(symbol);
5247
+ let orderRequest = undefined;
5248
+ if (market['spot']) {
5249
+ orderRequest = await this.createSpotOrderRequest(marketId, type, side, amount, price, orderParams);
5250
+ }
5251
+ else {
5252
+ orderRequest = this.createContractOrderRequest(marketId, type, side, amount, price, orderParams);
5253
+ }
5254
+ orderRequest = this.omit(orderRequest, 'marginMode');
5255
+ ordersRequests.push(orderRequest);
5256
+ }
5257
+ const request = {};
5258
+ let response = undefined;
5259
+ if (market['spot']) {
5260
+ response = await this.privatePostOrderBatchOrders(ordersRequests);
5261
+ }
5262
+ else {
5263
+ request['orders_data'] = ordersRequests;
5264
+ if (market['linear']) {
5265
+ marginMode = (marginMode === undefined) ? 'cross' : marginMode;
5266
+ if (marginMode === 'isolated') {
5267
+ response = await this.contractPrivatePostLinearSwapApiV1SwapBatchorder(request);
5268
+ }
5269
+ else if (marginMode === 'cross') {
5270
+ response = await this.contractPrivatePostLinearSwapApiV1SwapCrossBatchorder(request);
5271
+ }
5272
+ }
5273
+ else if (market['inverse']) {
5274
+ if (market['swap']) {
5275
+ response = await this.contractPrivatePostSwapApiV1SwapBatchorder(request);
5276
+ }
5277
+ else if (market['future']) {
5278
+ response = await this.contractPrivatePostApiV1ContractBatchorder(request);
5279
+ }
5280
+ }
5281
+ }
5282
+ //
5283
+ // spot
5284
+ //
5285
+ // {
5286
+ // "status": "ok",
5287
+ // "data": [
5288
+ // {
5289
+ // "order-id": 936847569789079,
5290
+ // "client-order-id": "AA03022abc3a55e82c-0087-4fc2-beac-112fdebb1ee9"
5291
+ // },
5292
+ // {
5293
+ // "client-order-id": "AA03022abcdb3baefb-3cfa-4891-8009-082b3d46ca82",
5294
+ // "err-code": "account-frozen-balance-insufficient-error",
5295
+ // "err-msg": "trade account balance is not enough, left: `89`"
5296
+ // }
5297
+ // ]
5298
+ // }
5299
+ //
5300
+ // swap and future
5301
+ //
5302
+ // {
5303
+ // "status": "ok",
5304
+ // "data": {
5305
+ // "errors": [
5306
+ // {
5307
+ // "index": 2,
5308
+ // "err_code": 1047,
5309
+ // "err_msg": "Insufficient margin available."
5310
+ // }
5311
+ // ],
5312
+ // "success": [
5313
+ // {
5314
+ // "order_id": 1172923090632953857,
5315
+ // "index": 1,
5316
+ // "order_id_str": "1172923090632953857"
5317
+ // }
5318
+ // ]
5319
+ // },
5320
+ // "ts": 1699688256671
5321
+ // }
5322
+ //
5323
+ let result = undefined;
5324
+ if (market['spot']) {
5325
+ result = this.safeValue(response, 'data', []);
5326
+ }
5327
+ else {
5328
+ const data = this.safeValue(response, 'data', {});
5329
+ const success = this.safeValue(data, 'success', []);
5330
+ const errors = this.safeValue(data, 'errors', []);
5331
+ result = this.arrayConcat(success, errors);
5332
+ }
5333
+ return this.parseOrders(result, market);
5334
+ }
5157
5335
  async cancelOrder(id, symbol = undefined, params = {}) {
5158
5336
  /**
5159
5337
  * @method
package/js/src/okx.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/okx.js';
2
- import { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Transaction, Ticker, OrderBook, Balances, Tickers, Market } from './base/types.js';
2
+ import { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderRequest, FundingHistory, Transaction, Ticker, OrderBook, Balances, Tickers, Market, Greeks } from './base/types.js';
3
3
  /**
4
4
  * @class okx
5
5
  * @extends Exchange
@@ -328,5 +328,27 @@ export default class okx extends Exchange {
328
328
  };
329
329
  parseSettlements(settlements: any, market: any): any[];
330
330
  fetchUnderlyingAssets(params?: {}): Promise<any>;
331
+ fetchGreeks(symbol: string, params?: {}): Promise<Greeks>;
332
+ parseGreeks(greeks: any, market?: any): {
333
+ symbol: any;
334
+ timestamp: number;
335
+ datetime: string;
336
+ delta: number;
337
+ gamma: number;
338
+ theta: number;
339
+ vega: number;
340
+ rho: any;
341
+ bidSize: any;
342
+ askSize: any;
343
+ bidImpliedVolatility: number;
344
+ askImpliedVolatility: number;
345
+ markImpliedVolatility: number;
346
+ bidPrice: any;
347
+ askPrice: any;
348
+ markPrice: any;
349
+ lastPrice: any;
350
+ underlyingPrice: any;
351
+ info: any;
352
+ };
331
353
  handleErrors(httpCode: any, reason: any, url: any, method: any, headers: any, body: any, response: any, requestHeaders: any, requestBody: any): any;
332
354
  }