启动交易模型,并构建 EA* B7 d% y" E2 i, X/ r
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
1 _9 S/ b# v- [( W/ x3 I0 F为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
( G6 n3 p0 Q# {; E) l; R' z+ D以下是制定这些规则的代码。9 Q+ i/ H' _+ ~+ G8 U. W
//--- Indicator ATR(1) with EMA(8) used for the stop level...5 N- t% V O0 g1 l
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);6 P, Q" T' D$ F: y: r
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
& p w0 w% q7 Q1 L. H//--- Define a variable that indicates that we have a deal...( S6 g# x- P c, j
bool tem_tick = false;
# Q3 [& [ D# p+ \( \//--- An auxiliary variable for opening a position% T( X7 I; l8 U4 b
#include<Trade/Trade.mqh>
4 \: X0 \/ F: \# c+ p#include<Trade/SymbolInfo.mqh>$ J8 |) }' U; S6 g
CTrade negocios;
( A; j4 x, P1 H# ^$ a- @' S, A9 @CSymbolInfo info;
+ l5 V1 U% o& D% e5 x2 X8 u/ B//--- Define in OnInit() the use of the timer every second
( `! h- V0 u) j2 V! ~) s//--- and start CTrade9 ]$ D0 g _ N: T5 m+ C! p( Z# u
int OnInit()
% \- G3 W7 }4 Z, L4 V) h{# l, R8 \3 p" u l2 _' i4 L" N
//--- Set the fill type to keep a pending order7 ]1 a# s. h/ Y t# y3 x) a; r3 G
//--- until it is fully filled
% ~9 ^+ Z" P* L+ F4 rnegocios.SetTypeFilling(ORDER_FILLING_RETURN); ^0 m6 t0 ?- S- k5 T h, v
//--- Leave the fixed deviation at it is not used on B3 exchange5 a7 T; K- P' d6 p) u2 r
negocios.SetDeviationInPoints(5);
8 y8 B0 |" }; N//--- Define the symbol in CSymbolInfo..., B* C$ W. r' Q0 u' b$ Y- j# b: s
info.Name(_Symbol);
, M( {8 D$ }, i//--- Set the timer.../ V, w1 F2 f0 T" E
EventSetTimer(1);3 Y- Y1 ]7 }$ _. {- S# f) v+ p* Z
//--- Set the base of the random number to have equal tests...) ?" k, N2 v0 H# m; r8 B ^) a
MathSrand(0xDEAD);
* U4 ]3 K6 m# O/ |return(INIT_SUCCEEDED);. s0 m3 ^4 M7 V- D: \
}5 u& t' \6 D( Q |+ v
//--- Since we set a timer, we need to destroy it in OnDeInit().
3 m# E# S) @' i) B; \6 Dvoid OnDeinit(const int reason)0 s8 s& e( e/ v- l. l0 E
{* h2 n# c8 U6 s3 O
EventKillTimer();, o* w9 V" D0 N/ y1 ^
}; F7 z. U' X, M$ a: M" O
//--- The OnTick function only informs us that we have a new deal* \: h3 G6 `7 a# s% e
void OnTick()
" F- n" ~0 f- I' f2 ^{
4 [" Y0 f* |! o6 f9 vtem_tick = true;( F9 R; |% W, R2 @/ m0 Z4 U
}9 E. v% }5 \/ ]; T+ L& [' C; W
//+------------------------------------------------------------------++ b* S3 `5 \, L4 g$ b
//| Expert Advisor main function |
' J9 x# t% {9 B, d5 w* h4 r//+------------------------------------------------------------------+# `% R5 C" [2 T0 H) M
void OnTimer()
# F& s+ K+ d, u3 q2 l( u8 J7 z& D{
% S* k4 A. W. g& I! s% ^; ^$ z2 ?MqlRates cotacao[];
$ h* c% R- h1 x e2 I# `return ;$ Q @' a2 s$ F7 ]3 d( t- Y
if (negocios_autorizados == false) // are we outside the trading window?; h* _3 i/ y) g) j. r
return ;
( h6 `7 a6 O/ R! K+ Z//--- We are in the trading window, try to open a new position!
9 q! v! f( e) ?! \! p& N# Tint sorteio = MathRand();) k3 w4 ?) K) ]8 f! J
//--- Entry rule 1.17 ?3 O; z4 V& g a" w
if(sorteio == 0 || sorteio == 32767) B1 z: [% x# X4 ]/ p) p0 F' E
return ;
: b' x$ H! J: O8 r( s, p1 gif(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy+ H4 I( e1 Z2 K p4 x: \) R9 O
{
* @; |6 W! R; rnegocios.Buy(info.LotsMin(), _Symbol);
2 o" n o' p2 a. O8 J}; h6 Y4 [; t8 J
else // Draw rule 1.3 -- odd number - Sell
1 `3 o7 q' N Y( N* f2 A{2 G( f! t9 B# m4 c0 c
negocios.Sell(info.LotsMin(), _Symbol);1 r8 b& y+ }1 T# G1 I$ F9 M5 z
}) M5 s; a( [+ T* F6 U
}
; H% L9 D3 k: A2 w//--- Check if we have a new candlestick...
3 ]; h2 ^& o s! b$ N$ Qbool tem_vela_nova(const MqlRates &rate)3 W/ j1 }, ?" o" G9 z4 |
{
& `/ H# [0 T" c: e3 T9 B6 P{
4 I0 U& O! q6 S7 }5 m: mret = true;4 O- _' M+ v5 R0 P' q
close_positions = false;, o- l) m- g: o4 B! k& y# j4 R; k
}
4 p2 y% ]3 ?1 S8 n" J( Jelse' Z& o! H3 Y# ]" m
{/ M4 R$ a# c: a. [. S
if(mdt.hour == 16)7 Q2 i2 M2 o+ s9 U$ B, z0 J! d
close_positions = (mdt.min >= 30);
/ b+ X' k! t# }/ K9 P. _}
8 w/ n0 [8 g' u4 a}7 a6 V% \2 D+ }# L3 }( X6 b0 J
return ret;
# l# |, D, t/ I' l4 \: v}/ h+ m' F! O% N5 M
//---9 ]/ d% S/ e1 R2 [9 }
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
; i5 O( B' v) Q+ c0 I5 i; o, n{% X. x; }1 ]: g9 w7 k$ \
if(PositionsTotal()) // Is there a position?, E( N3 n- s& W( e
{
4 N% O; f& C% r: E" ddouble offset[1] = { 0 };
: ?) ]2 {9 n& Z$ q3 E# {if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
* M" ]5 U7 d- B9 }- B# k8 }&& PositionSelect(_Symbol)) // Select the existing position!* {) _! D8 w; p: n
{: N: u6 h* l3 e& R$ P* n
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);" j5 L+ t/ @- j
double SL = PositionGetDouble(POSITION_SL);; W2 f* c2 k3 T {& m7 ^
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));; F/ ?' _% m9 R% L/ Z
if(tipo == POSITION_TYPE_BUY)
$ s& p' q6 u8 t9 E8 i1 |, q{/ k6 S, z; b' L" E" P
if (cotacoes[1].high > cotacoes[0].high) e# B' |* k: O1 @7 Y
{
/ Z7 K5 j" y2 X+ `1 k; R4 b: ?double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
. p4 P+ u( [; K# Finfo.NormalizePrice(sl);3 w) c5 G1 j" t+ R# k6 h2 N7 A
if (sl > SL)
* q, s! M9 x) E8 r. `3 D{) `' C) F& G! r+ E2 V1 u1 s
negocios.PositionModify(_Symbol, sl, TP);% C- \2 R7 i8 t! @
}: i; V+ e2 {, p
}: t1 p# r1 z* |# M+ O L
}# ]# Z) I% \6 |1 m8 t4 ~2 p
else // tipo == POSITION_TYPE_SELL
X/ m# Q m; Q ]3 S: i{
( j' e5 q4 L8 | r4 w$ e' e! f: f- |if (cotacoes[1].low < cotacoes[0].low)
" V# Q [3 l% l3 F% N9 C& M{ u8 F: {' Y9 \: E' s+ j; }: M
return true;
0 K1 }2 g' i; ~}* y& Q3 b9 \- T7 |' ]. s1 [" l( I
// there was no position
2 i, [ }0 q+ areturn false;5 _9 E# u; Q" i# `6 d0 V/ \& _& _
}
# \) o8 R) ]) m$ [! C9 o4 [我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
6 \! d- j- ]$ f1 W2 a1 o% y到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |