海龟原版:日线 20日突破 + 2ATR止损 + 10日反向出场
Timeframe
1d
Direction
Long & Short
Stoploss
-6.0%
Trailing Stop
No
ROI
0m: 30.0%, 720m: 15.0%, 2160m: 8.0%, 4320m: 0.0%
Interface Version
3
Startup Candles
60
Indicators
11
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
"""
Classic strategies v2 — each on its ORIGINAL recommended timeframe
Turtle: 1d | Donchian: 4h | RSI-Larry: 15m (scalping) | Bollinger: 1h |
Dual Thrust: 1h | Keltner: 1h | ParaSAR: 1h
"""
from pandas import DataFrame
import talib.abstract as ta
import numpy as np
from freqtrade.strategy import IStrategy
class Turtle1d(IStrategy):
"""海龟原版:日线 20日突破 + 2ATR止损 + 10日反向出场"""
INTERFACE_VERSION=3;timeframe='1d';can_short=True
stoploss=-0.06;trailing_stop=False
minimal_roi={"0":0.30,"720":0.15,"2160":0.08,"4320":0}
max_open_trades=3;startup_candle_count=60
process_only_new_candles=True;use_exit_signal=True
def populate_indicators(self,d,m):
d['dc_u']=d['high'].rolling(20).max().shift(1);d['dc_l']=d['low'].rolling(20).min().shift(1)
d['ex_u']=d['high'].rolling(10).max().shift(1);d['ex_l']=d['low'].rolling(10).min().shift(1)
d['atr']=ta.ATR(d,20);d['e20']=ta.EMA(d,20);d['e50']=ta.EMA(d,50)
return d
def populate_entry_trend(self,d,m):
d.loc[(d['close']>d['dc_u'])&(d['e20']>d['e50'])&(d['volume']>0),['enter_long','enter_tag']]=(1,'TL')
d.loc[(d['close']<d['dc_l'])&(d['e20']<d['e50'])&(d['volume']>0),['enter_short','enter_tag']]=(1,'TS')
return d
def populate_exit_trend(self,d,m):
d.loc[d['close']<d['ex_l'],['exit_long','exit_tag']]=(1,'EX')
d.loc[d['close']>d['ex_u'],['exit_short','exit_tag']]=(1,'EX')
return d
class Donchian4h(IStrategy):
"""唐奇安:4h 20周期突破 + ADX>25"""
INTERFACE_VERSION=3;timeframe='4h';can_short=True
stoploss=-0.035;trailing_stop=True;trailing_stop_positive=0.015;trailing_stop_positive_offset=0.03
trailing_only_offset_is_reached=True
minimal_roi={"0":0.10,"480":0.06,"1440":0.035,"2880":0}
max_open_trades=4;startup_candle_count=80
process_only_new_candles=True;use_exit_signal=False
def populate_indicators(self,d,m):
d['dc_h']=d['high'].rolling(20).max().shift(1);d['dc_l']=d['low'].rolling(20).min().shift(1)
d['adx']=ta.ADX(d,14);d['vr']=d['volume']/ta.SMA(d['volume'],20)
return d
def populate_entry_trend(self,d,m):
d.loc[(d['close']>d['dc_h'])&(d['adx']>25)&(d['vr']>1.2)&(d['volume']>0),['enter_long','enter_tag']]=(1,'L')
d.loc[(d['close']<d['dc_l'])&(d['adx']>25)&(d['vr']>1.2)&(d['volume']>0),['enter_short','enter_tag']]=(1,'S')
return d
def populate_exit_trend(self,d,m):return d
class Bollinger1h(IStrategy):
"""布林带均值回归:1h 2.5σ + RSI极端 + Stoch反转"""
INTERFACE_VERSION=3;timeframe='1h';can_short=True
stoploss=-0.03;trailing_stop=True;trailing_stop_positive=0.012;trailing_stop_positive_offset=0.022
trailing_only_offset_is_reached=True
minimal_roi={"0":0.06,"480":0.04,"1440":0.025,"2880":0}
max_open_trades=4;startup_candle_count=60
process_only_new_candles=True;use_exit_signal=True
def populate_indicators(self,d,m):
bb=ta.BBANDS(d,20,2.5,2.5);d['bu']=bb['upperband'];d['bl']=bb['lowerband'];d['bm']=bb['middleband']
d['bp']=(d['close']-d['bl'])/(d['bu']-d['bl']+1e-6);d['rsi']=ta.RSI(d,14)
st=ta.STOCH(d);d['sk']=st['slowk'];d['sd']=st['slowd'];d['vr']=d['volume']/ta.SMA(d['volume'],20)
return d
def populate_entry_trend(self,d,m):
d.loc[(d['bp']<0.05)&(d['rsi']<30)&(d['sk']>d['sd'])&(d['vr']>1.2)&(d['volume']>0),['enter_long','enter_tag']]=(1,'L')
d.loc[(d['bp']>0.95)&(d['rsi']>70)&(d['sk']<d['sd'])&(d['vr']>1.2)&(d['volume']>0),['enter_short','enter_tag']]=(1,'S')
return d
def populate_exit_trend(self,d,m):
d.loc[d['bp']>0.5,['exit_long','exit_tag']]=(1,'E')
d.loc[d['bp']<0.5,['exit_short','exit_tag']]=(1,'E')
return d
class DualThrust1h(IStrategy):
"""Dual Thrust:1h 4周期区间突破 + ADX"""
INTERFACE_VERSION=3;timeframe='1h';can_short=True
stoploss=-0.025;trailing_stop=True;trailing_stop_positive=0.01;trailing_stop_positive_offset=0.02
trailing_only_offset_is_reached=True
minimal_roi={"0":0.06,"480":0.04,"1440":0.025,"2880":0}
max_open_trades=4;startup_candle_count=60
process_only_new_candles=True;use_exit_signal=False
def populate_indicators(self,d,m):
n=4;k1=k2=0.5
d['hh']=d['high'].rolling(n).max();d['hc']=d['close'].rolling(n).max()
d['lc']=d['close'].rolling(n).min();d['ll']=d['low'].rolling(n).min()
d['range']=np.maximum(d['hh']-d['lc'],d['hc']-d['ll'])
d['up']=d['open']+k1*d['range'].shift(1);d['dn']=d['open']-k2*d['range'].shift(1)
d['adx']=ta.ADX(d,14);d['vr']=d['volume']/ta.SMA(d['volume'],20)
return d
def populate_entry_trend(self,d,m):
d.loc[(d['close']>d['up'])&(d['adx']>20)&(d['vr']>1.1)&(d['volume']>0),['enter_long','enter_tag']]=(1,'L')
d.loc[(d['close']<d['dn'])&(d['adx']>20)&(d['vr']>1.1)&(d['volume']>0),['enter_short','enter_tag']]=(1,'S')
return d
def populate_exit_trend(self,d,m):return d
class Keltner1h(IStrategy):
"""Keltner Squeeze:1h BB vs KC挤压突破"""
INTERFACE_VERSION=3;timeframe='1h';can_short=True
stoploss=-0.03;trailing_stop=True;trailing_stop_positive=0.012;trailing_stop_positive_offset=0.022
trailing_only_offset_is_reached=True
minimal_roi={"0":0.06,"480":0.04,"1440":0.025,"2880":0}
max_open_trades=4;startup_candle_count=60
process_only_new_candles=True;use_exit_signal=False
def populate_indicators(self,d,m):
d['kc_m']=ta.EMA(d,20);d['atr']=ta.ATR(d,10)
d['kc_u']=d['kc_m']+1.5*d['atr'];d['kc_l']=d['kc_m']-1.5*d['atr']
bb=ta.BBANDS(d,20);d['bb_u']=bb['upperband'];d['bb_l']=bb['lowerband']
d['sq']=(d['bb_u']<d['kc_u'])&(d['bb_l']>d['kc_l'])
d['vr']=d['volume']/ta.SMA(d['volume'],20);d['mom']=ta.ROC(d,3)
return d
def populate_entry_trend(self,d,m):
fire=(~d['sq'])&d['sq'].shift(1)
d.loc[fire&(d['close']>d['kc_u'])&(d['mom']>0)&(d['volume']>0),['enter_long','enter_tag']]=(1,'L')
d.loc[fire&(d['close']<d['kc_l'])&(d['mom']<0)&(d['volume']>0),['enter_short','enter_tag']]=(1,'S')
return d
def populate_exit_trend(self,d,m):return d
class ParaSAR1h(IStrategy):
"""Parabolic SAR:1h + ADX>22 过滤"""
INTERFACE_VERSION=3;timeframe='1h';can_short=True
stoploss=-0.04;trailing_stop=True;trailing_stop_positive=0.015;trailing_stop_positive_offset=0.03
trailing_only_offset_is_reached=True
minimal_roi={"0":0.08,"480":0.05,"1440":0.03,"2880":0}
max_open_trades=4;startup_candle_count=60
process_only_new_candles=True;use_exit_signal=True
def populate_indicators(self,d,m):
d['sar']=ta.SAR(d,0.02,0.2);d['adx']=ta.ADX(d,14)
d['e20']=ta.EMA(d,20);d['vr']=d['volume']/ta.SMA(d['volume'],20)
return d
def populate_entry_trend(self,d,m):
d.loc[(d['sar']<d['close'])&(d['adx']>22)&(d['close']>d['e20'])&(d['volume']>0),['enter_long','enter_tag']]=(1,'L')
d.loc[(d['sar']>d['close'])&(d['adx']>22)&(d['close']<d['e20'])&(d['volume']>0),['enter_short','enter_tag']]=(1,'S')
return d
def populate_exit_trend(self,d,m):
d.loc[d['sar']>d['close'],['exit_long','exit_tag']]=(1,'E')
d.loc[d['sar']<d['close'],['exit_short','exit_tag']]=(1,'E')
return d