hyperopt - freqai - docs and refactoring

This commit is contained in:
Wagner Costa Santos
2022-09-06 15:42:47 -03:00
parent 1820bc6832
commit 8d16dd804d
5 changed files with 29 additions and 111 deletions

View File

@@ -285,6 +285,7 @@ class Configuration:
logger.info('Parameter --stoplosses detected: %s ...', self.args["stoploss_range"])
# Hyperopt section
self._check_hyperopt_analyze_per_epoch_freqai()
self._args_to_config(config, argname='hyperopt',
logstring='Using Hyperopt class name: {}')
@@ -537,3 +538,12 @@ class Configuration:
config['pairs'] = load_file(pairs_file)
if 'pairs' in config and isinstance(config['pairs'], list):
config['pairs'].sort()
def _check_hyperopt_analyze_per_epoch_freqai(self) -> None:
"""
Helper for block hyperopt with analyze-per-epoch param.
"""
if ("analyze_per_epoch" in self.args and
self.args["analyze_per_epoch"] and "freqaimodel" in self.args):
raise OperationalException('analyze-per-epoch parameter is \
not allowed with a Freqai strategy.')

View File

@@ -93,16 +93,6 @@ class FreqaiDataDrawer:
"model_filename": "", "trained_timestamp": 0,
"priority": 1, "first": True, "data_path": "", "extras": {}}
def __getstate__(self):
"""
Return state values to be pickled.
It's necessary to allow serialization in hyperopt
"""
return ({
"pair_dict": self.pair_dict,
"pair_dictionary_path": self.pair_dictionary_path
})
def load_drawer_from_disk(self):
"""
Locate and load a previously saved data drawer full of all pair model metadata in
@@ -165,22 +155,14 @@ class FreqaiDataDrawer:
# create a backup
shutil.copy(self.historic_predictions_path, self.historic_predictions_bkp_path)
def save_drawer_to_disk(self, live=False):
def save_drawer_to_disk(self):
"""
Save data drawer full of all pair model metadata in present model folder.
"""
if live:
with self.save_lock:
with open(self.pair_dictionary_path, 'w') as fp:
rapidjson.dump(
self.pair_dict, fp, default=self.np_encoder,
number_mode=rapidjson.NM_NATIVE)
else:
# save_lock it's not working with hyperopt
with self.save_lock:
with open(self.pair_dictionary_path, 'w') as fp:
rapidjson.dump(
self.pair_dict, fp, default=self.np_encoder,
number_mode=rapidjson.NM_NATIVE)
rapidjson.dump(self.pair_dict, fp, default=self.np_encoder,
number_mode=rapidjson.NM_NATIVE)
def save_follower_dict_to_disk(self):
"""
@@ -455,7 +437,7 @@ class FreqaiDataDrawer:
self.model_dictionary[coin] = model
self.pair_dict[coin]["model_filename"] = dk.model_filename
self.pair_dict[coin]["data_path"] = str(dk.data_path)
self.save_drawer_to_disk(dk.live)
self.save_drawer_to_disk()
return

View File

@@ -92,10 +92,9 @@ class IFreqaiModel(ABC):
def __getstate__(self):
"""
Return state values to be pickled.
It's necessary to allow serialization in hyperopt
Return an empty state to be pickled in hyperopt
"""
return ({"dd": self.dd})
return ({})
def assert_config(self, config: Dict[str, Any]) -> None:

View File

@@ -6,9 +6,7 @@ import talib.abstract as ta
from pandas import DataFrame
from technical import qtpylib
from freqtrade.exchange import timeframe_to_prev_date
from freqtrade.persistence import Trade
from freqtrade.strategy import DecimalParameter, IntParameter, IStrategy, merge_informative_pair
from freqtrade.strategy import IStrategy, merge_informative_pair
logger = logging.getLogger(__name__)
@@ -47,11 +45,6 @@ class FreqaiExampleStrategy(IStrategy):
startup_candle_count: int = 40
can_short = False
linear_roi_offset = DecimalParameter(
0.00, 0.02, default=0.005, space="sell", optimize=False, load=True
)
max_roi_time_long = IntParameter(0, 800, default=400, space="sell", optimize=False, load=True)
def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist()
corr_pairs = self.config["freqai"]["feature_parameters"]["include_corr_pairlist"]
@@ -226,83 +219,6 @@ class FreqaiExampleStrategy(IStrategy):
def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1])
def custom_exit(
self, pair: str, trade: Trade, current_time, current_rate, current_profit, **kwargs
):
dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
trade_date = timeframe_to_prev_date(self.config["timeframe"], trade.open_date_utc)
trade_candle = dataframe.loc[(dataframe["date"] == trade_date)]
if trade_candle.empty:
return None
trade_candle = trade_candle.squeeze()
follow_mode = self.config.get("freqai", {}).get("follow_mode", False)
if not follow_mode:
pair_dict = self.freqai.dd.pair_dict
else:
pair_dict = self.freqai.dd.follower_dict
entry_tag = trade.enter_tag
if (
"prediction" + entry_tag not in pair_dict[pair]
or pair_dict[pair]['extras']["prediction" + entry_tag] == 0
):
pair_dict[pair]['extras']["prediction" + entry_tag] = abs(trade_candle["&-s_close"])
if not follow_mode:
self.freqai.dd.save_drawer_to_disk()
else:
self.freqai.dd.save_follower_dict_to_disk()
roi_price = pair_dict[pair]['extras']["prediction" + entry_tag]
roi_time = self.max_roi_time_long.value
roi_decay = roi_price * (
1 - ((current_time - trade.open_date_utc).seconds) / (roi_time * 60)
)
if roi_decay < 0:
roi_decay = self.linear_roi_offset.value
else:
roi_decay += self.linear_roi_offset.value
if current_profit > roi_decay:
return "roi_custom_win"
if current_profit < -roi_decay:
return "roi_custom_loss"
def confirm_trade_exit(
self,
pair: str,
trade: Trade,
order_type: str,
amount: float,
rate: float,
time_in_force: str,
exit_reason: str,
current_time,
**kwargs,
) -> bool:
entry_tag = trade.enter_tag
follow_mode = self.config.get("freqai", {}).get("follow_mode", False)
if not follow_mode:
pair_dict = self.freqai.dd.pair_dict
else:
pair_dict = self.freqai.dd.follower_dict
pair_dict[pair]['extras']["prediction" + entry_tag] = 0
if not follow_mode:
self.freqai.dd.save_drawer_to_disk()
else:
self.freqai.dd.save_follower_dict_to_disk()
return True
def confirm_trade_entry(
self,
pair: str,