ccxt 4.2.58__py2.py3-none-any.whl → 4.2.60__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/blofin.py +1 -0
- ccxt/abstract/kraken.py +37 -37
- ccxt/abstract/wazirx.py +6 -1
- ccxt/ascendex.py +10 -12
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ascendex.py +10 -12
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/binance.py +2 -2
- ccxt/async_support/bingx.py +40 -4
- ccxt/async_support/bitfinex2.py +20 -3
- ccxt/async_support/bitget.py +8 -3
- ccxt/async_support/bitmart.py +40 -23
- ccxt/async_support/bitmex.py +1 -1
- ccxt/async_support/blofin.py +53 -3
- ccxt/async_support/coinbase.py +21 -12
- ccxt/async_support/hitbtc.py +1 -1
- ccxt/async_support/htx.py +3 -1
- ccxt/async_support/kraken.py +42 -39
- ccxt/async_support/kucoinfutures.py +1 -0
- ccxt/async_support/lbank.py +1 -1
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/okx.py +1 -1
- ccxt/async_support/phemex.py +1 -1
- ccxt/async_support/wazirx.py +6 -1
- ccxt/async_support/woo.py +148 -76
- ccxt/base/exchange.py +3 -1
- ccxt/binance.py +2 -2
- ccxt/bingx.py +40 -4
- ccxt/bitfinex2.py +20 -3
- ccxt/bitget.py +8 -3
- ccxt/bitmart.py +40 -23
- ccxt/bitmex.py +1 -1
- ccxt/blofin.py +53 -3
- ccxt/coinbase.py +21 -12
- ccxt/hitbtc.py +1 -1
- ccxt/htx.py +3 -1
- ccxt/kraken.py +42 -39
- ccxt/kucoinfutures.py +1 -0
- ccxt/lbank.py +1 -1
- ccxt/mexc.py +1 -1
- ccxt/okx.py +1 -1
- ccxt/phemex.py +1 -1
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +12 -3
- ccxt/pro/bitfinex2.py +1 -1
- ccxt/pro/bitget.py +1 -1
- ccxt/pro/bitmart.py +44 -78
- ccxt/pro/bitvavo.py +1 -1
- ccxt/pro/bybit.py +1 -1
- ccxt/pro/coinex.py +1 -1
- ccxt/pro/cryptocom.py +1 -1
- ccxt/pro/deribit.py +188 -84
- ccxt/pro/gate.py +1 -1
- ccxt/pro/independentreserve.py +1 -1
- ccxt/pro/kraken.py +1 -1
- ccxt/pro/kucoinfutures.py +1 -1
- ccxt/pro/mexc.py +5 -4
- ccxt/pro/okx.py +1 -1
- ccxt/pro/woo.py +1 -1
- ccxt/test/test_async.py +4 -4
- ccxt/test/test_sync.py +4 -4
- ccxt/wazirx.py +6 -1
- ccxt/woo.py +148 -76
- {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/METADATA +4 -4
- {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/RECORD +68 -68
- {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/WHEEL +0 -0
- {ccxt-4.2.58.dist-info → ccxt-4.2.60.dist-info}/top_level.txt +0 -0
ccxt/async_support/woo.py
CHANGED
@@ -93,10 +93,10 @@ class woo(Exchange, ImplicitAPI):
|
|
93
93
|
'fetchPositionMode': False,
|
94
94
|
'fetchPositions': True,
|
95
95
|
'fetchPremiumIndexOHLCV': False,
|
96
|
-
'fetchStatus':
|
96
|
+
'fetchStatus': True,
|
97
97
|
'fetchTicker': False,
|
98
98
|
'fetchTickers': False,
|
99
|
-
'fetchTime':
|
99
|
+
'fetchTime': True,
|
100
100
|
'fetchTrades': True,
|
101
101
|
'fetchTradingFee': False,
|
102
102
|
'fetchTradingFees': True,
|
@@ -333,6 +333,60 @@ class woo(Exchange, ImplicitAPI):
|
|
333
333
|
'precisionMode': TICK_SIZE,
|
334
334
|
})
|
335
335
|
|
336
|
+
async def fetch_status(self, params={}):
|
337
|
+
"""
|
338
|
+
the latest known information on the availability of the exchange API
|
339
|
+
:see: https://docs.woo.org/#get-system-maintenance-status-public
|
340
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
341
|
+
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
342
|
+
"""
|
343
|
+
response = await self.v1PublicGetSystemInfo(params)
|
344
|
+
#
|
345
|
+
# {
|
346
|
+
# "success": True,
|
347
|
+
# "data": {
|
348
|
+
# "status": "0",
|
349
|
+
# "msg": "System is functioning properly."
|
350
|
+
# },
|
351
|
+
# "timestamp": "1709274106602"
|
352
|
+
# }
|
353
|
+
#
|
354
|
+
data = self.safe_dict(response, 'data', {})
|
355
|
+
status = self.safe_string(data, 'status')
|
356
|
+
if status is None:
|
357
|
+
status = 'error'
|
358
|
+
elif status == '0':
|
359
|
+
status = 'ok'
|
360
|
+
else:
|
361
|
+
status = 'maintenance'
|
362
|
+
return {
|
363
|
+
'status': status,
|
364
|
+
'updated': None,
|
365
|
+
'eta': None,
|
366
|
+
'url': None,
|
367
|
+
'info': response,
|
368
|
+
}
|
369
|
+
|
370
|
+
async def fetch_time(self, params={}):
|
371
|
+
"""
|
372
|
+
fetches the current integer timestamp in milliseconds from the exchange server
|
373
|
+
:see: https://docs.woo.org/#get-system-maintenance-status-public
|
374
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
375
|
+
:returns int: the current integer timestamp in milliseconds from the exchange server
|
376
|
+
"""
|
377
|
+
response = await self.v1PublicGetSystemInfo(params)
|
378
|
+
#
|
379
|
+
# {
|
380
|
+
# "success": True,
|
381
|
+
# "data": {
|
382
|
+
# "status": "0",
|
383
|
+
# "msg": "System is functioning properly."
|
384
|
+
# },
|
385
|
+
# "timestamp": "1709274106602"
|
386
|
+
# }
|
387
|
+
#
|
388
|
+
return self.safe_integer(response, 'timestamp')
|
389
|
+
|
336
390
|
async def fetch_markets(self, params={}):
|
337
391
|
"""
|
338
392
|
retrieves data on all markets for woo
|
@@ -361,7 +415,7 @@ class woo(Exchange, ImplicitAPI):
|
|
361
415
|
# "success": True
|
362
416
|
# }
|
363
417
|
#
|
364
|
-
data = self.
|
418
|
+
data = self.safe_list(response, 'rows', [])
|
365
419
|
return self.parse_markets(data)
|
366
420
|
|
367
421
|
def parse_market(self, market) -> Market:
|
@@ -491,7 +545,7 @@ class woo(Exchange, ImplicitAPI):
|
|
491
545
|
# ]
|
492
546
|
# }
|
493
547
|
#
|
494
|
-
resultResponse = self.
|
548
|
+
resultResponse = self.safe_list(response, 'rows', [])
|
495
549
|
return self.parse_trades(resultResponse, market, since, limit)
|
496
550
|
|
497
551
|
def parse_trade(self, trade, market: Market = None) -> Trade:
|
@@ -603,7 +657,7 @@ class woo(Exchange, ImplicitAPI):
|
|
603
657
|
# "timestamp": 1673323685109
|
604
658
|
# }
|
605
659
|
#
|
606
|
-
data = self.
|
660
|
+
data = self.safe_dict(response, 'data', {})
|
607
661
|
maker = self.safe_string(data, 'makerFeeRate')
|
608
662
|
taker = self.safe_string(data, 'takerFeeRate')
|
609
663
|
result = {}
|
@@ -687,7 +741,7 @@ class woo(Exchange, ImplicitAPI):
|
|
687
741
|
# "success": True
|
688
742
|
# }
|
689
743
|
#
|
690
|
-
tokenRows = self.
|
744
|
+
tokenRows = self.safe_list(tokenResponse, 'rows', [])
|
691
745
|
networksByCurrencyId = self.group_by(tokenRows, 'balance_token')
|
692
746
|
currencyIds = list(networksByCurrencyId.keys())
|
693
747
|
for i in range(0, len(currencyIds)):
|
@@ -831,7 +885,7 @@ class woo(Exchange, ImplicitAPI):
|
|
831
885
|
:param str [params.trailingTriggerPrice]: the price to trigger a trailing order, default uses the price argument
|
832
886
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
833
887
|
"""
|
834
|
-
reduceOnly = self.
|
888
|
+
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
835
889
|
params = self.omit(params, ['reduceOnly', 'reduce_only'])
|
836
890
|
orderType = type.upper()
|
837
891
|
await self.load_markets()
|
@@ -975,9 +1029,9 @@ class woo(Exchange, ImplicitAPI):
|
|
975
1029
|
# },
|
976
1030
|
# "timestamp": "1686149372216"
|
977
1031
|
# }
|
978
|
-
data = self.
|
1032
|
+
data = self.safe_dict(response, 'data')
|
979
1033
|
if data is not None:
|
980
|
-
rows = self.
|
1034
|
+
rows = self.safe_list(data, 'rows', [])
|
981
1035
|
return self.parse_order(rows[0], market)
|
982
1036
|
order = self.parse_order(response, market)
|
983
1037
|
order['type'] = type
|
@@ -1062,7 +1116,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1062
1116
|
# "timestamp": 0
|
1063
1117
|
# }
|
1064
1118
|
#
|
1065
|
-
data = self.
|
1119
|
+
data = self.safe_dict(response, 'data', {})
|
1066
1120
|
return self.parse_order(data, market)
|
1067
1121
|
|
1068
1122
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
@@ -1124,8 +1178,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1124
1178
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
1125
1179
|
"""
|
1126
1180
|
await self.load_markets()
|
1127
|
-
stop = self.
|
1128
|
-
params = self.omit(params, 'stop')
|
1181
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
1182
|
+
params = self.omit(params, ['stop', 'trigger'])
|
1129
1183
|
if stop:
|
1130
1184
|
return await self.v3PrivateDeleteAlgoOrdersPending(params)
|
1131
1185
|
if symbol is None:
|
@@ -1155,8 +1209,8 @@ class woo(Exchange, ImplicitAPI):
|
|
1155
1209
|
"""
|
1156
1210
|
await self.load_markets()
|
1157
1211
|
market = self.market(symbol) if (symbol is not None) else None
|
1158
|
-
stop = self.
|
1159
|
-
params = self.omit(params, 'stop')
|
1212
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
1213
|
+
params = self.omit(params, ['stop', 'trigger'])
|
1160
1214
|
request = {}
|
1161
1215
|
clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
1162
1216
|
response = None
|
@@ -1225,9 +1279,9 @@ class woo(Exchange, ImplicitAPI):
|
|
1225
1279
|
await self.load_markets()
|
1226
1280
|
request = {}
|
1227
1281
|
market: Market = None
|
1228
|
-
stop = self.
|
1282
|
+
stop = self.safe_bool_2(params, 'stop', 'trigger')
|
1229
1283
|
trailing = self.safe_bool(params, 'trailing', False)
|
1230
|
-
params = self.omit(params, ['stop', 'trailing'])
|
1284
|
+
params = self.omit(params, ['stop', 'trailing', 'trigger'])
|
1231
1285
|
if symbol is not None:
|
1232
1286
|
market = self.market(symbol)
|
1233
1287
|
request['symbol'] = market['id']
|
@@ -1277,7 +1331,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1277
1331
|
# }
|
1278
1332
|
#
|
1279
1333
|
data = self.safe_value(response, 'data', response)
|
1280
|
-
orders = self.
|
1334
|
+
orders = self.safe_list(data, 'rows')
|
1281
1335
|
return self.parse_orders(orders, market, since, limit, params)
|
1282
1336
|
|
1283
1337
|
def parse_time_in_force(self, timeInForce):
|
@@ -1377,7 +1431,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1377
1431
|
'type': orderType,
|
1378
1432
|
'timeInForce': self.parse_time_in_force(orderType),
|
1379
1433
|
'postOnly': None, # TO_DO
|
1380
|
-
'reduceOnly': self.
|
1434
|
+
'reduceOnly': self.safe_bool(order, 'reduce_only'),
|
1381
1435
|
'side': side,
|
1382
1436
|
'price': price,
|
1383
1437
|
'stopPrice': stopPrice,
|
@@ -1524,7 +1578,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1524
1578
|
# }
|
1525
1579
|
# }
|
1526
1580
|
#
|
1527
|
-
rows = self.
|
1581
|
+
rows = self.safe_list(response, 'rows', [])
|
1528
1582
|
return self.parse_ohlcvs(rows, market, timeframe, since, limit)
|
1529
1583
|
|
1530
1584
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
@@ -1574,7 +1628,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1574
1628
|
# }
|
1575
1629
|
# ]
|
1576
1630
|
# }
|
1577
|
-
trades = self.
|
1631
|
+
trades = self.safe_list(response, 'rows', [])
|
1578
1632
|
return self.parse_trades(trades, market, since, limit, params)
|
1579
1633
|
|
1580
1634
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
@@ -1618,7 +1672,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1618
1672
|
# ...
|
1619
1673
|
# ]
|
1620
1674
|
# }
|
1621
|
-
trades = self.
|
1675
|
+
trades = self.safe_list(response, 'rows', [])
|
1622
1676
|
return self.parse_trades(trades, market, since, limit, params)
|
1623
1677
|
|
1624
1678
|
async def fetch_accounts(self, params={}):
|
@@ -1644,7 +1698,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1644
1698
|
# "success": True
|
1645
1699
|
# }
|
1646
1700
|
#
|
1647
|
-
rows = self.
|
1701
|
+
rows = self.safe_list(response, 'rows', [])
|
1648
1702
|
return self.parse_accounts(rows, params)
|
1649
1703
|
|
1650
1704
|
def parse_account(self, account):
|
@@ -1696,14 +1750,14 @@ class woo(Exchange, ImplicitAPI):
|
|
1696
1750
|
# "timestamp": 1673323746259
|
1697
1751
|
# }
|
1698
1752
|
#
|
1699
|
-
data = self.
|
1753
|
+
data = self.safe_dict(response, 'data')
|
1700
1754
|
return self.parse_balance(data)
|
1701
1755
|
|
1702
1756
|
def parse_balance(self, response) -> Balances:
|
1703
1757
|
result = {
|
1704
1758
|
'info': response,
|
1705
1759
|
}
|
1706
|
-
balances = self.
|
1760
|
+
balances = self.safe_list(response, 'holding', [])
|
1707
1761
|
for i in range(0, len(balances)):
|
1708
1762
|
balance = balances[i]
|
1709
1763
|
code = self.safe_currency_code(self.safe_string(balance, 'token'))
|
@@ -1959,6 +2013,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1959
2013
|
|
1960
2014
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
1961
2015
|
"""
|
2016
|
+
:see: https://docs.woo.org/#get-transfer-history
|
1962
2017
|
transfer currency internally between wallets on the same account
|
1963
2018
|
:param str code: unified currency code
|
1964
2019
|
:param float amount: amount to transfer
|
@@ -1971,7 +2026,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1971
2026
|
currency = self.currency(code)
|
1972
2027
|
request = {
|
1973
2028
|
'token': currency['id'],
|
1974
|
-
'amount': self.
|
2029
|
+
'amount': self.parse_to_numeric(amount),
|
1975
2030
|
'from_application_id': fromAccount,
|
1976
2031
|
'to_application_id': toAccount,
|
1977
2032
|
}
|
@@ -1983,7 +2038,7 @@ class woo(Exchange, ImplicitAPI):
|
|
1983
2038
|
# }
|
1984
2039
|
#
|
1985
2040
|
transfer = self.parse_transfer(response, currency)
|
1986
|
-
transferOptions = self.
|
2041
|
+
transferOptions = self.safe_dict(self.options, 'transfer', {})
|
1987
2042
|
fillResponseFromRequest = self.safe_bool(transferOptions, 'fillResponseFromRequest', True)
|
1988
2043
|
if fillResponseFromRequest:
|
1989
2044
|
transfer['amount'] = amount
|
@@ -1994,41 +2049,68 @@ class woo(Exchange, ImplicitAPI):
|
|
1994
2049
|
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
1995
2050
|
"""
|
1996
2051
|
fetch a history of internal transfers made on an account
|
2052
|
+
:see: https://docs.woo.org/#get-transfer-history
|
1997
2053
|
:param str code: unified currency code of the currency transferred
|
1998
2054
|
:param int [since]: the earliest time in ms to fetch transfers for
|
1999
2055
|
:param int [limit]: the maximum number of transfers structures to retrieve
|
2000
2056
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2057
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
2001
2058
|
:returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
|
2002
2059
|
"""
|
2003
|
-
request = {
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2060
|
+
request = {}
|
2061
|
+
if limit is not None:
|
2062
|
+
request['size'] = limit
|
2063
|
+
if since is not None:
|
2064
|
+
request['start_t'] = since
|
2065
|
+
until = self.safe_integer_2(params, 'until', 'till') # unified in milliseconds
|
2066
|
+
params = self.omit(params, ['until', 'till'])
|
2067
|
+
if until is not None:
|
2068
|
+
request['end_t'] = until
|
2069
|
+
response = await self.v1PrivateGetAssetMainSubTransferHistory(self.extend(request, params))
|
2070
|
+
#
|
2071
|
+
# {
|
2072
|
+
# "rows": [
|
2073
|
+
# {
|
2074
|
+
# "id": 46704,
|
2075
|
+
# "token": "USDT",
|
2076
|
+
# "amount": 30000.00000000,
|
2077
|
+
# "status": "COMPLETED",
|
2078
|
+
# "from_application_id": "0f1bd3cd-dba2-4563-b8bb-0adb1bfb83a3",
|
2079
|
+
# "to_application_id": "c01e6940-a735-4022-9b6c-9d3971cdfdfa",
|
2080
|
+
# "from_user": "LeverageLow",
|
2081
|
+
# "to_user": "dev",
|
2082
|
+
# "created_time": "1709022325.427",
|
2083
|
+
# "updated_time": "1709022325.542"
|
2084
|
+
# }
|
2085
|
+
# ],
|
2086
|
+
# "meta": {
|
2087
|
+
# "total": 50,
|
2088
|
+
# "records_per_page": 25,
|
2089
|
+
# "current_page": 1
|
2090
|
+
# },
|
2091
|
+
# "success": True
|
2092
|
+
# }
|
2093
|
+
#
|
2094
|
+
data = self.safe_list(response, 'rows', [])
|
2095
|
+
return self.parse_transfers(data, None, since, limit, params)
|
2008
2096
|
|
2009
2097
|
def parse_transfer(self, transfer, currency: Currency = None):
|
2010
2098
|
#
|
2011
|
-
#
|
2012
|
-
#
|
2013
|
-
#
|
2014
|
-
#
|
2015
|
-
#
|
2016
|
-
#
|
2017
|
-
#
|
2018
|
-
#
|
2019
|
-
#
|
2020
|
-
#
|
2021
|
-
#
|
2022
|
-
#
|
2023
|
-
#
|
2024
|
-
# "amount": 1000,
|
2025
|
-
# "tx_id": "0x8a74c517bc104c8ebad0c3c3f64b1f302ed5f8bca598ae4459c63419038106b6",
|
2026
|
-
# "fee_token": null,
|
2027
|
-
# "fee_amount": null,
|
2028
|
-
# "status": "CONFIRMING"
|
2029
|
-
# }
|
2099
|
+
# fetchTransfers
|
2100
|
+
# {
|
2101
|
+
# "id": 46704,
|
2102
|
+
# "token": "USDT",
|
2103
|
+
# "amount": 30000.00000000,
|
2104
|
+
# "status": "COMPLETED",
|
2105
|
+
# "from_application_id": "0f1bd3cd-dba2-4563-b8bb-0adb1bfb83a3",
|
2106
|
+
# "to_application_id": "c01e6940-a735-4022-9b6c-9d3971cdfdfa",
|
2107
|
+
# "from_user": "LeverageLow",
|
2108
|
+
# "to_user": "dev",
|
2109
|
+
# "created_time": "1709022325.427",
|
2110
|
+
# "updated_time": "1709022325.542"
|
2111
|
+
# }
|
2030
2112
|
#
|
2031
|
-
#
|
2113
|
+
# transfer
|
2032
2114
|
# {
|
2033
2115
|
# "success": True,
|
2034
2116
|
# "id": 200
|
@@ -2037,19 +2119,8 @@ class woo(Exchange, ImplicitAPI):
|
|
2037
2119
|
networkizedCode = self.safe_string(transfer, 'token')
|
2038
2120
|
currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
|
2039
2121
|
code = currencyDefined['code']
|
2040
|
-
movementDirection = self.safe_string_lower(transfer, 'token_side')
|
2041
|
-
if movementDirection == 'withdraw':
|
2042
|
-
movementDirection = 'withdrawal'
|
2043
|
-
fromAccount: Str = None
|
2044
|
-
toAccount: Str = None
|
2045
|
-
if movementDirection == 'withdraw':
|
2046
|
-
fromAccount = None
|
2047
|
-
toAccount = 'spot'
|
2048
|
-
elif movementDirection == 'deposit':
|
2049
|
-
fromAccount = 'spot'
|
2050
|
-
toAccount = None
|
2051
2122
|
timestamp = self.safe_timestamp(transfer, 'created_time')
|
2052
|
-
success = self.
|
2123
|
+
success = self.safe_bool(transfer, 'success')
|
2053
2124
|
status: Str = None
|
2054
2125
|
if success is not None:
|
2055
2126
|
status = 'ok' if success else 'failed'
|
@@ -2059,8 +2130,8 @@ class woo(Exchange, ImplicitAPI):
|
|
2059
2130
|
'datetime': self.iso8601(timestamp),
|
2060
2131
|
'currency': code,
|
2061
2132
|
'amount': self.safe_number(transfer, 'amount'),
|
2062
|
-
'fromAccount':
|
2063
|
-
'toAccount':
|
2133
|
+
'fromAccount': self.safe_string(transfer, 'from_application_id'),
|
2134
|
+
'toAccount': self.safe_string(transfer, 'to_application_id'),
|
2064
2135
|
'status': self.parse_transfer_status(self.safe_string(transfer, 'status', status)),
|
2065
2136
|
'info': transfer,
|
2066
2137
|
}
|
@@ -2095,11 +2166,11 @@ class woo(Exchange, ImplicitAPI):
|
|
2095
2166
|
}
|
2096
2167
|
if tag is not None:
|
2097
2168
|
request['extra'] = tag
|
2098
|
-
networks = self.
|
2099
|
-
currencyNetworks = self.
|
2169
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
2170
|
+
currencyNetworks = self.safe_dict(currency, 'networks', {})
|
2100
2171
|
network = self.safe_string_upper(params, 'network')
|
2101
2172
|
networkId = self.safe_string(networks, network, network)
|
2102
|
-
coinNetwork = self.
|
2173
|
+
coinNetwork = self.safe_dict(currencyNetworks, networkId, {})
|
2103
2174
|
coinNetworkId = self.safe_string(coinNetwork, 'id')
|
2104
2175
|
if coinNetworkId is None:
|
2105
2176
|
raise BadRequest(self.id + ' withdraw() require network parameter')
|
@@ -2179,7 +2250,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2179
2250
|
else:
|
2180
2251
|
self.check_required_credentials()
|
2181
2252
|
if method == 'POST' and (path == 'algo/order' or path == 'order'):
|
2182
|
-
isSandboxMode = self.
|
2253
|
+
isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
2183
2254
|
if not isSandboxMode:
|
2184
2255
|
applicationId = 'bc830de7-50f3-460b-9ee0-f430f83f9dad'
|
2185
2256
|
brokerId = self.safe_string(self.options, 'brokerId', applicationId)
|
@@ -2212,7 +2283,8 @@ class woo(Exchange, ImplicitAPI):
|
|
2212
2283
|
if method == 'POST' or method == 'PUT' or method == 'DELETE':
|
2213
2284
|
body = auth
|
2214
2285
|
else:
|
2215
|
-
|
2286
|
+
if params:
|
2287
|
+
url += '?' + auth
|
2216
2288
|
auth += '|' + ts
|
2217
2289
|
headers['content-type'] = 'application/x-www-form-urlencoded'
|
2218
2290
|
headers['x-api-signature'] = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
|
@@ -2225,7 +2297,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2225
2297
|
# 400 Bad Request {"success":false,"code":-1012,"message":"Amount is required for buy market orders when margin disabled."}
|
2226
2298
|
# {"code":"-1011","message":"The system is under maintenance.","success":false}
|
2227
2299
|
#
|
2228
|
-
success = self.
|
2300
|
+
success = self.safe_bool(response, 'success')
|
2229
2301
|
errorCode = self.safe_string(response, 'code')
|
2230
2302
|
if not success:
|
2231
2303
|
feedback = self.id + ' ' + self.json(response)
|
@@ -2298,7 +2370,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2298
2370
|
# "success":true
|
2299
2371
|
# }
|
2300
2372
|
#
|
2301
|
-
result = self.
|
2373
|
+
result = self.safe_list(response, 'rows', [])
|
2302
2374
|
return self.parse_incomes(result, market, since, limit)
|
2303
2375
|
|
2304
2376
|
def parse_funding_rate(self, fundingRate, market: Market = None):
|
@@ -2379,7 +2451,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2379
2451
|
# "timestamp":1653633985646
|
2380
2452
|
# }
|
2381
2453
|
#
|
2382
|
-
rows = self.
|
2454
|
+
rows = self.safe_list(response, 'rows', [])
|
2383
2455
|
result = self.parse_funding_rates(rows)
|
2384
2456
|
return self.filter_by_array(result, 'symbol', symbols)
|
2385
2457
|
|
@@ -2428,7 +2500,7 @@ class woo(Exchange, ImplicitAPI):
|
|
2428
2500
|
# "timestamp":1653640814885
|
2429
2501
|
# }
|
2430
2502
|
#
|
2431
|
-
result = self.
|
2503
|
+
result = self.safe_list(response, 'rows')
|
2432
2504
|
rates = []
|
2433
2505
|
for i in range(0, len(result)):
|
2434
2506
|
entry = result[i]
|
@@ -2582,8 +2654,8 @@ class woo(Exchange, ImplicitAPI):
|
|
2582
2654
|
# "timestamp": 1673323880342
|
2583
2655
|
# }
|
2584
2656
|
#
|
2585
|
-
result = self.
|
2586
|
-
positions = self.
|
2657
|
+
result = self.safe_dict(response, 'data', {})
|
2658
|
+
positions = self.safe_list(result, 'positions', [])
|
2587
2659
|
return self.parse_positions(positions, symbols)
|
2588
2660
|
|
2589
2661
|
def parse_position(self, position, market: Market = None):
|
ccxt/base/exchange.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
|
7
|
-
__version__ = '4.2.
|
7
|
+
__version__ = '4.2.60'
|
8
8
|
|
9
9
|
# -----------------------------------------------------------------------------
|
10
10
|
|
@@ -3825,6 +3825,8 @@ class Exchange(object):
|
|
3825
3825
|
if value is not None:
|
3826
3826
|
params = self.omit(params, [optionName, defaultOptionName])
|
3827
3827
|
else:
|
3828
|
+
# handle routed methods like "watchTrades > watchTradesForSymbols"(or "watchTicker > watchTickers")
|
3829
|
+
methodName, params = self.handleParamString(params, 'callerMethodName', methodName)
|
3828
3830
|
# check if exchange has properties for self method
|
3829
3831
|
exchangeWideMethodOptions = self.safe_value(self.options, methodName)
|
3830
3832
|
if exchangeWideMethodOptions is not None:
|
ccxt/binance.py
CHANGED
@@ -4626,7 +4626,7 @@ class binance(Exchange, ImplicitAPI):
|
|
4626
4626
|
stopPriceIsRequired = False
|
4627
4627
|
quantityIsRequired = False
|
4628
4628
|
if uppercaseType == 'MARKET':
|
4629
|
-
quoteOrderQty = self.
|
4629
|
+
quoteOrderQty = self.safe_bool(self.options, 'quoteOrderQty', True)
|
4630
4630
|
if quoteOrderQty:
|
4631
4631
|
quoteOrderQtyNew = self.safe_value_2(params, 'quoteOrderQty', 'cost')
|
4632
4632
|
precision = market['precision']['price']
|
@@ -9546,7 +9546,7 @@ class binance(Exchange, ImplicitAPI):
|
|
9546
9546
|
# POST https://fapi.binance.com/fapi/v1/marginType 400 Bad Request
|
9547
9547
|
# binanceusdm
|
9548
9548
|
if isinstance(e, MarginModeAlreadySet):
|
9549
|
-
throwMarginModeAlreadySet = self.
|
9549
|
+
throwMarginModeAlreadySet = self.safe_bool(self.options, 'throwMarginModeAlreadySet', False)
|
9550
9550
|
if throwMarginModeAlreadySet:
|
9551
9551
|
raise e
|
9552
9552
|
else:
|
ccxt/bingx.py
CHANGED
@@ -7,7 +7,7 @@ from ccxt.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.bingx import ImplicitAPI
|
8
8
|
import hashlib
|
9
9
|
import numbers
|
10
|
-
from ccxt.base.types import Balances, Currency, Int, Leverage, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
|
10
|
+
from ccxt.base.types import Balances, Currency, Int, Leverage, MarginMode, Market, Order, TransferEntry, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, Transaction
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
13
|
from ccxt.base.errors import PermissionDenied
|
@@ -72,6 +72,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
72
72
|
'fetchFundingRates': True,
|
73
73
|
'fetchLeverage': True,
|
74
74
|
'fetchLiquidations': False,
|
75
|
+
'fetchMarginMode': True,
|
75
76
|
'fetchMarkets': True,
|
76
77
|
'fetchMarkOHLCV': True,
|
77
78
|
'fetchMyLiquidations': True,
|
@@ -457,7 +458,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
457
458
|
"""
|
458
459
|
if not self.check_required_credentials(False):
|
459
460
|
return None
|
460
|
-
isSandbox = self.
|
461
|
+
isSandbox = self.safe_bool(self.options, 'sandboxMode', False)
|
461
462
|
if isSandbox:
|
462
463
|
return None
|
463
464
|
response = self.walletsV1PrivateGetCapitalConfigGetall(params)
|
@@ -692,7 +693,7 @@ class bingx(Exchange, ImplicitAPI):
|
|
692
693
|
:returns dict[]: an array of objects representing market data
|
693
694
|
"""
|
694
695
|
requests = [self.fetch_swap_markets(params)]
|
695
|
-
isSandbox = self.
|
696
|
+
isSandbox = self.safe_bool(self.options, 'sandboxMode', False)
|
696
697
|
if not isSandbox:
|
697
698
|
requests.append(self.fetch_spot_markets(params)) # sandbox is swap only
|
698
699
|
promises = requests
|
@@ -3898,11 +3899,46 @@ class bingx(Exchange, ImplicitAPI):
|
|
3898
3899
|
data = self.safe_dict(response, 'data')
|
3899
3900
|
return self.parse_order(data, market)
|
3900
3901
|
|
3902
|
+
def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
|
3903
|
+
"""
|
3904
|
+
fetches the margin mode of the trading pair
|
3905
|
+
:see: https://bingx-api.github.io/docs/#/en-us/swapV2/trade-api.html#Query%20Margin%20Mode
|
3906
|
+
:param str symbol: unified symbol of the market to fetch the margin mode for
|
3907
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3908
|
+
:returns dict: Struct of MarginMode
|
3909
|
+
"""
|
3910
|
+
self.load_markets()
|
3911
|
+
market = self.market(symbol)
|
3912
|
+
request: dict = {
|
3913
|
+
'symbol': market['id'],
|
3914
|
+
}
|
3915
|
+
response = self.swapV2PrivateGetTradeMarginType(self.extend(request, params))
|
3916
|
+
#
|
3917
|
+
# {
|
3918
|
+
# "code": 0,
|
3919
|
+
# "msg": "",
|
3920
|
+
# "data": {
|
3921
|
+
# "marginType": "CROSSED"
|
3922
|
+
# }
|
3923
|
+
# }
|
3924
|
+
#
|
3925
|
+
data = self.safe_dict(response, 'data', {})
|
3926
|
+
return self.parse_margin_mode(data, market)
|
3927
|
+
|
3928
|
+
def parse_margin_mode(self, marginMode, market=None) -> MarginMode:
|
3929
|
+
marginType = self.safe_string_lower(marginMode, 'marginType')
|
3930
|
+
marginType = 'cross' if (marginType == 'crossed') else marginType
|
3931
|
+
return {
|
3932
|
+
'info': marginMode,
|
3933
|
+
'symbol': market['symbol'],
|
3934
|
+
'marginMode': marginType,
|
3935
|
+
}
|
3936
|
+
|
3901
3937
|
def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
|
3902
3938
|
type = section[0]
|
3903
3939
|
version = section[1]
|
3904
3940
|
access = section[2]
|
3905
|
-
isSandbox = self.
|
3941
|
+
isSandbox = self.safe_bool(self.options, 'sandboxMode', False)
|
3906
3942
|
if isSandbox and (type != 'swap'):
|
3907
3943
|
raise NotSupported(self.id + ' does not have a testnet/sandbox URL for ' + type + ' endpoints')
|
3908
3944
|
url = self.implode_hostname(self.urls['api'][type])
|
ccxt/bitfinex2.py
CHANGED
@@ -46,8 +46,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
46
46
|
'spot': True,
|
47
47
|
'margin': True,
|
48
48
|
'swap': True,
|
49
|
-
'future':
|
50
|
-
'option':
|
49
|
+
'future': False,
|
50
|
+
'option': False,
|
51
51
|
'addMargin': False,
|
52
52
|
'borrowCrossMargin': False,
|
53
53
|
'borrowIsolatedMargin': False,
|
@@ -58,6 +58,7 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
58
58
|
'createLimitOrder': True,
|
59
59
|
'createMarketOrder': True,
|
60
60
|
'createOrder': True,
|
61
|
+
'createPostOnlyOrder': True,
|
61
62
|
'createReduceOnlyOrder': True,
|
62
63
|
'createStopLimitOrder': True,
|
63
64
|
'createStopMarketOrder': True,
|
@@ -68,8 +69,11 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
68
69
|
'editOrder': True,
|
69
70
|
'fetchBalance': True,
|
70
71
|
'fetchBorrowInterest': False,
|
72
|
+
'fetchBorrowRate': False,
|
71
73
|
'fetchBorrowRateHistories': False,
|
72
74
|
'fetchBorrowRateHistory': False,
|
75
|
+
'fetchBorrowRates': False,
|
76
|
+
'fetchBorrowRatesPerSymbol': False,
|
73
77
|
'fetchClosedOrder': True,
|
74
78
|
'fetchClosedOrders': True,
|
75
79
|
'fetchCrossBorrowRate': False,
|
@@ -98,6 +102,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
98
102
|
'fetchOpenOrder': True,
|
99
103
|
'fetchOpenOrders': True,
|
100
104
|
'fetchOrder': True,
|
105
|
+
'fetchOrderBook': True,
|
106
|
+
'fetchOrderBooks': False,
|
101
107
|
'fetchOrderTrades': True,
|
102
108
|
'fetchPosition': False,
|
103
109
|
'fetchPositionMode': False,
|
@@ -117,6 +123,8 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
117
123
|
'setMargin': True,
|
118
124
|
'setMarginMode': False,
|
119
125
|
'setPositionMode': False,
|
126
|
+
'signIn': False,
|
127
|
+
'transfer': True,
|
120
128
|
'withdraw': True,
|
121
129
|
},
|
122
130
|
'timeframes': {
|
@@ -1484,7 +1492,16 @@ class bitfinex2(Exchange, ImplicitAPI):
|
|
1484
1492
|
:param float amount: how much you want to trade in units of the base currency
|
1485
1493
|
:param float [price]: the price of the order, in units of the quote currency, ignored in market orders
|
1486
1494
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1487
|
-
:
|
1495
|
+
:param float [params.stopPrice]: The price at which a trigger order is triggered at
|
1496
|
+
:param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
|
1497
|
+
:param bool [params.postOnly]:
|
1498
|
+
:param bool [params.reduceOnly]: Ensures that the executed order does not flip the opened position.
|
1499
|
+
:param int [params.flags]: additional order parameters: 4096(Post Only), 1024(Reduce Only), 16384(OCO), 64(Hidden), 512(Close), 524288(No Var Rates)
|
1500
|
+
:param int [params.lev]: leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive.
|
1501
|
+
:param str [params.price_traling]: The trailing price for a trailing stop order
|
1502
|
+
:param str [params.price_aux_limit]: Order price for stop limit orders
|
1503
|
+
:param str [params.price_oco_stop]: OCO stop price
|
1504
|
+
:returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1488
1505
|
"""
|
1489
1506
|
market = self.market(symbol)
|
1490
1507
|
amountString = self.amount_to_precision(symbol, amount)
|