stable/freqtrade/optimize/custom_hyperopt.py
2018-11-07 06:26:16 +01:00

153 lines
5.0 KiB
Python

# pragma pylint: disable=attribute-defined-outside-init
"""
This module load custom hyperopts
"""
import importlib
import os
import sys
from typing import Dict, Any, Callable
from pandas import DataFrame
from freqtrade.constants import Constants
from freqtrade.logger import Logger
from freqtrade.optimize.interface import IHyperOpt
sys.path.insert(0, r'../../user_data/hyperopts')
class CustomHyperOpt(object):
"""
This class contains all the logic to load custom hyperopt class
"""
def __init__(self, config: dict = {}) -> None:
"""
Load the custom class from config parameter
:param config:
:return:
"""
self.logger = Logger(name=__name__).get_logger()
# Verify the hyperopt is in the configuration, otherwise fallback to the default hyperopt
if 'hyperopt' in config:
hyperopt = config['hyperopt']
else:
hyperopt = Constants.DEFAULT_HYPEROPT
# Load the hyperopt
self._load_hyperopt(hyperopt)
def _load_hyperopt(self, hyperopt_name: str) -> None:
"""
Search and load the custom hyperopt. If no hyperopt found, fallback on the default hyperopt
Set the object into self.custom_hyperopt
:param hyperopt_name: name of the module to import
:return: None
"""
try:
# Start by sanitizing the file name (remove any extensions)
hyperopt_name = self._sanitize_module_name(filename=hyperopt_name)
# Search where can be the hyperopt file
path = self._search_hyperopt(filename=hyperopt_name)
# Load the hyperopt
self.custom_hyperopt = self._load_class(path + hyperopt_name)
# Fallback to the default hyperopt
except (ImportError, TypeError) as error:
self.logger.error(
"Impossible to load Hyperopt 'user_data/hyperopts/%s.py'. This file does not exist"
" or contains Python code errors",
hyperopt_name
)
self.logger.error(
"The error is:\n%s.",
error
)
def _load_class(self, filename: str) -> IHyperOpt:
"""
Import a hyperopt as a module
:param filename: path to the hyperopt (path from freqtrade/optimize/)
:return: return the hyperopt class
"""
module = importlib.import_module(filename, __package__)
custom_hyperopt = getattr(module, module.class_name)
self.logger.info("Load hyperopt class: %s (%s.py)", module.class_name, filename)
return custom_hyperopt()
@staticmethod
def _sanitize_module_name(filename: str) -> str:
"""
Remove any extension from filename
:param filename: filename to sanatize
:return: return the filename without extensions
"""
filename = os.path.basename(filename)
filename = os.path.splitext(filename)[0]
return filename
@staticmethod
def _search_hyperopt(filename: str) -> str:
"""
Search for the hyperopt file in different folder
1. search into the user_data/hyperopts folder
2. search into the freqtrade/optimize folder
3. if nothing found, return None
:param hyperopt_name: module name to search
:return: module path where is the hyperopt
"""
pwd = os.path.dirname(os.path.realpath(__file__)) + '/'
user_data = os.path.join(pwd, '..', '..', 'user_data', 'hyperopts', filename + '.py')
hyperopt_folder = os.path.join(pwd, filename + '.py')
path = None
if os.path.isfile(user_data):
path = 'user_data.hyperopts.'
elif os.path.isfile(hyperopt_folder):
path = '.'
return path
def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
"""
Populate indicators that will be used in the Buy and Sell hyperopt
:param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
:return: a Dataframe with all mandatory indicators for the strategies
"""
return self.custom_hyperopt.populate_indicators(dataframe)
def buy_strategy_generator(self, params: Dict[str, Any]) -> Callable:
"""
Create a buy strategy generator
"""
return self.custom_hyperopt.buy_strategy_generator(params)
def indicator_space(self) -> Dict[str, Any]:
"""
Create an indicator space
"""
return self.custom_hyperopt.indicator_space()
def generate_roi_table(self, params: Dict) -> Dict[int, float]:
"""
Create an roi table
"""
return self.custom_hyperopt.generate_roi_table(params)
def stoploss_space(self) -> Dict[str, Any]:
"""
Create a stoploss space
"""
return self.custom_hyperopt.stoploss_space()
def roi_space(self) -> Dict[str, Any]:
"""
Create a roi space
"""
return self.custom_hyperopt.roi_space()