# TestReport VBA策略回测

TestReport

该对象提供一整套测试环境, 让VBA的策略开发也可以像PEL语言一样进行策略测试. 使用VBA直接控制测评的最大好处在于用户可以利用VBA语法直接高效控制测试流程,实现众多PEL无法完成的测试事项,并且代码可以经过少量修改就可以实盘操作.

注意:

  • 该对象的测试规则与PEL语言一样为单向持仓,不允许双向持仓.
  • 测试费率使用 交易菜单->合约信息设置 里的资费设置.
  • 该对象仅提供测评功能实现, 开平仓后的持仓均为虚拟持仓,非正式交易环境. 若想实盘交易,请参考 Order 对象
属性
使用测评属性 说明
InitCash 初始投入资金,单位(元)
OpenLossPrice 开仓滑点,单位(最小变动价位)
CloseLossPrice 平仓滑点,单位(最小变动价位)
ReportType 测试报告类型:
0为专业测试报告
1为普通测试报告(比专业测试报告节省更多内存)
ReportName 测试报告名称。注意:如果频繁调用该属性,请注意使用完毕后释放返回值
ClosePosMode 平今仓方式模式。
默认为0期货模式(平今仓优先)
设置为1为平老仓优先(T+1股票模式)
OddlotMode 零股交易方式.指定图表交易是否允许零股买卖.
为0(默认参数)表示允许零股交易;
为1表示不允许零股交易,下单数量将根据每手交易单位自动调整
方法
使用测评方法 说明
StartAndInit 开始并初始化一个新的测试报告系统
AddTestStock 添加测试品种至测试报告系统
StepIt 步进测试报告,该方法通常用在一个测试循环的最后一部,告知测试系统做一些循环测试的后续工作
ShowReport 测试完毕后显示策略报告
交易系统
交易系统 说明
Buy 交易系统评测开多操作
Sell 交易系统评测平多操作
BuyShort 交易系统评测开空操作
SellShort 交易系统评测平空操作
Holding 测评模式下的持仓量,多仓返回正数空仓返回负数
DayHolding 测评模式下的今持仓量,多仓返回正数空仓返回负数
Cash 得到测试模式下当前可用资金余额, 例如Cash(0)表示多头方向的余额,Cash(1)表示空头方向的余额
ANNUALRETURNRATE 得到测试模式下当前的年化收益率, 算法:净利润/交易时间。交易时间不足一年的部分,以(自然日/365)处理
ANNUALRETURNRATER 得到测试模式下当前品种的回归年化收益率
AVGENTERPRICE 当前持有品种的平均持仓成本——最近空仓以来计
ASSET 得到测试模式下当前的净自有资产, 算法:可用现金+占用保证金-融资(现金+品种市值-融资)
AvgLoss 得到测试模式下当前平均亏损. 算法:平均亏损=总亏损/亏损交易次数
AVGLOSSPERIOD 得到测试模式下当前平均亏损周期,算法:平均亏损周期=亏损交易持仓周期/亏损交易次数
AVGPAYOFF 得到测试模式下当前平均盈亏.算法:平均盈亏=净利润/交易次数
AvgWin 得到测试模式下当前平均盈利,算法:平均盈利=总盈利/盈利交易次数
AVGWINPERIOD 得到测试模式下当前平均盈利周期,算法:平均盈利周期=盈利交易持仓周期/盈利交易次数
BESTPERCENT 得到测试模式下当前最大利润率,统计策略根据历史数据运行至今出现所有交易中利润率最大一次的利润率,其数值在0—1之间
BESTTRADE 得到测试模式下当前最大盈利额,统计策略根据历史数据运行至今出现所有交易中盈利最大一次的利润额
ENTERBARS 得到测试模式下当前开仓历时,返回上次开仓到当前的周期数,若之前没有开仓记录返回-1
ENTERPRICE 得到测试模式下当前上次开仓价
ENTERVOL 得到测试模式下当前上次开仓量
EXITBARS 得到测试模式下当前平仓历时,返回上次平仓到当前的周期数,若之前没有平仓记录返回-1
EXITPRICE 得到测试模式下当前上次平仓价
EXITVOL 得到测试模式下当前上次平仓量
GROSSLOSS 得到测试模式下当前总亏损额,算法:总亏损=策略亏损总额(未扣除手续费)
GROSSPROFIT 得到测试模式下当前总盈利额,算法:总盈利=策略盈利总额(未扣除手续费)
MAXDRAWDOWN 得到测试模式下当前最大回撤资金,算法:指资产(权益)曲线出现一个新的最高点后,此高点与其之后的最低点的差值
MAXDRAWDOWNPCT 得到测试模式下当前最大回撤幅度,算法:指资产(权益)曲线出现一个新的最高点后,此高点与其之后的最低点的回撤幅度
MAXSEQLOSS 得到测试模式下当前最大连亏次数,统计策略根据历史数据运行至今出现连续亏损交易的最大次数
MAXSEQWIN 得到测试模式下当前最大连盈次数,统计策略根据历史数据运行至今出现连续盈利交易的最大次数
NETPROFIT 得到测试模式下当前净利润,算法:统计策略所获取盈利或损失的总额.函数返回值为净利润值
NUMLOSSTRADE 得到测试模式下当前亏损次数,统计策略根据历史数据运行至今出现过连亏情况的总次数。每出现一次连亏的情况,数值+1。注意每次平仓算一次交易,而开仓不算
NUMPROFIT 得到测试模式下当前交易盈亏,得到指定交易的盈亏数额,平仓一次算一次交易,开仓不算。用法:NUMPROFIT(N),取第距离现在第N次交易的盈亏数额。例如:NUMPROFIT(1)表示最近一次的盈亏数额
NUMPROFITPER 得到测试模式下当前交易盈亏百分比幅度,得到指定交易的盈亏百分比幅度,平仓一次算一次交易,开仓不算。用法:NUMPROFITPER(N),取第距离现在第N次交易的盈亏百分比幅度。例如:NUMPROFITPER(1)表示最近一次的盈亏幅度
NUMSEQLOSS 得到测试模式下当前连亏次数,统计策略根据历史数据运行至今出现过连亏情况的总次数。每出现一次连亏的情况,数值+1。注意每次平仓算一次交易,而开仓不算
MAXSEQWIN 得到测试模式下当前最大连盈次数,统计策略根据历史数据运行至今出现连续盈利交易的最大次数
NETPROFIT 得到测试模式下当前净利润,算法:统计策略所获取盈利或损失的总额.函数返回值为净利润值
NUMLOSSTRADE 得到测试模式下当前亏损次数,统计策略根据历史数据运行至今出现过连亏情况的总次数。每出现一次连亏的情况,数值+1。注意每次平仓算一次交易,而开仓不算
OPENBAR 得到测试模式下当前开仓历时,上一次仓位=0以来的周期数
OPENPROFIT 得到测试模式下当前浮动盈亏,当前浮动盈亏(当前持仓市值与持仓成本之差)
OPENPROFITPER 得到测试模式下当前浮动盈亏百分比幅度,当前浮动盈亏(当前持仓市值与持仓成本之差)
PAYOFFRATE 得到测试模式下当前盈亏比,算法:盈亏比=总盈利/总亏损
PERCENTWIN 得到测试模式下当前交易胜率,统计策略根据历史数据运行至今出现盈利交易占总交易次数的比例,其数值在0—1之间
PROFITFACTOR 得到测试模式下当前盈利因子,算法:盈利因子=平均盈利/平均亏损
PROFITRISKRATIO 得到测试模式下当前收益风险比,算法:收益风险比=年化收益率/最大资产回撤幅度:即MAR比率。这是最常用的风险报酬比指标。考察让资产平均每年增值的幅度与需承受的最大资产回撤幅度的关系
SEQLOSS 得到测试模式下当前最大连亏金额,当前位置之前最大连续亏损额,注意每次平仓算一次交易,而开仓不算
SEQWIN 得到测试模式下当前最大连盈金额,当前位置之前最大连续盈利额,注意每次平仓算一次交易,而开仓不算
SHARPRATE 得到测试模式下当前夏普比率
SHARPI 得到测试模式下当前品种的夏普方差
TOTALDAYTRADE 得到测试模式下当前日内交易次数,当前位置之前总共有多少次当日的交易,注意每次平仓算一次交易,而开仓不算
TOTALTRADE 得到测试模式下当前交易次数,统计策略根据历史数据运行至今出现总共有多少次交易,注意每次平仓算一次交易,而开仓不算
TYPE 得到测试模式下当前上N次信号类型,得到当前位置之前上N次信号类型输出:
0、无信号
1、开多
2、平多
3、开空
4、平空
用法:TYPE(N)
TYPEBAR 得到测试模式下当前类信号历时,得到当前位置之前上N次信号指定类型距当前周期,用法:TYPEBAR(N,TYPE)N表示上次信号,TYPE表示信号类型
0、无信号
1、开多
2、平多
3、开空
4、平空
例如:TYPEBAR(2,1)表示:倒数第2个开多信号历时
WORSTPERCENT 得到测试模式下当前最大亏损率,统计策略根据历史数据运行至今出现所有交易中亏损率最大一次的利润率,其数值在0—1之间
WORSTTRADE 最大亏损额,统计策略根据历史数据运行至今出现所有交易中亏损最大一次的亏损额
RETURNRATE 得到测试模式下当前品种的收益率
RETURNRATER 得到测试模式下当前品种的回归收益率
SORTINOI 得到测试模式下当前品种的索丁诺方差
ULCERI 得到测试模式下当前品种的奥瑟方差
SORTINORATE 得到测试模式下当前品种的索丁诺比率
ULCERRATE 得到测试模式下当前品种的奥瑟比率
SHARPR 得到测试模式下当前品种的夏普绩效
SORTINOR 得到测试模式下当前品种的索丁诺绩效
ULCERR 得到测试模式下当前品种的奥瑟绩效
公共方法属性(仅对专业测试报告有效)
方法属性 说明
DetailCount 交易明细数量,若出错则返回-1
GetDetailItem 得到交易名细项
ItemType 得到当前打开的测试报告类别,返回值1-35,例如: 1为总体概要 34为组合收益图 35为连续盈亏分析,若出错则返回-1
ChangeItemType 设置当前打开的测试报告项,有效值范围1-35,例如 call TestReport.ChangeItemType(8) 表示切换至交易明细项
ItemListCount 得到测试报告项数据量,仅当打开的是列表式报告项时有效,出错或失败返回-1
GetItemText 得到测试报告项内容,仅当打开的是列表式报告项时有效
SetItemText 设置测试报告项内容,仅当打开的是列表式报告项时有效
InsertItem 在报表下方添加新的行
SaveReport 导出保存测试报告
SaveDetailed 导出保存测试交易明细至文本格式文件
事件(仅对专业测试报告有效)
事件 说明
ItemChanged 当切换报表项时触发该事件
StartAlarmTest 当开始执行后台程序化精细测试时发生。一般用此事件做一些初始化工作
EndAlarmTest 当后台程序化精细测试结束时发生。一般用来做结束后的一些清理工作
AlarmCalcBefor 当后台程序化精细测试,循环测试时准备计算刷新前发生

示例1. 单品种双向交易,5日均线大于收盘价平空做多,反之平多做空


Sub Test1()
    Testreport.StartAndInit '开始测评系统的准备工作
    Testreport.InitCash=100*10000 '初始资金100万
    Testreport.ReportType = 0'使用专业测试报告
    marketdata.HistoryDataMode = 0 'GetHistoryData函数使用共享内存模式

    Set HistroyData = marketdata.GetHistoryData("if00","zj",5)'取股指连续的日线数据
    If TestReport.AddTestStock(HistroyData,"IF00","ZJ",0) < 1 Then '向测试报告系统添加一个新测试品种
        MsgBox "请正确添加品种"
    End If

    Dim data '创建一个变量

    '创建Array外部对象,将对象实例置变量data中, 用来暂存收盘价,计算均价
    Set data = CreateObject("Stock.Array")

    '下面的代码控制循环测试
    '策略逻辑, 5日均线上穿收盘价做多, 下破收盘价平多
    For i = 0 to HistroyData.Count-1
        data.AddBack(HistroyData.Close(i)) '添加数组数据
        If data.Count > 5 Then '如果数组数据大于5个就删除第一个,保证数组只有5个大小
            data.Removeat(0)
        End If
 
        If Data.Count >= 5 Then
            AvgPrice = data.Average
            if HistroyData.Close(i) > AvgPrice Then '均价之上平空开多
                If TestReport.Holding < 0 Then
                    TestReport.SellShort 0,HistroyData.Close(i)
                End IF
                If TestReport.Holding = 0 Then
                    TestReport.Buy 1, HistroyData.Close(i) 
                End If
            End if

            if HistroyData.Close(i) < AvgPrice Then '下破均价平多开空
                If TestReport.Holding > 0 Then
                    TestReport.Sell 0, HistroyData.Close(i)
                End If

                If TestReport.Holding = 0 Then
                    TestReport.BuyShort 1,HistroyData.Close(i)
                End if
            End if
        End if

        '测试完毕强平持仓
        If i = HistroyData.Count-1 Then
            If TestReport.Holding < 0 Then
                TestReport.SellShort 0,HistroyData.Close(i)
            End IF

            If TestReport.Holding > 0 Then
                TestReport.Sell 0, HistroyData.Close(i)
            End If
        End If

        '显示测试时当前的资产,可以这个语句调试,检测当前测试时的变量状态
        Application.msgout TestReport.ASSET
        '为步进下一个数据做准备
        TestReport.StepIt i
    Next
 
    '测试完毕显示测试报告
    Testreport.ShowReport
    set data = Nothing'对象使用完毕后释放对象

    '数据处理完毕后,清理缓冲区 
      marketdata.DestroyHistoryData
End Sub
 
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

示例2.测试2个品种单向交易5日均线大于收盘价平空做多,反之平多做空

Sub Test2()
    Testreport.StartAndInit '开始测评系统的准备工作
    Testreport.InitCash=100*10000 '初始资金100万
    
    '///////////////////////////////////////////////
    '添加第一个股指连续品种测试
    Set HistroyData = marketdata.GetHistoryData("if00","zj",5)'取股指连续的日线数据
    If TestReport.AddTestStock(HistroyData,"IF00","ZJ",0) < 1 Then '向测试报告系统添加一个新测试品种
        MsgBox "请正确添加品种"
    End If

    Dim data '创建一个变量
    '创建Array外部对象,将对象实例置变量data中, 用来暂存收盘价,计算均价
    Set data = CreateObject("Stock.Array")

    '下面的代码控制循环测试
    '策略逻辑, 5日均线上穿收盘价做多, 下破收盘价平多
    For i = 0 to HistroyData.Count-1
        data.AddBack(HistroyData.Close(i)) '添加数组数据
        If data.Count > 5 Then '如果数组数据大于5个就删除第一个,保证数组只有5个大小
            data.Removeat(0)
        End If   
        If Data.Count >= 5 Then
            AvgPrice = data.Average
            if HistroyData.Close(i) > AvgPrice And TestReport.Holding = 0 Then '上穿均价开多
                TestReport.Buy 1, HistroyData.Close(i)
            End if

            if HistroyData.Close(i) < AvgPrice And TestReport.Holding > 0 Then '下破均价平多
                TestReport.Sell TestReport.Holding, HistroyData.Close(i)
            End if
        End if

        '为步进下一个数据做准备
        TestReport.StepIt i
    Next

    '///////////////////////////////////////////////
    '添加第二个螺纹钢连续品种测试
    Set HistroyData = marketdata.GetHistoryData("rb00","sq",5)'取螺纹钢连续的日线数据
    If TestReport.AddTestStock(HistroyData,"RB00","SQ",0) < 1 Then '向测试报告系统添加一个新测试品种
        MsgBox "请正确添加品种"
    End If

    data.Removeall '清空数组 
    '下面的代码控制循环测试
    '策略逻辑, 5日均线上穿收盘价做多, 下破收盘价平多
    For i = 0 to HistroyData.Count-1

        data.AddBack(HistroyData.Close(i)) '添加数组数据
        If data.Count > 5 Then '如果数组数据大于5个就删除第一个,保证数组只有5个大小
            data.Removeat(0)
        End If

        If Data.Count >= 5 Then
            AvgPrice = data.Average
            if HistroyData.Close(i) > AvgPrice And TestReport.Holding = 0 Then '上穿均价开多
                TestReport.Buy 1, HistroyData.Close(i)
            End if
    
            if HistroyData.Close(i) < AvgPrice And TestReport.Holding > 0 Then '下破均价平多
                TestReport.Sell TestReport.Holding, HistroyData.Close(i)
            End if
        End if

        '为步进下一个数据做准备
        TestReport.StepIt i
    Next

    '测试完毕显示报告
    Testreport.ShowReport

    set data = Nothing'对象使用完毕后释放对象

    '数据处理完毕后,清理缓冲区 
    marketdata.DestroyHistoryData

End Sub

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

示例3:该范例主要演示使用分段数据分段进行评测,比如我们可以调用一天天的分笔数据进行测试


Sub Test3()
    Testreport.StartAndInit '开始测评系统的准备工作
    Testreport.InitCash=100*10000 '初始资金100万

    '取历史分笔数据
    Set MinuteData = marketdata.GetHistoryMinuteData("if00","zj","2014-07-11")
    Set HistroyData = marketdata.Changedata(MinuteData)
   
    If TestReport.AddTestStock(HistroyData,"IF00","ZJ",0) < 1 Then '向测试报告系统添加一个新测试品种
        MsgBox "请正确添加品种"
    End If

    Dim data '创建一个变量
    '创建Array外部对象,将对象实例置变量data中, 用来暂存收盘价,计算均价
    Set data = CreateObject("Stock.Array")
    
    '下面的代码控制循环测试
    '策略逻辑, 60周期均线上穿收盘价做多, 下破收盘价平多
    For i = 0 to HistroyData.Count-1
        data.AddBack(HistroyData.Close(i)) '添加数组数据
        If data.Count > 60 Then '如果数组数据大于60个就删除第一个,保证数组只有60个大小
            data.Removeat(0)
        End If

        If Data.Count >= 60 Then
            AvgPrice = data.Average
            if HistroyData.Close(i) > AvgPrice Then '均价之上平空开多
                If TestReport.Holding < 0 Then
                    TestReport.SellShort 0,HistroyData.Close(i)
                End IF

                If TestReport.Holding = 0 Then
                    TestReport.Buy 1, HistroyData.Close(i) 
                End If
            End if

            if HistroyData.Close(i) < AvgPrice Then '下破均价平多开空
                If TestReport.Holding > 0 Then
                    TestReport.Sell 0, HistroyData.Close(i)
                End If

                If TestReport.Holding = 0 Then
                    TestReport.BuyShort 1,HistroyData.Close(i)
                End if
            End if
        End if

        '显示测试时当前的资产
        'Application.msgout TestReport.ASSET
        '为步进下一个数据做准备
        TestReport.StepIt i
    Next

    '////////////////////////////////////////////
    '分段测试第二笔
    Set MinuteData = marketdata.GetHistoryMinuteData("if00","zj","2014-07-14")
    Set HistroyData = marketdata.Changedata(MinuteData)
    
    If TestReport.AddTestStock(HistroyData,"IF00","ZJ",1) < 1 Then '向测试报告系统追加测试数据
        MsgBox "请正确添加品种"
    End If
    
    data.Removeall '清空数组
    
    'Application.MsgOut HistroyData.Count   
    '下面的代码控制循环测试
    '策略逻辑, 60周期均线上穿收盘价做多, 下破收盘价平多
    For i = 0 to HistroyData.Count-1
        data.AddBack(HistroyData.Close(i)) '添加数组数据
        If data.Count > 60 Then '如果数组数据大于60个就删除第一个,保证数组只有60个大小
            data.Removeat(0)
        End If
    
        If Data.Count >= 60 Then
            AvgPrice = data.Average
    
            if HistroyData.Close(i) > AvgPrice Then '均价之上平空开多
                If TestReport.Holding < 0 Then
                    TestReport.SellShort 0,HistroyData.Close(i)
                End IF

                If TestReport.Holding = 0 Then
                    TestReport.Buy 1, HistroyData.Close(i) 
                End If
            End if

            if HistroyData.Close(i) < AvgPrice Then '下破均价平多开空
                If TestReport.Holding > 0 Then
                    TestReport.Sell 0, HistroyData.Close(i)
                End If

                If TestReport.Holding = 0 Then
                    TestReport.BuyShort 1,HistroyData.Close(i)
                End if
            End if
        End if

        '显示测试时当前的资产
        'Application.msgout TestReport.ASSET
        '为步进下一个数据做准备
        TestReport.StepIt i
    Next

    '测试完毕显示测试报告
    Testreport.ShowReport

    set data = Nothing'对象使用完毕后释放对象
    '数据处理完毕后,清理缓冲区 
    marketdata.DestroyHistoryData
    '销毁历史分笔数据结构,释放缓冲区
    marketdata.DestroyHistoryMinuteData

End Sub

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

示例4.使用PLE语言做为信号,VBA进行测评

  • 'PEL语言代码:
  • '公式名:MATEST
MA1:=MA(CLOSE,5);
MA2:=MA(CLOSE,15);
开多:CROSS(MA1,MA2);
平多:CROSS(MA2,MA1);
1
2
3
4
Sub Test4()
    Testreport.StartAndInit '开始测评系统的准备工作
    Testreport.InitCash=100*10000 '初始资金100万

    Set Formula = marketdata.STKINDI("if00","zj","matest()",0,5) '调用中金所IF00合约的日线自定义指标
    Set HistroyData = Formula.ParentGrid.GetHistoryData '直接得到公式区的数据对象,提高运行效率
    
    If TestReport.AddTestStock(HistroyData,"IF00","ZJ",0) < 1 Then '向测试报告系统添加一个新测试品种
        MsgBox "请正确添加品种"
    End if

    '下面的代码控制循环测试
    '使用PEL策略的信号进行交易
    For i = 0 to HistroyData.Count-1 
        if Formula.GetBufData("开多",i) = 1 And TestReport.Holding = 0 Then '开多 
            TestReport.Buy 1, HistroyData.Close(i) 
        End if
    
        if Formula.GetBufData("平多",i) = 1 And TestReport.Holding > 0 Then '平多
            TestReport.Sell 0, HistroyData.Close(i)
        End if

        '显示测试时当前的资产
        Application.msgout TestReport.ASSET

        '为步进下一个数据做准备
        TestReport.StepIt i
    Next
    '测试完毕显示测试报告
    Testreport.ShowReport

End Sub
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