论坛全局菜单下方 - TICKMILL 285X70论坛全局菜单下方 - ThinkMarkets285X70论坛全局菜单下方 - 荔枝返现285X70论坛全局菜单下方 -  icmarkets285X70
查看:1146回复:1
老正
注册时间2003-09-21
365热心助人奖
[MT4相关]如何评估智能交易测试结果
楼主发表于:2013-11-11 18:27只看该作者倒序浏览
1楼 电梯直达
电梯直达
[backcolor=rgb(251, 251, 252)]首先,我们来谈谈测试程序。在测试开始之前,测试的子系统加载智能交易,设定用户指定的先前参量并且调用init()函数。随后通过生成次序测试开始,并且每次都会调用 start()函数。当测试的次序耗尽,会调用 deinit()函数。这样,整个交易历史在测试期间产生测试数据。在此时这个智能交易的效率可以进行分析。[/backcolor]
[backcolor=rgb(251, 251, 252)]CalculateSummary函数提供以下测试结果计算,即,在策略测试的标准报告中给出数据。[/backcolor]
void
CalculateSummary
(
double
initial_deposit
)
{
int
sequence
=
0
,
profitseqs
=
0
,
lossseqs
=
0
;
double
sequential
=
0.0
,
prevprofit
=
EMPTY_VALUE
,
drawdownpercent
,
drawdown
;
double
maxpeak
=
initial_deposit
,
minpeak
=
initial_deposit
,
balance
=
initial_deposit
;
int
trades_total
=
HistoryTotal
()
;
//---- 初始化总结
InitializeSummaries
(
initial_deposit
)
;
//----
for
(
int
i
=
0
;
i
<
trades_total
;
i
++
)
{
if
(
!
OrderSelect
(
i
,
SELECT_BY_POS
,
MODE_HISTORY
))
continue
;
int
type
=
OrderType
()
;
//---- 不考虑初始差额
if
(
i
==
0
&&
type
==
OP_BALANCE
)
continue
;
//---- 计算赢利
double
profit
=
OrderProfit
()
+
OrderCommission
()
+
OrderSwap
()
;
balance
+=
profit
;
//---- 检测借款
if
(
maxpeak
<
balance
)
{
drawdown
=
maxpeak
-
minpeak
;
if
(
maxpeak
!=
0.0
)
{
drawdownpercent
=
drawdown
/
maxpeak
*
100.0
;
if
(
RelDrawdownPercent
<
drawdownpercent
)
{
RelDrawdownPercent
=
drawdownpercent
;
RelDrawdown
=
drawdown
;
}
}
if
(
MaxDrawdown
<
drawdown
)
{
MaxDrawdown
=
drawdown
;
if
(
maxpeak
!=
0.0
)
MaxDrawdownPercent
=
MaxDrawdown
/
maxpeak
*
100.0
;
else
MaxDrawdownPercent
=
100.0
;
}
maxpeak
=
balance
;
minpeak
=
balance
;
}
if
(
minpeak
>
balance
)
minpeak
=
balance
;
if
(
MaxLoss
>
balance
)
MaxLoss
=
balance
;
//---- 仅限市场定单
if
(
type
!=
OP_BUY
&&
type
!=
OP_SELL
)
continue
;
SummaryProfit
+=
profit
;
SummaryTrades
++;
if
(
type
==
OP_BUY
)
LongTrades
++;
else
ShortTrades
++;
//---- 亏损交易
if
(
profit
<
0
)
{
LossTrades
++;
GrossLoss
+=
profit
;
if
(
MinProfit
>
profit
)
MinProfit
=
profit
;
//---- fortune changed
if
(
prevprofit
!=
EMPTY_VALUE
&&
prevprofit
>=
0
)
{
if
(
ConProfitTrades1
<
sequence
||
(
ConProfitTrades1
==
sequence
&&
ConProfit2
<
sequential
))
{
ConProfitTrades1
=
sequence
;
ConProfit1
=
sequential
;
}
if
(
ConProfit2
<
sequential
||
(
ConProfit2
==
sequential
&&
ConProfitTrades1
<
sequence
))
{
ConProfit2
=
sequential
;
ConProfitTrades2
=
sequence
;
}
profitseqs
++;
AvgConWinners
+=
sequence
;
sequence
=
0
;
sequential
=
0.0
;
}
}
//---- 赢利交易(profit>=0)
else
{
ProfitTrades
++;
if
(
type
==
OP_BUY
)
WinLongTrades
++;
if
(
type
==
OP_SELL
)
WinShortTrades
++;
GrossProfit
+=
profit
;
if
(
MaxProfit
<
profit
)
MaxProfit
=
profit
;
//---- fortune changed
if
(
prevprofit
!=
EMPTY_VALUE
&&
prevprofit
<
0
)
{
if
(
ConLossTrades1
<
sequence
||
(
ConLossTrades1
==
sequence
&&
ConLoss2
>
sequential
))
{
ConLossTrades1
=
sequence
;
ConLoss1
=
sequential
;
}
if
(
ConLoss2
>
sequential
||
(
ConLoss2
==
sequential
&&
ConLossTrades1
<
sequence
))
{
ConLoss2
=
sequential
;
ConLossTrades2
=
sequence
;
}
lossseqs
++;
AvgConLosers
+=
sequence
;
sequence
=
0
;
sequential
=
0.0
;
}
}
sequence
++;
sequential
+=
profit
;
//----
prevprofit
=
profit
;
}
//---- 最终借款检验
drawdown
=
maxpeak
-
minpeak
;
if
(
maxpeak
!=
0.0
)
{
drawdownpercent
=
drawdown
/
maxpeak
*
100.0
;
if
(
RelDrawdownPercent
<
drawdownpercent
)
{
RelDrawdownPercent
=
drawdownpercent
;
RelDrawdown
=
drawdown
;
}
}
if
(
MaxDrawdown
<
drawdown
)
{
MaxDrawdown
=
drawdown
;
if
(
maxpeak
!=
0
)
MaxDrawdownPercent
=
MaxDrawdown
/
maxpeak
*
100.0
;
else
MaxDrawdownPercent
=
100.0
;
}
//---- 考虑最后交易
if
(
prevprofit
!=
EMPTY_VALUE
)
{
profit
=
prevprofit
;
if
(
profit
<
0
)
{
if
(
ConLossTrades1
<
sequence
||
(
ConLossTrades1
==
sequence
&&
ConLoss2
>
sequential
))
{
ConLossTrades1
=
sequence
;
ConLoss1
=
sequential
;
}
if
(
ConLoss2
>
sequential
||
(
ConLoss2
==
sequential
&&
ConLossTrades1
<
sequence
))
{
ConLoss2
=
sequential
;
ConLossTrades2
=
sequence
;
}
lossseqs
++;
AvgConLosers
+=
sequence
;
}
else
{
if
(
ConProfitTrades1
<
sequence
||
(
ConProfitTrades1
==
sequence
&&
ConProfit2
<
sequential
))
{
ConProfitTrades1
=
sequence
;
ConProfit1
=
sequential
;
}
if
(
ConProfit2
<
sequential
||
(
ConProfit2
==
sequential
&&
ConProfitTrades1
<
sequence
))
{
ConProfit2
=
sequential
;
ConProfitTrades2
=
sequence
;
}
profitseqs
++;
AvgConWinners
+=
sequence
;
}
}
//---- 收集完毕
double
dnum
,
profitkoef
=
0.0
,
losskoef
=
0.0
,
avgprofit
=
0.0
,
avgloss
=
0.0
;
//---- 连续盈利和亏损的平均数
dnum
=
AvgConWinners
;
if
(
profitseqs
>
0
)
AvgConWinners
=
dnum
/
profitseqs
+
0.5
;
dnum
=
AvgConLosers
;
if
(
lossseqs
>
0
)
AvgConLosers
=
dnum
/
lossseqs
+
0.5
;
//---- 绝对值
if
(
GrossLoss
<
0.0
)
GrossLoss
*=-
1.0
;
if
(
MinProfit
<
0.0
)
MinProfit
*=-
1.0
;
if
(
ConLoss1
<
0.0
)
ConLoss1
*=-
1.0
;
if
(
ConLoss2
<
0.0
)
ConLoss2
*=-
1.0
;
//---- 赢利原因
if
(
GrossLoss
>
0.0
)
ProfitFactor
=
GrossProfit
/
GrossLoss
;
//----期待盈利
if
(
ProfitTrades
>
0
)
avgprofit
=
GrossProfit
/
ProfitTrades
;
if
(
LossTrades
>
0
)
avgloss
=
GrossLoss
/
LossTrades
;
if
(
SummaryTrades
>
0
)
{
profitkoef
=
1.0
*
ProfitTrades
/
SummaryTrades
;
losskoef
=
1.0
*
LossTrades
/
SummaryTrades
;
ExpectedPayoff
=
profitkoef
*
avgprofit
-
losskoef
*
avgloss
;
}
//---- 绝对借款
AbsoluteDrawdown
=
initial_deposit
-
MaxLoss
;
}
[backcolor=rgb(251, 251, 252)]计算正确,机会得知初始化存款额的值 。这样,在init() 函数中AccountBalance()函数必须被调用,在测试开始时将给出差额。[/backcolor]
void
init
()
{
ExtInitialDeposit
=
AccountBalance
()
;
}
[backcolor=rgb(251, 251, 252)]在上面的CalculateSummary 函数中, 与标准的报告一样,盈利在当前的存款额中计算。其他交易结果,像"最大盈利交易" 或 "最大连续亏损"在赢利基础上计算,同样要测量金钱数。随后重新以点数计算赢利。[/backcolor]
...
//---- 仅限市场定单
if
(
type
!=
OP_BUY
&&
type
!=
OP_SELL
)
continue
;
//---- 以点数计算赢利
profit
=
(
OrderClosePrice
()
-
OrderOpenPrice
())
/
MarketInfo
(
OrderSymbol
()
,
MODE_POINT
)
;
SummaryProfit
+=
profit
;...
[backcolor=rgb(251, 251, 252)]使用函数将得到结果写入报告文件中。[/backcolor]
void
WriteReport
(
string
report_name
)
{
int
handle
=
FileOpen
(
report_name
,
FILE_CSV
|
FILE_WRITE
,'\
t
'
)
;
if
(
handle
<
1
)
return
;
//----
FileWrite
(
handle
,
"
Initial deposit
"
,
InitialDeposit
)
;
FileWrite
(
handle
,
"
Total net profit
"
,
SummaryProfit
)
;
FileWrite
(
handle
,
"
Gross profit
"
,
GrossProfit
)
;
FileWrite
(
handle
,
"
Gross loss
"
,
GrossLoss
)
;
if
(
GrossLoss
>
0.0
)
FileWrite
(
handle
,
"
Profit factor
"
,
ProfitFactor
)
;
FileWrite
(
handle
,
"
Expected payoff
"
,
ExpectedPayoff
)
;
FileWrite
(
handle
,
"
Absolute drawdown
"
,
AbsoluteDrawdown
)
;
FileWrite
(
handle
,
"
Maximal drawdown
"
,
MaxDrawdown
,
StringConcatenate
(
"
(
"
,
MaxDrawdownPercent
,
"
%)
"
))
;
FileWrite
(
handle
,
"
Relative drawdown
"
,
StringConcatenate
(
RelDrawdownPercent
,
"
%
"
)
,
StringConcatenate
(
"
(
"
,
RelDrawdown
,
"
)
"
))
;
FileWrite
(
handle
,
"
Trades total
"
,
SummaryTrades
)
;
if
(
ShortTrades
>
0
)
FileWrite
(
handle
,
"
Short positions(won %)
"
,
ShortTrades
,
StringConcatenate
(
"
(
"
,
100.0
*
WinShortTrades
/
ShortTrades
,
"
%)
"
))
;
if
(
LongTrades
>
0
)
FileWrite
(
handle
,
"
Long positions(won %)
"
,
LongTrades
,
StringConcatenate
(
"
(
"
,
100.0
*
WinLongTrades
/
LongTrades
,
"
%)
"
))
;
if
(
ProfitTrades
>
0
)
FileWrite
(
handle
,
"
Profit trades (% of total)
"
,
ProfitTrades
,
StringConcatenate
(
"
(
"
,
100.0
*
ProfitTrades
/
SummaryTrades
,
"
%)
"
))
;
if
(
LossTrades
>
0
)
FileWrite
(
handle
,
"
Loss trades (% of total)
"
,
LossTrades
,
StringConcatenate
(
"
(
"
,
100.0
*
LossTrades
/
SummaryTrades
,
"
%)
"
))
;
FileWrite
(
handle
,
"
Largest profit trade
"
,
MaxProfit
)
;
FileWrite
(
handle
,
"
Largest loss trade
"
,-
MinProfit
)
;
if
(
ProfitTrades
>
0
)
FileWrite
(
handle
,
"
Average profit trade
"
,
GrossProfit
/
ProfitTrades
)
;
if
(
LossTrades
>
0
)
FileWrite
(
handle
,
"
Average loss trade
"
,-
GrossLoss
/
LossTrades
)
;
FileWrite
(
handle
,
"
Average consecutive wins
"
,
AvgConWinners
)
;
FileWrite
(
handle
,
"
Average consecutive losses
"
,
AvgConLosers
)
;
FileWrite
(
handle
,
"
Maximum consecutive wins (profit in money)
"
,
ConProfitTrades1
,
StringConcatenate
(
"
(
"
,
ConProfit1
,
"
)
"
))
;
FileWrite
(
handle
,
"
Maximum consecutive losses (loss in money)
"
,
ConLossTrades1
,
StringConcatenate
(
"
(
"
,-
ConLoss1
,
"
)
"
))
;
FileWrite
(
handle
,
"
Maximal consecutive profit (count of wins)
"
,
ConProfit2
,
StringConcatenate
(
"
(
"
,
ConProfitTrades2
,
"
)
"
))
;
FileWrite
(
handle
,
"
Maximal consecutive loss (count of losses)
"
, -
ConLoss2
,
StringConcatenate
(
"
(
"
,
ConLossTrades2
,
"
)
"
))
;
//----
FileClose
(
handle
)
;
}
[backcolor=rgb(251, 251, 252)]以下给出范例,如何使用这些函数生成报告。[/backcolor]
void
deinit
()
{
if
(
!
IsOptimization
())
{
if
(
!
IsTesting
())
ExtInitialDeposit
=
CalculateInitialDeposit
()
;
CalculateSummary
(
ExtInitialDeposit
)
;
WriteReport
(
"
MACD_Sample_Report.txt
"
)
;
}
}
[backcolor=rgb(251, 251, 252)]在上边的范例中,您能够看到报告结果不仅是在测试结束后生成, 智能交易的运作中。您也许会问如果在终端内账户历史没有全部下载(例如,在账户栏中仅下载一个月的账户历史),怎样获取初始存款额的大小呢。 CalculateInitialDeposit 函数将会帮助解决这个问题。[/backcolor]
double
CalculateInitialDeposit
()
{
double
initial_deposit
=
AccountBalance
()
;
//----
for
(
int
i
=
HistoryTotal
()
-
1
;
i
>=
0
;
i
--
)
{
if
(
!
OrderSelect
(
i
,
SELECT_BY_POS
,
MODE_HISTORY
))
continue
;
int
type
=
OrderType
()
;
//---- 不考虑初始化差额
if
(
i
==
0
&&
type
==
OP_BALANCE
)
break
;
if
(
type
==
OP_BUY
||
type
==
OP_SELL
)
{
//---- 计算赢利
double
profit
=
OrderProfit
()
+
OrderCommission
()
+
OrderSwap
()
;
//---- 并减少差额
initial_deposit
-=
profit
;
}
if
(
type
==
OP_BALANCE
||
type
==
OP_CREDIT
)
initial_deposit
-=
OrderProfit
()
;
}
//----
return
(
initial_deposit
)
;
}
[backcolor=rgb(251, 251, 252)]在MetaTrader 4 客户端内测试报告会以这种形式生成。[/backcolor]
[backcolor=rgb(251, 251, 252)]http://c.mql4.com/articles/2008/03/report.png[/backcolor]
[backcolor=rgb(251, 251, 252)]可以比较使用于独立程序的计算数据。[/backcolor]
Initial
deposit
10000
Total
net
profit
-
13.16
Gross
profit
20363.32
Gross
loss
20376.48
Profit
factor
0.99935416
Expected
payoff
-
0.01602923
Absolute
drawdown
404.28
Maximal
drawdown
1306.36
(
11.5677
%
)
Relative
drawdown
11.5966
%
(
1289.78
)
Trades
total
821
Short
positions
(
won
%
)
419
(
24.821
%
)
Long
positions
(
won
%
)
402
(
31.592
%
)
Profit
trades
(
%
of
total
)
231
(
28.1364
%
)
Loss
trades
(
%
of
total
)
590
(
71.8636
%
)
Largest
profit
trade
678.08
Largest
loss
trade
-
250
Average
profit
trade
88.15290043
Average
loss
trade
-
34.53640678
Average
consecutive
wins
1
Average
consecutive
losses
4
Maximum
consecutive
wins
(
profit
in
money
)
4
(
355.58
)
Maximum
consecutive
losses
(
loss
in
money
)
15
(
-
314.74
)
Maximal
consecutive
profit
(
count
of
wins
)
679.4
(
2
)
Maximal
consecutive
loss
(
count
of
losses
)
-
617.16
(
8
)
[backcolor=rgb(251, 251, 252)]该文章的附加文件SummaryReport.mq4 建议保存在目录experts\include 中并且使用 #include 开启。[/backcolor]
TK29帖子1楼右侧xm竖版广告90-240
个性签名

遇到矛盾 先站在对方的立场上想想问题,先试着去理解别人
如何使用WinMTR查询平台连接流畅度

广告
TK30+TK31帖子一樓廣告
TK30+TK31帖子一樓廣告
WLLYH
注册时间2016-09-17

本站免责声明:

1、本站所有广告及宣传信息均与韬客无关,如需投资请依法自行决定是否投资、斟酌资金安全及交易亏损风险;

2、韬客是独立的、仅为投资者提供交流的平台,网友发布信息不代表韬客的观点与意思表示,所有因网友发布的信息而造成的任何法律后果、风险与责任,均与韬客无关;

3、金融交易存在极高法律风险,未必适合所有投资者,请不要轻信任何高额投资收益的诱导而贸然投资;投资保证金交易导致的损失可能超过您投入的资金和预期。请您考虑自身的投资经验及风险承担能力,进行合法、理性投资;

4、所有投资者的交易帐户应仅限本人使用,不应交由第三方操作,对于任何接受第三方喊单、操盘、理财等操作的投资和交易,由此导致的任何风险、亏损及责任由投资者个人自行承担;

5、韬客不隶属于任何券商平台,亦不受任何第三方控制,韬客不邀约客户投资任何保证金交易,不接触亦不涉及投资者的任何资金及账户信息,不代理任何交易操盘行为,不向客户推荐任何券商平台,亦不存在其他任何推荐行为。投资者应自行选择券商平台,券商平台的任何行为均与韬客无关。投资者注册及使用韬客即表示其接受和认可上述声明,并自行承担法律风险。

版权所有:韬客外汇论坛 www.talkfx.com 联络我们:[email protected]