Strategy002 added
This commit is contained in:
parent
4996bd443e
commit
39458d1db8
@ -888,7 +888,7 @@ def test_api_whitelist(botclient):
|
||||
"whitelist": ['ETH/BTC', 'LTC/BTC', 'XRP/BTC', 'NEO/BTC'],
|
||||
"length": 4,
|
||||
"method": ["StaticPairList"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_api_forcebuy(botclient, mocker, fee):
|
||||
@ -980,7 +980,7 @@ def test_api_forcebuy(botclient, mocker, fee):
|
||||
'strategy': 'DefaultStrategy',
|
||||
'timeframe': 5,
|
||||
'exchange': 'bittrex',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_api_forcesell(botclient, mocker, ticker, fee, markets):
|
||||
@ -1150,8 +1150,9 @@ def test_api_strategies(botclient):
|
||||
assert rc.json() == {'strategies': [
|
||||
'DefaultStrategy',
|
||||
'HyperoptableStrategy',
|
||||
'Strategy002',
|
||||
'TestStrategyLegacy'
|
||||
]}
|
||||
]}
|
||||
|
||||
|
||||
def test_api_strategy(botclient):
|
||||
|
135
tests/strategy/strats/Strategy002.py
Normal file
135
tests/strategy/strats/Strategy002.py
Normal file
@ -0,0 +1,135 @@
|
||||
|
||||
# --- Do not remove these libs ---
|
||||
from freqtrade.strategy.interface import IStrategy
|
||||
from typing import Dict, List
|
||||
from functools import reduce
|
||||
from pandas import DataFrame
|
||||
# --------------------------------
|
||||
|
||||
import talib.abstract as ta
|
||||
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||
import numpy # noqa
|
||||
|
||||
|
||||
class Strategy002(IStrategy):
|
||||
"""
|
||||
Strategy 002
|
||||
author@: Gerald Lonlas
|
||||
github@: https://github.com/freqtrade/freqtrade-strategies
|
||||
|
||||
How to use it?
|
||||
> python3 ./freqtrade/main.py -s Strategy002
|
||||
"""
|
||||
|
||||
# Minimal ROI designed for the strategy.
|
||||
# This attribute will be overridden if the config file contains "minimal_roi"
|
||||
minimal_roi = {
|
||||
"60": 0.01,
|
||||
"30": 0.03,
|
||||
"20": 0.04,
|
||||
"0": 0.05
|
||||
}
|
||||
|
||||
# Optimal stoploss designed for the strategy
|
||||
# This attribute will be overridden if the config file contains "stoploss"
|
||||
stoploss = -0.10
|
||||
|
||||
# Optimal timeframe for the strategy
|
||||
timeframe = '5m'
|
||||
|
||||
# trailing stoploss
|
||||
trailing_stop = False
|
||||
trailing_stop_positive = 0.01
|
||||
trailing_stop_positive_offset = 0.02
|
||||
|
||||
# run "populate_indicators" only for new candle
|
||||
process_only_new_candles = False
|
||||
|
||||
# Experimental settings (configuration will overide these if set)
|
||||
use_sell_signal = True
|
||||
sell_profit_only = True
|
||||
ignore_roi_if_buy_signal = False
|
||||
|
||||
# Optional order type mapping
|
||||
order_types = {
|
||||
'buy': 'limit',
|
||||
'sell': 'limit',
|
||||
'stoploss': 'market',
|
||||
'stoploss_on_exchange': False
|
||||
}
|
||||
|
||||
def informative_pairs(self):
|
||||
"""
|
||||
Define additional, informative pair/interval combinations to be cached from the exchange.
|
||||
These pair/interval combinations are non-tradeable, unless they are part
|
||||
of the whitelist as well.
|
||||
For more information, please consult the documentation
|
||||
:return: List of tuples in the format (pair, interval)
|
||||
"""
|
||||
return [
|
||||
("ETH/USDT", "15m"),
|
||||
("BTC/USDT", "5m"),
|
||||
]
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
"""
|
||||
Adds several different TA indicators to the given DataFrame
|
||||
|
||||
Performance Note: For the best performance be frugal on the number of indicators
|
||||
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.
|
||||
"""
|
||||
|
||||
# Stoch
|
||||
stoch = ta.STOCH(dataframe)
|
||||
dataframe['slowk'] = stoch['slowk']
|
||||
|
||||
# RSI
|
||||
dataframe['rsi'] = ta.RSI(dataframe)
|
||||
|
||||
# Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy)
|
||||
rsi = 0.1 * (dataframe['rsi'] - 50)
|
||||
dataframe['fisher_rsi'] = (numpy.exp(2 * rsi) - 1) / (numpy.exp(2 * rsi) + 1)
|
||||
|
||||
# Bollinger bands
|
||||
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
|
||||
dataframe['bb_lowerband'] = bollinger['lower']
|
||||
|
||||
# SAR Parabol
|
||||
dataframe['sar'] = ta.SAR(dataframe)
|
||||
|
||||
# Hammer: values [0, 100]
|
||||
dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the buy signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['rsi'] < 30) &
|
||||
(dataframe['slowk'] < 20) &
|
||||
(dataframe['bb_lowerband'] > dataframe['close']) &
|
||||
(dataframe['CDLHAMMER'] == 100)
|
||||
),
|
||||
'buy'] = 1
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
"""
|
||||
Based on TA indicators, populates the sell signal for the given dataframe
|
||||
:param dataframe: DataFrame
|
||||
:return: DataFrame with buy column
|
||||
"""
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['sar'] > dataframe['close']) &
|
||||
(dataframe['fisher_rsi'] > 0.3)
|
||||
),
|
||||
'sell'] = 1
|
||||
return dataframe
|
@ -35,7 +35,7 @@ def test_search_all_strategies_no_failed():
|
||||
directory = Path(__file__).parent / "strats"
|
||||
strategies = StrategyResolver.search_all_objects(directory, enum_failed=False)
|
||||
assert isinstance(strategies, list)
|
||||
assert len(strategies) == 3
|
||||
assert len(strategies) == 4
|
||||
assert isinstance(strategies[0], dict)
|
||||
|
||||
|
||||
@ -43,10 +43,10 @@ def test_search_all_strategies_with_failed():
|
||||
directory = Path(__file__).parent / "strats"
|
||||
strategies = StrategyResolver.search_all_objects(directory, enum_failed=True)
|
||||
assert isinstance(strategies, list)
|
||||
assert len(strategies) == 4
|
||||
assert len(strategies) == 5
|
||||
# with enum_failed=True search_all_objects() shall find 2 good strategies
|
||||
# and 1 which fails to load
|
||||
assert len([x for x in strategies if x['class'] is not None]) == 3
|
||||
assert len([x for x in strategies if x['class'] is not None]) == 4
|
||||
assert len([x for x in strategies if x['class'] is None]) == 1
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user