hyperopt - freqai - docs and refactoring
This commit is contained in:
@@ -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.')
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user