Skip to content

MFI 通用

原文: https://www.backtrader.com/blog/2019-07-17-mfi-generic/mfi-generic/

在最近的规范与非规范帖子中,开发了MFI(又名MoneyFlowIndicator)。

虽然它是以规范的方式开发的,但它仍然提供了一些改进和通用化的空间。

让我们关注实现的 1st行,这些行创建了典型的价格

class MFI_Canonical(bt.Indicator):
    lines = ('mfi',)
    params = dict(period=14)

    def __init__(self):
        tprice = (self.data.close + self.data.low + self.data.high) / 3.0
        mfraw = tprice * self.data.volume
        ... 

典型的实例化如下所示

class MyMFIStrategy(bt.Strategy):

    def __init__(self):
        mfi = bt.MFI_Canonical(self.data) 

这里的问题应该是显而易见的:“需要为具有closelowhighvolume组件(即反向交易者生态系统中的 aka)的指标输入。”

当然,在这种情况下,人们可能希望使用来自不同数据源的组件(来自数据提要的行或来自其他指标的行)创建一个MoneyFlowIndicator,就像希望赋予close更多的权重一样简单,而无需开发特定指标。考虑到行业标准OHLCV字段排序、close的多个输入、额外重量,实例化可能如下所示

class MyMFIStrategy2(bt.Strategy):

    def __init__(self):
        wclose = self.data.close * 5.0
        mfi = bt.MFI_Canonical(self.data.high, self.data.low,
                               wclose, self.data.volume) 

或者是因为用户以前使用过ta-lib并且喜欢多输入风格。

支持多输入

backtrader试图尽可能成为pythonic,可以查询包含系统中数据馈送列表的self.datas数组(该数组自动神奇地提供给您的策略)的长度。让我们用这个来区分调用方想要什么,并正确计算tpricemfraw

class MFI_MultipleInputs(bt.Indicator):
    lines = ('mfi',)
    params = dict(period=14)

    def __init__(self):
        if len(self.datas) == 1:
            # 1 data feed passed, must have components
            tprice = (self.data.close + self.data.low + self.data.high) / 3.0
            mfraw = tprice * self.data.volume
        else:
            # if more than 1 data feed, individual components in OHLCV order
            tprice = (self.data0 + self.data1 + self.data2) / 3.0
            mfraw = tprice * self.data3

        # No changes with regards to previous implementation
        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) 

注意单个组件是如何被引用为self.dataX(例如self.data0self.data1

这与在self.datas[0]中使用self.datas[x]相同。。。


让我们以图形的方式来看,该指示器产生的结果与规范指示器相同,并且当多个输入对应于数据馈送的原始组件时,产生的结果相同。要做到这一点,它将在这样一种策略中运行

class MyMFIStrategy2(bt.Strategy):

    def __init__(self):
        MFI_Canonical(self.data)
        MFI_MultipleInputs(self.data, plotname='MFI Single Input')
        MFI_MultipleInputs(self.data.high,
                           self.data.low,
                           self.data.close,
                           self.data.volume,
                           plotname='MFI Multiple Inputs') 

!MFI Results Check

在不必检查每个值的情况下,从图中可以明显看出,这三个值的结果是相同的。

最后让我们看看如果在close上施加更多的重量会发生什么。我们就这样跑吧。

class MyMFIStrategy2(bt.Strategy):
    def __init__(self):

        MFI_MultipleInputs(self.data)
        MFI_MultipleInputs(self.data.high,
                           self.data.low,
                           self.data.close * 5.0,
                           self.data.volume,
                           plotname='MFI Close * 5.0') 

!MFI Close * 5.0

这是否有意义取决于读者,但我们可以清楚地看到,增加close的权重改变了模式。

结论

通过简单地使用 pythoniclen,可以将使用多个组件(和固定名称)的数据馈送的指示器转换为接受多个通用输入的指示器。


我们一直在努力

apachecn/AiLearning

【布客】中文翻译组