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