Merge pull request #1302 from freqtrade/fix/whitelistprobs

Fix no tickerdata for pair for open trades
This commit is contained in:
Matthias 2018-11-02 16:03:09 +01:00 committed by GitHub
commit efd59ed9ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 12 deletions

View File

@ -54,6 +54,7 @@ class FreqtradeBot(object):
self.rpc: RPCManager = RPCManager(self) self.rpc: RPCManager = RPCManager(self)
self.persistence = None self.persistence = None
self.exchange = Exchange(self.config) self.exchange = Exchange(self.config)
self.active_pair_whitelist: List[str] = self.config['exchange']['pair_whitelist']
self._init_modules() self._init_modules()
def _init_modules(self) -> None: def _init_modules(self) -> None:
@ -107,11 +108,8 @@ class FreqtradeBot(object):
constants.PROCESS_THROTTLE_SECS constants.PROCESS_THROTTLE_SECS
) )
nb_assets = self.config.get('dynamic_whitelist', None)
self._throttle(func=self._process, self._throttle(func=self._process,
min_secs=min_secs, min_secs=min_secs)
nb_assets=nb_assets)
return state return state
def _startup_messages(self) -> None: def _startup_messages(self) -> None:
@ -162,15 +160,15 @@ class FreqtradeBot(object):
time.sleep(duration) time.sleep(duration)
return result return result
def _process(self, nb_assets: Optional[int] = 0) -> bool: def _process(self) -> bool:
""" """
Queries the persistence layer for open trades and handles them, Queries the persistence layer for open trades and handles them,
otherwise a new trade is created. otherwise a new trade is created.
:param: nb_assets: the maximum number of pairs to be traded at the same time
:return: True if one or more trades has been created or closed, False otherwise :return: True if one or more trades has been created or closed, False otherwise
""" """
state_changed = False state_changed = False
try: try:
nb_assets = self.config.get('dynamic_whitelist', None)
# Refresh whitelist based on wallet maintenance # Refresh whitelist based on wallet maintenance
sanitized_list = self._refresh_whitelist( sanitized_list = self._refresh_whitelist(
self._gen_pair_whitelist( self._gen_pair_whitelist(
@ -179,15 +177,19 @@ class FreqtradeBot(object):
) )
# Keep only the subsets of pairs wanted (up to nb_assets) # Keep only the subsets of pairs wanted (up to nb_assets)
final_list = sanitized_list[:nb_assets] if nb_assets else sanitized_list self.active_pair_whitelist = sanitized_list[:nb_assets] if nb_assets else sanitized_list
self.config['exchange']['pair_whitelist'] = final_list
# Refreshing candles
self.exchange.refresh_tickers(final_list, self.strategy.ticker_interval)
# Query trades from persistence layer # Query trades from persistence layer
trades = Trade.query.filter(Trade.is_open.is_(True)).all() trades = Trade.query.filter(Trade.is_open.is_(True)).all()
# Extend active-pair whitelist with pairs from open trades
# ensures that tickers are downloaded for open trades
self.active_pair_whitelist.extend([trade.pair for trade in trades
if trade.pair not in self.active_pair_whitelist])
# Refreshing candles
self.exchange.refresh_tickers(self.active_pair_whitelist, self.strategy.ticker_interval)
# First process current opened trades # First process current opened trades
for trade in trades: for trade in trades:
state_changed |= self.process_maybe_execute_sell(trade) state_changed |= self.process_maybe_execute_sell(trade)
@ -380,7 +382,7 @@ class FreqtradeBot(object):
'Checking buy signals to create a new trade with stake_amount: %f ...', 'Checking buy signals to create a new trade with stake_amount: %f ...',
stake_amount stake_amount
) )
whitelist = copy.deepcopy(self.config['exchange']['pair_whitelist']) whitelist = copy.deepcopy(self.active_pair_whitelist)
# Remove currently opened and latest pairs from whitelist # Remove currently opened and latest pairs from whitelist
for trade in Trade.query.filter(Trade.is_open.is_(True)).all(): for trade in Trade.query.filter(Trade.is_open.is_(True)).all():

View File

@ -663,6 +663,52 @@ def test_process_trade_handling(
assert result is False assert result is False
def test_process_trade_no_whitelist_pair(
default_conf, ticker, limit_buy_order, markets, fee, mocker) -> None:
""" Test _process with trade not in pair list """
patch_RPCManager(mocker)
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
get_ticker=ticker,
get_markets=markets,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
get_order=MagicMock(return_value=limit_buy_order),
get_fee=fee,
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)
pair = 'NOCLUE/BTC'
# create open trade not in whitelist
Trade.session.add(Trade(
pair=pair,
stake_amount=0.001,
fee_open=fee.return_value,
fee_close=fee.return_value,
is_open=True,
amount=20,
open_rate=0.01,
exchange='bittrex',
))
Trade.session.add(Trade(
pair='ETH/BTC',
stake_amount=0.001,
fee_open=fee.return_value,
fee_close=fee.return_value,
is_open=True,
amount=12,
open_rate=0.001,
exchange='bittrex',
))
assert pair not in freqtrade.active_pair_whitelist
result = freqtrade._process()
assert pair in freqtrade.active_pair_whitelist
# Make sure each pair is only in the list once
assert len(freqtrade.active_pair_whitelist) == len(set(freqtrade.active_pair_whitelist))
assert result is True
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)