哦,我知道答案了...
macd 的计算方式需要计算ema数据...这就需要足够多的前置数据,如果数据不足,虽然也能计算出结果,但与具有充足的前置数据计算的结果不一样。
am默认缓存100根k线,我在jupyter里只使用了36根k线(ema26只需要26天的数据就能计算),但没想到的是,100根k线与36根k线的ema值不一样...
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)
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
在策略中,我用了两种方法计算macd指标数据,均使用了am的缓存数据:
一、
self.macd,self.signal,self.hist = am.macd(
self.fast_period,
self.slow_period,
self.signal_period,
array=False)
二、
close = self.am.close_array
macd,signal,hist = talib.MACD(close, 12, 26, 9)
在策略中打印指标数据:
白框里是ROC指标,红色是macd指标数据,分别是macd,signal,hist…
如图,使用am缓存的数据生成的macd指标数据是一样的,不论是直接通过talib还是使用am内置的指标获取函数,结果相同。
但是!
不用am缓存的数据,得到的macd指标数据不一样… 使用am内置的macd获取函数,用策略里相同的数据(沪深300指数),代码和运行结果如下:
如图,close数据相同,表示两种方法都使用了相同的数据...不同的是:是否经过am容器缓存
虽然macd的数据不一样,但其他指标的数据是一样的,如上面计算的ROC数据…这就很费解了…
二楼是策略源码,三楼是未使用am容器的计算结果
我用的同花顺的数据,回测了2017-2021年...与楼主的回测结果基本吻合,只是最后一个策略出入较大...
而且,2020-2021年的回测结果不理想,收益曲线不再保持前面的上升角度了...
1 、RsjDmiStrategy:
2 、RsjRsiStrategy:
3 、RsjRocStrategy:
结论:
初步判断,RSJ+技术指标也无法穿越牛熊...
靠ALPHA盈利的策略想要多、空、横通杀...唯有靠预测(具有一定成功率的预测系统)来过滤交易信号...
感谢分享,希望能坚持下去...
3、期货干脆就没有日线数据获取功能?
4、VNPY的数据管理也无法获取日线数据...
今天注册了体验账户,简单测试了一下,问题如下:
1、期货各品种没有主连和指数数据....这很重要啊!
2、A股数据的日线获取函数stock_quote_daily,只能调取单日?
用Python的交易员 wrote:
目前只支持了股票和期货的数据,没有支持指数的,可以去
https://www.github.com/vnpy/vnpy_tushare开个Issue,我们同事后续会跟进
ok
其他的都能正常下载...
这就有点滑稽了...收费的数据竟然不如免费的数据全...
连上证指数也只能获取2000年之后的...
认真的?
那2000年之前的数据咋办?自己拼接?
本来打算自己开发的...突然发现官方有这个模块...看来是有开发计划啊...
几个问题,望解答:
1、这个模块能否实时刷新的tick或者1分钟K线?
2、是否具有普通行情软件的功能,如:各种周期级别的切换、常用及定制技术指标的显示...等
3、历史成交单及盈亏显示、当前持仓盈亏显示