diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index c7958552b..9fcb70a76 100644 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -62,10 +62,10 @@ class Analyze(object): 'close': 'last', 'volume': 'max', }) - frame.drop(frame.tail(1).index, inplace=True) # eliminate partial candle + frame.drop(frame.tail(1).index, inplace=True) # eliminate partial candle return frame - def populate_indicators(self, dataframe: DataFrame) -> DataFrame: + def populate_indicators(self, dataframe: DataFrame, pair: str = None) -> DataFrame: """ Adds several different TA indicators to the given DataFrame @@ -73,23 +73,23 @@ class Analyze(object): you are using. Let uncomment only the indicator you are using in your strategies or your hyperopt configuration, otherwise you will waste your memory and CPU usage. """ - return self.strategy.populate_indicators(dataframe=dataframe) + return self.strategy.advise_indicators(dataframe=dataframe, pair=pair) - def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: + def populate_buy_trend(self, dataframe: DataFrame, pair: str = None) -> DataFrame: """ Based on TA indicators, populates the buy signal for the given dataframe :param dataframe: DataFrame :return: DataFrame with buy column """ - return self.strategy.populate_buy_trend(dataframe=dataframe) + return self.strategy.advise_buy(dataframe=dataframe, pair=pair) - def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: + def populate_sell_trend(self, dataframe: DataFrame, pair: str = None) -> DataFrame: """ Based on TA indicators, populates the sell signal for the given dataframe :param dataframe: DataFrame :return: DataFrame with buy column """ - return self.strategy.populate_sell_trend(dataframe=dataframe) + return self.strategy.advise_sell(dataframe=dataframe, pair=pair) def get_ticker_interval(self) -> str: """ @@ -98,16 +98,17 @@ class Analyze(object): """ return self.strategy.ticker_interval - def analyze_ticker(self, ticker_history: List[Dict]) -> DataFrame: + def analyze_ticker(self, ticker_history: List[Dict], pair: str) -> DataFrame: """ Parses the given ticker history and returns a populated DataFrame add several TA indicators and buy signal to it :return DataFrame with ticker data and indicator data """ + dataframe = self.parse_ticker_dataframe(ticker_history) - dataframe = self.populate_indicators(dataframe) - dataframe = self.populate_buy_trend(dataframe) - dataframe = self.populate_sell_trend(dataframe) + dataframe = self.populate_indicators(dataframe, pair) + dataframe = self.populate_buy_trend(dataframe, pair) + dataframe = self.populate_sell_trend(dataframe, pair) return dataframe def get_signal(self, pair: str, interval: str) -> Tuple[bool, bool]: @@ -123,7 +124,7 @@ class Analyze(object): return False, False try: - dataframe = self.analyze_ticker(ticker_hist) + dataframe = self.analyze_ticker(ticker_hist, pair) except ValueError as error: logger.warning( 'Unable to analyze ticker for pair %s: %s', diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 4ae358c6f..daad3881c 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -6,7 +6,7 @@ from typing import Dict from abc import ABC, abstractmethod from pandas import DataFrame - +import warnings class IStrategy(ABC): """ @@ -19,30 +19,80 @@ class IStrategy(ABC): ticker_interval -> str: value of the ticker interval to use for the strategy """ + # associated minimal roi minimal_roi: Dict + + # associated stoploss stoploss: float + + # associated ticker interval ticker_interval: str - @abstractmethod + # configuration used, just in case the strategy want's to use it for something + config: dict = {} + def populate_indicators(self, dataframe: DataFrame) -> DataFrame: """ Populate indicators that will be used in the Buy and Sell strategy :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe() :return: a Dataframe with all mandatory indicators for the strategies """ + warnings.warn("deprecated - please replace this method with advise_indicators!", DeprecationWarning) + return dataframe - @abstractmethod def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: """ Based on TA indicators, populates the buy signal for the given dataframe :param dataframe: DataFrame :return: DataFrame with buy column """ + warnings.warn("deprecated - please replace this method with advise_buy!", DeprecationWarning) + dataframe.loc[ + ( + ), + 'buy'] = 0 + return dataframe - @abstractmethod def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: """ Based on TA indicators, populates the sell signal for the given dataframe :param dataframe: DataFrame :return: DataFrame with sell column """ + warnings.warn("deprecated - please replace this method with advise_sell!", DeprecationWarning) + dataframe.loc[ + ( + ), + 'sell'] = 0 + return dataframe + + def advise_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame: + """ + + This wraps around the internal method + + Populate indicators that will be used in the Buy and Sell strategy + :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe() + :param pair: The currently traded pair + :return: a Dataframe with all mandatory indicators for the strategies + """ + return self.populate_indicators(dataframe) + + def advise_buy(self, dataframe: DataFrame, pair: str) -> DataFrame: + """ + Based on TA indicators, populates the buy signal for the given dataframe + :param dataframe: DataFrame + :param pair: The currently traded pair + :return: DataFrame with buy column + """ + + return self.populate_buy_trend(dataframe) + + def advise_sell(self, dataframe: DataFrame, pair: str) -> DataFrame: + """ + Based on TA indicators, populates the sell signal for the given dataframe + :param dataframe: DataFrame + :param pair: The currently traded pair + :return: DataFrame with sell column + """ + return self.populate_sell_trend(dataframe) diff --git a/freqtrade/strategy/resolver.py b/freqtrade/strategy/resolver.py index acb4258c1..a58389779 100644 --- a/freqtrade/strategy/resolver.py +++ b/freqtrade/strategy/resolver.py @@ -40,6 +40,8 @@ class StrategyResolver(object): self.strategy: IStrategy = self._load_strategy(strategy_name, extra_dir=config.get('strategy_path')) + self.strategy.config = config + # Set attributes # Check if we need to override configuration if 'minimal_roi' in config: diff --git a/freqtrade/tests/test_dataframe.py b/freqtrade/tests/test_dataframe.py index fd461a503..43003cb83 100644 --- a/freqtrade/tests/test_dataframe.py +++ b/freqtrade/tests/test_dataframe.py @@ -16,7 +16,7 @@ def load_dataframe_pair(pairs): dataframe = ld[pairs[0]] analyze = Analyze({'strategy': 'DefaultStrategy'}) - dataframe = analyze.analyze_ticker(dataframe) + dataframe = analyze.analyze_ticker(dataframe, pairs[0]) return dataframe