def __init__(self): self.wrs = WickReversalSignal() self.frs = FadeReversalSignal() self.lines.wick = self.wrs.lines.wick self.lines.fade = self.frs.lines.fade self.lines.any = bt.If( abs(self.lines.wick) > 0, self.lines.wick, bt.If(abs(self.lines.fade) > 0, self.lines.fade, np.NaN))
def __init__(self): std = bt.ind.StandardDeviation(self.data, period=self.p.std_period) pos = bt.If(self.data.close > self.data.close(-1), std, 0) neg = bt.If(self.data.close < self.data.close(-1), std, 0) usum = bt.ind.SumN(pos, period=self.p.std_period) dsum = bt.ind.SumN(neg, period=self.p.std_period) uavg = bt.ind.ExponentialMovingAverage(usum, period=self.p.ema_period) davg = bt.ind.ExponentialMovingAverage(dsum, period=self.p.ema_period) self.l.rvi = bt.ind.DivByZero(uavg, (uavg + davg)) * 100
def __init__(self): self.jxmj = JXMJIndicator(self.data) self.l.State = bt.If(self.jxmj.l.JXMJ == 1, 1, self.l.State) self.l.priceIntense = bt.If(self.jxmj.l.priceIntense == 1, 0.7, float('nan')) self.l.natrIntense = bt.If(self.jxmj.l.natrIntense == 1, 0.4, float('nan')) self.l.bollIntense = bt.If(self.jxmj.l.bollIntense == 1, 0.1, float('nan'))
def __init__(self): # Plot horizontal Line self.l.macd = bt.indicators.MACD(self.data,period_me1=self.p.fast,period_me2=self.p.slow).macd boll = bt.indicators.BollingerBands(self.data,period=self.p.channel, devfactor=self.p.mult) t1 = (self.l.macd(0)-self.l.macd(-1))*self.p.sensitivity self.l.exp = boll.top - boll.bot self.l.utrend = bt.If(t1 >= 0, t1, 0.0) self.l.dtrend = bt.If(t1 < 0, -1.0*t1, 0.0) self.l.dead = bt.indicators.AverageTrueRange(self.data,period=50).atr*self.p.dead
def __init__(self): atr = bt.indicators.AverageTrueRange(period=self.p.lookback_period) change = self.data.close - self.data.open body_multiplier = (change / atr) body_up_trig = body_multiplier(-1) > self.p.body_multiplier_min body_dn_trig = body_multiplier(-1) < -self.p.body_multiplier_min body_size = abs(change) / (self.data.high - self.data.low) * 100.0 fits_min = body_size > self.p.body_percent_min fits_max = body_size < self.p.body_percent_max fits = bt.And(fits_min, fits_max) precheck_dn = bt.And(body_up_trig, fits) precheck_up = bt.And(body_dn_trig, fits) r_dn = bt.And(precheck_dn, self.data.close < self.data.close(-1)) r_up = bt.And(precheck_up, self.data.close > self.data.close(-1)) self.lines.fade = bt.If(r_dn, self.data.high, bt.If(r_up, self.data.low, np.NaN))
def __init__(self): self.sma5 = btind.SimpleMovingAverage(period=5) # 5日均线 self.sma10 = btind.SimpleMovingAverage(period=10) # 10日均线 # bt.And 中所有条件都满足时返回 1;有一个条件不满足就返回 0 self.And = bt.And(self.data > self.sma5, self.data > self.sma10, self.sma5 > self.sma10) # bt.Or 中有一个条件满足时就返回 1;所有条件都不满足时返回 0 self.Or = bt.Or(self.data > self.sma5, self.data > self.sma10, self.sma5 > self.sma10) # bt.If(a, b, c) 如果满足条件 a,就返回 b,否则返回 c self.If = bt.If(self.data > self.sma5, 1000, 5000) # bt.All,同 bt.And self.All = bt.All(self.data > self.sma5, self.data > self.sma10, self.sma5 > self.sma10) # bt.Any,同 bt.Or self.Any = bt.Any(self.data > self.sma5, self.data > self.sma10, self.sma5 > self.sma10) # bt.Max,返回同一时刻所有指标中的最大值 self.Max = bt.Max(self.data, self.sma10, self.sma5) # bt.Min,返回同一时刻所有指标中的最小值 self.Min = bt.Min(self.data, self.sma10, self.sma5) # bt.Sum,对同一时刻所有指标进行求和 self.Sum = bt.Sum(self.data, self.sma10, self.sma5) # bt.Cmp(a,b), 如果 a>b ,返回 1;否则返回 -1 self.Cmp = bt.Cmp(self.data, self.sma5)
def __init__(self): """ Creates a breakout alert indicator using trend and wick source indicators """ self.trendSrc = self.p.trend_src(self.data) self.adSrc = self.p.ad_src(self.data) self.distribution = bt.If(self.trendSrc.lines.trend > 0, self.adSrc.lines.wick < 0, np.NaN) self.accumulation = bt.If(self.trendSrc.lines.trend < 0, self.adSrc.lines.wick > 0, np.NaN) # pass thru the relevant lines from the sources self.lines.trend = self.trendSrc.lines.trend self.lines.stop = self.trendSrc.lines.stop self.lines.ad = self.adSrc.lines.wick
def __init__(self): sma = btind.SimpleMovingAverage(period=self.p.smaperiod) sma1 = btind.SimpleMovingAverage(self.data, period=self.params.period1) sma2 = btind.SimpleMovingAverage(period=self.params.period2) myindicator = sma2 - sma1 + self.datas[0].close self.sma = btind.SimpleMovingAverage(period=self.p.period) # see the (delay) notation self.cmpval = self.data.close(-1) > self.sma datasum = btind.SumN(self.data, period=self.p.period1) # using operators / av = datasum / self.p.period1 self.line.sma = av # cannot use "and" operators, backtrader provides several methods close_over_sma = self.data.close > sma self.sma_dist_to_high = self.data.high - sma sma_dist_small = self.sma_dist_to_high < 3.5 sell_sig = bt.And(close_over_sma, sma_dist_small) high_or_low = bt.If(sma1 > self.data.close, self.data.low, self.data.high) self.buysell = btind.CrossOver(self.data.close, sma, plot=True) self.order = None
def next(self): #self.outside_high = self.data.high[0] > self.data.high[-int(self.p.ref)] #self.outside_low = self.data.low[0] < self.data.low[-int(self.p.ref)] #if self.outside_high and self.outside_low: self.outside = bt.If(self.outside_high and self.outside_low, 1, 0)
def __init__(self): self.plotinfo.plotyhlines = [0] self.addminperiod(55) self.data.hlc3 = (self.data.high + self.data.low + self.data.close) / 3 # This works - Note indexing should be () rather than [] # See: https://www.backtrader.com/docu/concepts.html#lines-delayed-indexing self.data.sv = bt.If((self.data.hlc3(0) - self.data.hlc3(-1)) / self.data.hlc3(-1) >= 0, self.data.volume, -self.data.volume) self.lines.kvo = bt.indicators.EMA(self.data.sv, period=self.p.fast) - bt.indicators.EMA(self.data.sv, period=self.p.slow) self.lines.sig = bt.indicators.EMA(self.lines.kvo, period=self.p.signal)
def __init__(self): wick_range = self.data.high - self.data.low body_high = bt.Max(self.data.close, self.data.open) body_low = bt.Min(self.data.close, self.data.open) body_range = body_high - body_low wick_buy = (body_low - self.data.low) >= ( self.p.wick_multiplier_min * body_range) wick_sell = (self.data.high - body_high) >= ( self.p.wick_multiplier_min * body_range) # be careful, if wick range = 0 then close-low = 0 ; so avoiding divide # by zero list this is correct close_percent = (self.data.close - self.data.low) / bt.If( wick_range == 0.0, 0.1, wick_range) close_buy = (close_percent >= (1 - self.p.close_percent_max)) close_sell = (close_percent <= self.p.close_percent_max) self.lines.wick = bt.If(bt.And(wick_buy, close_buy), self.data.low, bt.If(bt.And(wick_sell, close_sell), self.data.high, np.NaN) )
def __init__(self): self.addminperiod(self.p.period_kc*2) bands = bt.indicators.BollingerBands(self.data, period=self.p.period, devfactor=self.p.mult) self.l.ma = ma = self.p.movav(self.data,period=self.p.period_kc) atr = bt.indicators.ATR(self.data,period=self.p.period_kc) rma = self.p.movav(atr.atr, period=self.p.period_kc) uKC = ma + rma*self.p.mult_kc lKC = ma - rma*self.p.mult_kc bool = bt.And(bands.bot>lKC, bands.top<uKC) self.l.sqz = bt.If(bool,0.0,1.0)
def __init__(self): self.strat = self._owner # alias for clarity self.smaShort = bt.ind.SMA(self.data, period=self.p.period_short) self.smaMid = bt.ind.SMA(self.data, period=self.p.period_middle) self.smaLong = bt.ind.SMA(self.data, period=self.p.period_long) self.emaShort = bt.ind.EMA(self.data, period=self.p.period_short) self.emaMid = bt.ind.EMA(self.data, period=self.p.period_middle) self.emaLong = bt.ind.EMA(self.data, period=self.p.period_long) self.boll = bt.ind.BollingerBands(self.data) self.bollDiff = self.boll.top - self.boll.bot self.bollSignal = bt.ind.EMA(self.bollDiff, period=self.p.period_short) self.l.BollRange = bt.If(bt.And(self.bollDiff/self.p.boll_range_ThresholdValue > self.bollSignal, self.data > self.boll.mid), 1, 0) self.l.BollRange = bt.If( bt.And(self.bollDiff / self.p.boll_range_ThresholdValue > self.bollSignal, self.data < self.boll.mid), -1, self.l.BollRange) self.bollHisto = self.bollDiff - self.bollSignal jxmj_cs = abs(self.data / self.smaShort - 1)*100 jxmj_sm = abs(self.smaShort / self.smaMid - 1) * 100 jxmj_ml = abs(self.smaMid / self.smaLong - 1) * 100 self.JXMJ = JXMJDayFsumIndicator(bt.Max(jxmj_cs,jxmj_sm,jxmj_ml), period=self.p.period_jxmj).l.JXMJFsum self.l.JXMJ = bt.If( bt.And(self.JXMJ > self.p.jxmj_ThresholdValue, self.smaMid > self.smaLong), 1, 0) self.l.JXMJHoldState = self.data - self.data self.l.JXMJBuySellPoint = self.data - self.data self.lastClosePrice = 0 dfgl_cs = self.data - self.emaShort dfgl_sm = self.emaShort - self.emaMid dfgl_ml = self.emaMid - self.emaLong self.dfgl = bt.ind.PercentRank(abs(dfgl_sm), period=self.p.period_dfgl) self.l.DFGL = bt.If( bt.And(self.dfgl > self.p.dfgl_ThresholdValue, dfgl_sm > 0), 1, 0) self.holdStateLow = 9999 self.holdStateHigh = 0
def __init__(self): # Let the indicator get enough data self.addminperiod(self.p.period) # Plot horizontal Line self.plotinfo.plotyhlines = [0] # Aliases to avoid long lines c = self.data.close h = self.data.high l = self.data.low v = self.data.volume self.data.ad = bt.If(bt.Or(bt.And(c == h, c == l), h == l), 0, ((2 * c - l - h) / (h - l)) * v) self.lines.money_flow = bt.indicators.SumN(self.data.ad, period=self.p.period) / bt.indicators.SumN( self.data.volume, period=self.p.period)
def __init__(self): cpy = copy.copy(self.data) #Make a copy tmp = bt.If( self.data(0) == self.data(-1), cpy(-1) + 0.000001, self.data(0)) #Peak shift self.lines.zigzag_peak = bt.If( bt.And(tmp(-1) > tmp(-2), tmp(-1) > tmp(0)), self.data(-1), float('nan')) cpy = copy.copy(self.data) tmp = bt.If( self.data(0) == self.data(-1), cpy(-1) - 0.000001, self.data(0)) #Valley shift self.lines.zigzag_valley = bt.If( bt.And(tmp(-1) < tmp(-2), tmp(-1) < tmp(0)), self.data(-1), float('nan')) self.lines.zigzag = bt.If( self.zigzag_peak, self.zigzag_peak, bt.If(self.zigzag_valley, self.zigzag_valley, float('nan')))
def volume_indicator(self, ind, params, plot=True): """ Function that returns and binary volume confirmation indicator for simple strategy logic useage :param ind: Indicator choice (string type) - must be in list of self.indicators :param params: Parameters for Indicator - must have right amount of parameters or error thrown :return: Binary Trade Volume Indicator """ # Check Inputs self.check_input(ind, params) # Create Logic Blocks if ind == 'cvi': chaikin = ChaikinVolatility(self.data, ema_period=params[0], roc_period=params[1], plot=plot) volume = chaikin.cvi > 0.0 return volume elif ind == 'tdfi': tdfi = TrendDirectionForceIndex(self.data, period=params[0], plot=plot) volume1 = bt.If(tdfi.ntdf > params[1], 1.0, 0.0) volume2 = bt.If(tdfi.ntdf < -params[1], -1.0, 0.0) volume = volume1 + volume2 return volume elif ind == 'wae': wae = WaddahAttarExplosion(self.data, sensitivity=params[0], fast=params[1], slow=params[2], channel=params[3], mult=params[4], dead=params[5], plot=plot) # Buy Volume buy = bt.All(wae.utrend > wae.exp, wae.utrend > wae.dead, wae.exp > wae.dead) sell = bt.All(wae.dtrend > wae.exp, wae.dtrend > wae.dead, wae.exp > wae.dead) volume = buy - sell return volume elif ind == 'squeeze': sqz = SqueezeVolatility(self.data, period=params[0], mult=params[1], period_kc=params[2], mult_kc=params[3], movav=params[4]) return sqz.sqz elif ind == 'damiani': dv = DamianiVolatmeter(self.data, atr_fast=params[0], std_fast=params[1], atr_slow=params[2], std_slow=params[3], thresh=params[4], lag_supress=params[5]) volume = bt.If(bt.Cmp(dv.v, dv.t) > 0, 1.0, 0.0) return volume
def baseline_indicator(self, ind, params, plot=True): """ Function that returns and binary baseline indicator for simple strategy logic useage :param ind: Indicator choice (string type) - must be in list of self.indicators :param params: Parameters for Indicator - must have right amount of parameters or error thrown :return: Binary Trade Entry Indicator """ # Check Inputs self.check_input(ind, params) # Create Logic Blocks for Each Indicator if ind == 'kijun': ichi = bt.indicators.Ichimoku(self.data, kijun=params[0], plot=plot) base = ichi.kijun_sen elif ind == 'ma': ma = params[0](self.data, period=params[1], plot=plot) base = ma elif ind == 'itrend': itrend = iTrend(self.data, period=params[0]) base = itrend.itrend elif ind == 'fama': mama = MAMA(self.data, fast=params[0], slow=params[1], plot=plot) base = mama.FAMA elif ind == 'mama': mama = MAMA(self.data, fast=params[0], slow=params[1], plot=plot) base = mama.MAMA elif ind == 'laguerre': lag = LaguerreFilter(self.data, period=params[0], plot=plot) base = lag.filter elif ind == 'alaguerre': alag = AdaptiveLaguerreFilter(self.data, length=params[0], plot=plot) base = alag.filter elif ind == 'butter': butterworth = Butterworth(self.data, period=params[0], poles=params[1], plot=plot) base = butterworth.butter # Baseline Crossover Detection baseline = bt.indicators.CrossOver(self.data.close, base, plot=plot) # Baseline Crossover too Far diff = bt.If(baseline > 0, self.data.close - base, base - self.data.close) too_far = bt.If(diff > self.atr, True, False) return baseline, too_far
def entry_indicator(self, ind, params, plot=True): """ Function that returns and binary entry confirmation indicator for simple strategy logic useage :param ind: Indicator choice (string type) - must be in list of self.indicators :param params: Parameters for Indicator - must have right amount of parameters or error thrown :return: Binary Trade Entry Indicator """ # Check Inputs self.check_input(ind, params) # Create Logic Blocks for Each Indicator if ind == 'itrend': itrend = iTrend(self.data, period=params[0], plot=plot) entry = bt.Cmp(itrend.trigger, itrend.itrend) return entry elif ind == 'cybercycle': cc = CyberCycle(self.data, period=params[0], plot=plot) entry = bt.Cmp(cc.trigger, cc.cycle) return entry elif ind == 'adaptivecybercycle': acc = AdaptiveCyberCycle(self.data, period=params[0], lag=params[1], plot=plot) entry = bt.Cmp(acc.signal, acc.trigger) return entry elif ind == 'ssl': ssl = SSLChannel(self.data, period=params[0], plot=plot) entry = bt.Cmp(ssl.sslu, ssl.ssld) return entry elif ind == 'aroon': aud = bt.indicators.AroonUpDown(self.data, period=params[0], plot=plot) entry = bt.Cmp(aud.aroonup, aud.aroondown) return entry elif ind == 'ttf': ttf = TrendTriggerFactor(self.data, period=params[0], plot=plot) long = bt.indicators.CrossUp(ttf.ttf, -100.0, plot=plot) short = bt.indicators.CrossDown(ttf.ttf, 100.0, plot=plot) entry = long + -1 * short return entry elif ind == 'tdfi': tdfi = TrendDirectionForceIndex(self.data, period=params[0], plot=plot) e1 = bt.If(tdfi.ntdf > params[1], 1.0, 0.0) e2 = bt.If(tdfi.ntdf < -params[1], -1.0, 0.0) entry = e1 + e2 return entry elif ind == 'cmf': chaikin = ChaikinMoneyFlow(self.data, period=params[0], plot=plot) entry = bt.Cmp(chaikin.money_flow, 0.0) return entry elif ind == 'ash': ash = ASH(self.data, period=params[0], smoothing=params[1], mode=params[2], rsifactor=params[3], movav=params[4], smoothav=params[5], pointsize=params[6]) entry = bt.Cmp(ash.bulls, ash.bears) return entry elif ind == 'roof': roof = RoofingFilter(self.data, hp_period=params[0], ss_period=params[1], smooth=params[2], plot=plot) entry = bt.Cmp(roof.iroof, 0.0) return entry elif ind == 'mama': mama = MAMA(self.data, fast=params[0], slow=params[1], plot=plot) entry = bt.Cmp(mama.MAMA, mama.FAMA) return entry elif ind == 'dosc': dosc = DecyclerOscillator(self.data, hp_period=params[0], plot=plot) entry = bt.Cmp(dosc.osc, 0.0) return entry elif ind == 'idosc': idosc = iDecycler(self.data, hp_period=params[0], smooth=params[1], plot=plot) entry = bt.Cmp(idosc.idosc, 0.0) return entry elif ind == 'schaff': schaff = SchaffTrendCycle(self.data, fast=params[0], slow=params[1], cycle=params[2], factor=params[3], plot=plot) buy = bt.indicators.CrossUp(schaff.schaff, 25.0, plot=plot) sell = bt.indicators.CrossDown(schaff.schaff, 75.0, plot=plot) binary = buy - sell entry = SignalFiller(binary, plot=plot).signal return entry
def __init__(self): self.strat = self._owner # alias for clarity self.smaShort = bt.ind.SMA(self.data, period=self.p.period_short) self.smaMid = bt.ind.SMA(self.data, period=self.p.period_middle) self.smaLong = bt.ind.SMA(self.data, period=self.p.period_long) self.emaShort = bt.ind.EMA(self.data, period=self.p.period_short) self.emaMid = bt.ind.EMA(self.data, period=self.p.period_middle) self.emaLong = bt.ind.EMA(self.data, period=self.p.period_long) self.smaVolumeShort = bt.ind.SMA(self.data.volume, period=self.p.period_volumeShort) self.boll = bt.ind.BollingerBands(self.data) self.bollDiff = self.boll.top - self.boll.bot self.bollSignal = bt.ind.EMA(self.bollDiff, period=self.p.period_short) self.l.BollRange = bt.If( bt.And( self.bollDiff / self.p.boll_range_ThresholdValue > self.bollSignal, self.data > self.boll.mid), 1, 0) self.l.BollRange = bt.If( bt.And( self.bollDiff / self.p.boll_range_ThresholdValue > self.bollSignal, self.data < self.boll.mid), -1, self.l.BollRange) self.bollHisto = self.bollDiff - self.bollSignal self.boll_signal_Pct = self.bollDiff / self.bollSignal self.natr = bt.ind.ATR(self.data, period=self.p.period_short) / self.data self.natrEmaShort = bt.ind.EMA(self.natr) self.natr_ema_Pct = self.natr / self.natrEmaShort smaMin = bt.ind.Min(self.smaShort, self.smaMid, self.smaLong) smaMax = bt.ind.Max(self.smaShort, self.smaMid, self.smaLong) emaMin = bt.ind.Min(self.emaShort, self.emaMid, self.emaLong) emaMax = bt.ind.Max(self.emaShort, self.emaMid, self.emaLong) smaIntense = bt.If( (smaMax - smaMin) < self.data * self.p.jxmj_ThresholdPctLimit, True, False) emaIntense = bt.If( (emaMax - emaMin) < self.data * self.p.jxmj_ThresholdPctLimit, True, False) self.l.priceIntense = bt.And(smaIntense, emaIntense) self.l.bollIntense = JXMJDayFsumIndicator( self.boll_signal_Pct, period=self.p.period_short, func=lambda d: fsum( (x < 1) for x in d) > self.p.period_short * 0.7 or fsum( (x < 1.1) for x in d) > self.p.jxmj_ThresholdValue) self.l.natrIntense = JXMJDayFsumIndicator( self.natr_ema_Pct, period=self.p.period_short, func=lambda d: fsum( (x < 1) for x in d) > self.p.period_short * 0.7 or fsum( (x < 1.1) for x in d) > self.p.jxmj_ThresholdValue) self.l.JXMJ = bt.If( bt.And(self.priceIntense, bt.And(self.bollIntense, self.natrIntense)), 1, 0) self.l.JXMJHoldState = self.data - self.data self.l.JXMJBuySellPoint = self.data - self.data self.lastClosePrice = 0 dfgl_cs = self.data - self.emaShort dfgl_sm = self.emaShort - self.emaMid dfgl_ml = self.emaMid - self.emaLong self.dfgl = bt.ind.PercentRank(abs(dfgl_sm), period=self.p.period_dfgl) self.l.DFGL = bt.If( bt.And(self.dfgl > self.p.dfgl_ThresholdValue, dfgl_sm > 0), 1, 0) self.holdStateLow = 9999 self.holdStateHigh = 0
def __init__(self): cbar = self.data.close pbar = self.data.close(-self.p.period) self.td_base = bt.If(cbar > pbar, 1, bt.If(cbar < pbar, -1, 0))