add
This commit is contained in:
253
ccxt/test/exchange/sync/test_create_order.py
Normal file
253
ccxt/test/exchange/sync/test_create_order.py
Normal file
@@ -0,0 +1,253 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.base.decimal_to_precision import TICK_SIZE # noqa E402
|
||||
from ccxt.base.decimal_to_precision import TRUNCATE # noqa E402
|
||||
from ccxt.base.decimal_to_precision import ROUND # noqa E402
|
||||
from ccxt.base.decimal_to_precision import ROUND_UP # noqa E402
|
||||
from ccxt.base.decimal_to_precision import decimal_to_precision # noqa E402
|
||||
from ccxt.base.decimal_to_precision import number_to_string # noqa E402
|
||||
from ccxt.base.precise import Precise # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
from ccxt.test.exchange.base import test_order # noqa E402
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
def tco_debug(exchange, symbol, message):
|
||||
# just for debugging purposes
|
||||
debug_create_order = True
|
||||
if debug_create_order:
|
||||
# for c# fix, extra step to convert them to string
|
||||
print(' >>>>> testCreateOrder [', str((exchange['id'])), ' : ', symbol, '] ', message)
|
||||
return True
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
def test_create_order(exchange, skipped_properties, symbol):
|
||||
log_prefix = test_shared_methods.log_template(exchange, 'createOrder', [symbol])
|
||||
assert exchange.has['cancelOrder'] or exchange.has['cancelOrders'] or exchange.has['cancelAllOrders'], log_prefix + ' does not have cancelOrder|cancelOrders|canelAllOrders method, which is needed to make tests for `createOrder` method. Skipping the test...'
|
||||
# pre-define some coefficients, which will be used down below
|
||||
limit_price_safety_multiplier_from_median = 1.045 # todo: when this https://github.com/ccxt/ccxt/issues/22442 is implemented, we'll remove hardcoded value. atm 5% is enough
|
||||
market = exchange.market(symbol)
|
||||
is_swap_future = market['swap'] or market['future']
|
||||
assert exchange.has['fetchBalance'], log_prefix + ' does not have fetchBalance() method, which is needed to make tests for `createOrder` method. Skipping the test...'
|
||||
balance = exchange.fetch_balance()
|
||||
initial_base_balance = balance[market['base']]['free']
|
||||
initial_quote_balance = balance[market['quote']]['free']
|
||||
assert initial_quote_balance is not None, log_prefix + ' - testing account not have balance of' + market['quote'] + ' in fetchBalance() which is required to test'
|
||||
tco_debug(exchange, symbol, 'fetched balance for ' + symbol + ' : ' + str(initial_base_balance) + ' ' + market['base'] + '/' + initial_quote_balance + ' ' + market['quote'])
|
||||
[best_bid, best_ask] = test_shared_methods.fetch_best_bid_ask(exchange, 'createOrder', symbol)
|
||||
# **************** [Scenario 1 - START] **************** #
|
||||
tco_debug(exchange, symbol, '### SCENARIO 1 ###')
|
||||
# create a "limit order" which IS GUARANTEED not to have a fill (i.e. being far from the real price)
|
||||
tco_create_unfillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, 'buy', None)
|
||||
if is_swap_future:
|
||||
# for swap markets, we test sell orders too
|
||||
tco_create_unfillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, 'sell', None)
|
||||
tco_debug(exchange, symbol, '### SCENARIO 1 PASSED ###')
|
||||
# **************** [Scenario 2 - START] **************** #
|
||||
tco_debug(exchange, symbol, '### SCENARIO 2 ###')
|
||||
# create an order which IS GUARANTEED to have a fill (full or partial)
|
||||
tco_create_fillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, 'buy', None)
|
||||
if is_swap_future:
|
||||
# for swap markets, we test sell orders too
|
||||
tco_create_fillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, 'sell', None)
|
||||
tco_debug(exchange, symbol, '### SCENARIO 2 PASSED ###')
|
||||
# **************** [Scenario 3 - START] **************** #
|
||||
return True
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
def tco_create_unfillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, buy_or_sell, predefined_amount=None):
|
||||
try:
|
||||
symbol = market['symbol']
|
||||
minimun_prices = exchange.safe_dict(market['limits'], 'price', {})
|
||||
minimum_price = minimun_prices['min']
|
||||
maximum_price = minimun_prices['max']
|
||||
# below we set limit price, where the order will not be completed.
|
||||
# We do not use the extreme "limits" values for that market, because, even though min purchase amount for BTC/USDT can be 0.01 BTC, it means with 10$ you can buy 1000 BTC, which leads to unrealistic outcome. So, we just use around 5%-10% far price from the current price.
|
||||
limit_buy_price_non_fillable = best_bid / limit_price_safety_multiplier_from_median
|
||||
if minimum_price is not None and limit_buy_price_non_fillable < minimum_price:
|
||||
limit_buy_price_non_fillable = minimum_price
|
||||
limit_sell_price_non_fillable = best_ask * limit_price_safety_multiplier_from_median
|
||||
if maximum_price is not None and limit_sell_price_non_fillable > maximum_price:
|
||||
limit_sell_price_non_fillable = maximum_price
|
||||
created_order = None
|
||||
if buy_or_sell == 'buy':
|
||||
order_amount = tco_get_minimum_amount_for_limit_price(exchange, market, limit_buy_price_non_fillable, predefined_amount)
|
||||
created_order = tco_create_order_safe(exchange, symbol, 'limit', 'buy', order_amount, limit_buy_price_non_fillable, {}, skipped_properties)
|
||||
else:
|
||||
order_amount = tco_get_minimum_amount_for_limit_price(exchange, market, limit_sell_price_non_fillable, predefined_amount)
|
||||
created_order = tco_create_order_safe(exchange, symbol, 'limit', 'sell', order_amount, limit_sell_price_non_fillable, {}, skipped_properties)
|
||||
fetched_order = test_shared_methods.fetch_order(exchange, symbol, created_order['id'], skipped_properties)
|
||||
# test fetched order object
|
||||
if fetched_order is not None:
|
||||
test_order(exchange, skipped_properties, 'createOrder', fetched_order, symbol, exchange.milliseconds())
|
||||
# ensure that order is not filled
|
||||
test_shared_methods.assert_order_state(exchange, skipped_properties, 'createdOrder', created_order, 'open', False)
|
||||
test_shared_methods.assert_order_state(exchange, skipped_properties, 'fetchedOrder', fetched_order, 'open', True)
|
||||
# ensure that order side matches
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'createdOrder', created_order, 'side', [None, buy_or_sell])
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'fetchedOrder', fetched_order, 'side', [None, buy_or_sell])
|
||||
tco_cancel_order(exchange, symbol, created_order['id'])
|
||||
except Exception as e:
|
||||
raise Error(log_prefix + ' failed for Scenario 1: ' + str(e))
|
||||
return True
|
||||
|
||||
|
||||
def tco_create_fillable_order(exchange, market, log_prefix, skipped_properties, best_bid, best_ask, limit_price_safety_multiplier_from_median, buy_or_sell_string, predefined_amount=None):
|
||||
try:
|
||||
is_swap_future = market['swap'] or market['future']
|
||||
is_buy = (buy_or_sell_string == 'buy')
|
||||
entry_side = 'buy' if is_buy else 'sell'
|
||||
exit_side = 'sell' if is_buy else 'buy'
|
||||
entryorder_price = best_ask * limit_price_safety_multiplier_from_median if is_buy else best_bid / limit_price_safety_multiplier_from_median
|
||||
exitorder_price = best_bid / limit_price_safety_multiplier_from_median if is_buy else best_ask * limit_price_safety_multiplier_from_median # todo revise: (tcoMininumCost (exchange, market) / amountToClose) / limitPriceSafetyMultiplierFromMedian;
|
||||
#
|
||||
#
|
||||
symbol = market['symbol']
|
||||
entry_amount = tco_get_minimum_amount_for_limit_price(exchange, market, entryorder_price)
|
||||
entryorder_filled = tco_create_order_safe(exchange, symbol, 'limit', entry_side, entry_amount, entryorder_price, {}, skipped_properties)
|
||||
# just for case, cancel any possible unfilled amount (though it is not be expected because the order was fillable)
|
||||
tco_try_cancel_order(exchange, symbol, entryorder_filled, skipped_properties)
|
||||
# now, as order is closed/canceled, we can reliably fetch the order information
|
||||
entryorder_fetched = test_shared_methods.fetch_order(exchange, symbol, entryorder_filled['id'], skipped_properties)
|
||||
tco_assert_filled_order(exchange, market, log_prefix, skipped_properties, entryorder_filled, entryorder_fetched, entry_side, entry_amount)
|
||||
#
|
||||
# ### close the traded position ###
|
||||
#
|
||||
amount_to_close = exchange.parse_to_numeric(exchange.safe_string(entryorder_fetched, 'filled'))
|
||||
params = {}
|
||||
# as we want to close position, we should use 'reduceOnly' to ensure we don't open a margined position accidentally, because some exchanges might have automatically enabled margin-mode (on spot) or hedge-mode (on contracts)
|
||||
if is_swap_future:
|
||||
params['reduceOnly'] = True
|
||||
exitorder_filled = tco_create_order_safe(exchange, symbol, 'market', exit_side, amount_to_close, (None if market['spot'] else exitorder_price), params, skipped_properties)
|
||||
exitorder_fetched = test_shared_methods.fetch_order(exchange, symbol, exitorder_filled['id'], skipped_properties)
|
||||
tco_assert_filled_order(exchange, market, log_prefix, skipped_properties, exitorder_filled, exitorder_fetched, exit_side, amount_to_close)
|
||||
except Exception as e:
|
||||
raise Error('failed for Scenario 2: ' + str(e))
|
||||
return True
|
||||
|
||||
|
||||
def tco_assert_filled_order(exchange, market, log_prefix, skipped_properties, created_order, fetched_order, requested_side, requested_amount):
|
||||
# test filled amount
|
||||
precision_amount = exchange.safe_string(market['precision'], 'amount')
|
||||
entryorder_amount_string = exchange.number_to_string(requested_amount)
|
||||
filled_string = exchange.safe_string(fetched_order, 'filled')
|
||||
assert filled_string is not None, log_prefix + ' order should be filled, but it is not. ' + exchange.json(fetched_order)
|
||||
# filled amount should be whithin the expected range i.e. if you buy 100 DOGECOIN and amount-precision is 1,
|
||||
# and also considering possible roundings in implementation, then filled amount should be between 99 and 101
|
||||
max_expected_filled_amount = Precise.string_add(entryorder_amount_string, precision_amount)
|
||||
min_expected_filled_amount = Precise.string_sub(entryorder_amount_string, precision_amount)
|
||||
assert Precise.string_le(filled_string, max_expected_filled_amount), log_prefix + ' filled amount is more than expected, possibly some implementation issue. ' + exchange.json(fetched_order)
|
||||
assert Precise.string_ge(filled_string, min_expected_filled_amount), log_prefix + ' filled amount is less than expected, possibly some implementation issue. ' + exchange.json(fetched_order)
|
||||
# order state should be "closed"
|
||||
test_shared_methods.assert_order_state(exchange, skipped_properties, 'createdOrder', created_order, 'closed', False)
|
||||
test_shared_methods.assert_order_state(exchange, skipped_properties, 'fetchedOrder', fetched_order, 'closed', True)
|
||||
# ensure that order side matches
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'createdOrder', created_order, 'side', [None, requested_side])
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'fetchedOrder', fetched_order, 'side', [None, requested_side])
|
||||
return True
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
def tco_cancel_order(exchange, symbol, order_id=None):
|
||||
log_prefix = test_shared_methods.log_template(exchange, 'createOrder', [symbol])
|
||||
used_method = ''
|
||||
cancel_result = None
|
||||
if exchange.has['cancelOrder'] and order_id is not None:
|
||||
used_method = 'cancelOrder'
|
||||
cancel_result = exchange.cancel_order(order_id, symbol)
|
||||
elif exchange.has['cancelAllOrders']:
|
||||
used_method = 'cancelAllOrders'
|
||||
cancel_result = exchange.cancel_all_orders(symbol)
|
||||
elif exchange.has['cancelOrders']:
|
||||
raise Error(log_prefix + ' cancelOrders method is not unified yet, coming soon...')
|
||||
tco_debug(exchange, symbol, 'canceled order using ' + used_method + ':' + cancel_result['id'])
|
||||
# todo:
|
||||
# testSharedMethods.assertOrderState (exchange, skippedProperties, 'cancelOrder', cancelResult, 'canceled', false);
|
||||
# testSharedMethods.assertOrderState (exchange, skippedProperties, 'cancelOrder', cancelResult, 'closed', true);
|
||||
return True
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------------
|
||||
def tco_create_order_safe(exchange, symbol, order_type, side, amount, price=None, params={}, skipped_properties={}):
|
||||
tco_debug(exchange, symbol, 'Executing createOrder ' + order_type + ' ' + side + ' ' + amount + ' ' + price + ' ' + exchange.json(params))
|
||||
order = exchange.create_order(symbol, order_type, side, amount, price, params)
|
||||
try:
|
||||
test_order(exchange, skipped_properties, 'createOrder', order, symbol, int(time.time() * 1000))
|
||||
except Exception as e:
|
||||
if order_type != 'market':
|
||||
# if it was limit order, try to cancel it before exiting the script
|
||||
tco_try_cancel_order(exchange, symbol, order, skipped_properties)
|
||||
raise e
|
||||
return order
|
||||
|
||||
|
||||
def tco_mininum_amount(exchange, market):
|
||||
amount_values = exchange.safe_dict(market['limits'], 'amount', {})
|
||||
amount_min = exchange.safe_number(amount_values, 'min')
|
||||
assert amount_min is not None, exchange.id + ' ' + market['symbol'] + ' can not determine minimum amount for order'
|
||||
return amount_min
|
||||
|
||||
|
||||
def tco_mininum_cost(exchange, market):
|
||||
cost_values = exchange.safe_dict(market['limits'], 'cost', {})
|
||||
cost_min = exchange.safe_number(cost_values, 'min')
|
||||
assert cost_min is not None, exchange.id + ' ' + market['symbol'] + ' can not determine minimum cost for order'
|
||||
return cost_min
|
||||
|
||||
|
||||
def tco_get_minimum_amount_for_limit_price(exchange, market, price, predefined_amount=None):
|
||||
# this method calculates the minimum realistic order amount:
|
||||
# at first it checks the "minimum hardcap limit" (i.e. 7 DOGE), however, if exchange also has "minimum cost" limits,
|
||||
# then we need to calculate the amount using cost, because of price is volatile, today's 7 DOGE cost could be 1$
|
||||
# but "minimum cost" requirement could be 5$ (which translates to 35 DOGE amount)
|
||||
minimum_amount = tco_mininum_amount(exchange, market)
|
||||
minimum_cost = tco_mininum_cost(exchange, market)
|
||||
final_amount = minimum_amount
|
||||
if minimum_cost is not None:
|
||||
if final_amount * price < minimum_cost:
|
||||
final_amount = minimum_cost / price
|
||||
if predefined_amount is not None:
|
||||
final_amount = max(final_amount, predefined_amount)
|
||||
# because it's possible that calculated value might get truncated down in "createOrder" (i.e. 0.129 -> 0.12), we should ensure that final amount * price would bypass minimum cost requirements, by adding the "minimum precision"
|
||||
amount_precision = exchange.safe_number(market['precision'], 'amount')
|
||||
is_tick_size_precision = exchange.precisionMode == 4
|
||||
if amount_precision is None:
|
||||
amount_precision = 1e-15 # todo: revise this for better way in future
|
||||
else:
|
||||
# todo: remove after TICK_SIZE unification
|
||||
if not is_tick_size_precision:
|
||||
amount_precision = 1 / math.pow(10, amount_precision) # this converts DECIMAL_PRECISION into TICK_SIZE
|
||||
final_amount = final_amount + amount_precision
|
||||
final_amount = final_amount * 1.1 # add around 10% to ensure "cost" is enough
|
||||
final_amount = float(exchange.decimal_to_precision(final_amount, 2, market['precision']['amount'], exchange.precisionMode)) # 2 stands for ROUND_UP constant, 0 stands for TRUNCATE
|
||||
return final_amount
|
||||
|
||||
|
||||
def tco_try_cancel_order(exchange, symbol, order, skipped_properties):
|
||||
order_fetched = test_shared_methods.fetch_order(exchange, symbol, order['id'], skipped_properties)
|
||||
needs_cancel = exchange.in_array(order_fetched['status'], ['open', 'pending', None])
|
||||
# if it was not reported as closed/filled, then try to cancel it
|
||||
if needs_cancel:
|
||||
tco_debug(exchange, symbol, 'trying to cancel the remaining amount of partially filled order...')
|
||||
try:
|
||||
tco_cancel_order(exchange, symbol, order['id'])
|
||||
except Exception as e:
|
||||
# order might have been closed/filled already, before 'cancelOrder' call reaches server, so it is tolerable, we don't throw exception
|
||||
tco_debug(exchange, symbol, ' a moment ago order was reported as pending, but could not be cancelled at this moment. Exception message: ' + str(e))
|
||||
else:
|
||||
tco_debug(exchange, symbol, 'order is already closed/filled, no need to cancel it')
|
||||
return True
|
||||
124
ccxt/test/exchange/sync/test_features.py
Normal file
124
ccxt/test/exchange/sync/test_features.py
Normal file
@@ -0,0 +1,124 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_features(exchange, skipped_properties):
|
||||
market_types = ['spot', 'swap', 'future', 'option']
|
||||
sub_types = ['linear', 'inverse']
|
||||
features = exchange.features
|
||||
keys = list(features.keys())
|
||||
for i in range(0, len(keys)):
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'features', keys, i, market_types)
|
||||
market_type = keys[i]
|
||||
value = features[market_type]
|
||||
# assert (value !== undefined, 'exchange.features["' + marketType + '"] is undefined, that key should be either absent or have a value');
|
||||
if value is None:
|
||||
continue
|
||||
if market_type == 'spot':
|
||||
test_features_inner(exchange, skipped_properties, value)
|
||||
else:
|
||||
sub_keys = list(value.keys())
|
||||
for j in range(0, len(sub_keys)):
|
||||
sub_key = sub_keys[j]
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'features', sub_keys, j, sub_types)
|
||||
sub_value = value[sub_key]
|
||||
# sometimes it might not be available for exchange, eg. future>inverse)
|
||||
if sub_value is not None:
|
||||
test_features_inner(exchange, skipped_properties, sub_value)
|
||||
return True
|
||||
|
||||
|
||||
def test_features_inner(exchange, skipped_properties, feature_obj):
|
||||
format = {
|
||||
'sandbox': False,
|
||||
'createOrder': {
|
||||
'marginMode': False,
|
||||
'triggerPrice': False,
|
||||
'triggerPriceType': {
|
||||
'mark': False,
|
||||
'last': False,
|
||||
'index': False,
|
||||
},
|
||||
'stopLossPrice': False,
|
||||
'takeProfitPrice': False,
|
||||
'attachedStopLossTakeProfit': {
|
||||
'triggerPriceType': {
|
||||
'last': False,
|
||||
'mark': False,
|
||||
'index': False,
|
||||
},
|
||||
'price': False,
|
||||
},
|
||||
'timeInForce': {
|
||||
'GTC': False,
|
||||
'IOC': False,
|
||||
'FOK': False,
|
||||
'PO': False,
|
||||
'GTD': False,
|
||||
},
|
||||
'hedged': False,
|
||||
'trailing': False,
|
||||
},
|
||||
'createOrders': {
|
||||
'max': 5,
|
||||
},
|
||||
'fetchMyTrades': {
|
||||
'marginMode': False,
|
||||
'daysBack': 0,
|
||||
'limit': 0,
|
||||
'untilDays': 0,
|
||||
'symbolRequired': False,
|
||||
},
|
||||
'fetchOrder': {
|
||||
'marginMode': False,
|
||||
'trigger': False,
|
||||
'trailing': False,
|
||||
'symbolRequired': False,
|
||||
},
|
||||
'fetchOpenOrders': {
|
||||
'marginMode': False,
|
||||
'limit': 0,
|
||||
'trigger': False,
|
||||
'trailing': False,
|
||||
'symbolRequired': False,
|
||||
},
|
||||
'fetchOrders': {
|
||||
'marginMode': False,
|
||||
'limit': 0,
|
||||
'daysBack': 0,
|
||||
'untilDays': 0,
|
||||
'trigger': False,
|
||||
'trailing': False,
|
||||
'symbolRequired': False,
|
||||
},
|
||||
'fetchClosedOrders': {
|
||||
'marginMode': False,
|
||||
'limit': 0,
|
||||
'daysBack': 0,
|
||||
'daysBackCanceled': 0,
|
||||
'untilDays': 0,
|
||||
'trigger': False,
|
||||
'trailing': False,
|
||||
'symbolRequired': False,
|
||||
},
|
||||
'fetchOHLCV': {
|
||||
'limit': 0,
|
||||
},
|
||||
}
|
||||
feature_keys = list(feature_obj.keys())
|
||||
all_methods = list(exchange.has.keys())
|
||||
for i in range(0, len(feature_keys)):
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, 'features', feature_keys, i, all_methods)
|
||||
test_shared_methods.assert_structure(exchange, skipped_properties, 'features', feature_obj, format, None, True) # deep structure check
|
||||
24
ccxt/test/exchange/sync/test_fetch_accounts.py
Normal file
24
ccxt/test/exchange/sync/test_fetch_accounts.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_account # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_accounts(exchange, skipped_properties):
|
||||
method = 'fetchAccounts'
|
||||
accounts = exchange.fetch_accounts()
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, accounts)
|
||||
for i in range(0, len(accounts)):
|
||||
test_account(exchange, skipped_properties, method, accounts[i])
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_balance.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_balance.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_balance # noqa E402
|
||||
|
||||
def test_fetch_balance(exchange, skipped_properties):
|
||||
method = 'fetchBalance'
|
||||
response = exchange.fetch_balance()
|
||||
test_balance(exchange, skipped_properties, method, response)
|
||||
return True
|
||||
24
ccxt/test/exchange/sync/test_fetch_borrow_interest.py
Normal file
24
ccxt/test/exchange/sync/test_fetch_borrow_interest.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_borrow_interest # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_borrow_interest(exchange, skipped_properties, code, symbol):
|
||||
method = 'fetchBorrowInterest'
|
||||
borrow_interest = exchange.fetch_borrow_interest(code, symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, borrow_interest, code)
|
||||
for i in range(0, len(borrow_interest)):
|
||||
test_borrow_interest(exchange, skipped_properties, method, borrow_interest[i], code, symbol)
|
||||
return True
|
||||
28
ccxt/test/exchange/sync/test_fetch_closed_orders.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_closed_orders.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_closed_orders(exchange, skipped_properties, symbol):
|
||||
method = 'fetchClosedOrders'
|
||||
orders = exchange.fetch_closed_orders(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, orders, symbol)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(orders)):
|
||||
order = orders[i]
|
||||
test_order(exchange, skipped_properties, method, order, symbol, now)
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, method, order, 'status', ['closed', 'canceled'])
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, orders)
|
||||
return True
|
||||
73
ccxt/test/exchange/sync/test_fetch_currencies.py
Normal file
73
ccxt/test/exchange/sync/test_fetch_currencies.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_currency # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_currencies(exchange, skipped_properties):
|
||||
method = 'fetchCurrencies'
|
||||
currencies = exchange.fetch_currencies()
|
||||
# todo: try to invent something to avoid undefined undefined, i.e. maybe move into private and force it to have a value
|
||||
num_inactive_currencies = 0
|
||||
max_inactive_currencies_percentage = exchange.safe_integer(skipped_properties, 'maxInactiveCurrenciesPercentage', 50) # no more than X% currencies should be inactive
|
||||
required_active_currencies = ['BTC', 'ETH', 'USDT', 'USDC']
|
||||
features = exchange.features
|
||||
features_spot = exchange.safe_dict(features, 'spot', {})
|
||||
fetch_currencies = exchange.safe_dict(features_spot, 'fetchCurrencies', {})
|
||||
is_fetch_currencies_private = exchange.safe_value(fetch_currencies, 'private', False)
|
||||
if not is_fetch_currencies_private:
|
||||
values = list(currencies.values())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, values)
|
||||
currencies_length = len(values)
|
||||
# ensure exchange returns enough length of currencies
|
||||
skip_amount = ('amountOfCurrencies' in skipped_properties)
|
||||
assert skip_amount or currencies_length > 5, exchange.id + ' ' + method + ' must return at least several currencies, but it returned ' + str(currencies_length)
|
||||
# allow skipped exchanges
|
||||
skip_active = ('activeCurrenciesQuota' in skipped_properties)
|
||||
skip_major_currency_check = ('activeMajorCurrencies' in skipped_properties)
|
||||
# loop
|
||||
for i in range(0, currencies_length):
|
||||
currency = values[i]
|
||||
test_currency(exchange, skipped_properties, method, currency)
|
||||
# detailed check for deposit/withdraw
|
||||
active = exchange.safe_bool(currency, 'active')
|
||||
if active is False:
|
||||
num_inactive_currencies = num_inactive_currencies + 1
|
||||
# ensure that major currencies are active and enabled for deposit and withdrawal
|
||||
code = exchange.safe_string(currency, 'code', None)
|
||||
withdraw = exchange.safe_bool(currency, 'withdraw')
|
||||
deposit = exchange.safe_bool(currency, 'deposit')
|
||||
if exchange.in_array(code, required_active_currencies):
|
||||
assert skip_major_currency_check or (withdraw and deposit), 'Major currency ' + code + ' should have withdraw and deposit flags enabled'
|
||||
# check at least X% of currencies are active
|
||||
inactive_currencies_percentage = (num_inactive_currencies / currencies_length) * 100
|
||||
assert skip_active or (inactive_currencies_percentage < max_inactive_currencies_percentage), 'Percentage of inactive currencies is too high at ' + str(inactive_currencies_percentage) + '% that is more than the allowed maximum of ' + str(max_inactive_currencies_percentage) + '%'
|
||||
detect_currency_conflicts(exchange, currencies)
|
||||
return True
|
||||
|
||||
|
||||
def detect_currency_conflicts(exchange, currency_values):
|
||||
# detect if there are currencies with different ids for the same code
|
||||
ids = {}
|
||||
keys = list(currency_values.keys())
|
||||
for i in range(0, len(keys)):
|
||||
key = keys[i]
|
||||
currency = currency_values[key]
|
||||
code = currency['code']
|
||||
if not (code in ids):
|
||||
ids[code] = currency['id']
|
||||
else:
|
||||
is_different = ids[code] != currency['id']
|
||||
assert not is_different, exchange.id + ' fetchCurrencies() has different ids for the same code: ' + code + ' ' + ids[code] + ' ' + currency['id']
|
||||
return True
|
||||
26
ccxt/test/exchange/sync/test_fetch_deposit_withdrawals.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_deposit_withdrawals.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_deposit_withdrawal # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_deposit_withdrawals(exchange, skipped_properties, code):
|
||||
method = 'fetchTransactions'
|
||||
transactions = exchange.fetch_transactions(code)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, transactions, code)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(transactions)):
|
||||
test_deposit_withdrawal(exchange, skipped_properties, method, transactions[i], code, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, transactions)
|
||||
return True
|
||||
26
ccxt/test/exchange/sync/test_fetch_deposits.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_deposits.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_deposit_withdrawal # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_deposits(exchange, skipped_properties, code):
|
||||
method = 'fetchDeposits'
|
||||
transactions = exchange.fetch_deposits(code)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, transactions, code)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(transactions)):
|
||||
test_deposit_withdrawal(exchange, skipped_properties, method, transactions[i], code, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, transactions)
|
||||
return True
|
||||
25
ccxt/test/exchange/sync/test_fetch_funding_rate_history.py
Normal file
25
ccxt/test/exchange/sync/test_fetch_funding_rate_history.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_funding_rate_history # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_funding_rate_history(exchange, skipped_properties, symbol):
|
||||
method = 'fetchFundingRateHistory'
|
||||
funding_rates_history = exchange.fetch_funding_rate_history(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, funding_rates_history, symbol)
|
||||
for i in range(0, len(funding_rates_history)):
|
||||
test_funding_rate_history(exchange, skipped_properties, method, funding_rates_history[i], symbol)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, funding_rates_history)
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_l2_order_book.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_l2_order_book.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order_book # noqa E402
|
||||
|
||||
def test_fetch_l2_order_book(exchange, skipped_properties, symbol):
|
||||
method = 'fetchL2OrderBook'
|
||||
order_book = exchange.fetch_l2_order_book(symbol)
|
||||
test_order_book(exchange, skipped_properties, method, order_book, symbol)
|
||||
return True
|
||||
37
ccxt/test/exchange/sync/test_fetch_last_prices.py
Normal file
37
ccxt/test/exchange/sync/test_fetch_last_prices.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_last_price # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_last_prices(exchange, skipped_properties, symbol):
|
||||
method = 'fetchLastprices'
|
||||
# log ('fetching all tickers at once...')
|
||||
response = None
|
||||
checked_symbol = None
|
||||
try:
|
||||
response = exchange.fetch_last_prices()
|
||||
except Exception as e:
|
||||
response = exchange.fetch_last_prices([symbol])
|
||||
checked_symbol = symbol
|
||||
assert isinstance(response, dict), exchange.id + ' ' + method + ' ' + checked_symbol + ' must return an object. ' + exchange.json(response)
|
||||
values = list(response.values())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, values, checked_symbol)
|
||||
at_least_one_passed = False
|
||||
for i in range(0, len(values)):
|
||||
# todo: symbol check here
|
||||
test_last_price(exchange, skipped_properties, method, values[i], checked_symbol)
|
||||
at_least_one_passed = at_least_one_passed or (exchange.safe_number(values[i], 'price') > 0)
|
||||
assert at_least_one_passed, exchange.id + ' ' + method + ' ' + checked_symbol + ' at least one symbol should pass the test'
|
||||
return True
|
||||
26
ccxt/test/exchange/sync/test_fetch_ledger.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_ledger.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_ledger_entry # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_ledger(exchange, skipped_properties, code):
|
||||
method = 'fetchLedger'
|
||||
items = exchange.fetch_ledger(code)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, items, code)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(items)):
|
||||
test_ledger_entry(exchange, skipped_properties, method, items[i], code, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, items)
|
||||
return True
|
||||
29
ccxt/test/exchange/sync/test_fetch_ledger_entry.py
Normal file
29
ccxt/test/exchange/sync/test_fetch_ledger_entry.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_ledger_entry # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_ledger_entry(exchange, skipped_properties, code):
|
||||
method = 'fetchLedgerEntry'
|
||||
items = exchange.fetch_ledger(code)
|
||||
length = len(items)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, items, code)
|
||||
if length > 0:
|
||||
first_item = items[0]
|
||||
id = first_item['id']
|
||||
item = exchange.fetch_ledger_entry(id)
|
||||
now = exchange.milliseconds()
|
||||
test_ledger_entry(exchange, skipped_properties, method, item, code, now)
|
||||
return True
|
||||
34
ccxt/test/exchange/sync/test_fetch_leverage_tiers.py
Normal file
34
ccxt/test/exchange/sync/test_fetch_leverage_tiers.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_leverage_tier # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_leverage_tiers(exchange, skipped_properties, symbol):
|
||||
method = 'fetchLeverageTiers'
|
||||
tiers = exchange.fetch_leverage_tiers(['symbol'])
|
||||
# const format = {
|
||||
# 'RAY/USDT': [
|
||||
# {},
|
||||
# ],
|
||||
# };
|
||||
assert isinstance(tiers, dict), exchange.id + ' ' + method + ' ' + symbol + ' must return an object. ' + exchange.json(tiers)
|
||||
tier_keys = list(tiers.keys())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, tier_keys, symbol)
|
||||
for i in range(0, len(tier_keys)):
|
||||
tiers_for_symbol = tiers[tier_keys[i]]
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, tiers_for_symbol, symbol)
|
||||
for j in range(0, len(tiers_for_symbol)):
|
||||
test_leverage_tier(exchange, skipped_properties, method, tiers_for_symbol[j])
|
||||
return True
|
||||
28
ccxt/test/exchange/sync/test_fetch_liquidations.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_liquidations.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
from ccxt.test.exchange.base import test_liquidation # noqa E402
|
||||
|
||||
def test_fetch_liquidations(exchange, skipped_properties, code):
|
||||
method = 'fetchLiquidations'
|
||||
if not exchange.has['fetchLiquidations']:
|
||||
return True
|
||||
items = exchange.fetch_liquidations(code)
|
||||
assert isinstance(items, list), exchange.id + ' ' + method + ' ' + code + ' must return an array. ' + exchange.json(items)
|
||||
# const now = exchange.milliseconds ();
|
||||
for i in range(0, len(items)):
|
||||
test_liquidation(exchange, skipped_properties, method, items[i], code)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, items)
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_margin_mode.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_margin_mode.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_margin_mode # noqa E402
|
||||
|
||||
def test_fetch_margin_mode(exchange, skipped_properties, symbol):
|
||||
method = 'fetchMarginMode'
|
||||
margin_mode = exchange.fetch_margin_mode(symbol)
|
||||
test_margin_mode(exchange, skipped_properties, method, margin_mode)
|
||||
return True
|
||||
28
ccxt/test/exchange/sync/test_fetch_margin_modes.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_margin_modes.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_margin_mode # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_margin_modes(exchange, skipped_properties, symbol):
|
||||
method = 'fetchMarginModes'
|
||||
margin_modes = exchange.fetch_margin_modes(['symbol'])
|
||||
assert isinstance(margin_modes, dict), exchange.id + ' ' + method + ' ' + symbol + ' must return an object. ' + exchange.json(margin_modes)
|
||||
margin_mode_keys = list(margin_modes.keys())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, margin_modes, symbol)
|
||||
for i in range(0, len(margin_mode_keys)):
|
||||
margin_mode = margin_modes[margin_mode_keys[i]]
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, margin_mode, symbol)
|
||||
test_margin_mode(exchange, skipped_properties, method, margin_mode)
|
||||
return True
|
||||
24
ccxt/test/exchange/sync/test_fetch_market_leverage_tiers.py
Normal file
24
ccxt/test/exchange/sync/test_fetch_market_leverage_tiers.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_leverage_tier # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_market_leverage_tiers(exchange, skipped_properties, symbol):
|
||||
method = 'fetchMarketLeverageTiers'
|
||||
tiers = exchange.fetch_market_leverage_tiers(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, tiers, symbol)
|
||||
for j in range(0, len(tiers)):
|
||||
test_leverage_tier(exchange, skipped_properties, method, tiers[j])
|
||||
return True
|
||||
41
ccxt/test/exchange/sync/test_fetch_markets.py
Normal file
41
ccxt/test/exchange/sync/test_fetch_markets.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_market # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_markets(exchange, skipped_properties):
|
||||
method = 'fetchMarkets'
|
||||
markets = exchange.fetch_markets()
|
||||
assert isinstance(markets, dict), exchange.id + ' ' + method + ' must return an object. ' + exchange.json(markets)
|
||||
market_values = list(markets.values())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, market_values)
|
||||
for i in range(0, len(market_values)):
|
||||
test_market(exchange, skipped_properties, method, market_values[i])
|
||||
detect_market_conflicts(exchange, markets)
|
||||
return True
|
||||
|
||||
|
||||
def detect_market_conflicts(exchange, market_values):
|
||||
# detect if there are markets with different ids for the same symbol
|
||||
ids = {}
|
||||
for i in range(0, len(market_values)):
|
||||
market = market_values[i]
|
||||
symbol = market['symbol']
|
||||
if not (symbol in ids):
|
||||
ids[symbol] = market['id']
|
||||
else:
|
||||
is_different = ids[symbol] != market['id']
|
||||
assert not is_different, exchange.id + ' fetchMarkets() has different ids for the same symbol: ' + symbol + ' ' + ids[symbol] + ' ' + market['id']
|
||||
return True
|
||||
28
ccxt/test/exchange/sync/test_fetch_my_liquidations.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_my_liquidations.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
from ccxt.test.exchange.base import test_liquidation # noqa E402
|
||||
|
||||
def test_fetch_my_liquidations(exchange, skipped_properties, code):
|
||||
method = 'fetchMyLiquidations'
|
||||
if not exchange.has['fetchMyLiquidations']:
|
||||
return True
|
||||
items = exchange.fetch_my_liquidations(code)
|
||||
assert isinstance(items, list), exchange.id + ' ' + method + ' ' + code + ' must return an array. ' + exchange.json(items)
|
||||
# const now = exchange.milliseconds ();
|
||||
for i in range(0, len(items)):
|
||||
test_liquidation(exchange, skipped_properties, method, items[i], code)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, items)
|
||||
return True
|
||||
26
ccxt/test/exchange/sync/test_fetch_my_trades.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_my_trades.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
from ccxt.test.exchange.base import test_trade # noqa E402
|
||||
|
||||
def test_fetch_my_trades(exchange, skipped_properties, symbol):
|
||||
method = 'fetchMyTrades'
|
||||
trades = exchange.fetch_my_trades(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, trades, symbol)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(trades)):
|
||||
test_trade(exchange, skipped_properties, method, trades[i], symbol, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, trades)
|
||||
return True
|
||||
35
ccxt/test/exchange/sync/test_fetch_ohlcv.py
Normal file
35
ccxt/test/exchange/sync/test_fetch_ohlcv.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_ohlcv # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_ohlcv(exchange, skipped_properties, symbol):
|
||||
method = 'fetchOHLCV'
|
||||
timeframe_keys = list(exchange.timeframes.keys())
|
||||
assert len(timeframe_keys), exchange.id + ' ' + method + ' - no timeframes found'
|
||||
# prefer 1m timeframe if available, otherwise return the first one
|
||||
chosen_timeframe_key = '1m'
|
||||
if not exchange.in_array(chosen_timeframe_key, timeframe_keys):
|
||||
chosen_timeframe_key = timeframe_keys[0]
|
||||
limit = 10
|
||||
duration = exchange.parse_timeframe(chosen_timeframe_key)
|
||||
since = exchange.milliseconds() - duration * limit * 1000 - 1000
|
||||
ohlcvs = exchange.fetch_ohlcv(symbol, chosen_timeframe_key, since, limit)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, ohlcvs, symbol)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(ohlcvs)):
|
||||
test_ohlcv(exchange, skipped_properties, method, ohlcvs[i], symbol, now)
|
||||
# todo: sorted timestamps check
|
||||
return True
|
||||
24
ccxt/test/exchange/sync/test_fetch_open_interest_history.py
Normal file
24
ccxt/test/exchange/sync/test_fetch_open_interest_history.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_open_interest # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_open_interest_history(exchange, skipped_properties, symbol):
|
||||
method = 'fetchOpenInterestHistory'
|
||||
open_interest_history = exchange.fetch_open_interest_history(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, open_interest_history, symbol)
|
||||
for i in range(0, len(open_interest_history)):
|
||||
test_open_interest(exchange, skipped_properties, method, open_interest_history[i])
|
||||
return True
|
||||
28
ccxt/test/exchange/sync/test_fetch_open_orders.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_open_orders.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_open_orders(exchange, skipped_properties, symbol):
|
||||
method = 'fetchOpenOrders'
|
||||
orders = exchange.fetch_open_orders(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, orders, symbol)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(orders)):
|
||||
order = orders[i]
|
||||
test_order(exchange, skipped_properties, method, order, symbol, now)
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, method, order, 'status', ['open'])
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, orders)
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_order_book.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_order_book.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order_book # noqa E402
|
||||
|
||||
def test_fetch_order_book(exchange, skipped_properties, symbol):
|
||||
method = 'fetchOrderBook'
|
||||
orderbook = exchange.fetch_order_book(symbol)
|
||||
test_order_book(exchange, skipped_properties, method, orderbook, symbol)
|
||||
return True
|
||||
27
ccxt/test/exchange/sync/test_fetch_order_books.py
Normal file
27
ccxt/test/exchange/sync/test_fetch_order_books.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order_book # noqa E402
|
||||
|
||||
def test_fetch_order_books(exchange, skipped_properties):
|
||||
method = 'fetchOrderBooks'
|
||||
symbol = exchange.symbols[0]
|
||||
order_books = exchange.fetch_order_books([symbol])
|
||||
assert isinstance(order_books, dict), exchange.id + ' ' + method + ' must return an object. ' + exchange.json(order_books)
|
||||
order_book_keys = list(order_books.keys())
|
||||
assert len(order_book_keys), exchange.id + ' ' + method + ' returned 0 length data'
|
||||
for i in range(0, len(order_book_keys)):
|
||||
symbol_inner = order_book_keys[i]
|
||||
test_order_book(exchange, skipped_properties, method, order_books[symbol_inner], symbol_inner)
|
||||
return True
|
||||
27
ccxt/test/exchange/sync/test_fetch_orders.py
Normal file
27
ccxt/test/exchange/sync/test_fetch_orders.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_order # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_orders(exchange, skipped_properties, symbol):
|
||||
method = 'fetchOrders'
|
||||
orders = exchange.fetch_orders(symbol)
|
||||
assert isinstance(orders, list), exchange.id + ' ' + method + ' must return an array, returned ' + exchange.json(orders)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, orders, symbol)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(orders)):
|
||||
test_order(exchange, skipped_properties, method, orders[i], symbol, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, orders)
|
||||
return True
|
||||
35
ccxt/test/exchange/sync/test_fetch_positions.py
Normal file
35
ccxt/test/exchange/sync/test_fetch_positions.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_position # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_positions(exchange, skipped_properties, symbol):
|
||||
method = 'fetchPositions'
|
||||
now = exchange.milliseconds()
|
||||
# without symbol
|
||||
positions = exchange.fetch_positions()
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, positions, symbol)
|
||||
for i in range(0, len(positions)):
|
||||
test_position(exchange, skipped_properties, method, positions[i], None, now)
|
||||
# testSharedMethods.assertTimestampOrder (exchange, method, undefined, positions); # currently order of positions does not make sense
|
||||
# with symbol
|
||||
positions_for_symbol = exchange.fetch_positions([symbol])
|
||||
assert isinstance(positions_for_symbol, list), exchange.id + ' ' + method + ' must return an array, returned ' + exchange.json(positions_for_symbol)
|
||||
positions_for_symbol_length = len(positions_for_symbol)
|
||||
assert positions_for_symbol_length <= 4, exchange.id + ' ' + method + ' positions length for particular symbol should be less than 4, returned ' + exchange.json(positions_for_symbol)
|
||||
for i in range(0, len(positions_for_symbol)):
|
||||
test_position(exchange, skipped_properties, method, positions_for_symbol[i], symbol, now)
|
||||
# testSharedMethods.assertTimestampOrder (exchange, method, symbol, positionsForSymbol);
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_status.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_status.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_status # noqa E402
|
||||
|
||||
def test_fetch_status(exchange, skipped_properties):
|
||||
method = 'fetchStatus'
|
||||
status = exchange.fetch_status()
|
||||
test_status(exchange, skipped_properties, method, status, exchange.milliseconds())
|
||||
return True
|
||||
21
ccxt/test/exchange/sync/test_fetch_ticker.py
Normal file
21
ccxt/test/exchange/sync/test_fetch_ticker.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_ticker # noqa E402
|
||||
|
||||
def test_fetch_ticker(exchange, skipped_properties, symbol):
|
||||
method = 'fetchTicker'
|
||||
ticker = exchange.fetch_ticker(symbol)
|
||||
test_ticker(exchange, skipped_properties, method, ticker, symbol)
|
||||
return True
|
||||
58
ccxt/test/exchange/sync/test_fetch_tickers.py
Normal file
58
ccxt/test/exchange/sync/test_fetch_tickers.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_ticker # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_tickers(exchange, skipped_properties, symbol):
|
||||
without_symbol = test_fetch_tickers_helper(exchange, skipped_properties, None)
|
||||
with_symbol = test_fetch_tickers_helper(exchange, skipped_properties, [symbol])
|
||||
results = asyncio.gather(*[without_symbol, with_symbol])
|
||||
test_fetch_tickers_amounts(exchange, skipped_properties, results[0])
|
||||
return results
|
||||
|
||||
|
||||
def test_fetch_tickers_helper(exchange, skipped_properties, arg_symbols, arg_params={}):
|
||||
method = 'fetchTickers'
|
||||
response = exchange.fetch_tickers(arg_symbols, arg_params)
|
||||
assert isinstance(response, dict), exchange.id + ' ' + method + ' ' + exchange.json(arg_symbols) + ' must return an object. ' + exchange.json(response)
|
||||
values = list(response.values())
|
||||
checked_symbol = None
|
||||
if arg_symbols is not None and len(arg_symbols) == 1:
|
||||
checked_symbol = arg_symbols[0]
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, values, checked_symbol)
|
||||
for i in range(0, len(values)):
|
||||
# todo: symbol check here
|
||||
ticker = values[i]
|
||||
test_ticker(exchange, skipped_properties, method, ticker, checked_symbol)
|
||||
return response
|
||||
|
||||
|
||||
def test_fetch_tickers_amounts(exchange, skipped_properties, tickers):
|
||||
tickers_values = list(tickers.values())
|
||||
if not ('checkActiveSymbols' in skipped_properties):
|
||||
#
|
||||
# ensure all "active" symbols have tickers
|
||||
#
|
||||
non_inactive_markets = test_shared_methods.get_active_markets(exchange)
|
||||
not_inactive_symbols_length = len(non_inactive_markets)
|
||||
obtained_tickers_length = len(tickers_values)
|
||||
min_ratio = 0.99 # 1.0 - 0.01 = 0.99, hardcoded to avoid C# transpiler type casting issues
|
||||
assert obtained_tickers_length >= not_inactive_symbols_length * min_ratio, exchange.id + ' ' + 'fetchTickers' + ' must return tickers for all active markets. but returned: ' + str(obtained_tickers_length) + ' tickers, ' + str(not_inactive_symbols_length) + ' active markets'
|
||||
#
|
||||
# ensure tickers length is less than markets length
|
||||
#
|
||||
all_markets = exchange.markets
|
||||
all_markets_length = len(list(all_markets.keys()))
|
||||
assert obtained_tickers_length <= all_markets_length, exchange.id + ' ' + 'fetchTickers' + ' must return <= than all markets, but returned: ' + str(obtained_tickers_length) + ' tickers, ' + str(all_markets_length) + ' markets'
|
||||
28
ccxt/test/exchange/sync/test_fetch_trades.py
Normal file
28
ccxt/test/exchange/sync/test_fetch_trades.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
from ccxt.test.exchange.base import test_trade # noqa E402
|
||||
|
||||
def test_fetch_trades(exchange, skipped_properties, symbol):
|
||||
method = 'fetchTrades'
|
||||
trades = exchange.fetch_trades(symbol)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, trades)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(trades)):
|
||||
test_trade(exchange, skipped_properties, method, trades[i], symbol, now)
|
||||
test_shared_methods.assert_in_array(exchange, skipped_properties, method, trades[i], 'takerOrMaker', ['taker', None])
|
||||
if not ('timestampSort' in skipped_properties):
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, symbol, trades)
|
||||
return True
|
||||
22
ccxt/test/exchange/sync/test_fetch_trading_fee.py
Normal file
22
ccxt/test/exchange/sync/test_fetch_trading_fee.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_trading_fee # noqa E402
|
||||
|
||||
def test_fetch_trading_fee(exchange, skipped_properties, symbol):
|
||||
method = 'fetchTradingFee'
|
||||
fee = exchange.fetch_trading_fee(symbol)
|
||||
assert isinstance(fee, dict), exchange.id + ' ' + method + ' ' + symbol + ' must return an object. ' + exchange.json(fee)
|
||||
test_trading_fee(exchange, skipped_properties, method, symbol, fee)
|
||||
return True
|
||||
26
ccxt/test/exchange/sync/test_fetch_trading_fees.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_trading_fees.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_trading_fee # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_trading_fees(exchange, skipped_properties):
|
||||
method = 'fetchTradingFees'
|
||||
fees = exchange.fetch_trading_fees()
|
||||
symbols = list(fees.keys())
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, symbols)
|
||||
for i in range(0, len(symbols)):
|
||||
symbol = symbols[i]
|
||||
test_trading_fee(exchange, skipped_properties, method, symbol, fees[symbol])
|
||||
return True
|
||||
22
ccxt/test/exchange/sync/test_fetch_transaction_fees.py
Normal file
22
ccxt/test/exchange/sync/test_fetch_transaction_fees.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
||||
def test_fetch_transaction_fees(exchange, skipped_properties):
|
||||
# const method = 'fetchTransactionFees';
|
||||
# const fees = await exchange.fetchTransactionFees ();
|
||||
# const withdrawKeys = Object.keys (fees['withdraw']);
|
||||
# todo : assert each entry
|
||||
return None
|
||||
26
ccxt/test/exchange/sync/test_fetch_withdrawals.py
Normal file
26
ccxt/test/exchange/sync/test_fetch_withdrawals.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_deposit_withdrawal # noqa E402
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_fetch_withdrawals(exchange, skipped_properties, code):
|
||||
method = 'fetchWithdrawals'
|
||||
transactions = exchange.fetch_withdrawals(code)
|
||||
test_shared_methods.assert_non_emtpy_array(exchange, skipped_properties, method, transactions, code)
|
||||
now = exchange.milliseconds()
|
||||
for i in range(0, len(transactions)):
|
||||
test_deposit_withdrawal(exchange, skipped_properties, method, transactions[i], code, now)
|
||||
test_shared_methods.assert_timestamp_order(exchange, method, code, transactions)
|
||||
return True
|
||||
31
ccxt/test/exchange/sync/test_load_markets.py
Normal file
31
ccxt/test/exchange/sync/test_load_markets.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_market # noqa E402
|
||||
|
||||
def test_load_markets(exchange, skipped_properties):
|
||||
method = 'loadMarkets'
|
||||
markets = exchange.load_markets()
|
||||
assert isinstance(exchange.markets, dict), '.markets is not an object'
|
||||
assert isinstance(exchange.symbols, list), '.symbols is not an array'
|
||||
symbols_length = len(exchange.symbols)
|
||||
market_keys = list(exchange.markets.keys())
|
||||
market_keys_length = len(market_keys)
|
||||
assert symbols_length > 0, '.symbols count <= 0 (less than or equal to zero)'
|
||||
assert market_keys_length > 0, '.markets objects keys length <= 0 (less than or equal to zero)'
|
||||
assert symbols_length == market_keys_length, 'number of .symbols is not equal to the number of .markets'
|
||||
market_values = list(markets.values())
|
||||
for i in range(0, len(market_values)):
|
||||
test_market(exchange, skipped_properties, method, market_values[i])
|
||||
return True
|
||||
73
ccxt/test/exchange/sync/test_proxies.py
Normal file
73
ccxt/test/exchange/sync/test_proxies.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ccxt.test.exchange.base import test_shared_methods # noqa E402
|
||||
|
||||
def test_proxies(exchange, skipped_properties):
|
||||
test_proxy_url(exchange, skipped_properties)
|
||||
test_http_proxy(exchange, skipped_properties)
|
||||
# 'httpsProxy', 'socksProxy'
|
||||
test_proxy_for_exceptions(exchange, skipped_properties)
|
||||
|
||||
|
||||
def test_proxy_url(exchange, skipped_properties):
|
||||
method = 'proxyUrl'
|
||||
proxy_server_ip = '5.75.153.75'
|
||||
[proxy_url, http_proxy, https_proxy, socks_proxy] = test_shared_methods.remove_proxy_options(exchange, skipped_properties)
|
||||
exchange.proxy_url = 'http://' + proxy_server_ip + ':8090/proxy_url.php?caller=https://ccxt.com&url='
|
||||
encoded_colon = '%3A'
|
||||
encoded_slash = '%2F'
|
||||
ip_check_url = 'https' + encoded_colon + encoded_slash + encoded_slash + 'api.ipify.org'
|
||||
response = exchange.fetch(ip_check_url)
|
||||
assert response == proxy_server_ip, exchange.id + ' ' + method + ' test failed. Returned response is ' + response + ' while it should be "' + proxy_server_ip + '"'
|
||||
# reset the instance property
|
||||
test_shared_methods.set_proxy_options(exchange, skipped_properties, proxy_url, http_proxy, https_proxy, socks_proxy)
|
||||
return True
|
||||
|
||||
|
||||
def test_http_proxy(exchange, skipped_properties):
|
||||
method = 'httpProxy'
|
||||
proxy_server_ip = '5.75.153.75'
|
||||
[proxy_url, http_proxy, https_proxy, socks_proxy] = test_shared_methods.remove_proxy_options(exchange, skipped_properties)
|
||||
exchange.http_proxy = 'http://' + proxy_server_ip + ':8911'
|
||||
ip_check_url = 'https://api.ipify.org/'
|
||||
response = exchange.fetch(ip_check_url)
|
||||
assert response == proxy_server_ip, exchange.id + ' ' + method + ' test failed. Returned response is ' + response + ' while it should be "' + proxy_server_ip + '"'
|
||||
# reset the instance property
|
||||
test_shared_methods.set_proxy_options(exchange, skipped_properties, proxy_url, http_proxy, https_proxy, socks_proxy)
|
||||
|
||||
|
||||
# with the below method we test out all variations of possible proxy options, so at least 2 of them should be set together, and such cases must throw exception
|
||||
def test_proxy_for_exceptions(exchange, skipped_properties):
|
||||
method = 'testProxyForExceptions'
|
||||
[proxy_url, http_proxy, https_proxy, socks_proxy] = test_shared_methods.remove_proxy_options(exchange, skipped_properties)
|
||||
possible_options_array = ['proxyUrl', 'proxyUrlCallback', 'proxy_url', 'proxy_url_callback', 'httpProxy', 'httpProxyCallback', 'http_proxy', 'http_proxy_callback', 'httpsProxy', 'httpsProxyCallback', 'https_proxy', 'https_proxy_callback', 'socksProxy', 'socksProxyCallback', 'socks_proxy', 'socks_proxy_callback']
|
||||
for i in range(0, len(possible_options_array)):
|
||||
for j in range(0, len(possible_options_array)):
|
||||
if j != i:
|
||||
proxy_first = possible_options_array[i]
|
||||
proxy_second = possible_options_array[j]
|
||||
exchange.set_property(exchange, proxy_first, '0.0.0.0') # actual value does not matter
|
||||
exchange.set_property(exchange, proxy_second, '0.0.0.0') # actual value does not matter
|
||||
exception_caught = False
|
||||
try:
|
||||
exchange.fetch('http://example.com') # url does not matter, it will not be called
|
||||
except Exception as e:
|
||||
exception_caught = True
|
||||
assert exception_caught, exchange.id + ' ' + method + ' test failed. No exception was thrown, while ' + proxy_first + ' and ' + proxy_second + ' were set together'
|
||||
# reset to undefined
|
||||
exchange.set_property(exchange, proxy_first, None)
|
||||
exchange.set_property(exchange, proxy_second, None)
|
||||
# reset the instance property
|
||||
test_shared_methods.set_proxy_options(exchange, skipped_properties, proxy_url, http_proxy, https_proxy, socks_proxy)
|
||||
21
ccxt/test/exchange/sync/test_sign_in.py
Normal file
21
ccxt/test/exchange/sync/test_sign_in.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
sys.path.append(root)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
|
||||
def test_sign_in(exchange, skipped_properties):
|
||||
method = 'signIn'
|
||||
if exchange.has[method]:
|
||||
exchange.sign_in()
|
||||
return True
|
||||
Reference in New Issue
Block a user