Add tests for fill methods
This commit is contained in:
parent
1e988c97ad
commit
db03a24109
@ -608,22 +608,24 @@ class Exchange:
|
||||
"""
|
||||
if self.exchange_has('fetchL2OrderBook'):
|
||||
ob = self.fetch_l2_order_book(pair, 20)
|
||||
book_entry_type = 'asks' if side == 'buy' else 'bids'
|
||||
ob_type = 'asks' if side == 'buy' else 'bids'
|
||||
|
||||
remaining_amount = amount
|
||||
filled_amount = 0
|
||||
for book_entry in ob[book_entry_type]:
|
||||
for book_entry in ob[ob_type]:
|
||||
book_entry_price = book_entry[0]
|
||||
book_entry_coin_volume = book_entry[1]
|
||||
book_entry_ref_currency_volume = book_entry_price * book_entry_coin_volume
|
||||
if remaining_amount > 0:
|
||||
if remaining_amount < book_entry_ref_currency_volume:
|
||||
if remaining_amount < book_entry_coin_volume:
|
||||
filled_amount += remaining_amount * book_entry_price
|
||||
else:
|
||||
filled_amount += book_entry_ref_currency_volume * book_entry_price
|
||||
remaining_amount -= book_entry_ref_currency_volume
|
||||
filled_amount += book_entry_coin_volume * book_entry_price
|
||||
remaining_amount -= book_entry_coin_volume
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# If remaining_amount wasn't consumed completely (break was not called)
|
||||
filled_amount += remaining_amount * book_entry_price
|
||||
forecast_avg_filled_price = filled_amount / amount
|
||||
return self.price_to_precision(pair, forecast_avg_filled_price)
|
||||
|
||||
|
@ -1087,6 +1087,40 @@ def order_book_l2():
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def order_book_l2_usd():
|
||||
return MagicMock(return_value={
|
||||
'symbol': 'LTC/USDT',
|
||||
'bids': [
|
||||
[25.563, 49.269],
|
||||
[25.562, 83.0],
|
||||
[25.56, 106.0],
|
||||
[25.559, 15.381],
|
||||
[25.558, 29.299],
|
||||
[25.557, 34.624],
|
||||
[25.556, 10.0],
|
||||
[25.555, 14.684],
|
||||
[25.554, 45.91],
|
||||
[25.553, 50.0]
|
||||
],
|
||||
'asks': [
|
||||
[25.566, 14.27],
|
||||
[25.567, 48.484],
|
||||
[25.568, 92.349],
|
||||
[25.572, 31.48],
|
||||
[25.573, 23.0],
|
||||
[25.574, 20.0],
|
||||
[25.575, 89.606],
|
||||
[25.576, 262.016],
|
||||
[25.577, 178.557],
|
||||
[25.578, 78.614]
|
||||
],
|
||||
'timestamp': None,
|
||||
'datetime': None,
|
||||
'nonce': 2372149736
|
||||
})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ohlcv_history_list():
|
||||
return [
|
||||
|
@ -947,6 +947,70 @@ def test_create_dry_run_order(default_conf, mocker, side, exchange_name):
|
||||
assert order["symbol"] == "ETH/BTC"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side,startprice,endprice", [
|
||||
("buy", 25.563, 25.566),
|
||||
("sell", 25.566, 25.563)
|
||||
])
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_create_dry_run_order_limit_fill(default_conf, mocker, side, startprice, endprice,
|
||||
exchange_name, order_book_l2_usd):
|
||||
default_conf['dry_run'] = True
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
fetch_l2_order_book=order_book_l2_usd,
|
||||
)
|
||||
|
||||
order = exchange.create_dry_run_order(
|
||||
pair='LTC/USDT', ordertype='limit', side=side, amount=1, rate=startprice)
|
||||
assert 'id' in order
|
||||
assert f'dry_run_{side}_' in order["id"]
|
||||
assert order["side"] == side
|
||||
assert order["type"] == "limit"
|
||||
assert order["symbol"] == "LTC/USDT"
|
||||
|
||||
order_closed = exchange.fetch_dry_run_order(order['id'])
|
||||
assert order_book_l2_usd.call_count == 1
|
||||
assert order_closed['status'] == 'open'
|
||||
assert not order['fee']
|
||||
|
||||
order_book_l2_usd.reset_mock()
|
||||
order_closed['price'] = endprice
|
||||
|
||||
order_closed = exchange.fetch_dry_run_order(order['id'])
|
||||
assert order_closed['status'] == 'closed'
|
||||
assert order['fee']
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side,amount,endprice", [
|
||||
("buy", 1, 25.566),
|
||||
("buy", 100, 25.5672), # Requires interpolation
|
||||
("buy", 1000, 25.575), # More than orderbook return
|
||||
("sell", 1, 25.563),
|
||||
("sell", 100, 25.5625), # Requires interpolation
|
||||
("sell", 1000, 25.5555), # More than orderbook return
|
||||
])
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_create_dry_run_order_market_fill(default_conf, mocker, side, amount, endprice,
|
||||
exchange_name, order_book_l2_usd):
|
||||
default_conf['dry_run'] = True
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
fetch_l2_order_book=order_book_l2_usd,
|
||||
)
|
||||
|
||||
order = exchange.create_dry_run_order(
|
||||
pair='LTC/USDT', ordertype='market', side=side, amount=amount, rate=25.5)
|
||||
assert 'id' in order
|
||||
assert f'dry_run_{side}_' in order["id"]
|
||||
assert order["side"] == side
|
||||
assert order["type"] == "market"
|
||||
assert order["symbol"] == "LTC/USDT"
|
||||
assert order['status'] == 'closed'
|
||||
assert round(order["average"], 4) == round(endprice, 4)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side", [
|
||||
("buy"),
|
||||
("sell")
|
||||
|
Loading…
Reference in New Issue
Block a user