启动交易模型,并构建 EA
8 I0 |+ U/ ?3 n' d* F4 _$ l在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
8 Y, ~7 R9 X- W1 ~为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。0 }3 p. L, F* _) G% `
以下是制定这些规则的代码。
3 N$ P4 f# W9 @) a//--- Indicator ATR(1) with EMA(8) used for the stop level..." E3 I1 j! x, a, `5 s
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);) p5 b; N4 D/ P2 ~; @$ w n; Q
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
8 V. _6 C5 b5 w/ `' ]5 {9 {//--- Define a variable that indicates that we have a deal...
5 s- G. u9 |0 |5 ubool tem_tick = false;* L+ l f+ u7 j9 ], n6 P x8 M* I
//--- An auxiliary variable for opening a position# g9 i& m$ ?7 u- r+ T
#include<Trade/Trade.mqh>
9 u1 J" d- u4 }9 l; R! R) G& K#include<Trade/SymbolInfo.mqh>
( x T! E; W3 e9 ?$ hCTrade negocios;/ C5 r5 P0 m8 l" s& ?3 i
CSymbolInfo info;( W. i4 H4 s% Y8 l3 t c( D
//--- Define in OnInit() the use of the timer every second$ |7 [7 D. R) w9 P# @
//--- and start CTrade4 j' c- ?5 ~8 A! M0 }$ g0 R5 J
int OnInit()! ]/ j/ x! P1 N3 E$ s/ }, N
{
4 Q& z$ K+ i) I. M, W7 i//--- Set the fill type to keep a pending order
0 @1 \1 Z W" r& A# x//--- until it is fully filled
1 B) t9 j4 `0 L! n" r1 O8 Vnegocios.SetTypeFilling(ORDER_FILLING_RETURN);8 F6 y; t0 j. ~1 g5 w
//--- Leave the fixed deviation at it is not used on B3 exchange4 |. A# c- @% i2 N9 z9 D
negocios.SetDeviationInPoints(5);
% o9 {+ ~% J7 d1 q, X! S; t2 L//--- Define the symbol in CSymbolInfo...
3 K3 C0 H: n! U8 }" F) J' t* [info.Name(_Symbol);- i9 o! Z7 H4 c6 I+ X# y
//--- Set the timer...
! I' X! F' \+ k% S; cEventSetTimer(1);
+ z i5 @2 ^0 v//--- Set the base of the random number to have equal tests...
. R9 d1 F% k7 ~4 oMathSrand(0xDEAD);/ f2 J; \5 x8 v- ]' x; R
return(INIT_SUCCEEDED);
. h0 X& V: w5 b! V" U9 q}* d' v: j/ E5 O4 X- Z& I6 o: W% [2 C
//--- Since we set a timer, we need to destroy it in OnDeInit().
7 _, {6 m) S% Mvoid OnDeinit(const int reason)
7 [, C4 [3 p- e{- G8 ]6 Y( K* o, [& t
EventKillTimer();
" }0 p, A8 p7 g}: b$ J# W; s* p4 y* I
//--- The OnTick function only informs us that we have a new deal
F9 Q0 F, B* {void OnTick()
0 R; a" G( j2 M4 x- u: }: y, D{! Q2 w ?* L% T) {7 o4 z- `* Q
tem_tick = true;) x0 \2 a$ I2 N/ m: R' g! z) R
}
* d: @) M- o: |- M3 Q9 m# Q//+------------------------------------------------------------------+8 R6 {, o1 M2 B5 }) p( G
//| Expert Advisor main function |
3 S# v$ c! T6 I" l//+------------------------------------------------------------------+% ?( e& k: n; b8 p2 c/ f
void OnTimer()3 `! u+ k: v! f+ ?
{
( ~6 M t3 H5 L% o( \1 r1 _" DMqlRates cotacao[];6 `- s! J, q, @3 ]( G2 d
return ;
. z9 N. t; w* R0 p$ d6 eif (negocios_autorizados == false) // are we outside the trading window?' N0 Y# j' o5 _3 I: B
return ;6 r# C' a1 E9 W9 [5 I, A0 M6 i
//--- We are in the trading window, try to open a new position!
! t/ Q* G) L' P- V( o8 m5 B, wint sorteio = MathRand();
# v: y2 ]' o0 F6 r- _3 A//--- Entry rule 1.13 w" V( E) d0 T' f. A
if(sorteio == 0 || sorteio == 32767)
; ^5 N* }+ x, v) i; k# Y! [return ;3 J' A, t7 D- s$ j1 h# A
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
9 v/ p1 K! M% X( o) y{& ]8 h e1 v9 G' x8 M
negocios.Buy(info.LotsMin(), _Symbol);9 H8 B) |9 c2 p1 d' O
}1 Q' W. ]6 {; Q& Z4 t) i
else // Draw rule 1.3 -- odd number - Sell
- p8 J: E; b8 z% I) V+ m{
8 c" m: k( x. s6 h6 enegocios.Sell(info.LotsMin(), _Symbol);
$ o4 T) Z, k, u8 |" Y* f}
+ ?. s' ]6 u8 p' i/ N" y}0 e% p$ m! G. c9 r8 \3 M' f' q
//--- Check if we have a new candlestick...
& N7 M+ N/ x* M# ^6 N. ]* ^ ?bool tem_vela_nova(const MqlRates &rate)% z3 \5 d1 g/ e* b4 M! N' ]
{) a, p. s/ h: [, h# v" s
{
+ [1 V: Z1 \- [& ^, Q; l& Iret = true;
7 q8 C7 O% V' N* g( ]close_positions = false;/ I8 Q) G$ R9 s' X) {) B X" s+ L5 X
}
, M/ ?+ q X& D* m0 E9 A* ?! x4 j1 pelse
1 h/ t8 t5 L2 o4 M! f' _{
* E/ k9 A' i2 t2 o* `) pif(mdt.hour == 16)! c. h& f( Z* a2 b
close_positions = (mdt.min >= 30);$ v1 _0 V6 m8 `( q& W; V! ]
}
2 u( }4 c3 Q6 x" V C+ u( h}
( z6 l7 K/ H& r. Wreturn ret;9 k, r5 x* s, ~, U: }
}
- {5 g g3 r" h- X//---. i0 `7 t& @9 d( |. I, f
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
. `, k2 e1 g' o{7 F4 M; i+ @- S) ^. a
if(PositionsTotal()) // Is there a position?( m5 a) Y/ H! `/ r. q8 w# q: b8 J
{" D$ c# W6 q* ^1 G- T; O2 R, @
double offset[1] = { 0 };! K' A+ Z V' y' N8 ~
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
|2 d3 B7 M* `9 J$ O) c* k. O- l&& PositionSelect(_Symbol)) // Select the existing position!% M9 ?4 G/ ?% s) h4 m; W
{1 c% P W( Z( V" h& H
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);2 T3 P2 V& V$ N4 ]6 t8 W
double SL = PositionGetDouble(POSITION_SL);
! I* I# U7 C2 O$ _ T9 L( B( bdouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));
K; D' W" }& e# Yif(tipo == POSITION_TYPE_BUY)
% }- ?& O# z. w+ n{, @9 Y# _; w4 P) P; H
if (cotacoes[1].high > cotacoes[0].high)
) q7 g$ s% R+ N5 L3 Y{
- E% a5 e9 S* q; q3 z9 v( G1 kdouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];$ U9 O; |/ R+ V
info.NormalizePrice(sl);; p: ^9 N1 {; Q5 `
if (sl > SL)/ k9 V) f$ }. t; M) ~& N
{
4 _. U6 S. |6 B0 n. p j onegocios.PositionModify(_Symbol, sl, TP);9 p" [2 a& W8 u$ j1 q( ]* E6 `
}3 v+ t" j' k- }* l+ v6 {% a! _
}4 g# I# A, l; m$ R6 u2 b
}
5 ]& L, J, \: I { \8 ]else // tipo == POSITION_TYPE_SELL. C# L6 ]0 H# t
{8 z- U5 r; l1 o; g' N$ D
if (cotacoes[1].low < cotacoes[0].low)
+ H7 D# ]" W# k& ^0 K{
( F5 |6 B' e8 R! p- Y, _' Freturn true;% C1 T/ W: P5 ~; p9 ?
}8 z$ Y( n8 o3 b0 M$ v( ^
// there was no position& F; x4 i& I% y/ \0 C
return false;% I1 J, g; p$ ~0 I
}& \0 W; x( ]% P* p! G
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。! h/ S5 Z: E8 j, J. _
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |