vnpy版本众多,各个版本启动方式都有差别,当然我这种彩笔现在只会vtmain和run两种方式。由于项目经常更新,所以,这些启动方式会时不时调整。以下分析为图形界面的VNPY,无人值守的cta策略,不在这里。记录一下,我这彩笔使用pycharm的debug功能查看,cta策略启动流程分析。高手用sublime居然可以调试python这也真是厉害,python程序执行跳来跳去,长期搞得我晕头转向。虽然,pycharm的索引功能常常乱索引,但是总比没有好得多。最后,个人发现1.7.1版本的vnpy在pycharm调试的时候会调用project所在的工作目录的trader目录,但是,在cmd命令行模式下一般会调用c盘下的anaconda下的vnpy。
1、在这个目录下的这个文件H:\vnpy-1.3\vn.trader\vtMain.py,下面是内容。其实是一个常规python启动的main文件。
# encoding: UTF-8
import sys
import os
import ctypes
import platform
import vtPath
from vtEngine import MainEngine
from uiMainWindow import *
# 文件路径名
path = os.path.abspath(os.path.dirname(__file__))
ICON_FILENAME = 'vnpy.ico'
ICON_FILENAME = os.path.join(path, ICON_FILENAME)
SETTING_FILENAME = 'VT_setting.json'
SETTING_FILENAME = os.path.join(path, SETTING_FILENAME)
#----------------------------------------------------------------------
def main():
"""主程序入口"""
# 重载sys模块,设置默认字符串编码方式为utf8
reload(sys)
sys.setdefaultencoding('utf8')
# 设置Windows底部任务栏图标
if 'Windows' in platform.uname() :
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('vn.trader')
# 初始化Qt应用对象
app = QtGui.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon(ICON_FILENAME))
app.setFont(BASIC_FONT)
# 设置Qt的皮肤
try:
f = file(SETTING_FILENAME)
setting = json.load(f)
if setting['darkStyle']:
import qdarkstyle
app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
except:
pass
# 初始化主引擎和主窗口对象
mainEngine = MainEngine()
mainWindow = MainWindow(mainEngine, mainEngine.eventEngine)
mainWindow.showMaximized()
# 在主线程中启动Qt事件循环
sys.exit(app.exec_())
if __name__ == '__main__':
main()
2、关键是这个,他会向python的系统路径path添加vtMain的路径,然后才可以调用各种模块,python的模块引用是最几把坑爹的。
3、剩下的是顺序执行了,前面的一些是系统设置和pyqt的图形界面设置,然后重点,上图。在调试的时候要把断点设置到这里来。
这个MainEngine()是vnpy的核心。
这个是vtEngien的MainEngine类的部分内容,红线的就是cta策略的引擎(什么是引擎,我也不清楚,反正就是最重要的东西。)
4、cta策略的设置启动。在这个目录下面H:\vnpy-1.3\vn.trader\ctaAlgo有这么两个文件,是需要设置的。启动前需要配置的,当然策略需要放在该目录下面。
这就是cta启动的界面。
5、cta策略的初始化一些问题。
初始化其实也是个大坑,开始的我鬼都不知道,点初始化只会打印一个“策略初始化”,然后指标只会部分变化。有些指标怎么都不变化,其实这是初始化失败的产物。而且很多回测的时候,出现没有交易的回测,都有可能是初始化失败的问题。还说一下,我以前不会用pycharm调试,我这种彩笔,只会print,根据打印信息到处print,坑逼啊。很多变量,类,对象的情况print还是不好用。
说初始化的问题,其实还是在时间序列的buffer.size的大小和指标周期的大小问题。
# 保存K线数据
self.closeArray[0:self.bufferSize-1] = self.closeArray[1:self.bufferSize]
self.highArray[0:self.bufferSize-1] = self.highArray[1:self.bufferSize]
self.lowArray[0:self.bufferSize-1] = self.lowArray[1:self.bufferSize]
self.closeArray[-1] = bar.close
self.highArray[-1] = bar.high
self.lowArray[-1] = bar.low
self.bufferCount += 1
if self.bufferCount < self.bufferSize:
return