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'):
|
if self.exchange_has('fetchL2OrderBook'):
|
||||||
ob = self.fetch_l2_order_book(pair, 20)
|
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
|
remaining_amount = amount
|
||||||
filled_amount = 0
|
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_price = book_entry[0]
|
||||||
book_entry_coin_volume = book_entry[1]
|
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 > 0:
|
||||||
if remaining_amount < book_entry_ref_currency_volume:
|
if remaining_amount < book_entry_coin_volume:
|
||||||
filled_amount += remaining_amount * book_entry_price
|
filled_amount += remaining_amount * book_entry_price
|
||||||
else:
|
else:
|
||||||
filled_amount += book_entry_ref_currency_volume * book_entry_price
|
filled_amount += book_entry_coin_volume * book_entry_price
|
||||||
remaining_amount -= book_entry_ref_currency_volume
|
remaining_amount -= book_entry_coin_volume
|
||||||
else:
|
else:
|
||||||
break
|
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
|
forecast_avg_filled_price = filled_amount / amount
|
||||||
return self.price_to_precision(pair, forecast_avg_filled_price)
|
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
|
@pytest.fixture
|
||||||
def ohlcv_history_list():
|
def ohlcv_history_list():
|
||||||
return [
|
return [
|
||||||
|
@ -947,6 +947,70 @@ def test_create_dry_run_order(default_conf, mocker, side, exchange_name):
|
|||||||
assert order["symbol"] == "ETH/BTC"
|
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", [
|
@pytest.mark.parametrize("side", [
|
||||||
("buy"),
|
("buy"),
|
||||||
("sell")
|
("sell")
|
||||||
|
Loading…
Reference in New Issue
Block a user