Merge pull request #1550 from hroff-1902/patch-2

execute_buy, handle_trade: do not use ticker if use_order_book:true is set in config
This commit is contained in:
Matthias 2019-02-16 13:55:33 +01:00 committed by GitHub
commit e0c420b93f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 52 deletions

View File

@ -204,19 +204,11 @@ class FreqtradeBot(object):
self.state = State.STOPPED self.state = State.STOPPED
return state_changed return state_changed
def get_target_bid(self, pair: str, ticker: Dict[str, float]) -> float: def get_target_bid(self, pair: str) -> float:
""" """
Calculates bid target between current ask price and last price Calculates bid target between current ask price and last price
:param ticker: Ticker to use for getting Ask and Last Price
:return: float: Price :return: float: Price
""" """
if ticker['ask'] < ticker['last']:
ticker_rate = ticker['ask']
else:
balance = self.config['bid_strategy']['ask_last_balance']
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
used_rate = ticker_rate
config_bid_strategy = self.config.get('bid_strategy', {}) config_bid_strategy = self.config.get('bid_strategy', {})
if 'use_order_book' in config_bid_strategy and\ if 'use_order_book' in config_bid_strategy and\
config_bid_strategy.get('use_order_book', False): config_bid_strategy.get('use_order_book', False):
@ -226,15 +218,16 @@ class FreqtradeBot(object):
logger.debug('order_book %s', order_book) logger.debug('order_book %s', order_book)
# top 1 = index 0 # top 1 = index 0
order_book_rate = order_book['bids'][order_book_top - 1][0] order_book_rate = order_book['bids'][order_book_top - 1][0]
# if ticker has lower rate, then use ticker ( usefull if down trending )
logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate) logger.info('...top %s order book buy rate %0.8f', order_book_top, order_book_rate)
if ticker_rate < order_book_rate: used_rate = order_book_rate
logger.info('...using ticker rate instead %0.8f', ticker_rate)
used_rate = ticker_rate
else:
used_rate = order_book_rate
else: else:
logger.info('Using Last Ask / Last Price') logger.info('Using Last Ask / Last Price')
ticker = self.exchange.get_ticker(pair)
if ticker['ask'] < ticker['last']:
ticker_rate = ticker['ask']
else:
balance = self.config['bid_strategy']['ask_last_balance']
ticker_rate = ticker['ask'] + balance * (ticker['last'] - ticker['ask'])
used_rate = ticker_rate used_rate = ticker_rate
return used_rate return used_rate
@ -380,7 +373,7 @@ class FreqtradeBot(object):
buy_limit_requested = price buy_limit_requested = price
else: else:
# Calculate amount # Calculate amount
buy_limit_requested = self.get_target_bid(pair, self.exchange.get_ticker(pair)) buy_limit_requested = self.get_target_bid(pair)
min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit_requested) min_stake_amount = self._get_min_pair_stake_amount(pair_s, buy_limit_requested)
if min_stake_amount is not None and min_stake_amount > stake_amount: if min_stake_amount is not None and min_stake_amount > stake_amount:
@ -580,7 +573,6 @@ class FreqtradeBot(object):
raise ValueError(f'Attempt to handle closed trade: {trade}') raise ValueError(f'Attempt to handle closed trade: {trade}')
logger.debug('Handling %s ...', trade) logger.debug('Handling %s ...', trade)
sell_rate = self.exchange.get_ticker(trade.pair)['bid']
(buy, sell) = (False, False) (buy, sell) = (False, False)
experimental = self.config.get('experimental', {}) experimental = self.config.get('experimental', {})
@ -600,18 +592,15 @@ class FreqtradeBot(object):
for i in range(order_book_min, order_book_max + 1): for i in range(order_book_min, order_book_max + 1):
order_book_rate = order_book['asks'][i - 1][0] order_book_rate = order_book['asks'][i - 1][0]
# if orderbook has higher rate (high profit),
# use orderbook, otherwise just use bids rate
logger.info(' order book asks top %s: %0.8f', i, order_book_rate) logger.info(' order book asks top %s: %0.8f', i, order_book_rate)
if sell_rate < order_book_rate: sell_rate = order_book_rate
sell_rate = order_book_rate
if self.check_sell(trade, sell_rate, buy, sell): if self.check_sell(trade, sell_rate, buy, sell):
return True return True
else: else:
logger.debug('checking sell') logger.debug('checking sell')
sell_rate = self.exchange.get_ticker(trade.pair)['bid']
if self.check_sell(trade, sell_rate, buy, sell): if self.check_sell(trade, sell_rate, buy, sell):
return True return True

View File

@ -841,22 +841,27 @@ def test_process_informative_pairs_added(default_conf, ticker, markets, mocker)
def test_balance_fully_ask_side(mocker, default_conf) -> None: def test_balance_fully_ask_side(mocker, default_conf) -> None:
default_conf['bid_strategy']['ask_last_balance'] = 0.0 default_conf['bid_strategy']['ask_last_balance'] = 0.0
freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
MagicMock(return_value={'ask': 20, 'last': 10}))
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 20, 'last': 10}) == 20 assert freqtrade.get_target_bid('ETH/BTC') == 20
def test_balance_fully_last_side(mocker, default_conf) -> None: def test_balance_fully_last_side(mocker, default_conf) -> None:
default_conf['bid_strategy']['ask_last_balance'] = 1.0 default_conf['bid_strategy']['ask_last_balance'] = 1.0
freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
MagicMock(return_value={'ask': 20, 'last': 10}))
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 20, 'last': 10}) == 10 assert freqtrade.get_target_bid('ETH/BTC') == 10
def test_balance_bigger_last_ask(mocker, default_conf) -> None: def test_balance_bigger_last_ask(mocker, default_conf) -> None:
default_conf['bid_strategy']['ask_last_balance'] = 1.0 default_conf['bid_strategy']['ask_last_balance'] = 1.0
freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 5, 'last': 10}) == 5 MagicMock(return_value={'ask': 5, 'last': 10}))
assert freqtrade.get_target_bid('ETH/BTC') == 5
def test_execute_buy(mocker, default_conf, fee, markets, limit_buy_order) -> None: def test_execute_buy(mocker, default_conf, fee, markets, limit_buy_order) -> None:
@ -2813,10 +2818,13 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2, markets)
instead of the ask rate instead of the ask rate
""" """
patch_exchange(mocker) patch_exchange(mocker)
ticker_mock = MagicMock(return_value={'ask': 0.045, 'last': 0.046})
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
get_markets=markets, get_markets=markets,
get_order_book=order_book_l2 get_order_book=order_book_l2,
get_ticker=ticker_mock,
) )
default_conf['exchange']['name'] = 'binance' default_conf['exchange']['name'] = 'binance'
default_conf['bid_strategy']['use_order_book'] = True default_conf['bid_strategy']['use_order_book'] = True
@ -2825,7 +2833,8 @@ def test_order_book_bid_strategy1(mocker, default_conf, order_book_l2, markets)
default_conf['telegram']['enabled'] = False default_conf['telegram']['enabled'] = False
freqtrade = FreqtradeBot(default_conf) freqtrade = FreqtradeBot(default_conf)
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.045, 'last': 0.046}) == 0.043935 assert freqtrade.get_target_bid('ETH/BTC') == 0.043935
assert ticker_mock.call_count == 0
def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2, markets) -> None: def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2, markets) -> None:
@ -2834,10 +2843,13 @@ def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2, markets)
instead of the order book rate (even if enabled) instead of the order book rate (even if enabled)
""" """
patch_exchange(mocker) patch_exchange(mocker)
ticker_mock = MagicMock(return_value={'ask': 0.042, 'last': 0.046})
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
get_markets=markets, get_markets=markets,
get_order_book=order_book_l2 get_order_book=order_book_l2,
get_ticker=ticker_mock,
) )
default_conf['exchange']['name'] = 'binance' default_conf['exchange']['name'] = 'binance'
default_conf['bid_strategy']['use_order_book'] = True default_conf['bid_strategy']['use_order_book'] = True
@ -2846,29 +2858,9 @@ def test_order_book_bid_strategy2(mocker, default_conf, order_book_l2, markets)
default_conf['telegram']['enabled'] = False default_conf['telegram']['enabled'] = False
freqtrade = FreqtradeBot(default_conf) freqtrade = FreqtradeBot(default_conf)
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.042, 'last': 0.046}) == 0.042 # ordrebook shall be used even if tickers would be lower.
assert freqtrade.get_target_bid('ETH/BTC', ) != 0.042
assert ticker_mock.call_count == 0
def test_order_book_bid_strategy3(default_conf, mocker, order_book_l2, markets) -> None:
"""
test if function get_target_bid will return ask rate instead
of the order book rate
"""
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
get_markets=markets,
get_order_book=order_book_l2
)
default_conf['exchange']['name'] = 'binance'
default_conf['bid_strategy']['use_order_book'] = True
default_conf['bid_strategy']['order_book_top'] = 1
default_conf['bid_strategy']['ask_last_balance'] = 0
default_conf['telegram']['enabled'] = False
freqtrade = FreqtradeBot(default_conf)
assert freqtrade.get_target_bid('ETH/BTC', {'ask': 0.03, 'last': 0.029}) == 0.03
def test_check_depth_of_market_buy(default_conf, mocker, order_book_l2, markets) -> None: def test_check_depth_of_market_buy(default_conf, mocker, order_book_l2, markets) -> None: