Merge pull request #3317 from hroff-1902/refactor-informative

Refactor informative pairs
This commit is contained in:
Matthias 2020-05-18 21:57:16 +02:00 committed by GitHub
commit 76bd97d510
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 20 deletions

View File

@ -5,7 +5,7 @@ including ticker and orderbook data, live and historical candle (OHLCV) data
Common Interface for bot and strategy to access data. Common Interface for bot and strategy to access data.
""" """
import logging import logging
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional
from pandas import DataFrame from pandas import DataFrame
@ -13,6 +13,8 @@ from freqtrade.data.history import load_pair_history
from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.state import RunMode from freqtrade.state import RunMode
from freqtrade.typing import ListPairsWithTimeframes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -25,8 +27,8 @@ class DataProvider:
self._pairlists = pairlists self._pairlists = pairlists
def refresh(self, def refresh(self,
pairlist: List[Tuple[str, str]], pairlist: ListPairsWithTimeframes,
helping_pairs: List[Tuple[str, str]] = None) -> None: helping_pairs: ListPairsWithTimeframes = None) -> None:
""" """
Refresh data, called with each cycle Refresh data, called with each cycle
""" """
@ -36,7 +38,7 @@ class DataProvider:
self._exchange.refresh_latest_ohlcv(pairlist) self._exchange.refresh_latest_ohlcv(pairlist)
@property @property
def available_pairs(self) -> List[Tuple[str, str]]: def available_pairs(self) -> ListPairsWithTimeframes:
""" """
Return a list of tuples containing (pair, timeframe) for which data is currently cached. Return a list of tuples containing (pair, timeframe) for which data is currently cached.
Should be whitelist + open trades. Should be whitelist + open trades.

View File

@ -23,6 +23,7 @@ from freqtrade.exceptions import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError) OperationalException, TemporaryError)
from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async from freqtrade.exchange.common import BAD_EXCHANGES, retrier, retrier_async
from freqtrade.misc import deep_merge_dicts, safe_value_fallback from freqtrade.misc import deep_merge_dicts, safe_value_fallback
from freqtrade.typing import ListPairsWithTimeframes
CcxtModuleType = Any CcxtModuleType = Any
@ -675,7 +676,7 @@ class Exchange:
logger.info("Downloaded data for %s with length %s.", pair, len(data)) logger.info("Downloaded data for %s with length %s.", pair, len(data))
return data return data
def refresh_latest_ohlcv(self, pair_list: List[Tuple[str, str]]) -> List[Tuple[str, List]]: def refresh_latest_ohlcv(self, pair_list: ListPairsWithTimeframes) -> List[Tuple[str, List]]:
""" """
Refresh in-memory OHLCV asynchronously and set `_klines` with the result Refresh in-memory OHLCV asynchronously and set `_klines` with the result
Loops asynchronously over pair_list and downloads all pairs async (semi-parallel). Loops asynchronously over pair_list and downloads all pairs async (semi-parallel).

View File

@ -7,7 +7,7 @@ import traceback
from datetime import datetime from datetime import datetime
from math import isclose from math import isclose
from threading import Lock from threading import Lock
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional
import arrow import arrow
from cachetools import TTLCache from cachetools import TTLCache
@ -84,7 +84,7 @@ class FreqtradeBot:
self.edge = Edge(self.config, self.exchange, self.strategy) if \ self.edge = Edge(self.config, self.exchange, self.strategy) if \
self.config.get('edge', {}).get('enabled', False) else None self.config.get('edge', {}).get('enabled', False) else None
self.active_pair_whitelist = self._refresh_whitelist() self.active_pair_whitelist = self._refresh_active_whitelist()
# Set initial bot state from config # Set initial bot state from config
initial_state = self.config.get('initial_state') initial_state = self.config.get('initial_state')
@ -145,10 +145,10 @@ class FreqtradeBot:
# Query trades from persistence layer # Query trades from persistence layer
trades = Trade.get_open_trades() trades = Trade.get_open_trades()
self.active_pair_whitelist = self._refresh_whitelist(trades) self.active_pair_whitelist = self._refresh_active_whitelist(trades)
# Refreshing candles # Refreshing candles
self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist), self.dataprovider.refresh(self.pairlists.create_pair_list(self.active_pair_whitelist),
self.strategy.informative_pairs()) self.strategy.informative_pairs())
with self._sell_lock: with self._sell_lock:
@ -175,9 +175,10 @@ class FreqtradeBot:
if self.config['cancel_open_orders_on_exit']: if self.config['cancel_open_orders_on_exit']:
self.cancel_all_open_orders() self.cancel_all_open_orders()
def _refresh_whitelist(self, trades: List[Trade] = []) -> List[str]: def _refresh_active_whitelist(self, trades: List[Trade] = []) -> List[str]:
""" """
Refresh whitelist from pairlist or edge and extend it with trades. Refresh active whitelist from pairlist or edge and extend it with
pairs that have open trades.
""" """
# Refresh whitelist # Refresh whitelist
self.pairlists.refresh_pairlist() self.pairlists.refresh_pairlist()
@ -194,12 +195,6 @@ class FreqtradeBot:
_whitelist.extend([trade.pair for trade in trades if trade.pair not in _whitelist]) _whitelist.extend([trade.pair for trade in trades if trade.pair not in _whitelist])
return _whitelist return _whitelist
def _create_pair_whitelist(self, pairs: List[str]) -> List[Tuple[str, str]]:
"""
Create pair-whitelist tuple with (pair, ticker_interval)
"""
return [(pair, self.config['ticker_interval']) for pair in pairs]
def get_free_open_trades(self): def get_free_open_trades(self):
""" """
Return the number of free open trades slots or 0 if Return the number of free open trades slots or 0 if

View File

@ -10,6 +10,7 @@ from cachetools import TTLCache, cached
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.pairlist.IPairList import IPairList from freqtrade.pairlist.IPairList import IPairList
from freqtrade.resolvers import PairListResolver from freqtrade.resolvers import PairListResolver
from freqtrade.typing import ListPairsWithTimeframes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -107,3 +108,9 @@ class PairListManager():
pairlist.remove(p) pairlist.remove(p)
return pairlist return pairlist
def create_pair_list(self, pairs: List[str], timeframe: str = None) -> ListPairsWithTimeframes:
"""
Create list of pair tuples with (pair, ticker_interval)
"""
return [(pair, timeframe or self._config['ticker_interval']) for pair in pairs]

View File

@ -7,7 +7,7 @@ import warnings
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import datetime, timezone from datetime import datetime, timezone
from enum import Enum from enum import Enum
from typing import Dict, List, NamedTuple, Optional, Tuple from typing import Dict, NamedTuple, Optional, Tuple
import arrow import arrow
from pandas import DataFrame from pandas import DataFrame
@ -17,8 +17,10 @@ from freqtrade.exceptions import StrategyError
from freqtrade.exchange import timeframe_to_minutes from freqtrade.exchange import timeframe_to_minutes
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper from freqtrade.strategy.strategy_wrapper import strategy_safe_wrapper
from freqtrade.typing import ListPairsWithTimeframes
from freqtrade.wallets import Wallets from freqtrade.wallets import Wallets
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -185,7 +187,7 @@ class IStrategy(ABC):
""" """
return False return False
def informative_pairs(self) -> List[Tuple[str, str]]: def informative_pairs(self) -> ListPairsWithTimeframes:
""" """
Define additional, informative pair/interval combinations to be cached from the exchange. Define additional, informative pair/interval combinations to be cached from the exchange.
These pair/interval combinations are non-tradeable, unless they are part These pair/interval combinations are non-tradeable, unless they are part

8
freqtrade/typing.py Normal file
View File

@ -0,0 +1,8 @@
"""
Common Freqtrade types
"""
from typing import List, Tuple
# List of pairs with their timeframes
ListPairsWithTimeframes = List[Tuple[str, str]]

View File

@ -92,7 +92,7 @@ def patch_wallet(mocker, free=999.9) -> None:
def patch_whitelist(mocker, conf) -> None: def patch_whitelist(mocker, conf) -> None:
mocker.patch('freqtrade.freqtradebot.FreqtradeBot._refresh_whitelist', mocker.patch('freqtrade.freqtradebot.FreqtradeBot._refresh_active_whitelist',
MagicMock(return_value=conf['exchange']['pair_whitelist'])) MagicMock(return_value=conf['exchange']['pair_whitelist']))