启动交易模型,并构建 EA
f4 W/ w: a% ]9 W在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
2 n6 _+ j5 K+ q0 ^) M为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。- O+ }2 _# l }1 D9 l- P' R7 |' }, k0 j
以下是制定这些规则的代码。
( _$ i- @- k5 A//--- Indicator ATR(1) with EMA(8) used for the stop level..." x% w: \* s) x. h) H& Y0 _; [3 K
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);& _3 w1 G- k' A( t. G
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
0 c; n! T' L# f; N% V( ^//--- Define a variable that indicates that we have a deal...
& F1 K4 N5 g" w2 c" l) Bbool tem_tick = false;
3 y8 v! O" \) ]6 k6 M//--- An auxiliary variable for opening a position$ H' r# P$ X3 ^! U& ~* ^# d" i
#include<Trade/Trade.mqh>
# J9 h2 Y& w, V g( o#include<Trade/SymbolInfo.mqh>0 k- b$ C& \8 l* T* ], Q6 i
CTrade negocios;
6 h3 P& ?' E/ u% ~1 o1 K& |7 dCSymbolInfo info;/ G9 N! Z4 q6 I3 q6 p# N. X) e
//--- Define in OnInit() the use of the timer every second
/ v3 g M! X8 l P' l//--- and start CTrade. F) v4 j5 u B8 S+ I# W
int OnInit()
; W3 _& K+ F+ z/ H& k" _+ t$ R{
3 G8 r6 Q5 j- V8 P//--- Set the fill type to keep a pending order
3 Z2 U' @- B& k, R" J4 a: ^//--- until it is fully filled( T; y6 R6 \; r5 ~2 u
negocios.SetTypeFilling(ORDER_FILLING_RETURN);; F; u) b% k6 S, H) s- O8 J; d
//--- Leave the fixed deviation at it is not used on B3 exchange
' b1 H, j( r" @$ knegocios.SetDeviationInPoints(5);
" u5 t- X* c, @! S; i//--- Define the symbol in CSymbolInfo...
! o. W% O3 u! @' `" I3 Dinfo.Name(_Symbol);
" W3 k7 C; P8 ^3 M//--- Set the timer...
5 r4 H8 p- e/ @# `! D" WEventSetTimer(1);; }7 ^: ~' I( v6 s8 E. |
//--- Set the base of the random number to have equal tests...
" |) F2 U0 o/ F5 C8 ]* s5 G) x9 HMathSrand(0xDEAD);1 a4 e2 c; W! w& C
return(INIT_SUCCEEDED);# V0 O4 ?) j& {8 }, y& z
}% B$ F. C! n. X3 h3 Y
//--- Since we set a timer, we need to destroy it in OnDeInit()." F2 q& m9 i, e( J; ~
void OnDeinit(const int reason)
: W7 `4 d4 @" `' s4 I+ [{- k/ E5 a/ X; v2 {( q
EventKillTimer();8 l; x" d: Z$ I1 m }1 G1 N$ |
}) s/ d3 S* [: K; A) m( _
//--- The OnTick function only informs us that we have a new deal& W& x- s1 w7 j3 i( B( r
void OnTick()
+ o" p+ y0 i. V* q& z! _% }5 ~{
A/ Y2 h& o! z( z6 Ytem_tick = true;
- ^3 a' A; p1 N}
/ c2 m) w# o/ J' N//+------------------------------------------------------------------++ ?- z4 q7 F3 B- k( A. H, D% @
//| Expert Advisor main function |
1 |5 k; i" U( M8 ~* q& R//+------------------------------------------------------------------+. i' X7 G# C. M( W$ S
void OnTimer() t0 s! m% s+ Z0 | `5 h! C+ S4 W, I
{
5 A2 \' |) r1 E6 jMqlRates cotacao[];
& n. a2 T" j3 S9 Creturn ;
/ h l3 _ j8 Cif (negocios_autorizados == false) // are we outside the trading window?
% O; z' `& W6 Freturn ;
" \* h4 e6 U4 q7 X* M//--- We are in the trading window, try to open a new position!. N a# r5 e! F; ~) T
int sorteio = MathRand();
$ }' ^9 I. g8 Z9 S9 b. n//--- Entry rule 1.1
. S5 k3 w. R$ xif(sorteio == 0 || sorteio == 32767)0 z5 j8 ^2 Z4 C1 Q
return ;5 ]7 |' X' h* j) X% r% y# U( Q) T
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy+ k; f; Z7 t) X' d/ x$ S+ V
{
, q. R: N3 c: z7 e0 c' \, Z, f3 Tnegocios.Buy(info.LotsMin(), _Symbol);4 `/ y+ h+ P6 O$ B: ^
}
7 d# u7 D( @& A- g. h7 ?; l& n% velse // Draw rule 1.3 -- odd number - Sell
; `3 v4 w5 T6 A6 v9 T: g8 o3 n! S{
! M5 K( h, a/ ?negocios.Sell(info.LotsMin(), _Symbol);
* q/ a- J* C; [2 ]4 u- h- X) n}1 \" |9 `! @& v4 K
}
8 M- M5 P7 g) I//--- Check if we have a new candlestick...
# N3 ?5 S" e+ F7 Gbool tem_vela_nova(const MqlRates &rate)
( h* y/ U9 a q3 H$ J& h) v{8 v: g9 n! e+ T) n
{
, V% _4 r. f3 \5 Wret = true;% x$ p+ Z2 k) D/ i6 l4 k
close_positions = false;
% i( \. j- T/ X! T% E% k}
) W/ @% l; A2 t& E# T, j$ K% felse
1 d, _$ l' b3 Z( i3 E{
, @3 q% I, l" ?: |& Xif(mdt.hour == 16)' o( r3 P3 Z9 X3 v) }, H
close_positions = (mdt.min >= 30);
; S1 `$ N9 H1 o3 Y3 t4 h+ B}5 r# F/ Y, O! u8 J2 N! S- _6 U
}4 @+ E; ^. ]. G1 M. T4 J
return ret;
/ Y6 f% O$ j, b! p}( {2 ~) W6 U% _) W) b$ G
//---
' g& j4 I/ E: U$ v( \' F' qbool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
3 s$ m; A( j8 q, P" `6 K' i{
, c5 [' k( r* l1 g- F# d8 @. qif(PositionsTotal()) // Is there a position?
, c5 s `, K2 F' A+ l4 K{
+ t4 a1 [7 ~& A' D6 fdouble offset[1] = { 0 };) z- k: z5 Y* Y6 F5 L# x/ s
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
3 s! S3 {+ h* f2 \, `5 K7 ~&& PositionSelect(_Symbol)) // Select the existing position!/ _& X% b& r+ c5 _0 L+ ^3 v* o
{
# C9 y& L: r: f' _% ]4 J' L: N" N. BENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
. }! J5 y i6 O. Q$ O7 rdouble SL = PositionGetDouble(POSITION_SL);& x# S a" ~8 ~' W9 q" D/ }
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));! s: l6 h4 `$ P* E, S8 W0 ^$ W+ A
if(tipo == POSITION_TYPE_BUY)1 p- N2 Q& o( V' g3 \
{6 y/ ^( l/ t' ]
if (cotacoes[1].high > cotacoes[0].high)- X6 X+ c/ A, z( i2 l, f' j; k
{; Q5 o0 ?. c- v2 t
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
4 F' U2 B+ [, Linfo.NormalizePrice(sl);
* u3 {; g. A# n3 Iif (sl > SL)4 _5 x8 f l2 h
{# V0 ]9 \' J7 X; N% j" B" u
negocios.PositionModify(_Symbol, sl, TP);( y7 k) `/ @; z0 p; d
}
8 R: h5 N1 o# a+ o' t/ _8 t}/ G# q& H' L) S) H- @8 K* b& r1 h
}8 f4 E* `5 Q1 f" h( p
else // tipo == POSITION_TYPE_SELL, a- ~5 |# c# A
{
! J% |" x% k& m8 U: s( h" x& n$ oif (cotacoes[1].low < cotacoes[0].low)) }/ ~8 c6 [" b" N2 X
{9 T1 `. n+ g# Q/ V* U5 Z9 `9 ~ R/ z
return true;" u9 Y6 h4 Z; ^9 L% {
}" S3 D# K- S7 b" h D& k" Y
// there was no position" s1 `1 X% E( i" _
return false;
2 L* s2 R6 ] U( B0 I( b}; _+ ]7 q/ I5 c* [) O# u" s
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。- Q# }9 j) x: S
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |