Merge pull request #944 from freqtrade/improve-strategy-handling

Improve strategy handling
This commit is contained in:
Janne Sinivirta 2018-06-23 14:32:39 +03:00 committed by GitHub
commit 90caa09ae0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 6 deletions

View File

@ -39,7 +39,6 @@ class Hyperopt(Backtesting):
hyperopt.start() hyperopt.start()
""" """
def __init__(self, config: Dict[str, Any]) -> None: def __init__(self, config: Dict[str, Any]) -> None:
super().__init__(config) super().__init__(config)
# set TARGET_TRADES to suit your number concurrent trades so its realistic # set TARGET_TRADES to suit your number concurrent trades so its realistic
# to the number of days # to the number of days

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

View File

@ -1,14 +1,39 @@
# pragma pylint: disable=missing-docstring, protected-access, C0103 # pragma pylint: disable=missing-docstring, protected-access, C0103
import logging import logging
import os import os
import pytest import pytest
from freqtrade.strategy import import_strategy
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy.resolver import StrategyResolver from freqtrade.strategy.resolver import StrategyResolver
def test_import_strategy(caplog):
caplog.set_level(logging.DEBUG)
strategy = DefaultStrategy()
strategy.some_method = lambda *args, **kwargs: 42
assert strategy.__module__ == 'freqtrade.strategy.default_strategy'
assert strategy.some_method() == 42
imported_strategy = import_strategy(strategy)
assert dir(strategy) == dir(imported_strategy)
assert imported_strategy.__module__ == 'freqtrade.strategy'
assert imported_strategy.some_method() == 42
assert (
'freqtrade.strategy',
logging.DEBUG,
'Imported strategy freqtrade.strategy.default_strategy.DefaultStrategy '
'as freqtrade.strategy.DefaultStrategy',
) in caplog.record_tuples
def test_search_strategy(): def test_search_strategy():
default_location = os.path.join(os.path.dirname( default_location = os.path.join(os.path.dirname(
os.path.realpath(__file__)), '..', '..', 'strategy' os.path.realpath(__file__)), '..', '..', 'strategy'
@ -20,8 +45,7 @@ def test_search_strategy():
def test_load_strategy(result): def test_load_strategy(result):
resolver = StrategyResolver() resolver = StrategyResolver({'strategy': 'TestStrategy'})
resolver._load_strategy('TestStrategy')
assert hasattr(resolver.strategy, 'populate_indicators') assert hasattr(resolver.strategy, 'populate_indicators')
assert 'adx' in resolver.strategy.populate_indicators(result) assert 'adx' in resolver.strategy.populate_indicators(result)