Use `candle_type_def` where possible

This commit is contained in:
Matthias 2021-12-08 14:10:08 +01:00
parent 222c293602
commit d89cbda7b8
9 changed files with 28 additions and 22 deletions

View File

@ -14,6 +14,7 @@ from freqtrade.configuration.directory_operations import create_datadir, create_
from freqtrade.configuration.environment_vars import enironment_vars_to_dict from freqtrade.configuration.environment_vars import enironment_vars_to_dict
from freqtrade.configuration.load_config import load_config_file, load_file from freqtrade.configuration.load_config import load_config_file, load_file
from freqtrade.enums import NON_UTIL_MODES, TRADING_MODES, RunMode from freqtrade.enums import NON_UTIL_MODES, TRADING_MODES, RunMode
from freqtrade.enums.candletype import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.loggers import setup_logging from freqtrade.loggers import setup_logging
from freqtrade.misc import deep_merge_dicts, parse_db_uri_for_logging from freqtrade.misc import deep_merge_dicts, parse_db_uri_for_logging
@ -433,6 +434,7 @@ class Configuration:
logstring='Detected --new-pairs-days: {}') logstring='Detected --new-pairs-days: {}')
self._args_to_config(config, argname='trading_mode', self._args_to_config(config, argname='trading_mode',
logstring='Detected --trading-mode: {}') logstring='Detected --trading-mode: {}')
config['candle_type_def'] = CandleType.get_default(config.get('trading_mode', 'spot'))
self._args_to_config(config, argname='candle_types', self._args_to_config(config, argname='candle_types',
logstring='Detected --candle-types: {}') logstring='Detected --candle-types: {}')

View File

@ -260,7 +260,7 @@ def refresh_backtest_ohlcv_data(exchange: Exchange, pairs: List[str], timeframes
""" """
pairs_not_available = [] pairs_not_available = []
data_handler = get_datahandler(datadir, data_format) data_handler = get_datahandler(datadir, data_format)
candle_type = CandleType.FUTURES if trading_mode == 'futures' else CandleType.SPOT_ candle_type = CandleType.get_default(trading_mode)
for idx, pair in enumerate(pairs, start=1): for idx, pair in enumerate(pairs, start=1):
if pair not in exchange.markets: if pair not in exchange.markets:
pairs_not_available.append(pair) pairs_not_available.append(pair)

View File

@ -10,7 +10,6 @@ from pandas import DataFrame
from freqtrade.configuration import PeriodicCache from freqtrade.configuration import PeriodicCache
from freqtrade.constants import ListPairsWithTimeframes from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import plural from freqtrade.misc import plural
from freqtrade.plugins.pairlist.IPairList import IPairList from freqtrade.plugins.pairlist.IPairList import IPairList
@ -74,7 +73,7 @@ class AgeFilter(IPairList):
:return: new allowlist :return: new allowlist
""" """
needed_pairs: ListPairsWithTimeframes = [ needed_pairs: ListPairsWithTimeframes = [
(p, '1d', CandleType.SPOT_) for p in pairlist (p, '1d', self._config['candle_type_def']) for p in pairlist
if p not in self._symbolsChecked and p not in self._symbolsCheckFailed] if p not in self._symbolsChecked and p not in self._symbolsCheckFailed]
if not needed_pairs: if not needed_pairs:
# Remove pairs that have been removed before # Remove pairs that have been removed before
@ -90,8 +89,8 @@ class AgeFilter(IPairList):
candles = self._exchange.refresh_latest_ohlcv(needed_pairs, since_ms=since_ms, cache=False) candles = self._exchange.refresh_latest_ohlcv(needed_pairs, since_ms=since_ms, cache=False)
if self._enabled: if self._enabled:
for p in deepcopy(pairlist): for p in deepcopy(pairlist):
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if ( daily_candles = candles[(p, '1d', self._config['candle_type_def'])] if (
p, '1d', CandleType.SPOT_) in candles else None p, '1d', self._config['candle_type_def']) in candles else None
if not self._validate_pair_loc(p, daily_candles): if not self._validate_pair_loc(p, daily_candles):
pairlist.remove(p) pairlist.remove(p)
self.log_once(f"Validated {len(pairlist)} pairs.", logger.info) self.log_once(f"Validated {len(pairlist)} pairs.", logger.info)

View File

@ -12,7 +12,6 @@ from cachetools.ttl import TTLCache
from pandas import DataFrame from pandas import DataFrame
from freqtrade.constants import ListPairsWithTimeframes from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import plural from freqtrade.misc import plural
from freqtrade.plugins.pairlist.IPairList import IPairList from freqtrade.plugins.pairlist.IPairList import IPairList
@ -70,7 +69,7 @@ class VolatilityFilter(IPairList):
:return: new allowlist :return: new allowlist
""" """
needed_pairs: ListPairsWithTimeframes = [ needed_pairs: ListPairsWithTimeframes = [
(p, '1d', CandleType.SPOT_) for p in pairlist if p not in self._pair_cache] (p, '1d', self._config['candle_type_def']) for p in pairlist if p not in self._pair_cache]
since_ms = (arrow.utcnow() since_ms = (arrow.utcnow()
.floor('day') .floor('day')
@ -84,8 +83,8 @@ class VolatilityFilter(IPairList):
if self._enabled: if self._enabled:
for p in deepcopy(pairlist): for p in deepcopy(pairlist):
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if ( daily_candles = candles[(p, '1d', self._config['candle_type_def'])] if (
p, '1d', CandleType.SPOT_) in candles else None p, '1d', self._config['candle_type_def']) in candles else None
if not self._validate_pair_loc(p, daily_candles): if not self._validate_pair_loc(p, daily_candles):
pairlist.remove(p) pairlist.remove(p)
return pairlist return pairlist

View File

@ -11,7 +11,6 @@ import arrow
from cachetools.ttl import TTLCache from cachetools.ttl import TTLCache
from freqtrade.constants import ListPairsWithTimeframes from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange import timeframe_to_minutes from freqtrade.exchange import timeframe_to_minutes
from freqtrade.misc import format_ms_time from freqtrade.misc import format_ms_time
@ -45,6 +44,7 @@ class VolumePairList(IPairList):
self._lookback_days = self._pairlistconfig.get('lookback_days', 0) self._lookback_days = self._pairlistconfig.get('lookback_days', 0)
self._lookback_timeframe = self._pairlistconfig.get('lookback_timeframe', '1d') self._lookback_timeframe = self._pairlistconfig.get('lookback_timeframe', '1d')
self._lookback_period = self._pairlistconfig.get('lookback_period', 0) self._lookback_period = self._pairlistconfig.get('lookback_period', 0)
self._def_candletype = self._config['candle_type_def']
if (self._lookback_days > 0) & (self._lookback_period > 0): if (self._lookback_days > 0) & (self._lookback_period > 0):
raise OperationalException( raise OperationalException(
@ -162,7 +162,7 @@ class VolumePairList(IPairList):
f"{self._lookback_timeframe}, starting from {format_ms_time(since_ms)} " f"{self._lookback_timeframe}, starting from {format_ms_time(since_ms)} "
f"till {format_ms_time(to_ms)}", logger.info) f"till {format_ms_time(to_ms)}", logger.info)
needed_pairs: ListPairsWithTimeframes = [ needed_pairs: ListPairsWithTimeframes = [
(p, self._lookback_timeframe, CandleType.SPOT_) for p in (p, self._lookback_timeframe, self._def_candletype) for p in
[s['symbol'] for s in filtered_tickers] [s['symbol'] for s in filtered_tickers]
if p not in self._pair_cache if p not in self._pair_cache
] ]
@ -175,8 +175,10 @@ class VolumePairList(IPairList):
) )
for i, p in enumerate(filtered_tickers): for i, p in enumerate(filtered_tickers):
pair_candles = candles[ pair_candles = candles[
(p['symbol'], self._lookback_timeframe, CandleType.SPOT_) (p['symbol'], self._lookback_timeframe, self._def_candletype)
] if (p['symbol'], self._lookback_timeframe, CandleType.SPOT_) in candles else None ] if (
p['symbol'], self._lookback_timeframe, self._def_candletype
) in candles else None
# in case of candle data calculate typical price and quoteVolume for candle # in case of candle data calculate typical price and quoteVolume for candle
if pair_candles is not None and not pair_candles.empty: if pair_candles is not None and not pair_candles.empty:
pair_candles['typical_price'] = (pair_candles['high'] + pair_candles['low'] pair_candles['typical_price'] = (pair_candles['high'] + pair_candles['low']

View File

@ -10,7 +10,6 @@ from cachetools.ttl import TTLCache
from pandas import DataFrame from pandas import DataFrame
from freqtrade.constants import ListPairsWithTimeframes from freqtrade.constants import ListPairsWithTimeframes
from freqtrade.enums import CandleType
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import plural from freqtrade.misc import plural
from freqtrade.plugins.pairlist.IPairList import IPairList from freqtrade.plugins.pairlist.IPairList import IPairList
@ -68,7 +67,7 @@ class RangeStabilityFilter(IPairList):
:return: new allowlist :return: new allowlist
""" """
needed_pairs: ListPairsWithTimeframes = [ needed_pairs: ListPairsWithTimeframes = [
(p, '1d', CandleType.SPOT_) for p in pairlist if p not in self._pair_cache] (p, '1d', self._config['candle_type_def']) for p in pairlist if p not in self._pair_cache]
since_ms = (arrow.utcnow() since_ms = (arrow.utcnow()
.floor('day') .floor('day')
@ -82,8 +81,8 @@ class RangeStabilityFilter(IPairList):
if self._enabled: if self._enabled:
for p in deepcopy(pairlist): for p in deepcopy(pairlist):
daily_candles = candles[(p, '1d', CandleType.SPOT_)] if ( daily_candles = candles[(p, '1d', self._config['candle_type_def'])] if (
p, '1d', CandleType.SPOT_) in candles else None p, '1d', self._config['candle_type_def']) in candles else None
if not self._validate_pair_loc(p, daily_candles): if not self._validate_pair_loc(p, daily_candles):
pairlist.remove(p) pairlist.remove(p)
return pairlist return pairlist

View File

@ -15,7 +15,7 @@ class InformativeData(NamedTuple):
timeframe: str timeframe: str
fmt: Union[str, Callable[[Any], str], None] fmt: Union[str, Callable[[Any], str], None]
ffill: bool ffill: bool
candle_type: CandleType = CandleType.SPOT_ candle_type: CandleType
def informative(timeframe: str, asset: str = '', def informative(timeframe: str, asset: str = '',
@ -58,7 +58,8 @@ def informative(timeframe: str, asset: str = '',
def decorator(fn: PopulateIndicators): def decorator(fn: PopulateIndicators):
informative_pairs = getattr(fn, '_ft_informative', []) informative_pairs = getattr(fn, '_ft_informative', [])
# TODO-lev: Add candle_type to InformativeData # TODO-lev: Add candle_type to InformativeData
informative_pairs.append(InformativeData(_asset, _timeframe, _fmt, _ffill)) informative_pairs.append(InformativeData(_asset, _timeframe, _fmt, _ffill,
CandleType.SPOT_))
setattr(fn, '_ft_informative', informative_pairs) setattr(fn, '_ft_informative', informative_pairs)
return fn return fn
return decorator return decorator

View File

@ -424,7 +424,8 @@ class IStrategy(ABC, HyperStrategyMixin):
informative_pairs = self.informative_pairs() informative_pairs = self.informative_pairs()
# Compatibility code for 2 tuple informative pairs # Compatibility code for 2 tuple informative pairs
informative_pairs = [ informative_pairs = [
(p[0], p[1], CandleType.from_string(p[2]) if len(p) > 2 else CandleType.SPOT_) (p[0], p[1], CandleType.from_string(p[2]) if len(
p) > 2 else self.config['candle_type_def'])
for p in informative_pairs] for p in informative_pairs]
for inf_data, _ in self._ft_informative: for inf_data, _ in self._ft_informative:
if inf_data.asset: if inf_data.asset:
@ -530,8 +531,9 @@ class IStrategy(ABC, HyperStrategyMixin):
dataframe = self.analyze_ticker(dataframe, metadata) dataframe = self.analyze_ticker(dataframe, metadata)
self._last_candle_seen_per_pair[pair] = dataframe.iloc[-1]['date'] self._last_candle_seen_per_pair[pair] = dataframe.iloc[-1]['date']
if self.dp: if self.dp:
self.dp._set_cached_df(pair, self.timeframe, dataframe, CandleType.SPOT_) self.dp._set_cached_df(
# TODO-lev: CandleType should be set conditionally pair, self.timeframe, dataframe,
candle_type=self.config['candle_type_def'])
else: else:
logger.debug("Skipping TA Analysis for already analyzed candle") logger.debug("Skipping TA Analysis for already analyzed candle")
dataframe[SignalType.ENTER_LONG.value] = 0 dataframe[SignalType.ENTER_LONG.value] = 0

View File

@ -19,6 +19,7 @@ from freqtrade.commands import Arguments
from freqtrade.data.converter import ohlcv_to_dataframe from freqtrade.data.converter import ohlcv_to_dataframe
from freqtrade.edge import PairInfo from freqtrade.edge import PairInfo
from freqtrade.enums import Collateral, RunMode, TradingMode from freqtrade.enums import Collateral, RunMode, TradingMode
from freqtrade.enums.candletype import CandleType
from freqtrade.enums.signaltype import SignalDirection from freqtrade.enums.signaltype import SignalDirection
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.freqtradebot import FreqtradeBot from freqtrade.freqtradebot import FreqtradeBot
@ -459,6 +460,7 @@ def get_default_conf(testdatadir):
"disableparamexport": True, "disableparamexport": True,
"internals": {}, "internals": {},
"export": "none", "export": "none",
"candle_type_def": CandleType.SPOT,
} }
return configuration return configuration