Adding the pair name when populating indicators allowing the strategy to have customized context for a pair

This commit is contained in:
Jean-Baptiste LE STANG 2018-01-30 15:03:38 +01:00
parent 5f86c389b0
commit 26e288e655
14 changed files with 46 additions and 46 deletions

View File

@ -51,7 +51,7 @@ update your buy strategy.
Sample from `user_data/strategies/test_strategy.py`: Sample from `user_data/strategies/test_strategy.py`:
```python ```python
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair : str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
@ -74,7 +74,7 @@ update your sell strategy.
Sample from `user_data/strategies/test_strategy.py`: Sample from `user_data/strategies/test_strategy.py`:
```python ```python
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, pair : str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
@ -97,7 +97,7 @@ the method `populate_indicators()` from your strategy file.
Sample: Sample:
```python ```python
def populate_indicators(dataframe: DataFrame) -> DataFrame: def populate_indicators(dataframe: DataFrame, pair : str) -> DataFrame:
""" """
Adds several different TA indicators to the given DataFrame Adds several different TA indicators to the given DataFrame
""" """

View File

@ -42,7 +42,7 @@ If you have updated the buy strategy, means change the content of
As for an example if your `populate_buy_trend()` method is: As for an example if your `populate_buy_trend()` method is:
```python ```python
def populate_buy_trend(dataframe: DataFrame) -> DataFrame: def populate_buy_trend(dataframe: DataFrame, pair: str) -> DataFrame:
dataframe.loc[ dataframe.loc[
(dataframe['rsi'] < 35) & (dataframe['rsi'] < 35) &
(dataframe['adx'] > 65), (dataframe['adx'] > 65),
@ -81,7 +81,7 @@ space = {
... ...
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
conditions = [] conditions = []
# GUARDS AND TRENDS # GUARDS AND TRENDS
if params['adx']['enabled']: if params['adx']['enabled']:
@ -280,7 +280,7 @@ at `adx`-block, that translates to the following code block:
So translating your whole hyperopt result to as the new buy-signal So translating your whole hyperopt result to as the new buy-signal
would be the following: would be the following:
``` ```
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
dataframe.loc[ dataframe.loc[
( (
(dataframe['adx'] > 15.0) & # adx-value (dataframe['adx'] > 15.0) & # adx-value

View File

@ -37,7 +37,7 @@ def parse_ticker_dataframe(ticker: list) -> DataFrame:
return frame return frame
def populate_indicators(dataframe: DataFrame) -> DataFrame: def populate_indicators(dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Adds several different TA indicators to the given DataFrame Adds several different TA indicators to the given DataFrame
@ -46,39 +46,39 @@ def populate_indicators(dataframe: DataFrame) -> DataFrame:
or your hyperopt configuration, otherwise you will waste your memory and CPU usage. or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
""" """
strategy = Strategy() strategy = Strategy()
return strategy.populate_indicators(dataframe=dataframe) return strategy.populate_indicators(dataframe=dataframe, pair=pair)
def populate_buy_trend(dataframe: DataFrame) -> DataFrame: def populate_buy_trend(dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
:return: DataFrame with buy column :return: DataFrame with buy column
""" """
strategy = Strategy() strategy = Strategy()
return strategy.populate_buy_trend(dataframe=dataframe) return strategy.populate_buy_trend(dataframe=dataframe, pair=pair)
def populate_sell_trend(dataframe: DataFrame) -> DataFrame: def populate_sell_trend(dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
:return: DataFrame with buy column :return: DataFrame with buy column
""" """
strategy = Strategy() strategy = Strategy()
return strategy.populate_sell_trend(dataframe=dataframe) return strategy.populate_sell_trend(dataframe=dataframe, pair=pair)
def analyze_ticker(ticker_history: List[Dict]) -> DataFrame: def analyze_ticker(ticker_history: List[Dict], pair: str) -> DataFrame:
""" """
Parses the given ticker history and returns a populated DataFrame Parses the given ticker history and returns a populated DataFrame
add several TA indicators and buy signal to it add several TA indicators and buy signal to it
:return DataFrame with ticker data and indicator data :return DataFrame with ticker data and indicator data
""" """
dataframe = parse_ticker_dataframe(ticker_history) dataframe = parse_ticker_dataframe(ticker_history)
dataframe = populate_indicators(dataframe) dataframe = populate_indicators(dataframe, pair)
dataframe = populate_buy_trend(dataframe) dataframe = populate_buy_trend(dataframe, pair)
dataframe = populate_sell_trend(dataframe) dataframe = populate_sell_trend(dataframe, pair)
return dataframe return dataframe
@ -96,7 +96,7 @@ def get_signal(pair: str, interval: int) -> (bool, bool):
return (False, False) # return False ? return (False, False) # return False ?
try: try:
dataframe = analyze_ticker(ticker_hist) dataframe = analyze_ticker(ticker_hist, pair)
except ValueError as ex: except ValueError as ex:
logger.warning('Unable to analyze ticker for pair %s: %s', pair, str(ex)) logger.warning('Unable to analyze ticker for pair %s: %s', pair, str(ex))
return (False, False) # return False ? return (False, False) # return False ?

View File

@ -91,7 +91,7 @@ def tickerdata_to_dataframe(data):
def preprocess(tickerdata: Dict[str, List]) -> Dict[str, DataFrame]: def preprocess(tickerdata: Dict[str, List]) -> Dict[str, DataFrame]:
"""Creates a dataframe and populates indicators for given ticker data""" """Creates a dataframe and populates indicators for given ticker data"""
return {pair: populate_indicators(parse_ticker_dataframe(pair_data)) return {pair: populate_indicators(parse_ticker_dataframe(pair_data), pair)
for pair, pair_data in tickerdata.items()} for pair, pair_data in tickerdata.items()}

View File

@ -117,7 +117,7 @@ def backtest(args) -> DataFrame:
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
for pair, pair_data in processed.items(): for pair, pair_data in processed.items():
pair_data['buy'], pair_data['sell'] = 0, 0 pair_data['buy'], pair_data['sell'] = 0, 0
ticker = populate_sell_trend(populate_buy_trend(pair_data)) ticker = populate_sell_trend(populate_buy_trend(pair_data, pair), pair)
# for each buy point # for each buy point
lock_pair_until = None lock_pair_until = None
headers = ['buy', 'open', 'close', 'date', 'sell'] headers = ['buy', 'open', 'close', 'date', 'sell']

View File

@ -61,7 +61,7 @@ TRIALS = Trials()
main._CONF = OPTIMIZE_CONFIG main._CONF = OPTIMIZE_CONFIG
def populate_indicators(dataframe: DataFrame) -> DataFrame: def populate_indicators(dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Adds several different TA indicators to the given DataFrame Adds several different TA indicators to the given DataFrame
""" """
@ -320,7 +320,7 @@ def buy_strategy_generator(params: Dict[str, Any]) -> Callable:
""" """
Define the buy strategy parameters to be used by hyperopt Define the buy strategy parameters to be used by hyperopt
""" """
def populate_buy_trend(dataframe: DataFrame) -> DataFrame: def populate_buy_trend(dataframe: DataFrame, pair: str) -> DataFrame:
conditions = [] conditions = []
# GUARDS AND TRENDS # GUARDS AND TRENDS
if 'uptrend_long_ema' in params and params['uptrend_long_ema']['enabled']: if 'uptrend_long_ema' in params and params['uptrend_long_ema']['enabled']:

View File

@ -29,7 +29,7 @@ class DefaultStrategy(IStrategy):
# Optimal ticker interval for the strategy # Optimal ticker interval for the strategy
ticker_interval = 5 ticker_interval = 5
def populate_indicators(self, dataframe: DataFrame) -> DataFrame: def populate_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Adds several different TA indicators to the given DataFrame Adds several different TA indicators to the given DataFrame
@ -196,7 +196,7 @@ class DefaultStrategy(IStrategy):
return dataframe return dataframe
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
@ -217,7 +217,7 @@ class DefaultStrategy(IStrategy):
return dataframe return dataframe
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame

View File

@ -19,7 +19,7 @@ class IStrategy(ABC):
""" """
@abstractmethod @abstractmethod
def populate_indicators(self, dataframe: DataFrame) -> DataFrame: def populate_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Populate indicators that will be used in the Buy and Sell strategy 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 dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
@ -27,7 +27,7 @@ class IStrategy(ABC):
""" """
@abstractmethod @abstractmethod
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
@ -36,7 +36,7 @@ class IStrategy(ABC):
""" """
@abstractmethod @abstractmethod
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame

View File

@ -143,27 +143,27 @@ class Strategy(object):
return path return path
def populate_indicators(self, dataframe: DataFrame) -> DataFrame: def populate_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Populate indicators that will be used in the Buy and Sell strategy 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 dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
:return: a Dataframe with all mandatory indicators for the strategies :return: a Dataframe with all mandatory indicators for the strategies
""" """
return self.custom_strategy.populate_indicators(dataframe) return self.custom_strategy.populate_indicators(dataframe, pair)
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
:return: DataFrame with buy column :return: DataFrame with buy column
:return: :return:
""" """
return self.custom_strategy.populate_buy_trend(dataframe) return self.custom_strategy.populate_buy_trend(dataframe, pair)
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
:return: DataFrame with buy column :return: DataFrame with buy column
""" """
return self.custom_strategy.populate_sell_trend(dataframe) return self.custom_strategy.populate_sell_trend(dataframe, pair)

View File

@ -30,7 +30,7 @@ def test_default_strategy(result):
assert type(strategy.minimal_roi) is dict assert type(strategy.minimal_roi) is dict
assert type(strategy.stoploss) is float assert type(strategy.stoploss) is float
assert type(strategy.ticker_interval) is int assert type(strategy.ticker_interval) is int
indicators = strategy.populate_indicators(result) indicators = strategy.populate_indicators(result, None)
assert type(indicators) is DataFrame assert type(indicators) is DataFrame
assert type(strategy.populate_buy_trend(indicators)) is DataFrame assert type(strategy.populate_buy_trend(indicators, None)) is DataFrame
assert type(strategy.populate_sell_trend(indicators)) is DataFrame assert type(strategy.populate_sell_trend(indicators, None)) is DataFrame

View File

@ -37,7 +37,7 @@ def test_load_strategy(result):
assert not hasattr(Strategy, 'custom_strategy') assert not hasattr(Strategy, 'custom_strategy')
assert hasattr(strategy.custom_strategy, 'populate_indicators') assert hasattr(strategy.custom_strategy, 'populate_indicators')
assert 'adx' in strategy.populate_indicators(result) assert 'adx' in strategy.populate_indicators(result, None)
def test_strategy(result): def test_strategy(result):
@ -51,14 +51,14 @@ def test_strategy(result):
assert strategy.stoploss == -0.10 assert strategy.stoploss == -0.10
assert hasattr(strategy.custom_strategy, 'populate_indicators') assert hasattr(strategy.custom_strategy, 'populate_indicators')
assert 'adx' in strategy.populate_indicators(result) assert 'adx' in strategy.populate_indicators(result, None)
assert hasattr(strategy.custom_strategy, 'populate_buy_trend') assert hasattr(strategy.custom_strategy, 'populate_buy_trend')
dataframe = strategy.populate_buy_trend(strategy.populate_indicators(result)) dataframe = strategy.populate_buy_trend(strategy.populate_indicators(result, None), None)
assert 'buy' in dataframe.columns assert 'buy' in dataframe.columns
assert hasattr(strategy.custom_strategy, 'populate_sell_trend') assert hasattr(strategy.custom_strategy, 'populate_sell_trend')
dataframe = strategy.populate_sell_trend(strategy.populate_indicators(result)) dataframe = strategy.populate_sell_trend(strategy.populate_indicators(result, None), None)
assert 'sell' in dataframe.columns assert 'sell' in dataframe.columns

View File

@ -26,7 +26,7 @@ def test_populates_buy_trend(result):
# Load the default strategy for the unit test, because this logic is done in main.py # Load the default strategy for the unit test, because this logic is done in main.py
Strategy().init({'strategy': 'default_strategy'}) Strategy().init({'strategy': 'default_strategy'})
dataframe = populate_buy_trend(populate_indicators(result)) dataframe = populate_buy_trend(populate_indicators(result, None), None)
assert 'buy' in dataframe.columns assert 'buy' in dataframe.columns
@ -34,7 +34,7 @@ def test_populates_sell_trend(result):
# Load the default strategy for the unit test, because this logic is done in main.py # Load the default strategy for the unit test, because this logic is done in main.py
Strategy().init({'strategy': 'default_strategy'}) Strategy().init({'strategy': 'default_strategy'})
dataframe = populate_sell_trend(populate_indicators(result)) dataframe = populate_sell_trend(populate_indicators(result, None), None)
assert 'sell' in dataframe.columns assert 'sell' in dataframe.columns

View File

@ -12,7 +12,7 @@ def load_dataframe_pair(pairs):
assert isinstance(ld, dict) assert isinstance(ld, dict)
assert isinstance(pairs[0], str) assert isinstance(pairs[0], str)
dataframe = ld[pairs[0]] dataframe = ld[pairs[0]]
dataframe = analyze.analyze_ticker(dataframe) dataframe = analyze.analyze_ticker(dataframe, pairs[0])
return dataframe return dataframe

View File

@ -47,7 +47,7 @@ class TestStrategy(IStrategy):
# Optimal ticker interval for the strategy # Optimal ticker interval for the strategy
ticker_interval = 5 ticker_interval = 5
def populate_indicators(self, dataframe: DataFrame) -> DataFrame: def populate_indicators(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Adds several different TA indicators to the given DataFrame Adds several different TA indicators to the given DataFrame
@ -214,7 +214,7 @@ class TestStrategy(IStrategy):
return dataframe return dataframe
def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame: def populate_buy_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the buy signal for the given dataframe Based on TA indicators, populates the buy signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame
@ -230,7 +230,7 @@ class TestStrategy(IStrategy):
return dataframe return dataframe
def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, pair: str) -> DataFrame:
""" """
Based on TA indicators, populates the sell signal for the given dataframe Based on TA indicators, populates the sell signal for the given dataframe
:param dataframe: DataFrame :param dataframe: DataFrame