ccxt 4.3.8__py2.py3-none-any.whl → 4.3.10__py2.py3-none-any.whl
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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +1 -1
- ccxt/abstract/bingx.py +1 -1
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/kucoinfutures.py +2 -0
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bingx.py +18 -11
- ccxt/async_support/bitget.py +1 -1
- ccxt/async_support/coinex.py +656 -389
- ccxt/async_support/coinmetro.py +31 -31
- ccxt/async_support/kucoinfutures.py +148 -12
- ccxt/async_support/okx.py +47 -1
- ccxt/base/exchange.py +4 -4
- ccxt/base/types.py +2 -0
- ccxt/bingx.py +18 -11
- ccxt/bitget.py +1 -1
- ccxt/coinex.py +656 -389
- ccxt/coinmetro.py +31 -31
- ccxt/kucoinfutures.py +148 -12
- ccxt/okx.py +47 -1
- ccxt/pro/__init__.py +1 -1
- {ccxt-4.3.8.dist-info → ccxt-4.3.10.dist-info}/METADATA +4 -4
- {ccxt-4.3.8.dist-info → ccxt-4.3.10.dist-info}/RECORD +25 -25
- {ccxt-4.3.8.dist-info → ccxt-4.3.10.dist-info}/WHEEL +0 -0
- {ccxt-4.3.8.dist-info → ccxt-4.3.10.dist-info}/top_level.txt +0 -0
ccxt/coinex.py
CHANGED
@@ -1688,7 +1688,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
1688
1688
|
# "client_id": "",
|
1689
1689
|
# }
|
1690
1690
|
#
|
1691
|
-
# Spot and Margin
|
1691
|
+
# Spot and Margin cancelOrder, fetchOrder
|
1692
1692
|
#
|
1693
1693
|
# {
|
1694
1694
|
# "amount":"1.5",
|
@@ -1716,7 +1716,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
1716
1716
|
# "client_id": "",
|
1717
1717
|
# }
|
1718
1718
|
#
|
1719
|
-
# Swap
|
1719
|
+
# Swap cancelOrder, fetchOrder
|
1720
1720
|
#
|
1721
1721
|
# {
|
1722
1722
|
# "amount": "0.0005",
|
@@ -1753,10 +1753,6 @@ class coinex(Exchange, ImplicitAPI):
|
|
1753
1753
|
# "user_id": 3620173
|
1754
1754
|
# }
|
1755
1755
|
#
|
1756
|
-
# Stop order createOrder
|
1757
|
-
#
|
1758
|
-
# {"status":"success"}
|
1759
|
-
#
|
1760
1756
|
# Swap Stop cancelOrder, fetchOrder
|
1761
1757
|
#
|
1762
1758
|
# {
|
@@ -1887,85 +1883,166 @@ class coinex(Exchange, ImplicitAPI):
|
|
1887
1883
|
# "user_id": 3620173
|
1888
1884
|
# }
|
1889
1885
|
#
|
1890
|
-
#
|
1886
|
+
# Spot and Margin createOrder, createOrders, cancelOrders v2
|
1891
1887
|
#
|
1892
1888
|
# {
|
1893
|
-
# "amount": "0.
|
1894
|
-
# "
|
1895
|
-
# "
|
1896
|
-
# "
|
1897
|
-
# "
|
1898
|
-
# "
|
1899
|
-
# "
|
1900
|
-
# "
|
1901
|
-
# "
|
1902
|
-
# "
|
1903
|
-
# "
|
1904
|
-
# "
|
1905
|
-
# "
|
1906
|
-
# "
|
1907
|
-
# "
|
1908
|
-
# "
|
1909
|
-
# "
|
1889
|
+
# "amount": "0.0001",
|
1890
|
+
# "base_fee": "0",
|
1891
|
+
# "ccy": "BTC",
|
1892
|
+
# "client_id": "x-167673045-a0a3c6461459a801",
|
1893
|
+
# "created_at": 1714114386250,
|
1894
|
+
# "discount_fee": "0",
|
1895
|
+
# "filled_amount": "0",
|
1896
|
+
# "filled_value": "0",
|
1897
|
+
# "last_fill_amount": "0",
|
1898
|
+
# "last_fill_price": "0",
|
1899
|
+
# "maker_fee_rate": "0.002",
|
1900
|
+
# "market": "BTCUSDT",
|
1901
|
+
# "market_type": "SPOT",
|
1902
|
+
# "order_id": 117178743547,
|
1903
|
+
# "price": "61000",
|
1904
|
+
# "quote_fee": "0",
|
1905
|
+
# "side": "buy",
|
1906
|
+
# "taker_fee_rate": "0.002",
|
1907
|
+
# "type": "limit",
|
1908
|
+
# "unfilled_amount": "0.0001",
|
1909
|
+
# "updated_at": 1714114386250
|
1910
|
+
# }
|
1911
|
+
#
|
1912
|
+
# Spot, Margin and Swap trigger createOrder, createOrders v2
|
1913
|
+
#
|
1914
|
+
# {
|
1915
|
+
# "stop_id": 117180138153
|
1916
|
+
# }
|
1917
|
+
#
|
1918
|
+
# Swap createOrder, createOrders, cancelOrders v2
|
1919
|
+
#
|
1920
|
+
# {
|
1921
|
+
# "amount": "0.0001",
|
1922
|
+
# "client_id": "x-167673045-1471b81d747080a0",
|
1923
|
+
# "created_at": 1714116769986,
|
1924
|
+
# "fee": "0",
|
1925
|
+
# "fee_ccy": "USDT",
|
1926
|
+
# "filled_amount": "0",
|
1927
|
+
# "filled_value": "0",
|
1928
|
+
# "last_filled_amount": "0",
|
1929
|
+
# "last_filled_price": "0",
|
1930
|
+
# "maker_fee_rate": "0.0003",
|
1931
|
+
# "market": "BTCUSDT",
|
1932
|
+
# "market_type": "FUTURES",
|
1933
|
+
# "order_id": 136913377780,
|
1934
|
+
# "price": "61000.42",
|
1935
|
+
# "realized_pnl": "0",
|
1936
|
+
# "side": "buy",
|
1937
|
+
# "taker_fee_rate": "0.0005",
|
1938
|
+
# "type": "limit",
|
1939
|
+
# "unfilled_amount": "0.0001",
|
1940
|
+
# "updated_at": 1714116769986
|
1941
|
+
# }
|
1942
|
+
#
|
1943
|
+
# Swap stopLossPrice and takeProfitPrice createOrder v2
|
1944
|
+
#
|
1945
|
+
# {
|
1946
|
+
# "adl_level": 1,
|
1947
|
+
# "ath_margin_size": "2.14586666",
|
1948
|
+
# "ath_position_amount": "0.0001",
|
1949
|
+
# "avg_entry_price": "64376",
|
1950
|
+
# "bkr_price": "0",
|
1951
|
+
# "close_avbl": "0.0001",
|
1952
|
+
# "cml_position_value": "6.4376",
|
1953
|
+
# "created_at": 1714119054558,
|
1910
1954
|
# "leverage": "3",
|
1911
|
-
# "
|
1955
|
+
# "liq_price": "0",
|
1956
|
+
# "maintenance_margin_rate": "0.005",
|
1957
|
+
# "maintenance_margin_value": "0.03218632",
|
1958
|
+
# "margin_avbl": "2.14586666",
|
1959
|
+
# "margin_mode": "cross",
|
1912
1960
|
# "market": "BTCUSDT",
|
1913
|
-
# "
|
1914
|
-
# "
|
1915
|
-
# "
|
1916
|
-
# "
|
1917
|
-
# "
|
1918
|
-
# "
|
1919
|
-
# "
|
1920
|
-
# "
|
1921
|
-
# "
|
1922
|
-
# "
|
1923
|
-
# "
|
1924
|
-
# "
|
1925
|
-
# "
|
1926
|
-
# "
|
1927
|
-
# "
|
1928
|
-
#
|
1929
|
-
#
|
1961
|
+
# "market_type": "FUTURES",
|
1962
|
+
# "max_position_value": "6.4376",
|
1963
|
+
# "open_interest": "0.0001",
|
1964
|
+
# "position_id": 303884204,
|
1965
|
+
# "position_margin_rate": "3.10624785634397912265",
|
1966
|
+
# "realized_pnl": "-0.0032188",
|
1967
|
+
# "settle_price": "64376",
|
1968
|
+
# "settle_value": "6.4376",
|
1969
|
+
# "side": "long",
|
1970
|
+
# "stop_loss_price": "62000",
|
1971
|
+
# "stop_loss_type": "latest_price",
|
1972
|
+
# "take_profit_price": "0",
|
1973
|
+
# "take_profit_type": "",
|
1974
|
+
# "unrealized_pnl": "0",
|
1975
|
+
# "updated_at": 1714119054559
|
1976
|
+
# }
|
1977
|
+
#
|
1978
|
+
# Swap and Spot stop cancelOrders v2
|
1979
|
+
#
|
1980
|
+
# {
|
1981
|
+
# "amount": "0.0001",
|
1982
|
+
# "client_id": "x-167673045-a7d7714c6478acf6",
|
1983
|
+
# "created_at": 1714187923820,
|
1984
|
+
# "market": "BTCUSDT",
|
1985
|
+
# "market_type": "FUTURES",
|
1986
|
+
# "price": "61000",
|
1987
|
+
# "side": "buy",
|
1988
|
+
# "stop_id": 136984426097,
|
1989
|
+
# "trigger_direction": "higher",
|
1990
|
+
# "trigger_price": "62000",
|
1991
|
+
# "trigger_price_type": "latest_price",
|
1992
|
+
# "type": "limit",
|
1993
|
+
# "updated_at": 1714187974363
|
1930
1994
|
# }
|
1931
1995
|
#
|
1932
1996
|
rawStatus = self.safe_string(order, 'status')
|
1933
1997
|
timestamp = self.safe_timestamp(order, 'create_time')
|
1998
|
+
if timestamp is None:
|
1999
|
+
timestamp = self.safe_integer(order, 'created_at')
|
2000
|
+
update = self.safe_timestamp(order, 'update_time')
|
2001
|
+
if update is None:
|
2002
|
+
update = self.safe_integer(order, 'updated_at')
|
1934
2003
|
marketId = self.safe_string(order, 'market')
|
1935
2004
|
defaultType = self.safe_string(self.options, 'defaultType')
|
1936
2005
|
orderType = 'swap' if ('source' in order) else defaultType
|
1937
2006
|
market = self.safe_market(marketId, market, None, orderType)
|
1938
|
-
feeCurrencyId = self.
|
2007
|
+
feeCurrencyId = self.safe_string_2(order, 'fee_asset', 'fee_ccy')
|
1939
2008
|
feeCurrency = self.safe_currency_code(feeCurrencyId)
|
1940
2009
|
if feeCurrency is None:
|
1941
2010
|
feeCurrency = market['quote']
|
1942
|
-
|
2011
|
+
rawIntegerSide = self.safe_integer(order, 'side')
|
2012
|
+
rawStringSide = self.safe_string(order, 'side')
|
1943
2013
|
side: Str = None
|
1944
|
-
if
|
2014
|
+
if rawIntegerSide == 1:
|
1945
2015
|
side = 'sell'
|
1946
|
-
elif
|
2016
|
+
elif rawIntegerSide == 2:
|
1947
2017
|
side = 'buy'
|
2018
|
+
elif (rawStringSide == 'buy') or (rawStringSide == 'sell'):
|
2019
|
+
side = rawStringSide
|
1948
2020
|
else:
|
1949
2021
|
side = self.safe_string(order, 'type')
|
1950
2022
|
rawType = self.safe_string(order, 'order_type')
|
1951
2023
|
type: Str = None
|
1952
2024
|
if rawType is None:
|
1953
2025
|
typeInteger = self.safe_integer(order, 'type')
|
2026
|
+
typeString = self.safe_string(order, 'type')
|
1954
2027
|
if typeInteger == 1:
|
1955
2028
|
type = 'limit'
|
1956
2029
|
elif typeInteger == 2:
|
1957
2030
|
type = 'market'
|
2031
|
+
elif (typeString == 'limit') or (typeString == 'market'):
|
2032
|
+
type = typeString
|
2033
|
+
elif typeString == 'maker_only':
|
2034
|
+
type = 'limit'
|
1958
2035
|
else:
|
1959
2036
|
type = rawType
|
1960
2037
|
clientOrderId = self.safe_string(order, 'client_id')
|
1961
2038
|
if clientOrderId == '':
|
1962
2039
|
clientOrderId = None
|
1963
2040
|
return self.safe_order({
|
1964
|
-
'id': self.
|
2041
|
+
'id': self.safe_string_n(order, ['id', 'order_id', 'stop_id']),
|
1965
2042
|
'clientOrderId': clientOrderId,
|
1966
2043
|
'datetime': self.iso8601(timestamp),
|
1967
2044
|
'timestamp': timestamp,
|
1968
|
-
'lastTradeTimestamp':
|
2045
|
+
'lastTradeTimestamp': update,
|
1969
2046
|
'status': self.parse_order_status(rawStatus),
|
1970
2047
|
'symbol': market['symbol'],
|
1971
2048
|
'type': type,
|
@@ -1974,19 +2051,19 @@ class coinex(Exchange, ImplicitAPI):
|
|
1974
2051
|
'reduceOnly': None,
|
1975
2052
|
'side': side,
|
1976
2053
|
'price': self.safe_string(order, 'price'),
|
1977
|
-
'stopPrice': self.
|
1978
|
-
'triggerPrice': self.
|
2054
|
+
'stopPrice': self.safe_string_2(order, 'stop_price', 'trigger_price'),
|
2055
|
+
'triggerPrice': self.safe_string_2(order, 'stop_price', 'trigger_price'),
|
1979
2056
|
'takeProfitPrice': self.safe_number(order, 'take_profit_price'),
|
1980
2057
|
'stopLossPrice': self.safe_number(order, 'stop_loss_price'),
|
1981
|
-
'cost': self.
|
1982
|
-
'average': self.
|
2058
|
+
'cost': self.safe_string_2(order, 'deal_money', 'filled_value'),
|
2059
|
+
'average': self.safe_string_2(order, 'avg_price', 'avg_entry_price'),
|
1983
2060
|
'amount': self.safe_string(order, 'amount'),
|
1984
|
-
'filled': self.
|
1985
|
-
'remaining': self.
|
2061
|
+
'filled': self.safe_string_2(order, 'deal_amount', 'filled_amount'),
|
2062
|
+
'remaining': self.safe_string_2(order, 'left', 'unfilled_amount'),
|
1986
2063
|
'trades': None,
|
1987
2064
|
'fee': {
|
1988
2065
|
'currency': feeCurrency,
|
1989
|
-
'cost': self.
|
2066
|
+
'cost': self.safe_string_n(order, ['deal_fee', 'quote_fee', 'fee']),
|
1990
2067
|
},
|
1991
2068
|
'info': order,
|
1992
2069
|
}, market)
|
@@ -1995,6 +2072,7 @@ class coinex(Exchange, ImplicitAPI):
|
|
1995
2072
|
"""
|
1996
2073
|
create a market buy order by providing the symbol and cost
|
1997
2074
|
:see: https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade003_market_order
|
2075
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/put-order
|
1998
2076
|
:param str symbol: unified symbol of the market to create an order in
|
1999
2077
|
:param float cost: how much you want to trade in units of the quote currency
|
2000
2078
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2011,20 +2089,17 @@ class coinex(Exchange, ImplicitAPI):
|
|
2011
2089
|
market = self.market(symbol)
|
2012
2090
|
swap = market['swap']
|
2013
2091
|
clientOrderId = self.safe_string_2(params, 'client_id', 'clientOrderId')
|
2014
|
-
stopPrice = self.
|
2015
|
-
stopLossPrice = self.
|
2016
|
-
takeProfitPrice = self.
|
2092
|
+
stopPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
|
2093
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
2094
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
2017
2095
|
option = self.safe_string(params, 'option')
|
2018
2096
|
isMarketOrder = type == 'market'
|
2019
|
-
postOnly = self.is_post_only(isMarketOrder, option == '
|
2020
|
-
|
2021
|
-
|
2022
|
-
reduceOnly = self.safe_value(params, 'reduceOnly')
|
2097
|
+
postOnly = self.is_post_only(isMarketOrder, option == 'maker_only', params)
|
2098
|
+
timeInForceRaw = self.safe_string_upper(params, 'timeInForce')
|
2099
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
2023
2100
|
if reduceOnly:
|
2024
2101
|
if not market['swap']:
|
2025
2102
|
raise InvalidOrder(self.id + ' createOrder() does not support reduceOnly for ' + market['type'] + ' orders, reduceOnly orders are supported for swap markets only')
|
2026
|
-
if positionId is None:
|
2027
|
-
raise ArgumentsRequired(self.id + ' createOrder() requires a position_id/positionId parameter for reduceOnly orders')
|
2028
2103
|
request = {
|
2029
2104
|
'market': market['id'],
|
2030
2105
|
}
|
@@ -2034,53 +2109,41 @@ class coinex(Exchange, ImplicitAPI):
|
|
2034
2109
|
request['client_id'] = brokerId + '-' + self.uuid16()
|
2035
2110
|
else:
|
2036
2111
|
request['client_id'] = clientOrderId
|
2112
|
+
if (stopLossPrice is None) and (takeProfitPrice is None):
|
2113
|
+
if not reduceOnly:
|
2114
|
+
request['side'] = side
|
2115
|
+
requestType = type
|
2116
|
+
if postOnly:
|
2117
|
+
requestType = 'maker_only'
|
2118
|
+
elif timeInForceRaw is not None:
|
2119
|
+
if timeInForceRaw == 'IOC':
|
2120
|
+
requestType = 'ioc'
|
2121
|
+
elif timeInForceRaw == 'FOK':
|
2122
|
+
requestType = 'fok'
|
2123
|
+
if not isMarketOrder:
|
2124
|
+
request['price'] = self.price_to_precision(symbol, price)
|
2125
|
+
request['type'] = requestType
|
2037
2126
|
if swap:
|
2127
|
+
request['market_type'] = 'FUTURES'
|
2038
2128
|
if stopLossPrice or takeProfitPrice:
|
2039
|
-
request['stop_type'] = self.safe_integer(params, 'stop_type', 1) # 1: triggered by the latest transaction, 2: mark price, 3: index price
|
2040
|
-
if positionId is None:
|
2041
|
-
raise ArgumentsRequired(self.id + ' createOrder() requires a position_id parameter for stop loss and take profit orders')
|
2042
|
-
request['position_id'] = positionId
|
2043
2129
|
if stopLossPrice:
|
2044
2130
|
request['stop_loss_price'] = self.price_to_precision(symbol, stopLossPrice)
|
2131
|
+
request['stop_loss_type'] = self.safe_string(params, 'stop_type', 'latest_price')
|
2045
2132
|
elif takeProfitPrice:
|
2046
2133
|
request['take_profit_price'] = self.price_to_precision(symbol, takeProfitPrice)
|
2134
|
+
request['take_profit_type'] = self.safe_string(params, 'stop_type', 'latest_price')
|
2047
2135
|
else:
|
2048
|
-
|
2136
|
+
request['amount'] = self.amount_to_precision(symbol, amount)
|
2049
2137
|
if stopPrice is not None:
|
2050
|
-
request['
|
2051
|
-
request['
|
2052
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
2053
|
-
request['side'] = requestSide
|
2054
|
-
if type == 'limit':
|
2055
|
-
request['price'] = self.price_to_precision(symbol, price)
|
2056
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
2057
|
-
timeInForce = None
|
2058
|
-
if (type != 'market') or (stopPrice is not None):
|
2059
|
-
if postOnly:
|
2060
|
-
request['option'] = 1
|
2061
|
-
elif timeInForceRaw is not None:
|
2062
|
-
if timeInForceRaw == 'IOC':
|
2063
|
-
timeInForce = 2
|
2064
|
-
elif timeInForceRaw == 'FOK':
|
2065
|
-
timeInForce = 3
|
2066
|
-
else:
|
2067
|
-
timeInForce = 1
|
2068
|
-
request['effect_type'] = timeInForce # exchange takes 'IOC' and 'FOK'
|
2069
|
-
if type == 'limit' and stopPrice is None:
|
2070
|
-
if reduceOnly:
|
2071
|
-
request['position_id'] = positionId
|
2072
|
-
else:
|
2073
|
-
request['side'] = requestSide
|
2074
|
-
request['price'] = self.price_to_precision(symbol, price)
|
2075
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
2076
|
-
elif type == 'market' and stopPrice is None:
|
2077
|
-
if reduceOnly:
|
2078
|
-
request['position_id'] = positionId
|
2079
|
-
else:
|
2080
|
-
request['side'] = requestSide
|
2081
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
2138
|
+
request['trigger_price'] = self.price_to_precision(symbol, stopPrice)
|
2139
|
+
request['trigger_price_type'] = self.safe_string(params, 'stop_type', 'latest_price')
|
2082
2140
|
else:
|
2083
|
-
|
2141
|
+
marginMode = None
|
2142
|
+
marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
|
2143
|
+
if marginMode is not None:
|
2144
|
+
request['market_type'] = 'MARGIN'
|
2145
|
+
else:
|
2146
|
+
request['market_type'] = 'SPOT'
|
2084
2147
|
if (type == 'market') and (side == 'buy'):
|
2085
2148
|
createMarketBuyOrderRequiresPrice = True
|
2086
2149
|
createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
|
@@ -2099,44 +2162,21 @@ class coinex(Exchange, ImplicitAPI):
|
|
2099
2162
|
request['amount'] = self.cost_to_precision(symbol, amount)
|
2100
2163
|
else:
|
2101
2164
|
request['amount'] = self.amount_to_precision(symbol, amount)
|
2102
|
-
if (type == 'limit') or (type == 'ioc'):
|
2103
|
-
request['price'] = self.price_to_precision(symbol, price)
|
2104
2165
|
if stopPrice is not None:
|
2105
|
-
request['
|
2106
|
-
|
2107
|
-
# following options cannot be applied to vanilla market orders(but can be applied to stop-market orders)
|
2108
|
-
if (timeInForceRaw is not None) or postOnly:
|
2109
|
-
if (postOnly or (timeInForceRaw != 'IOC')) and ((type == 'limit') and (stopPrice is not None)):
|
2110
|
-
raise InvalidOrder(self.id + ' createOrder() only supports the IOC option for stop-limit orders')
|
2111
|
-
if postOnly:
|
2112
|
-
request['option'] = 'MAKER_ONLY'
|
2113
|
-
else:
|
2114
|
-
if timeInForceRaw is not None:
|
2115
|
-
request['option'] = timeInForceRaw # exchange takes 'IOC' and 'FOK'
|
2116
|
-
accountId = self.safe_integer(params, 'account_id')
|
2117
|
-
marginMode = None
|
2118
|
-
marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
|
2119
|
-
if marginMode is not None:
|
2120
|
-
if accountId is None:
|
2121
|
-
raise BadRequest(self.id + ' createOrder() requires an account_id parameter for margin orders')
|
2122
|
-
request['account_id'] = accountId
|
2123
|
-
params = self.omit(params, ['reduceOnly', 'positionId', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice'])
|
2166
|
+
request['trigger_price'] = self.price_to_precision(symbol, stopPrice)
|
2167
|
+
params = self.omit(params, ['reduceOnly', 'timeInForce', 'postOnly', 'stopPrice', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice'])
|
2124
2168
|
return self.extend(request, params)
|
2125
2169
|
|
2126
2170
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2127
2171
|
"""
|
2128
2172
|
create a trade order
|
2129
|
-
:see: https://
|
2130
|
-
:see: https://
|
2131
|
-
:see: https://
|
2132
|
-
:see: https://
|
2133
|
-
:see: https://
|
2134
|
-
:see: https://
|
2135
|
-
:see: https://
|
2136
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http019_put_limit_stop
|
2137
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http020_put_market_stop
|
2138
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http031_market_close
|
2139
|
-
:see: https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http030_limit_close
|
2173
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/put-order
|
2174
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/put-stop-order
|
2175
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/put-order
|
2176
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/put-stop-order
|
2177
|
+
:see: https://docs.coinex.com/api/v2/futures/position/http/close-position
|
2178
|
+
:see: https://docs.coinex.com/api/v2/futures/position/http/set-position-stop-loss
|
2179
|
+
:see: https://docs.coinex.com/api/v2/futures/position/http/set-position-take-profit
|
2140
2180
|
:param str symbol: unified symbol of the market to create an order in
|
2141
2181
|
:param str type: 'market' or 'limit'
|
2142
2182
|
:param str side: 'buy' or 'sell'
|
@@ -2149,15 +2189,14 @@ class coinex(Exchange, ImplicitAPI):
|
|
2149
2189
|
:param str [params.timeInForce]: 'GTC', 'IOC', 'FOK', 'PO'
|
2150
2190
|
:param boolean [params.postOnly]: set to True if you wish to make a post only order
|
2151
2191
|
:param boolean [params.reduceOnly]: *contract only* indicates if self order is to reduce the size of a position
|
2152
|
-
:param int [params.position_id]: *required for reduce only orders* the position id to reduce
|
2153
2192
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2154
2193
|
"""
|
2155
2194
|
self.load_markets()
|
2156
2195
|
market = self.market(symbol)
|
2157
|
-
reduceOnly = self.
|
2158
|
-
triggerPrice = self.
|
2159
|
-
stopLossTriggerPrice = self.
|
2160
|
-
takeProfitTriggerPrice = self.
|
2196
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
2197
|
+
triggerPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
|
2198
|
+
stopLossTriggerPrice = self.safe_string(params, 'stopLossPrice')
|
2199
|
+
takeProfitTriggerPrice = self.safe_string(params, 'takeProfitPrice')
|
2161
2200
|
isTriggerOrder = triggerPrice is not None
|
2162
2201
|
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
2163
2202
|
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
@@ -2166,121 +2205,211 @@ class coinex(Exchange, ImplicitAPI):
|
|
2166
2205
|
response = None
|
2167
2206
|
if market['spot']:
|
2168
2207
|
if isTriggerOrder:
|
2169
|
-
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2208
|
+
response = self.v2PrivatePostSpotStopOrder(request)
|
2209
|
+
#
|
2210
|
+
# {
|
2211
|
+
# "code": 0,
|
2212
|
+
# "data": {
|
2213
|
+
# "stop_id": 117180138153
|
2214
|
+
# },
|
2215
|
+
# "message": "OK"
|
2216
|
+
# }
|
2217
|
+
#
|
2173
2218
|
else:
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2219
|
+
response = self.v2PrivatePostSpotOrder(request)
|
2220
|
+
#
|
2221
|
+
# {
|
2222
|
+
# "code": 0,
|
2223
|
+
# "data": {
|
2224
|
+
# "amount": "0.0001",
|
2225
|
+
# "base_fee": "0",
|
2226
|
+
# "ccy": "BTC",
|
2227
|
+
# "client_id": "x-167673045-a0a3c6461459a801",
|
2228
|
+
# "created_at": 1714114386250,
|
2229
|
+
# "discount_fee": "0",
|
2230
|
+
# "filled_amount": "0",
|
2231
|
+
# "filled_value": "0",
|
2232
|
+
# "last_fill_amount": "0",
|
2233
|
+
# "last_fill_price": "0",
|
2234
|
+
# "maker_fee_rate": "0.002",
|
2235
|
+
# "market": "BTCUSDT",
|
2236
|
+
# "market_type": "SPOT",
|
2237
|
+
# "order_id": 117178743547,
|
2238
|
+
# "price": "61000",
|
2239
|
+
# "quote_fee": "0",
|
2240
|
+
# "side": "buy",
|
2241
|
+
# "taker_fee_rate": "0.002",
|
2242
|
+
# "type": "limit",
|
2243
|
+
# "unfilled_amount": "0.0001",
|
2244
|
+
# "updated_at": 1714114386250
|
2245
|
+
# },
|
2246
|
+
# "message": "OK"
|
2247
|
+
# }
|
2248
|
+
#
|
2178
2249
|
else:
|
2179
2250
|
if isTriggerOrder:
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2251
|
+
response = self.v2PrivatePostFuturesStopOrder(request)
|
2252
|
+
#
|
2253
|
+
# {
|
2254
|
+
# "code": 0,
|
2255
|
+
# "data": {
|
2256
|
+
# "stop_id": 136915460994
|
2257
|
+
# },
|
2258
|
+
# "message": "OK"
|
2259
|
+
# }
|
2260
|
+
#
|
2184
2261
|
elif isStopLossOrTakeProfitTrigger:
|
2185
2262
|
if isStopLossTriggerOrder:
|
2186
|
-
response = self.
|
2263
|
+
response = self.v2PrivatePostFuturesSetPositionStopLoss(request)
|
2264
|
+
#
|
2265
|
+
# {
|
2266
|
+
# "code": 0,
|
2267
|
+
# "data": {
|
2268
|
+
# "adl_level": 1,
|
2269
|
+
# "ath_margin_size": "2.14586666",
|
2270
|
+
# "ath_position_amount": "0.0001",
|
2271
|
+
# "avg_entry_price": "64376",
|
2272
|
+
# "bkr_price": "0",
|
2273
|
+
# "close_avbl": "0.0001",
|
2274
|
+
# "cml_position_value": "6.4376",
|
2275
|
+
# "created_at": 1714119054558,
|
2276
|
+
# "leverage": "3",
|
2277
|
+
# "liq_price": "0",
|
2278
|
+
# "maintenance_margin_rate": "0.005",
|
2279
|
+
# "maintenance_margin_value": "0.03218632",
|
2280
|
+
# "margin_avbl": "2.14586666",
|
2281
|
+
# "margin_mode": "cross",
|
2282
|
+
# "market": "BTCUSDT",
|
2283
|
+
# "market_type": "FUTURES",
|
2284
|
+
# "max_position_value": "6.4376",
|
2285
|
+
# "open_interest": "0.0001",
|
2286
|
+
# "position_id": 303884204,
|
2287
|
+
# "position_margin_rate": "3.10624785634397912265",
|
2288
|
+
# "realized_pnl": "-0.0032188",
|
2289
|
+
# "settle_price": "64376",
|
2290
|
+
# "settle_value": "6.4376",
|
2291
|
+
# "side": "long",
|
2292
|
+
# "stop_loss_price": "62000",
|
2293
|
+
# "stop_loss_type": "latest_price",
|
2294
|
+
# "take_profit_price": "0",
|
2295
|
+
# "take_profit_type": "",
|
2296
|
+
# "unrealized_pnl": "0",
|
2297
|
+
# "updated_at": 1714119054559
|
2298
|
+
# },
|
2299
|
+
# "message": "OK"
|
2300
|
+
# }
|
2301
|
+
#
|
2187
2302
|
elif isTakeProfitTriggerOrder:
|
2188
|
-
response = self.
|
2303
|
+
response = self.v2PrivatePostFuturesSetPositionTakeProfit(request)
|
2304
|
+
#
|
2305
|
+
# {
|
2306
|
+
# "code": 0,
|
2307
|
+
# "data": {
|
2308
|
+
# "adl_level": 1,
|
2309
|
+
# "ath_margin_size": "2.14586666",
|
2310
|
+
# "ath_position_amount": "0.0001",
|
2311
|
+
# "avg_entry_price": "64376",
|
2312
|
+
# "bkr_price": "0",
|
2313
|
+
# "close_avbl": "0.0001",
|
2314
|
+
# "cml_position_value": "6.4376",
|
2315
|
+
# "created_at": 1714119054558,
|
2316
|
+
# "leverage": "3",
|
2317
|
+
# "liq_price": "0",
|
2318
|
+
# "maintenance_margin_rate": "0.005",
|
2319
|
+
# "maintenance_margin_value": "0.03218632",
|
2320
|
+
# "margin_avbl": "2.14586666",
|
2321
|
+
# "margin_mode": "cross",
|
2322
|
+
# "market": "BTCUSDT",
|
2323
|
+
# "market_type": "FUTURES",
|
2324
|
+
# "max_position_value": "6.4376",
|
2325
|
+
# "open_interest": "0.0001",
|
2326
|
+
# "position_id": 303884204,
|
2327
|
+
# "position_margin_rate": "3.10624785634397912265",
|
2328
|
+
# "realized_pnl": "-0.0032188",
|
2329
|
+
# "settle_price": "64376",
|
2330
|
+
# "settle_value": "6.4376",
|
2331
|
+
# "side": "long",
|
2332
|
+
# "stop_loss_price": "62000",
|
2333
|
+
# "stop_loss_type": "latest_price",
|
2334
|
+
# "take_profit_price": "70000",
|
2335
|
+
# "take_profit_type": "latest_price",
|
2336
|
+
# "unrealized_pnl": "0",
|
2337
|
+
# "updated_at": 1714119054559
|
2338
|
+
# },
|
2339
|
+
# "message": "OK"
|
2340
|
+
# }
|
2341
|
+
#
|
2189
2342
|
else:
|
2190
2343
|
if reduceOnly:
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2344
|
+
response = self.v2PrivatePostFuturesClosePosition(request)
|
2345
|
+
#
|
2346
|
+
# {
|
2347
|
+
# "code": 0,
|
2348
|
+
# "data": {
|
2349
|
+
# "amount": "0.0001",
|
2350
|
+
# "client_id": "x-167673045-4f264600c432ac06",
|
2351
|
+
# "created_at": 1714119323764,
|
2352
|
+
# "fee": "0.003221",
|
2353
|
+
# "fee_ccy": "USDT",
|
2354
|
+
# "filled_amount": "0.0001",
|
2355
|
+
# "filled_value": "6.442017",
|
2356
|
+
# "last_filled_amount": "0.0001",
|
2357
|
+
# "last_filled_price": "64420.17",
|
2358
|
+
# "maker_fee_rate": "0",
|
2359
|
+
# "market": "BTCUSDT",
|
2360
|
+
# "market_type": "FUTURES",
|
2361
|
+
# "order_id": 136915813578,
|
2362
|
+
# "price": "0",
|
2363
|
+
# "realized_pnl": "0.004417",
|
2364
|
+
# "side": "sell",
|
2365
|
+
# "taker_fee_rate": "0.0005",
|
2366
|
+
# "type": "market",
|
2367
|
+
# "unfilled_amount": "0",
|
2368
|
+
# "updated_at": 1714119323764
|
2369
|
+
# },
|
2370
|
+
# "message": "OK"
|
2371
|
+
# }
|
2372
|
+
#
|
2195
2373
|
else:
|
2196
|
-
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2224
|
-
|
2225
|
-
# "stock_fee": "0",
|
2226
|
-
# "taker_fee_rate": "0.002",
|
2227
|
-
# "type": "buy"
|
2228
|
-
# },
|
2229
|
-
# "message": "Success"
|
2230
|
-
# }
|
2231
|
-
#
|
2232
|
-
# Swap
|
2233
|
-
#
|
2234
|
-
# {
|
2235
|
-
# "code": 0,
|
2236
|
-
# "data": {
|
2237
|
-
# "amount": "0.0005",
|
2238
|
-
# "client_id": "",
|
2239
|
-
# "create_time": 1651004578.618224,
|
2240
|
-
# "deal_asset_fee": "0.00000000000000000000",
|
2241
|
-
# "deal_fee": "0.00000000000000000000",
|
2242
|
-
# "deal_profit": "0.00000000000000000000",
|
2243
|
-
# "deal_stock": "0.00000000000000000000",
|
2244
|
-
# "effect_type": 1,
|
2245
|
-
# "fee_asset": "",
|
2246
|
-
# "fee_discount": "0.00000000000000000000",
|
2247
|
-
# "last_deal_amount": "0.00000000000000000000",
|
2248
|
-
# "last_deal_id": 0,
|
2249
|
-
# "last_deal_price": "0.00000000000000000000",
|
2250
|
-
# "last_deal_role": 0,
|
2251
|
-
# "last_deal_time": 0,
|
2252
|
-
# "last_deal_type": 0,
|
2253
|
-
# "left": "0.0005",
|
2254
|
-
# "leverage": "3",
|
2255
|
-
# "maker_fee": "0.00030",
|
2256
|
-
# "market": "BTCUSDT",
|
2257
|
-
# "order_id": 18221659097,
|
2258
|
-
# "position_id": 0,
|
2259
|
-
# "position_type": 1,
|
2260
|
-
# "price": "30000.00",
|
2261
|
-
# "side": 2,
|
2262
|
-
# "source": "api.v1",
|
2263
|
-
# "stop_id": 0,
|
2264
|
-
# "taker_fee": "0.00050",
|
2265
|
-
# "target": 0,
|
2266
|
-
# "type": 1,
|
2267
|
-
# "update_time": 1651004578.618224,
|
2268
|
-
# "user_id": 3620173
|
2269
|
-
# },
|
2270
|
-
# "message": "OK"
|
2271
|
-
# }
|
2272
|
-
#
|
2273
|
-
# Stop Order
|
2274
|
-
#
|
2275
|
-
# {"code":0,"data":{"status":"success"},"message":"OK"}
|
2276
|
-
#
|
2374
|
+
response = self.v2PrivatePostFuturesOrder(request)
|
2375
|
+
#
|
2376
|
+
# {
|
2377
|
+
# "code": 0,
|
2378
|
+
# "data": {
|
2379
|
+
# "amount": "0.0001",
|
2380
|
+
# "client_id": "x-167673045-1471b81d747080a0",
|
2381
|
+
# "created_at": 1714116769986,
|
2382
|
+
# "fee": "0",
|
2383
|
+
# "fee_ccy": "USDT",
|
2384
|
+
# "filled_amount": "0",
|
2385
|
+
# "filled_value": "0",
|
2386
|
+
# "last_filled_amount": "0",
|
2387
|
+
# "last_filled_price": "0",
|
2388
|
+
# "maker_fee_rate": "0.0003",
|
2389
|
+
# "market": "BTCUSDT",
|
2390
|
+
# "market_type": "FUTURES",
|
2391
|
+
# "order_id": 136913377780,
|
2392
|
+
# "price": "61000.42",
|
2393
|
+
# "realized_pnl": "0",
|
2394
|
+
# "side": "buy",
|
2395
|
+
# "taker_fee_rate": "0.0005",
|
2396
|
+
# "type": "limit",
|
2397
|
+
# "unfilled_amount": "0.0001",
|
2398
|
+
# "updated_at": 1714116769986
|
2399
|
+
# },
|
2400
|
+
# "message": "OK"
|
2401
|
+
# }
|
2402
|
+
#
|
2277
2403
|
data = self.safe_dict(response, 'data', {})
|
2278
2404
|
return self.parse_order(data, market)
|
2279
2405
|
|
2280
2406
|
def create_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
|
2281
2407
|
"""
|
2282
2408
|
create a list of trade orders(all orders should be of the same symbol)
|
2283
|
-
:see: https://
|
2409
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/put-multi-order
|
2410
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/put-multi-stop-order
|
2411
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/put-multi-order
|
2412
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/put-multi-stop-order
|
2284
2413
|
: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
|
2285
2414
|
:param dict [params]: extra parameters specific to the api endpoint
|
2286
2415
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2288,6 +2417,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
2288
2417
|
self.load_markets()
|
2289
2418
|
ordersRequests = []
|
2290
2419
|
symbol = None
|
2420
|
+
reduceOnly = False
|
2421
|
+
isTriggerOrder = False
|
2422
|
+
isStopLossOrTakeProfitTrigger = False
|
2291
2423
|
for i in range(0, len(orders)):
|
2292
2424
|
rawOrder = orders[i]
|
2293
2425
|
marketId = self.safe_string(rawOrder, 'symbol')
|
@@ -2303,54 +2435,138 @@ class coinex(Exchange, ImplicitAPI):
|
|
2303
2435
|
orderParams = self.safe_value(rawOrder, 'params', {})
|
2304
2436
|
if type != 'limit':
|
2305
2437
|
raise NotSupported(self.id + ' createOrders() does not support ' + type + ' orders, only limit orders are accepted')
|
2438
|
+
reduceOnly = self.safe_value(orderParams, 'reduceOnly')
|
2439
|
+
triggerPrice = self.safe_number_2(orderParams, 'stopPrice', 'triggerPrice')
|
2440
|
+
stopLossTriggerPrice = self.safe_number(orderParams, 'stopLossPrice')
|
2441
|
+
takeProfitTriggerPrice = self.safe_number(orderParams, 'takeProfitPrice')
|
2442
|
+
isTriggerOrder = triggerPrice is not None
|
2443
|
+
isStopLossTriggerOrder = stopLossTriggerPrice is not None
|
2444
|
+
isTakeProfitTriggerOrder = takeProfitTriggerPrice is not None
|
2445
|
+
isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder or isTakeProfitTriggerOrder
|
2306
2446
|
orderRequest = self.create_order_request(marketId, type, side, amount, price, orderParams)
|
2307
2447
|
ordersRequests.append(orderRequest)
|
2308
2448
|
market = self.market(symbol)
|
2309
|
-
if not market['spot']:
|
2310
|
-
raise NotSupported(self.id + ' createOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
2311
2449
|
request = {
|
2312
2450
|
'market': market['id'],
|
2313
|
-
'
|
2451
|
+
'orders': ordersRequests,
|
2314
2452
|
}
|
2315
|
-
response =
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2322
|
-
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2453
|
+
response = None
|
2454
|
+
if market['spot']:
|
2455
|
+
if isTriggerOrder:
|
2456
|
+
response = self.v2PrivatePostSpotBatchStopOrder(request)
|
2457
|
+
#
|
2458
|
+
# {
|
2459
|
+
# "code": 0,
|
2460
|
+
# "data": [
|
2461
|
+
# {
|
2462
|
+
# "code": 0,
|
2463
|
+
# "data": {
|
2464
|
+
# "stop_id": 117186257510
|
2465
|
+
# },
|
2466
|
+
# "message": "OK"
|
2467
|
+
# },
|
2468
|
+
# ],
|
2469
|
+
# "message": "OK"
|
2470
|
+
# }
|
2471
|
+
#
|
2472
|
+
else:
|
2473
|
+
response = self.v2PrivatePostSpotBatchOrder(request)
|
2474
|
+
#
|
2475
|
+
# {
|
2476
|
+
# "code": 0,
|
2477
|
+
# "data": [
|
2478
|
+
# {
|
2479
|
+
# "amount": "0.0001",
|
2480
|
+
# "base_fee": "0",
|
2481
|
+
# "ccy": "BTC",
|
2482
|
+
# "client_id": "x-167673045-f3651372049dab0d",
|
2483
|
+
# "created_at": 1714121403450,
|
2484
|
+
# "discount_fee": "0",
|
2485
|
+
# "filled_amount": "0",
|
2486
|
+
# "filled_value": "0",
|
2487
|
+
# "last_fill_amount": "0",
|
2488
|
+
# "last_fill_price": "0",
|
2489
|
+
# "maker_fee_rate": "0.002",
|
2490
|
+
# "market": "BTCUSDT",
|
2491
|
+
# "market_type": "SPOT",
|
2492
|
+
# "order_id": 117185362233,
|
2493
|
+
# "price": "61000",
|
2494
|
+
# "quote_fee": "0",
|
2495
|
+
# "side": "buy",
|
2496
|
+
# "taker_fee_rate": "0.002",
|
2497
|
+
# "type": "limit",
|
2498
|
+
# "unfilled_amount": "0.0001",
|
2499
|
+
# "updated_at": 1714121403450
|
2500
|
+
# },
|
2501
|
+
# {
|
2502
|
+
# "code": 3109,
|
2503
|
+
# "data": null,
|
2504
|
+
# "message": "balance not enough"
|
2505
|
+
# }
|
2506
|
+
# ],
|
2507
|
+
# "message": "OK"
|
2508
|
+
# }
|
2509
|
+
#
|
2510
|
+
else:
|
2511
|
+
if isTriggerOrder:
|
2512
|
+
response = self.v2PrivatePostFuturesBatchStopOrder(request)
|
2513
|
+
#
|
2514
|
+
# {
|
2515
|
+
# "code": 0,
|
2516
|
+
# "data": [
|
2517
|
+
# {
|
2518
|
+
# "code": 0,
|
2519
|
+
# "data": {
|
2520
|
+
# "stop_id": 136919625994
|
2521
|
+
# },
|
2522
|
+
# "message": "OK"
|
2523
|
+
# },
|
2524
|
+
# ],
|
2525
|
+
# "message": "OK"
|
2526
|
+
# }
|
2527
|
+
#
|
2528
|
+
elif isStopLossOrTakeProfitTrigger:
|
2529
|
+
raise NotSupported(self.id + ' createOrders() does not support stopLossPrice or takeProfitPrice orders')
|
2530
|
+
else:
|
2531
|
+
if reduceOnly:
|
2532
|
+
raise NotSupported(self.id + ' createOrders() does not support reduceOnly orders')
|
2533
|
+
else:
|
2534
|
+
response = self.v2PrivatePostFuturesBatchOrder(request)
|
2535
|
+
#
|
2536
|
+
# {
|
2537
|
+
# "code": 0,
|
2538
|
+
# "data": [
|
2539
|
+
# {
|
2540
|
+
# "code": 0,
|
2541
|
+
# "data": {
|
2542
|
+
# "amount": "0.0001",
|
2543
|
+
# "client_id": "x-167673045-2cb7436f3462a654",
|
2544
|
+
# "created_at": 1714122832493,
|
2545
|
+
# "fee": "0",
|
2546
|
+
# "fee_ccy": "USDT",
|
2547
|
+
# "filled_amount": "0",
|
2548
|
+
# "filled_value": "0",
|
2549
|
+
# "last_filled_amount": "0",
|
2550
|
+
# "last_filled_price": "0",
|
2551
|
+
# "maker_fee_rate": "0.0003",
|
2552
|
+
# "market": "BTCUSDT",
|
2553
|
+
# "market_type": "FUTURES",
|
2554
|
+
# "order_id": 136918835063,
|
2555
|
+
# "price": "61000",
|
2556
|
+
# "realized_pnl": "0",
|
2557
|
+
# "side": "buy",
|
2558
|
+
# "taker_fee_rate": "0.0005",
|
2559
|
+
# "type": "limit",
|
2560
|
+
# "unfilled_amount": "0.0001",
|
2561
|
+
# "updated_at": 1714122832493
|
2562
|
+
# },
|
2563
|
+
# "message": "OK"
|
2564
|
+
# },
|
2565
|
+
# ],
|
2566
|
+
# "message": "OK"
|
2567
|
+
# }
|
2568
|
+
#
|
2569
|
+
data = self.safe_list(response, 'data', [])
|
2354
2570
|
results = []
|
2355
2571
|
for i in range(0, len(data)):
|
2356
2572
|
entry = data[i]
|
@@ -2361,20 +2577,28 @@ class coinex(Exchange, ImplicitAPI):
|
|
2361
2577
|
status = 'rejected'
|
2362
2578
|
else:
|
2363
2579
|
status = 'open'
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2580
|
+
innerData = self.safe_dict(entry, 'data', {})
|
2581
|
+
order = None
|
2582
|
+
if market['spot'] and not isTriggerOrder:
|
2583
|
+
entry['status'] = status
|
2584
|
+
order = self.parse_order(entry, market)
|
2585
|
+
else:
|
2586
|
+
innerData['status'] = status
|
2587
|
+
order = self.parse_order(innerData, market)
|
2367
2588
|
results.append(order)
|
2368
2589
|
return results
|
2369
2590
|
|
2370
2591
|
def cancel_orders(self, ids, symbol: Str = None, params={}):
|
2371
2592
|
"""
|
2372
2593
|
cancel multiple orders
|
2373
|
-
:see: https://
|
2374
|
-
:see: https://
|
2594
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/cancel-batch-order
|
2595
|
+
:see: https://docs.coinex.com/api/v2/spot/order/http/cancel-batch-stop-order
|
2596
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/cancel-batch-order
|
2597
|
+
:see: https://docs.coinex.com/api/v2/futures/order/http/cancel-batch-stop-order
|
2375
2598
|
:param str[] ids: order ids
|
2376
2599
|
:param str symbol: unified market symbol
|
2377
2600
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2601
|
+
:param boolean [params.stop]: set to True for canceling stop orders
|
2378
2602
|
:returns dict: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2379
2603
|
"""
|
2380
2604
|
if symbol is None:
|
@@ -2384,111 +2608,153 @@ class coinex(Exchange, ImplicitAPI):
|
|
2384
2608
|
request = {
|
2385
2609
|
'market': market['id'],
|
2386
2610
|
}
|
2387
|
-
|
2611
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
2612
|
+
params = self.omit(params, ['stop', 'trigger'])
|
2388
2613
|
response = None
|
2614
|
+
if stop:
|
2615
|
+
request['stop_ids'] = ids
|
2616
|
+
else:
|
2617
|
+
request['order_ids'] = ids
|
2389
2618
|
if market['spot']:
|
2390
|
-
|
2391
|
-
|
2619
|
+
if stop:
|
2620
|
+
response = self.v2PrivatePostSpotCancelBatchStopOrder(self.extend(request, params))
|
2621
|
+
#
|
2622
|
+
# {
|
2623
|
+
# "code": 0,
|
2624
|
+
# "data": [
|
2625
|
+
# {
|
2626
|
+
# "code": 0,
|
2627
|
+
# "data": {
|
2628
|
+
# "amount": "0.0001",
|
2629
|
+
# "ccy": "BTC",
|
2630
|
+
# "client_id": "x-167673045-8e33d6f4a4bcb022",
|
2631
|
+
# "created_at": 1714188827291,
|
2632
|
+
# "market": "BTCUSDT",
|
2633
|
+
# "market_type": "SPOT",
|
2634
|
+
# "price": "61000",
|
2635
|
+
# "side": "buy",
|
2636
|
+
# "stop_id": 117248845854,
|
2637
|
+
# "trigger_direction": "higher",
|
2638
|
+
# "trigger_price": "62000",
|
2639
|
+
# "trigger_price_type": "mark_price",
|
2640
|
+
# "type": "limit",
|
2641
|
+
# "updated_at": 1714188827291
|
2642
|
+
# },
|
2643
|
+
# "message": "OK"
|
2644
|
+
# },
|
2645
|
+
# ],
|
2646
|
+
# "message": "OK"
|
2647
|
+
# }
|
2648
|
+
#
|
2649
|
+
else:
|
2650
|
+
response = self.v2PrivatePostSpotCancelBatchOrder(self.extend(request, params))
|
2651
|
+
#
|
2652
|
+
# {
|
2653
|
+
# "code": 0,
|
2654
|
+
# "data": [
|
2655
|
+
# {
|
2656
|
+
# "code": 0,
|
2657
|
+
# "data": {
|
2658
|
+
# "amount": "0.0001",
|
2659
|
+
# "base_fee": "0",
|
2660
|
+
# "ccy": "BTC",
|
2661
|
+
# "client_id": "x-167673045-c1cc78e5b42d8c4e",
|
2662
|
+
# "created_at": 1714188449497,
|
2663
|
+
# "discount_fee": "0",
|
2664
|
+
# "filled_amount": "0",
|
2665
|
+
# "filled_value": "0",
|
2666
|
+
# "last_fill_amount": "0",
|
2667
|
+
# "last_fill_price": "0",
|
2668
|
+
# "maker_fee_rate": "0.002",
|
2669
|
+
# "market": "BTCUSDT",
|
2670
|
+
# "market_type": "SPOT",
|
2671
|
+
# "order_id": 117248494358,
|
2672
|
+
# "price": "60000",
|
2673
|
+
# "quote_fee": "0",
|
2674
|
+
# "side": "buy",
|
2675
|
+
# "taker_fee_rate": "0.002",
|
2676
|
+
# "type": "limit",
|
2677
|
+
# "unfilled_amount": "0.0001",
|
2678
|
+
# "updated_at": 1714188449497
|
2679
|
+
# },
|
2680
|
+
# "message": ""
|
2681
|
+
# },
|
2682
|
+
# ],
|
2683
|
+
# "message": "OK"
|
2684
|
+
# }
|
2685
|
+
#
|
2392
2686
|
else:
|
2393
|
-
request['
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
|
-
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2445
|
-
|
2446
|
-
|
2447
|
-
|
2448
|
-
|
2449
|
-
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
# "leverage": "3",
|
2461
|
-
# "maker_fee": "0.00030",
|
2462
|
-
# "market": "BTCUSDT",
|
2463
|
-
# "option": 0,
|
2464
|
-
# "order_id": 115940476323,
|
2465
|
-
# "position_id": 0,
|
2466
|
-
# "position_type": 2,
|
2467
|
-
# "price": "25000.00",
|
2468
|
-
# "side": 2,
|
2469
|
-
# "source": "api.v1",
|
2470
|
-
# "stop_id": 0,
|
2471
|
-
# "stop_loss_price": "0.00000000000000000000",
|
2472
|
-
# "stop_loss_type": 0,
|
2473
|
-
# "take_profit_price": "0.00000000000000000000",
|
2474
|
-
# "take_profit_type": 0,
|
2475
|
-
# "taker_fee": "0.00050",
|
2476
|
-
# "target": 0,
|
2477
|
-
# "type": 1,
|
2478
|
-
# "update_time": 1701233721.718884,
|
2479
|
-
# "user_id": 3620173
|
2480
|
-
# }
|
2481
|
-
# },
|
2482
|
-
# ],
|
2483
|
-
# "message": "OK"
|
2484
|
-
# }
|
2485
|
-
#
|
2486
|
-
data = self.safe_value(response, 'data', [])
|
2687
|
+
request['market_type'] = 'FUTURES'
|
2688
|
+
if stop:
|
2689
|
+
response = self.v2PrivatePostFuturesCancelBatchStopOrder(self.extend(request, params))
|
2690
|
+
#
|
2691
|
+
# {
|
2692
|
+
# "code": 0,
|
2693
|
+
# "data": [
|
2694
|
+
# {
|
2695
|
+
# "code": 0,
|
2696
|
+
# "data": {
|
2697
|
+
# "amount": "0.0001",
|
2698
|
+
# "client_id": "x-167673045-a7d7714c6478acf6",
|
2699
|
+
# "created_at": 1714187923820,
|
2700
|
+
# "market": "BTCUSDT",
|
2701
|
+
# "market_type": "FUTURES",
|
2702
|
+
# "price": "61000",
|
2703
|
+
# "side": "buy",
|
2704
|
+
# "stop_id": 136984426097,
|
2705
|
+
# "trigger_direction": "higher",
|
2706
|
+
# "trigger_price": "62000",
|
2707
|
+
# "trigger_price_type": "latest_price",
|
2708
|
+
# "type": "limit",
|
2709
|
+
# "updated_at": 1714187974363
|
2710
|
+
# },
|
2711
|
+
# "message": ""
|
2712
|
+
# },
|
2713
|
+
# ],
|
2714
|
+
# "message": "OK"
|
2715
|
+
# }
|
2716
|
+
#
|
2717
|
+
else:
|
2718
|
+
response = self.v2PrivatePostFuturesCancelBatchOrder(self.extend(request, params))
|
2719
|
+
#
|
2720
|
+
# {
|
2721
|
+
# "code": 0,
|
2722
|
+
# "data": [
|
2723
|
+
# {
|
2724
|
+
# "code": 0,
|
2725
|
+
# "data": {
|
2726
|
+
# "amount": "0.0001",
|
2727
|
+
# "client_id": "x-167673045-9f80fde284339a72",
|
2728
|
+
# "created_at": 1714187491784,
|
2729
|
+
# "fee": "0",
|
2730
|
+
# "fee_ccy": "USDT",
|
2731
|
+
# "filled_amount": "0",
|
2732
|
+
# "filled_value": "0",
|
2733
|
+
# "last_filled_amount": "0",
|
2734
|
+
# "last_filled_price": "0",
|
2735
|
+
# "maker_fee_rate": "0.0003",
|
2736
|
+
# "market": "BTCUSDT",
|
2737
|
+
# "market_type": "FUTURES",
|
2738
|
+
# "order_id": 136983851788,
|
2739
|
+
# "price": "61000",
|
2740
|
+
# "realized_pnl": "0",
|
2741
|
+
# "side": "buy",
|
2742
|
+
# "taker_fee_rate": "0.0005",
|
2743
|
+
# "type": "limit",
|
2744
|
+
# "unfilled_amount": "0.0001",
|
2745
|
+
# "updated_at": 1714187567079
|
2746
|
+
# },
|
2747
|
+
# "message": ""
|
2748
|
+
# },
|
2749
|
+
# ],
|
2750
|
+
# "message": "OK"
|
2751
|
+
# }
|
2752
|
+
#
|
2753
|
+
data = self.safe_list(response, 'data', [])
|
2487
2754
|
results = []
|
2488
2755
|
for i in range(0, len(data)):
|
2489
2756
|
entry = data[i]
|
2490
|
-
|
2491
|
-
item = self.safe_value(entry, dataRequest, {})
|
2757
|
+
item = self.safe_dict(entry, 'data', {})
|
2492
2758
|
order = self.parse_order(item, market)
|
2493
2759
|
results.append(order)
|
2494
2760
|
return results
|
@@ -5403,7 +5669,10 @@ class coinex(Exchange, ImplicitAPI):
|
|
5403
5669
|
query = self.keysort(query)
|
5404
5670
|
urlencoded = self.rawencode(query)
|
5405
5671
|
preparedString = method + '/' + version + '/' + path
|
5406
|
-
if
|
5672
|
+
if method == 'POST':
|
5673
|
+
body = self.json(query)
|
5674
|
+
preparedString += body
|
5675
|
+
elif urlencoded:
|
5407
5676
|
preparedString += '?' + urlencoded
|
5408
5677
|
preparedString += nonce + self.secret
|
5409
5678
|
signature = self.hash(self.encode(preparedString), 'sha256')
|
@@ -5412,11 +5681,9 @@ class coinex(Exchange, ImplicitAPI):
|
|
5412
5681
|
'X-COINEX-SIGN': signature,
|
5413
5682
|
'X-COINEX-TIMESTAMP': nonce,
|
5414
5683
|
}
|
5415
|
-
if
|
5684
|
+
if method != 'POST':
|
5416
5685
|
if urlencoded:
|
5417
5686
|
url += '?' + urlencoded
|
5418
|
-
else:
|
5419
|
-
body = self.json(query)
|
5420
5687
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
5421
5688
|
|
5422
5689
|
def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
|