VNPY中 Tick级别准高频交易简单策略

发布时间:2025-09-04 00:38:57 作者:益华网络 来源:undefined 浏览量(0) 点赞(0)
摘要:VNPY中,大多策略都是基于bar分钟级别;国内tick是一秒两笔,频率不算太高。这里尝试做了一个Tick基本准高频交易策略,只是为了实现思路。可以回测,不要直接用。。 回测时

VNPY中,大多策略都是基于bar分钟级别;国内tick是一秒两笔,频率不算太高。这里尝试做了一个Tick基本准高频交易策略,只是为了实现思路。可以回测,不要直接用。。

回测时候记得把回测模式改为TICK_MODE, 数据库改为TICK_DB_NAME,还有setStartDate时候initdays设为0,不需要回读历史天数,只需要当天数据; 另外TICK回测超过一天系统就报错内存不够, 所以最好一天就够。 还有,把 currentTime改为开盘时间, 因为策略只在开盘时间运行,收盘前会自动平仓。

入场: 每次读 Tick ,分析过去 10 tick 的的总计,如果买量大于卖量,开多单 ;反之空单

          下单价格是当前tick市价;

止损:下单同时开反向2个价位的阻止单;

离场:下次TICK读取时候,如果已经是买入价格正向3个点,再次判断买卖量比,如果已经不符合,市价卖出;如果还是符合原来量比就极小持有,清掉之前阻止单,改挂当前价位反向2个点阻止单。

7 -24 更新,具体代码更新等验证后更新:

更改 stoporder 止损单为 limit order 限价单,这样更为快速;放在 ontrade() ,一旦主动交易确认发生后,发出这个止损 limit order

onorder() 加入,一旦发现发出交易没有完成,还在挂单,取消

新增一个类全局变量级别的锁,当有 order 挂单或者没有 order 发出单没有返回信息时候,这个锁关闭,不再开新单;避免多个单同时阻塞。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# encoding: UTF-8
from __future__ import division
from vnpy.trader.vtGateway import *
from datetime import datetime, time
from vnpy.trader.vtObject import VtBarData
from vnpy.trader.vtConstant import EMPTY_STRING
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
BarGenerator,
ArrayManager,
TickArrayManager)
########################################################################
class TickOneStrategy(CtaTemplate):
"""基于Tick的交易策略"""
className = TickOneStrategy
author = uBillyZhang
# 策略参数
fixedSize = 1
Ticksize = 10
initDays = 0
DAY_START = time(9, 00)  # 日盘启动和停止时间
DAY_END = time(14, 58)
NIGHT_START = time(21, 00)  # 夜盘启动和停止时间
NIGHT_END = time(10, 58)
# 策略变量
posPrice = 0  # 持仓价格
pos = 0       # 持仓数量
# 参数列表,保存了参数的名称
paramList = [name,
className,
author,
vtSymbol,
initDays,
Ticksize,
fixedSize
]
# 变量列表,保存了变量的名称
varList = [inited,
trading,
pos,
posPrice
]
# 同步列表,保存了需要保存到数据库的变量名称
syncList = [pos,
posPrice,
intraTradeHigh,
intraTradeLow]
# ----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(TickOneStrategy, self).__init__(ctaEngine, setting)
#创建Array队列
self.tickArray = TickArrayManager(self.Ticksize)
# ----------------------------------------------------------------------
def onminBarClose(self, bar):
""""""
# ----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必须由用户继承实现)"""
self.writeCtaLog(u%s策略初始化 % self.name)
#tick级别交易,不需要过往历史数据
self.putEvent()
# ----------------------------------------------------------------------
def onStart(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u%s策略启动 % self.name)
self.putEvent()
# ----------------------------------------------------------------------
def onStop(self):
"""停止策略(必须由用户继承实现)"""
self.writeCtaLog(u%s策略停止 % self.name)
self.putEvent()
# ----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送(必须由用户继承实现)"""
currentTime = datetime.now().time()
# 平当日仓位, 如果当前时间是结束前日盘15点28分钟,或者夜盘10点58分钟,如果有持仓,平仓。
if ((currentTime >= self.DAY_START and currentTime <= self.DAY_END) or
(currentTime >= self.NIGHT_START and currentTime <= self.NIGHT_END)):
TA = self.tickArray
TA.updateTick(tick)
if not TA.inited:
return
if self.pos == 0:
# 如果空仓,分析过去10个对比,ask卖方多下空单,bid买方多下多单,并防止两个差价阻止单
if TA.askBidVolumeDif() > 0:
self.short(tick.lastPrice, self.fixedSize, False)
self.cover(tick.lastPrice + 2,self.fixedSize, True)
elif TA.askBidVolumeDif() < 0:
self.buy(tick.lastPrice, self.fixedSize, False)
self.sell(tick.lastPrice - 2, self.fixedSize, True)
elif self.pos > 0:
# 如果持有多单,如果已经是买入价格正向N3个点,再次判断趋势,如果已经不符合,市价卖出。如果持有,清掉之前阻止单,改挂当前价位反向2个点阻止单。
if  tick.lastprice - self.posPrice >= 3:
if TA.askBidVolumeDif() < 0:
self.cancelAll()
self.sell(tick.lastPrice - 2, self.fixedSize, True)
else:
self.cancelAll()
self.sell(tick.lastPrice, self.fixedSize, False)
elif self.pos < 0:
# 如果持有空单,如果已经是买入价格反向N3个点,再次判断趋势,如果已经不符合,市价卖出。如果持有,清掉之前阻止单,改挂当前价位反向2个点阻止单。
if  tick.lastPrice - self.posPrice <= -3:
if TA.askBidVolumeDif() > 0:
self.cancelAll()
self.cover(tick.lastPrice + 2, self.fixedSize, True)
else:
self.cancelAll()
self.cover(tick.lastPrice, self.fixedSize, False)
else:
if self.pos > 0:
self.sell(tick.close, abs(self.pos),False)
elif self.pos < 0:
self.cover(tick.close, abs(self.pos),False)
elif self.pos == 0:
return
# ----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送(必须由用户继承实现)"""
# ----------------------------------------------------------------------
def onXminBar(self, bar):
"""收到X分钟K线"""
# ----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托变化推送(必须由用户继承实现)"""
pass
# ----------------------------------------------------------------------
def onTrade(self, trade):
self.posPrice = trade.price
# 同步数据到数据库
self.saveSyncData()
# 发出状态更新事件
self.putEvent()
# ----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止单推送"""
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
CTAtemplate 加入新类TickArrayManager
########################################################################
class TickArrayManager(object):
"""
Tick序列管理工具,负责:
1. Tick时间序列的维护
2. 常用技术指标的计算
"""
# ----------------------------------------------------------------------
def __init__(self, size=10):
"""Constructor"""
self.count = 0  # 缓存计数
self.size = size  # 缓存大小
self.inited = False  # True if count>=size
self.TicklastPriceArray = np.zeros(self.size)
self.TickaskVolume1Array = np.zeros(self.size)
self.TickbidVolume1Array = np.zeros(self.size)
self.TickaskPrice1Array = np.zeros(self.size)
self.TickbidPrice1Array = np.zeros(self.size)
self.TickopenInterestArray = np.zeros(self.size)
self.TickvolumeArray = np.zeros(self.size)
# ----------------------------------------------------------------------
def updateTick(self, tick):
"""更新tick Array"""
self.count += 1
if not self.inited and self.count >= self.size:
self.inited = True
self.TicklastPriceArray[0:self.size - 1] = self.TicklastPriceArray[1:self.size]
self.TickaskVolume1Array[0:self.size - 1] = self.TickaskVolume1Array[1:self.size]
self.TickbidVolume1Array[0:self.size - 1] = self.TickbidVolume1Array[1:self.size]
self.TickaskPrice1Array[0:self.size - 1] = self.TickaskPrice1Array[1:self.size]
self.TickbidPrice1Array[0:self.size - 1] = self.TickbidPrice1Array[1:self.size]
self.TickopenInterestArray[0:self.size - 1] = self.TickopenInterestArray[1:self.size]
self.TickvolumeArray[0:self.size - 1] = self.TickvolumeArray[1:self.size]
self.TicklastPriceArray[-1] = tick.lastPrice
self.TickaskVolume1Array[-1] = tick.askVolume1
self.TickbidVolume1Array[-1] = tick.bidVolume1
self.TickaskPrice1Array[-1] = tick.askPrice1
self.TickbidPrice1Array[-1] = tick.bidPrice1
self.TickopenInterestArray[-1] = tick.openInterest
self.TickvolumeArray[-1] = tick.volume
def askBidVolumeDif(self):
return (self.TickaskPrice1Array.sum() - self.TickbidVolume1Array.sum())

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!