Merge pull request #3317 from hroff-1902/refactor-informative
Refactor informative pairs
This commit is contained in:
commit
76bd97d510
@ -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.
|
||||||
|
@ -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).
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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
8
freqtrade/typing.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
"""
|
||||||
|
Common Freqtrade types
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
# List of pairs with their timeframes
|
||||||
|
ListPairsWithTimeframes = List[Tuple[str, str]]
|
@ -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']))
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user