启动交易模型,并构建 EA/ ~4 {* B( I5 I% P. M4 y' Y7 \; N
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。5 n8 N$ C6 M* D* W8 Z
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。& I$ _# q: w; w5 w1 g1 x
以下是制定这些规则的代码。& w0 r/ J% i1 `% p9 h# Y
//--- Indicator ATR(1) with EMA(8) used for the stop level...
$ ?+ s1 y: _. y gint ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
, @8 e& X Y1 P( d9 gint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);/ U6 e" O5 }: k, D
//--- Define a variable that indicates that we have a deal...
! M9 @/ C' e" v0 ~ E" A. Bbool tem_tick = false;
}0 o1 U7 U* S" [//--- An auxiliary variable for opening a position) e: e4 R; Y) O5 z1 h7 M
#include<Trade/Trade.mqh>; k2 Q% q4 h0 {# E
#include<Trade/SymbolInfo.mqh> N% ^3 C2 E4 o! ^% q
CTrade negocios;
% f3 M8 |& O& L8 o/ [3 u$ k UCSymbolInfo info;
0 }2 z3 v2 t% j f9 i//--- Define in OnInit() the use of the timer every second
1 P5 K6 x2 s( I q* s% a: R! P//--- and start CTrade) l: j, l4 N4 ]& t
int OnInit()
4 d7 j! J4 @0 s, k{
2 r6 X% ^1 i* G4 u//--- Set the fill type to keep a pending order! y+ P' c: ?. W1 D
//--- until it is fully filled+ H7 K( Q5 \; s6 y2 P
negocios.SetTypeFilling(ORDER_FILLING_RETURN);9 T0 |" k4 i+ ]. Z; f4 \9 z
//--- Leave the fixed deviation at it is not used on B3 exchange
2 x3 r. s* N- j+ @. d9 xnegocios.SetDeviationInPoints(5);
% E$ @ \. ^3 T. m% n% f' {//--- Define the symbol in CSymbolInfo...1 r" U( j5 Z |
info.Name(_Symbol);8 K$ U3 l* _; b# g4 J! ?
//--- Set the timer...0 O5 p+ x4 G0 |
EventSetTimer(1);
1 f/ V8 h- \ g//--- Set the base of the random number to have equal tests...$ Q2 m9 i& ]4 T# B2 ?4 o* m9 P
MathSrand(0xDEAD);: r. D; C. S% O4 K$ m; S4 R) [
return(INIT_SUCCEEDED);
n W: S3 j# J% r& [" i}4 Z- P" j6 z8 h/ f
//--- Since we set a timer, we need to destroy it in OnDeInit().
: q' R3 G" U/ w9 q$ z0 J! M; M# n# fvoid OnDeinit(const int reason)- n) v' t9 ]$ M1 r4 L
{
; T& x8 f" y# F! E8 m! Z: i0 WEventKillTimer();$ N) \. j; O1 g$ b
}8 m4 Q4 R9 J e" F. C" L8 H
//--- The OnTick function only informs us that we have a new deal
0 Y" c! l( H( {& svoid OnTick()/ Y9 K9 v: G( f/ X$ g/ v
{5 Y4 V9 ^0 U3 S
tem_tick = true;3 r0 k0 K" ~& J. w C
}
) l7 D7 Y8 H/ T: \7 Y" q//+------------------------------------------------------------------+
% d; o4 }2 \- o//| Expert Advisor main function |
; q. s- X9 o ~//+------------------------------------------------------------------+
9 J# n$ q' j6 D6 N( h( M0 \2 e$ \void OnTimer()
2 M+ ` ~: }9 U) U, N7 p4 ]' f{
I( F; r5 ~% Q; }% s+ V: dMqlRates cotacao[];2 n W! m- J& h) A
return ;8 Q) h! b+ W8 q( C0 o6 o# f2 O
if (negocios_autorizados == false) // are we outside the trading window?' L6 y4 a t8 i6 {8 j/ q
return ;
. B2 @: d6 q% ~//--- We are in the trading window, try to open a new position!
1 M8 h6 y2 Z1 Z" y# ], d- V1 lint sorteio = MathRand();5 i$ ^1 m1 T$ d2 _" j( c0 J* I
//--- Entry rule 1.1
3 ]4 L4 L# h5 v. d0 V: Pif(sorteio == 0 || sorteio == 32767)
9 F1 {2 F' d' U1 z1 ^return ;; w" H, x* p0 C
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy- C' F# B+ h& `6 A9 ~! l9 v9 @, Q
{& p0 ~4 k# z0 B* ?* c: A; x
negocios.Buy(info.LotsMin(), _Symbol);
3 Z" b: v# @) l! R4 V7 v% n}
5 n3 g9 t% T0 ~% r. W( F% s/ h& Xelse // Draw rule 1.3 -- odd number - Sell
4 Q- d' o/ A. q7 H{/ c1 i+ ^! @6 H. h% k' }
negocios.Sell(info.LotsMin(), _Symbol);! y2 J$ H+ H1 [; W
}
; u: g/ o; l! l2 ], s2 w& @: W. t}* F. _" {* _1 A2 ]
//--- Check if we have a new candlestick...1 k7 m. f& }5 |7 y
bool tem_vela_nova(const MqlRates &rate)
5 b y) n$ \" V$ D3 J- f{
+ o! y* P5 l' W" C C{& m! q6 B! x! d' x Z
ret = true;, ]0 E4 `7 O, n V8 Z
close_positions = false;6 R; ~; X. \- j1 B1 h; Z
}. E: @% F& ?; z. C5 }: t& O
else! D1 A ^8 B( f8 }3 |( @
{
" a1 ~2 i2 Q* P% k- s4 L% H( iif(mdt.hour == 16)3 \; Y1 P; w( y7 [
close_positions = (mdt.min >= 30);
4 J; `1 S; P5 v" h! B' \}
' [% \ X3 L7 M- d; X}
! H. q5 Y) i; i# S5 I$ {/ P+ E0 Lreturn ret;9 Y8 n3 Y) D, {' `- f0 V% N
}; R, B# f7 R1 I2 K$ X9 L2 y) w
//---2 D) R* e" [. c4 N) C5 s \
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[]) D: M/ H, @ X4 I& o
{
; ?2 t' X' X; ~# p- }: Dif(PositionsTotal()) // Is there a position?
6 v8 C5 h, f/ M' _3 s. d, W' p{
. n9 q$ }0 Q1 L( \* ]double offset[1] = { 0 };
4 G$ q3 o, R1 e! {8 Kif(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?- N3 G& b; d/ k9 y8 C1 c
&& PositionSelect(_Symbol)) // Select the existing position!- q- M9 W: U: u! I2 l7 r/ ?7 ^
{
8 {# M- X ~6 [$ S- ]1 G, M% R% AENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
5 y: d0 e9 Y0 \$ X* O1 Ndouble SL = PositionGetDouble(POSITION_SL);
0 @" [, ]6 U, O* r2 Jdouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));3 D* D9 X8 }& D r+ P$ C8 m( Q% y: k' e7 x
if(tipo == POSITION_TYPE_BUY)3 y+ k9 i. e, y5 h5 f0 o
{ h4 f. \* L, a4 a t
if (cotacoes[1].high > cotacoes[0].high)
2 @; v) `/ s+ u* U! h3 S6 `1 i9 X{# O2 u+ m2 O5 X) M9 q) V/ s! \
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];" @' s" [0 ?$ o) ?1 D
info.NormalizePrice(sl);
7 u7 H: Y5 I5 W/ a0 T( Iif (sl > SL)
5 B% Y5 s# T$ m3 ?% F4 E y- _{9 w1 n/ Y5 C7 O" N/ Q
negocios.PositionModify(_Symbol, sl, TP);
! o- p V: m# H& W}
5 W# c: `/ L' P9 _9 \}0 |+ t# R- U4 I% y
}8 \. [6 G) b: ?- {8 ~+ W
else // tipo == POSITION_TYPE_SELL
! E* |8 c5 C( K1 W0 W, o0 R{6 v+ h" g+ h* E/ S& S8 }; @6 L
if (cotacoes[1].low < cotacoes[0].low)
9 r+ Q4 h& G" [9 k7 S( I# m{
# o" H/ ^6 g3 _% Kreturn true;4 ?$ c9 w4 {* a7 y
}
# P/ c" [ i N0 E, d3 H+ K9 `// there was no position
/ a0 M D# a8 O& p* j3 b; M1 {5 h* lreturn false;/ w; o, Z. w7 T. b D9 P/ H {, [
}- a2 {6 D5 u; I" c( m
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
+ g2 p! D8 b# Y到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |