启动交易模型,并构建 EA
% c- Z6 [* t/ T( \在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。9 z0 t& b4 c$ V' |
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
' n G- Q5 M, F4 D. D以下是制定这些规则的代码。7 T4 H$ L: c5 e4 L
//--- Indicator ATR(1) with EMA(8) used for the stop level...
7 P( u7 R0 V1 \5 eint ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
" ?. r% h! t% j! |; r+ A4 gint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);3 r2 J7 Y- Z4 q" L" `) Y
//--- Define a variable that indicates that we have a deal...
8 b9 U2 C+ [" j) \- Obool tem_tick = false;% ?( a( @- ]. W* S% I
//--- An auxiliary variable for opening a position* F6 j- O5 N% H- ?3 e4 I
#include<Trade/Trade.mqh>
* [2 `6 O/ x$ R: g/ w7 U1 Q& d#include<Trade/SymbolInfo.mqh>
4 n6 p; D" x/ mCTrade negocios;
8 O+ }+ O* j' A, \" l, G+ j' VCSymbolInfo info;
% i# y g# _ N5 `" A: k//--- Define in OnInit() the use of the timer every second
) j3 v6 H- }: h! d4 g//--- and start CTrade
4 O: b5 A- l0 t3 Z, k7 c' v6 K! F4 jint OnInit(): U/ p, z4 S9 P& f
{
- C! W; c7 x& S% q7 @//--- Set the fill type to keep a pending order
4 e$ a. `$ z# o0 q4 [" R9 Q5 v//--- until it is fully filled: f; m0 B$ Z/ i$ g; ^+ W( |
negocios.SetTypeFilling(ORDER_FILLING_RETURN);
) X, d- I1 ^( ^) g. s//--- Leave the fixed deviation at it is not used on B3 exchange
& {3 _# r% X1 q5 Cnegocios.SetDeviationInPoints(5);
/ x4 ]) o8 l7 v8 P% l/ ]6 H//--- Define the symbol in CSymbolInfo...# g7 m6 y# v' q
info.Name(_Symbol);7 q9 C3 \) D, h
//--- Set the timer...
9 K3 e2 k# P7 A4 w! ]0 uEventSetTimer(1);
2 K* I: C+ u+ P$ @7 ?//--- Set the base of the random number to have equal tests.... l% W4 h5 t% u w5 N* ^5 x* a
MathSrand(0xDEAD);
3 G: i9 S( ~) e$ H7 k7 {return(INIT_SUCCEEDED);
, M+ d2 Y( v9 \/ l# x6 o+ h}
: n0 @, o2 b8 f( R7 V/ r# a& r//--- Since we set a timer, we need to destroy it in OnDeInit().
5 l1 i0 S' G7 _* kvoid OnDeinit(const int reason)& ?* R9 q4 D: Y# x% g% i# M8 `. R
{
9 F& ^: P: T6 e `! y7 v- kEventKillTimer();0 r# o0 k1 w3 G
}
p( ]% U+ |& D* ^) C( o. s) T \//--- The OnTick function only informs us that we have a new deal- o5 \! u1 d; B- e7 i
void OnTick()
7 s8 X) ]' i4 ?0 K) a{, ^# B+ @- k* b0 X& j+ B! B
tem_tick = true;6 }" W2 n5 g% s8 D5 `
}- c. C# B1 t4 ^ m* l
//+------------------------------------------------------------------+
$ \+ p, ~8 V% i1 B3 i3 |* e8 v//| Expert Advisor main function |
7 v; G9 @ ]( d6 s$ @+ O3 S4 }. x//+------------------------------------------------------------------+: u, K, ?; ?+ s, W. n& K2 O. ^5 U/ U
void OnTimer()+ `7 K: ?( e8 m, W4 B
{
* k Y& [9 K7 h" K6 ^ a6 DMqlRates cotacao[];
M8 J, V: e1 g% w- g/ rreturn ;, V. l6 ?2 ~$ J7 ?2 H1 }! f6 L! ~
if (negocios_autorizados == false) // are we outside the trading window?7 h! e, s* B1 `% ^& L& h& o2 k
return ;3 k. q# V! T! ]* e1 X5 D
//--- We are in the trading window, try to open a new position!5 h3 y7 k/ V8 v/ I* e
int sorteio = MathRand();! k5 L( r6 S; |- `6 D e9 F& k4 I7 v
//--- Entry rule 1.1
$ f$ H4 j5 h/ Y! a6 Pif(sorteio == 0 || sorteio == 32767)
; M k1 m3 N$ F. |return ;; j- v$ A/ U" t8 Q$ Y3 q
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
# _5 P! V# H/ J/ v9 ^3 d8 p) J5 B3 U{2 D: q1 l1 x1 [
negocios.Buy(info.LotsMin(), _Symbol);2 j, G) I7 D, a" U6 p* U4 W
}: h+ Y) @) H& s7 C% \# W) l8 A
else // Draw rule 1.3 -- odd number - Sell* A) T7 i2 u( s: _- c
{
3 |& S' c, j. Inegocios.Sell(info.LotsMin(), _Symbol);- W1 x; b% M& F2 E$ O/ ?
}
W# c3 [2 K. [7 q" J; P" U7 V' E}( g0 }: `, \+ h; D' r
//--- Check if we have a new candlestick...* E( k+ o! {0 O7 C
bool tem_vela_nova(const MqlRates &rate)
; i5 o( D& j! ~- E: T{+ O& L ~: z/ H; \. \, b% `
{/ a4 v z9 J$ S, K% M
ret = true;
; C1 e# S* I' J1 d* e" Yclose_positions = false;
) u$ M( e9 A Z! K5 E6 d; ^. k}
0 M* n. g' S- S& E& Welse& Z- z6 O# ` V$ r# z: f
{( X: E- A8 I1 I1 D
if(mdt.hour == 16)
! u) d1 c0 ]" i# s/ O% dclose_positions = (mdt.min >= 30);" h+ O2 G5 a% M; i
}" a2 |3 ]% e- C2 r5 p) t
}; J( ]" S9 B$ l* G1 P: \' q# J
return ret;
. k: Q' C8 }" h) z: c, Q* r$ R' C}' Y& x* l2 |$ ^, P5 M
//---
# t9 i5 ^# i* B2 C3 A5 f! o, `bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])! f" h0 z8 F" s1 z, ?3 u' t: l
{9 m1 t* d5 J/ d- K( s
if(PositionsTotal()) // Is there a position?
3 D0 y: O" p; X# H{- `$ `" n1 q$ `4 A N' b+ N" A: [' u
double offset[1] = { 0 };
" e, [, X. m( ~if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
+ i1 y! d3 Q, ~8 e& R1 Q. i&& PositionSelect(_Symbol)) // Select the existing position! M- ~; |, j' N$ j4 A
{' K7 o5 S' U i, d+ G2 A: d, f
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
/ y3 B2 p- V; U9 L7 e" w6 Qdouble SL = PositionGetDouble(POSITION_SL);+ Y9 Z/ l5 p0 [( e
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));
% ]! O" S2 X' S1 D8 zif(tipo == POSITION_TYPE_BUY)
* Q: N; P/ B% R{1 ?& @1 o9 u8 p4 z7 w% B7 Z- o, v
if (cotacoes[1].high > cotacoes[0].high)
" F1 d; ~4 ^7 N J{
+ R1 [. }! I& m+ ~. Mdouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
9 h" ^- w5 d; D O! k+ ~) binfo.NormalizePrice(sl);! c5 m; ^1 S0 m, K& d
if (sl > SL)
& t3 k& H+ V+ c( n0 S{
) H( ~" A$ \- Nnegocios.PositionModify(_Symbol, sl, TP);
& ]. s H4 N/ e- `7 L! f}+ r, `4 S) T0 v j4 r' o/ _
}$ M- o) ^: q, y8 E+ H3 {3 P$ d
}
; W5 f& V% ~2 g. g) }else // tipo == POSITION_TYPE_SELL5 R" W; R* \9 d# _1 ?4 z4 H8 l
{
1 W. O' G/ C* m4 d! N' `$ nif (cotacoes[1].low < cotacoes[0].low)
4 ?6 G0 O8 C& X{1 ]( N3 {) \7 }) S
return true;
P' {% e" c% v( o+ z/ g8 }}& q$ J% k- Z0 p4 C( A: l- H2 x- j
// there was no position
$ c! b: K* ?$ c# b; b2 a4 Vreturn false;
* S: x" }% U; c& _}
" V6 w# M2 u$ a我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
D1 p( ~* Q d到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |