BackTrader 中文文档(二十九)(2)https://developer.aliyun.com/article/1505506
康纳斯 RSI
Google 提供的此指标参考文献:
两个来源对公式都表示同意,尽管术语不同(见下文)。 应按以下方式计算 Connors RSI:
CRSI(3, 2, 100) = [RSI(3) + RSI(Streak, 2) + PercentRank(100)] / 3
注意
TradingView 表示 ROC
(“变动率”)必须用于 PctRank
(“百分比排名”)的位置,但从 TradingView 自身提供的定义来看,显然是错误的。
Streak
是一个非标准术语,需要定义,让我们从源(在 TradingView 行话中称为 “UpDown”) 中参考它。
- 每日价格收盘比前一日高/低的连续天数
- 如果某日收盘价与前一日相同,则连续数重置为
0
- 向上连续产生正值,向下连续产生负值
手头有公式,理解需要使用 PercentRank
以及对 Streak
(或 UpDown
)有清晰定义,创建 ConnorsRSI
指标应该轻而易举。
class Streak(bt.ind.PeriodN): ''' Keeps a counter of the current upwards/downwards/neutral streak ''' lines = ('streak',) params = dict(period=2) # need prev/cur days (2) for comparisons curstreak = 0 def next(self): d0, d1 = self.data[0], self.data[-1] if d0 > d1: self.l.streak[0] = self.curstreak = max(1, self.curstreak + 1) elif d0 < d1: self.l.streak[0] = self.curstreak = min(-1, self.curstreak - 1) else: self.l.streak[0] = self.curstreak = 0 class ConnorsRSI(bt.Indicator): ''' Calculates the ConnorsRSI as: - (RSI(per_rsi) + RSI(Streak, per_streak) + PctRank(per_rank)) / 3 ''' lines = ('crsi',) params = dict(prsi=3, pstreak=2, prank=100) def __init__(self): # Calculate the components rsi = bt.ind.RSI(self.data, period=self.p.prsi) streak = Streak(self.data) rsi_streak = bt.ind.RSI(streak, period=self.p.pstreak) prank = bt.ind.PercentRank(self.data, period=self.p.prank) # Apply the formula self.l.crsi = (rsi + rsi_streak + prank) / 3.0
这里展示了指标的工作原理,还包括Streak
辅助指标,以便视觉上验证实际连续数的输出。
Donchian 通道
class DonchianChannels(bt.Indicator): ''' Params Note: - `lookback` (default: -1) If `-1`, the bars to consider will start 1 bar in the past and the current high/low may break through the channel. If `0`, the current prices will be considered for the Donchian Channel. This means that the price will **NEVER** break through the upper/lower channel bands. ''' alias = ('DCH', 'DonchianChannel',) lines = ('dcm', 'dch', 'dcl',) # dc middle, dc high, dc low params = dict( period=20, lookback=-1, # consider current bar or not ) plotinfo = dict(subplot=False) # plot along with data plotlines = dict( dcm=dict(ls='--'), # dashed line dch=dict(_samecolor=True), # use same color as prev line (dcm) dcl=dict(_samecolor=True), # use same color as prev line (dch) ) def __init__(self): hi, lo = self.data.high, self.data.low if self.p.lookback: # move backwards as needed hi, lo = hi(self.p.lookback), lo(self.p.lookback) self.l.dch = bt.ind.Highest(hi, period=self.p.period) self.l.dcl = bt.ind.Lowest(lo, period=self.p.period) self.l.dcm = (self.l.dch + self.l.dcl) / 2.0 # avg of the above
资金流动指标
参考
class MFI(bt.Indicator): lines = ('mfi',) params = dict(period=14) alias = ('MoneyFlowIndicator',) def __init__(self): tprice = (self.data.close + self.data.low + self.data.high) / 3.0 mfraw = tprice * self.data.volume flowpos = bt.ind.SumN(mfraw * (tprice > tprice(-1)), period=self.p.period) flowneg = bt.ind.SumN(mfraw * (tprice < tprice(-1)), period=self.p.period) mfiratio = bt.ind.DivByZero(flowpos, flowneg, zero=100.0) self.l.mfi = 100.0 - 100.0 / (1.0 + mfiratio)
这是指标运作的一个视角
BackTrader 中文文档(二十九)(4)https://developer.aliyun.com/article/1505509