启动交易模型,并构建 EA/ O" e/ k1 u0 h+ q6 [. j
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。1 [, W% }/ i9 _ n3 E1 f
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
; x% V; w: c! S+ V" C以下是制定这些规则的代码。
r d2 Q' f0 N' R//--- Indicator ATR(1) with EMA(8) used for the stop level...1 ?, v, g. S) S8 b2 B$ _9 E
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);8 N( }& Y! n1 O' _7 E
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
) j! J3 ]& O X, w' ?3 \ [3 i+ {//--- Define a variable that indicates that we have a deal..., X& _2 N$ V( ]$ b" p, E
bool tem_tick = false;6 a1 G) t- o2 A) q) a3 }. G7 f6 s
//--- An auxiliary variable for opening a position
/ v' G7 I1 T5 Y, e& y; s! ^#include<Trade/Trade.mqh>
( \1 X8 q+ T: ^7 q8 F7 P2 l9 g#include<Trade/SymbolInfo.mqh>) G/ x5 j X" N2 j. X: \. |! G
CTrade negocios;0 T0 y7 l7 H3 ^+ ?, |- g
CSymbolInfo info;$ M7 m! \7 C9 W# f+ w9 A9 `& |
//--- Define in OnInit() the use of the timer every second
( d! @* J) e* ~' s+ j6 ~# K/ ]* u( A' Z//--- and start CTrade1 I2 W! \& Z0 o7 \" X/ Z1 Y
int OnInit()1 X. w& J& T( c' w
{
# Y2 p# f: M* x/ g//--- Set the fill type to keep a pending order9 `" G W: j" V* f" x# z
//--- until it is fully filled$ T& b. j& ~9 `& |- r# O
negocios.SetTypeFilling(ORDER_FILLING_RETURN);, S2 H# S7 I- c3 q. f8 p1 @
//--- Leave the fixed deviation at it is not used on B3 exchange. G: ?( Z7 c7 F f' I
negocios.SetDeviationInPoints(5);( o( s7 G! C4 | O$ f& N
//--- Define the symbol in CSymbolInfo...$ h: Q5 A0 D# r& f+ n( o3 ?
info.Name(_Symbol);
# c8 f4 x J' m//--- Set the timer...* ^2 O& b5 k/ B2 t9 @
EventSetTimer(1);
, W5 C8 n/ W# j, u//--- Set the base of the random number to have equal tests...3 t9 h8 p7 U- u2 s
MathSrand(0xDEAD);9 x! A1 d4 Q9 Z9 z& `/ [
return(INIT_SUCCEEDED);
: u2 w2 ^! n$ S* T( |2 N}1 W5 b7 ]6 W G5 q3 v
//--- Since we set a timer, we need to destroy it in OnDeInit().
; O5 U2 p5 N3 O/ _void OnDeinit(const int reason)3 F1 k e' I2 V4 K7 Y0 l; g
{
$ B/ K* x! \& qEventKillTimer();
+ e6 @1 o! u- [* v! g! g}5 A2 \, m2 n( _* k6 N. i1 @
//--- The OnTick function only informs us that we have a new deal9 S3 I7 g2 Q" M0 A( o9 S' K r8 e
void OnTick()- y$ Z! h7 w. n; ~$ d* }/ y
{6 I7 `& @' E1 I9 }
tem_tick = true;
1 f3 F3 s5 J1 X0 z' K- p}
& F! X, ]: r- V: _- H" t! o1 N//+------------------------------------------------------------------+- G- Y+ J- _8 b' T7 H
//| Expert Advisor main function |
# B4 Q9 c1 ], m* O//+------------------------------------------------------------------+
0 P" x7 f3 f1 B( {) Fvoid OnTimer()0 U. {- k# D) Z ~* |1 [; ]
{
$ z+ z! t3 [1 F3 [MqlRates cotacao[];
& x' {3 n- N+ v6 X' Areturn ;
$ |( v( ~+ C6 G# T6 l+ ?if (negocios_autorizados == false) // are we outside the trading window?' v; Q3 E( K8 q, ]$ d
return ;) b2 u2 f+ Q4 _* J6 m$ N1 h& Z) `
//--- We are in the trading window, try to open a new position!* `" n" Q: M5 o0 W, E
int sorteio = MathRand();6 p" z( u7 E. |8 Y
//--- Entry rule 1.1
: M. `: x3 c6 Z3 Sif(sorteio == 0 || sorteio == 32767)& H& |$ i, @+ ^! R
return ;
9 R% @9 ~2 f9 T8 Uif(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
$ s& b5 f# W( y8 ?{2 ~5 e* @% U1 |
negocios.Buy(info.LotsMin(), _Symbol);
' q/ h6 n4 j, e- w% e. v& [}' {6 E" M Q h. D
else // Draw rule 1.3 -- odd number - Sell
# s7 J, \! W2 H7 \! t: T3 }8 l/ F{9 }; l9 g' {0 ]
negocios.Sell(info.LotsMin(), _Symbol);
. Z7 `* F! T3 K& f, R}; `5 c( V& d4 w- g% L% F7 F1 Z
}* g, C$ N" a; k4 D" E
//--- Check if we have a new candlestick...- B5 ?$ k+ J: r
bool tem_vela_nova(const MqlRates &rate)- ]4 g. z! W9 M9 q
{* q) V; q! _- s6 D! i* W+ v$ t
{
+ I# Y* O; ]3 x- Vret = true;
* t7 \. G' ^) O5 g) A1 |, oclose_positions = false;
+ I) R* y. X- @" ?1 J1 t}
+ i6 j8 l+ J) H& v- P( a# ~5 B' A8 S: relse0 m2 s: O- p6 S: y# r
{8 Y* L6 y. `3 B
if(mdt.hour == 16). Z) e" t; S' E
close_positions = (mdt.min >= 30);
. Z$ A, k5 Y3 p, g5 s}
; \/ O4 g, r, u% [; h}2 m: u: K- V4 D$ p/ Z& g( t
return ret;; s$ p" T, @# Q$ ]# g" j- {6 B
}$ F7 X6 W1 h9 U. t0 }6 \/ q
//---8 N! U4 n, _ R; u6 w+ ^7 D5 R
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
, K, Y6 y. L# e' d* G" Q7 X) V( w" B{6 a) j( e5 q" I" K/ i6 C# E
if(PositionsTotal()) // Is there a position?% r* P* N3 G+ y. ^) M0 r/ z
{
# W) @0 O6 _9 K/ O( I. z9 m( jdouble offset[1] = { 0 };0 V) f5 j% f$ v* C/ u N: Y
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
& p* O' n8 Z" `# u0 ?1 G+ `0 F&& PositionSelect(_Symbol)) // Select the existing position!
0 ]" a1 |9 t5 W) r8 A+ N{$ h$ @( d2 u K3 X& ~' `+ i# W
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
) F! P6 i7 h- K& q" T) Jdouble SL = PositionGetDouble(POSITION_SL);
0 I7 z( Q& z' r# V1 i2 ^double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));
) Z: J3 x @; d3 Zif(tipo == POSITION_TYPE_BUY)
2 L8 U: V; c$ s( D2 p{# Y& A Y8 G3 I# Z- O) z
if (cotacoes[1].high > cotacoes[0].high)
: @7 A. W9 t; d8 a6 t- @$ x$ v! s{
% O! \. V4 [: h! ^" I' wdouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];6 P1 N) e+ ^. S" ^1 O* @9 Y. ^
info.NormalizePrice(sl);
: V: ~% g+ W' kif (sl > SL)
+ x. i5 L" j. Q( S9 r1 U{2 |( ^! i+ R5 q9 P+ c: P/ |* w8 g
negocios.PositionModify(_Symbol, sl, TP);
2 R" G5 i7 |, i9 \}* y7 E* l+ }$ ` \
}
3 ~9 V4 D8 g9 b6 x; F: j}8 K [ L1 a4 j! H5 w
else // tipo == POSITION_TYPE_SELL# n! p2 Y- W" x2 d8 N( W( K
{' r( V/ J6 X4 _! f! f+ X
if (cotacoes[1].low < cotacoes[0].low)
3 ~+ q7 M' R0 i8 p/ O( I% t; L{
1 g4 Y( A- S5 |# }return true;
$ E. ~. X: k. v, o F6 c}
2 W: F! Q" z1 @7 g4 o7 }// there was no position- o+ L3 }* G- V ^; h2 ]" g" J- G
return false;
6 f# c6 M0 {6 U}! B+ e9 D3 z6 A1 B
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
& c$ N1 F0 s; \3 Z9 p# X到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |