mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
Seperate detail data loading from regular backest-data loading
This commit is contained in:
parent
88172fab82
commit
8405ccc15e
|
@ -22,7 +22,7 @@ ARGS_COMMON_OPTIMIZE = ["timeframe", "timerange", "dataformat_ohlcv",
|
||||||
"max_open_trades", "stake_amount", "fee", "pairs"]
|
"max_open_trades", "stake_amount", "fee", "pairs"]
|
||||||
|
|
||||||
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
|
ARGS_BACKTEST = ARGS_COMMON_OPTIMIZE + ["position_stacking", "use_max_market_positions",
|
||||||
"enable_protections", "dry_run_wallet", "detail_timeframe",
|
"enable_protections", "dry_run_wallet", "timeframe_detail",
|
||||||
"strategy_list", "export", "exportfilename"]
|
"strategy_list", "export", "exportfilename"]
|
||||||
|
|
||||||
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
|
ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
|
||||||
|
|
|
@ -135,7 +135,7 @@ AVAILABLE_CLI_OPTIONS = {
|
||||||
help='Override the value of the `stake_amount` configuration setting.',
|
help='Override the value of the `stake_amount` configuration setting.',
|
||||||
),
|
),
|
||||||
# Backtesting
|
# Backtesting
|
||||||
"detail_timeframe": Arg(
|
"timeframe_detail": Arg(
|
||||||
'--timeframe-detail',
|
'--timeframe-detail',
|
||||||
help='Specify detail timeframe for backtesting (`1m`, `5m`, `30m`, `1h`, `1d`).',
|
help='Specify detail timeframe for backtesting (`1m`, `5m`, `30m`, `1h`, `1d`).',
|
||||||
),
|
),
|
||||||
|
|
|
@ -242,9 +242,9 @@ class Configuration:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self._args_to_config(config, argname='detail_timeframe',
|
self._args_to_config(config, argname='timeframe_detail',
|
||||||
logstring='Parameter --detail-timeframe detected, '
|
logstring='Parameter --detail-timeframe detected, '
|
||||||
'using {} for intra-candle backtesting')
|
'using {} for intra-candle backtesting ...')
|
||||||
self._args_to_config(config, argname='stake_amount',
|
self._args_to_config(config, argname='stake_amount',
|
||||||
logstring='Parameter --stake-amount detected, '
|
logstring='Parameter --stake-amount detected, '
|
||||||
'overriding stake_amount to: {} ...')
|
'overriding stake_amount to: {} ...')
|
||||||
|
|
|
@ -87,7 +87,7 @@ class Backtesting:
|
||||||
self.timeframe = str(self.config.get('timeframe'))
|
self.timeframe = str(self.config.get('timeframe'))
|
||||||
self.timeframe_min = timeframe_to_minutes(self.timeframe)
|
self.timeframe_min = timeframe_to_minutes(self.timeframe)
|
||||||
# Load detail timeframe if specified
|
# Load detail timeframe if specified
|
||||||
self.timeframe_detail = str(self.config.get('detail_timeframe', ''))
|
self.timeframe_detail = str(self.config.get('timeframe_detail', ''))
|
||||||
if self.timeframe_detail:
|
if self.timeframe_detail:
|
||||||
self.timeframe_detail_min = timeframe_to_minutes(self.timeframe_detail)
|
self.timeframe_detail_min = timeframe_to_minutes(self.timeframe_detail)
|
||||||
if self.timeframe_min <= self.timeframe_detail_min:
|
if self.timeframe_min <= self.timeframe_detail_min:
|
||||||
|
@ -96,6 +96,7 @@ class Backtesting:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.timeframe_detail_min = 0
|
self.timeframe_detail_min = 0
|
||||||
|
self.detail_data: Dict[str, DataFrame] = {}
|
||||||
|
|
||||||
self.pairlists = PairListManager(self.exchange, self.config)
|
self.pairlists = PairListManager(self.exchange, self.config)
|
||||||
if 'VolumePairList' in self.pairlists.name_list:
|
if 'VolumePairList' in self.pairlists.name_list:
|
||||||
|
@ -168,7 +169,7 @@ class Backtesting:
|
||||||
conf['protections'] = strategy.protections
|
conf['protections'] = strategy.protections
|
||||||
self.protections = ProtectionManager(self.config, strategy.protections)
|
self.protections = ProtectionManager(self.config, strategy.protections)
|
||||||
|
|
||||||
def load_bt_data(self) -> Tuple[Dict[str, DataFrame], TimeRange, Dict[str, DataFrame]]:
|
def load_bt_data(self) -> Tuple[Dict[str, DataFrame], TimeRange]:
|
||||||
"""
|
"""
|
||||||
Loads backtest data and returns the data combined with the timerange
|
Loads backtest data and returns the data combined with the timerange
|
||||||
as tuple.
|
as tuple.
|
||||||
|
@ -184,18 +185,6 @@ class Backtesting:
|
||||||
fail_without_data=True,
|
fail_without_data=True,
|
||||||
data_format=self.config.get('dataformat_ohlcv', 'json'),
|
data_format=self.config.get('dataformat_ohlcv', 'json'),
|
||||||
)
|
)
|
||||||
if self.timeframe_detail:
|
|
||||||
detail_data = history.load_data(
|
|
||||||
datadir=self.config['datadir'],
|
|
||||||
pairs=self.pairlists.whitelist,
|
|
||||||
timeframe=self.timeframe_detail,
|
|
||||||
timerange=self.timerange,
|
|
||||||
startup_candles=0,
|
|
||||||
fail_without_data=True,
|
|
||||||
data_format=self.config.get('dataformat_ohlcv', 'json'),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
detail_data = None
|
|
||||||
|
|
||||||
min_date, max_date = history.get_timerange(data)
|
min_date, max_date = history.get_timerange(data)
|
||||||
|
|
||||||
|
@ -208,7 +197,24 @@ class Backtesting:
|
||||||
self.required_startup, min_date)
|
self.required_startup, min_date)
|
||||||
|
|
||||||
self.progress.set_new_value(1)
|
self.progress.set_new_value(1)
|
||||||
return data, self.timerange, detail_data
|
return data, self.timerange
|
||||||
|
|
||||||
|
def load_bt_data_detail(self) -> None:
|
||||||
|
"""
|
||||||
|
Loads backtest detail data (smaller timeframe) if necessary.
|
||||||
|
"""
|
||||||
|
if self.timeframe_detail:
|
||||||
|
self.detail_data = history.load_data(
|
||||||
|
datadir=self.config['datadir'],
|
||||||
|
pairs=self.pairlists.whitelist,
|
||||||
|
timeframe=self.timeframe_detail,
|
||||||
|
timerange=self.timerange,
|
||||||
|
startup_candles=0,
|
||||||
|
fail_without_data=True,
|
||||||
|
data_format=self.config.get('dataformat_ohlcv', 'json'),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.detail_data = {}
|
||||||
|
|
||||||
def prepare_backtest(self, enable_protections):
|
def prepare_backtest(self, enable_protections):
|
||||||
"""
|
"""
|
||||||
|
@ -637,7 +643,8 @@ class Backtesting:
|
||||||
"""
|
"""
|
||||||
data: Dict[str, Any] = {}
|
data: Dict[str, Any] = {}
|
||||||
|
|
||||||
data, timerange, self.detail_data = self.load_bt_data()
|
data, timerange = self.load_bt_data()
|
||||||
|
self.load_bt_data_detail()
|
||||||
logger.info("Dataload complete. Calculating indicators")
|
logger.info("Dataload complete. Calculating indicators")
|
||||||
|
|
||||||
for strat in self.strategylist:
|
for strat in self.strategylist:
|
||||||
|
|
|
@ -368,6 +368,7 @@ def generate_strategy_stats(btdata: Dict[str, DataFrame],
|
||||||
'max_open_trades_setting': (config['max_open_trades']
|
'max_open_trades_setting': (config['max_open_trades']
|
||||||
if config['max_open_trades'] != float('inf') else -1),
|
if config['max_open_trades'] != float('inf') else -1),
|
||||||
'timeframe': config['timeframe'],
|
'timeframe': config['timeframe'],
|
||||||
|
'timeframe_detail': config.get('timeframe_detail', ''),
|
||||||
'timerange': config.get('timerange', ''),
|
'timerange': config.get('timerange', ''),
|
||||||
'enable_protections': config.get('enable_protections', False),
|
'enable_protections': config.get('enable_protections', False),
|
||||||
'strategy_name': strategy,
|
'strategy_name': strategy,
|
||||||
|
|
|
@ -46,11 +46,14 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
|
||||||
if (
|
if (
|
||||||
not ApiServer._bt
|
not ApiServer._bt
|
||||||
or lastconfig.get('timeframe') != strat.timeframe
|
or lastconfig.get('timeframe') != strat.timeframe
|
||||||
|
or lastconfig.get('timeframe_detail') != btconfig.get('timeframe_detail')
|
||||||
or lastconfig.get('dry_run_wallet') != btconfig.get('dry_run_wallet', 0)
|
or lastconfig.get('dry_run_wallet') != btconfig.get('dry_run_wallet', 0)
|
||||||
or lastconfig.get('timerange') != btconfig['timerange']
|
or lastconfig.get('timerange') != btconfig['timerange']
|
||||||
):
|
):
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
ApiServer._bt = Backtesting(btconfig)
|
ApiServer._bt = Backtesting(btconfig)
|
||||||
|
if ApiServer._bt.timeframe_detail:
|
||||||
|
ApiServer._bt.load_bt_data_detail()
|
||||||
|
|
||||||
# Only reload data if timeframe changed.
|
# Only reload data if timeframe changed.
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -324,6 +324,7 @@ class PairHistory(BaseModel):
|
||||||
class BacktestRequest(BaseModel):
|
class BacktestRequest(BaseModel):
|
||||||
strategy: str
|
strategy: str
|
||||||
timeframe: Optional[str]
|
timeframe: Optional[str]
|
||||||
|
timeframe_detail: Optional[str]
|
||||||
timerange: Optional[str]
|
timerange: Optional[str]
|
||||||
max_open_trades: Optional[int]
|
max_open_trades: Optional[int]
|
||||||
stake_amount: Optional[Union[float, str]]
|
stake_amount: Optional[Union[float, str]]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user