本教程将主要以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