-- 作者:雪梨
-- 发布时间:2016/12/19 11:26:43
-- [VBA策略] 自行处理拆单的算法处理模块范例模板
本教程将主要以MA均线金叉死叉为范例做一个可以将大单拆分下单的模板。
金字塔已经自带大单拆单处理模块,因此本教程的目的是为自带功能无法满足的客户的定制的,用户可以在此代码基础上进行调整以满足自身需要,如果用户还不了解金字塔自带的大单拆单处理模块功能,请先参考下面的链接,以确定您是否需要可以直接使用自带的功能。
金字塔程序化交易平台新版滑点优化处理功能说明
http://www.weistock.com/bbs/dispbbs.asp?boardid=10&Id=49056
本文主要以金字塔的VBA自定义函数来实现所需的功能,因此需要读者需要掌握了解金字塔的VBA的一些基础开发,以及如何在VBA使用和开发自定义函数,可以参考
金字塔公式系统里使用自定义函数
http://www.weistock.com/bbs/dispbbs.asp?boardid=5&Id=158&page=2
金字塔VBA编程基础使用介绍教程
在线观看:http://v.youku.com/v_show/id_XMTY3MjE1NjY0.html
PEL范例源码
input:TRADER(0); //交易控制参数,为1表示允许交易
//定义4个超全局变量,防止出现重复触发下单用 GLOBALVARIABLE :buyFig=0; GLOBALVARIABLE :sellFig=0; GLOBALVARIABLE :buyshortfig=0; GLOBALVARIABLE :sellshortFig=0;
MA1:MA(C,5); MA2:MA(C,10);
//取上跟周期的开平仓信号,用来实现固定轮询模式下的走完K线下单 CONDBUY:=REF(CROSS(MA1,MA2),1); CONDSELL:=REF(CROSS(MA2,MA1),1);
DRAWTEXTEX(trader > 0,0,10,15,\'程序化交易运行中\'),COLORRED;
If Islastbar AND trader > 0 THEN Begin fign:=date+time; If CONDBUY and buyFig <> fign Then BEGIN //市场代码和名称置全局变量,用于与VBA系统进行字符串通讯 EXTGBSTRINGSET(\'sCode\' , STKLABEL); EXTGBSTRINGSET(\'sMarket\' , MARKETLABEL); OrderPlease(20,3); //调用自定义函数实现平空操作 sellshortFig := fign; OrderPlease(20,0); //开多 buyFig := fign; end; If CONDSELL and sellFig <> fign Then BEGIN //市场代码和名称置全局变量,用于与VBA系统进行字符串通讯 EXTGBSTRINGSET(\'sCode\' , STKLABEL); EXTGBSTRINGSET(\'sMarket\' , MARKETLABEL); OrderPlease(20,1); //平多 sellFig := fign; OrderPlease(20,2); //开空 buyshortfig := fign; end; End;
VBA范例代码
代码主要逻辑思想简述,将PEL传递过来的下单数量和交易类型,预先按照预设的5组等份切分,然后塞到数组中,定时器按照5秒一次的频率读取数组中的下单设定,然后进行下单,不考虑挂单是否成交,只是按照简单固定方法进行下单。
\'全局数组变量定义区 Set strCode = CreateObject("Stock.ArrayString") Set strMarket = CreateObject("Stock.ArrayString") Set arVol = CreateObject("Stock.Array") Set arOrderType = CreateObject("Stock.Array")
\'VBA自定义函数,PEL调用后直接执行这里
Function OrderPlease(Formula,Vol,OrderType) Application.msgout Now()&" 触发交易信号--"&Vol&"--"&OrderType \'读取PEL置于全局变量中的字符串 Code = document.GetExtString("sCode") Market = document.GetExtString("sMarket") SpiltNum = 5 \'按照5组切分 \'使用简单的循环算法预先将要下单的数量拆分到数组中 sNum = CInt(Vol / SpiltNum) If sNum < 1 Then sNum = 1 End If sVol = 0 For i = 1 to SpiltNum strCode.AddBack(Code) strMarket.AddBack(Market) arOrderType.AddBack(OrderType) If i = SpiltNum Then sNum = sNum + (Vol mod SpiltNum) \'最后一步循环将不能整除的余下数量最后一次处理 End If arVol.AddBack(sNum) sVol = sVol + sNum If sVol >= Vol Then Exit For End If Next
End Function
\'VBA启动后的事件,用来执行定义一个5秒0号定时器 Sub APPLICATION_VBAStart() Application.SetTimer 0,5*1000 \'设定0号定时器,每隔5秒触发一次 End Sub
\'定时器触发事件函数,当有符合触发条件的时间出现后将调用这里,本范例是5秒循环调用一次 Sub APPLICATION_Timer(ID) If Id = 0 Then If strCode.Count > 0 Then \'定时器中的代码比较简单,只要循环将数组的下单直接发送交易即可 Code = strCode.GetAt(0) Market = strMarket.GetAt(0) Vol = arVol.GetAt(0) OrderType = arOrderType.GetAt(0) Set Report1 = marketdata.GetReportData(Code,Market) If Report1 is nothing Then Exit Sub End If If OrderType = 0 Then Price = Report1.SellPrice1 \'获取当前对手价格 If Price = 0 Then \'防止涨停板判断 Price = Report1.NewPrice End If call Order.Buy(0,Vol,Price,0,Code,Market,"",0) ElseIf OrderType = 1 Then Price = Report1.BuyPrice1 If Price = 0 Then Price = Report1.NewPrice End If call Order.Sell(0,Vol,Price,0,Code,Market,"",0) ElseIf OrderType = 2 Then Price = Report1.BuyPrice1 If Price = 0 Then Price = Report1.NewPrice End If call Order.BuyShort(0,Vol,Price,0,Code,Market,"",0) ElseIf OrderType = 3 Then Price = Report1.SellPrice1 If Price = 0 Then Price = Report1.NewPrice End If call Order.Sell(0,Vol,Price,0,Code,Market,"",0) End If \'处理完毕删除数组队列 strCode.RemoveAt(0) strMarket.RemoveAt(0) arVol.RemoveAt(0) arOrderType.RemoveAt(0) End If End If End Sub
|