Merge branch 'develop' into spice-rack

This commit is contained in:
robcaulk
2022-09-25 11:37:38 +02:00
148 changed files with 3787 additions and 930 deletions

View File

@@ -15,7 +15,7 @@ from pandas import DataFrame
from freqtrade import constants
from freqtrade.configuration import TimeRange, validate_config_consistency
from freqtrade.constants import DATETIME_PRINT_FORMAT, LongShort
from freqtrade.constants import DATETIME_PRINT_FORMAT, Config, LongShort
from freqtrade.data import history
from freqtrade.data.btanalysis import find_existing_backtest_stats, trade_list_to_dataframe
from freqtrade.data.converter import trim_dataframe, trim_dataframes
@@ -70,7 +70,7 @@ class Backtesting:
backtesting.start()
"""
def __init__(self, config: Dict[str, Any]) -> None:
def __init__(self, config: Config) -> None:
LoggingMixin.show_output = False
self.config = config
@@ -95,8 +95,8 @@ class Backtesting:
if self.config.get('strategy_list'):
if self.config.get('freqai', {}).get('enabled', False):
raise OperationalException(
"You can't use strategy_list and freqai at the same time.")
logger.warning("Using --strategy-list with FreqAI REQUIRES all strategies "
"to have identical populate_any_indicators.")
for strat in list(self.config['strategy_list']):
stratconf = deepcopy(self.config)
stratconf['strategy'] = strat
@@ -143,9 +143,14 @@ class Backtesting:
# Get maximum required startup period
self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
self.exchange.validate_required_startup_candles(self.required_startup, self.timeframe)
if self.config.get('freqai', {}).get('enabled', False):
# For FreqAI, increase the required_startup to includes the training data
self.required_startup = self.dataprovider.get_required_startup(self.timeframe)
# Add maximum startup candle count to configuration for informative pairs support
self.config['startup_candle_count'] = self.required_startup
self.exchange.validate_required_startup_candles(self.required_startup, self.timeframe)
self.trading_mode: TradingMode = config.get('trading_mode', TradingMode.SPOT)
# strategies which define "can_short=True" will fail to load in Spot mode.
@@ -221,7 +226,7 @@ class Backtesting:
pairs=self.pairlists.whitelist,
timeframe=self.timeframe,
timerange=self.timerange,
startup_candles=self.dataprovider.get_required_startup(self.timeframe),
startup_candles=self.config['startup_candle_count'],
fail_without_data=True,
data_format=self.config.get('dataformat_ohlcv', 'json'),
candle_type=self.config.get('candle_type_def', CandleType.SPOT)

View File

@@ -4,10 +4,10 @@
This module contains the edge backtesting interface
"""
import logging
from typing import Any, Dict
from freqtrade import constants
from freqtrade.configuration import TimeRange, validate_config_consistency
from freqtrade.constants import Config
from freqtrade.data.dataprovider import DataProvider
from freqtrade.edge import Edge
from freqtrade.optimize.optimize_reports import generate_edge_table
@@ -26,7 +26,7 @@ class EdgeCli:
edge.start()
"""
def __init__(self, config: Dict[str, Any]) -> None:
def __init__(self, config: Config) -> None:
self.config = config
# Ensure using dry-run

View File

@@ -21,7 +21,7 @@ from joblib import Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_
from joblib.externals import cloudpickle
from pandas import DataFrame
from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN
from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN, Config
from freqtrade.data.converter import trim_dataframes
from freqtrade.data.history import get_timerange
from freqtrade.enums import HyperoptState
@@ -66,7 +66,7 @@ class Hyperopt:
hyperopt.start()
"""
def __init__(self, config: Dict[str, Any]) -> None:
def __init__(self, config: Config) -> None:
self.buy_space: List[Dimension] = []
self.sell_space: List[Dimension] = []
self.protection_space: List[Dimension] = []
@@ -132,7 +132,7 @@ class Hyperopt:
self.print_json = self.config.get('print_json', False)
@staticmethod
def get_lock_filename(config: Dict[str, Any]) -> str:
def get_lock_filename(config: Config) -> str:
return str(config['user_data_dir'] / 'hyperopt.lock')

View File

@@ -10,6 +10,7 @@ from typing import Dict, List, Union
from sklearn.base import RegressorMixin
from skopt.space import Categorical, Dimension, Integer
from freqtrade.constants import Config
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.misc import round_dict
from freqtrade.optimize.space import SKDecimal
@@ -32,7 +33,7 @@ class IHyperOpt(ABC):
timeframe: str
strategy: IStrategy
def __init__(self, config: dict) -> None:
def __init__(self, config: Config) -> None:
self.config = config
# Assign timeframe to be used in hyperopt

View File

@@ -10,6 +10,7 @@ from typing import Any, Dict
from pandas import DataFrame
from freqtrade.constants import Config
from freqtrade.data.metrics import calculate_max_drawdown
from freqtrade.optimize.hyperopt import IHyperOptLoss
@@ -27,7 +28,7 @@ class CalmarHyperOptLoss(IHyperOptLoss):
trade_count: int,
min_date: datetime,
max_date: datetime,
config: Dict,
config: Config,
processed: Dict[str, DataFrame],
backtest_stats: Dict[str, Any],
*args,

View File

@@ -4,10 +4,9 @@ MaxDrawDownRelativeHyperOptLoss
This module defines the alternative HyperOptLoss class which can be used for
Hyperoptimization.
"""
from typing import Dict
from pandas import DataFrame
from freqtrade.constants import Config
from freqtrade.data.metrics import calculate_underwater
from freqtrade.optimize.hyperopt import IHyperOptLoss
@@ -22,7 +21,7 @@ class MaxDrawDownRelativeHyperOptLoss(IHyperOptLoss):
"""
@staticmethod
def hyperopt_loss_function(results: DataFrame, config: Dict,
def hyperopt_loss_function(results: DataFrame, config: Config,
*args, **kwargs) -> float:
"""

View File

@@ -9,6 +9,8 @@ from typing import Any, Dict
from pandas import DataFrame
from freqtrade.constants import Config
class IHyperOptLoss(ABC):
"""
@@ -21,7 +23,7 @@ class IHyperOptLoss(ABC):
@abstractmethod
def hyperopt_loss_function(*, results: DataFrame, trade_count: int,
min_date: datetime, max_date: datetime,
config: Dict, processed: Dict[str, DataFrame],
config: Config, processed: Dict[str, DataFrame],
backtest_stats: Dict[str, Any],
**kwargs) -> float:
"""

View File

@@ -12,7 +12,7 @@ import tabulate
from colorama import Fore, Style
from pandas import isna, json_normalize
from freqtrade.constants import FTHYPT_FILEVERSION, USERPATH_STRATEGIES
from freqtrade.constants import FTHYPT_FILEVERSION, USERPATH_STRATEGIES, Config
from freqtrade.enums import HyperoptState
from freqtrade.exceptions import OperationalException
from freqtrade.misc import deep_merge_dicts, round_coin_value, round_dict, safe_value_fallback2
@@ -45,7 +45,7 @@ class HyperoptStateContainer():
class HyperoptTools():
@staticmethod
def get_strategy_filename(config: Dict, strategy_name: str) -> Optional[Path]:
def get_strategy_filename(config: Config, strategy_name: str) -> Optional[Path]:
"""
Get Strategy-location (filename) from strategy_name
"""
@@ -81,7 +81,7 @@ class HyperoptTools():
)
@staticmethod
def try_export_params(config: Dict[str, Any], strategy_name: str, params: Dict):
def try_export_params(config: Config, strategy_name: str, params: Dict):
if params.get(FTHYPT_FILEVERSION, 1) >= 2 and not config.get('disableparamexport', False):
# Export parameters ...
fn = HyperoptTools.get_strategy_filename(config, strategy_name)
@@ -91,7 +91,7 @@ class HyperoptTools():
logger.warning("Strategy not found, not exporting parameter file.")
@staticmethod
def has_space(config: Dict[str, Any], space: str) -> bool:
def has_space(config: Config, space: str) -> bool:
"""
Tell if the space value is contained in the configuration
"""
@@ -131,7 +131,7 @@ class HyperoptTools():
return False
@staticmethod
def load_filtered_results(results_file: Path, config: Dict[str, Any]) -> Tuple[List, int]:
def load_filtered_results(results_file: Path, config: Config) -> Tuple[List, int]:
filteroptions = {
'only_best': config.get('hyperopt_list_best', False),
'only_profitable': config.get('hyperopt_list_profitable', False),
@@ -346,7 +346,7 @@ class HyperoptTools():
return trials
@staticmethod
def get_result_table(config: dict, results: list, total_epochs: int, highlight_best: bool,
def get_result_table(config: Config, results: list, total_epochs: int, highlight_best: bool,
print_colorized: bool, remove_header: int) -> str:
"""
Log result table
@@ -444,7 +444,7 @@ class HyperoptTools():
return table
@staticmethod
def export_csv_file(config: dict, results: list, csv_file: str) -> None:
def export_csv_file(config: Config, results: list, csv_file: str) -> None:
"""
Log result to csv-file
"""

View File

@@ -7,7 +7,8 @@ from typing import Any, Dict, List, Union
from pandas import DataFrame, to_datetime
from tabulate import tabulate
from freqtrade.constants import DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN, UNLIMITED_STAKE_AMOUNT
from freqtrade.constants import (DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN, UNLIMITED_STAKE_AMOUNT,
Config)
from freqtrade.data.metrics import (calculate_cagr, calculate_csum, calculate_market_change,
calculate_max_drawdown)
from freqtrade.misc import decimals_per_coin, file_dump_joblib, file_dump_json, round_coin_value
@@ -898,7 +899,7 @@ def show_backtest_result(strategy: str, results: Dict[str, Any], stake_currency:
print()
def show_backtest_results(config: Dict, backtest_stats: Dict):
def show_backtest_results(config: Config, backtest_stats: Dict):
stake_currency = config['stake_currency']
for strategy, results in backtest_stats['strategy'].items():
@@ -918,7 +919,7 @@ def show_backtest_results(config: Dict, backtest_stats: Dict):
print('\nFor more details, please look at the detail tables above')
def show_sorted_pairlist(config: Dict, backtest_stats: Dict):
def show_sorted_pairlist(config: Config, backtest_stats: Dict):
if config.get('backtest_show_pair_list', False):
for strategy, results in backtest_stats['strategy'].items():
print(f"Pairs for Strategy {strategy}: \n[")