diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index a08304abb..c7da19659 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -39,6 +39,11 @@ A strategy file contains all the information needed to build a good strategy: The bot also include a sample strategy called `SampleStrategy` you can update: `user_data/strategies/sample_strategy.py`. You can test it with the parameter: `--strategy SampleStrategy` +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 ``` diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 37aa96b68..514e9f22b 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.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 5c7d50a65..4907f20ed 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 """ + INTERFACE_VERSION = 2 # Minimal ROI designed for the strategy minimal_roi = { diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 99f5f26de..3f2478cc0 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 + 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 33c6e1128..cd1102ead 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.INTERFACE_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_interface_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.INTERFACE_VERSION == 2 indicator_df = resolver.strategy.advise_indicators(result, metadata=metadata) assert isinstance(indicator_df, DataFrame) diff --git a/user_data/strategies/sample_strategy.py b/user_data/strategies/sample_strategy.py index 4610a2e41..0649c6f94 100644 --- a/user_data/strategies/sample_strategy.py +++ b/user_data/strategies/sample_strategy.py @@ -27,6 +27,9 @@ class SampleStrategy(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. + INTERFACE_VERSION = 2 # Minimal ROI designed for the strategy. # This attribute will be overridden if the config file contains "minimal_roi"