Merge branch 'develop' into spice-rack
This commit is contained in:
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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')
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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:
|
||||
|
||||
"""
|
||||
|
@@ -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:
|
||||
"""
|
||||
|
@@ -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
|
||||
"""
|
||||
|
@@ -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[")
|
||||
|
Reference in New Issue
Block a user