ccxt 4.3.8 → 4.3.9

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.
@@ -1740,7 +1740,7 @@ class coinex extends coinex$1 {
1740
1740
  // "client_id": "",
1741
1741
  // }
1742
1742
  //
1743
- // Spot and Margin createOrder, createOrders, cancelOrder, cancelOrders, fetchOrder
1743
+ // Spot and Margin cancelOrder, cancelOrders, fetchOrder
1744
1744
  //
1745
1745
  // {
1746
1746
  // "amount":"1.5",
@@ -1768,7 +1768,7 @@ class coinex extends coinex$1 {
1768
1768
  // "client_id": "",
1769
1769
  // }
1770
1770
  //
1771
- // Swap createOrder, cancelOrder, fetchOrder
1771
+ // Swap cancelOrder, fetchOrder
1772
1772
  //
1773
1773
  // {
1774
1774
  // "amount": "0.0005",
@@ -1805,10 +1805,6 @@ class coinex extends coinex$1 {
1805
1805
  // "user_id": 3620173
1806
1806
  // }
1807
1807
  //
1808
- // Stop order createOrder
1809
- //
1810
- // {"status":"success"}
1811
- //
1812
1808
  // Swap Stop cancelOrder, fetchOrder
1813
1809
  //
1814
1810
  // {
@@ -1981,25 +1977,128 @@ class coinex extends coinex$1 {
1981
1977
  // "user_id": 3620173
1982
1978
  // }
1983
1979
  //
1980
+ // Spot and Margin createOrder, createOrders v2
1981
+ //
1982
+ // {
1983
+ // "amount": "0.0001",
1984
+ // "base_fee": "0",
1985
+ // "ccy": "BTC",
1986
+ // "client_id": "x-167673045-a0a3c6461459a801",
1987
+ // "created_at": 1714114386250,
1988
+ // "discount_fee": "0",
1989
+ // "filled_amount": "0",
1990
+ // "filled_value": "0",
1991
+ // "last_fill_amount": "0",
1992
+ // "last_fill_price": "0",
1993
+ // "maker_fee_rate": "0.002",
1994
+ // "market": "BTCUSDT",
1995
+ // "market_type": "SPOT",
1996
+ // "order_id": 117178743547,
1997
+ // "price": "61000",
1998
+ // "quote_fee": "0",
1999
+ // "side": "buy",
2000
+ // "taker_fee_rate": "0.002",
2001
+ // "type": "limit",
2002
+ // "unfilled_amount": "0.0001",
2003
+ // "updated_at": 1714114386250
2004
+ // }
2005
+ //
2006
+ // Spot, Margin and Swap trigger createOrder, createOrders v2
2007
+ //
2008
+ // {
2009
+ // "stop_id": 117180138153
2010
+ // }
2011
+ //
2012
+ // Swap createOrder, createOrders v2
2013
+ //
2014
+ // {
2015
+ // "amount": "0.0001",
2016
+ // "client_id": "x-167673045-1471b81d747080a0",
2017
+ // "created_at": 1714116769986,
2018
+ // "fee": "0",
2019
+ // "fee_ccy": "USDT",
2020
+ // "filled_amount": "0",
2021
+ // "filled_value": "0",
2022
+ // "last_filled_amount": "0",
2023
+ // "last_filled_price": "0",
2024
+ // "maker_fee_rate": "0.0003",
2025
+ // "market": "BTCUSDT",
2026
+ // "market_type": "FUTURES",
2027
+ // "order_id": 136913377780,
2028
+ // "price": "61000.42",
2029
+ // "realized_pnl": "0",
2030
+ // "side": "buy",
2031
+ // "taker_fee_rate": "0.0005",
2032
+ // "type": "limit",
2033
+ // "unfilled_amount": "0.0001",
2034
+ // "updated_at": 1714116769986
2035
+ // }
2036
+ //
2037
+ // Swap stopLossPrice and takeProfitPrice createOrder v2
2038
+ //
2039
+ // {
2040
+ // "adl_level": 1,
2041
+ // "ath_margin_size": "2.14586666",
2042
+ // "ath_position_amount": "0.0001",
2043
+ // "avg_entry_price": "64376",
2044
+ // "bkr_price": "0",
2045
+ // "close_avbl": "0.0001",
2046
+ // "cml_position_value": "6.4376",
2047
+ // "created_at": 1714119054558,
2048
+ // "leverage": "3",
2049
+ // "liq_price": "0",
2050
+ // "maintenance_margin_rate": "0.005",
2051
+ // "maintenance_margin_value": "0.03218632",
2052
+ // "margin_avbl": "2.14586666",
2053
+ // "margin_mode": "cross",
2054
+ // "market": "BTCUSDT",
2055
+ // "market_type": "FUTURES",
2056
+ // "max_position_value": "6.4376",
2057
+ // "open_interest": "0.0001",
2058
+ // "position_id": 303884204,
2059
+ // "position_margin_rate": "3.10624785634397912265",
2060
+ // "realized_pnl": "-0.0032188",
2061
+ // "settle_price": "64376",
2062
+ // "settle_value": "6.4376",
2063
+ // "side": "long",
2064
+ // "stop_loss_price": "62000",
2065
+ // "stop_loss_type": "latest_price",
2066
+ // "take_profit_price": "0",
2067
+ // "take_profit_type": "",
2068
+ // "unrealized_pnl": "0",
2069
+ // "updated_at": 1714119054559
2070
+ // }
2071
+ //
1984
2072
  const rawStatus = this.safeString(order, 'status');
1985
- const timestamp = this.safeTimestamp(order, 'create_time');
2073
+ let timestamp = this.safeTimestamp(order, 'create_time');
2074
+ if (timestamp === undefined) {
2075
+ timestamp = this.safeInteger(order, 'created_at');
2076
+ }
2077
+ let update = this.safeTimestamp(order, 'update_time');
2078
+ if (update === undefined) {
2079
+ update = this.safeInteger(order, 'updated_at');
2080
+ }
1986
2081
  const marketId = this.safeString(order, 'market');
1987
2082
  const defaultType = this.safeString(this.options, 'defaultType');
1988
2083
  const orderType = ('source' in order) ? 'swap' : defaultType;
1989
2084
  market = this.safeMarket(marketId, market, undefined, orderType);
1990
- const feeCurrencyId = this.safeString(order, 'fee_asset');
2085
+ const feeCurrencyId = this.safeString2(order, 'fee_asset', 'fee_ccy');
1991
2086
  let feeCurrency = this.safeCurrencyCode(feeCurrencyId);
1992
2087
  if (feeCurrency === undefined) {
1993
2088
  feeCurrency = market['quote'];
1994
2089
  }
1995
- const rawSide = this.safeInteger(order, 'side');
2090
+ const rawIntegerSide = this.safeInteger(order, 'side');
2091
+ const rawStringSide = this.safeString(order, 'side');
1996
2092
  let side = undefined;
1997
- if (rawSide === 1) {
2093
+ if (rawIntegerSide === 1) {
1998
2094
  side = 'sell';
1999
2095
  }
2000
- else if (rawSide === 2) {
2096
+ else if (rawIntegerSide === 2) {
2001
2097
  side = 'buy';
2002
2098
  }
2099
+ else if ((rawStringSide === 'buy') || (rawStringSide === 'sell')) {
2100
+ side = rawStringSide;
2101
+ }
2003
2102
  else {
2004
2103
  side = this.safeString(order, 'type');
2005
2104
  }
@@ -2007,12 +2106,19 @@ class coinex extends coinex$1 {
2007
2106
  let type = undefined;
2008
2107
  if (rawType === undefined) {
2009
2108
  const typeInteger = this.safeInteger(order, 'type');
2109
+ const typeString = this.safeString(order, 'type');
2010
2110
  if (typeInteger === 1) {
2011
2111
  type = 'limit';
2012
2112
  }
2013
2113
  else if (typeInteger === 2) {
2014
2114
  type = 'market';
2015
2115
  }
2116
+ else if ((typeString === 'limit') || (typeString === 'market')) {
2117
+ type = typeString;
2118
+ }
2119
+ else if (typeString === 'maker_only') {
2120
+ type = 'limit';
2121
+ }
2016
2122
  }
2017
2123
  else {
2018
2124
  type = rawType;
@@ -2022,11 +2128,11 @@ class coinex extends coinex$1 {
2022
2128
  clientOrderId = undefined;
2023
2129
  }
2024
2130
  return this.safeOrder({
2025
- 'id': this.safeString2(order, 'id', 'order_id'),
2131
+ 'id': this.safeStringN(order, ['id', 'order_id', 'stop_id']),
2026
2132
  'clientOrderId': clientOrderId,
2027
2133
  'datetime': this.iso8601(timestamp),
2028
2134
  'timestamp': timestamp,
2029
- 'lastTradeTimestamp': this.safeTimestamp(order, 'update_time'),
2135
+ 'lastTradeTimestamp': update,
2030
2136
  'status': this.parseOrderStatus(rawStatus),
2031
2137
  'symbol': market['symbol'],
2032
2138
  'type': type,
@@ -2039,15 +2145,15 @@ class coinex extends coinex$1 {
2039
2145
  'triggerPrice': this.safeString(order, 'stop_price'),
2040
2146
  'takeProfitPrice': this.safeNumber(order, 'take_profit_price'),
2041
2147
  'stopLossPrice': this.safeNumber(order, 'stop_loss_price'),
2042
- 'cost': this.safeString(order, 'deal_money'),
2043
- 'average': this.safeString(order, 'avg_price'),
2148
+ 'cost': this.safeString2(order, 'deal_money', 'filled_value'),
2149
+ 'average': this.safeString2(order, 'avg_price', 'avg_entry_price'),
2044
2150
  'amount': this.safeString(order, 'amount'),
2045
- 'filled': this.safeString(order, 'deal_amount'),
2046
- 'remaining': this.safeString(order, 'left'),
2151
+ 'filled': this.safeString2(order, 'deal_amount', 'filled_amount'),
2152
+ 'remaining': this.safeString2(order, 'left', 'unfilled_amount'),
2047
2153
  'trades': undefined,
2048
2154
  'fee': {
2049
2155
  'currency': feeCurrency,
2050
- 'cost': this.safeString(order, 'deal_fee'),
2156
+ 'cost': this.safeStringN(order, ['deal_fee', 'quote_fee', 'fee']),
2051
2157
  },
2052
2158
  'info': order,
2053
2159
  }, market);
@@ -2058,6 +2164,7 @@ class coinex extends coinex$1 {
2058
2164
  * @name coinex#createMarketBuyOrderWithCost
2059
2165
  * @description create a market buy order by providing the symbol and cost
2060
2166
  * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade003_market_order
2167
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-order
2061
2168
  * @param {string} symbol unified symbol of the market to create an order in
2062
2169
  * @param {float} cost how much you want to trade in units of the quote currency
2063
2170
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -2075,22 +2182,18 @@ class coinex extends coinex$1 {
2075
2182
  const market = this.market(symbol);
2076
2183
  const swap = market['swap'];
2077
2184
  const clientOrderId = this.safeString2(params, 'client_id', 'clientOrderId');
2078
- const stopPrice = this.safeValue2(params, 'stopPrice', 'triggerPrice');
2079
- const stopLossPrice = this.safeValue(params, 'stopLossPrice');
2080
- const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
2185
+ const stopPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
2186
+ const stopLossPrice = this.safeString(params, 'stopLossPrice');
2187
+ const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
2081
2188
  const option = this.safeString(params, 'option');
2082
2189
  const isMarketOrder = type === 'market';
2083
- const postOnly = this.isPostOnly(isMarketOrder, option === 'MAKER_ONLY', params);
2084
- const positionId = this.safeInteger2(params, 'position_id', 'positionId'); // Required for closing swap positions
2085
- const timeInForceRaw = this.safeString(params, 'timeInForce'); // Spot: IOC, FOK, PO, GTC, ... NORMAL (default), MAKER_ONLY
2086
- const reduceOnly = this.safeValue(params, 'reduceOnly');
2190
+ const postOnly = this.isPostOnly(isMarketOrder, option === 'maker_only', params);
2191
+ const timeInForceRaw = this.safeStringUpper(params, 'timeInForce');
2192
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
2087
2193
  if (reduceOnly) {
2088
2194
  if (!market['swap']) {
2089
2195
  throw new errors.InvalidOrder(this.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only');
2090
2196
  }
2091
- if (positionId === undefined) {
2092
- throw new errors.ArgumentsRequired(this.id + ' createOrder() requires a position_id/positionId parameter for reduceOnly orders');
2093
- }
2094
2197
  }
2095
2198
  const request = {
2096
2199
  'market': market['id'],
@@ -2103,73 +2206,56 @@ class coinex extends coinex$1 {
2103
2206
  else {
2104
2207
  request['client_id'] = clientOrderId;
2105
2208
  }
2209
+ if ((stopLossPrice === undefined) && (takeProfitPrice === undefined)) {
2210
+ if (!reduceOnly) {
2211
+ request['side'] = side;
2212
+ }
2213
+ let requestType = type;
2214
+ if (postOnly) {
2215
+ requestType = 'maker_only';
2216
+ }
2217
+ else if (timeInForceRaw !== undefined) {
2218
+ if (timeInForceRaw === 'IOC') {
2219
+ requestType = 'ioc';
2220
+ }
2221
+ else if (timeInForceRaw === 'FOK') {
2222
+ requestType = 'fok';
2223
+ }
2224
+ }
2225
+ if (!isMarketOrder) {
2226
+ request['price'] = this.priceToPrecision(symbol, price);
2227
+ }
2228
+ request['type'] = requestType;
2229
+ }
2106
2230
  if (swap) {
2231
+ request['market_type'] = 'FUTURES';
2107
2232
  if (stopLossPrice || takeProfitPrice) {
2108
- request['stop_type'] = this.safeInteger(params, 'stop_type', 1); // 1: triggered by the latest transaction, 2: mark price, 3: index price
2109
- if (positionId === undefined) {
2110
- throw new errors.ArgumentsRequired(this.id + ' createOrder() requires a position_id parameter for stop loss and take profit orders');
2111
- }
2112
- request['position_id'] = positionId;
2113
2233
  if (stopLossPrice) {
2114
2234
  request['stop_loss_price'] = this.priceToPrecision(symbol, stopLossPrice);
2235
+ request['stop_loss_type'] = this.safeString(params, 'stop_type', 'latest_price');
2115
2236
  }
2116
2237
  else if (takeProfitPrice) {
2117
2238
  request['take_profit_price'] = this.priceToPrecision(symbol, takeProfitPrice);
2239
+ request['take_profit_type'] = this.safeString(params, 'stop_type', 'latest_price');
2118
2240
  }
2119
2241
  }
2120
2242
  else {
2121
- const requestSide = (side === 'buy') ? 2 : 1;
2243
+ request['amount'] = this.amountToPrecision(symbol, amount);
2122
2244
  if (stopPrice !== undefined) {
2123
- request['stop_price'] = this.priceToPrecision(symbol, stopPrice);
2124
- request['stop_type'] = this.safeInteger(params, 'stop_type', 1); // 1: triggered by the latest transaction, 2: mark price, 3: index price;
2125
- request['amount'] = this.amountToPrecision(symbol, amount);
2126
- request['side'] = requestSide;
2127
- if (type === 'limit') {
2128
- request['price'] = this.priceToPrecision(symbol, price);
2129
- }
2130
- request['amount'] = this.amountToPrecision(symbol, amount);
2131
- }
2132
- let timeInForce = undefined;
2133
- if ((type !== 'market') || (stopPrice !== undefined)) {
2134
- if (postOnly) {
2135
- request['option'] = 1;
2136
- }
2137
- else if (timeInForceRaw !== undefined) {
2138
- if (timeInForceRaw === 'IOC') {
2139
- timeInForce = 2;
2140
- }
2141
- else if (timeInForceRaw === 'FOK') {
2142
- timeInForce = 3;
2143
- }
2144
- else {
2145
- timeInForce = 1;
2146
- }
2147
- request['effect_type'] = timeInForce; // exchange takes 'IOC' and 'FOK'
2148
- }
2149
- }
2150
- if (type === 'limit' && stopPrice === undefined) {
2151
- if (reduceOnly) {
2152
- request['position_id'] = positionId;
2153
- }
2154
- else {
2155
- request['side'] = requestSide;
2156
- }
2157
- request['price'] = this.priceToPrecision(symbol, price);
2158
- request['amount'] = this.amountToPrecision(symbol, amount);
2159
- }
2160
- else if (type === 'market' && stopPrice === undefined) {
2161
- if (reduceOnly) {
2162
- request['position_id'] = positionId;
2163
- }
2164
- else {
2165
- request['side'] = requestSide;
2166
- request['amount'] = this.amountToPrecision(symbol, amount);
2167
- }
2245
+ request['trigger_price'] = this.priceToPrecision(symbol, stopPrice);
2246
+ request['trigger_price_type'] = this.safeString(params, 'stop_type', 'latest_price');
2168
2247
  }
2169
2248
  }
2170
2249
  }
2171
2250
  else {
2172
- request['type'] = side;
2251
+ let marginMode = undefined;
2252
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2253
+ if (marginMode !== undefined) {
2254
+ request['market_type'] = 'MARGIN';
2255
+ }
2256
+ else {
2257
+ request['market_type'] = 'SPOT';
2258
+ }
2173
2259
  if ((type === 'market') && (side === 'buy')) {
2174
2260
  let createMarketBuyOrderRequiresPrice = true;
2175
2261
  [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
@@ -2194,39 +2280,11 @@ class coinex extends coinex$1 {
2194
2280
  else {
2195
2281
  request['amount'] = this.amountToPrecision(symbol, amount);
2196
2282
  }
2197
- if ((type === 'limit') || (type === 'ioc')) {
2198
- request['price'] = this.priceToPrecision(symbol, price);
2199
- }
2200
2283
  if (stopPrice !== undefined) {
2201
- request['stop_price'] = this.priceToPrecision(symbol, stopPrice);
2202
- }
2203
- if ((type !== 'market') || (stopPrice !== undefined)) {
2204
- // following options cannot be applied to vanilla market orders (but can be applied to stop-market orders)
2205
- if ((timeInForceRaw !== undefined) || postOnly) {
2206
- if ((postOnly || (timeInForceRaw !== 'IOC')) && ((type === 'limit') && (stopPrice !== undefined))) {
2207
- throw new errors.InvalidOrder(this.id + ' createOrder() only supports the IOC option for stop-limit orders');
2208
- }
2209
- if (postOnly) {
2210
- request['option'] = 'MAKER_ONLY';
2211
- }
2212
- else {
2213
- if (timeInForceRaw !== undefined) {
2214
- request['option'] = timeInForceRaw; // exchange takes 'IOC' and 'FOK'
2215
- }
2216
- }
2217
- }
2284
+ request['trigger_price'] = this.priceToPrecision(symbol, stopPrice);
2218
2285
  }
2219
2286
  }
2220
- const accountId = this.safeInteger(params, 'account_id');
2221
- let marginMode = undefined;
2222
- [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2223
- if (marginMode !== undefined) {
2224
- if (accountId === undefined) {
2225
- throw new errors.BadRequest(this.id + ' createOrder() requires an account_id parameter for margin orders');
2226
- }
2227
- request['account_id'] = accountId;
2228
- }
2229
- params = this.omit(params, ['reduceOnly', 'positionId', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
2287
+ params = this.omit(params, ['reduceOnly', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
2230
2288
  return this.extend(request, params);
2231
2289
  }
2232
2290
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
@@ -2234,17 +2292,13 @@ class coinex extends coinex$1 {
2234
2292
  * @method
2235
2293
  * @name coinex#createOrder
2236
2294
  * @description create a trade order
2237
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade001_limit_order
2238
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade003_market_order
2239
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade004_IOC_order
2240
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade005_stop_limit_order
2241
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade006_stop_market_order
2242
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http017_put_limit
2243
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http018_put_market
2244
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http019_put_limit_stop
2245
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http020_put_market_stop
2246
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http031_market_close
2247
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http030_limit_close
2295
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-order
2296
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-stop-order
2297
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-order
2298
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-stop-order
2299
+ * @see https://docs.coinex.com/api/v2/futures/position/http/close-position
2300
+ * @see https://docs.coinex.com/api/v2/futures/position/http/set-position-stop-loss
2301
+ * @see https://docs.coinex.com/api/v2/futures/position/http/set-position-take-profit
2248
2302
  * @param {string} symbol unified symbol of the market to create an order in
2249
2303
  * @param {string} type 'market' or 'limit'
2250
2304
  * @param {string} side 'buy' or 'sell'
@@ -2257,15 +2311,14 @@ class coinex extends coinex$1 {
2257
2311
  * @param {string} [params.timeInForce] 'GTC', 'IOC', 'FOK', 'PO'
2258
2312
  * @param {boolean} [params.postOnly] set to true if you wish to make a post only order
2259
2313
  * @param {boolean} [params.reduceOnly] *contract only* indicates if this order is to reduce the size of a position
2260
- * @param {int} [params.position_id] *required for reduce only orders* the position id to reduce
2261
2314
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2262
2315
  */
2263
2316
  await this.loadMarkets();
2264
2317
  const market = this.market(symbol);
2265
- const reduceOnly = this.safeValue(params, 'reduceOnly');
2266
- const triggerPrice = this.safeNumber2(params, 'stopPrice', 'triggerPrice');
2267
- const stopLossTriggerPrice = this.safeNumber(params, 'stopLossPrice');
2268
- const takeProfitTriggerPrice = this.safeNumber(params, 'takeProfitPrice');
2318
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
2319
+ const triggerPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
2320
+ const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
2321
+ const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
2269
2322
  const isTriggerOrder = triggerPrice !== undefined;
2270
2323
  const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
2271
2324
  const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
@@ -2274,135 +2327,212 @@ class coinex extends coinex$1 {
2274
2327
  let response = undefined;
2275
2328
  if (market['spot']) {
2276
2329
  if (isTriggerOrder) {
2277
- if (type === 'limit') {
2278
- response = await this.v1PrivatePostOrderStopLimit(request);
2279
- }
2280
- else {
2281
- response = await this.v1PrivatePostOrderStopMarket(request);
2282
- }
2330
+ response = await this.v2PrivatePostSpotStopOrder(request);
2331
+ //
2332
+ // {
2333
+ // "code": 0,
2334
+ // "data": {
2335
+ // "stop_id": 117180138153
2336
+ // },
2337
+ // "message": "OK"
2338
+ // }
2339
+ //
2283
2340
  }
2284
2341
  else {
2285
- if (type === 'limit') {
2286
- response = await this.v1PrivatePostOrderLimit(request);
2287
- }
2288
- else {
2289
- response = await this.v1PrivatePostOrderMarket(request);
2290
- }
2342
+ response = await this.v2PrivatePostSpotOrder(request);
2343
+ //
2344
+ // {
2345
+ // "code": 0,
2346
+ // "data": {
2347
+ // "amount": "0.0001",
2348
+ // "base_fee": "0",
2349
+ // "ccy": "BTC",
2350
+ // "client_id": "x-167673045-a0a3c6461459a801",
2351
+ // "created_at": 1714114386250,
2352
+ // "discount_fee": "0",
2353
+ // "filled_amount": "0",
2354
+ // "filled_value": "0",
2355
+ // "last_fill_amount": "0",
2356
+ // "last_fill_price": "0",
2357
+ // "maker_fee_rate": "0.002",
2358
+ // "market": "BTCUSDT",
2359
+ // "market_type": "SPOT",
2360
+ // "order_id": 117178743547,
2361
+ // "price": "61000",
2362
+ // "quote_fee": "0",
2363
+ // "side": "buy",
2364
+ // "taker_fee_rate": "0.002",
2365
+ // "type": "limit",
2366
+ // "unfilled_amount": "0.0001",
2367
+ // "updated_at": 1714114386250
2368
+ // },
2369
+ // "message": "OK"
2370
+ // }
2371
+ //
2291
2372
  }
2292
2373
  }
2293
2374
  else {
2294
2375
  if (isTriggerOrder) {
2295
- if (type === 'limit') {
2296
- response = await this.v1PerpetualPrivatePostOrderPutStopLimit(request);
2297
- }
2298
- else {
2299
- response = await this.v1PerpetualPrivatePostOrderPutStopMarket(request);
2300
- }
2376
+ response = await this.v2PrivatePostFuturesStopOrder(request);
2377
+ //
2378
+ // {
2379
+ // "code": 0,
2380
+ // "data": {
2381
+ // "stop_id": 136915460994
2382
+ // },
2383
+ // "message": "OK"
2384
+ // }
2385
+ //
2301
2386
  }
2302
2387
  else if (isStopLossOrTakeProfitTrigger) {
2303
2388
  if (isStopLossTriggerOrder) {
2304
- response = await this.v1PerpetualPrivatePostPositionStopLoss(request);
2389
+ response = await this.v2PrivatePostFuturesSetPositionStopLoss(request);
2390
+ //
2391
+ // {
2392
+ // "code": 0,
2393
+ // "data": {
2394
+ // "adl_level": 1,
2395
+ // "ath_margin_size": "2.14586666",
2396
+ // "ath_position_amount": "0.0001",
2397
+ // "avg_entry_price": "64376",
2398
+ // "bkr_price": "0",
2399
+ // "close_avbl": "0.0001",
2400
+ // "cml_position_value": "6.4376",
2401
+ // "created_at": 1714119054558,
2402
+ // "leverage": "3",
2403
+ // "liq_price": "0",
2404
+ // "maintenance_margin_rate": "0.005",
2405
+ // "maintenance_margin_value": "0.03218632",
2406
+ // "margin_avbl": "2.14586666",
2407
+ // "margin_mode": "cross",
2408
+ // "market": "BTCUSDT",
2409
+ // "market_type": "FUTURES",
2410
+ // "max_position_value": "6.4376",
2411
+ // "open_interest": "0.0001",
2412
+ // "position_id": 303884204,
2413
+ // "position_margin_rate": "3.10624785634397912265",
2414
+ // "realized_pnl": "-0.0032188",
2415
+ // "settle_price": "64376",
2416
+ // "settle_value": "6.4376",
2417
+ // "side": "long",
2418
+ // "stop_loss_price": "62000",
2419
+ // "stop_loss_type": "latest_price",
2420
+ // "take_profit_price": "0",
2421
+ // "take_profit_type": "",
2422
+ // "unrealized_pnl": "0",
2423
+ // "updated_at": 1714119054559
2424
+ // },
2425
+ // "message": "OK"
2426
+ // }
2427
+ //
2305
2428
  }
2306
2429
  else if (isTakeProfitTriggerOrder) {
2307
- response = await this.v1PerpetualPrivatePostPositionTakeProfit(request);
2430
+ response = await this.v2PrivatePostFuturesSetPositionTakeProfit(request);
2431
+ //
2432
+ // {
2433
+ // "code": 0,
2434
+ // "data": {
2435
+ // "adl_level": 1,
2436
+ // "ath_margin_size": "2.14586666",
2437
+ // "ath_position_amount": "0.0001",
2438
+ // "avg_entry_price": "64376",
2439
+ // "bkr_price": "0",
2440
+ // "close_avbl": "0.0001",
2441
+ // "cml_position_value": "6.4376",
2442
+ // "created_at": 1714119054558,
2443
+ // "leverage": "3",
2444
+ // "liq_price": "0",
2445
+ // "maintenance_margin_rate": "0.005",
2446
+ // "maintenance_margin_value": "0.03218632",
2447
+ // "margin_avbl": "2.14586666",
2448
+ // "margin_mode": "cross",
2449
+ // "market": "BTCUSDT",
2450
+ // "market_type": "FUTURES",
2451
+ // "max_position_value": "6.4376",
2452
+ // "open_interest": "0.0001",
2453
+ // "position_id": 303884204,
2454
+ // "position_margin_rate": "3.10624785634397912265",
2455
+ // "realized_pnl": "-0.0032188",
2456
+ // "settle_price": "64376",
2457
+ // "settle_value": "6.4376",
2458
+ // "side": "long",
2459
+ // "stop_loss_price": "62000",
2460
+ // "stop_loss_type": "latest_price",
2461
+ // "take_profit_price": "70000",
2462
+ // "take_profit_type": "latest_price",
2463
+ // "unrealized_pnl": "0",
2464
+ // "updated_at": 1714119054559
2465
+ // },
2466
+ // "message": "OK"
2467
+ // }
2468
+ //
2308
2469
  }
2309
2470
  }
2310
2471
  else {
2311
2472
  if (reduceOnly) {
2312
- if (type === 'limit') {
2313
- response = await this.v1PerpetualPrivatePostOrderCloseLimit(request);
2314
- }
2315
- else {
2316
- response = await this.v1PerpetualPrivatePostOrderCloseMarket(request);
2317
- }
2473
+ response = await this.v2PrivatePostFuturesClosePosition(request);
2474
+ //
2475
+ // {
2476
+ // "code": 0,
2477
+ // "data": {
2478
+ // "amount": "0.0001",
2479
+ // "client_id": "x-167673045-4f264600c432ac06",
2480
+ // "created_at": 1714119323764,
2481
+ // "fee": "0.003221",
2482
+ // "fee_ccy": "USDT",
2483
+ // "filled_amount": "0.0001",
2484
+ // "filled_value": "6.442017",
2485
+ // "last_filled_amount": "0.0001",
2486
+ // "last_filled_price": "64420.17",
2487
+ // "maker_fee_rate": "0",
2488
+ // "market": "BTCUSDT",
2489
+ // "market_type": "FUTURES",
2490
+ // "order_id": 136915813578,
2491
+ // "price": "0",
2492
+ // "realized_pnl": "0.004417",
2493
+ // "side": "sell",
2494
+ // "taker_fee_rate": "0.0005",
2495
+ // "type": "market",
2496
+ // "unfilled_amount": "0",
2497
+ // "updated_at": 1714119323764
2498
+ // },
2499
+ // "message": "OK"
2500
+ // }
2501
+ //
2318
2502
  }
2319
2503
  else {
2320
- if (type === 'limit') {
2321
- response = await this.v1PerpetualPrivatePostOrderPutLimit(request);
2322
- }
2323
- else {
2324
- response = await this.v1PerpetualPrivatePostOrderPutMarket(request);
2325
- }
2504
+ response = await this.v2PrivatePostFuturesOrder(request);
2505
+ //
2506
+ // {
2507
+ // "code": 0,
2508
+ // "data": {
2509
+ // "amount": "0.0001",
2510
+ // "client_id": "x-167673045-1471b81d747080a0",
2511
+ // "created_at": 1714116769986,
2512
+ // "fee": "0",
2513
+ // "fee_ccy": "USDT",
2514
+ // "filled_amount": "0",
2515
+ // "filled_value": "0",
2516
+ // "last_filled_amount": "0",
2517
+ // "last_filled_price": "0",
2518
+ // "maker_fee_rate": "0.0003",
2519
+ // "market": "BTCUSDT",
2520
+ // "market_type": "FUTURES",
2521
+ // "order_id": 136913377780,
2522
+ // "price": "61000.42",
2523
+ // "realized_pnl": "0",
2524
+ // "side": "buy",
2525
+ // "taker_fee_rate": "0.0005",
2526
+ // "type": "limit",
2527
+ // "unfilled_amount": "0.0001",
2528
+ // "updated_at": 1714116769986
2529
+ // },
2530
+ // "message": "OK"
2531
+ // }
2532
+ //
2326
2533
  }
2327
2534
  }
2328
2535
  }
2329
- //
2330
- // Spot and Margin
2331
- //
2332
- // {
2333
- // "code": 0,
2334
- // "data": {
2335
- // "amount": "0.0005",
2336
- // "asset_fee": "0",
2337
- // "avg_price": "0.00",
2338
- // "client_id": "",
2339
- // "create_time": 1650951627,
2340
- // "deal_amount": "0",
2341
- // "deal_fee": "0",
2342
- // "deal_money": "0",
2343
- // "fee_asset": null,
2344
- // "fee_discount": "1",
2345
- // "finished_time": null,
2346
- // "id": 74510932594,
2347
- // "left": "0.0005",
2348
- // "maker_fee_rate": "0.002",
2349
- // "market": "BTCUSDT",
2350
- // "money_fee": "0",
2351
- // "order_type": "limit",
2352
- // "price": "30000",
2353
- // "status": "not_deal",
2354
- // "stock_fee": "0",
2355
- // "taker_fee_rate": "0.002",
2356
- // "type": "buy"
2357
- // },
2358
- // "message": "Success"
2359
- // }
2360
- //
2361
- // Swap
2362
- //
2363
- // {
2364
- // "code": 0,
2365
- // "data": {
2366
- // "amount": "0.0005",
2367
- // "client_id": "",
2368
- // "create_time": 1651004578.618224,
2369
- // "deal_asset_fee": "0.00000000000000000000",
2370
- // "deal_fee": "0.00000000000000000000",
2371
- // "deal_profit": "0.00000000000000000000",
2372
- // "deal_stock": "0.00000000000000000000",
2373
- // "effect_type": 1,
2374
- // "fee_asset": "",
2375
- // "fee_discount": "0.00000000000000000000",
2376
- // "last_deal_amount": "0.00000000000000000000",
2377
- // "last_deal_id": 0,
2378
- // "last_deal_price": "0.00000000000000000000",
2379
- // "last_deal_role": 0,
2380
- // "last_deal_time": 0,
2381
- // "last_deal_type": 0,
2382
- // "left": "0.0005",
2383
- // "leverage": "3",
2384
- // "maker_fee": "0.00030",
2385
- // "market": "BTCUSDT",
2386
- // "order_id": 18221659097,
2387
- // "position_id": 0,
2388
- // "position_type": 1,
2389
- // "price": "30000.00",
2390
- // "side": 2,
2391
- // "source": "api.v1",
2392
- // "stop_id": 0,
2393
- // "taker_fee": "0.00050",
2394
- // "target": 0,
2395
- // "type": 1,
2396
- // "update_time": 1651004578.618224,
2397
- // "user_id": 3620173
2398
- // },
2399
- // "message": "OK"
2400
- // }
2401
- //
2402
- // Stop Order
2403
- //
2404
- // {"code":0,"data":{"status":"success"},"message":"OK"}
2405
- //
2406
2536
  const data = this.safeDict(response, 'data', {});
2407
2537
  return this.parseOrder(data, market);
2408
2538
  }
@@ -2411,7 +2541,10 @@ class coinex extends coinex$1 {
2411
2541
  * @method
2412
2542
  * @name coinex#createOrders
2413
2543
  * @description create a list of trade orders (all orders should be of the same symbol)
2414
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade002_batch_limit_orders
2544
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-multi-order
2545
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-multi-stop-order
2546
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-multi-order
2547
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-multi-stop-order
2415
2548
  * @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
2416
2549
  * @param {object} [params] extra parameters specific to the api endpoint
2417
2550
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
@@ -2419,6 +2552,9 @@ class coinex extends coinex$1 {
2419
2552
  await this.loadMarkets();
2420
2553
  const ordersRequests = [];
2421
2554
  let symbol = undefined;
2555
+ let reduceOnly = false;
2556
+ let isTriggerOrder = false;
2557
+ let isStopLossOrTakeProfitTrigger = false;
2422
2558
  for (let i = 0; i < orders.length; i++) {
2423
2559
  const rawOrder = orders[i];
2424
2560
  const marketId = this.safeString(rawOrder, 'symbol');
@@ -2438,56 +2574,148 @@ class coinex extends coinex$1 {
2438
2574
  if (type !== 'limit') {
2439
2575
  throw new errors.NotSupported(this.id + ' createOrders() does not support ' + type + ' orders, only limit orders are accepted');
2440
2576
  }
2577
+ reduceOnly = this.safeValue(orderParams, 'reduceOnly');
2578
+ const triggerPrice = this.safeNumber2(orderParams, 'stopPrice', 'triggerPrice');
2579
+ const stopLossTriggerPrice = this.safeNumber(orderParams, 'stopLossPrice');
2580
+ const takeProfitTriggerPrice = this.safeNumber(orderParams, 'takeProfitPrice');
2581
+ isTriggerOrder = triggerPrice !== undefined;
2582
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
2583
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
2584
+ isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
2441
2585
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
2442
2586
  ordersRequests.push(orderRequest);
2443
2587
  }
2444
2588
  const market = this.market(symbol);
2445
- if (!market['spot']) {
2446
- throw new errors.NotSupported(this.id + ' createOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted');
2447
- }
2448
2589
  const request = {
2449
2590
  'market': market['id'],
2450
- 'batch_orders': this.json(ordersRequests),
2591
+ 'orders': ordersRequests,
2451
2592
  };
2452
- const response = await this.v1PrivatePostOrderLimitBatch(request);
2453
- //
2454
- // {
2455
- // "code": 0,
2456
- // "data": [
2457
- // {
2458
- // "code": 0,
2459
- // "data": {
2460
- // "amount": "0.0005",
2461
- // "asset_fee": "0",
2462
- // "avg_price": "0.00",
2463
- // "client_id": "x-167673045-d34bfb41242d8fd1",
2464
- // "create_time": 1701229157,
2465
- // "deal_amount": "0",
2466
- // "deal_fee": "0",
2467
- // "deal_money": "0",
2468
- // "fee_asset": null,
2469
- // "fee_discount": "1",
2470
- // "finished_time": null,
2471
- // "id": 107745856676,
2472
- // "left": "0.0005",
2473
- // "maker_fee_rate": "0.002",
2474
- // "market": "BTCUSDT",
2475
- // "money_fee": "0",
2476
- // "order_type": "limit",
2477
- // "price": "23000",
2478
- // "source_id": "",
2479
- // "status": "not_deal",
2480
- // "stock_fee": "0",
2481
- // "taker_fee_rate": "0.002",
2482
- // "type": "buy"
2483
- // },
2484
- // "message": "OK"
2485
- // },
2486
- // ],
2487
- // "message": "Success"
2488
- // }
2489
- //
2490
- const data = this.safeValue(response, 'data', []);
2593
+ let response = undefined;
2594
+ if (market['spot']) {
2595
+ if (isTriggerOrder) {
2596
+ response = await this.v2PrivatePostSpotBatchStopOrder(request);
2597
+ //
2598
+ // {
2599
+ // "code": 0,
2600
+ // "data": [
2601
+ // {
2602
+ // "code": 0,
2603
+ // "data": {
2604
+ // "stop_id": 117186257510
2605
+ // },
2606
+ // "message": "OK"
2607
+ // },
2608
+ // ],
2609
+ // "message": "OK"
2610
+ // }
2611
+ //
2612
+ }
2613
+ else {
2614
+ response = await this.v2PrivatePostSpotBatchOrder(request);
2615
+ //
2616
+ // {
2617
+ // "code": 0,
2618
+ // "data": [
2619
+ // {
2620
+ // "amount": "0.0001",
2621
+ // "base_fee": "0",
2622
+ // "ccy": "BTC",
2623
+ // "client_id": "x-167673045-f3651372049dab0d",
2624
+ // "created_at": 1714121403450,
2625
+ // "discount_fee": "0",
2626
+ // "filled_amount": "0",
2627
+ // "filled_value": "0",
2628
+ // "last_fill_amount": "0",
2629
+ // "last_fill_price": "0",
2630
+ // "maker_fee_rate": "0.002",
2631
+ // "market": "BTCUSDT",
2632
+ // "market_type": "SPOT",
2633
+ // "order_id": 117185362233,
2634
+ // "price": "61000",
2635
+ // "quote_fee": "0",
2636
+ // "side": "buy",
2637
+ // "taker_fee_rate": "0.002",
2638
+ // "type": "limit",
2639
+ // "unfilled_amount": "0.0001",
2640
+ // "updated_at": 1714121403450
2641
+ // },
2642
+ // {
2643
+ // "code": 3109,
2644
+ // "data": null,
2645
+ // "message": "balance not enough"
2646
+ // }
2647
+ // ],
2648
+ // "message": "OK"
2649
+ // }
2650
+ //
2651
+ }
2652
+ }
2653
+ else {
2654
+ if (isTriggerOrder) {
2655
+ response = await this.v2PrivatePostFuturesBatchStopOrder(request);
2656
+ //
2657
+ // {
2658
+ // "code": 0,
2659
+ // "data": [
2660
+ // {
2661
+ // "code": 0,
2662
+ // "data": {
2663
+ // "stop_id": 136919625994
2664
+ // },
2665
+ // "message": "OK"
2666
+ // },
2667
+ // ],
2668
+ // "message": "OK"
2669
+ // }
2670
+ //
2671
+ }
2672
+ else if (isStopLossOrTakeProfitTrigger) {
2673
+ throw new errors.NotSupported(this.id + ' createOrders() does not support stopLossPrice or takeProfitPrice orders');
2674
+ }
2675
+ else {
2676
+ if (reduceOnly) {
2677
+ throw new errors.NotSupported(this.id + ' createOrders() does not support reduceOnly orders');
2678
+ }
2679
+ else {
2680
+ response = await this.v2PrivatePostFuturesBatchOrder(request);
2681
+ //
2682
+ // {
2683
+ // "code": 0,
2684
+ // "data": [
2685
+ // {
2686
+ // "code": 0,
2687
+ // "data": {
2688
+ // "amount": "0.0001",
2689
+ // "client_id": "x-167673045-2cb7436f3462a654",
2690
+ // "created_at": 1714122832493,
2691
+ // "fee": "0",
2692
+ // "fee_ccy": "USDT",
2693
+ // "filled_amount": "0",
2694
+ // "filled_value": "0",
2695
+ // "last_filled_amount": "0",
2696
+ // "last_filled_price": "0",
2697
+ // "maker_fee_rate": "0.0003",
2698
+ // "market": "BTCUSDT",
2699
+ // "market_type": "FUTURES",
2700
+ // "order_id": 136918835063,
2701
+ // "price": "61000",
2702
+ // "realized_pnl": "0",
2703
+ // "side": "buy",
2704
+ // "taker_fee_rate": "0.0005",
2705
+ // "type": "limit",
2706
+ // "unfilled_amount": "0.0001",
2707
+ // "updated_at": 1714122832493
2708
+ // },
2709
+ // "message": "OK"
2710
+ // },
2711
+ // ],
2712
+ // "message": "OK"
2713
+ // }
2714
+ //
2715
+ }
2716
+ }
2717
+ }
2718
+ const data = this.safeList(response, 'data', []);
2491
2719
  const results = [];
2492
2720
  for (let i = 0; i < data.length; i++) {
2493
2721
  const entry = data[i];
@@ -2501,9 +2729,16 @@ class coinex extends coinex$1 {
2501
2729
  status = 'open';
2502
2730
  }
2503
2731
  }
2504
- const item = this.safeValue(entry, 'data', {});
2505
- item['status'] = status;
2506
- const order = this.parseOrder(item, market);
2732
+ const innerData = this.safeDict(entry, 'data', {});
2733
+ let order = undefined;
2734
+ if (market['spot'] && !isTriggerOrder) {
2735
+ entry['status'] = status;
2736
+ order = this.parseOrder(entry, market);
2737
+ }
2738
+ else {
2739
+ innerData['status'] = status;
2740
+ order = this.parseOrder(innerData, market);
2741
+ }
2507
2742
  results.push(order);
2508
2743
  }
2509
2744
  return results;
@@ -5776,7 +6011,11 @@ class coinex extends coinex$1 {
5776
6011
  query = this.keysort(query);
5777
6012
  const urlencoded = this.rawencode(query);
5778
6013
  let preparedString = method + '/' + version + '/' + path;
5779
- if (urlencoded) {
6014
+ if (method === 'POST') {
6015
+ body = this.json(query);
6016
+ preparedString += body;
6017
+ }
6018
+ else if (urlencoded) {
5780
6019
  preparedString += '?' + urlencoded;
5781
6020
  }
5782
6021
  preparedString += nonce + this.secret;
@@ -5786,14 +6025,11 @@ class coinex extends coinex$1 {
5786
6025
  'X-COINEX-SIGN': signature,
5787
6026
  'X-COINEX-TIMESTAMP': nonce,
5788
6027
  };
5789
- if ((method === 'GET') || (method === 'DELETE') || (method === 'PUT')) {
6028
+ if (method !== 'POST') {
5790
6029
  if (urlencoded) {
5791
6030
  url += '?' + urlencoded;
5792
6031
  }
5793
6032
  }
5794
- else {
5795
- body = this.json(query);
5796
- }
5797
6033
  }
5798
6034
  }
5799
6035
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };