启动交易模型,并构建 EA
1 e8 q1 C( J& K3 l! O' `在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。8 P" s1 G+ ^' D8 z/ X; s
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
; V' ~- U+ L( D; w3 Y4 k以下是制定这些规则的代码。
; v$ f1 I3 Z5 ?3 K' x% s& P: H' e: c//--- Indicator ATR(1) with EMA(8) used for the stop level...
: V- ]) ?; P2 F( o2 \8 ?int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
2 y1 z: g S( j/ w8 b: tint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
0 e9 m8 U7 K* n//--- Define a variable that indicates that we have a deal...
% B1 y* ^ c. |- r k5 b& J) v1 [: abool tem_tick = false;
1 P$ { h4 E0 t//--- An auxiliary variable for opening a position
2 ~. z6 _9 Z# s* i, p4 ^#include<Trade/Trade.mqh>- i# z* f$ K. S! z
#include<Trade/SymbolInfo.mqh>
# i& j! r1 b* `CTrade negocios;
. d5 Z, }* u6 |0 l! f4 ^4 sCSymbolInfo info;' l" _& |. F: U/ e$ _" \5 t) g
//--- Define in OnInit() the use of the timer every second
6 [) L' ?; R& s//--- and start CTrade$ \- ~. s' d3 `& p0 M2 M4 K# i
int OnInit()3 Y: o' J7 n; Q. [" e
{
4 l! H0 Y; D. x+ e2 ?5 F+ N//--- Set the fill type to keep a pending order, J2 r& a0 @4 @8 D& G
//--- until it is fully filled
3 ], P& B2 b/ j3 Onegocios.SetTypeFilling(ORDER_FILLING_RETURN);0 ]$ U4 R0 k0 Y1 P
//--- Leave the fixed deviation at it is not used on B3 exchange
7 V5 U4 s/ H `' X2 Z" X$ Rnegocios.SetDeviationInPoints(5);
2 B. l: u7 N/ l0 } U//--- Define the symbol in CSymbolInfo...
$ B% n. s( n. V" ]info.Name(_Symbol);
) c- [' {$ C1 {$ f$ T* v( c//--- Set the timer...
- {, T: u) a! u; OEventSetTimer(1);
8 C6 \0 W1 W) O; N//--- Set the base of the random number to have equal tests.../ v( Z% ]0 Y& e
MathSrand(0xDEAD);
: R" ^6 W6 A; Z* y# P1 yreturn(INIT_SUCCEEDED);
! f: \; B( \- j+ J3 u1 r U4 B}0 e; V5 Q: \" e4 C2 J
//--- Since we set a timer, we need to destroy it in OnDeInit().
" K7 p A, n: A( h1 c" z* Kvoid OnDeinit(const int reason)
7 M C; R7 V: E9 N1 A{
8 j( I/ g6 @4 p% B; Q8 T0 g/ M+ AEventKillTimer();6 S. N5 s# h- ^) P% s6 ], N/ j
}8 l7 Z" x* m5 o2 c U
//--- The OnTick function only informs us that we have a new deal8 T" j+ P- ^0 q
void OnTick()
U4 S- q+ Q- f2 }, d& o{' T' R* b. j% ]# R- v' R/ o" U
tem_tick = true;
2 e8 q X( C8 `" ^}
% L( n9 v9 O4 m+ C) D4 k//+------------------------------------------------------------------+
) X9 J7 G! T# t, l7 I//| Expert Advisor main function |- W& L7 }% `9 t* n9 @- ?/ j
//+------------------------------------------------------------------+
. O8 F, F9 ~; ~9 d( V8 \void OnTimer()
" y0 `6 R' K$ C! q{
; Q2 d+ L, W0 _& i" W5 ?MqlRates cotacao[];
, I5 j4 G; F( P- L' h" U. ]return ;
* e; R7 j0 o F" |if (negocios_autorizados == false) // are we outside the trading window?$ N; M. f- V+ H% H
return ;! {9 I6 ~7 h) ~4 Z( u7 k ^
//--- We are in the trading window, try to open a new position!1 }- N7 \9 Q; z1 a$ e* q+ x8 _
int sorteio = MathRand();' a# d# w Q) T; u3 K. ~, ~* W( P
//--- Entry rule 1.1
6 |. w7 v3 G" ^' R. kif(sorteio == 0 || sorteio == 32767)
$ r4 o k; A5 I6 H$ |* Lreturn ;, w6 z0 u! z1 G6 L% Q) z6 W
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy! M8 \* Q) I: S, r0 Y1 e
{- {9 x$ s$ O0 A% W' @) Y- I
negocios.Buy(info.LotsMin(), _Symbol);4 r) v# J' J4 R; ]- x
}
# B( D5 O+ G: T; _/ k l+ ^* nelse // Draw rule 1.3 -- odd number - Sell7 V0 `" T6 O4 P! Q; e& k
{3 m- {% B) J% v5 U5 s; V
negocios.Sell(info.LotsMin(), _Symbol);
& L, ] r" X9 U" M} J% _, |4 F8 m$ r0 J: q5 U
}
% p7 y- _! ` w0 ~ Y% x/ P1 N//--- Check if we have a new candlestick...- K3 {) _3 b' X' r6 s4 H3 P- Q
bool tem_vela_nova(const MqlRates &rate)
7 U6 m) t7 r5 R/ ?3 l) a1 `{; s& D, ]4 E% i0 H/ S, z, w# Q. G
{
( e6 |% x; A! W' fret = true;
7 T1 f* B4 C2 T1 Nclose_positions = false;
% W& P: J8 a; k! H: j2 u, c/ V}
I2 |( F/ b5 q: p5 k1 d7 ^else
2 w& o9 ^5 x7 i7 [+ n& L3 T{
! K9 U% \% O* ]if(mdt.hour == 16)" a. E: F4 u( e- S4 x# W- r
close_positions = (mdt.min >= 30);
+ J+ A8 w: u. X+ c0 y6 s3 _0 g}3 E8 D% N e& a8 n9 h
}6 L* l5 ], z) U* O
return ret;
6 L, S- `, Z F E}1 J: w& ?. I. Z+ d$ B, Q3 b
//---' q( W& Z8 y v& Z
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
9 G0 b2 ?8 _2 n7 z{
7 [, U! G4 C% o2 }# rif(PositionsTotal()) // Is there a position?
- Q/ M# ~' k# W# n6 ^( f{
" `0 B# H% s( }( L: udouble offset[1] = { 0 };
- {8 }1 z* L& x3 Eif(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
! ]# X6 Z. U5 j, M2 p; [&& PositionSelect(_Symbol)) // Select the existing position!
" O1 a: g0 I3 b7 A{* w; b9 e/ O" A& H
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);) u. O* C" O8 S, q3 Z0 a
double SL = PositionGetDouble(POSITION_SL);
9 y7 S' a. u7 {# E% Z$ e3 Fdouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));: V, p) x9 ]& h5 a$ U
if(tipo == POSITION_TYPE_BUY)
3 m; U; R+ k: ]+ M* ]7 E$ c{7 K" M) m& f9 a- c4 k; Q8 s
if (cotacoes[1].high > cotacoes[0].high)! o9 ^- j0 a D9 _; l
{* e# S* a1 A6 _' X% L
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
5 k, k' _) n0 z; N3 d+ l+ }info.NormalizePrice(sl);
& s K& w! h$ w; P' g$ tif (sl > SL), }. a0 z" o- f/ n/ F; j. I1 G3 j
{
' Y$ G/ ^. C( A* G+ E: ?negocios.PositionModify(_Symbol, sl, TP);& V& O! @9 C1 X3 s9 P
}
0 m' W0 L4 ~7 H% m* _8 ^}: a1 {) Q T+ H1 Y0 E5 u' y# f
}
. U6 [+ [. c3 a6 l8 [# R. Ielse // tipo == POSITION_TYPE_SELL0 c+ |& R: M: V/ v4 ]
{0 f; e' E! o, Q4 t: ^ t' T& I
if (cotacoes[1].low < cotacoes[0].low)0 e" |" F' o9 t, K6 F9 `# O# K
{
8 W" W9 ~. X7 E) v$ }! `" u8 F7 preturn true;
L- w0 y4 ~. \: V( [}
7 ]+ G1 t- t2 {6 b' z, {// there was no position3 _8 ~( e9 A9 V* G. F& W7 v7 `& {9 a
return false;2 I+ l" Y/ d- p4 w3 s# Q* w
}
2 }2 u5 m: F& m我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。6 A& n3 i u9 C3 E- Y
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |