启动交易模型,并构建 EA
7 P$ `0 y/ H& X' g, Q在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。 u8 ^+ U8 `9 I. d
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
0 X3 {& d& K: ], {6 Q以下是制定这些规则的代码。/ a" e* i8 I$ B3 Y; t5 _
//--- Indicator ATR(1) with EMA(8) used for the stop level...
6 N7 j9 k# t5 F. ?int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);" I$ Z# w! \! |! q4 f
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
6 R5 E3 L8 K: N# M: U: _6 s1 O' d3 x n//--- Define a variable that indicates that we have a deal...# s5 R5 _1 u- `/ {7 _$ I
bool tem_tick = false;
% p4 d1 s' `1 o, C9 n* u1 O//--- An auxiliary variable for opening a position
, O* V7 G% N+ w* U+ W8 p4 O#include<Trade/Trade.mqh>
1 o& v) c1 ?* b$ m7 n8 I9 [* _#include<Trade/SymbolInfo.mqh> _4 D3 `: h0 B6 z2 }
CTrade negocios;
' t0 K: t5 h3 X: a% ^4 eCSymbolInfo info;
2 h. U) o6 f2 m7 V; p# T: P0 K//--- Define in OnInit() the use of the timer every second. B4 _5 q$ S- \ C% l% ^
//--- and start CTrade/ N+ w3 F: Z! E3 Z8 H
int OnInit()( }9 B) V! e& r0 c
{7 J. s3 H7 F6 b. T
//--- Set the fill type to keep a pending order
# v9 J9 @' ^8 j//--- until it is fully filled; M2 N+ s& L/ P# V/ A" l: o' O
negocios.SetTypeFilling(ORDER_FILLING_RETURN);
: I$ T& }* o6 ~$ g3 h2 S//--- Leave the fixed deviation at it is not used on B3 exchange
. C( m0 {# `' u5 tnegocios.SetDeviationInPoints(5);# F/ g k$ @- P
//--- Define the symbol in CSymbolInfo...
' R k! Z; U% @) T. ^2 y. \info.Name(_Symbol);& [3 [# J% N: W h1 j* m7 M
//--- Set the timer...! H6 d7 {* C L7 j) k" E6 T$ Z
EventSetTimer(1);: n0 c6 W- Y2 Y/ i
//--- Set the base of the random number to have equal tests...1 B1 V- j+ {3 |& ~9 w
MathSrand(0xDEAD);
. J0 \5 e `% N8 Z/ X& D$ A$ S4 p- ureturn(INIT_SUCCEEDED);
3 p2 q6 z9 S( ^$ O& {3 o% k}) F: w3 g! O* j" M9 g8 o/ o' K1 m
//--- Since we set a timer, we need to destroy it in OnDeInit().
0 t& p" g, j0 bvoid OnDeinit(const int reason): E1 F# z, ] P) b9 z6 n9 b/ W
{- }, W) o, F+ c" B" N7 K
EventKillTimer();
2 j; e4 i8 Z+ | D}
2 j9 @/ C" q5 Y" t4 D! U3 ^//--- The OnTick function only informs us that we have a new deal
* {' g' H B' Xvoid OnTick()
' w( x9 k- v: G: ~8 [2 L2 }& Q; I3 X{) o: `$ C) ?, j/ h o/ n J
tem_tick = true;% k. q1 k: ?0 M, Y; l. {/ w; y
}
( G" i2 A7 S+ E! P8 [//+------------------------------------------------------------------+% M! a8 s7 d- }$ @
//| Expert Advisor main function |
* B4 E. J# P* }: x+ S- a5 H//+------------------------------------------------------------------+
. K, l1 H% j5 L9 Hvoid OnTimer()) G* U% I8 c- ^0 n: b% C r
{- }3 n: {/ D) Z: A6 E
MqlRates cotacao[];5 M( ^; M8 o. {# G' ^
return ;
* |- {! w+ O: q) Nif (negocios_autorizados == false) // are we outside the trading window?5 `3 B7 X& @# D+ C+ I
return ;
{& x0 m& ?( C9 ~7 y& C! K4 ?2 y//--- We are in the trading window, try to open a new position! v" H3 h; h) d7 J! E
int sorteio = MathRand();% H. J* m: S) l; S
//--- Entry rule 1.1
* g, i2 j+ i; }) wif(sorteio == 0 || sorteio == 32767)/ q; F$ _1 f$ } X6 g4 N2 f, {& U
return ;
% M3 N9 T$ k# H0 ]9 i$ { gif(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy" j1 F2 K2 k! I* |8 c
{
7 z6 Z P: S8 g, w' Nnegocios.Buy(info.LotsMin(), _Symbol);4 T" K) W* P4 `3 l8 z0 D
}% B, G7 k' e% `
else // Draw rule 1.3 -- odd number - Sell4 F- E4 i9 E' F; ]( p
{, @/ ]3 Q! o: ~
negocios.Sell(info.LotsMin(), _Symbol);
" r/ @- d5 W* E3 N, S/ u' P}
/ C# B. d3 l7 _) f- L}, u; J" Z7 k* C* u5 ?" J1 P
//--- Check if we have a new candlestick...
5 C1 a7 V6 _6 A1 X, B' Cbool tem_vela_nova(const MqlRates &rate)1 g$ F+ Y3 ?8 ~) }$ ~
{+ L) a) T+ e7 b" ]- t( A/ V
{
: o/ `7 O. F; F8 e$ q+ p$ x1 n: |" Pret = true;* n3 n0 s% U# R+ N8 j4 Q
close_positions = false;3 Y( A$ a/ J7 ^8 Y
}5 w) c/ h* X7 F; H. e$ h! y
else
7 x$ w5 S: o1 t0 |{
. Y D& M% h$ K4 K+ N1 ]if(mdt.hour == 16) _/ h" v. H5 b% m- V7 W$ N
close_positions = (mdt.min >= 30);
& g" Y$ d$ d% A) X6 |9 n0 x}1 K3 u/ t" {) L+ }0 c' p1 }7 d9 g% s
}
) ]* H% t! ^/ r9 a/ K0 ?5 C. s: K: breturn ret;# q& B0 u# g" z5 h1 n! t' c+ l( h
} G+ u$ t& M' y- t) {# H8 c
//---
4 V0 E$ e [+ H+ v) Q. _' H; @# Hbool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
) \0 q* v# P; v, _, v{% O( l, L$ z5 _
if(PositionsTotal()) // Is there a position?
/ e) K0 J2 j% R! z" V{5 y$ c5 k! R8 s5 Y# e
double offset[1] = { 0 };/ h' L" |3 t( s0 L! }, v+ h
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
3 a# X1 l2 y1 \9 q0 N' T+ A&& PositionSelect(_Symbol)) // Select the existing position!
) S/ i1 \) B% s! h{+ z+ S5 O) a3 E4 T
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
: J0 x+ m) }8 Z- P" ?double SL = PositionGetDouble(POSITION_SL);
$ a/ s5 C, \8 r; A$ D$ Idouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));* ]3 ], z6 T: E! X0 t, ^# B4 A
if(tipo == POSITION_TYPE_BUY)
: l$ ?8 J* d3 {6 q% D{
0 q8 d8 u- c/ \9 \if (cotacoes[1].high > cotacoes[0].high)
- v: z( l$ ?9 h8 J; c{3 x; B; E0 ?8 t
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
) J& L) c; f5 d9 Hinfo.NormalizePrice(sl);- c: w# F# v8 A" `( Z
if (sl > SL)) J* o6 G8 q: @5 M' W! t
{9 w3 |" e' K; l2 u$ d: [* v! j. ~
negocios.PositionModify(_Symbol, sl, TP);
, a3 |! M m2 J, ?7 c7 y3 |9 \}
" c: b3 Z9 c7 l4 T}
3 N$ |2 a0 D- E6 w% t8 }}/ c2 V+ ?5 _& i) n, S/ ?# m) X* ~
else // tipo == POSITION_TYPE_SELL
. ^! e( p: J, j5 ]/ e6 G% T{8 d! o: }3 k8 d2 s: g E
if (cotacoes[1].low < cotacoes[0].low)
, g R7 l3 c" p{
# N7 D; D& i# J! h6 x" qreturn true;
3 O: `- H* G+ [' V7 ], S}
) [- [+ F( h8 `5 E T// there was no position
2 ~, I' s4 J9 z( e+ ureturn false;& f6 `! Z9 E# y4 F5 T5 ~* n" l& J
}
) y5 |, L; z, @0 W我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。. ~6 Z& k; G; C6 b/ Z& f
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |