金字塔决策交易系统—高级教程(2016修订版) 下载本文

金字塔决策交易系统初级教程 2016 金字塔决策交易系统 高级教程 上海金之塔信息技术有限公司 金字塔决策交易系统初级教程

? 本教程主要介绍金字塔的后台程序化交易,VBA、C++二次开发的编程。

目录

目录 .................................................................................................................................................................. 2 第一章金字塔的后台程序化交易 .................................................................................................................. 1 1.1后台程序化工作机理 ............................................................................................................................ 1 1.2 后台程序化交易函数 ........................................................................................................................... 2 1.3 后台套利模型范例 ............................................................................................................................... 5 1.4 后台程序化的启用 ............................................................................................................................... 7 1.5 后台程序化的调试 ............................................................................................................................... 8 1.6 后台程序化注意事项 ......................................................................................................................... 10 第二章图表交易和后台交易的主要区别和联系 ........................................................................................ 12 2.1 图表、交易函数的区别 ..................................................................................................................... 12 2.11 图表交易函数 ............................................................................................................................... 12 2.12 后台交易函数 ............................................................................................................................... 12 2.3图表交易和后台交易的主要区别 ...................................................................................................... 13 第三章基于VBA的二次开发 ....................................................................................................................... 14 3.1金字塔VBA与OFFICE VBA区别和联系 ............................................................................................ 14 3.2 VBA 原理的隐喻 ................................................................................................................................. 14 3.3 VBA 简介 ............................................................................................................................................. 15 3.3.1VBA 及其IDE 初步 ....................................................................................................................... 15 3.3.2模块、函数和过程 ....................................................................................................................... 18 3.3.3数据类型和变量 ........................................................................................................................... 20 3.3.4VBA 语言基础 ............................................................................................................................... 23 3.3.5用户窗体 ....................................................................................................................................... 29 3.4金字塔的对象模型 .............................................................................................................................. 33 3.4.1Application 对象 ........................................................................................................................... 34 3.4.2Order 对象 .................................................................................................................................... 36

金字塔决策交易系统初级教程

3.4.3MarketData 对象 .......................................................................................................................... 45 3.4.4 ReportData对象 ........................................................................................................................... 49 3.4.5 HistoryData 对象 .......................................................................................................................... 50 3.4.6 Document对象 ............................................................................................................................. 52 3.4.7 Frame 对象................................................................................................................................... 54 3.4.8 Grid对象 ....................................................................................................................................... 56 3.4.9 Formula 对象 ............................................................................................................................... 62 3.4.10 NetWork 对象 ............................................................................................................................ 63 3.4.11 TestReport 对象 ......................................................................................................................... 65 第四章 VBA实用范例 .................................................................................................................................. 75 4.1 跨期套利交易范例 ............................................................................................................................. 75 4.2 金字塔VBA指标调用数据库教程 .................................................................................................... 76 4.2.1数据库的准备工作(vba使用数据库首先我们需要连接数据库) ........................................ 76 4.2.2 数据库操作方法(具体代码和注释<使用时选取需要的代码只要稍许修改>) .................. 77 第五章基于C++二次开发 ............................................................................................................................. 85 5.1使用金字塔C++ API开发策略的优势 ............................................................................................... 85 5.2金字塔的C++ API与主程序的组织结构 ........................................................................................... 86 5.3金字塔的接口范例下载与简要说明 .................................................................................................. 86 5.3.1 API接口报价行情订阅 ................................................................................................................ 86 5.3.2报价行情变化通知 ....................................................................................................................... 87 5.3.3获取指定市场全部合约报价 ....................................................................................................... 87 5.3.4历史数据的获取 ........................................................................................................................... 87 5.3.5下单委托指令 ............................................................................................................................... 88 5.3.6订单状态推送回报 ....................................................................................................................... 88 5.3.7策略编写调试与跟踪 ................................................................................................................... 89 5.3.8API接口更多功能信息 ................................................................................................................. 90 第六章自定义PEL函数 ................................................................................................................................ 91 6.1 使用VBA自定义PEL函数 ................................................................................................................ 91 6.1.1自定义函数的格式 ....................................................................................................................... 91

金字塔决策交易系统初级教程

6.1.2自定义函数的两种工作模式 ....................................................................................................... 92 6.2 使用C++DLL扩展函数程序调用 ....................................................................................................... 94

金字塔决策交易系统初级教程

第一章 金字塔的后台程序化交易

金字塔提供功能性和扩展性更为强大的基于后台预警模式的程序化交易模式(后台程序化),可以在不影响用户前台图形操作的情况下,高效地与预警系统一起工作,实现自动交易。由于该模式运行在后台,不需要打开图表占用过多的资源,且只需最后一个周期的信号,所以原则上公式不做多余计算,效率高,便于对多个品种同一个策略进行轮循监控。

从某种意义讲,后台程序化属于图表程序的深化,它的优点是更注重于策略的高效执行,更完美地实现策略的设计初衷。虽然后台程序化的功能强大,但用户切忌直接使用后台策略,而跳过学习图表程序化的过程。原因是在后台程序化中用户无法直接在图表上看到信号的整个出现过程,因此对用户的公式编写水平有一定的要求。其次,用户需要对金字塔的后台交易系统工作机理有比较深的了解,并且要对自己的公式系统有清晰的认识,这样一旦遇到问题也能及时找到原因。后台交易过程中,一旦遇到问题,需要客户掌握第八章后台程序化交易调试的技巧。以我们多年的经验来看,用户先将策略经测评、优化、图表实盘上运行后,再转化成后台策略,会取得非常好的效果。

1.1后台程序化工作机理

在初级教程中,我们介绍了基于虚拟数据技术的图表程序化交易。想必经过一段时间的学习,大家已将图表程序化运用的相当纯熟。不过当你进行实盘的时候,是否发现在某些情况下,例如碰到未成交单、未完全成交单、需要进行追撤单等更精细的下单操作时,图表程序化就束手无策了。这是由于图表基于虚拟数据的特性,无法与真实账户进行交互,虚拟数据的成交并不考虑实盘的的流动性情况,只要价格达到即成交。而实际情况可能并不是这样。

另一方面,当图表程序化碰上多品种、多策略、或者较复杂的策略时,有时系统会显得相对较慢、不流畅。这是由于图表需要计算大量以往的历史数据进行判断操作,并在图表上进行输出。这消耗了相当多的资源。但实盘并不需要考虑历史曾经如何,实时交易需要考虑的是如何高效的执行,其实只需根据最后一根K线上的数据,来确定开平仓的动作。这也就是例如DYNAINFO等这些常数函数无法进行测评而实盘的公式确可以用的主要原因,因为DYNAINFO只有最新的一笔行情数据,而没有历史的序列数据。金字塔后台程序化也是这个道理,因为金字塔的后台程序化只注重交易,因此无法用来测评。

总结一下,金字塔的后台程序化交易是金字塔很大的特色。从工作机制的角度看,后台程序化在沿用PEL语言体系的情况下,为用户创造了近似VB、C++才能达到的精细化、高效快捷程序化下单模式。因此它特别适合那些多周期、多策略、多品种的组合交易以及对效率要求较高的套利交易,为您的交易带来无与伦比的便捷。

1

金字塔决策交易系统高级教程

1.2后台程序化交易函数

金字塔的后台程序化交易只能在专业版及更高级的版本中使用,它可以运行在序列和逐K线两种模式,但是推荐序列模式运行,这样可以极大提高后台执行的效率。

为了让用户更快的编写和熟悉金字塔的后台程序化交易,金字塔的程序化交易函数,前面都在交易系统函数名称前加 T 字母,比如BUY改为TBUY, 使用方法大致相同,用户仔细注意查看函数的使用说明。与图表交易系统函数不同的是,后台程序化交易的函数都使用实际的用户持仓和资金。

让我们通过案例来学习后台程序化交易函数。

例1:MA指标后台公式

//中间变量 MA3:MA(C,3); MA5:MA(C,5); //交易系统

TBUY(CROSS(MA3,MA5),1,LMT,C); //按照最新价限价开多

TSELL(CROSS(MA5,MA3),0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

请注意TBUY和TSELL函数的参数出现了变化,真正的下单时,需要指定下单类型和价格的,否则系统会按照市价进行交易。

用以模拟交易的函数和真实交易的函数,大部分只是有了前面T字母差别,大部分的用以交易评测的交易系统,只要将交易函数部分前面加

T字母即可解决,唯一区别最大的就是

TBUY,TSELL,TBUYSHORT,TSELLSHORT 这4个函数与模拟交易用的函数区别较大,请仔细辨别。

请注意后台程序化交易不能使用图表交易功能,且图表交易和后台交易的函数不能混用。交易控制符 THISCLOSE 在真实交易中被 LMT 等真实交易控制符所取代,金字塔的模拟交易控制符和真实交易控制符两者不能通用。金字塔的真实下单函数只支持LMT限价 MKT市价 STP止损 STPLMT限价止损 这4个交易控制符。

真实下单交易函数,下单数量不再支持百分比模式。 程序化交易的函数介绍: 程序化交易系统之开多操作:

用法:TBUY(COND,V,[Type,P1,P2,AC,STOCK]);表示当COND条件成立时, 买入V股(手)当前品种,

TYPE表示开仓类型,LMT限价 MKT市价 STP止损 STPLMT限价止损

P1表示开仓价格,当TYPE为LMT和STP,STPLMT时为指定限价和止损价格,其他情况填0

P2为止损限价,当TYPE为STPLMT时,必须指定P2的止损限价,其他情况填0,当P1止损价触发时按照

2

金字塔决策交易系统高级教程

P2价格止损操作.

当TYPE参数省略时,为市价开仓。AC为帐户ID,为空时为系统默认帐户,否则将下单到指定帐户中 STOCK为品种代码,比如'SH600215',为空或者不填时为当前品种

后台程序化交易不能使用图表交易功能,且图表交易和后台交易的函数不能混用。例如,限价在图表中函数为Limit,后台为Lmt。市价在图表是函数Market,在后台是Mkt。

例如:TBUY(C>O ,1000,LMT,C);表示收阳线则在本周期收盘价上买入1000股(手)。

TBUY(C>0,1000,STP,CLOSE+0.2);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按市价开仓止损.

TBUY(C>0,1000,STPLMT,CLOSE+0.2,CLOSE);表示收阳线则在本周期收盘价高于0.2元下1000股(手)止损单,当盘中价格到了触发价时按CLOSE价格开仓止损。

程序化交易系统之平多操作:

TSELL(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上 程序化交易系统之开空操作:

TBUYSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上 程序化交易系统之平空操作:

TSELLSHORT(COND,V,[Type,P1,P2,AC,STOCK]); 用法同上

注意:程序化交易系统的函数中交易类型Type与交易测试系统的差别

例2:唐奇安通道模型

//中间变量

input:N(20,5,100,1),NS(10,0,60,1); Price:=AVGENTERPRICE;//持仓价位 //交易条件

开多平空条件:=CROSS(H, hhv(ref(h,1),N)); 开空平多条件:=CROSS(llv(ref(l,1), N),L); //交易系统

SELLSHORT(开多平空条件 and 持仓<0,持仓,market); SELLSHORT(持仓<0,持仓,Stopr,Price+NS); //止损 BUY(开多平空条件 and 持仓=0,30%,market); SELL(开空平多条件 and 持仓>0,持仓,market); SELL(持仓>0,持仓,Stopr,Price-NS);//止损

BUYSHORT(开空平多条件 and 持仓=0,30%,market); //其他

资产:asset,noaxis,colorgreen;

3

金字塔决策交易系统高级教程

持仓:HOLDING,LINETHICK0; 总次数: TOTALTRADE,LINETHICK0; 盈利:NUMWINTRADE,LINETHICK0;

胜率:ROUNDS(100*PERCENTWIN,1),LINETHICK0; 连亏:MAXSEQLOSS,LINETHICK0; 连盈:MAXSEQWIN,LINETHICK0;

将交易模型转换成程序化交易系统,主要是涉及交易系统函数的转化,即在交易系统函数前加“t”,以及交易类型的改动;并且程序化交易函数都是在后台运行,不能在图表中显示;交易数量不能用30%的写法,只能用具体数量。

因此,唐奇安通道模型转化为可程序化交易的系统: //中间变量

input:N(20,0,60,1) ,NS(30,0,100,1); 持仓:=tHOLDING,LINETHICK0;

KCS:=intpart(tasset*0.3/(close*multiplier));//也表示30%的开仓数 BUY1:=hhv(ref(h,1),N); SELL1:=llv(ref(l,1),N);

Price:=tAVGENTERPRICE; //持仓价位 //交易条件

开多平空条件:=CROSS(H,BUY1); 开空平多条件:=CROSS(SELL1,L); //交易系统

TSELLSHORT(开多平空条件 and 持仓<0,t持仓,mkt); TSELLSHORT(持仓<0,持仓,Stp,Price+NS); TBUY(开多平空条件 and 持仓=0, KCS,mkt); TSELL(开空平多条件 and 持仓>0,持仓,mkt); TSELL(持仓>0,持仓,Stp,Price-NS);

TBUYSHORT(开空平多条件 and 持仓=0, KCS,mkt); 若想与交易模型完全一样,后6句则需这样写:

tSELLSHORT(ref(开多平空条件,1) and 持仓<0,t持仓,mkt); tSELLSHORT(持仓<0,持仓,Stp,Price+NS); tBUY(ref(开多平空条件,1) and 持仓=0, KCS,mkt); tSELL(ref(开空平多条件,1) and 持仓>0,t持仓,mkt);

4

金字塔决策交易系统高级教程

tSELL(持仓>0,持仓,Stp,Price-NS);

tBUYSHORT(ref(开空平多条件,1) and 持仓=0, KCS,mkt);

注意:在公式编辑中,点击 [ << ] 可弹出函数列表,可按类查找需要的函数,双击该函数将直接引入公式。公式中的蓝色字段为函数名,将鼠标放在未知的蓝色字段上,将看到该函数的描述和基本用法。

1.3后台套利模型范例

基于后台程序化效率高、操作灵活的特性,用来处理对价格异常敏感的套利交易就非常合适了。以下我们选取了常见的集中情况作为范例。

(1)简单价差类型的套利模型

C1为两个品种的价差。

当价差小于 300 时,买入开仓前一品种RB05,卖出开仓后一品种RB03 当价差大于500时,卖出平仓前一品种,买入平仓后一品种 当价差大于 600 时,卖出开仓前一品种,买入开仓后一品种 当价差小于400时,买入平仓前一品种,卖出平仓后一品种

由于涉及到需要同时下单到不同的品种,这里直接使用后台程序化交易系统编写。 //中间变量

C1:= “RB05$close”-“RB03$close”; //交易系统

TBUY(CROSS(300,C1),10, mkt,0,0,'','SQRB05');//开多 TBUYSHORT(CROSS(300,C1),10,mkt, 0,0,'','SQRB03'); //开空 TSELL(CROSS(C1,500),10,mkt,0,0,'','SQRB05'); //平多

TSELLSHORT(CROSS (C1,500),10,mkt, 0,0, '','SQRB03'); //平空 TBUYSHORT(CROSS(C1,600),10,mkt, 0,0, '','SQRB05'); //开空 TBUY(CROSS(C1,600),10, mkt,0,0,'','SQRB03');//开多

TSELLSHORT(CROSS (400,C1),10,mkt, 0,0, '','SQRB05'); //平空 TSELL(CROSS (400,C1),10,mkt, 0,0, '','SQRB03'); //平多

注意在后台程序化交易监控中,用户至少需要监控RB05或者RB03其中的一个。

(2)如何编制技术指标的套利模型:

//中间变量

C1:= “RB05$close”-“RB03$close”;

5

金字塔决策交易系统高级教程

DIFF := EMA(C1,12) - EMA(C1,26); DEA:= EMA(DIFF,9); MACD:=2*(DIFF-DEA); //交易条件

平空开多条件:=MACD>0; 平多开空条件:=MACD<0; //交易系统

TSELLSHORT(平多开空条件,10, mkt, 0,0, '','SQRB03'); //平空 TBUY(平空开多条件,10,mkt,0,0,'','SQRB05');//开多 TSELL(平多开空条件,10, mkt,0,0,'','SQRB05'); //平多 TBUYSHORT(平空开多条件,10,mkt, 0,0, '','SQRB03'); //开空

(3)如何编制技术指标的多账户模型:

账户1:16801 账户2:16802 //中间变量

DIFF := EMA(C,12) - EMA(C,26); DEA:= EMA(DIFF,9); MACD:=2*(DIFF-DEA); //交易系统

IF THOLDING<0 THENBEGIN

TSELLSHORT(MACD>0 and THOLDING<0, THOLDING, mkt,0,0,'16801'); //平空 TSELLSHORT(MACD>0,10, mkt, 0,0, '16802'); //平空 END

IF THOLDING=0 THENBEGIN

TBUY(MACD>0 and THOLDING=0,10,mkt, 0,0, '16801');//开多 TBUY(MACD>0,10,mkt, 0,0, '16802');//开多 END

IF THOLDING>0 THENBEGIN

TSELL(MACD<0 and THOLDING>0, THOLDING,10, mkt,0,0,'16801'); //平多 TSELL(MACD<0,10, mkt,0,0,'16802'); //平多 END

IF THOLDING=0 THENBEGIN

TBUYSHORT(MACD<0 and THOLDING=0,10,mkt,0,0,'16801'); //开空

6

金字塔决策交易系统高级教程

TBUYSHORT(MACD<0,10,mkt, 0,0, '16802'); //开空 END

所有上述模型仅供参考,据此交易风险自负。

更多范例请登陆 金字塔论坛——策略发布区 http:/www.weistock.com/bbs/index.asp?boardid=10

1.4后台程序化的启用

选择“交易→后台程序化交易”或按Ctrl + A会出现图7.3本地预警交易。

图1.41本地预警交易

(1)选“新增条件”,将出现图7.4程序化条件设定

图1.42程序化条件设定

7

金字塔决策交易系统高级教程

(2) 参数设置

第一步:首先,点“指标公式”,选择你的模型和使用周期; 第二步:加入要监控的品种; 第三步:其它各种设置,

注意:打勾“允许程序化交易”,其中,可将“下单需手工确认”关闭,如勾选自定义分品种下单,会出现确认对话框,请用户详看出现的每一个提示确认对话框;设定“预警时间间隔”及“时间范围启用”;等等然后按“确认” ;

最后点击“启动预警”。

(3)在程序化交易过程中,用户可随时点击【监控】,观察系统运行情况,并可在信心爆棚时,手工加减仓干预。如图7.5程序化交易明细

1.43程序化交易明细

1.5后台程序化的调试

如前文所述,后台程序化需要用户对金字塔的后台交易系统工作机理有比较深的了解,并且要对自己的公式系统有清晰的认识,现在,我们就将讲解的后台自动交易的调试内容,这是每个后台自动交易编写用户所必须掌握的基本的能力要求,只有用户掌握了调试技巧,才能在金字塔的平台上做出有效而又符合要求的后台自动化交易模型。

供后台调试金字塔提供了两个函数 DEBUGOUT 和DEBUGFILE,其中DEBUGOUT是只针对程序化交易使用,在Ctrl+A预警设置窗口点击“监控”按钮后的程序化交易监控窗口,将显示出当前每个品种的监控过程以及下单动作。

8

金字塔决策交易系统高级教程

图1.5

DEBUGOUT函数的描述如下:

DEBUGOUT(STR,NUM),STR为用户指定输出的一个行文字,NUM为用户指定的一个监控数字. 例如:DEBUGOUT('当前资产为%.2f',TASSET),将在程序化交易的监控部分打印出来 \当前资产为1234.00\假设当前的资产为1234)

\为一个打印的控制符号,系统会将他替换为指定的一个数字输出,%.2f为显示两位小数,%.0f则表示不显示小数.

用户最常见的问题就是,从图表上看明明应该某个时间段应该是开平仓了,但是结果确没有反应,后台并没有按预计发出交易指令,这种情况用户一般需要基于下面原因考虑:

(1)用于交易的品种历史数据是否补齐,因为金字塔的历史数据是基于点播模式补充的,处于后台交易的品种如果缺失数据将会导致交易信号出现不可预料的情况。

(2)用户所选择的交易系统周期是否合理,预警监控间隔时间是否合理,甚至用户是否选中了“允许程序化交易”复选框。

(3)用户的TBUY等交易指令在多帐户交易时,市价委托是否指定了交易价格,常见错误是用户认为指定MKT指令后就不用填写价格了,应该填0补充。

比如:

MA3:MA(C,3); MA5:MA(C,5);

开多条件:= CROSS(MA3,MA5); 平多条件:= CROSS(MA5,MA3);

TBUY(开多条件,1,LMT,C);//按照最新价限价开多

TSELL(平多条件,0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

这样一个简单的公式,是否出现交易信号,完全取觉于BK和平多条件这两个变量的计算结果,只要这样

9

金字塔决策交易系统高级教程

MA3:MA(C,3); MA5:MA(C,5);

开多条件:= CROSS(MA3,MA5); 平多条件:= CROSS(MA5,MA3);

DEBUGOUT(‘开多条件=%.0f’,开多条件); DEBUGOUT(‘平多条件=%.0f’,平多条件); TBUY(开多条件,1,LMT,C);//按照最新价限价开多

TSELL(平多条件,0,LMT,C);//按照最新价限价平多,0表示平掉全部持仓

这样用户就可以一直在程序化交易监控窗口看到整个变量在不断循环中的值变化了,给用户带来了调试的机会。但是上述的只表达了开多条件,平多条件这两个信号,可能并不能让用户最终找到问题原因,要找到,用户可能还得将MA3,MA5的变量值变化也打印输出,只要一直这样往上逐个筛选每个结果数据,就能最终找到问题的原因。

金字塔的另一个非常重要函数DEBUGFILE,可以将调试日志记录文件中,方便用户查询更长的历史记录,

如果用户不习惯使用DEBUGOUT的窗口输出模式,可以使用DEBUGFILE做输出,使用其他文本工具打开。另外,DEBUGFILE与DEBUGOUT不同之处在于他不限于一定运行在后台程序化交易环境中,DEBUGFILE描述如下:

用法:DEBUGFILE(PATH,STR,NUM),PATH为用户的本地计算机路径,STR为用户指定输出的一个行文字,NUM为用户指定的一个监控数字.

例如:DEBUGFILE('D:\\TEST.TXT','当前资产为%.2f',1234),将在程序化交易的监控部分输出到D:\\TEST.TXT文件, \当前资产为1234.00\,\为一个打印的控制符号,系统会将他替换为指定的一个数字输出,%.2f为显示两位小数,%.0f则表示不显示小数。

此外金字塔提供的另一个MSGOUT函数,通过在消息窗口自行输出字符串信息,也可以起到很好的调试作用。

最后我们讲一下日志记录功能,此功能会记录下您本地所有的下单情况。如何启动记录日志:选择“交易”菜单->下单设置->程序化交易->将“记录下单日志”打勾。打勾的同时,会提醒您日志所保存的文件路径。

在图表交易和后台自动交易的甚至手工下单的过程中,金字塔会将与交易有关的动作记录在内,便于用户查找和分析问题原因。

1.6后台程序化注意事项

(1)图表BUY等显示函数是不能放在后台做监控交易的,但是将\允许程序化交易\勾去掉后单独做预警是可以的。

10

金字塔决策交易系统高级教程

(2)只有少数的带T的后台交易函数允许使用在BUY前台图表交易策略中. Tholding,

TAVGENTERPRICE,Taccount,Tasset,但是金字塔强烈不建议使用,因为这样会造成图表上的交易信号与实际的下单记录不符。

(3)金字塔的后台交易部分,使用手工闪电下单的记录,将无法通过比如TENTERPRICE等与交易记录有关函数中得到结果,但可以通过程序化交易监控中的手工下单干预功能完成此项目的。

(4)金字塔的后台交易,查询持仓和资产均为用户当前的实际数值,如果多个策略同时多一个品种或通一个帐户进行操作会产生相互干扰现象,解决办法就是通过使用交易系统使用虚拟持仓和资金,这样就完全可以避免这种共振现象,但是推荐高级用户使用,因为需要很多技巧需要处理。

(5)用以图表显示的交易系统和后台程序化交易的交易指令函数,参数有明显的不同,用户不能简单的将BUY函数加个T就可以直接后台交易,使用前应该将鼠标放在TBUY函数上认真看看函数说明。 同名交易系统函数与程序化交易函数的差别:

函数意义 开多 平多 开空 平空 其中TYPE:次周期限价 TYPE:本周期限价 TYPE:次周期停损 TYPE:本周期停损 TYPE:次周期市价 TYPE:本周期市价 开仓百分比 语句 函数 前台图表交易模型 BUY SELL BUYSHORT SELLSHORT LIMIT LIMITR STOP STOPR MARKET MARKETR 30% 语句 可在图表上显示 后台交易系统 TBUY TSELL TBUYSHORT TSELLSHORT REF(条件,1),LMT LMT REF(条件,1),STP STP REF(条件,1),MKT MKT KCS:=intpart(tasset*0.3/MULTIPLIER/close); T语句 不能在图表上显示 总之,通过函数列表,了解他们的细微差别。

11

金字塔决策交易系统高级教程

第二章 图表交易和后台交易的主要区别和联系

2.1 图表、交易函数的区别

2.11图表交易函数

BUY

开多

BUYSHORT 开空 SELL

平多

SELLSHORT平空

适用于图表程序式交易模式,本函数中可以设置下单条件、下单手数、下单价格等参数。这种交易函数优

点在于可以将本交易函数套用到若干个循环逻辑判断语句中,对下单手数灵活设置,对下单价格灵活的掌控,与之配套使用的各类函数较多,因此能够用于实现较为复杂的交易模型;缺点是没有参数设置账户名、下单品种、只能运行在逐K线模式等。 例2.1:

BUY(vol/ref(vol,1)>3 AND CLOSE>OPEN , 1 ,LIMIT ,CLOSE ); SELL(vol/ref(vol,1)>3 AND CLOSE

IFvol/ref(vol,1)>3THEN BEGIN

BUY(CLOSE>OPEN , 1 ,LIMIT ,CLOSE ); SELL(CLOSE

其中LIMIT为限价委托交易控制符,新图表程序化交易可使用的交易控制符非常丰富,还有LIMITR;MARKET; NEXTHIGH; NEXTLOW; NEXTMID;NEXTOPEN; THISCLOSE;这些交易控制符的具体用法用户可以在公式编辑器左方的函数列表中找到。

2.12 后台交易函数

TBUY

开多 开空 平多 平空

TBUYSHORT TSELL

TSELLSHORT

适用于后台程序化交易模式,在图表交易函数的基础上又增加了关于下单账户、下单品种两个参数,对交

12

金字塔决策交易系统高级教程

易过程的控制能力进一步增强,本函数可以设置下单条件、下单手数、下单价格、下单账户、下单品种等参数。这种交易函数的优点在于可以适用于后台交易模式,对下单手数、价格和账户都可以做到精确控制,有大量的实时动态行情函数、后台函数等可以与之配套使用,基本所有的交易模型都可以通过后台交易模式来实现。 例2.3:

TBUY(vol/ref(vol,1)>3 AND CLOSE>OPEN ,1,LMT ,CLOSE ,0,’351579’ ,’al02’); TSELL(vol/ref(vol,1)>3 AND CLOSE

注意:限价委托交易控制符在后台程序化交易已由LMT取代,后台程序化交易由于是采用的真实持仓的

方式工作,因此只有LMT;MKT;STP;LMTSTP这4个交易控制符,并且这些交易控制符不可混用,也就是后台的交易控制符不能用在图表的BUY函数中,同样图表的交易控制符不能用在TBUY中,后面的章节中我们还会对其用对照表方式进行详细的对比。

2.3图表交易和后台交易的主要区别

(1)适用交易模式不同

图表交易函数用在图表程序化交易中; 后台交易函数用于后台程序化交易中;

(2)显示方式不同

在使用时,需要在所看的当前品种分析K线图中调用出交易指标,调用后K线图中会显示买卖信号; 后台交易函数使用时只会在后台静默的运行,不需要在当前所看的K线图中调用交易指标,因此在当前所看的K线图中不显示买卖信号;

(3)启用和设置方式不同

图表程序化交易的设置和启用界面位于菜单栏的“交易>图表程序化交易”选项。 后台程序化交易的设置和启用界面位于菜单栏的“交易>后台程序化交易”选项。

(4)虚拟和真实的区别

图表程序化交易采用的是虚拟持仓、虚拟资金等概念,各个买卖点以及中间过程返回给用户的持仓和资金是根据历史交易信号和相关初始化的数据计算得来,资金、费率等初始化数据是在指标编辑器中的“费率设置”中进行设置。

后台程序化交易采用的是真实持仓、真实资金的概念,它们调用的是账户栏中真实的账户数据。

13

金字塔决策交易系统高级教程

第三章基于VBA的二次开发

一个优秀的程序化交易软件不仅需要满足个人个性化的策略实现外,策略的执行也至关重要,俗话说:细节决定成败,前面章节我们都是介绍的使用金字塔内置的PEL脚本语言作为程序化交易使用,但是PEL终归还是为普通非计算机专业投资者准备的脚本语言,方便投资者学习和使用的同时,也带来了其自身存在的格式固化,运行不够灵活,效率不足等问题,是无法满足具有更多想法更多需求的程序化交易者的。在各种高级语言中,熟悉和精通VB的人无疑是最多的。著名的微软OFFICE办公软件中的二次开发也是使用的VBA。但是金字塔不仅仅是一个被广泛应用的金融分析软件,除了具有一般软件的数据处理、统计分析、图表功能外,最大的特点是集成了VBA 环境。并提供了VBA 的IDE 环境。可以应用金字塔的所有现有功能,例如其数据处理、图表绘制、数据库连接、内置函数等等。利用这些接口将极大的发挥我们专业程序化交易投资者的编程空间,使我们的交易系统具有强大的计算能力、扩展能力和生命力。

3.1金字塔VBA与OFFICE VBA区别和联系

尽管金字塔VBA与OFFICE VBA都是VBA,但是它们2个还是有些不同的地方,这里假设读者是熟悉OFFICE VBA的用户,如果你是VBA的初学者,那么可以不必理会这里的差别。

金字塔的脚本引擎是VBS,与OFFICE的VBA主要区别在于变量无需声明就可以使用。

金字塔软件的VBA系统是介于传统VBS与VBA之间的系统,支持VBA系统中才有的窗体,框架等等更多的对象,另外,语法上又兼容VBS。

除了类模块外,所有的框架和窗体对象模块的数据都是公用的,框架和窗体之所以独立是因为方便用户编辑和管理,实际运行代码是合在一起的。比如你在框架或者窗体中定义了一个函数过程外的全局变量,实际上是所有VBS代码都可以调用的,在窗体框架对象中的过程名在其他窗体中调用也无需使用 窗体.过程名 这种方式,可以直接使用过程名。

金字塔中的窗体与OFFICE其他组件的窗体在访问其内部控件时稍有不同,例如访问UserForm1窗体的Text1编辑控件,使其隐藏。代码如下: UserForm1_Text1.Visible = False

除此之外,金字塔VBA与OFFICE VBA在IDE界面,使用方法和布局上,完全一致,如果读者熟悉OFFICE VBA的开发,那么就应该很快掌握金字塔VBA的开发。

3.2 VBA 原理的隐喻

VBA 的基本原理可通过下图做示意性解释。

金字塔对象 14 VBA VBA代码 金字塔决策交易系统高级教程

VBA 作为应用VBA 编写的代码和金字塔对象之间的一个桥梁,为2 者之间的调用提供支持,这种调用是通过COM 自动化实现的。例如我们的代码中一句代码,调用金字塔中一个对象的一个属性,那么这个过程大概是类似这样的:VBA 环境解释执行这句代码,如果发现对金字塔对象的调用,就通过COM 的方式调用这个对象,获取其属性,这样VBA 代码就可以和金字塔对象进行交互。

3.3VBA 简介

要使用 VBA 进行数据处理,第一要熟悉VBA 的IDE 环境,知道如何进行代码书写,如何编写代码,设计窗体,创建类模块(对象),第二要熟悉VBA 的基本语法和。二者都是VBA 程序设计的基础,需要认真学习。

VBA 语法不是一章就可以全部介绍完全的,本章介绍的内容是最基本和应该熟练掌握的内容,对于不熟悉或者不理解的内容可以在学习了后面的内容后再反过头来学习。有些内容需要反复练习和熟悉。对于VBA 语法和用法的很多内容可以随时通过查看帮助来获得相关信息。

本章和下一章(金字塔 对象模型)的部分内容,特别是表格内的一些内容,没有必要完全记住,可以作为参考手册来使用。

3.3.1VBA 及其IDE 初步

本部分将对VBA 及其开发环境IDE(集成开发环境)作一概略的介绍。VBA IDE 是进行程序设计和代码编写的地方,同一个金字塔共享同一IDE。文中会涉及到一些诸如对象、事件等部分读者可能不熟悉或不清楚的概念,对于此类问题可直接忽略之,因为在后面会有详细介绍。本部分也不是一个VBA 的参考文档,只是其语法、特征的快速浏览和介绍。

(1)VBA 集成开发环境(IDE)的组成

VBA 代码和金字塔文档文件是保存在一起的,可以通过点击“工具―宏― Visual Basic 工程”打开VBA 的IDE 环境,进行程序设计和代码编写。

图3-1Visual Basic IDE 环境

15

金字塔决策交易系统高级教程

图3-1 为金字塔 VBA 的IDE 环境,缺省情况下,VBA IDE 环境上方为菜单和工具条(图3-1),左侧窗口为工程资源管理器窗口,右侧最大的窗口为代码窗口。

每一个金字塔文档文件,对应的VBA 工程都有4 类对象,包括:框架、窗体、模块和类模块(图3-2)。这里的框架主要是金字塔运行时的技术分析图表,例如我们常见的K线走势分析图的框架对象,双击这些对象会打开代码窗口(图3-1 右侧窗口),在此窗口中可输入相关的代码,响应事件,例如框架的打开、关闭,窗格的激活、品种显示的修改、选择等(有关事件、金字塔对象模型见后)。窗体对象代表了自定义对话框或界面,模块为自定义代码的载体,类模块则是以类或对象的方式编写代码的载体,关于各对象的具体含义和使用见后。在工程资源管理器窗口的右键菜单下,有添加用户窗体、模块、类模块的选项,也可以将已有的模块移除、导入和导出。

注意:建议用户新建一个VBA工程来完成你的个性化VBA代码,尽量不要在默认的工程中添加,防止多个不同工程的代码相互干扰,您可以点击左侧工程资源窗口上的

(2)在 VBA IDE 下进行开发

熟悉了VBA 的IDE 环境后,我们来开发VBA 之旅的第一个程序。首先我们双击左侧工程资源管理器上的窗口的模块分类,然后双击“Macro”模块,打开宏模块代码编辑窗口(图3-3),然后选择“插入”菜单->过程,再随后弹出的宏名称编辑窗口里输入“MyFirstVBAProgram”,然后单击确定,这样系统会自动将MyFirstVBAProgram这个过程函数插入到代码编辑窗口中,我们只要在打开窗口中输入以下代码:

Sub MyFirstVBAProgram() MsgBox “我的第一个自编程序。” End Sub

通过“运行”菜单->宏,或者按Alt+F8快捷键,弹出宏运行窗口,下拉框中选择我们前面建立的“MyFirstVBAProgram”宏,然后就能看到运行的结果了。

工具栏来新建一个VBA工程。

图3-2

16

金字塔决策交易系统高级教程

注意:与其他程序设计语言不同,VBA 程序是事件驱动的,没有Main 函数之类的入口的概念。本质上,

VBA 代码应该只是一些完成具体工作的集合,而通过界面元素或者金字塔的事件驱动执行,你可以通过自定义按钮、菜单,并指定一个宏(VBA 过程,自定义界面也可以通过编程手段完成此类工作),通过单击此按钮即可调用相应的VBA代码,或者将调用绑定在金字塔的某个事件下。

下面我们简单看一下这段代码的组成,代码第1 行表示这是一个新的过程,名称为“MyFirstVBAProgram” 第2行调用MsgBox 这个函数,显示一个对话框,第3 行表示过程结束。VBA 程序由不同的模块组成,在模块内部,可以定义不同的变量、过程或函数,由此组成一个完整的程序。

(3)善用工具及其他

VBA 集成开发环境,提供了很多便利的工具可以帮助或辅助我们写出好的程序,其中的方便必须亲自使用才可以体会,因此,一定要善用工具。VBA 的代码编辑器提供了几项非常有用的功能,代码即时提示可以使我们不必记忆太多的东西,输入对象后会自动列出其属性、方法等内容。

在实际的编程过程中,一定要善于利用在线帮助,VBA 的在线帮助包含了大量对编程有用的参考信息,任何人都不可能记得住所有的函数、对象的用法和程序语言的语法,所以一定要利用好帮助。帮助的使用可以在“帮助”菜单->VBA编程信息 处获得。可以通过帮助目录浏览,或者通过查找输入关键字查找相关内容。

图3-3

在代码书写中,如果一句代码过长,应该使用接行字符(“-”)将其分为几行,而不是书写为一行,一

17

金字塔决策交易系统高级教程

般来说,代码的长度不要超过80 个字符为宜,这样阅读方便,不需要横向拉动滚动条,也不容易出错。例如上面第一个例子我们可以将对话框文字输出分成2行:

MsgBox _

“我的第一个自编程序。”

对于代码格式,一定要养成缩进的习惯,在过程之后,循环语句、判断语句之内,如本书的例子样子,缩进4 个字符,便于阅读。代码中,在一个逻辑或者操作完成之后,应该空一行,以表示其逻辑关系,在过程与过程之间,也应该空一行。VBA 中,使用单引号“’”表示注释,编写程序时,一定要养成注释的习惯。注释不是所有代码都要注释;一般来说,对一个模块、过程、函数,要大概说明其功能,参数;对于一个过程,如果涉及较复杂的算法,要说明其使用的算法或流程。在过程和函数中,对关键代码,说明其操作的目的、算法或流程。

3.3.2模块、函数和过程

(1)模块

模块是自定义的过程、函数保存的地方有两种基本类型的模块:类模块和标准模块,本节介绍标准模块,类模块将在专门介绍。模块可以通过右键单击工程资源管理器的工程名,选择“插入-模块”来新建,新建的模块缺省的名称为“模块1”,“模块2”,建议在模块右键->重命名中更改为有意义的名称。模块有2 个任务:(1)保存过程和函数;(2)定义类模块内的私有变量或整个工程的公有变量。

在模块中可以声明变量(包括对象),定义过程和函数。过程和函数的定义见下文,变量的声明如下。 变量的声明:

Dim I ‘Dim 表示声明变量i

注意:要求变量声明VBA 缺省可以不声明变量,在第一次使用的时候自动声明,但此功能也是VBA 代码(包括其他Basic 代码)的一个主要错误之源。试想第一次使用了一个变量strMyFirstName,之后又通过strMyFirstNme(少一个a)来使用它,但由于拼写不同,VBA 以为是一个新的变量,于是会新声明一个变量,这样的错误极其难以发现。可以通过“工具-选项”对话框,在“其他”页,选中“VBA变量名必须显式声明所有变量”,则在使用变量前,都必须先通过Dim 语句声明。

(2)过程

过程是最基本的运行单位。一个完整的过程一般类似如下格式: Sub Test(参数列表…) … … End Sub

在以上程序中,Sub 代表过程种类,表示运行指定的操作,但不返回运行结果;Test表示过程名称,最后以End Sub 结束。

其中按值按地址传递参数指一种将参数地址而不是将值传递给过程的方式,这就使过程访问到实际的变量。

18

金字塔决策交易系统高级教程

结果,过程可改变变量的真正值。VBA 缺省按地址传递参数。

Sub MyTest() dim V1,V2 V1 = 1 V2 = 2

MyTestCall (v1,v2) 'v1,v2是参数 MsgBox v1 MsgBox v2 End Sub

Sub MyTestCall(V1,V2) V1=5 V2=.6 End Sub 调用的方法是:

运行结束后,你会发现V1和V2值都被改变了。

所有的可执行代码都必须属于某个过程。不能在别的过程中定义Sub 过程。Exit Sub 语句使执行立即从一个Sub 过程中退出。程序接着从调用该Sub 过程的语句下一条语句执行。在Sub 过程的任何位置都可以有Exit Sub 语句。在Sub 过程中使用的变量分为两类:一类是在过程内显式定义的,另一类则不是。在过程内显式定义的变量(使用Dim 方法)都是局部变量。过程(包括函数等)的创建可以通过在代码窗口直接键入“Sub…”来创建,也可以使用菜单的“插入-过程”对话框来创建。

(3)函数

函数是包含在 Function 和 End Function 语句之间的一组语句。Function 过程与 Sub 过程类似,但是 Function 过程可以返回值。Function 过程可以使用参数(由调用过程传递的常数、变量或表达式)。如果 Function 过程无任何参数,则 Function 语句必须包含空括号 ()。Function 过程通过函数名返回一个值,这个值是在过程的语句中赋给函数名的。Function 返回值的数据类型总是 Variant。

在下面的示例中,Celsius 函数将华氏度换算为摄氏度。Sub 过程 ConvertTemp 调用此函数时,包含参数值的变量被传递给函数。换算结果返回到调用过程并显示在消息框中。

Sub ConvertTemp()

temp = InputBox(\请输入华氏温度。\

MsgBox \温度为 \摄氏度。\ End Sub

Function Celsius(fDegrees)

Celsius = (fDegrees - 32) * 5 / 9

19

金字塔决策交易系统高级教程

End Function

VBA 中有大量内置函数,例如前边例子里使用过的MsgBox,InputBox。VBA 的函数主要包括数学函数(包括三角函数、随机数等)、字符串函数等等,熟悉VBA 的内置函数可以提高工作效率,更好的完成工作。对于VBA 的函数,可以参考VBA帮助文档。

(4)在代码中使用 Sub 和 Function 过程

调用 Function 过程时,函数名必须用在变量赋值语句的右端或表达式中。例如: Temp = Celsius(fDegrees) 或

MsgBox \温度为 \摄氏度。\

调用 Sub 过程时,只需输入过程名及所有参数值,参数值之间使用逗号分隔。不需使用 Call 语句,但如果使用了此语句,则必须将所有参数包含在括号之中。

下面的示例显示了调用 MyProc 过程的两种方式。一种使用 Call 语句;另一种则不使用。两种方式效果相同。

Call MyProc(firstarg, secondarg) MyProc firstarg, secondarg

请注意当不使用 Call 语句进行调用时,括号被省略。

3.3.3数据类型和变量

(1)什么是 VBA 数据类型?

金字塔VBA 只有一种数据类型,称为 Variant。Variant 是一种特殊的数据类型,根据使用的方式,它可以包含不同类别的信息。因为 Variant 是 VBScript 中唯一的数据类型,所以它也是 VBScript 中所有函数的返回值的数据类型。

最简单的 Variant 可以包含数字或字符串信息。Variant 用于数字上下文中时作为数字处理,用于字符串上下文中时作为字符串处理。这就是说,如果使用看起来象是数字的数据,则 VBScript 会假定其为数字并以适用于数字的方式处理。与此类似,如果使用的数据只可能是字符串,则 VBScript 将按字符串处理。当然,也可以将数字包含在引号 (\中使其成为字符串。

(2)什么是变量?

变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存储 Script 运行时可更改的程序信息。例如,可以创建一个名为 ClickCount 的变量来存储用户单击某个对象的次数。使用变量并不需要了解变量在计算机内存中的地址,只要通过变量名引用变量就可以查看或更改变量的值。在 VBA 中只有一个基本

20

金字塔决策交易系统高级教程

数据类型,即 Variant,因此所有变量的数据类型都是 Variant。

(3)声明变量

声明变量的一种方式是使用 Dim 语句、Public 语句和 Private 语句在 Script 中显式声明变量。例如:

Dim DegreesFahrenheit

声明多个变量时,使用逗号分隔变量。例如:

Dim Top, Bottom, Left, Right

另一种方式是通过直接在 Script 中使用变量名这一简单方式隐式声明变量。这通常不是一个好习惯,因为这样有时会由于变量名被拼错而导致在运行 Script 时出现意外的结果。因此,最好通过“工具-选项”对话

框,在“其他”页,选中“VBA变量名必须显式声明所有变量”,则在使用变量前,都必须先通过Dim 语句声明。。

(4)命名规则

变量命名必须遵循 VBA的标准命名规则。变量命名必须遵循:

? 第一个字符必须是字母。 ? 不能包含嵌入的句点。 ? 长度不能超过 255 个字符。 ? 在被声明的作用域内必须唯一。

(5)变量的作用域与存活期

变量的作用域由声明它的位置决定。如果在过程中声明变量,则只有该过程中的代码可以访问或更改变量值,此时变量具有局部作用域并被称为过程级变量。如果在过程之外声明变量,则该变量可以被 Script 中所有过程所识别,称为 Script 级变量,具有 Script 级作用域。

变量存在的时间称为存活期。Script 级变量的存活期从被声明的一刻起,直到 Script 运行结束。对于过程级变量,其存活期仅是该过程运行的时间,该过程结束后,变量随之消失。在执行过程时,局部变量是理想的临时存储空间。可以在不同过程中使用同名的局部变量,这是因为每个局部变量只被声明它的过程识别。

(6)给变量赋值

创建如下形式的表达式给变量赋值:变量在表达式左边,要赋的值在表达式右边。例如: B = 200

(7)标量变量和数组变量

多数情况下,只需为声明的变量赋一个值。只包含一个值的变量被称为标量变量。有时候,将多个相关值赋给一个变量更为方便,因此可以创建包含一系列值的变量,称为数组变量。数组变量和标量变量是以相同的方式声明的,唯一的区别是声明数组变量时变量名后面带有括号 ( )。下例声明了一个包含 11 个元素的一维数组:

Dim A(10)

虽然括号中显示的数字是 10,但由于在 VBA中所有数组都是基于 0 的,所以这个数组实际上包含 11 个元素。在基于 0 的数组中,数组元素的数目总是括号中显示的数目加 1。这种数组被称为固定大小的数组。

在数组中使用索引为数组的每个元素赋值。从 0 到 10,将数据赋给数组的元素,如下所示:

21

金字塔决策交易系统高级教程

A(0) = 256 A(1) = 324 A(2) = 100 . . . A(10) = 55

与此类似,使用索引可以检索到所需的数组元素的数据。例如: . . .

SomeVariable = A(8) . . .

数组并不仅限于一维。数组的维数最大可以为 60(尽管大多数人不能理解超过 3 或 4 的维数)。声明多维数组时用逗号分隔括号中每个表示数组大小的数字。在下例中,MyTable 变量是一个有 6 行和 11 列的二维数组:

Dim MyTable(5, 10)

在二维数组中,括号中第一个数字表示行的数目,第二个数字表示列的数目。

也可以声明动态数组,即在运行 Script 时大小发生变化的数组。对数组的最初声明使用 Dim 语句或 ReDim 语句。但是对于动态数组,括号中不包含任何数字。例如:

Dim MyArray() ReDim AnotherArray()

要使用动态数组,必须随后使用 ReDim 确定维数和每一维的大小。在下例中,ReDim 将动态数组的初始大小设置为 25,而后面的 ReDim 语句将数组的大小重新调整为 30,同时使用 Preserve 关键字在重新调整大小时保留数组的内容。

ReDim MyArray(25) . . .

ReDim Preserve MyArray(30)

重新调整动态数组大小的次数是没有任何限制的,但是应注意:将数组的大小调小时,将会丢失被删除元素的数据。

(8)字符串

字符串是VBA 中需要经常处理的一种数据类型,有2 种字符串类型:变长字符串和定长字符串。变长字符串理论上可以保存大约2G(231)字节的字符串,实际中其保存的字符串长度由内存大小决定;而定长字符串可以保存大约65000(216)长度的字符串。

字符串定义后为空字符串,即没有任何数据的字符串(“”),可以通过以下方式对字符串赋值。字符串在VBA 中用双引号表示。

MyString = \

22

金字塔决策交易系统高级教程

MyFixedString = \MyEmptyString = \

字符串的连接可以使用“&”或者“+”,不过不推荐使用后者,因为容易和数字运算混淆。例如可以使用以下语句连接字符串。

MyString = “test”

MyString = MyString &“ Test Added” MyString = MyString + “ Added Still”

(9)日期和时间

日期和时间数据类型中,日期的范围是100-1-1 到9999-12-31,每天的时间范围是0:00:00 到23:59:59。Date 数据类型可以同时保存日期和时间,也可以只在其中保存时间或者日期。相对于字符串等方式保存日期和时间,应用Date 数据类型,可以在变量之间进行日期运算。

给Date 数据类型赋值时需要在时间和日期外使用“#”符号包括起来,VBA 基本上可以识别常见的各种时间格式,但为防止引入错误,最好还是使用本机的时间和日期格式。当给一个Date 类型的变量赋以一个不可识别的时间格式的时间或日期,会引发一个错误。下面是一些使用Date 数据类型的例子:

MyDate = #15 July 1999# StartDate = #April 8, 2001# MyTime = #8:47 PM#

StartingDateTime = #05/07/1992 15:56#

3.3.4VBA 语言基础

本部分将介绍在进行VBA 程序设计时,需要熟悉的VBA 语法,包括流程控制语句,最简单的用户交互,一些常用的函数,字符串操作等VBA 语言的基础内容。

(1)处理简单的用户输入输出

在程序设计时,经常需要进行用户交互,例如显示一条信息反馈给用户,需要用户输入一些信息等。VBA 中,最简单的用户输入输出方法是使用MsgBox 函数和InputBox 函数。我们在前面已经使用过这两个函数,下面我们将系统的学习一下这两个函数的使用方法。

MsgBox 函数可以在用户屏幕显示一个对话框,等待用户点击,最后返回一个值,代表用户点击的按钮。MsgBox 的语法如下:

MsgBox(prompt[, buttons][, title][, helpfile, context])

其中prompt 代表其显示的消息,之后的参数可以全部省略;buttons 表示对话框显示的按钮和图标,title 表示其标题。例如以下代码片断: Dim iReturn

23

金字塔决策交易系统高级教程

iReturn = MsgBox(\测试\标题\If iReturn = vbYes Then

MsgBox \Else

MsgBox \End If

第2行显示一个有询问图标,有Yes 和No 按钮(是和否)的对话框,单击后根据返回值判断,告诉你点击了那个按钮。

(2)控制程序流程

VBA 程序代码的流程同其他程序设计语言一样,有顺序语句:从上到下,由程序的第一行执行到最后一行;判断分支语句:根据条件跳过部分语句,执行另一部分;循环语句:循环执行一段语句。

(3)使用 If...Then...Else 进行判断

If...Then...Else 语句用于计算条件是否为 True 或 False,并且根据计算结果指定要运行的语句。通常,条件是使用比较运算符对值或变量进行比较的表达式。有关比较运算符的详细信息,请参阅比较运算符。If...Then...Else 语句可以按照需要进行嵌套。

(4)条件为 True 时运行语句

要在条件为 True 时运行单行语句,可使用 If...Then...Else 语句的单行语法。下例示范了单行语法。请注意此例省略了关键字 Else。

Sub FixDate() Dim myDate myDate = #2/13/95#

If myDate < Now Then myDate = Now End Sub

要运行多行代码,必须使用多行(或块)语法。多行(或块)语法包含 End If 语句,如下所示: Sub AlertUser(value) If value = 0 Then

AlertLabel.ForeColor = vbRed AlertLabel.Bold = True AlertLabel.Italic = True End If End Sub

(5)条件为 True 和 False 时分别运行某些语句

可以使用 If...Then...Else 语句定义两个可执行语句块:条件为 True 时运行某一语句块,条件为 False 时运行另一语句块。

24

金字塔决策交易系统高级教程

Sub AlertUser(value) If value = 0 Then

AlertLabel.ForeColor = vbRed AlertLabel.Bold = True AlertLabel.Italic = True Else

AlertLabel.Forecolor = vbBlack AlertLabel.Bold = False AlertLabel.Italic = False End If End Sub

(6)对多个条件进行判断

If...Then...Else 语句的一种变形允许您从多个条件中选择,即添加 ElseIf 子句以扩充 If...Then...Else 语句的功能,使您可以控制基于多种可能的程序流程。例如:

Sub ReportValue(value) If value = 0 Then MsgBox value ElseIf value = 1 Then MsgBox value ElseIf value = 2 then Msgbox value Else

Msgbox \数值超出范围!\ End If

可以添加任意多个 ElseIf 子句以提供多种选择。使用多个 ElseIf 子句经常会变得很累赘。在多个条件中进行选择的更好方法是使用 Select Case 语句。 (7)使用 Select Case 进行判断

Select Case 结构提供了 If...Then...ElseIf 结构的一个变通形式,可以从多个语句块中选择执行其中的一个。Select Case 语句提供的功能与 If...Then...Else 语句类似,但是可以使代码更加简练易读。

Select Case 结构在其开始处使用一个只计算一次的简单测试表达式。表达式的结果将与结构中每个 Case 的值比较。如果匹配,则执行与该 Case 关联的语句块: Select Case Form1.Caption Case \ DisplayMCLogo

25

金字塔决策交易系统高级教程

ValidateMCAccount Case \

DisplayVisaLogo ValidateVisaAccount Case \ DisplayAMEXCOLogo ValidateAMEXCOAccount Case Else

DisplayUnknownImage PromptAgain End Select

请注意 Select Case 结构只计算开始处的一个表达式(只计算一次),而 If...Then...ElseIf 结构计算每个 ElseIf 语句的表达式,这些表达式可以各不相同。仅当每个 ElseIf 语句计算的表达式都相同时,才可以使用 Select Case 结构代替 If...Then...ElseIf 结构。 (8)循环语句

如果需要反复执行某一句或者某一段语句,则可以使用VBA 的循环语句。循环允许重复执行一组语句。某些循环重复执行语句直到条件为False(Do...Loop While);某些循环重复执行语句直到条件为True(Do...Loop While);某些循环执行一指定次数的语句(For…Next) (9)使用 Do 循环

可以使用 Do...Loop 语句多次(次数不定)运行语句块。当条件为 True 时或条件变为 True 之前,重复执行语句块。

(10)当条件为 True 时重复执行语句

While 关键字用于检查 Do...Loop 语句中的条件。有两种方式检查条件:在进入循环之前检查条件(如下面的 ChkFirstWhile 示例);或者在循环至少运行完一次之后检查条件(如下面的 ChkLastWhile 示例)。在 ChkFirstWhile 过程中,如果 myNum 的初始值被设置为 9 而不是 20,则永远不会执行循环体中的语句。在 ChkLastWhile 过程中,循环体中的语句只会执行一次,因为条件在检查时已经为 False。 Sub ChkFirstWhile() Dim counter, myNum counter = 0 myNum = 20

Do While myNum > 10 myNum = myNum - 1 counter = counter + 1 Loop

26

金字塔决策交易系统高级教程

MsgBox \循环重复了 \次。\ End Sub

Sub ChkLastWhile() Dim counter, myNum counter = 0 myNum = 9 Do

myNum = myNum - 1 counter = counter + 1 Loop While myNum > 10

MsgBox \循环重复了 \次。\ End Sub

(11)重复执行语句直到条件变为 True

Until 关键字用于检查 Do...Loop 语句中的条件。有两种方式检查条件:在进入循环之前检查条件(如下面的 ChkFirstUntil 示例);或者在循环至少运行完一次之后检查条件(如下面的 ChkLastUntil 示例)。只要条件为 False,就会进行循环。

Sub ChkFirstUntil() Dim counter, myNum counter = 0 myNum = 20

Do Until myNum = 10 myNum = myNum - 1 counter = counter + 1 Loop

MsgBox \循环重复了 \次。\ End Sub

Sub ChkLastUntil() Dim counter, myNum counter = 0 myNum = 1 Do

myNum = myNum + 1

27

金字塔决策交易系统高级教程

counter = counter + 1 Loop Until myNum = 10

MsgBox \循环重复了 \次。\ End Sub

(11)退出循环

Exit Do 语句用于退出 Do...Loop 循环。因为通常只是在某些特殊情况下要退出循环(例如要避免死循环),所以可在 If...Then...Else 语句的 True 语句块中使用 Exit Do 语句。如果条件为 False,循环将照常运行。

在下面的示例中,myNum 的初始值将导致死循环。If...Then...Else 语句检查此条件,防止出现死循环。 Sub ExitExample() Dim counter, myNum counter = 0 myNum = 9

Do Until myNum = 10 myNum = myNum - 1 counter = counter + 1

If myNum < 10 Then Exit Do Loop

MsgBox \循环重复了 \次。\ End Sub

(12)使用 While...Wend

While...Wend 语句是为那些熟悉其用法的用户提供的。但是由于 While...Wend 缺少灵活性,所以建议最好使用 Do...Loop 语句。

(13)使用 For...Next

For...Next 语句用于将语句块运行指定的次数。在循环中使用计数器变量,该变量的值随每一次循环增加或减少。

例如,下面的示例将过程 MyProc 重复执行 50 次。For 语句指定计数器变量 x 及其起始值与终止值。Next 语句使计数器变量每次加 1。

Sub DoMyProc50Times() Dim x

For x = 1 To 50 MyProc Next End Sub

28

金字塔决策交易系统高级教程

关键字 Step 用于指定计数器变量每次增加或减少的值。在下面的示例中,计数器变量 j 每次加 2。循环结束后,total 的值为 2、4、6、8 和 10 的总和。

Sub TwosTotal() Dim j, total

For j = 2 To 10 Step 2 total = total + j Next

MsgBox \总和为 \。\ End Sub

要使计数器变量递减,可将 Step 设为负值。此时计数器变量的终止值必须小于起始值。在下面的示例中,计数器变量 myNum 每次减 2。循环结束后,total 的值为 16、14、12、10、8、6、4 和 2 的总和。

Sub NewTotal() Dim myNum, total

For myNum = 16 To 2 Step -2 total = total + myNum Next

MsgBox \总和为 \。\ End Sub

Exit For 语句用于在计数器达到其终止值之前退出 For...Next 语句。因为通常只是在某些特殊情况下(例如在发生错误时)要退出循环,所以可以在 If...Then...Else 语句的 True 语句块中使用 Exit For 语句。如果条件为 False,循环将照常运行。

3.3.5用户窗体

VBA 包括一类特殊的对象――用户窗体(UserForm),用户窗体是一个窗口或对话框,用以构成应用程序的用户界面部分。使用用户窗体可以提供一个图形用户界面,在此界面上,可以为其添加按钮、图片、文本框等控件,作为一个自定义窗口或者对话框,供用户与程序进行交互。

(1)设计用户窗体

通过在工程资源管理器右键单击,选择“插入-用户窗体”可以新建一个用户窗体(图3-4),新建的用户窗体缺省名称为“UserForm1”,新建以后的用户窗体是一个空白区域,可以从工具箱中选择控件为用户窗体添加界面元素。选中用户窗体,在右键选择属性窗口内可以设置其属性(如果工具箱和属性窗口没有显示,可以通过查看菜单激活之),也可以拖动改变其大小。窗体具有设计模式和代码模式之分,在资源管理器窗口选择窗体,可以在其工具栏或者通过右键切换窗体的设计模式和代码模式。设计模式下可以通过鼠标拖拽以及属性调整来可视化设计用户窗体的外观以及样式。在代码模式下,可以和在一般的模块窗体一样,定义变量、

29

金字塔决策交易系统高级教程

过程,并且可以响应窗体和控件的事件。

新建一个窗体,按Ctrl+S快捷键,在随后的窗体保存窗口名称设置为“frmMyHelloWorld”,在属性窗口,将Caption 设置为“Hello, My First Form”。

图3-4用户窗体设计界面

从工具箱中选择不同的控件,然后在用户窗体上按下鼠标左键,拖动即可将控件添加到用户窗体。从工具箱选择“文本框”,添加到用户窗体,右键该控件选择属性命令,在属性窗口设置其名称为“txtHelloMsg”;选择“命令按钮”,添加到用户窗体,属性窗口设置其名称为“cmdHello”,Caption 为“Hello”。双击处于设计状态的窗体,VBA IDE 自动打开代码窗口,选择代码窗口上方的对象名和右侧的事件,这里我们选择Click事件,这时金字塔将新建一个名为“rmMyHelloWorld_cmdHello_Click”的过程,这个过程称为事件,当用户点击按钮,此过程内的代码就会执行。在此过程中输入如下代码:

Sub rmMyHelloWorld_cmdHello_Click()

rmMyHelloWorld_txtHelloMsg.Text = \

30

金字塔决策交易系统高级教程

End Sub

按Alt+F8弹出宏运行窗口,选择我们刚才建立的frmMyHelloWorld窗体,单击按钮,文本框的文字将会变成“Hello, My VBA!”(图3-6)。

图3-5 代码与事件显示窗口

图3-6运行的My First Form

这就是用户窗体编程的基本概念,我们可以操作的窗体,文本框,按钮等都是对象,准确来说,都是ActiveX 控件,通过对这些对象的可视化设计,设置其属性,然后在其事件内写入需要的操作。总而言之,用户窗体是VBA 中的一个对象,我们可以通过设置其属性、调用其方法、响应其事件来操作用户窗体和其之上的控件,当用户对用户窗体的元素进行操作时(通过鼠标、按钮),响应的事件就会被执行,这种编程模式就叫做事件驱动的编程模式。我们可以创建一个过程来显示设计好的用户窗体。

(2)事件驱动

下面介绍一下事件的有关概念。事件简单来说,就是由用户或者系统触发的、可以在代码中响应的一段代码。例如,我们移动鼠标、点击窗体和按钮、敲击键盘、窗体的显示移动等等都会产生一系列的事件,通过编写代码中响应这些事件,当发生此类事件时,例如单击了一个按钮,程序代码就会进行相应的操作。例如在前边的例子中,在按钮单击事件中(cmdHello_Click()),我们书写了改变文本框文本的代码。窗体、窗体上的控件都定义了很多事件,例如鼠标移动、单击等事件。用户窗体编程时,编写一个事件的响应代码可以在代码

31

金字塔决策交易系统高级教程

编辑器上方左侧的“对象框”选择对象,然后在其右侧的“过程/事件框”选择响应的事件,即可定位或创建这个事件。

(3)使用控件

用户窗体编程的大部分工作就是在工具箱选择合适的工具,放置到用户窗体,设置其属性。工具箱中包含了一系列可以放置到窗体的控件,例如标签(Label)控件,可以显示静态文本,文本框(TextBox)可以显示动态的可编辑文本。可以直接从工具箱将控件拖拽到窗体上的合适位置,通过拖拽设置大小、位置,在属性窗口设置其属性。用户窗体以及工具箱的常用控件包含有一些通用的属性、方法和事件(不一定所有控件都有)这些属性、方法和事件描述如下:

BackColor 属性:控制控件的背景色。

Caption 属性:在控件上显示的文本,不能被用户改变。 Change 事件:当控件的Value 属性改变时调用。 Click 事件:用户在控件上单击鼠标时调用。

ControlTipText 属性:当用户鼠标指针停留在控件上时显示的提示信息。 DblClick 事件:用户在控件上双击鼠标时调用。

Enabled 属性:当为True 时,会获取焦点并响应用户操作。 Enter 事件:在控件获取了焦点后触发。

Exit 事件:当控件的焦点转移到其他控件时发生。 Font 属性:表示控件的字体样式。

ForeColor 属性:表示控件的前景色,如控件上字体的颜色 Height 属性:表示控件的高度。

Left 属性:表示控件左侧距窗体左侧的距离。 Locked 属性:当为True 时,用户无法改变其内容。 Name (名称)属性: 表示控件的名称。

SpecialEffect 属性:控件的显示效果,例如平面效果之类。 TabIndex 属性:设置控件在窗体中的Tab 顺序。

TabStop 属性:当用户使用Tab 键设置焦点到此控件后,控件是否接受焦点。 Top 属性:控件距窗体上部的距离。 Value 属性:一般包含控件的状态或者内容。

Visible 属性:为True 则显示在窗体上,否则不显示。 Width 属性:控件宽度。

Top,Left,Width 和Height 的单位都是以磅(Point)为单位。Value 属性的具体含义与控件的类型有关,当Value 改变时,都会触发Change 事件。Click 和DblClick事件发生在用户单击或双击鼠标时,一般来说,客户代码往往都包含在Click 事件中,例如下拉列表框的选择,按钮的点击等。对VBA 用户窗体中的

32

金字塔决策交易系统高级教程

控件的介绍和应用如果有疑问请及时参阅随机附带的VBA编程手册(帮助菜单->VBA编程信息和Microsoft 窗体参考)。

(4)调试VBA 代码

程序设计过程中,经常需要定位错误位置并改之,此过程常称为调试。VBA 中第一类错误为语法错误,如果你打开了代码编辑器的“自动语法检查”,则当你输入了一条错误的语法时,VBA IDE 会即时给出一条提示信息。

第二类错误为运行错误。运行错误是指造成应用程序停止运行的任何错误。有时这是由于错误的拼写,例如对象名字。VBA 不会检查这种类型的错误,除非运行该过程。运行错误也可能是用户的操作所引起的,而用户的操作不是你所能控制和预测的。例如,如果用户不给你编写的函数提供数据,就有可能产生运行错误。对于此类情况,就需要写错误处理代码。最后一种可能出现的错误是逻辑错误。逻辑错误不会显示在IDE,问题在于代码的执行结果和预期的结果不同,这就意味着代码的逻辑或算法出了问题。随着对语言和环境的熟悉,大部分的调试时间可能都用在对逻辑错误的处理上。

本文主要介绍使用Application.MsgOut函数调试的方法,这个函数可以在金字塔下方的消息窗口输出指定的文本,可以对程序进行跟踪判断和调试。举例如下:

Dim i

For i = 1 To 10 Step 1 Application.MsgOuti Next

(5)错误处理

所谓调试,就是对可以预测的问题进行处理并进行纠正的过程。调试只能够发现可以预测的错误,要处理不可预测的和不可避免的错误时,就必须使用错误处理。通过启用错误处理,就可以使应用程序更稳定、更健壮。所谓错误处理程序,就是应用程序中用来捕获和处理错误的实用程序。

若不使用 On Error Resume Next 语句,发生的任何运行时错误都将是致命的,即,显示错误信息并终止运行。 On Error Resume Next 会使程序从紧随产生错误的语句之后的语句继续执行,或是从紧随最近一次调用过程(该过程含有 On Error Resume Next 语句)的语句继续运行。这个语句可以不顾运行时错误,继续执行程序,之后您可以在过程内部建立错误处理例程。在调用另一个过程时,On Error Resume Next 语句变为非活动的。所以,如果希望在例程中进行内部错误处理,则应在每一个调用的例程中执行 On Error Resume Next 语句。

3.4金字塔的对象模型

上一章介绍了VBA 的IDE 环境和VBA 语法,这一章介绍金字塔对象模型,VBA 语法和金字塔对象模型组成了应用金字塔分析 和VBA 进行开发的基础。从某种程度上讲,理解和熟悉金字塔对象模型的过程,也就是使用金字塔和VBA 进行开发的过程。和使用其他程序开发语言和环境一个很大的差别是,金字塔 VBA 开

33

金字塔决策交易系统高级教程

发必须时刻牢记,开发的目的是解决问题,解决问题的关键在于使用已有的功能,补充和开发缺乏或者很难用的功能(例如某些函数),才是我们使用金字塔交易 和VBA 进行开发的目的。这一切的前提就是熟悉金字塔对象模型。另一方面,金字塔对象模型包括了大量的对象、属性和方法,任何人也不可能记住所有的内容,因此,熟悉是指熟悉其结构和组成,对于一个对象的具体方法和属性则没有必要记住,完全可以在开发的时候通过查看帮助菜单->VBA编程信息来获得帮助。在这里我们主要列举11个我们最常用到的内部对象。

3.4.1Application 对象

Application 对象是金字塔对象模型的最上部的对象,代表了金字塔应用程序本身。Application 对象提供了大量属性、方法和事件,用来操作金字塔程序,下面我们挑选一些重要的属性和方法介绍,并随机附带范例。

(1)框架类方法

框架在金字塔中是个很重要的概念,我们操作金字塔软件看盘分析都在框架中进行,金字塔的概念中,框架是整体的一个局部的概念,比如我们常见的K线技术分析图表,就是一个框架,每个框架由若干的窗格组成,有关窗格的对象我们后面还会有介绍,以K线技术分析框架为例,它就是由一个主窗格(K线图)加下面若干个技术分析副图组成。

ActivateFrame 激活或者打开一个指定的框架。 IsActivateFrame 确定一个框架是否激活显示状态。

GetActiveFrameName 得到当前激活的框架名称,若激活窗口不是框架,那么返回空串 ActivateFrameWithCode 以指定代码和周期激活或者打开一个指定的框架。 举例:

'如果没有打开k线技术分析图表框架,就打开 if Application.isActivateFrame(\ Call application.ActivateFrame(\ end if

(2)定时器

如果我们需要金字塔定时每隔一段时间完成某些事情,比如到了某个时间点关闭软件,每隔10秒下委托一笔交易,这就需要定时器了。

举例:

‘VBA引擎开启时运行该事件 Sub Application_VBAStart()

Call Application.SetTimer(0,2*1000) '设置一个0号计时器,间隔2秒执行一次 Call Application.Settimer(9,5*1000) '设置一个9号计时器,间隔5秒执行一次 End Sub

34

金字塔决策交易系统高级教程

'下面的过程是计时器循环体,我让计时器显示每次触发的时间,你看看是不是间隔设定的秒数就触发。 Sub Application_Timer(ID) If ID=0 then

Application.msgout Cdate(time) & \号计时器触发了\ end if If ID=9 then

Application.msgout Cdate(time) & \号计时器触发了\ end if End Sub

特别需要注意的地方:

1、计时器一旦设置,如果不显式销毁,下次启动vba时依然会生效的。 所以,你要记住在Application_VBAEnd事件中使用Killtimer来销毁计时器。

2、Application_VBAStart只能有一个,你不要在多个模块中拥有多个vbastart事件,那样系统就会出错的。

(3)MsgOut

消息窗口显示消息,可以用该函数进行用户消息提示或者进行调试工作。例如 Application.MsgOut(\你好\,将弹出消息窗口显示字符串。

(4)ClearMsg

清除消息窗口的所有显示文本 (5)PostMessage

发送系统消息,发送完毕后直接返回。消息参数一般是系统的菜单命令或者一些系统命令。比如 文件->退出菜单的命令ID是57665,因此只要使用该命令就可以让金字塔退出,示例:

application.PostMessage(57665) 下面是我们常用的一些菜单的ID 退出关闭金字塔 57665 刷新沪深扩展统计数据 33898 停止VBA引擎 32797 打开全局变量数据库 33179 交易菜单->账户窗口 33821 交易菜单->交易状态 33829 交易菜单->登录交易平台 33846 交易菜单->持仓及账户汇总 33956

35

金字塔决策交易系统高级教程

交易菜单->图表程式化交易 33873 交易菜单->后台程式化交易 33228 工具菜单->数据补充 33882 工具菜单->数据->数据管理器 454 工具菜单->手机远程监控 34005 查看菜单->全屏显示 32920 查看菜单->刷新 32883 分析菜单->自定义数据 33478 画线工具栏命令 重置画线 59800 线段 59808

3.4.2Order对象

对象负责定单管理和查询等操作,接收委托服务器发送来的各种帐户持仓信息。该Order对象还支持多帐户的下单模式,用户可以在闪电下单时截获该事件,并处理成自己的操作方式以达到可以实现比如赢损下单的目的。除此之外,该对象还支持多帐户操作。该对象是金字塔程序化交易最常用的对象,重要程序不言而喻。

下面我们主要介绍一些常用的属性和方法,更多的请用户参考 帮助菜单->VBA编程信息->内部对象

主要属性:

(1)Holding2:得到当前指定帐户的持仓品种数量

(2)OrderNum2:得到所有当前有效的未成交合约品种数量

(3)OrderQueue:顺序执行下单成交,即按委托顺序成交报单,可以用于平仓反手,套利等委托动作 主要方法: Account: Account2: Buy: Sell:

得到当前默认帐户信息 得到指定的帐户信息

开多操作 平多操作

开空操作

BuyShort: SellShort:

平空操作 执行撤单操作

取指定索引的指定帐户的合约持仓信息

CancelOrder: HoldingInfo2:

HoldingInfoByCode2:取指定品种的持仓合约信息 OrderInfo2:

取指定索引的未成交合约信息

36

金字塔决策交易系统高级教程

OrderInfoByCode2: Contract:

取指定品种的未成交合约信息 取指定品种的合约信息

计算指定品种的本次交易手续费用

判断指定帐号是否是当前已登录有效帐号,例如 Order.IsAccount(\,

ChargeByNum: IsAccount:

如果该账户已登录则返回1,否则返回0

主要事件

OrderStatusEx2: 当委托订单出现变化时发生该扩展事件,比如撤单、成交等

应用场景及代码片段:

(1)获取指定者账户的所有持仓合约,保存到一个字符串中。

此例需要解决的问题:首先要获取账户的总持仓数,需要用到Holding2属性,然后要逐一循环取出每一个持仓合约的持仓量,需要用到HoldingInfo2方法。

function GetHoldStr(sAccount) dim i dim BuyHold dim BuyCost dim SellHold dim SellCost dim CurCode dim CurMarket

On Error resume Next HoldStr=\

HoldingCount=Order.Holding2(sAccount) If HoldingCount>0 then For i=0 to HoldingCount-1 Call

Order.HoldingInfo2(i,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,Code,Market,sAccount) CurCode=Code CurMarket=Market BuyHold=BuyHolding SellHold=SellHolding HoldStr=HoldStr & CurCode

37

金字塔决策交易系统高级教程

if BuyHold>0 then

HoldStr=HoldStr & \ end if

if SellHold>0 then

HoldStr=HoldStr & \ end if

HoldStr=HoldStr & \

Set Code = nothing Set Market = nothing Next

HoldStr=Left(HoldStr,len(HoldStr)-1) End If

GetHoldStr=HoldStr End function

本代码使用函数方式,传递一个账户号码,就可以获取该账户的持仓信息,调用方法是:hold=GetHoldStr(\。

(2)获取指定合约的信息,包括合约最小跳动单位,合约保证金比例、合约乘数。 private iMultipliter,iMinTick,iShortPercent,iLongPercent Sub GetContractHold(sCode,sMarket) '获取合约的信息 'Application.MsgOut sCode & \ on error resume next

Call Order.Contract(sCode,sMarket,Multipliter,MinTick,ShortPercent,LongPercent) iMultipliter=Multipliter

'application.MsgOut iMultipliter iMinTick=MinTick

iShortPercent=ShortPercent iLongPercent=LongPercent End Sub

本例使用变量来存储合约信息的4个值,所以,变量定义置于过程顶端,调用本过程之后,变量就存储了该合约的对应值,其他过程就可以直接使用了。

(3)获取未成交的订单信息

38

金字塔决策交易系统高级教程

Function GetPendingOrder(sCode,sMarket) '获取未成交单 dim Orderid '订单ID dim Filled '提交手数 dim Remaining '剩余手数 dim Action '买卖 dim OrderType '订单类型 dim LmtPrice '委托价 dim Account '账户 dim Kaiping '开平 GetPendingOrder=0

PendingCount=Order.OrderNum2 For i=0 to PendingCount-1 Call

Order.OrderInfo2(i,OrderID,ConSign,Filled,Remaining,Action,OrderType,LmtPrice,Account,Kaiping,Code,Market)

if Code=sCode then

GetPendingOrder=OrderID end if

Set Code = nothing Set Market = nothing Set Account = nothing

Next end function

本函数返回指定合约的未成交单的订单号,调用方法:OrdID=GetPendingOrder(\然后根据这个返回的OrdID,你可以进行其他的操作,比如,如果是要下单,先看有没有未成交的委托单,如果有就不下单,或者取消该委托单然后再下单等。

(4)取消所有委托单

Sub CancelAllOrder() '撤销所有委托 dim Orderid '订单ID dim Filled '提交手数 dim Remaining '剩余手数 dim Action '买卖 dim OrderType '订单类型

39

金字塔决策交易系统高级教程

dim LmtPrice '委托价 dim Account '账户 dim Kaiping '开平

PendingCount=Order.OrderNum2 For i=0 to PendingCount-1

CallOrder.OrderInfo2(i,OrderID,ConSign,Filled,Remaining,Action,OrderType,LmtPrice,Account,Kaiping,Code,Market) CancelOrder OrderID

Set Code = nothing Set Market = nothing Set Account = nothing Next End Sub

这个过程,遍历每一个委托单,逐一进行撤销操作。如果你要撤销指定OrderID的委托单,只需对此过程稍作修改就可以实现了。

(5)获取指定品种的持仓量、持仓均价

private AccountID,iBuyHold,iSellHold,BuyPrice,SellPrice Sub GetHoldByCode(sAccount,sCode,sMarket) dim i,k

dim BuyHolding dim BuyCost

dim BuyTodayHolding dim SellHolding dim SellCost

dim SellTodayHolding dim PNL dim UseMargin dim Code dim Market

On Error resume Next

AccountStatus=Order.Account2(2,sAccount)

'application.MsgOut sCode & \账户状态:\

40

金字塔决策交易系统高级教程

if AccountStatus=255 Or AccountStatus=\ exit sub end if Call

Order.HoldingInfoByCode2(sCode,sMarket,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,sAccount) iBuyHold=BuyHolding iSellHold=SellHolding BuyPrice=BuyCost SellPrice=SellCost End Sub

这个过程也是将返回的值保存到外部变量,供其他过程使用。所以过程前的定义变量必不可少。 使用方式:GetHoldByCode \'传入交易账户、合约代码、市场代码

(6)计算订单手续费

手续费的计算可以使用ChargeByNum(Code, Market, lmtPrice, Volume, Type)方法

如计算股指期货IF05的交易手续费,可以这么做: sxf=ChargeByNum(\参数说明:Code合约代码、Market市场代码、lmtPrice委托价、Volume委托量、Type买卖方向

使用此方法计算的手续费取决于你是否正确设置了合约信息中的保证金比例、手续费标准,如果设置不对,计算就不对了。

(7)根据合约代码获取持仓量、持仓均价并存入全局变量中共后台策略调用 '传入交易账户号、合约代码、市场代码 如:GetHoldByCode \Sub GetHoldByCode(sAccount,sCode,sMarket) dim i dim BuyHolding dim BuyCost

dim BuyTodayHolding dim SellHolding dim SellCost

dim SellTodayHolding dim PNL

41

金字塔决策交易系统高级教程

dim UseMargin dim Code dim Market

On Error resume Next

AccountStatus=Order.Account2(2,sAccount) '检测账户是否登陆,如果没有登陆就退出

'application.MsgOut sCode & \账户状态:\

if AccountStatus=255 Or AccountStatus=\ exit sub end if

Call Order.HoldingInfoByCode2(sCode,sMarket,BuyHolding,BuyCost,BuyTodayHolding,SellHolding,SellCost,SellTodayHolding,PNL,UseMargin,sAccount) iBuyHold=BuyHolding iSellHold=SellHolding DuoPrice=BuyCost KongPrice=SellCost

Call Document.SetExtData(\多开仓价\ Call Document.SetExtData(\空开仓价\ Call Document.SetExtData(\多持仓\ Call Document.SetExtData(\空持仓\

End Sub

图表或后台策略中调用全局变量的方法: aa:=extgbdata('多开仓价'); bb:=extgbdata('空开仓价'); cc:=extgbdata('多持仓); dd:=extgbdata('空持仓);

(8)OrderStatusEx2事件

当委托订单出现变化时发生,比如撤单、成交等会触发该事件。Order对象的OrderStatusEx和OrderStatusEx2的区别是,后者返回了交易账户。建议使用后者,可以精确指定对那个帐户的交易情况进行处理。OrderStatusEx2是重头戏,这个事件威力无穷,值得好好聊聊。

从帮助文字可以看出,这个事件监控订单的变化情况,从下单、撤单、成交等都可以实时回传给你的,通过这个事件,你可以做很多事件的。

42

金字塔决策交易系统高级教程

1)做一个账户跟踪程序,跟踪另一个账户的交易,就要用到这个事件,具体思路是有成交时,判断是哪一个账户成交,如果是你要监控的账户,就同步在另一个账户开同向的仓位。

2)可以做一个将成交记录实时写到Excel的程序,这样你就可以清楚地看到你当前的交易,盈亏计算也可以在excel中完成。

http://www.weistock.com/bbs/dispbbs.asp?boardid=5&Id=10234

3)用在套利策略中,可以用来处理单腿交易等。

4)其他需要监控账户变动情况,如:下单后多长时间不成交撤单,你需要记录下单的时间,然后比较最新时间与该时间的间隔来确定是否需要撤单。

需要说明一下金字塔返回的订单状态: 1)Submitted:是已经提交订单。 2)Filled:是已经成交的订单。

3)Tradeing:是成交回报,可能filled状态的单成交时分多次成交,那么这个状态的单就会有多个。 4)Cancelled:是已经取消的单

下面是一个将成交情况存入全局变量的实例

Sub ORDER_OrderStatusEx2(OrderID, Status, Filled, Remaining, Price, Code, Market, OrderType, Aspect, Kaiping,Account, AccountType)

'账户类型 0 IB 1 CTP 2 金仕达3其他 Dim sStatus '成交状态 If AccountType=0 then sAccType=\

ElseIf AccountType=1 then sAccType=\

ElseIf AccountType=2 then sAccType=\金士达\End if

If AccountType=0 then sStatus=\

ElseIf AccountType=1 then sStatus=\lseIf AccountType=2 then sStatus=\

43

金字塔决策交易系统高级教程

End if

If UCase(Status)=\只跟踪成交的单 if Aspect=0 and Kaiping=0 then '买入

Call Document.SetExtString(\成交时间 Call Document.SetExtData(\成交价格 Call Document.SetExtData(\成交手数 Call Document.SetExtData(\成交单号 end if

if Aspect=1 and Kaiping=0 then '卖出

Call Document.SetExtString(\成交时间 Call Document.SetExtData(\成交价格 Call Document.SetExtData(\成交手数 Call Document.SetExtData(\成交单号 end if

if Aspect=1 and Kaiping>0 then '卖平

Call Document.SetExtString(\成交时间 Call Document.SetExtData(\成交价格 Call Document.SetExtData(\成交手数 Call Document.SetExtData(\成交单号 end if

if Aspect=0 and Kaiping>0 then '买平

Call Document.SetExtString(\成交时间 Call Document.SetExtData(\成交价格 Call Document.SetExtData(\成交手数 end if End if End Sub

把这段代码复制到你的金字塔vba模块中,试着下几个单,然后可以看看全局变量中是否有下单时间、成交价格、成交手数、成交单号这些变量。

44

金字塔决策交易系统高级教程

3.4.3MarketData 对象

该对象描述了市场行情数据。可以通过这个对象来访问指定的品种的各种数据,也可以维护接收数据的设置。作为一个程序化交易软件,是离不开大量数据支持的,该对象也是一个数据的集中地,包括所有的数据处理均可以在该对象中找到方法。

下面我们例举一些最常用的方法和事件,该方法还包含了有关后台预警,后台程序化,以及股票池、期权等很多的操作这里不再一一列举,请用户参考 帮助菜单->VBA编程信息->内部对象。

GetReportData:取指定品种行情数据ReportData对象,该对象用于表示该品种最新

行情数据.

'在Test过程中打印出上海600217品种当前最新价。 Sub test()

set Report1 = marketdata.GetReportData(\msgbox Report1.NewPrice End Sub

GetReportCount:得到指定市场的品种数量.例如:GetReportCount(\表示取上海

期货交易所所有合约数量.如果调用失败返回-1.

GetReportDataByIndex:得到指定市场指定基于0索引的ReportData对象,该方法

主要可以用来对整个市场的品种进行遍历.

示例

‘该示例从郑州市场筛选SR合约得最大持仓量做为主力合约 Sub Test() Dim MaxCode Dim MaxVolume

'得到市场所有品种

Count = MarketData.GetReportCount(\ For i = 0 To Count-1

Set Report1 = MarketData.GetReportDataByIndex(\ '只处理SR合约

if Left(Report1.Label,2) = \ '只处理有效合约

if Right(Report1.Label,2) >= \ If Report1.Volume > MaxVolume Then

45

金字塔决策交易系统高级教程

MaxCode = Report1.Label MaxVolume = Report1.Volume End if end if End if Next

'显示成交量最大得合约 MsgBox MaxCode End Sub

GetHistoryData:取指定品种历史数据HistoryData对象,该对象记录了该品种历史数

据。

注意:

(1)HistoryDataMode属性为0时,该对象使用一个共有的缓冲区来保存用户打开的市场数据,这意味着用户所调用的数据内容再下次重新调用其他品种或者调用不同种类的数据后会自动失效,若要在不同的品种间做横向数据处理请注意备份之前打开的数据,用户可以使用Visual Basic内部提供的数组,另外还可以使用金字塔为您提供的功能强大的数组类Array.

(2)HistoryDataMode属性为1时,不同品种为独立的缓冲区,这样你就可以同时打开多个品种进行横向统计处理了,但是注意当HistoryDataMode=1时,数据使用完毕请调用DestroyHistoryData方法清理内存缓冲区.处于该模式时只有不同的品种才是独立的内存缓冲区,如果相同品种的多次调用,同样是共享缓冲区的.

GetHistoryData (Code, Market,CycType,[Count,Parameter]) Code 品种代码 Market 市场标识

Cyctype 周期类型,0 1分钟 1 5分钟 2 15分钟 3 30分钟 4 60分钟 5日线 6周线 7月线 8年线 9多日线 10分笔成交11多小时线 12多秒线13多分钟线14季度线 15半年线 16节气线 17 3分钟 18 10分钟 19 多笔线

Count 可选参数,若填数字则表示指定的调用数量,为0或者不填表示读取该品种在本地硬盘保存的全部数据

Parameter 可选参数若,当Cyctype为自定义周期时指定自定义周期数字。不填则表示使用系统选项设置中的自定义周期数字。

返回值 返回品种HistoryData对象 范例1:

46