talib包计算MACD值和行情软件有差异的解决方法

talib包是计算许多行情指标必备的第三方库,但在计算过程中发现,计算出来的数值和行情软件的计算方法存在很大的差异,可能会导致策略出现错误。为此,专门写了一个函数解决这个问题。欢迎大家一起交流讨论。

MACD的计算

MACD的计算很简单,主要包括DIF、DEA和BAR三个参数。计算方式如下:

0_1603416493225_861ffe33-a5ec-4278-a46f-32d62a8194fb-image.png
(图片来源百度百科)

注: 在计算过程中,需要注意数据的初始化。上市首日,DIF、DEA、BAR默认为0.但次日计算中EMA12和EMA26是按照上市首日的收盘价来计算的,所以这里面涉及一个初始化的问题。在计算上市以来第二个交易日的MACD时要先将EMA12和EMA26都替换为上市首日收盘价。

函数编写思路

  • 首先,需要自上市以来的收盘价数据。这里利用掘金的history接口,将开始日期设置为一个较早的日期以确保将标的自上市以来的全部收盘价都涵盖(这里设定为1997年)。

  • 其次,根据上图中的公式计算出各项指标,存为dataframe。

  • 最后,由于不需要上市以来全部的MACD指标,只需要其中的一段时间。所以,设定一个时间筛选条件,能够满足只要设定开始时间和结束时间即可提取到所需数据的函数。

基于以上思路,可以编写出函数如下:

def get_macd(symbol,start_time,end_time):
    # 取历史数据
    data = history(symbol = symbol,frequency = '1d',start_time = '1997-01-20',end_time = end_time,fields = 'symbol,bob,close',df = True)
    index = data['bob'].apply(lambda x: x.strftime('%Y-%m-%d')).tolist()

    # 编写计算函数
    # 上市首日,DIFF、DEA、MACD = 0
    # 用来装变量的list
    EMA12 = []
    EMA26 = []
    DIFF = []
    DEA = []
    BAR = []
    # 如果是上市首日
    if len(data) == 1:
        # 则DIFF、DEA、MACD均为0
        DIFF = [0]
        DEA = [0]
        BAR = [0]

    # 如果不是首日
    else:
        # 第一日的EMA要用收盘价代替
        EMA12.append(data['close'].iloc[0])
        EMA26.append(data['close'].iloc[0])
        DIFF.append(0)
        DEA.append(0)
        BAR.append(0)

        # 计算接下来的EMA
        # 搜集收盘价
        close = list(data['close'].iloc[1:])    # 从第二天开始计算,去掉第一天
        for i in close:
            ema12 = EMA12[-1] * (11/13) + i * (2/13)
            ema26 = EMA26[-1] * (25/27) + i * (2/27)
            diff = ema12 - ema26
            dea = DEA[-1] * (8/10) + diff * (2/10)
            bar = 2 * (diff - dea)

            # 将计算结果写进list中
            EMA12.append(ema12)
            EMA26.append(ema26)
            DIFF.append(diff)
            DEA.append(dea)
            BAR.append(bar)

    # 返回全部的macd
    MACD = pd.DataFrame({'DIFF':DIFF,'DEA':DEA,'BAR':BAR, 'time':index},index = index)

   # 按照时间筛选子集
    MACD = MACD[(MACD['time'] >= start_time) & (MACD['time'] <= end_time)]

    return MACD

利用数据验证一下。我用的是大商所的豆油(DCE.y2011合约),结果和东方财富显示的相符。

a = get_macd(symbol = 'DCE.y2011',start_time = '2020-01-01',end_time = '2020-10-22')

Tips:
虽然这样能够解决talib计算MACD和行情软件有差异的问题,但这样计算也会衍生出新的问题。

  1. 将该函数放到循环中,每循环一次就要重新提取一次数据,无形之中增加了策略运行的时间和工作量。
  2. 如果利用其他频率的数据计算macd(比如用60s的数据计算MACD),没有能够追溯到上市当天的历史数据,这样计算出来的结果仍然是不准确的。

自己写函数 or 用talib包?

由于talib包没有详细的计算方法解释,所以暂时无法得知该包是怎样计算macd的,但不可否认的是,在事件驱动的高频交易中,用talib包的确更方便一些。

基于以上,选择哪种方法还需自行斟酌。 

---------------------------------------------------------------------------------------------

推荐阅读:

1.一个量化策略师的自白(好文强烈推荐)

2.股票期货经典的量化交易策略都在这里了!(源码)

3.期货/股票数据大全查询(历史/实时/Tick/财务等)

4.史上最全的Python定量金融三方库汇总

5.干货 | 量化选股策略模型大全

6.量化金融经典理论、重要模型、发展简史大全

 

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要使用 talib 库来计算 MACD,需要首先安装 talib 库。在安装完成后,可以按照以下步骤计算 MACD: 1. 导入 talib 库和 pandas 库。 ```python import talib import pandas as pd ``` 2. 从数据源(如 CSV 文件或数据库)加载股票数据。以下示例加载了一个名为 `data.csv` 的 CSV 文件。 ```python df = pd.read_csv('data.csv') ``` 3. 将数据转换为 talib 库所需的格式。talib 库要求输入的数据为 numpy 数组,因此需要将 pandas 数据框转换为 numpy 数组。 ```python close = df['close'].values ``` 4. 调用 talib 库中的 `MACD` 函数计算 MACD 指标。 ```python macd, signal, hist = talib.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9) ``` 在这个示例中,我们将 `close` 数组传递给 `MACD` 函数,并指定了 `fastperiod`、`slowperiod` 和 `signalperiod` 参数。这些参数分别表示 MACD 线、信号线和 MACD 柱的计算期间。通常情况下,`fastperiod` 为 12,`slowperiod` 为 26,`signalperiod` 为 9。 5. 将计算结果保存到 pandas 数据框中。 ```python df['macd'] = macd df['signal'] = signal df['hist'] = hist ``` 在这个示例中,我们将计算出的 MACD、信号线和 MACD 柱分别保存到名为 `macd`、`signal` 和 `hist` 的新列中。 完整代码示例: ```python import talib import pandas as pd # 从 CSV 文件加载数据 df = pd.read_csv('data.csv') # 将数据转换为 numpy 数组 close = df['close'].values # 计算 MACD macd, signal, hist = talib.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9) # 将计算结果保存到数据框中 df['macd'] = macd df['signal'] = signal df['hist'] = hist # 打印数据框 print(df) ``` 注意:MACD 指标的计算需要至少 26 个数据点,因此在加载数据时需要确保数据的时间范围足够长。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值