From 92011f82945f2e36fa73d0bcaaa1ea13fa20a301 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 26 Aug 2019 19:44:33 +0200 Subject: [PATCH 1/3] Introduce strategy_version variable --- freqtrade/resolvers/strategy_resolver.py | 4 ++++ freqtrade/strategy/default_strategy.py | 1 + freqtrade/strategy/interface.py | 5 +++++ freqtrade/tests/strategy/test_strategy.py | 25 +++++++++++++++++++++++ user_data/strategies/test_strategy.py | 7 +++++-- 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 37aa96b68..4e6ef154b 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -153,6 +153,10 @@ class StrategyResolver(IResolver): strategy._populate_fun_len = len(getfullargspec(strategy.populate_indicators).args) strategy._buy_fun_len = len(getfullargspec(strategy.populate_buy_trend).args) strategy._sell_fun_len = len(getfullargspec(strategy.populate_sell_trend).args) + if any([x == 2 for x in [strategy._populate_fun_len, + strategy._buy_fun_len, + strategy._sell_fun_len]]): + strategy.strategy_version = 1 try: return import_strategy(strategy, config=config) diff --git a/freqtrade/strategy/default_strategy.py b/freqtrade/strategy/default_strategy.py index 5c7d50a65..51ef49193 100644 --- a/freqtrade/strategy/default_strategy.py +++ b/freqtrade/strategy/default_strategy.py @@ -13,6 +13,7 @@ class DefaultStrategy(IStrategy): Default Strategy provided by freqtrade bot. You can override it with your own strategy """ + strategy_version: int = 2 # Minimal ROI designed for the strategy minimal_roi = { diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 99f5f26de..4133d31a9 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -60,6 +60,11 @@ class IStrategy(ABC): stoploss -> float: optimal stoploss designed for the strategy ticker_interval -> str: value of the ticker interval to use for the strategy """ + # Strategy interface version + # Default to version 2 + # version 1 is the initial interface without metadata dict + # Version 2 populate_* include metadata dict + strategy_version: int = 2 _populate_fun_len: int = 0 _buy_fun_len: int = 0 diff --git a/freqtrade/tests/strategy/test_strategy.py b/freqtrade/tests/strategy/test_strategy.py index 240b83b8b..28acdea61 100644 --- a/freqtrade/tests/strategy/test_strategy.py +++ b/freqtrade/tests/strategy/test_strategy.py @@ -380,6 +380,31 @@ def test_call_deprecated_function(result, monkeypatch, default_conf): assert resolver.strategy._populate_fun_len == 2 assert resolver.strategy._buy_fun_len == 2 assert resolver.strategy._sell_fun_len == 2 + assert resolver.strategy.strategy_version == 1 + + indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) + assert isinstance(indicator_df, DataFrame) + assert 'adx' in indicator_df.columns + + buydf = resolver.strategy.advise_buy(result, metadata=metadata) + assert isinstance(buydf, DataFrame) + assert 'buy' in buydf.columns + + selldf = resolver.strategy.advise_sell(result, metadata=metadata) + assert isinstance(selldf, DataFrame) + assert 'sell' in selldf + + +def test_strategy_versioning(result, monkeypatch, default_conf): + default_conf.update({'strategy': 'DefaultStrategy'}) + resolver = StrategyResolver(default_conf) + metadata = {'pair': 'ETH/BTC'} + + # Make sure we are using a legacy function + assert resolver.strategy._populate_fun_len == 3 + assert resolver.strategy._buy_fun_len == 3 + assert resolver.strategy._sell_fun_len == 3 + assert resolver.strategy.strategy_version == 2 indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) diff --git a/user_data/strategies/test_strategy.py b/user_data/strategies/test_strategy.py index d8ff790b2..876a2845a 100644 --- a/user_data/strategies/test_strategy.py +++ b/user_data/strategies/test_strategy.py @@ -28,6 +28,9 @@ class TestStrategy(IStrategy): - the prototype for the methods: minimal_roi, stoploss, populate_indicators, populate_buy_trend, populate_sell_trend, hyperopt_space, buy_strategy_generator """ + # Strategy intervace version - allow new iterations of the strategy interface. + # Check the documentation or the Sample strategy to get the latest version. + strategy_version: int = 2 # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi" @@ -256,14 +259,14 @@ class TestStrategy(IStrategy): # Retrieve best bid and best ask # ------------------------------------ """ - # first check if dataprovider is available + # first check if dataprovider is available if self.dp: if self.dp.runmode in ('live', 'dry_run'): ob = self.dp.orderbook(metadata['pair'], 1) dataframe['best_bid'] = ob['bids'][0][0] dataframe['best_ask'] = ob['asks'][0][0] """ - + return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: From 0e62b8bd8502d70c9675bcbf0327fde076494461 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 26 Aug 2019 20:16:03 +0200 Subject: [PATCH 2/3] Update strategy_version to INTERFACE_VERSION --- freqtrade/resolvers/strategy_resolver.py | 2 +- freqtrade/strategy/default_strategy.py | 2 +- freqtrade/strategy/interface.py | 4 ++-- freqtrade/tests/strategy/test_strategy.py | 6 +++--- user_data/strategies/test_strategy.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 4e6ef154b..514e9f22b 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -156,7 +156,7 @@ class StrategyResolver(IResolver): if any([x == 2 for x in [strategy._populate_fun_len, strategy._buy_fun_len, strategy._sell_fun_len]]): - strategy.strategy_version = 1 + strategy.INTERFACE_VERSION = 1 try: return import_strategy(strategy, config=config) diff --git a/freqtrade/strategy/default_strategy.py b/freqtrade/strategy/default_strategy.py index 51ef49193..4907f20ed 100644 --- a/freqtrade/strategy/default_strategy.py +++ b/freqtrade/strategy/default_strategy.py @@ -13,7 +13,7 @@ class DefaultStrategy(IStrategy): Default Strategy provided by freqtrade bot. You can override it with your own strategy """ - strategy_version: int = 2 + INTERFACE_VERSION = 2 # Minimal ROI designed for the strategy minimal_roi = { diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4133d31a9..3f2478cc0 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -62,9 +62,9 @@ class IStrategy(ABC): """ # Strategy interface version # Default to version 2 - # version 1 is the initial interface without metadata dict + # Version 1 is the initial interface without metadata dict # Version 2 populate_* include metadata dict - strategy_version: int = 2 + INTERFACE_VERSION: int = 2 _populate_fun_len: int = 0 _buy_fun_len: int = 0 diff --git a/freqtrade/tests/strategy/test_strategy.py b/freqtrade/tests/strategy/test_strategy.py index 28acdea61..b1a6a6548 100644 --- a/freqtrade/tests/strategy/test_strategy.py +++ b/freqtrade/tests/strategy/test_strategy.py @@ -380,7 +380,7 @@ def test_call_deprecated_function(result, monkeypatch, default_conf): assert resolver.strategy._populate_fun_len == 2 assert resolver.strategy._buy_fun_len == 2 assert resolver.strategy._sell_fun_len == 2 - assert resolver.strategy.strategy_version == 1 + assert resolver.strategy.INTERFACE_VERSION == 1 indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) @@ -395,7 +395,7 @@ def test_call_deprecated_function(result, monkeypatch, default_conf): assert 'sell' in selldf -def test_strategy_versioning(result, monkeypatch, default_conf): +def test_strategy_interface_versioning(result, monkeypatch, default_conf): default_conf.update({'strategy': 'DefaultStrategy'}) resolver = StrategyResolver(default_conf) metadata = {'pair': 'ETH/BTC'} @@ -404,7 +404,7 @@ def test_strategy_versioning(result, monkeypatch, default_conf): assert resolver.strategy._populate_fun_len == 3 assert resolver.strategy._buy_fun_len == 3 assert resolver.strategy._sell_fun_len == 3 - assert resolver.strategy.strategy_version == 2 + assert resolver.strategy.INTERFACE_VERSION == 2 indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) diff --git a/user_data/strategies/test_strategy.py b/user_data/strategies/test_strategy.py index 876a2845a..8e2bf8973 100644 --- a/user_data/strategies/test_strategy.py +++ b/user_data/strategies/test_strategy.py @@ -30,7 +30,7 @@ class TestStrategy(IStrategy): """ # Strategy intervace version - allow new iterations of the strategy interface. # Check the documentation or the Sample strategy to get the latest version. - strategy_version: int = 2 + INTERFACE_VERSION = 2 # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi" From d66fb86449eccca42637177d0764f1a2eebe5ae2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 27 Aug 2019 06:32:01 +0200 Subject: [PATCH 3/3] Add documentation for interface_version --- docs/strategy-customization.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 9e32ded18..5cf3784ef 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -36,9 +36,14 @@ A strategy file contains all the information needed to build a good strategy: - Minimal ROI recommended - Stoploss strongly recommended -The bot also include a sample strategy called `TestStrategy` you can update: `user_data/strategies/test_strategy.py`. +The bot includes a sample strategy called `TestStrategy` you can update: `user_data/strategies/test_strategy.py`. You can test it with the parameter: `--strategy TestStrategy` +Additionally, there is an attribute called `INTERFACE_VERSION`, which defines the version of the strategy interface the bot should use. +The current version is 2 - which is also the default when it's not set explicitly in the strategy. + +Future versions will require this to be set. + ```bash freqtrade --strategy AwesomeStrategy ```