move logic from hyperopt to freqtrade.strategy

This commit is contained in:
gcarq 2018-06-23 11:13:49 +02:00
parent 3360bf4001
commit c40e6a12d1
3 changed files with 35 additions and 21 deletions

View File

@ -11,7 +11,6 @@ import pickle
import signal import signal
import sys import sys
from argparse import Namespace from argparse import Namespace
from copy import deepcopy
from functools import reduce from functools import reduce
from math import exp from math import exp
from operator import itemgetter from operator import itemgetter
@ -27,25 +26,10 @@ from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration from freqtrade.configuration import Configuration
from freqtrade.optimize import load_data from freqtrade.optimize import load_data
from freqtrade.optimize.backtesting import Backtesting from freqtrade.optimize.backtesting import Backtesting
from freqtrade.strategy.interface import IStrategy
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
HyperoptStrategy = None
def wrap_strategy(strategy: IStrategy) -> Optional[HyperoptStrategy]:
"""Wraps a given Strategy instance to HyperoptStrategy"""
global HyperoptStrategy
attr = deepcopy(dict(strategy.__class__.__dict__))
# Patch module name to make it compatible with pickle
attr['__module__'] = 'freqtrade.optimize.hyperopt'
HyperoptStrategy = type('HyperoptStrategy', (IStrategy,), attr)
return HyperoptStrategy()
class Hyperopt(Backtesting): class Hyperopt(Backtesting):
""" """
Hyperopt class, this class contains all the logic to run a hyperopt simulation Hyperopt class, this class contains all the logic to run a hyperopt simulation
@ -72,9 +56,6 @@ class Hyperopt(Backtesting):
# check that the reported Σ% values do not exceed this! # check that the reported Σ% values do not exceed this!
self.expected_max_profit = 3.0 self.expected_max_profit = 3.0
# Wrap strategy to make it compatible with pickle
self.analyze.strategy = wrap_strategy(self.analyze.strategy)
# Configuration and data used by hyperopt # Configuration and data used by hyperopt
self.processed: Optional[Dict[str, Any]] = None self.processed: Optional[Dict[str, Any]] = None

View File

@ -0,0 +1,32 @@
import logging
from copy import deepcopy
from freqtrade.strategy.interface import IStrategy
logger = logging.getLogger(__name__)
def import_strategy(strategy: IStrategy) -> IStrategy:
"""
Imports given Strategy instance to global scope
of freqtrade.strategy and returns an instance of it
"""
# Copy all attributes from base class and class
attr = deepcopy({**strategy.__class__.__dict__, **strategy.__dict__})
# Adjust module name
attr['__module__'] = 'freqtrade.strategy'
name = strategy.__class__.__name__
clazz = type(name, (IStrategy,), attr)
logger.debug(
'Imported strategy %s.%s as %s.%s',
strategy.__module__, strategy.__class__.__name__,
clazz.__module__, strategy.__class__.__name__,
)
# Modify global scope to declare class
globals()[name] = clazz
return clazz()

View File

@ -11,6 +11,7 @@ from collections import OrderedDict
from typing import Optional, Dict, Type from typing import Optional, Dict, Type
from freqtrade import constants from freqtrade import constants
from freqtrade.strategy import import_strategy
from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.interface import IStrategy
@ -83,7 +84,7 @@ class StrategyResolver(object):
strategy = self._search_strategy(path, strategy_name) strategy = self._search_strategy(path, strategy_name)
if strategy: if strategy:
logger.info('Using resolved strategy %s from \'%s\'', strategy_name, path) logger.info('Using resolved strategy %s from \'%s\'', strategy_name, path)
return strategy return import_strategy(strategy)
raise ImportError( raise ImportError(
"Impossible to load Strategy '{}'. This class does not exist" "Impossible to load Strategy '{}'. This class does not exist"
@ -100,7 +101,7 @@ class StrategyResolver(object):
""" """
# Generate spec based on absolute path # Generate spec based on absolute path
spec = importlib.util.spec_from_file_location('user_data.strategies', module_path) spec = importlib.util.spec_from_file_location('unknown', module_path)
module = importlib.util.module_from_spec(spec) module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module) # type: ignore # importlib does not use typehints spec.loader.exec_module(module) # type: ignore # importlib does not use typehints