Merge pull request #2378 from freqtrade/fix/1364
Use crossed() in sample strategy
This commit is contained in:
commit
abc504412a
@ -138,15 +138,19 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
|||||||
"""
|
"""
|
||||||
dataframe.loc[
|
dataframe.loc[
|
||||||
(
|
(
|
||||||
(dataframe['adx'] > 30) &
|
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
|
||||||
(dataframe['tema'] <= dataframe['bb_middleband']) &
|
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard
|
||||||
(dataframe['tema'] > dataframe['tema'].shift(1))
|
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard
|
||||||
|
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
||||||
),
|
),
|
||||||
'buy'] = 1
|
'buy'] = 1
|
||||||
|
|
||||||
return dataframe
|
return dataframe
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
Buying requires sellers to buy from - therefore volume needs to be > 0 (`dataframe['volume'] > 0`) to make sure that the bot does not buy/sell in no-activity periods.
|
||||||
|
|
||||||
### Sell signal rules
|
### Sell signal rules
|
||||||
|
|
||||||
Edit the method `populate_sell_trend()` into your strategy file to update your sell strategy.
|
Edit the method `populate_sell_trend()` into your strategy file to update your sell strategy.
|
||||||
@ -168,9 +172,10 @@ def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame
|
|||||||
"""
|
"""
|
||||||
dataframe.loc[
|
dataframe.loc[
|
||||||
(
|
(
|
||||||
(dataframe['adx'] > 70) &
|
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
|
||||||
(dataframe['tema'] > dataframe['bb_middleband']) &
|
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard
|
||||||
(dataframe['tema'] < dataframe['tema'].shift(1))
|
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard
|
||||||
|
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
||||||
),
|
),
|
||||||
'sell'] = 1
|
'sell'] = 1
|
||||||
return dataframe
|
return dataframe
|
||||||
|
@ -39,7 +39,7 @@ def test_search_strategy():
|
|||||||
def test_load_strategy(default_conf, result):
|
def test_load_strategy(default_conf, result):
|
||||||
default_conf.update({'strategy': 'SampleStrategy'})
|
default_conf.update({'strategy': 'SampleStrategy'})
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
|
|
||||||
|
|
||||||
def test_load_strategy_base64(result, caplog, default_conf):
|
def test_load_strategy_base64(result, caplog, default_conf):
|
||||||
@ -48,7 +48,7 @@ def test_load_strategy_base64(result, caplog, default_conf):
|
|||||||
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
default_conf.update({'strategy': 'SampleStrategy:{}'.format(encoded_string)})
|
||||||
|
|
||||||
resolver = StrategyResolver(default_conf)
|
resolver = StrategyResolver(default_conf)
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'rsi' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
# Make sure strategy was loaded from base64 (using temp directory)!!
|
# Make sure strategy was loaded from base64 (using temp directory)!!
|
||||||
assert log_has_re(r"Using resolved strategy SampleStrategy from '"
|
assert log_has_re(r"Using resolved strategy SampleStrategy from '"
|
||||||
+ tempfile.gettempdir() + r"/.*/SampleStrategy\.py'\.\.\.", caplog)
|
+ tempfile.gettempdir() + r"/.*/SampleStrategy\.py'\.\.\.", caplog)
|
||||||
|
@ -34,9 +34,8 @@ class SampleStrategy(IStrategy):
|
|||||||
# Minimal ROI designed for the strategy.
|
# Minimal ROI designed for the strategy.
|
||||||
# This attribute will be overridden if the config file contains "minimal_roi".
|
# This attribute will be overridden if the config file contains "minimal_roi".
|
||||||
minimal_roi = {
|
minimal_roi = {
|
||||||
"40": 0.0,
|
"60": 0.01,
|
||||||
"30": 0.01,
|
"30": 0.02,
|
||||||
"20": 0.02,
|
|
||||||
"0": 0.04
|
"0": 0.04
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,13 +98,16 @@ class SampleStrategy(IStrategy):
|
|||||||
:return: a Dataframe with all mandatory indicators for the strategies
|
:return: a Dataframe with all mandatory indicators for the strategies
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Momentum Indicator
|
# Momentum Indicators
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
# ADX
|
# RSI
|
||||||
dataframe['adx'] = ta.ADX(dataframe)
|
dataframe['rsi'] = ta.RSI(dataframe)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
# ADX
|
||||||
|
# dataframe['adx'] = ta.ADX(dataframe)
|
||||||
|
|
||||||
# Awesome oscillator
|
# Awesome oscillator
|
||||||
dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)
|
dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)
|
||||||
|
|
||||||
@ -133,9 +135,6 @@ class SampleStrategy(IStrategy):
|
|||||||
# ROC
|
# ROC
|
||||||
dataframe['roc'] = ta.ROC(dataframe)
|
dataframe['roc'] = ta.ROC(dataframe)
|
||||||
|
|
||||||
# RSI
|
|
||||||
dataframe['rsi'] = ta.RSI(dataframe)
|
|
||||||
|
|
||||||
# Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy)
|
# Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy)
|
||||||
rsi = 0.1 * (dataframe['rsi'] - 50)
|
rsi = 0.1 * (dataframe['rsi'] - 50)
|
||||||
dataframe['fisher_rsi'] = (numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1)
|
dataframe['fisher_rsi'] = (numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1)
|
||||||
@ -255,7 +254,7 @@ class SampleStrategy(IStrategy):
|
|||||||
dataframe['ha_low'] = heikinashi['low']
|
dataframe['ha_low'] = heikinashi['low']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Retrieve best bid and best ask
|
# Retrieve best bid and best ask from the orderbook
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
"""
|
"""
|
||||||
# first check if dataprovider is available
|
# first check if dataprovider is available
|
||||||
@ -277,9 +276,9 @@ class SampleStrategy(IStrategy):
|
|||||||
"""
|
"""
|
||||||
dataframe.loc[
|
dataframe.loc[
|
||||||
(
|
(
|
||||||
(dataframe['adx'] > 30) &
|
(qtpylib.crossed_above(dataframe['rsi'], 30)) & # Signal: RSI crosses above 30
|
||||||
(dataframe['tema'] <= dataframe['bb_middleband']) &
|
(dataframe['tema'] <= dataframe['bb_middleband']) & # Guard: tema below BB middle
|
||||||
(dataframe['tema'] > dataframe['tema'].shift(1)) &
|
(dataframe['tema'] > dataframe['tema'].shift(1)) & # Guard: tema is raising
|
||||||
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
||||||
),
|
),
|
||||||
'buy'] = 1
|
'buy'] = 1
|
||||||
@ -295,9 +294,9 @@ class SampleStrategy(IStrategy):
|
|||||||
"""
|
"""
|
||||||
dataframe.loc[
|
dataframe.loc[
|
||||||
(
|
(
|
||||||
(dataframe['adx'] > 70) &
|
(qtpylib.crossed_above(dataframe['rsi'], 70)) & # Signal: RSI crosses above 70
|
||||||
(dataframe['tema'] > dataframe['bb_middleband']) &
|
(dataframe['tema'] > dataframe['bb_middleband']) & # Guard: tema above BB middle
|
||||||
(dataframe['tema'] < dataframe['tema'].shift(1)) &
|
(dataframe['tema'] < dataframe['tema'].shift(1)) & # Guard: tema is falling
|
||||||
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
(dataframe['volume'] > 0) # Make sure Volume is not 0
|
||||||
),
|
),
|
||||||
'sell'] = 1
|
'sell'] = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user