VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 17
声望: 0

在策略中,我用了两种方法计算macd指标数据,均使用了am的缓存数据:
一、

用arraymanager内置的macd获取函数生成指标数据

        self.macd,self.signal,self.hist = am.macd(
                                                self.fast_period,
                                                self.slow_period,
                                                self.signal_period,
                                                array=False)

二、

直接在策略中使用talib获取macd指标数据

        close = self.am.close_array
        macd,signal,hist = talib.MACD(close, 12, 26, 9)

description
在策略中打印指标数据:
白框里是ROC指标,红色是macd指标数据,分别是macd,signal,hist…
如图,使用am缓存的数据生成的macd指标数据是一样的,不论是直接通过talib还是使用am内置的指标获取函数,结果相同。

但是!

不用am缓存的数据,得到的macd指标数据不一样… 使用am内置的macd获取函数,用策略里相同的数据(沪深300指数),代码和运行结果如下:

description

如图,close数据相同,表示两种方法都使用了相同的数据...不同的是:是否经过am容器缓存
虽然macd的数据不一样,但其他指标的数据是一样的,如上面计算的ROC数据…这就很费解了…
二楼是策略源码,三楼是未使用am容器的计算结果

Member
avatar
加入于:
帖子: 17
声望: 0

from vnpy_ctastrategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
import talib

class MacdStrategy(CtaTemplate):
""""""

author = "alxbj"

macd = 0
signal = 0
hist = 0
roc = 0

fast_period = 12
slow_period = 26
signal_period = 9

#参数
parameters = [
    "fast_period",
    "slow_period",
    "signal_period",
]
#变量
variables = [
    "macd",
    "signal",
    "hist"
]

def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
    """"""
    super().__init__(cta_engine, strategy_name, vt_symbol, setting)

    self.bg = BarGenerator(self.on_bar)
    self.am = ArrayManager()

def on_init(self):
    """
    Callback when strategy is inited.
    """
    self.write_log("策略初始化")
    self.load_bar(10)

def on_start(self):
    """
    Callback when strategy is started.
    """
    self.write_log("策略启动")

def on_stop(self):
    """
    Callback when strategy is stopped.
    """
    self.write_log("策略停止")

def on_tick(self, tick: TickData):
    """
    Callback of new tick data update.
    """
    self.bg.update_tick(tick)

def on_bar(self, bar: BarData):
    """
    Callback of new bar data update.
    """

    self.cancel_all()

    am = self.am
    am.update_bar(bar)
    if not am.inited:
        return


    # 用arraymanager内置的macd获取函数生成指标数据
    self.macd,self.signal,self.hist = am.macd(
                                            self.fast_period, 
                                            self.slow_period, 
                                            self.signal_period,
                                            array=False)

    self.roc = am.roc(14,array=False)                    
    print('date:',bar.datetime.strftime( '%Y-%m-%d' ),
    'close:',bar.close_price)
    print('am.talib',self.roc,self.macd,self.signal,self.hist)

    # 直接用talib获取macd指标数据
    close = self.am.close_array
    macd,signal,hist = talib.MACD(close, 12, 26, 9)
    roc = talib.ROC(close,14)
    print('talib   ',roc[-1],macd[-1], signal[-1], hist[-1])
    print('-------------------------------------------------------------------')

    self.put_event()

def on_order(self, order: OrderData):
    """
    Callback of new order data update.
    """
    pass

def on_trade(self, trade: TradeData):
    """
    Callback of new trade data update.
    """
    self.put_event()

def on_stop_order(self, stop_order: StopOrder):
    """
    Callback of stop order update.
    """
    pass
Member
avatar
加入于:
帖子: 17
声望: 0

import talib
import pandas as pd
import numpy as np
def macd(
close,
fast_period: int,
slow_period: int,
signal_period: int,
array: bool = False):
"""
MACD.
"""
macd, signal, hist = talib.MACD(
close, fast_period, slow_period, signal_period
)
if array:
return macd, signal, hist
return macd[-1], signal[-1], hist[-1]
close =df1.close.values
macd_df = pd.DataFrame()
macd,signal,hist = macd(close, 12, 26, 9,array=True)
macd_df['date'] = df1.date
macd_df['close'] = df1.close
macd_df['roc'] = talib.ROC(close, 14)
macd_df['macd'] = macd
macd_df['signal'] = signal
macd_df['hist'] = hist
macd_df.tail(10)

Member
avatar
加入于:
帖子: 17
声望: 0

哦,我知道答案了...
macd 的计算方式需要计算ema数据...这就需要足够多的前置数据,如果数据不足,虽然也能计算出结果,但与具有充足的前置数据计算的结果不一样。

am默认缓存100根k线,我在jupyter里只使用了36根k线(ema26只需要26天的数据就能计算),但没想到的是,100根k线与36根k线的ema值不一样...

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】