From 2b00a5d90a168df621731ea30687597ef2f44b12 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 8 Sep 2019 02:43:02 +0300 Subject: [PATCH 1/3] Get rid of import_strategy() --- freqtrade/optimize/__init__.py | 10 ------ freqtrade/resolvers/strategy_resolver.py | 8 +---- freqtrade/strategy/__init__.py | 42 ------------------------ 3 files changed, 1 insertion(+), 59 deletions(-) diff --git a/freqtrade/optimize/__init__.py b/freqtrade/optimize/__init__.py index 2c7c42c4d..973ea1ff5 100644 --- a/freqtrade/optimize/__init__.py +++ b/freqtrade/optimize/__init__.py @@ -25,16 +25,6 @@ def setup_configuration(args: Namespace, method: RunMode) -> Dict[str, Any]: raise DependencyException('stake amount could not be "%s" for backtesting' % constants.UNLIMITED_STAKE_AMOUNT) - if method == RunMode.HYPEROPT: - # Special cases for Hyperopt - if config.get('strategy') and config.get('strategy') != 'DefaultStrategy': - logger.error("Please don't use --strategy for hyperopt.") - logger.error( - "Read the documentation at " - "https://github.com/freqtrade/freqtrade/blob/develop/docs/hyperopt.md " - "to understand how to configure hyperopt.") - raise DependencyException("--strategy configured but not supported for hyperopt") - return config diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 514e9f22b..ca7e1165b 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -13,7 +13,6 @@ from typing import Dict, Optional from freqtrade import constants, OperationalException from freqtrade.resolvers import IResolver -from freqtrade.strategy import import_strategy from freqtrade.strategy.interface import IStrategy logger = logging.getLogger(__name__) @@ -158,12 +157,7 @@ class StrategyResolver(IResolver): strategy._sell_fun_len]]): strategy.INTERFACE_VERSION = 1 - try: - return import_strategy(strategy, config=config) - except TypeError as e: - logger.warning( - f"Impossible to load strategy '{strategy_name}'. " - f"Error: {e}") + return strategy raise OperationalException( f"Impossible to load Strategy '{strategy_name}'. This class does not exist " diff --git a/freqtrade/strategy/__init__.py b/freqtrade/strategy/__init__.py index c62bfe5dc..3fcc87ff3 100644 --- a/freqtrade/strategy/__init__.py +++ b/freqtrade/strategy/__init__.py @@ -1,45 +1,3 @@ -import logging -import sys -from copy import deepcopy - from freqtrade.strategy.interface import IStrategy # Import Default-Strategy to have hyperopt correctly resolve from freqtrade.strategy.default_strategy import DefaultStrategy # noqa: F401 - - -logger = logging.getLogger(__name__) - - -def import_strategy(strategy: IStrategy, config: dict) -> 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 - comb = {**strategy.__class__.__dict__, **strategy.__dict__} - - # Delete '_abc_impl' from dict as deepcopy fails on 3.7 with - # `TypeError: can't pickle _abc_data objects`` - # This will only apply to python 3.7 - if sys.version_info.major == 3 and sys.version_info.minor == 7 and '_abc_impl' in comb: - del comb['_abc_impl'] - - attr = deepcopy(comb) - - # 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(config) From 45cfdbbda7dc05f38cde8d411bde69838fcf1b9e Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 8 Sep 2019 03:10:01 +0300 Subject: [PATCH 2/3] Make flake happy --- freqtrade/strategy/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/strategy/__init__.py b/freqtrade/strategy/__init__.py index 3fcc87ff3..8e5dab975 100644 --- a/freqtrade/strategy/__init__.py +++ b/freqtrade/strategy/__init__.py @@ -1,3 +1,3 @@ -from freqtrade.strategy.interface import IStrategy +from freqtrade.strategy.interface import IStrategy # noqa: F401 # Import Default-Strategy to have hyperopt correctly resolve from freqtrade.strategy.default_strategy import DefaultStrategy # noqa: F401 From 865e0d3af94ddbfa9195373ed9949bdb31659862 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Sun, 8 Sep 2019 03:19:21 +0300 Subject: [PATCH 3/3] Adjust tests: removed tests for/with import_strategy() --- freqtrade/tests/optimize/test_hyperopt.py | 20 +------------ freqtrade/tests/strategy/test_strategy.py | 34 ----------------------- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/freqtrade/tests/optimize/test_hyperopt.py b/freqtrade/tests/optimize/test_hyperopt.py index 976cb3d53..fe7d9ccc4 100644 --- a/freqtrade/tests/optimize/test_hyperopt.py +++ b/freqtrade/tests/optimize/test_hyperopt.py @@ -9,7 +9,7 @@ from arrow import Arrow from filelock import Timeout from pathlib import Path -from freqtrade import DependencyException, OperationalException +from freqtrade import OperationalException from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.history import load_tickerdata_file from freqtrade.optimize import setup_configuration, start_hyperopt @@ -246,24 +246,6 @@ def test_start_no_data(mocker, default_conf, caplog) -> None: assert log_has('No data found. Terminating.', caplog) -def test_start_failure(mocker, default_conf, caplog) -> None: - start_mock = MagicMock() - patched_configuration_load_config_file(mocker, default_conf) - mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock) - patch_exchange(mocker) - - args = [ - '--config', 'config.json', - '--strategy', 'SampleStrategy', - 'hyperopt', - '--epochs', '5' - ] - args = get_args(args) - with pytest.raises(DependencyException): - start_hyperopt(args) - assert log_has("Please don't use --strategy for hyperopt.", caplog) - - def test_start_filelock(mocker, default_conf, caplog) -> None: start_mock = MagicMock(side_effect=Timeout(Hyperopt.get_lock_filename(default_conf))) patched_configuration_load_config_file(mocker, default_conf) diff --git a/freqtrade/tests/strategy/test_strategy.py b/freqtrade/tests/strategy/test_strategy.py index cd1102ead..24ec830a0 100644 --- a/freqtrade/tests/strategy/test_strategy.py +++ b/freqtrade/tests/strategy/test_strategy.py @@ -5,40 +5,16 @@ import warnings from base64 import urlsafe_b64encode from os import path from pathlib import Path -from unittest.mock import Mock import pytest from pandas import DataFrame from freqtrade import OperationalException from freqtrade.resolvers import StrategyResolver -from freqtrade.strategy import import_strategy -from freqtrade.strategy.default_strategy import DefaultStrategy from freqtrade.strategy.interface import IStrategy from freqtrade.tests.conftest import log_has, log_has_re -def test_import_strategy(caplog): - caplog.set_level(logging.DEBUG) - default_config = {} - - strategy = DefaultStrategy(default_config) - strategy.some_method = lambda *args, **kwargs: 42 - - assert strategy.__module__ == 'freqtrade.strategy.default_strategy' - assert strategy.some_method() == 42 - - imported_strategy = import_strategy(strategy, default_config) - - assert dir(strategy) == dir(imported_strategy) - - assert imported_strategy.__module__ == 'freqtrade.strategy' - assert imported_strategy.some_method() == 42 - - assert log_has('Imported strategy freqtrade.strategy.default_strategy.DefaultStrategy ' - 'as freqtrade.strategy.DefaultStrategy', caplog) - - def test_search_strategy(): default_config = {} default_location = Path(__file__).parent.parent.parent.joinpath('strategy').resolve() @@ -96,16 +72,6 @@ def test_load_not_found_strategy(default_conf): strategy._load_strategy(strategy_name='NotFoundStrategy', config=default_conf) -def test_load_staticmethod_importerror(mocker, caplog, default_conf): - mocker.patch("freqtrade.resolvers.strategy_resolver.import_strategy", Mock( - side_effect=TypeError("can't pickle staticmethod objects"))) - with pytest.raises(OperationalException, - match=r"Impossible to load Strategy 'DefaultStrategy'. " - r"This class does not exist or contains Python code errors."): - StrategyResolver(default_conf) - assert log_has_re(r".*Error: can't pickle staticmethod objects", caplog) - - def test_strategy(result, default_conf): default_conf.update({'strategy': 'DefaultStrategy'})