Merge pull request #944 from freqtrade/improve-strategy-handling
Improve strategy handling
This commit is contained in:
commit
90caa09ae0
@ -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
|
||||||
|
@ -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()
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user