-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathctaTemplate.html
478 lines (427 loc) · 34 KB
/
ctaTemplate.html
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" integrity="sha384-9eLZqc9ds8eNjO3TmqPeYcDj8n+Qfa4nuSiGYa6DjLNcv9BtN69ZIulL9+8CqC9Y" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<link href="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
<style>
.task-list-item { list-style-type: none; } .task-list-item-checkbox { margin-left: -20px; vertical-align: middle; }
</style>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'HelveticaNeue-Light', 'Ubuntu', 'Droid Sans', sans-serif;
font-size: 14px;
line-height: 1.6;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.js"></script>
</head>
<body>
<p>ctaTemplate类所在路径vnpy/trader/app/ctaStrategy/ctaTemplate.py</p>
<pre><code class="language-python"><div><span class="hljs-string">'''
本文件包含了CTA引擎中的策略开发用模板,开发策略时需要继承CtaTemplate类。
'''</span>
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime,timedelta,time
<span class="hljs-keyword">import</span> talib
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> defaultdict
<span class="hljs-keyword">from</span> vnpy.trader.vtConstant <span class="hljs-keyword">import</span> *
<span class="hljs-keyword">from</span> vnpy.trader.vtObject <span class="hljs-keyword">import</span> VtBarData
<span class="hljs-keyword">from</span> vnpy.trader.vtUtility <span class="hljs-keyword">import</span> BarGenerator, ArrayManager
<span class="hljs-keyword">from</span> vnpy.trader.utils.email <span class="hljs-keyword">import</span> mail
<span class="hljs-keyword">from</span> .ctaBase <span class="hljs-keyword">import</span> *
<span class="hljs-comment">########################################################################</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CtaTemplate</span><span class="hljs-params">(object)</span>:</span>
<span class="hljs-string">"""CTA策略模板"""</span>
<span class="hljs-comment"># 策略类的名称和作者</span>
className = <span class="hljs-string">'CtaTemplate'</span>
author = EMPTY_UNICODE
<span class="hljs-comment"># MongoDB数据库的名称,K线数据库默认为1分钟</span>
tickDbName = TICK_DB_NAME
barDbName = MINUTE_DB_NAME
<span class="hljs-comment"># 策略的基本参数</span>
name = EMPTY_UNICODE <span class="hljs-comment"># 策略实例名称</span>
vtSymbol = EMPTY_STRING <span class="hljs-comment"># 交易的合约vt系统代码</span>
productClass = EMPTY_STRING <span class="hljs-comment"># 产品类型(只有IB接口需要)</span>
currency = EMPTY_STRING <span class="hljs-comment"># 货币(只有IB接口需要)</span>
<span class="hljs-comment"># 策略的基本变量,由引擎管理</span>
inited = <span class="hljs-keyword">False</span> <span class="hljs-comment"># 是否进行了初始化</span>
trading = <span class="hljs-keyword">False</span> <span class="hljs-comment"># 是否启动交易,由引擎管理</span>
symbolList = [] <span class="hljs-comment"># 策略的标的列表</span>
<span class="hljs-comment"># 参数列表,保存了参数的名称,列表里的内容最后会显示在qt界面上</span>
paramList = [<span class="hljs-string">'name'</span>,
<span class="hljs-string">'className'</span>,
<span class="hljs-string">'author'</span>,
<span class="hljs-string">'symbolList'</span>]
<span class="hljs-comment"># 变量列表,保存了变量的名称,列表里的内容最后会显示在qt界面上</span>
varList = [<span class="hljs-string">'inited'</span>,
<span class="hljs-string">'trading'</span>,
<span class="hljs-string">'posDict'</span>]
<span class="hljs-comment"># 同步列表,保存了需要保存到数据库的变量名称</span>
syncList = [<span class="hljs-string">'posDict'</span>,
<span class="hljs-string">'eveningDict'</span>,
<span class="hljs-string">'accountDict'</span>]
<span class="hljs-comment"># ----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, ctaEngine, setting)</span>:</span>
<span class="hljs-string">"""Constructor"""</span>
self.ctaEngine = ctaEngine <span class="hljs-comment">#</span>
self.posDict = {}<span class="hljs-comment">#仓位字典,形式如同{"eosusd_long":1,"eosusd_short":1}表明多空都有,自动在引擎内部生成</span>
self.eveningDict = {}<span class="hljs-comment">#保证金字典,一般不用</span>
self.accountDict = {}<span class="hljs-comment">#账户字典,暂时没用上还不知道干啥的</span>
<span class="hljs-comment"># 设置策略的参数</span>
</div></code></pre>
<p>通过setting里的key和value自动在类内部创建属性,通过往self.__dict__[key]=value的方式
不懂的话可以自行百度self.__dict__</p>
<pre><code class="language-python"><div> <span class="hljs-keyword">if</span> setting:
d = self.__dict__
<span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> self.paramList:
<span class="hljs-keyword">if</span> key <span class="hljs-keyword">in</span> setting:
d[key] = setting[key]
<span class="hljs-comment"># self.posDict = {}</span>
<span class="hljs-comment"># self.eveningDict = {}</span>
</div></code></pre>
<p>NotImplementedError可以实现c++的pure virtual的功能,就是说子类必须继承父类的方法并加以实现,否则就报错
引擎上会有四个功能键
初始化->onInit
启动->onStart
停止->onStop
恢复->onRestore</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onInit</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""初始化策略(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onStart</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""启动策略(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onStop</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""停止策略(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onRestore</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""恢复策略(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>程序通过websocket与交易所建立持久化连接,交易所会推送给tick数据
引擎内部会把tick数据处理成固定的数据格式
tick的数据格式如下</p>
<pre><code class="language-python"><div> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VtTickData</span><span class="hljs-params">(VtBaseData)</span>:</span>
<span class="hljs-string">"""Tick行情数据类"""</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""Constructor"""</span>
super(VtTickData, self).__init__()
<span class="hljs-comment"># 代码相关</span>
self.symbol = EMPTY_STRING <span class="hljs-comment"># 合约代码</span>
self.exchange = EMPTY_STRING <span class="hljs-comment"># 交易所代码</span>
self.vtSymbol = EMPTY_STRING <span class="hljs-comment"># 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码</span>
<span class="hljs-comment"># 成交数据</span>
self.lastPrice = EMPTY_FLOAT <span class="hljs-comment"># 最新成交价</span>
self.lastVolume = EMPTY_INT <span class="hljs-comment"># 最新成交量</span>
self.volume = EMPTY_INT <span class="hljs-comment"># 今天总成交量</span>
self.openInterest = EMPTY_INT <span class="hljs-comment"># 持仓量</span>
self.time = EMPTY_STRING <span class="hljs-comment"># 时间 11:20:56.5</span>
self.date = EMPTY_STRING <span class="hljs-comment"># 日期 20151009</span>
self.datetime = <span class="hljs-keyword">None</span> <span class="hljs-comment"># python的datetime时间对象</span>
<span class="hljs-comment"># 常规行情</span>
self.openPrice = EMPTY_FLOAT <span class="hljs-comment"># 今日开盘价</span>
self.highPrice = EMPTY_FLOAT <span class="hljs-comment"># 今日最高价</span>
self.lowPrice = EMPTY_FLOAT <span class="hljs-comment"># 今日最低价</span>
self.preClosePrice = EMPTY_FLOAT
self.upperLimit = EMPTY_FLOAT <span class="hljs-comment"># 涨停价</span>
self.lowerLimit = EMPTY_FLOAT <span class="hljs-comment"># 跌停价</span>
<span class="hljs-comment"># 五档行情</span>
self.bidPrice1 = EMPTY_FLOAT
self.bidPrice2 = EMPTY_FLOAT
self.bidPrice3 = EMPTY_FLOAT
self.bidPrice4 = EMPTY_FLOAT
self.bidPrice5 = EMPTY_FLOAT
self.askPrice1 = EMPTY_FLOAT
self.askPrice2 = EMPTY_FLOAT
self.askPrice3 = EMPTY_FLOAT
self.askPrice4 = EMPTY_FLOAT
self.askPrice5 = EMPTY_FLOAT
self.bidVolume1 = EMPTY_INT
self.bidVolume2 = EMPTY_INT
self.bidVolume3 = EMPTY_INT
self.bidVolume4 = EMPTY_INT
self.bidVolume5 = EMPTY_INT
self.askVolume1 = EMPTY_INT
self.askVolume2 = EMPTY_INT
self.askVolume3 = EMPTY_INT
self.askVolume4 = EMPTY_INT
self.askVolume5 = EMPTY_INT
</div></code></pre>
<p>会把tick传入如下函数,在策略里继承实现</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onTick</span><span class="hljs-params">(self, tick)</span>:</span>
<span class="hljs-string">"""收到行情TICK推送(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>onOrder会在订单发生变化的时候,进行推送,通过websocket传来
websocket会订阅很多频道,订单这个单独有一个频道
行情数据也有单独的频道,传来的是json格式,内部处理成order的数据格式,
格式如下</p>
<pre><code class="language-python"><div> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VtOrderData</span><span class="hljs-params">(VtBaseData)</span>:</span>
<span class="hljs-string">"""订单数据类"""</span>
<span class="hljs-comment">#----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""Constructor"""</span>
super(VtOrderData, self).__init__()
<span class="hljs-comment"># 代码编号相关</span>
self.symbol = EMPTY_STRING <span class="hljs-comment"># 合约代码</span>
self.exchange = EMPTY_STRING <span class="hljs-comment"># 交易所代码</span>
self.vtSymbol = EMPTY_STRING <span class="hljs-comment"># 索引,统一格式:f"{symbol}.{exchange}"</span>
self.orderID = EMPTY_STRING <span class="hljs-comment"># 订单编号 gateway内部自己生成的编号</span>
self.vtOrderID = EMPTY_STRING <span class="hljs-comment"># 索引,统一格式:f"{gatewayName}.{orderId}"</span>
<span class="hljs-comment"># 报单相关</span>
self.direction = EMPTY_UNICODE <span class="hljs-comment"># 报单方向</span>
self.offset = EMPTY_UNICODE <span class="hljs-comment"># 报单开平仓</span>
self.price = EMPTY_FLOAT <span class="hljs-comment"># 报单价格</span>
self.totalVolume = EMPTY_INT <span class="hljs-comment"># 报单总数量</span>
self.tradedVolume = EMPTY_INT <span class="hljs-comment"># 报单成交数量</span>
self.status = EMPTY_UNICODE <span class="hljs-comment"># 报单状态</span>
self.orderTime = EMPTY_STRING <span class="hljs-comment"># 发单时间</span>
self.cancelTime = EMPTY_STRING <span class="hljs-comment"># 撤单时间</span>
<span class="hljs-comment"># CTP/LTS相关</span>
self.frontID = EMPTY_INT <span class="hljs-comment"># 前置机编号</span>
self.sessionID = EMPTY_INT
</div></code></pre>
<p>交易所会发来一个orderID作为唯一标志,传递某一个订单的状态order.status
有“未成交”,“部分成交”,“全部成交”,“已撤销”,“未知”(未知是引擎内部处理的,用于应付掉线情况)
vtOrderID是引擎内部根据orderID维护的一个列表,也是唯一的,按从1开始的顺序递增,方便处理,
所以一般在策略里都使用order.vtOrderID
order.vtSymbol是你交易的品种
order.direction是你下的这单的方向,多或空
order.offset是你下的这单是开仓还是平仓
buy->“多” “开仓”
sell->“空” “平仓”
short->“空” “开仓”
cover->“多” “平仓”
order.price报单价格
order.totalVolume报单总数量
order.tradedVolume成交数量</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onOrder</span><span class="hljs-params">(self, order)</span>:</span>
<span class="hljs-string">"""收到委托变化推送(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>如果是完全成交或部分成交的order.status会被推到onTrade里,顺序在onOrder之后,
所以如果要在onTrade里写东西,最好不要写交易逻辑,不然会要先运行完onOrder再过来,速度跟不上
或者onOrder自己实现异步的,不阻塞到onTrade。
trade的数据格式如下</p>
<pre><code class="language-python"><div> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VtTradeData</span><span class="hljs-params">(VtBaseData)</span>:</span>
<span class="hljs-string">"""
成交数据类
一般来说,一个VtOrderData可能对应多个VtTradeData:一个订单可能多次部分成交
"""</span>
<span class="hljs-comment">#----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""Constructor"""</span>
super(VtTradeData, self).__init__()
<span class="hljs-comment"># 代码编号相关</span>
self.symbol = EMPTY_STRING <span class="hljs-comment"># 合约代码</span>
self.exchange = EMPTY_STRING <span class="hljs-comment"># 交易所代码</span>
self.vtSymbol = EMPTY_STRING <span class="hljs-comment"># 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码</span>
self.tradeID = EMPTY_STRING <span class="hljs-comment"># 成交编号 gateway内部自己生成的编号</span>
self.vtTradeID = EMPTY_STRING <span class="hljs-comment"># 成交在vt系统中的唯一编号,通常是 Gateway名.成交编号</span>
self.orderID = EMPTY_STRING <span class="hljs-comment"># 订单编号</span>
self.vtOrderID = EMPTY_STRING <span class="hljs-comment"># 订单在vt系统中的唯一编号,通常是 Gateway名.订单编号</span>
<span class="hljs-comment"># 成交相关</span>
self.direction = EMPTY_UNICODE <span class="hljs-comment"># 成交方向</span>
self.offset = EMPTY_UNICODE <span class="hljs-comment"># 成交开平仓</span>
self.price = EMPTY_FLOAT <span class="hljs-comment"># 成交价格</span>
self.volume = EMPTY_INT <span class="hljs-comment"># 成交数量</span>
self.tradeTime = EMPTY_STRING <span class="hljs-comment"># 成交时间</span>
</div></code></pre>
<p>部分成交和全部成交会被推送到onTrade函数里</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onTrade</span><span class="hljs-params">(self, trade)</span>:</span>
<span class="hljs-string">"""收到成交推送(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>bar就是传统的k线,数据格式如下</p>
<pre><code class="language-python"><div> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VtBarData</span><span class="hljs-params">(VtBaseData)</span>:</span>
<span class="hljs-string">"""K线数据"""</span>
<span class="hljs-comment">#----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""Constructor"""</span>
super(VtBarData, self).__init__()
self.vtSymbol = EMPTY_STRING <span class="hljs-comment"># vt系统代码</span>
self.symbol = EMPTY_STRING <span class="hljs-comment"># 代码</span>
self.exchange = EMPTY_STRING <span class="hljs-comment"># 交易所</span>
self.open = EMPTY_FLOAT <span class="hljs-comment"># OHLC</span>
self.high = EMPTY_FLOAT
self.low = EMPTY_FLOAT
self.close = EMPTY_FLOAT
self.date = EMPTY_STRING <span class="hljs-comment"># bar开始的时间,日期</span>
self.time = EMPTY_STRING <span class="hljs-comment"># 时间</span>
self.datetime = <span class="hljs-keyword">None</span> <span class="hljs-comment"># python的datetime时间对象</span>
self.volume = EMPTY_INT <span class="hljs-comment"># 成交量</span>
self.openInterest = EMPTY_INT <span class="hljs-comment"># 持仓量 </span>
self.interval = EMPTY_UNICODE <span class="hljs-comment"># K线周期</span>
</div></code></pre>
<p>onBar默认是一分钟推送一次,第一次推送在第一个整分钟。</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onBar</span><span class="hljs-params">(self, bar)</span>:</span>
<span class="hljs-string">"""收到Bar推送(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>停止单,目前还没用过,等用过再来补充</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">onStopOrder</span><span class="hljs-params">(self, so)</span>:</span>
<span class="hljs-string">"""收到停止单推送(必须由用户继承实现)"""</span>
<span class="hljs-keyword">raise</span> NotImplementedError
</div></code></pre>
<p>buy,sell,short,cover是四种下单方式,在onOrder里介绍了
这里要说明的是这四种下单方式的函数会返回一个list,list里只有一个元素,这个元素是vtOrderID</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">buy</span><span class="hljs-params">(self, vtSymbol, price, volume, priceType = PRICETYPE_LIMITPRICE,
stop=False)</span>:</span>
<span class="hljs-string">"""买开"""</span>
<span class="hljs-keyword">return</span> self.sendOrder(CTAORDER_BUY, vtSymbol, price, volume,
priceType, stop)
<span class="hljs-comment"># ----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sell</span><span class="hljs-params">(self, vtSymbol, price, volume, priceType = PRICETYPE_LIMITPRICE,
stop=False)</span>:</span>
<span class="hljs-string">"""卖平"""</span>
<span class="hljs-keyword">return</span> self.sendOrder(CTAORDER_SELL, vtSymbol, price, volume,
priceType, stop)
<span class="hljs-comment"># ----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">short</span><span class="hljs-params">(self, vtSymbol, price, volume, priceType =
PRICETYPE_LIMITPRICE, stop=False)</span>:</span>
<span class="hljs-string">"""卖开"""</span>
<span class="hljs-keyword">return</span> self.sendOrder(CTAORDER_SHORT, vtSymbol, price, volume,
priceType, stop)
<span class="hljs-comment"># ----------------------------------------------------------------------</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cover</span><span class="hljs-params">(self, vtSymbol, price, volume, priceType =
PRICETYPE_LIMITPRICE, stop=False)</span>:</span>
<span class="hljs-string">"""买平"""</span>
<span class="hljs-keyword">return</span> self.sendOrder(CTAORDER_COVER, vtSymbol, price, volume,
priceType, stop)
</div></code></pre>
<p>buy,sell,short,cover调用此函数发单</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sendOrder</span><span class="hljs-params">(self, orderType, vtSymbol, price, volume, priceType =
PRICETYPE_LIMITPRICE, stop=False)</span>:</span>
<span class="hljs-string">"""发送委托"""</span>
<span class="hljs-keyword">if</span> self.trading:
<span class="hljs-comment"># 如果stop为True,则意味着发本地停止单</span>
<span class="hljs-keyword">if</span> stop:
vtOrderIDList = self.ctaEngine.sendStopOrder(vtSymbol, orderType, price, volume, priceType, self)
<span class="hljs-keyword">else</span>:
vtOrderIDList = self.ctaEngine.sendOrder(vtSymbol, orderType, price, volume, priceType, self)
<span class="hljs-keyword">return</span> vtOrderIDList
<span class="hljs-keyword">else</span>:
<span class="hljs-comment"># 交易停止时发单返回空字符串</span>
<span class="hljs-keyword">return</span> []
</div></code></pre>
<p>cancelOrder取消订单,传入参数是vtOrderID,每次发单buy,sell,cover,short返回值都是一个列表
列表里只有一个元素就是vtOrderID,把那个vtOrderID传入cancelOrder函数,完成撤单</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cancelOrder</span><span class="hljs-params">(self, vtOrderID)</span>:</span>
<span class="hljs-string">"""撤单"""</span>
<span class="hljs-comment"># 如果发单号为空字符串,则不进行后续操作</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> vtOrderID:
<span class="hljs-keyword">return</span>
<span class="hljs-keyword">if</span> STOPORDERPREFIX <span class="hljs-keyword">in</span> vtOrderID:
self.ctaEngine.cancelStopOrder(vtOrderID)
<span class="hljs-keyword">else</span>:
self.ctaEngine.cancelOrder(vtOrderID)
</div></code></pre>
<p>cancelAll是循环vtOrderID去发撤单,所以为了程序的精细化处理一般不用cancelAll</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cancelAll</span><span class="hljs-params">(self)</span>:</span>
<span class="hljs-string">"""全部撤单"""</span>
self.ctaEngine.cancelAll(self.name)
</div></code></pre>
<p>如上,暂没有使用过StopOrder</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">cancelAllStopOrder</span><span class="hljs-params">(self)</span>:</span>
self.ctaEngine.cancelAllStopOrder(self.name)
</div></code></pre>
<p>batchCancelOrder批量撤单,如果单特别多,使用cancelOrder会慢,所以用batchCancelOrder</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">batchCancelOrder</span><span class="hljs-params">(self,vtOrderIDList)</span>:</span>
<span class="hljs-keyword">if</span> len(vtOrderIDList)><span class="hljs-number">5</span>:
self.writeCtaLog(<span class="hljs-string">u'策略发送批量撤单委托失败,单量超过5张'</span>)
<span class="hljs-keyword">return</span>
self.ctaEngine.batchCancelOrder(vtOrderIDList)
</div></code></pre>
<p>回测中使用,但实盘没有tick可以load所以不loadtick</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">loadTick</span><span class="hljs-params">(self, hours=<span class="hljs-number">1</span>)</span>:</span>
<span class="hljs-string">"""读取tick数据"""</span>
<span class="hljs-keyword">return</span> self.ctaEngine.loadTick(self.tickDbName, self.symbolList,
hours)
</div></code></pre>
<p>加载bar数据</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">loadBar</span><span class="hljs-params">(self, hours=<span class="hljs-number">1</span>)</span>:</span>
<span class="hljs-string">"""读取bar数据"""</span>
<span class="hljs-keyword">return</span> self.ctaEngine.loadBar(self.barDbName, self.symbolList, hours)
</div></code></pre>
<p>非常重要的功能,会把日志打下来,方便复盘,但记住别放在交易逻辑之前,尽量放在之后</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">writeCtaLog</span><span class="hljs-params">(self, content)</span>:</span>
<span class="hljs-string">"""记录CTA日志"""</span>
content = self.name + <span class="hljs-string">':'</span> + content
self.ctaEngine.writeCtaLog(content)
</div></code></pre>
<p>loadHistoryBar可以在实盘中通过交易所提供的restful Api获取一定数量的bar,</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">loadHistoryBar</span><span class="hljs-params">(self,vtSymbol,type_,size= None,since = None)</span>:</span>
<span class="hljs-string">"""策略开始前下载历史数据"""</span>
<span class="hljs-keyword">if</span> type_ <span class="hljs-keyword">in</span> [<span class="hljs-string">"1min"</span>,<span class="hljs-string">"5min"</span>,<span class="hljs-string">"15min"</span>,<span class="hljs-string">"30min"</span>,<span class="hljs-string">"60min"</span>,<span class="hljs-string">"120min"</span>,<span class="hljs-string">"240min"</span>,
<span class="hljs-string">"360min"</span>,<span class="hljs-string">"480min"</span>,<span class="hljs-string">"1day"</span>,<span class="hljs-string">"1week"</span>,<span class="hljs-string">"1month"</span>]:
data = self.ctaEngine.loadHistoryBar(vtSymbol,type_,size,since)
lastbar = data[<span class="hljs-number">-1</span>]
<span class="hljs-keyword">if</span> <span class="hljs-string">'min'</span> <span class="hljs-keyword">in</span> type_:
minute = int(type_[:<span class="hljs-number">-3</span>])
<span class="hljs-keyword">if</span> datetime.now() < (lastbar.datetime + timedelta(seconds =
<span class="hljs-number">60</span>*minute)):
self.writeCtaLog(<span class="hljs-string">u'加载历史数据抛弃最后一个非完整K线,频率%s,时
间%s'</span>%(type_, lastbar.datetime))
data = data[:<span class="hljs-number">-1</span>]
<span class="hljs-keyword">return</span> data
<span class="hljs-keyword">else</span>:
self.writeCtaLog(
<span class="hljs-string">u'下载历史数据参数错误,请参考以下参数["1min","5min","15min",
"30min","60min","120min","240min","360min","480min","1day",
"1week","1month"],同时size建议不大于2000'</span>)
<span class="hljs-keyword">return</span>
</div></code></pre>
<p>可以给自己发邮件,在实盘中启用</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">mail</span><span class="hljs-params">(self,my_context)</span>:</span>
<span class="hljs-string">"""邮件发送模块"""</span>
<span class="hljs-keyword">if</span> self.ctaEngine.engineType == ENGINETYPE_BACKTESTING:
<span class="hljs-keyword">pass</span>
<span class="hljs-keyword">else</span>:
msg = mail(my_context,self)
self.writeCtaLog(<span class="hljs-string">'%s'</span>%msg)
</div></code></pre>
<p>注册一个函数onXmimBar写函数名字
xmin写分钟数,必须是整分钟,比如5,15 这种,可以参考行情软件上的k线时间
然后会自动生成两个变量通过setattr(key,value)
一个是BarGenerator对象的
一个是ArrayManager对象的
名字是</p>
<pre><code class="language-auto"><div># if xmin:
# variable = "bg%sDict"%xmin
# variable2 = "am%sDict"%xmin
# else:
# variable = "bgDict"
# variable2 = "amDict"
</div></code></pre>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generateBarDict</span><span class="hljs-params">(self, onBar, xmin=<span class="hljs-number">0</span>, onXminBar=None, size = <span class="hljs-number">100</span>,
alignment=<span class="hljs-string">'sharp'</span>, marketClose = <span class="hljs-params">(<span class="hljs-number">23</span>,<span class="hljs-number">59</span>)</span>)</span>:</span>
<span class="hljs-keyword">if</span> xmin:
variable = <span class="hljs-string">"bg%sDict"</span>%xmin
variable2 = <span class="hljs-string">"am%sDict"</span>%xmin
<span class="hljs-keyword">else</span>:
variable = <span class="hljs-string">"bgDict"</span>
variable2 = <span class="hljs-string">"amDict"</span>
bgDict= {
sym: BarGenerator(onBar,xmin,onXminBar, alignment=alignment,
marketClose=marketClose)
<span class="hljs-keyword">for</span> sym <span class="hljs-keyword">in</span> self.symbolList }
amDict = {
sym: ArrayManager(size)
<span class="hljs-keyword">for</span> sym <span class="hljs-keyword">in</span> self.symbolList }
setattr(self, variable, bgDict)
setattr(self, variable2, amDict)
</div></code></pre>
<p>秒级别的bar,类似分钟级别的参数,一般是给高频,而且秒级别的噪声很大,一般需要很长的研究过程</p>
<pre><code class="language-python"><div> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generateHFBar</span><span class="hljs-params">(self,xSecond,size = <span class="hljs-number">60</span>)</span>:</span>
self.hfDict = {sym: BarGenerator(self.onHFBar,xSecond = xSecond)
<span class="hljs-keyword">for</span> sym <span class="hljs-keyword">in</span> self.symbolList}
self.amhfDict = {sym: ArrayManager(size) <span class="hljs-keyword">for</span> sym <span class="hljs-keyword">in</span> self.symbolList}
</div></code></pre>
</body>
</html>