-
Notifications
You must be signed in to change notification settings - Fork 94
/
talib-tutorial.html
518 lines (452 loc) · 39.8 KB
/
talib-tutorial.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
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
<!DOCTYPE html>
<html lang="zh"
>
<head>
<title>使用TA-Lib在vn.trader上开发CTA交易策略 - vn.py</title>
<!-- Using the latest rendering mode for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/images/favicon.png" rel="icon">
<link rel="canonical" href="/talib-tutorial.html">
<meta name="author" content="用Python的交易员" />
<meta name="description" content="TA-Lib简介 作为一套被业界广泛应用的开源技术分析库(包含技术指标计算和K线模式识别等),TA-Lib自2001年发布以来已经有了十多年的历史。TA-Lib中一共包含大约125个技术指标的计算函数,同时提供了包括C/C++、Java、Perl、Python等多种语言的API。 有什么用 简单来说TA-Lib就是提供了一堆经过长期实践检验的技术指标计算函数。基于现成的计算函数,开发新策略雏形、快速验证某个灵感的时间可以大幅缩短,否则想象一下每开发个策略都要自己实现要用的技术指标,未免太浪费时间。 但是除此以外,TA-Lib还可以有一些其他的用法,举两个例子。 百科全书 坚持每天收盘后选一个自己没用过的指标,输入数据,画个图、跑个回测,开发量化策略很很多其他的技术一样都是熟能生巧。 另外,所有的技术指标在被开发出来的时候,背后都有一定的金融逻辑原理(行为金融学)的支撑,生搬硬套固然不可取,但是放着前人经验完全不看,整天凭自己的空想就弄个机器学习算法在数据上瞎折腾岂不是更浪费时间? Alpha库 很大一部分CTA类的策略可以总结为几个简单的逻辑框架,比如趋势策略通常可以分解成以下部分:趋势信号(通常是基于某几个参数计算出来的指标值超过某个阈值)、信号过滤(和趋势信号类似)、出场方案(固定点数/百分比的止盈和止损,移动止损)。 因此把逻辑框架的代码搭好后,就可以通过机器学习算法来实现一种自动的策略开发方式: 从TA-Lib中选取两个指标分别作为趋势信号和信号过滤,结合止损、止盈方案 ..." />
<meta property="og:site_name" content="vn.py" />
<meta property="og:type" content="article"/>
<meta property="og:title" content="使用TA-Lib在vn.trader上开发CTA交易策略"/>
<meta property="og:url" content="/talib-tutorial.html"/>
<meta property="og:description" content="TA-Lib简介 作为一套被业界广泛应用的开源技术分析库(包含技术指标计算和K线模式识别等),TA-Lib自2001年发布以来已经有了十多年的历史。TA-Lib中一共包含大约125个技术指标的计算函数,同时提供了包括C/C++、Java、Perl、Python等多种语言的API。 有什么用 简单来说TA-Lib就是提供了一堆经过长期实践检验的技术指标计算函数。基于现成的计算函数,开发新策略雏形、快速验证某个灵感的时间可以大幅缩短,否则想象一下每开发个策略都要自己实现要用的技术指标,未免太浪费时间。 但是除此以外,TA-Lib还可以有一些其他的用法,举两个例子。 百科全书 坚持每天收盘后选一个自己没用过的指标,输入数据,画个图、跑个回测,开发量化策略很很多其他的技术一样都是熟能生巧。 另外,所有的技术指标在被开发出来的时候,背后都有一定的金融逻辑原理(行为金融学)的支撑,生搬硬套固然不可取,但是放着前人经验完全不看,整天凭自己的空想就弄个机器学习算法在数据上瞎折腾岂不是更浪费时间? Alpha库 很大一部分CTA类的策略可以总结为几个简单的逻辑框架,比如趋势策略通常可以分解成以下部分:趋势信号(通常是基于某几个参数计算出来的指标值超过某个阈值)、信号过滤(和趋势信号类似)、出场方案(固定点数/百分比的止盈和止损,移动止损)。 因此把逻辑框架的代码搭好后,就可以通过机器学习算法来实现一种自动的策略开发方式: 从TA-Lib中选取两个指标分别作为趋势信号和信号过滤,结合止损、止盈方案 ..."/>
<meta property="article:published_time" content="2016-03-01" />
<meta property="article:section" content="文章" />
<meta property="article:author" content="用Python的交易员" />
<!-- Bootstrap -->
<link rel="stylesheet" href="/theme/css/bootstrap.readable.min.css" type="text/css"/>
<link href="/theme/css/font-awesome.min.css" rel="stylesheet">
<link href="/theme/css/pygments/monokai.css" rel="stylesheet">
<link rel="stylesheet" href="/theme/css/style.css" type="text/css"/>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?e8c7573f82d43fa50c895a8e28c49ceb";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="/" class="navbar-brand">
<img src="/images/favicon.png" width=""/> vn.py </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
<li><a href="/pages/quickstart.html">
Quick Start
</a></li>
<li><a href="/pages/blog.html">
日志
</a></li>
<li><a href="/pages/screenshot.html">
截图
</a></li>
<li><a href="/pages/community.html">
社区
</a></li>
<li><a href="/pages/api.html">
API接口
</a></li>
<li><a href="/pages/download.html">
下载
</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="/archives.html"><i class="fa fa-th-list"></i><span class="icon-label">Archives</span></a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
</div> <!-- /.navbar -->
<!-- Banner -->
<style>
#banner{
background-image:url("/images/banner.png");
}
</style>
<div id="banner">
<div class="container">
<div class="copy">
<h1>vn.py</h1>
<p class="intro">Developed by traders, for traders.</p>
</div>
</div>
</div><!-- End Banner -->
<div class="container">
<div class="row">
<div class="col-sm-9">
<section id="content">
<article>
<header class="page-header">
<h1>
<a href="/talib-tutorial.html"
rel="bookmark"
title="Permalink to 使用TA-Lib在vn.trader上开发CTA交易策略">
使用TA-Lib在vn.trader上开发CTA交易策略
</a>
</h1>
</header>
<div class="entry-content">
<div class="panel">
<div class="panel-body">
<footer class="post-info">
<span class="label label-default">Date</span>
<span class="published">
<i class="fa fa-calendar"></i><time datetime="2016-03-01T13:58:42+08:00"> 2016-03-01(周二)</time>
</span>
</footer><!-- /.post-info --> </div>
</div>
<h2>TA-Lib简介</h2>
<p>作为一套被业界广泛应用的开源技术分析库(包含技术指标计算和K线模式识别等),TA-Lib自2001年发布以来已经有了十多年的历史。TA-Lib中一共包含大约125个技术指标的计算函数,同时提供了包括C/C++、Java、Perl、Python等多种语言的API。</p>
<h2>有什么用</h2>
<p>简单来说TA-Lib就是提供了一堆经过长期实践检验的技术指标计算函数。基于现成的计算函数,开发新策略雏形、快速验证某个灵感的时间可以大幅缩短,否则想象一下每开发个策略都要自己实现要用的技术指标,未免太浪费时间。</p>
<p>但是除此以外,TA-Lib还可以有一些其他的用法,举两个例子。</p>
<p><strong>百科全书 </strong></p>
<p>坚持每天收盘后选一个自己没用过的指标,输入数据,画个图、跑个回测,开发量化策略很很多其他的技术一样都是熟能生巧。</p>
<p>另外,所有的技术指标在被开发出来的时候,背后都有一定的金融逻辑原理(行为金融学)的支撑,生搬硬套固然不可取,但是放着前人经验完全不看,整天凭自己的空想就弄个机器学习算法在数据上瞎折腾岂不是更浪费时间?</p>
<p><strong>Alpha库</strong></p>
<p>很大一部分CTA类的策略可以总结为几个简单的逻辑框架,比如趋势策略通常可以分解成以下部分:趋势信号(通常是基于某几个参数计算出来的指标值超过某个阈值)、信号过滤(和趋势信号类似)、出场方案(固定点数/百分比的止盈和止损,移动止损)。</p>
<p>因此把逻辑框架的代码搭好后,就可以通过机器学习算法来实现一种自动的策略开发方式:</p>
<ol>
<li>
<p>从TA-Lib中选取两个指标分别作为趋势信号和信号过滤,结合止损、止盈方案,生成一个策略;</p>
</li>
<li>
<p>基于某一组历史数据(如股指的1分钟行情),通过遗传算法来对以上的参数进行光与优化;</p>
</li>
<li>
<p>两个指标的参数加起来通常不会超过10个,再加上止盈、止损、移动止损的参数,总参数不会超过15个,在一组高达十几万个数据点的时间序列上进行回测,过度拟合的可能性不大;</p>
</li>
<li>
<p>现在云服务器价格也不贵,租一个核多一点的,把算法和数据丢上去7×24小时的跑,Alpha值达到一定标准的策略存下来;</p>
</li>
<li>
<p>把上一步中保存下来的策略作为雏形,研究员再来进行针对性的有效性验证和更精细化的策略改进,把策略开发变成有的放矢,而不是盲人摸象。</p>
</li>
</ol>
<p>这种策略开发方式使用传统的商业软件(如TB、MC等)几乎不可能实现,而Python这类开源软件就成为了最好的选择,用户可以自行决定几乎所有的算法(指标如何选择、遗传算法优化参数时如何迭代等等)。</p>
<h2>怎么安装</h2>
<p>尽管TA-Lib原生提供了基于SWIG封装的Python API,但是由于性能和编译不方便的原因,作者推荐Github上的一位开发者mrjbq7基于Cython封装的版本。</p>
<p>安装过程:</p>
<ol>
<li>
<p>在<a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib">这里</a>下载<strong>TA_Lib-0.4.9-cp27-none-win32.whl</strong>放到桌面上,也就是vn.py建议的运行环境Anaconda 2.7 32位</p>
</li>
<li>
<p>在桌面上按住Shift点击鼠标右键后,选择<strong>在此处打开命令窗口</strong>打开cmd</p>
</li>
<li>
<p>安装wheel包,在cmd中运行:</p>
<blockquote>
<p>pip install wheel</p>
</blockquote>
</li>
<li>
<p>安装TA-Lib,在cmd中运行:</p>
<blockquote>
<p>pip install TA_Lib-0.4.9-cp27-none-win32.whl</p>
</blockquote>
</li>
<li>
<p>打开Python,运行:</p>
<blockquote>
<p>import talib</p>
</blockquote>
<p>没有报错则说明安装成功</p>
</li>
</ol>
<p>一定要尝试自己编译的用户,可以根据<a href="http://mrjbq7.github.io/ta-lib/install.html">该项目的网站</a>上的教程来安装。作者的两台电脑,一台直接安装成功,另一台安装了MinGW的电脑则报GCC编译错误(其实自己编译没有任何意义,感谢加州大学欧文分校打包的whl文件,省去了很多麻烦)。</p>
<p>Linux下的安装建议使用Anaconda的conda工具:</p>
<blockquote>
<p>conda install -c quantopian ta-lib=0.4.9</p>
</blockquote>
<p>具体可以参考这里:<a href="https://anaconda.org/Quantopian/ta-lib">https://anaconda.org/Quantopian/ta-lib</a></p>
<h2>DEMO</h2>
<p>下面这个策略DEMO可以直接在vn.trader的CTA模块中使用(回测、模拟交易),请不要用于实盘!</p>
<div class="highlight"><pre><span></span><span class="c1"># encoding: UTF-8</span>
<span class="kn">import</span> <span class="nn">talib</span> <span class="kn">as</span> <span class="nn">ta</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
<span class="kn">from</span> <span class="nn">ctaBase</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">ctaTemplate</span> <span class="kn">import</span> <span class="n">CtaTemplate</span>
<span class="c1">########################################################################</span>
<span class="k">class</span> <span class="nc">TalibDoubleSmaDemo</span><span class="p">(</span><span class="n">CtaTemplate</span><span class="p">):</span>
<span class="sd">"""基于Talib模块的双指数均线策略Demo"""</span>
<span class="n">className</span> <span class="o">=</span> <span class="s1">'TalibDoubleSmaDemo'</span>
<span class="n">author</span> <span class="o">=</span> <span class="s1">u'ideaplat'</span>
<span class="c1"># 策略参数</span>
<span class="n">fastPeriod</span> <span class="o">=</span> <span class="mi">5</span> <span class="c1"># 快速均线参数</span>
<span class="n">slowPeriod</span> <span class="o">=</span> <span class="mi">20</span> <span class="c1"># 慢速均线参数</span>
<span class="n">initDays</span> <span class="o">=</span> <span class="mi">5</span> <span class="c1"># 初始化数据所用的天数</span>
<span class="c1"># 策略变量</span>
<span class="n">bar</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">barMinute</span> <span class="o">=</span> <span class="n">EMPTY_STRING</span>
<span class="n">closeHistory</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># 缓存K线收盘价的数组</span>
<span class="n">maxHistory</span> <span class="o">=</span> <span class="mi">50</span> <span class="c1"># 最大缓存数量</span>
<span class="n">fastMa0</span> <span class="o">=</span> <span class="n">EMPTY_FLOAT</span> <span class="c1"># 当前最新的快速均线数值</span>
<span class="n">fastMa1</span> <span class="o">=</span> <span class="n">EMPTY_FLOAT</span> <span class="c1"># 上一根的快速均线数值</span>
<span class="n">slowMa0</span> <span class="o">=</span> <span class="n">EMPTY_FLOAT</span> <span class="c1"># 慢速均线数值</span>
<span class="n">slowMa1</span> <span class="o">=</span> <span class="n">EMPTY_FLOAT</span>
<span class="c1"># 参数列表,保存了参数的名称</span>
<span class="n">paramList</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'name'</span><span class="p">,</span>
<span class="s1">'className'</span><span class="p">,</span>
<span class="s1">'author'</span><span class="p">,</span>
<span class="s1">'vtSymbol'</span><span class="p">,</span>
<span class="s1">'fastPeriod'</span><span class="p">,</span>
<span class="s1">'slowPeriod'</span><span class="p">]</span>
<span class="c1"># 变量列表,保存了变量的名称</span>
<span class="n">varList</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'inited'</span><span class="p">,</span>
<span class="s1">'trading'</span><span class="p">,</span>
<span class="s1">'pos'</span><span class="p">,</span>
<span class="s1">'fastMa0'</span><span class="p">,</span>
<span class="s1">'fastMa1'</span><span class="p">,</span>
<span class="s1">'slowMa0'</span><span class="p">,</span>
<span class="s1">'slowMa1'</span><span class="p">]</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctaEngine</span><span class="p">,</span> <span class="n">setting</span><span class="p">):</span>
<span class="sd">"""Constructor"""</span>
<span class="nb">super</span><span class="p">(</span><span class="n">TalibDoubleSmaDemo</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">ctaEngine</span><span class="p">,</span> <span class="n">setting</span><span class="p">)</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onInit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""初始化策略(必须由用户继承实现)"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">writeCtaLog</span><span class="p">(</span><span class="s1">u'双SMA演示策略初始化'</span><span class="p">)</span>
<span class="n">initData</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">loadBar</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">initDays</span><span class="p">)</span>
<span class="k">for</span> <span class="n">bar</span> <span class="ow">in</span> <span class="n">initData</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">onBar</span><span class="p">(</span><span class="n">bar</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">putEvent</span><span class="p">()</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onStart</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""启动策略(必须由用户继承实现)"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">writeCtaLog</span><span class="p">(</span><span class="s1">u'双SMA演示策略启动'</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">putEvent</span><span class="p">()</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onStop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""停止策略(必须由用户继承实现)"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">writeCtaLog</span><span class="p">(</span><span class="s1">u'双SMA演示策略停止'</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">putEvent</span><span class="p">()</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onTick</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tick</span><span class="p">):</span>
<span class="sd">"""收到行情TICK推送(必须由用户继承实现)"""</span>
<span class="c1"># 计算K线</span>
<span class="n">tickMinute</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">minute</span>
<span class="k">if</span> <span class="n">tickMinute</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">barMinute</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">bar</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">onBar</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bar</span><span class="p">)</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">CtaBarData</span><span class="p">()</span>
<span class="n">bar</span><span class="o">.</span><span class="n">vtSymbol</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">vtSymbol</span>
<span class="n">bar</span><span class="o">.</span><span class="n">symbol</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">symbol</span>
<span class="n">bar</span><span class="o">.</span><span class="n">exchange</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">exchange</span>
<span class="n">bar</span><span class="o">.</span><span class="n">open</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span>
<span class="n">bar</span><span class="o">.</span><span class="n">high</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span>
<span class="n">bar</span><span class="o">.</span><span class="n">low</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span>
<span class="n">bar</span><span class="o">.</span><span class="n">close</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span>
<span class="n">bar</span><span class="o">.</span><span class="n">date</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">date</span>
<span class="n">bar</span><span class="o">.</span><span class="n">time</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">time</span>
<span class="n">bar</span><span class="o">.</span><span class="n">datetime</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">datetime</span> <span class="c1"># K线的时间设为第一个Tick的时间</span>
<span class="c1"># 实盘中用不到的数据可以选择不算,从而加快速度</span>
<span class="c1"># bar.volume = tick.volume</span>
<span class="c1"># bar.openInterest = tick.openInterest</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bar</span> <span class="o">=</span> <span class="n">bar</span> <span class="c1"># 这种写法为了减少一层访问,加快速度</span>
<span class="bp">self</span><span class="o">.</span><span class="n">barMinute</span> <span class="o">=</span> <span class="n">tickMinute</span> <span class="c1"># 更新当前的分钟</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># 否则继续累加新的K线</span>
<span class="n">bar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bar</span> <span class="c1"># 写法同样为了加快速度</span>
<span class="n">bar</span><span class="o">.</span><span class="n">high</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">high</span><span class="p">,</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span><span class="p">)</span>
<span class="n">bar</span><span class="o">.</span><span class="n">low</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">low</span><span class="p">,</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span><span class="p">)</span>
<span class="n">bar</span><span class="o">.</span><span class="n">close</span> <span class="o">=</span> <span class="n">tick</span><span class="o">.</span><span class="n">lastPrice</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onBar</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bar</span><span class="p">):</span>
<span class="sd">"""收到Bar推送(必须由用户继承实现)"""</span>
<span class="c1"># 把最新的收盘价缓存到列表中</span>
<span class="bp">self</span><span class="o">.</span><span class="n">closeHistory</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
<span class="c1"># 检查列表长度,如果超过缓存上限则移除最老的数据</span>
<span class="c1"># 这样是为了减少计算用的数据量,提高速度</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">closeHistory</span><span class="p">)</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">maxHistory</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">closeHistory</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># 如果小于缓存上限,则说明初始化数据尚未足够,不进行后续计算</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span>
<span class="c1"># 将缓存的收盘价数转化为numpy数组后,传入talib的函数SMA中计算</span>
<span class="n">closeArray</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">closeHistory</span><span class="p">)</span>
<span class="n">fastSMA</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">SMA</span><span class="p">(</span><span class="n">closeArray</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fastPeriod</span><span class="p">)</span>
<span class="n">slowSMA</span> <span class="o">=</span> <span class="n">ta</span><span class="o">.</span><span class="n">SMA</span><span class="p">(</span><span class="n">closeArray</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">slowPeriod</span><span class="p">)</span>
<span class="c1"># 读取当前K线和上一根K线的数值,用于判断均线交叉</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fastMa0</span> <span class="o">=</span> <span class="n">fastSMA</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fastMa1</span> <span class="o">=</span> <span class="n">fastSMA</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">slowMa0</span> <span class="o">=</span> <span class="n">slowSMA</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">slowMa1</span> <span class="o">=</span> <span class="n">slowSMA</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span>
<span class="c1"># 判断买卖</span>
<span class="n">crossOver</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fastMa0</span><span class="o">></span><span class="bp">self</span><span class="o">.</span><span class="n">slowMa0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">fastMa1</span><span class="o"><</span><span class="bp">self</span><span class="o">.</span><span class="n">slowMa1</span> <span class="c1"># 金叉上穿</span>
<span class="n">crossBelow</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fastMa0</span><span class="o"><</span><span class="bp">self</span><span class="o">.</span><span class="n">slowMa0</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">fastMa1</span><span class="o">></span><span class="bp">self</span><span class="o">.</span><span class="n">slowMa1</span> <span class="c1"># 死叉下穿</span>
<span class="c1"># 金叉和死叉的条件是互斥</span>
<span class="k">if</span> <span class="n">crossOver</span><span class="p">:</span>
<span class="c1"># 如果金叉时手头没有持仓,则直接做多</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buy</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># 如果有空头持仓,则先平空,再做多</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cover</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">buy</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># 死叉和金叉相反</span>
<span class="k">elif</span> <span class="n">crossBelow</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">short</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sell</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">short</span><span class="p">(</span><span class="n">bar</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># 发出状态更新事件</span>
<span class="bp">self</span><span class="o">.</span><span class="n">putEvent</span><span class="p">()</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onOrder</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">order</span><span class="p">):</span>
<span class="sd">"""收到委托变化推送(必须由用户继承实现)"""</span>
<span class="c1"># 对于无需做细粒度委托控制的策略,可以忽略onOrder</span>
<span class="k">pass</span>
<span class="c1"># ----------------------------------------------------------------------</span>
<span class="k">def</span> <span class="nf">onTrade</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">trade</span><span class="p">):</span>
<span class="sd">"""收到成交推送(必须由用户继承实现)"""</span>
<span class="c1"># 对于无需做细粒度委托控制的策略,可以忽略onOrder</span>
<span class="k">pass</span>
</pre></div>
<p>(感谢社区ideaplat用户贡献的代码!作者做了一些小修改。)</p>
<p>将上面的代码保存到一个talibDemo.py文件中后,参考vn.trader下ctaAlgo文件夹内的ctaBacktesting.py运行回测,也可以通过ctaSetting.py进行配置后,在vn.trader中进行模拟交易。</p>
<p>从上面的DEMO中我们可以看到,talib中的技术指标函数主要接受一个numpy数组作为原始数据及若干个指标算法中的参数作为输入,返回的数据也是一个numpy数组,使用起来非常方便。</p>
<p>注意缓存数据时使用的是Python列表而非numpy数组,主要原因是numpy数组的append方法本质是结合原数组中的数据和新的数据生成一个新的数组对象,相对于列表的append开销要高很多。</p>
</div>
<!-- /.entry-content -->
</article>
</section>
</div>
<div class="col-sm-3" id="sidebar">
<aside>
<section class="well well-sm">
<ul class="list-group list-group-flush">
<li class="list-group-item"><h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Social</span></h4>
<ul class="list-group" id="social">
<li class="list-group-item"><a href="http://github.com/vnpy/vnpy"><i class="fa fa-github-square fa-lg"></i> Github</a></li>
</ul>
</li>
<li class="list-group-item"><h4><i class="fa fa-external-link-square fa-lg"></i><span class="icon-label">Links</span></h4>
<ul class="list-group" id="links">
<li class="list-group-item">
<a href="http://www.vnpie.com" target="_blank">
官方论坛 - 维恩的派
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.trader" target="_blank">
交易平台
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.event" target="_blank">
事件引擎
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.ctp" target="_blank">
CTP接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.xspeed" target="_blank">
飞创接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.femas" target="_blank">
飞马接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.ksotp" target="_blank">
金仕达期权接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.ksgold" target="_blank">
金仕达黄金接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.sgit" target="_blank">
飞鼠接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/dev/vn.qdp" target="_blank">
QDP接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.oanda" target="_blank">
OANDA接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.ib" target="_blank">
IB接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.shzd" target="_blank">
直达期货接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.okcoin" target="_blank">
OKCoin接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.datayes" target="_blank">
通联数据接口
</a>
</li>
<li class="list-group-item">
<a href="http://github.com/vnpy/vnpy/tree/master/vn.demo" target="_blank">
开发DEMO
</a>
</li>
</ul>
</li>
</ul>
</section>
</aside>
</div>
</div>
</div>
<footer>
<div class="container">
<hr>
<div class="row">
<div class="col-xs-10">© 2017 用Python的交易员
· Powered by <a href="https://github.com/DandyDev/pelican-bootstrap3" target="_blank">pelican-bootstrap3</a>,
<a href="http://docs.getpelican.com/" target="_blank">Pelican</a>,
<a href="http://getbootstrap.com" target="_blank">Bootstrap</a> </div>
<div class="col-xs-2"><p class="pull-right"><i class="fa fa-arrow-up"></i> <a href="#">Back to top</a></p></div>
</div>
</div>
</footer>
<script src="/theme/js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="/theme/js/bootstrap.min.js"></script>
<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->
<script src="/theme/js/respond.min.js"></script>
<script src="/theme/js/bodypadding.js"></script>
</body>
</html>