ccxt 4.3.8 → 4.3.10

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/coinex.js CHANGED
@@ -1743,7 +1743,7 @@ export default class coinex extends Exchange {
1743
1743
  // "client_id": "",
1744
1744
  // }
1745
1745
  //
1746
- // Spot and Margin createOrder, createOrders, cancelOrder, cancelOrders, fetchOrder
1746
+ // Spot and Margin cancelOrder, fetchOrder
1747
1747
  //
1748
1748
  // {
1749
1749
  // "amount":"1.5",
@@ -1771,7 +1771,7 @@ export default class coinex extends Exchange {
1771
1771
  // "client_id": "",
1772
1772
  // }
1773
1773
  //
1774
- // Swap createOrder, cancelOrder, fetchOrder
1774
+ // Swap cancelOrder, fetchOrder
1775
1775
  //
1776
1776
  // {
1777
1777
  // "amount": "0.0005",
@@ -1808,10 +1808,6 @@ export default class coinex extends Exchange {
1808
1808
  // "user_id": 3620173
1809
1809
  // }
1810
1810
  //
1811
- // Stop order createOrder
1812
- //
1813
- // {"status":"success"}
1814
- //
1815
1811
  // Swap Stop cancelOrder, fetchOrder
1816
1812
  //
1817
1813
  // {
@@ -1942,67 +1938,146 @@ export default class coinex extends Exchange {
1942
1938
  // "user_id": 3620173
1943
1939
  // }
1944
1940
  //
1945
- // swap: cancelOrders
1941
+ // Spot and Margin createOrder, createOrders, cancelOrders v2
1946
1942
  //
1947
1943
  // {
1948
- // "amount": "0.0005",
1949
- // "client_id": "x-167673045-b0cee0c584718b65",
1950
- // "create_time": 1701233683.294231,
1951
- // "deal_asset_fee": "0.00000000000000000000",
1952
- // "deal_fee": "0.00000000000000000000",
1953
- // "deal_profit": "0.00000000000000000000",
1954
- // "deal_stock": "0.00000000000000000000",
1955
- // "effect_type": 1,
1956
- // "fee_asset": "",
1957
- // "fee_discount": "0.00000000000000000000",
1958
- // "last_deal_amount": "0.00000000000000000000",
1959
- // "last_deal_id": 0,
1960
- // "last_deal_price": "0.00000000000000000000",
1961
- // "last_deal_role": 0,
1962
- // "last_deal_time": 0,
1963
- // "last_deal_type": 0,
1964
- // "left": "0.0005",
1944
+ // "amount": "0.0001",
1945
+ // "base_fee": "0",
1946
+ // "ccy": "BTC",
1947
+ // "client_id": "x-167673045-a0a3c6461459a801",
1948
+ // "created_at": 1714114386250,
1949
+ // "discount_fee": "0",
1950
+ // "filled_amount": "0",
1951
+ // "filled_value": "0",
1952
+ // "last_fill_amount": "0",
1953
+ // "last_fill_price": "0",
1954
+ // "maker_fee_rate": "0.002",
1955
+ // "market": "BTCUSDT",
1956
+ // "market_type": "SPOT",
1957
+ // "order_id": 117178743547,
1958
+ // "price": "61000",
1959
+ // "quote_fee": "0",
1960
+ // "side": "buy",
1961
+ // "taker_fee_rate": "0.002",
1962
+ // "type": "limit",
1963
+ // "unfilled_amount": "0.0001",
1964
+ // "updated_at": 1714114386250
1965
+ // }
1966
+ //
1967
+ // Spot, Margin and Swap trigger createOrder, createOrders v2
1968
+ //
1969
+ // {
1970
+ // "stop_id": 117180138153
1971
+ // }
1972
+ //
1973
+ // Swap createOrder, createOrders, cancelOrders v2
1974
+ //
1975
+ // {
1976
+ // "amount": "0.0001",
1977
+ // "client_id": "x-167673045-1471b81d747080a0",
1978
+ // "created_at": 1714116769986,
1979
+ // "fee": "0",
1980
+ // "fee_ccy": "USDT",
1981
+ // "filled_amount": "0",
1982
+ // "filled_value": "0",
1983
+ // "last_filled_amount": "0",
1984
+ // "last_filled_price": "0",
1985
+ // "maker_fee_rate": "0.0003",
1986
+ // "market": "BTCUSDT",
1987
+ // "market_type": "FUTURES",
1988
+ // "order_id": 136913377780,
1989
+ // "price": "61000.42",
1990
+ // "realized_pnl": "0",
1991
+ // "side": "buy",
1992
+ // "taker_fee_rate": "0.0005",
1993
+ // "type": "limit",
1994
+ // "unfilled_amount": "0.0001",
1995
+ // "updated_at": 1714116769986
1996
+ // }
1997
+ //
1998
+ // Swap stopLossPrice and takeProfitPrice createOrder v2
1999
+ //
2000
+ // {
2001
+ // "adl_level": 1,
2002
+ // "ath_margin_size": "2.14586666",
2003
+ // "ath_position_amount": "0.0001",
2004
+ // "avg_entry_price": "64376",
2005
+ // "bkr_price": "0",
2006
+ // "close_avbl": "0.0001",
2007
+ // "cml_position_value": "6.4376",
2008
+ // "created_at": 1714119054558,
1965
2009
  // "leverage": "3",
1966
- // "maker_fee": "0.00030",
2010
+ // "liq_price": "0",
2011
+ // "maintenance_margin_rate": "0.005",
2012
+ // "maintenance_margin_value": "0.03218632",
2013
+ // "margin_avbl": "2.14586666",
2014
+ // "margin_mode": "cross",
1967
2015
  // "market": "BTCUSDT",
1968
- // "option": 0,
1969
- // "order_id": 115940476323,
1970
- // "position_id": 0,
1971
- // "position_type": 2,
1972
- // "price": "25000.00",
1973
- // "side": 2,
1974
- // "source": "api.v1",
1975
- // "stop_id": 0,
1976
- // "stop_loss_price": "0.00000000000000000000",
1977
- // "stop_loss_type": 0,
1978
- // "take_profit_price": "0.00000000000000000000",
1979
- // "take_profit_type": 0,
1980
- // "taker_fee": "0.00050",
1981
- // "target": 0,
1982
- // "type": 1,
1983
- // "update_time": 1701233721.718884,
1984
- // "user_id": 3620173
2016
+ // "market_type": "FUTURES",
2017
+ // "max_position_value": "6.4376",
2018
+ // "open_interest": "0.0001",
2019
+ // "position_id": 303884204,
2020
+ // "position_margin_rate": "3.10624785634397912265",
2021
+ // "realized_pnl": "-0.0032188",
2022
+ // "settle_price": "64376",
2023
+ // "settle_value": "6.4376",
2024
+ // "side": "long",
2025
+ // "stop_loss_price": "62000",
2026
+ // "stop_loss_type": "latest_price",
2027
+ // "take_profit_price": "0",
2028
+ // "take_profit_type": "",
2029
+ // "unrealized_pnl": "0",
2030
+ // "updated_at": 1714119054559
2031
+ // }
2032
+ //
2033
+ // Swap and Spot stop cancelOrders v2
2034
+ //
2035
+ // {
2036
+ // "amount": "0.0001",
2037
+ // "client_id": "x-167673045-a7d7714c6478acf6",
2038
+ // "created_at": 1714187923820,
2039
+ // "market": "BTCUSDT",
2040
+ // "market_type": "FUTURES",
2041
+ // "price": "61000",
2042
+ // "side": "buy",
2043
+ // "stop_id": 136984426097,
2044
+ // "trigger_direction": "higher",
2045
+ // "trigger_price": "62000",
2046
+ // "trigger_price_type": "latest_price",
2047
+ // "type": "limit",
2048
+ // "updated_at": 1714187974363
1985
2049
  // }
1986
2050
  //
1987
2051
  const rawStatus = this.safeString(order, 'status');
1988
- const timestamp = this.safeTimestamp(order, 'create_time');
2052
+ let timestamp = this.safeTimestamp(order, 'create_time');
2053
+ if (timestamp === undefined) {
2054
+ timestamp = this.safeInteger(order, 'created_at');
2055
+ }
2056
+ let update = this.safeTimestamp(order, 'update_time');
2057
+ if (update === undefined) {
2058
+ update = this.safeInteger(order, 'updated_at');
2059
+ }
1989
2060
  const marketId = this.safeString(order, 'market');
1990
2061
  const defaultType = this.safeString(this.options, 'defaultType');
1991
2062
  const orderType = ('source' in order) ? 'swap' : defaultType;
1992
2063
  market = this.safeMarket(marketId, market, undefined, orderType);
1993
- const feeCurrencyId = this.safeString(order, 'fee_asset');
2064
+ const feeCurrencyId = this.safeString2(order, 'fee_asset', 'fee_ccy');
1994
2065
  let feeCurrency = this.safeCurrencyCode(feeCurrencyId);
1995
2066
  if (feeCurrency === undefined) {
1996
2067
  feeCurrency = market['quote'];
1997
2068
  }
1998
- const rawSide = this.safeInteger(order, 'side');
2069
+ const rawIntegerSide = this.safeInteger(order, 'side');
2070
+ const rawStringSide = this.safeString(order, 'side');
1999
2071
  let side = undefined;
2000
- if (rawSide === 1) {
2072
+ if (rawIntegerSide === 1) {
2001
2073
  side = 'sell';
2002
2074
  }
2003
- else if (rawSide === 2) {
2075
+ else if (rawIntegerSide === 2) {
2004
2076
  side = 'buy';
2005
2077
  }
2078
+ else if ((rawStringSide === 'buy') || (rawStringSide === 'sell')) {
2079
+ side = rawStringSide;
2080
+ }
2006
2081
  else {
2007
2082
  side = this.safeString(order, 'type');
2008
2083
  }
@@ -2010,12 +2085,19 @@ export default class coinex extends Exchange {
2010
2085
  let type = undefined;
2011
2086
  if (rawType === undefined) {
2012
2087
  const typeInteger = this.safeInteger(order, 'type');
2088
+ const typeString = this.safeString(order, 'type');
2013
2089
  if (typeInteger === 1) {
2014
2090
  type = 'limit';
2015
2091
  }
2016
2092
  else if (typeInteger === 2) {
2017
2093
  type = 'market';
2018
2094
  }
2095
+ else if ((typeString === 'limit') || (typeString === 'market')) {
2096
+ type = typeString;
2097
+ }
2098
+ else if (typeString === 'maker_only') {
2099
+ type = 'limit';
2100
+ }
2019
2101
  }
2020
2102
  else {
2021
2103
  type = rawType;
@@ -2025,11 +2107,11 @@ export default class coinex extends Exchange {
2025
2107
  clientOrderId = undefined;
2026
2108
  }
2027
2109
  return this.safeOrder({
2028
- 'id': this.safeString2(order, 'id', 'order_id'),
2110
+ 'id': this.safeStringN(order, ['id', 'order_id', 'stop_id']),
2029
2111
  'clientOrderId': clientOrderId,
2030
2112
  'datetime': this.iso8601(timestamp),
2031
2113
  'timestamp': timestamp,
2032
- 'lastTradeTimestamp': this.safeTimestamp(order, 'update_time'),
2114
+ 'lastTradeTimestamp': update,
2033
2115
  'status': this.parseOrderStatus(rawStatus),
2034
2116
  'symbol': market['symbol'],
2035
2117
  'type': type,
@@ -2038,19 +2120,19 @@ export default class coinex extends Exchange {
2038
2120
  'reduceOnly': undefined,
2039
2121
  'side': side,
2040
2122
  'price': this.safeString(order, 'price'),
2041
- 'stopPrice': this.safeString(order, 'stop_price'),
2042
- 'triggerPrice': this.safeString(order, 'stop_price'),
2123
+ 'stopPrice': this.safeString2(order, 'stop_price', 'trigger_price'),
2124
+ 'triggerPrice': this.safeString2(order, 'stop_price', 'trigger_price'),
2043
2125
  'takeProfitPrice': this.safeNumber(order, 'take_profit_price'),
2044
2126
  'stopLossPrice': this.safeNumber(order, 'stop_loss_price'),
2045
- 'cost': this.safeString(order, 'deal_money'),
2046
- 'average': this.safeString(order, 'avg_price'),
2127
+ 'cost': this.safeString2(order, 'deal_money', 'filled_value'),
2128
+ 'average': this.safeString2(order, 'avg_price', 'avg_entry_price'),
2047
2129
  'amount': this.safeString(order, 'amount'),
2048
- 'filled': this.safeString(order, 'deal_amount'),
2049
- 'remaining': this.safeString(order, 'left'),
2130
+ 'filled': this.safeString2(order, 'deal_amount', 'filled_amount'),
2131
+ 'remaining': this.safeString2(order, 'left', 'unfilled_amount'),
2050
2132
  'trades': undefined,
2051
2133
  'fee': {
2052
2134
  'currency': feeCurrency,
2053
- 'cost': this.safeString(order, 'deal_fee'),
2135
+ 'cost': this.safeStringN(order, ['deal_fee', 'quote_fee', 'fee']),
2054
2136
  },
2055
2137
  'info': order,
2056
2138
  }, market);
@@ -2061,6 +2143,7 @@ export default class coinex extends Exchange {
2061
2143
  * @name coinex#createMarketBuyOrderWithCost
2062
2144
  * @description create a market buy order by providing the symbol and cost
2063
2145
  * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade003_market_order
2146
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-order
2064
2147
  * @param {string} symbol unified symbol of the market to create an order in
2065
2148
  * @param {float} cost how much you want to trade in units of the quote currency
2066
2149
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -2078,22 +2161,18 @@ export default class coinex extends Exchange {
2078
2161
  const market = this.market(symbol);
2079
2162
  const swap = market['swap'];
2080
2163
  const clientOrderId = this.safeString2(params, 'client_id', 'clientOrderId');
2081
- const stopPrice = this.safeValue2(params, 'stopPrice', 'triggerPrice');
2082
- const stopLossPrice = this.safeValue(params, 'stopLossPrice');
2083
- const takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
2164
+ const stopPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
2165
+ const stopLossPrice = this.safeString(params, 'stopLossPrice');
2166
+ const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
2084
2167
  const option = this.safeString(params, 'option');
2085
2168
  const isMarketOrder = type === 'market';
2086
- const postOnly = this.isPostOnly(isMarketOrder, option === 'MAKER_ONLY', params);
2087
- const positionId = this.safeInteger2(params, 'position_id', 'positionId'); // Required for closing swap positions
2088
- const timeInForceRaw = this.safeString(params, 'timeInForce'); // Spot: IOC, FOK, PO, GTC, ... NORMAL (default), MAKER_ONLY
2089
- const reduceOnly = this.safeValue(params, 'reduceOnly');
2169
+ const postOnly = this.isPostOnly(isMarketOrder, option === 'maker_only', params);
2170
+ const timeInForceRaw = this.safeStringUpper(params, 'timeInForce');
2171
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
2090
2172
  if (reduceOnly) {
2091
2173
  if (!market['swap']) {
2092
2174
  throw new InvalidOrder(this.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only');
2093
2175
  }
2094
- if (positionId === undefined) {
2095
- throw new ArgumentsRequired(this.id + ' createOrder() requires a position_id/positionId parameter for reduceOnly orders');
2096
- }
2097
2176
  }
2098
2177
  const request = {
2099
2178
  'market': market['id'],
@@ -2106,73 +2185,56 @@ export default class coinex extends Exchange {
2106
2185
  else {
2107
2186
  request['client_id'] = clientOrderId;
2108
2187
  }
2188
+ if ((stopLossPrice === undefined) && (takeProfitPrice === undefined)) {
2189
+ if (!reduceOnly) {
2190
+ request['side'] = side;
2191
+ }
2192
+ let requestType = type;
2193
+ if (postOnly) {
2194
+ requestType = 'maker_only';
2195
+ }
2196
+ else if (timeInForceRaw !== undefined) {
2197
+ if (timeInForceRaw === 'IOC') {
2198
+ requestType = 'ioc';
2199
+ }
2200
+ else if (timeInForceRaw === 'FOK') {
2201
+ requestType = 'fok';
2202
+ }
2203
+ }
2204
+ if (!isMarketOrder) {
2205
+ request['price'] = this.priceToPrecision(symbol, price);
2206
+ }
2207
+ request['type'] = requestType;
2208
+ }
2109
2209
  if (swap) {
2210
+ request['market_type'] = 'FUTURES';
2110
2211
  if (stopLossPrice || takeProfitPrice) {
2111
- request['stop_type'] = this.safeInteger(params, 'stop_type', 1); // 1: triggered by the latest transaction, 2: mark price, 3: index price
2112
- if (positionId === undefined) {
2113
- throw new ArgumentsRequired(this.id + ' createOrder() requires a position_id parameter for stop loss and take profit orders');
2114
- }
2115
- request['position_id'] = positionId;
2116
2212
  if (stopLossPrice) {
2117
2213
  request['stop_loss_price'] = this.priceToPrecision(symbol, stopLossPrice);
2214
+ request['stop_loss_type'] = this.safeString(params, 'stop_type', 'latest_price');
2118
2215
  }
2119
2216
  else if (takeProfitPrice) {
2120
2217
  request['take_profit_price'] = this.priceToPrecision(symbol, takeProfitPrice);
2218
+ request['take_profit_type'] = this.safeString(params, 'stop_type', 'latest_price');
2121
2219
  }
2122
2220
  }
2123
2221
  else {
2124
- const requestSide = (side === 'buy') ? 2 : 1;
2222
+ request['amount'] = this.amountToPrecision(symbol, amount);
2125
2223
  if (stopPrice !== undefined) {
2126
- request['stop_price'] = this.priceToPrecision(symbol, stopPrice);
2127
- request['stop_type'] = this.safeInteger(params, 'stop_type', 1); // 1: triggered by the latest transaction, 2: mark price, 3: index price;
2128
- request['amount'] = this.amountToPrecision(symbol, amount);
2129
- request['side'] = requestSide;
2130
- if (type === 'limit') {
2131
- request['price'] = this.priceToPrecision(symbol, price);
2132
- }
2133
- request['amount'] = this.amountToPrecision(symbol, amount);
2134
- }
2135
- let timeInForce = undefined;
2136
- if ((type !== 'market') || (stopPrice !== undefined)) {
2137
- if (postOnly) {
2138
- request['option'] = 1;
2139
- }
2140
- else if (timeInForceRaw !== undefined) {
2141
- if (timeInForceRaw === 'IOC') {
2142
- timeInForce = 2;
2143
- }
2144
- else if (timeInForceRaw === 'FOK') {
2145
- timeInForce = 3;
2146
- }
2147
- else {
2148
- timeInForce = 1;
2149
- }
2150
- request['effect_type'] = timeInForce; // exchange takes 'IOC' and 'FOK'
2151
- }
2152
- }
2153
- if (type === 'limit' && stopPrice === undefined) {
2154
- if (reduceOnly) {
2155
- request['position_id'] = positionId;
2156
- }
2157
- else {
2158
- request['side'] = requestSide;
2159
- }
2160
- request['price'] = this.priceToPrecision(symbol, price);
2161
- request['amount'] = this.amountToPrecision(symbol, amount);
2162
- }
2163
- else if (type === 'market' && stopPrice === undefined) {
2164
- if (reduceOnly) {
2165
- request['position_id'] = positionId;
2166
- }
2167
- else {
2168
- request['side'] = requestSide;
2169
- request['amount'] = this.amountToPrecision(symbol, amount);
2170
- }
2224
+ request['trigger_price'] = this.priceToPrecision(symbol, stopPrice);
2225
+ request['trigger_price_type'] = this.safeString(params, 'stop_type', 'latest_price');
2171
2226
  }
2172
2227
  }
2173
2228
  }
2174
2229
  else {
2175
- request['type'] = side;
2230
+ let marginMode = undefined;
2231
+ [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2232
+ if (marginMode !== undefined) {
2233
+ request['market_type'] = 'MARGIN';
2234
+ }
2235
+ else {
2236
+ request['market_type'] = 'SPOT';
2237
+ }
2176
2238
  if ((type === 'market') && (side === 'buy')) {
2177
2239
  let createMarketBuyOrderRequiresPrice = true;
2178
2240
  [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
@@ -2197,39 +2259,11 @@ export default class coinex extends Exchange {
2197
2259
  else {
2198
2260
  request['amount'] = this.amountToPrecision(symbol, amount);
2199
2261
  }
2200
- if ((type === 'limit') || (type === 'ioc')) {
2201
- request['price'] = this.priceToPrecision(symbol, price);
2202
- }
2203
2262
  if (stopPrice !== undefined) {
2204
- request['stop_price'] = this.priceToPrecision(symbol, stopPrice);
2263
+ request['trigger_price'] = this.priceToPrecision(symbol, stopPrice);
2205
2264
  }
2206
- if ((type !== 'market') || (stopPrice !== undefined)) {
2207
- // following options cannot be applied to vanilla market orders (but can be applied to stop-market orders)
2208
- if ((timeInForceRaw !== undefined) || postOnly) {
2209
- if ((postOnly || (timeInForceRaw !== 'IOC')) && ((type === 'limit') && (stopPrice !== undefined))) {
2210
- throw new InvalidOrder(this.id + ' createOrder() only supports the IOC option for stop-limit orders');
2211
- }
2212
- if (postOnly) {
2213
- request['option'] = 'MAKER_ONLY';
2214
- }
2215
- else {
2216
- if (timeInForceRaw !== undefined) {
2217
- request['option'] = timeInForceRaw; // exchange takes 'IOC' and 'FOK'
2218
- }
2219
- }
2220
- }
2221
- }
2222
- }
2223
- const accountId = this.safeInteger(params, 'account_id');
2224
- let marginMode = undefined;
2225
- [marginMode, params] = this.handleMarginModeAndParams('createOrder', params);
2226
- if (marginMode !== undefined) {
2227
- if (accountId === undefined) {
2228
- throw new BadRequest(this.id + ' createOrder() requires an account_id parameter for margin orders');
2229
- }
2230
- request['account_id'] = accountId;
2231
2265
  }
2232
- params = this.omit(params, ['reduceOnly', 'positionId', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
2266
+ params = this.omit(params, ['reduceOnly', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
2233
2267
  return this.extend(request, params);
2234
2268
  }
2235
2269
  async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
@@ -2237,17 +2271,13 @@ export default class coinex extends Exchange {
2237
2271
  * @method
2238
2272
  * @name coinex#createOrder
2239
2273
  * @description create a trade order
2240
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade001_limit_order
2241
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade003_market_order
2242
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade004_IOC_order
2243
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade005_stop_limit_order
2244
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade006_stop_market_order
2245
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http017_put_limit
2246
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http018_put_market
2247
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http019_put_limit_stop
2248
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http020_put_market_stop
2249
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http031_market_close
2250
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http030_limit_close
2274
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-order
2275
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-stop-order
2276
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-order
2277
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-stop-order
2278
+ * @see https://docs.coinex.com/api/v2/futures/position/http/close-position
2279
+ * @see https://docs.coinex.com/api/v2/futures/position/http/set-position-stop-loss
2280
+ * @see https://docs.coinex.com/api/v2/futures/position/http/set-position-take-profit
2251
2281
  * @param {string} symbol unified symbol of the market to create an order in
2252
2282
  * @param {string} type 'market' or 'limit'
2253
2283
  * @param {string} side 'buy' or 'sell'
@@ -2260,15 +2290,14 @@ export default class coinex extends Exchange {
2260
2290
  * @param {string} [params.timeInForce] 'GTC', 'IOC', 'FOK', 'PO'
2261
2291
  * @param {boolean} [params.postOnly] set to true if you wish to make a post only order
2262
2292
  * @param {boolean} [params.reduceOnly] *contract only* indicates if this order is to reduce the size of a position
2263
- * @param {int} [params.position_id] *required for reduce only orders* the position id to reduce
2264
2293
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2265
2294
  */
2266
2295
  await this.loadMarkets();
2267
2296
  const market = this.market(symbol);
2268
- const reduceOnly = this.safeValue(params, 'reduceOnly');
2269
- const triggerPrice = this.safeNumber2(params, 'stopPrice', 'triggerPrice');
2270
- const stopLossTriggerPrice = this.safeNumber(params, 'stopLossPrice');
2271
- const takeProfitTriggerPrice = this.safeNumber(params, 'takeProfitPrice');
2297
+ const reduceOnly = this.safeBool(params, 'reduceOnly');
2298
+ const triggerPrice = this.safeString2(params, 'stopPrice', 'triggerPrice');
2299
+ const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
2300
+ const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
2272
2301
  const isTriggerOrder = triggerPrice !== undefined;
2273
2302
  const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
2274
2303
  const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
@@ -2277,135 +2306,212 @@ export default class coinex extends Exchange {
2277
2306
  let response = undefined;
2278
2307
  if (market['spot']) {
2279
2308
  if (isTriggerOrder) {
2280
- if (type === 'limit') {
2281
- response = await this.v1PrivatePostOrderStopLimit(request);
2282
- }
2283
- else {
2284
- response = await this.v1PrivatePostOrderStopMarket(request);
2285
- }
2309
+ response = await this.v2PrivatePostSpotStopOrder(request);
2310
+ //
2311
+ // {
2312
+ // "code": 0,
2313
+ // "data": {
2314
+ // "stop_id": 117180138153
2315
+ // },
2316
+ // "message": "OK"
2317
+ // }
2318
+ //
2286
2319
  }
2287
2320
  else {
2288
- if (type === 'limit') {
2289
- response = await this.v1PrivatePostOrderLimit(request);
2290
- }
2291
- else {
2292
- response = await this.v1PrivatePostOrderMarket(request);
2293
- }
2321
+ response = await this.v2PrivatePostSpotOrder(request);
2322
+ //
2323
+ // {
2324
+ // "code": 0,
2325
+ // "data": {
2326
+ // "amount": "0.0001",
2327
+ // "base_fee": "0",
2328
+ // "ccy": "BTC",
2329
+ // "client_id": "x-167673045-a0a3c6461459a801",
2330
+ // "created_at": 1714114386250,
2331
+ // "discount_fee": "0",
2332
+ // "filled_amount": "0",
2333
+ // "filled_value": "0",
2334
+ // "last_fill_amount": "0",
2335
+ // "last_fill_price": "0",
2336
+ // "maker_fee_rate": "0.002",
2337
+ // "market": "BTCUSDT",
2338
+ // "market_type": "SPOT",
2339
+ // "order_id": 117178743547,
2340
+ // "price": "61000",
2341
+ // "quote_fee": "0",
2342
+ // "side": "buy",
2343
+ // "taker_fee_rate": "0.002",
2344
+ // "type": "limit",
2345
+ // "unfilled_amount": "0.0001",
2346
+ // "updated_at": 1714114386250
2347
+ // },
2348
+ // "message": "OK"
2349
+ // }
2350
+ //
2294
2351
  }
2295
2352
  }
2296
2353
  else {
2297
2354
  if (isTriggerOrder) {
2298
- if (type === 'limit') {
2299
- response = await this.v1PerpetualPrivatePostOrderPutStopLimit(request);
2300
- }
2301
- else {
2302
- response = await this.v1PerpetualPrivatePostOrderPutStopMarket(request);
2303
- }
2355
+ response = await this.v2PrivatePostFuturesStopOrder(request);
2356
+ //
2357
+ // {
2358
+ // "code": 0,
2359
+ // "data": {
2360
+ // "stop_id": 136915460994
2361
+ // },
2362
+ // "message": "OK"
2363
+ // }
2364
+ //
2304
2365
  }
2305
2366
  else if (isStopLossOrTakeProfitTrigger) {
2306
2367
  if (isStopLossTriggerOrder) {
2307
- response = await this.v1PerpetualPrivatePostPositionStopLoss(request);
2368
+ response = await this.v2PrivatePostFuturesSetPositionStopLoss(request);
2369
+ //
2370
+ // {
2371
+ // "code": 0,
2372
+ // "data": {
2373
+ // "adl_level": 1,
2374
+ // "ath_margin_size": "2.14586666",
2375
+ // "ath_position_amount": "0.0001",
2376
+ // "avg_entry_price": "64376",
2377
+ // "bkr_price": "0",
2378
+ // "close_avbl": "0.0001",
2379
+ // "cml_position_value": "6.4376",
2380
+ // "created_at": 1714119054558,
2381
+ // "leverage": "3",
2382
+ // "liq_price": "0",
2383
+ // "maintenance_margin_rate": "0.005",
2384
+ // "maintenance_margin_value": "0.03218632",
2385
+ // "margin_avbl": "2.14586666",
2386
+ // "margin_mode": "cross",
2387
+ // "market": "BTCUSDT",
2388
+ // "market_type": "FUTURES",
2389
+ // "max_position_value": "6.4376",
2390
+ // "open_interest": "0.0001",
2391
+ // "position_id": 303884204,
2392
+ // "position_margin_rate": "3.10624785634397912265",
2393
+ // "realized_pnl": "-0.0032188",
2394
+ // "settle_price": "64376",
2395
+ // "settle_value": "6.4376",
2396
+ // "side": "long",
2397
+ // "stop_loss_price": "62000",
2398
+ // "stop_loss_type": "latest_price",
2399
+ // "take_profit_price": "0",
2400
+ // "take_profit_type": "",
2401
+ // "unrealized_pnl": "0",
2402
+ // "updated_at": 1714119054559
2403
+ // },
2404
+ // "message": "OK"
2405
+ // }
2406
+ //
2308
2407
  }
2309
2408
  else if (isTakeProfitTriggerOrder) {
2310
- response = await this.v1PerpetualPrivatePostPositionTakeProfit(request);
2409
+ response = await this.v2PrivatePostFuturesSetPositionTakeProfit(request);
2410
+ //
2411
+ // {
2412
+ // "code": 0,
2413
+ // "data": {
2414
+ // "adl_level": 1,
2415
+ // "ath_margin_size": "2.14586666",
2416
+ // "ath_position_amount": "0.0001",
2417
+ // "avg_entry_price": "64376",
2418
+ // "bkr_price": "0",
2419
+ // "close_avbl": "0.0001",
2420
+ // "cml_position_value": "6.4376",
2421
+ // "created_at": 1714119054558,
2422
+ // "leverage": "3",
2423
+ // "liq_price": "0",
2424
+ // "maintenance_margin_rate": "0.005",
2425
+ // "maintenance_margin_value": "0.03218632",
2426
+ // "margin_avbl": "2.14586666",
2427
+ // "margin_mode": "cross",
2428
+ // "market": "BTCUSDT",
2429
+ // "market_type": "FUTURES",
2430
+ // "max_position_value": "6.4376",
2431
+ // "open_interest": "0.0001",
2432
+ // "position_id": 303884204,
2433
+ // "position_margin_rate": "3.10624785634397912265",
2434
+ // "realized_pnl": "-0.0032188",
2435
+ // "settle_price": "64376",
2436
+ // "settle_value": "6.4376",
2437
+ // "side": "long",
2438
+ // "stop_loss_price": "62000",
2439
+ // "stop_loss_type": "latest_price",
2440
+ // "take_profit_price": "70000",
2441
+ // "take_profit_type": "latest_price",
2442
+ // "unrealized_pnl": "0",
2443
+ // "updated_at": 1714119054559
2444
+ // },
2445
+ // "message": "OK"
2446
+ // }
2447
+ //
2311
2448
  }
2312
2449
  }
2313
2450
  else {
2314
2451
  if (reduceOnly) {
2315
- if (type === 'limit') {
2316
- response = await this.v1PerpetualPrivatePostOrderCloseLimit(request);
2317
- }
2318
- else {
2319
- response = await this.v1PerpetualPrivatePostOrderCloseMarket(request);
2320
- }
2452
+ response = await this.v2PrivatePostFuturesClosePosition(request);
2453
+ //
2454
+ // {
2455
+ // "code": 0,
2456
+ // "data": {
2457
+ // "amount": "0.0001",
2458
+ // "client_id": "x-167673045-4f264600c432ac06",
2459
+ // "created_at": 1714119323764,
2460
+ // "fee": "0.003221",
2461
+ // "fee_ccy": "USDT",
2462
+ // "filled_amount": "0.0001",
2463
+ // "filled_value": "6.442017",
2464
+ // "last_filled_amount": "0.0001",
2465
+ // "last_filled_price": "64420.17",
2466
+ // "maker_fee_rate": "0",
2467
+ // "market": "BTCUSDT",
2468
+ // "market_type": "FUTURES",
2469
+ // "order_id": 136915813578,
2470
+ // "price": "0",
2471
+ // "realized_pnl": "0.004417",
2472
+ // "side": "sell",
2473
+ // "taker_fee_rate": "0.0005",
2474
+ // "type": "market",
2475
+ // "unfilled_amount": "0",
2476
+ // "updated_at": 1714119323764
2477
+ // },
2478
+ // "message": "OK"
2479
+ // }
2480
+ //
2321
2481
  }
2322
2482
  else {
2323
- if (type === 'limit') {
2324
- response = await this.v1PerpetualPrivatePostOrderPutLimit(request);
2325
- }
2326
- else {
2327
- response = await this.v1PerpetualPrivatePostOrderPutMarket(request);
2328
- }
2483
+ response = await this.v2PrivatePostFuturesOrder(request);
2484
+ //
2485
+ // {
2486
+ // "code": 0,
2487
+ // "data": {
2488
+ // "amount": "0.0001",
2489
+ // "client_id": "x-167673045-1471b81d747080a0",
2490
+ // "created_at": 1714116769986,
2491
+ // "fee": "0",
2492
+ // "fee_ccy": "USDT",
2493
+ // "filled_amount": "0",
2494
+ // "filled_value": "0",
2495
+ // "last_filled_amount": "0",
2496
+ // "last_filled_price": "0",
2497
+ // "maker_fee_rate": "0.0003",
2498
+ // "market": "BTCUSDT",
2499
+ // "market_type": "FUTURES",
2500
+ // "order_id": 136913377780,
2501
+ // "price": "61000.42",
2502
+ // "realized_pnl": "0",
2503
+ // "side": "buy",
2504
+ // "taker_fee_rate": "0.0005",
2505
+ // "type": "limit",
2506
+ // "unfilled_amount": "0.0001",
2507
+ // "updated_at": 1714116769986
2508
+ // },
2509
+ // "message": "OK"
2510
+ // }
2511
+ //
2329
2512
  }
2330
2513
  }
2331
2514
  }
2332
- //
2333
- // Spot and Margin
2334
- //
2335
- // {
2336
- // "code": 0,
2337
- // "data": {
2338
- // "amount": "0.0005",
2339
- // "asset_fee": "0",
2340
- // "avg_price": "0.00",
2341
- // "client_id": "",
2342
- // "create_time": 1650951627,
2343
- // "deal_amount": "0",
2344
- // "deal_fee": "0",
2345
- // "deal_money": "0",
2346
- // "fee_asset": null,
2347
- // "fee_discount": "1",
2348
- // "finished_time": null,
2349
- // "id": 74510932594,
2350
- // "left": "0.0005",
2351
- // "maker_fee_rate": "0.002",
2352
- // "market": "BTCUSDT",
2353
- // "money_fee": "0",
2354
- // "order_type": "limit",
2355
- // "price": "30000",
2356
- // "status": "not_deal",
2357
- // "stock_fee": "0",
2358
- // "taker_fee_rate": "0.002",
2359
- // "type": "buy"
2360
- // },
2361
- // "message": "Success"
2362
- // }
2363
- //
2364
- // Swap
2365
- //
2366
- // {
2367
- // "code": 0,
2368
- // "data": {
2369
- // "amount": "0.0005",
2370
- // "client_id": "",
2371
- // "create_time": 1651004578.618224,
2372
- // "deal_asset_fee": "0.00000000000000000000",
2373
- // "deal_fee": "0.00000000000000000000",
2374
- // "deal_profit": "0.00000000000000000000",
2375
- // "deal_stock": "0.00000000000000000000",
2376
- // "effect_type": 1,
2377
- // "fee_asset": "",
2378
- // "fee_discount": "0.00000000000000000000",
2379
- // "last_deal_amount": "0.00000000000000000000",
2380
- // "last_deal_id": 0,
2381
- // "last_deal_price": "0.00000000000000000000",
2382
- // "last_deal_role": 0,
2383
- // "last_deal_time": 0,
2384
- // "last_deal_type": 0,
2385
- // "left": "0.0005",
2386
- // "leverage": "3",
2387
- // "maker_fee": "0.00030",
2388
- // "market": "BTCUSDT",
2389
- // "order_id": 18221659097,
2390
- // "position_id": 0,
2391
- // "position_type": 1,
2392
- // "price": "30000.00",
2393
- // "side": 2,
2394
- // "source": "api.v1",
2395
- // "stop_id": 0,
2396
- // "taker_fee": "0.00050",
2397
- // "target": 0,
2398
- // "type": 1,
2399
- // "update_time": 1651004578.618224,
2400
- // "user_id": 3620173
2401
- // },
2402
- // "message": "OK"
2403
- // }
2404
- //
2405
- // Stop Order
2406
- //
2407
- // {"code":0,"data":{"status":"success"},"message":"OK"}
2408
- //
2409
2515
  const data = this.safeDict(response, 'data', {});
2410
2516
  return this.parseOrder(data, market);
2411
2517
  }
@@ -2414,7 +2520,10 @@ export default class coinex extends Exchange {
2414
2520
  * @method
2415
2521
  * @name coinex#createOrders
2416
2522
  * @description create a list of trade orders (all orders should be of the same symbol)
2417
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade002_batch_limit_orders
2523
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-multi-order
2524
+ * @see https://docs.coinex.com/api/v2/spot/order/http/put-multi-stop-order
2525
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-multi-order
2526
+ * @see https://docs.coinex.com/api/v2/futures/order/http/put-multi-stop-order
2418
2527
  * @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
2419
2528
  * @param {object} [params] extra parameters specific to the api endpoint
2420
2529
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
@@ -2422,6 +2531,9 @@ export default class coinex extends Exchange {
2422
2531
  await this.loadMarkets();
2423
2532
  const ordersRequests = [];
2424
2533
  let symbol = undefined;
2534
+ let reduceOnly = false;
2535
+ let isTriggerOrder = false;
2536
+ let isStopLossOrTakeProfitTrigger = false;
2425
2537
  for (let i = 0; i < orders.length; i++) {
2426
2538
  const rawOrder = orders[i];
2427
2539
  const marketId = this.safeString(rawOrder, 'symbol');
@@ -2441,56 +2553,148 @@ export default class coinex extends Exchange {
2441
2553
  if (type !== 'limit') {
2442
2554
  throw new NotSupported(this.id + ' createOrders() does not support ' + type + ' orders, only limit orders are accepted');
2443
2555
  }
2556
+ reduceOnly = this.safeValue(orderParams, 'reduceOnly');
2557
+ const triggerPrice = this.safeNumber2(orderParams, 'stopPrice', 'triggerPrice');
2558
+ const stopLossTriggerPrice = this.safeNumber(orderParams, 'stopLossPrice');
2559
+ const takeProfitTriggerPrice = this.safeNumber(orderParams, 'takeProfitPrice');
2560
+ isTriggerOrder = triggerPrice !== undefined;
2561
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
2562
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
2563
+ isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
2444
2564
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, orderParams);
2445
2565
  ordersRequests.push(orderRequest);
2446
2566
  }
2447
2567
  const market = this.market(symbol);
2448
- if (!market['spot']) {
2449
- throw new NotSupported(this.id + ' createOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted');
2450
- }
2451
2568
  const request = {
2452
2569
  'market': market['id'],
2453
- 'batch_orders': this.json(ordersRequests),
2570
+ 'orders': ordersRequests,
2454
2571
  };
2455
- const response = await this.v1PrivatePostOrderLimitBatch(request);
2456
- //
2457
- // {
2458
- // "code": 0,
2459
- // "data": [
2460
- // {
2461
- // "code": 0,
2462
- // "data": {
2463
- // "amount": "0.0005",
2464
- // "asset_fee": "0",
2465
- // "avg_price": "0.00",
2466
- // "client_id": "x-167673045-d34bfb41242d8fd1",
2467
- // "create_time": 1701229157,
2468
- // "deal_amount": "0",
2469
- // "deal_fee": "0",
2470
- // "deal_money": "0",
2471
- // "fee_asset": null,
2472
- // "fee_discount": "1",
2473
- // "finished_time": null,
2474
- // "id": 107745856676,
2475
- // "left": "0.0005",
2476
- // "maker_fee_rate": "0.002",
2477
- // "market": "BTCUSDT",
2478
- // "money_fee": "0",
2479
- // "order_type": "limit",
2480
- // "price": "23000",
2481
- // "source_id": "",
2482
- // "status": "not_deal",
2483
- // "stock_fee": "0",
2484
- // "taker_fee_rate": "0.002",
2485
- // "type": "buy"
2486
- // },
2487
- // "message": "OK"
2488
- // },
2489
- // ],
2490
- // "message": "Success"
2491
- // }
2492
- //
2493
- const data = this.safeValue(response, 'data', []);
2572
+ let response = undefined;
2573
+ if (market['spot']) {
2574
+ if (isTriggerOrder) {
2575
+ response = await this.v2PrivatePostSpotBatchStopOrder(request);
2576
+ //
2577
+ // {
2578
+ // "code": 0,
2579
+ // "data": [
2580
+ // {
2581
+ // "code": 0,
2582
+ // "data": {
2583
+ // "stop_id": 117186257510
2584
+ // },
2585
+ // "message": "OK"
2586
+ // },
2587
+ // ],
2588
+ // "message": "OK"
2589
+ // }
2590
+ //
2591
+ }
2592
+ else {
2593
+ response = await this.v2PrivatePostSpotBatchOrder(request);
2594
+ //
2595
+ // {
2596
+ // "code": 0,
2597
+ // "data": [
2598
+ // {
2599
+ // "amount": "0.0001",
2600
+ // "base_fee": "0",
2601
+ // "ccy": "BTC",
2602
+ // "client_id": "x-167673045-f3651372049dab0d",
2603
+ // "created_at": 1714121403450,
2604
+ // "discount_fee": "0",
2605
+ // "filled_amount": "0",
2606
+ // "filled_value": "0",
2607
+ // "last_fill_amount": "0",
2608
+ // "last_fill_price": "0",
2609
+ // "maker_fee_rate": "0.002",
2610
+ // "market": "BTCUSDT",
2611
+ // "market_type": "SPOT",
2612
+ // "order_id": 117185362233,
2613
+ // "price": "61000",
2614
+ // "quote_fee": "0",
2615
+ // "side": "buy",
2616
+ // "taker_fee_rate": "0.002",
2617
+ // "type": "limit",
2618
+ // "unfilled_amount": "0.0001",
2619
+ // "updated_at": 1714121403450
2620
+ // },
2621
+ // {
2622
+ // "code": 3109,
2623
+ // "data": null,
2624
+ // "message": "balance not enough"
2625
+ // }
2626
+ // ],
2627
+ // "message": "OK"
2628
+ // }
2629
+ //
2630
+ }
2631
+ }
2632
+ else {
2633
+ if (isTriggerOrder) {
2634
+ response = await this.v2PrivatePostFuturesBatchStopOrder(request);
2635
+ //
2636
+ // {
2637
+ // "code": 0,
2638
+ // "data": [
2639
+ // {
2640
+ // "code": 0,
2641
+ // "data": {
2642
+ // "stop_id": 136919625994
2643
+ // },
2644
+ // "message": "OK"
2645
+ // },
2646
+ // ],
2647
+ // "message": "OK"
2648
+ // }
2649
+ //
2650
+ }
2651
+ else if (isStopLossOrTakeProfitTrigger) {
2652
+ throw new NotSupported(this.id + ' createOrders() does not support stopLossPrice or takeProfitPrice orders');
2653
+ }
2654
+ else {
2655
+ if (reduceOnly) {
2656
+ throw new NotSupported(this.id + ' createOrders() does not support reduceOnly orders');
2657
+ }
2658
+ else {
2659
+ response = await this.v2PrivatePostFuturesBatchOrder(request);
2660
+ //
2661
+ // {
2662
+ // "code": 0,
2663
+ // "data": [
2664
+ // {
2665
+ // "code": 0,
2666
+ // "data": {
2667
+ // "amount": "0.0001",
2668
+ // "client_id": "x-167673045-2cb7436f3462a654",
2669
+ // "created_at": 1714122832493,
2670
+ // "fee": "0",
2671
+ // "fee_ccy": "USDT",
2672
+ // "filled_amount": "0",
2673
+ // "filled_value": "0",
2674
+ // "last_filled_amount": "0",
2675
+ // "last_filled_price": "0",
2676
+ // "maker_fee_rate": "0.0003",
2677
+ // "market": "BTCUSDT",
2678
+ // "market_type": "FUTURES",
2679
+ // "order_id": 136918835063,
2680
+ // "price": "61000",
2681
+ // "realized_pnl": "0",
2682
+ // "side": "buy",
2683
+ // "taker_fee_rate": "0.0005",
2684
+ // "type": "limit",
2685
+ // "unfilled_amount": "0.0001",
2686
+ // "updated_at": 1714122832493
2687
+ // },
2688
+ // "message": "OK"
2689
+ // },
2690
+ // ],
2691
+ // "message": "OK"
2692
+ // }
2693
+ //
2694
+ }
2695
+ }
2696
+ }
2697
+ const data = this.safeList(response, 'data', []);
2494
2698
  const results = [];
2495
2699
  for (let i = 0; i < data.length; i++) {
2496
2700
  const entry = data[i];
@@ -2504,9 +2708,16 @@ export default class coinex extends Exchange {
2504
2708
  status = 'open';
2505
2709
  }
2506
2710
  }
2507
- const item = this.safeValue(entry, 'data', {});
2508
- item['status'] = status;
2509
- const order = this.parseOrder(item, market);
2711
+ const innerData = this.safeDict(entry, 'data', {});
2712
+ let order = undefined;
2713
+ if (market['spot'] && !isTriggerOrder) {
2714
+ entry['status'] = status;
2715
+ order = this.parseOrder(entry, market);
2716
+ }
2717
+ else {
2718
+ innerData['status'] = status;
2719
+ order = this.parseOrder(innerData, market);
2720
+ }
2510
2721
  results.push(order);
2511
2722
  }
2512
2723
  return results;
@@ -2516,11 +2727,14 @@ export default class coinex extends Exchange {
2516
2727
  * @method
2517
2728
  * @name coinex#cancelOrders
2518
2729
  * @description cancel multiple orders
2519
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade016_batch_cancel_order
2520
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http021-0_cancel_order_batch
2730
+ * @see https://docs.coinex.com/api/v2/spot/order/http/cancel-batch-order
2731
+ * @see https://docs.coinex.com/api/v2/spot/order/http/cancel-batch-stop-order
2732
+ * @see https://docs.coinex.com/api/v2/futures/order/http/cancel-batch-order
2733
+ * @see https://docs.coinex.com/api/v2/futures/order/http/cancel-batch-stop-order
2521
2734
  * @param {string[]} ids order ids
2522
2735
  * @param {string} symbol unified market symbol
2523
2736
  * @param {object} [params] extra parameters specific to the exchange API endpoint
2737
+ * @param {boolean} [params.stop] set to true for canceling stop orders
2524
2738
  * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2525
2739
  */
2526
2740
  if (symbol === undefined) {
@@ -2531,113 +2745,161 @@ export default class coinex extends Exchange {
2531
2745
  const request = {
2532
2746
  'market': market['id'],
2533
2747
  };
2534
- const idsString = ids.join(',');
2748
+ const stop = this.safeBool2(params, 'stop', 'trigger');
2749
+ params = this.omit(params, ['stop', 'trigger']);
2535
2750
  let response = undefined;
2751
+ if (stop) {
2752
+ request['stop_ids'] = ids;
2753
+ }
2754
+ else {
2755
+ request['order_ids'] = ids;
2756
+ }
2536
2757
  if (market['spot']) {
2537
- request['batch_ids'] = idsString;
2538
- response = await this.v1PrivateDeleteOrderPendingBatch(this.extend(request, params));
2758
+ if (stop) {
2759
+ response = await this.v2PrivatePostSpotCancelBatchStopOrder(this.extend(request, params));
2760
+ //
2761
+ // {
2762
+ // "code": 0,
2763
+ // "data": [
2764
+ // {
2765
+ // "code": 0,
2766
+ // "data": {
2767
+ // "amount": "0.0001",
2768
+ // "ccy": "BTC",
2769
+ // "client_id": "x-167673045-8e33d6f4a4bcb022",
2770
+ // "created_at": 1714188827291,
2771
+ // "market": "BTCUSDT",
2772
+ // "market_type": "SPOT",
2773
+ // "price": "61000",
2774
+ // "side": "buy",
2775
+ // "stop_id": 117248845854,
2776
+ // "trigger_direction": "higher",
2777
+ // "trigger_price": "62000",
2778
+ // "trigger_price_type": "mark_price",
2779
+ // "type": "limit",
2780
+ // "updated_at": 1714188827291
2781
+ // },
2782
+ // "message": "OK"
2783
+ // },
2784
+ // ],
2785
+ // "message": "OK"
2786
+ // }
2787
+ //
2788
+ }
2789
+ else {
2790
+ response = await this.v2PrivatePostSpotCancelBatchOrder(this.extend(request, params));
2791
+ //
2792
+ // {
2793
+ // "code": 0,
2794
+ // "data": [
2795
+ // {
2796
+ // "code": 0,
2797
+ // "data": {
2798
+ // "amount": "0.0001",
2799
+ // "base_fee": "0",
2800
+ // "ccy": "BTC",
2801
+ // "client_id": "x-167673045-c1cc78e5b42d8c4e",
2802
+ // "created_at": 1714188449497,
2803
+ // "discount_fee": "0",
2804
+ // "filled_amount": "0",
2805
+ // "filled_value": "0",
2806
+ // "last_fill_amount": "0",
2807
+ // "last_fill_price": "0",
2808
+ // "maker_fee_rate": "0.002",
2809
+ // "market": "BTCUSDT",
2810
+ // "market_type": "SPOT",
2811
+ // "order_id": 117248494358,
2812
+ // "price": "60000",
2813
+ // "quote_fee": "0",
2814
+ // "side": "buy",
2815
+ // "taker_fee_rate": "0.002",
2816
+ // "type": "limit",
2817
+ // "unfilled_amount": "0.0001",
2818
+ // "updated_at": 1714188449497
2819
+ // },
2820
+ // "message": ""
2821
+ // },
2822
+ // ],
2823
+ // "message": "OK"
2824
+ // }
2825
+ //
2826
+ }
2539
2827
  }
2540
2828
  else {
2541
- request['order_ids'] = idsString;
2542
- response = await this.v1PerpetualPrivatePostOrderCancelBatch(this.extend(request, params));
2829
+ request['market_type'] = 'FUTURES';
2830
+ if (stop) {
2831
+ response = await this.v2PrivatePostFuturesCancelBatchStopOrder(this.extend(request, params));
2832
+ //
2833
+ // {
2834
+ // "code": 0,
2835
+ // "data": [
2836
+ // {
2837
+ // "code": 0,
2838
+ // "data": {
2839
+ // "amount": "0.0001",
2840
+ // "client_id": "x-167673045-a7d7714c6478acf6",
2841
+ // "created_at": 1714187923820,
2842
+ // "market": "BTCUSDT",
2843
+ // "market_type": "FUTURES",
2844
+ // "price": "61000",
2845
+ // "side": "buy",
2846
+ // "stop_id": 136984426097,
2847
+ // "trigger_direction": "higher",
2848
+ // "trigger_price": "62000",
2849
+ // "trigger_price_type": "latest_price",
2850
+ // "type": "limit",
2851
+ // "updated_at": 1714187974363
2852
+ // },
2853
+ // "message": ""
2854
+ // },
2855
+ // ],
2856
+ // "message": "OK"
2857
+ // }
2858
+ //
2859
+ }
2860
+ else {
2861
+ response = await this.v2PrivatePostFuturesCancelBatchOrder(this.extend(request, params));
2862
+ //
2863
+ // {
2864
+ // "code": 0,
2865
+ // "data": [
2866
+ // {
2867
+ // "code": 0,
2868
+ // "data": {
2869
+ // "amount": "0.0001",
2870
+ // "client_id": "x-167673045-9f80fde284339a72",
2871
+ // "created_at": 1714187491784,
2872
+ // "fee": "0",
2873
+ // "fee_ccy": "USDT",
2874
+ // "filled_amount": "0",
2875
+ // "filled_value": "0",
2876
+ // "last_filled_amount": "0",
2877
+ // "last_filled_price": "0",
2878
+ // "maker_fee_rate": "0.0003",
2879
+ // "market": "BTCUSDT",
2880
+ // "market_type": "FUTURES",
2881
+ // "order_id": 136983851788,
2882
+ // "price": "61000",
2883
+ // "realized_pnl": "0",
2884
+ // "side": "buy",
2885
+ // "taker_fee_rate": "0.0005",
2886
+ // "type": "limit",
2887
+ // "unfilled_amount": "0.0001",
2888
+ // "updated_at": 1714187567079
2889
+ // },
2890
+ // "message": ""
2891
+ // },
2892
+ // ],
2893
+ // "message": "OK"
2894
+ // }
2895
+ //
2896
+ }
2543
2897
  }
2544
- //
2545
- // spot
2546
- //
2547
- // {
2548
- // "code": 0,
2549
- // "data": [
2550
- // {
2551
- // "code": 0,
2552
- // "data": {
2553
- // "account_id": 0,
2554
- // "amount": "0.0005",
2555
- // "asset_fee": "0",
2556
- // "avg_price": "0.00",
2557
- // "client_id": "x-167673045-d4e03c38f4d19b4e",
2558
- // "create_time": 1701229157,
2559
- // "deal_amount": "0",
2560
- // "deal_fee": "0",
2561
- // "deal_money": "0",
2562
- // "fee_asset": null,
2563
- // "fee_discount": "1",
2564
- // "finished_time": 0,
2565
- // "id": 107745856682,
2566
- // "left": "0",
2567
- // "maker_fee_rate": "0.002",
2568
- // "market": "BTCUSDT",
2569
- // "money_fee": "0",
2570
- // "order_type": "limit",
2571
- // "price": "22000",
2572
- // "status": "not_deal",
2573
- // "stock_fee": "0",
2574
- // "taker_fee_rate": "0.002",
2575
- // "type": "buy"
2576
- // },
2577
- // "message": ""
2578
- // },
2579
- // ],
2580
- // "message": "Success"
2581
- // }
2582
- //
2583
- // swap
2584
- //
2585
- // {
2586
- // "code": 0,
2587
- // "data": [
2588
- // {
2589
- // "code": 0,
2590
- // "message": "",
2591
- // "order": {
2592
- // "amount": "0.0005",
2593
- // "client_id": "x-167673045-b0cee0c584718b65",
2594
- // "create_time": 1701233683.294231,
2595
- // "deal_asset_fee": "0.00000000000000000000",
2596
- // "deal_fee": "0.00000000000000000000",
2597
- // "deal_profit": "0.00000000000000000000",
2598
- // "deal_stock": "0.00000000000000000000",
2599
- // "effect_type": 1,
2600
- // "fee_asset": "",
2601
- // "fee_discount": "0.00000000000000000000",
2602
- // "last_deal_amount": "0.00000000000000000000",
2603
- // "last_deal_id": 0,
2604
- // "last_deal_price": "0.00000000000000000000",
2605
- // "last_deal_role": 0,
2606
- // "last_deal_time": 0,
2607
- // "last_deal_type": 0,
2608
- // "left": "0.0005",
2609
- // "leverage": "3",
2610
- // "maker_fee": "0.00030",
2611
- // "market": "BTCUSDT",
2612
- // "option": 0,
2613
- // "order_id": 115940476323,
2614
- // "position_id": 0,
2615
- // "position_type": 2,
2616
- // "price": "25000.00",
2617
- // "side": 2,
2618
- // "source": "api.v1",
2619
- // "stop_id": 0,
2620
- // "stop_loss_price": "0.00000000000000000000",
2621
- // "stop_loss_type": 0,
2622
- // "take_profit_price": "0.00000000000000000000",
2623
- // "take_profit_type": 0,
2624
- // "taker_fee": "0.00050",
2625
- // "target": 0,
2626
- // "type": 1,
2627
- // "update_time": 1701233721.718884,
2628
- // "user_id": 3620173
2629
- // }
2630
- // },
2631
- // ],
2632
- // "message": "OK"
2633
- // }
2634
- //
2635
- const data = this.safeValue(response, 'data', []);
2898
+ const data = this.safeList(response, 'data', []);
2636
2899
  const results = [];
2637
2900
  for (let i = 0; i < data.length; i++) {
2638
2901
  const entry = data[i];
2639
- const dataRequest = market['spot'] ? 'data' : 'order';
2640
- const item = this.safeValue(entry, dataRequest, {});
2902
+ const item = this.safeDict(entry, 'data', {});
2641
2903
  const order = this.parseOrder(item, market);
2642
2904
  results.push(order);
2643
2905
  }
@@ -5779,7 +6041,11 @@ export default class coinex extends Exchange {
5779
6041
  query = this.keysort(query);
5780
6042
  const urlencoded = this.rawencode(query);
5781
6043
  let preparedString = method + '/' + version + '/' + path;
5782
- if (urlencoded) {
6044
+ if (method === 'POST') {
6045
+ body = this.json(query);
6046
+ preparedString += body;
6047
+ }
6048
+ else if (urlencoded) {
5783
6049
  preparedString += '?' + urlencoded;
5784
6050
  }
5785
6051
  preparedString += nonce + this.secret;
@@ -5789,14 +6055,11 @@ export default class coinex extends Exchange {
5789
6055
  'X-COINEX-SIGN': signature,
5790
6056
  'X-COINEX-TIMESTAMP': nonce,
5791
6057
  };
5792
- if ((method === 'GET') || (method === 'DELETE') || (method === 'PUT')) {
6058
+ if (method !== 'POST') {
5793
6059
  if (urlencoded) {
5794
6060
  url += '?' + urlencoded;
5795
6061
  }
5796
6062
  }
5797
- else {
5798
- body = this.json(query);
5799
- }
5800
6063
  }
5801
6064
  }
5802
6065
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };