启动交易模型,并构建 EA: q4 D7 o$ _! L$ H0 O
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。6 Y) I7 m$ ~8 M( h _) o
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
. h& U5 @& Q" C$ w以下是制定这些规则的代码。
; G4 p6 V; }& `8 ~4 z//--- Indicator ATR(1) with EMA(8) used for the stop level...
@# J( x5 o) P' v! ?" `. K$ Vint ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
4 R2 x- _' D7 a4 t. dint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);; `% E1 ?7 [9 x
//--- Define a variable that indicates that we have a deal...
2 w4 x! r0 p4 ~8 o) ] `bool tem_tick = false;
( Q# E, _+ E( O; l/ t* t0 g' `//--- An auxiliary variable for opening a position$ l2 [1 a9 X, v
#include<Trade/Trade.mqh>
8 v' C' Q$ C, Y" @$ \1 V#include<Trade/SymbolInfo.mqh>) k$ `/ v; [6 ~/ C
CTrade negocios;- I { P/ C2 x+ E% T
CSymbolInfo info;
! _' y( b) u" p, h1 H+ x) `' B7 _//--- Define in OnInit() the use of the timer every second" w; j( P+ S: W3 i( d1 n
//--- and start CTrade
. f8 I8 B) O0 q7 s! m. mint OnInit()( B& l, K4 z1 A/ @
{
. P4 ~5 H2 Q0 c. l9 ]( G) r//--- Set the fill type to keep a pending order4 y3 ] g9 o: F; j9 B( e
//--- until it is fully filled* V |% e- r0 i0 S. z; Q
negocios.SetTypeFilling(ORDER_FILLING_RETURN);6 u: P8 O+ _4 k5 U+ z7 T
//--- Leave the fixed deviation at it is not used on B3 exchange
( f* i1 t8 e. N! y& J6 g5 bnegocios.SetDeviationInPoints(5);. O8 u! T6 z! b& p( L: w6 Q% N/ b
//--- Define the symbol in CSymbolInfo..., D; L. _) Z& u. l+ O) u, F- A2 R- H
info.Name(_Symbol);: z0 s# ~3 J3 ?5 W$ M) d$ [: g
//--- Set the timer...% g U7 F3 L+ h
EventSetTimer(1);9 {+ F7 j9 o* H7 w
//--- Set the base of the random number to have equal tests...4 j7 G8 N$ Y. Q6 r. h, @
MathSrand(0xDEAD);
5 h# A l' ?5 n. Hreturn(INIT_SUCCEEDED);" L" L. ~* ] o9 b
}" t8 u U* V* b2 P, Q$ q; u2 {- F
//--- Since we set a timer, we need to destroy it in OnDeInit().$ \( w9 y. @4 \9 ?% X8 \3 z8 [) |
void OnDeinit(const int reason)" H0 T0 w8 b9 B+ F- m
{
9 ^' ^1 j* v7 eEventKillTimer();9 w( | P4 n5 p! }4 o, ]6 j3 b! j
} E: T6 R! S) i+ z8 w# e
//--- The OnTick function only informs us that we have a new deal s w3 z2 z( }- K
void OnTick()
; V- U9 ~& K% `2 p" J{
" d3 S& C/ ^6 }8 J% R8 J! Rtem_tick = true;
3 x+ v; r: \9 V* ~. _5 L. s8 s}0 F4 y; p6 C5 [) U6 Z# m. }
//+------------------------------------------------------------------+3 N4 p/ s! ?9 S. X
//| Expert Advisor main function |' L+ Z6 P6 D- E% {3 ~% a7 J
//+------------------------------------------------------------------+* z9 Y( `2 x, X
void OnTimer() a/ r: u! b6 W. j- D2 S; g; M- _
{
. n3 @( O( y4 z' E5 a9 V3 b1 lMqlRates cotacao[];
) [$ v6 _# U+ l7 s+ Mreturn ;
6 l8 m% z' F, `0 G6 e# W6 Bif (negocios_autorizados == false) // are we outside the trading window?
1 K& k# Q5 F( k4 |; ireturn ;
4 [2 W( K0 W) V' n& M0 n) V) @//--- We are in the trading window, try to open a new position!
) J/ k5 z9 c9 \2 wint sorteio = MathRand();' K2 e; K& t5 i' b
//--- Entry rule 1.1/ h, c4 H v1 B; `9 Q/ m- B
if(sorteio == 0 || sorteio == 32767)
( w3 |% u% k/ Lreturn ;. O+ ]9 r6 X# n. u/ C! g" T! _2 q
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
* P' d; i6 ^/ ?. m ~{
$ g5 t4 {& [, C& i6 Y+ y7 Z) V) T1 @" Snegocios.Buy(info.LotsMin(), _Symbol);
0 l# f" N' r7 W}. T' R0 `2 `$ @& l3 v& R
else // Draw rule 1.3 -- odd number - Sell
c5 M6 j8 _6 s& L{& a$ E" m8 e* ?1 E! \, {1 K
negocios.Sell(info.LotsMin(), _Symbol);
& w% |" ^3 G! _/ C}& l5 u" q6 V4 m; k( w6 m
}2 z0 X" Z) r$ X9 e- _
//--- Check if we have a new candlestick...0 X( o4 v4 M- j/ q; B2 d
bool tem_vela_nova(const MqlRates &rate)
2 F8 F Q# I0 o; t9 \$ t{
" ~0 j7 }) Y" ~" t- r% `{
1 ] L" a9 Q' U9 }ret = true;, Y1 k4 b I2 [1 K+ x
close_positions = false;
( K: y9 N7 e3 @2 }2 z}) J+ _ u8 g0 n4 Q; g, X
else- k" i) U0 B# N- U8 B, c
{
( E" m' Q1 z, fif(mdt.hour == 16)2 l4 P, G+ R5 T% s3 d: I
close_positions = (mdt.min >= 30);' I/ Q6 d7 r) [& Q8 ]3 I: P
}
% S% Z! h" P& G% x# r}
8 P7 j# l. @0 @% S& Y: P( P/ k" o/ Yreturn ret;
5 t5 T8 X# n% |}5 @! P7 U( |; o# S2 y! [9 p
//---* G: @1 u& L1 D! o. M" G: ~
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
+ h5 u# a5 X) P; t; v, i7 T{) y$ p. s6 t4 W n1 D2 U) a
if(PositionsTotal()) // Is there a position?, h" f& y/ t6 z; u* ?3 u' W# l9 X
{- S" {. s0 t% Q# x& X
double offset[1] = { 0 };( j5 D5 U$ o9 _8 \7 W. v
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
! K* o; | d$ f) V( m7 r8 n7 h&& PositionSelect(_Symbol)) // Select the existing position!
. V# q- z4 j' j( ~# \2 {; V, }, N{/ l! _, w( A# S( k
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
Y; b( h, ~( e9 {. B8 tdouble SL = PositionGetDouble(POSITION_SL);
: c. D+ B0 l5 p& Mdouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));1 I7 C) U8 H) s( x, p' D
if(tipo == POSITION_TYPE_BUY)+ P) K/ s$ E/ ^/ w& q# F9 Z$ M0 r% ~. t
{% ?- v# z- q2 ~. k
if (cotacoes[1].high > cotacoes[0].high)) L# `* j' e; E7 }* e# r0 U
{
: W$ [: X; V, G, Ydouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
9 [. O- j/ p( b) h+ w+ f+ binfo.NormalizePrice(sl);: Z, b9 R6 A, ~" |- V6 U! I+ \
if (sl > SL). }, \$ ~6 y) v& E! ?( J
{
% C3 o1 V0 z: n4 ^" d2 inegocios.PositionModify(_Symbol, sl, TP);
0 \$ F4 b! \, p+ Z6 x' C}
" u/ L2 W: C7 @+ R}
% c9 O* p7 {7 w4 X/ X, w}
: d9 H, B* I- m* p melse // tipo == POSITION_TYPE_SELL
0 u5 u, L$ \* Q( a1 Z% V. E# m{ v; U4 I9 r% h! t h* h
if (cotacoes[1].low < cotacoes[0].low)7 j6 w6 I& x U' F2 h
{4 c7 J( T9 R Y3 q3 T& u' p
return true;, C% l0 X9 D4 ]) ?& r
}: r) A1 t# J' N; q0 _
// there was no position8 P% q. }% ]) [7 W8 \" M D
return false;$ @2 x% p" J% b7 W6 t
}
6 a- G3 d1 @: Y7 V: h9 s' V4 z我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。5 z& v0 a4 s6 R
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |