启动交易模型,并构建 EA
( e; i: D) R& ^8 ?在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。) \: `' c; w* f4 b8 g
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
3 h" g( m, n' x8 l以下是制定这些规则的代码。
5 K: Y6 z4 n! U% R! l3 ]! N//--- Indicator ATR(1) with EMA(8) used for the stop level...
% J* x `' y2 y. E# vint ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
7 a6 h! V5 B0 H. Vint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);0 j. c- K4 h, D
//--- Define a variable that indicates that we have a deal...
# V+ ]/ n x# `5 t" y% e6 Jbool tem_tick = false;7 t6 p9 y* [& K! Z
//--- An auxiliary variable for opening a position+ M1 n h* K3 W- o/ Q- M
#include<Trade/Trade.mqh>! x! z$ z7 g& ], r) A
#include<Trade/SymbolInfo.mqh>7 m2 n, k( y9 p. |. x
CTrade negocios;
8 K3 \# x0 B/ ~- d+ o; \& cCSymbolInfo info;
2 L+ l# \) h/ W" W* }//--- Define in OnInit() the use of the timer every second
8 x7 u% W) U A5 s `" h//--- and start CTrade3 M& V* o9 Q* j: V, y, r0 Z
int OnInit()" ?+ f' e/ x1 s5 r* k0 l; T/ q
{
5 \4 b# R" g( w5 @ j+ U; a# }//--- Set the fill type to keep a pending order
- i: e m1 N) L, D1 z& X8 O//--- until it is fully filled# b1 W/ O7 s" ^/ B$ e
negocios.SetTypeFilling(ORDER_FILLING_RETURN);
1 B6 L) D( A5 Z5 W" j//--- Leave the fixed deviation at it is not used on B3 exchange
% q8 ^. B1 N+ P/ k% o/ Hnegocios.SetDeviationInPoints(5);3 T- j5 V+ h; Q" U* {
//--- Define the symbol in CSymbolInfo.../ E8 A9 D/ C$ G# s1 p
info.Name(_Symbol);
4 F X" B5 n7 M% {5 k, w+ Y- Y//--- Set the timer...0 C. `/ e7 x+ d6 r: `4 n3 e
EventSetTimer(1);
8 m8 Z- c, d, j. K* r//--- Set the base of the random number to have equal tests...
4 V. p( Y P5 m* KMathSrand(0xDEAD);4 y3 {; d6 I* y$ L/ T; |3 K) F
return(INIT_SUCCEEDED);2 o6 L# z9 B4 \; I& M B
}7 R/ u! m1 ~) C" n/ D7 A( z8 p
//--- Since we set a timer, we need to destroy it in OnDeInit().; ~" q1 ~' c& Z& c/ E- }
void OnDeinit(const int reason)
3 a, b' N2 n7 G+ \! O" e1 S{% U+ ~* i2 ]8 j
EventKillTimer();; g' `: r6 _8 W
}* D1 V9 V) ~$ e6 [! L8 t' d9 T. x/ A
//--- The OnTick function only informs us that we have a new deal. s; _5 C1 W, v5 X/ G" q1 j6 e
void OnTick()4 f8 a+ J9 k9 k; }% H* E" O5 k! [
{
2 G( c& y9 n6 y% Y ?6 ktem_tick = true;+ z; W. e0 h. {5 ^
}
' |9 D1 y+ n, {- Y" {, h//+------------------------------------------------------------------+
+ y8 c+ a/ r9 a- z3 z% D//| Expert Advisor main function |
" y8 F$ V* H* y4 d2 r, U2 G//+------------------------------------------------------------------+ S( j, e; }5 V" G
void OnTimer()
' f& j8 G" x4 t{( S8 Q2 h, z' o, f. ^3 W( s$ ^
MqlRates cotacao[];2 |6 \% L# `# ]8 p7 K
return ;
( m+ v: B1 o4 t9 T4 V6 G# Kif (negocios_autorizados == false) // are we outside the trading window?
, U( K/ M/ c0 Q$ X8 Treturn ;
$ P' r% q3 n9 k. Q//--- We are in the trading window, try to open a new position!
2 G, \' t4 j! ^7 M, U: _int sorteio = MathRand();$ q- [, K& b$ w" T( _/ X
//--- Entry rule 1.1
) Q `9 w: J6 _- l! u) a; Dif(sorteio == 0 || sorteio == 32767)
# K3 S" o: T ereturn ;+ P& u- W5 t0 ~# r+ Y
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
7 U4 {8 E, i' O! Q" h* M7 \{ D' v7 `" J' `- k0 ^9 { G2 m
negocios.Buy(info.LotsMin(), _Symbol);% V. v( m S7 V9 @6 p m" w5 H0 ?
}
9 ]3 q! Z' T/ Y1 Lelse // Draw rule 1.3 -- odd number - Sell" }" Z( x( Z' \ Q- K* c3 v3 f A
{
% ]: @! {7 ~0 Z+ Dnegocios.Sell(info.LotsMin(), _Symbol);- x/ A4 t- s& m; i
}2 q2 I, |8 O. A5 y" u. j$ K
}
9 Z _" [) ~/ V5 Q4 Q, ^$ p//--- Check if we have a new candlestick...
Y$ G2 @% P# x5 a6 w8 M/ @* Sbool tem_vela_nova(const MqlRates &rate)
: [2 d# A4 s1 O; [* _8 z+ W{
5 w: h1 X, o3 y" S$ u9 ?: R" \, h/ u! b- H{
3 ^8 i. x5 T. ~0 G' f- l# \ret = true;
1 Q+ h. e8 B) ^8 W- c; mclose_positions = false;! `5 j- N1 W4 [$ q' x- p
}7 P3 O+ S, }& A/ Q/ M
else; G b' o9 s/ j1 z3 v* o
{
; _. T, Q! \2 c7 n! I4 |" \if(mdt.hour == 16)
3 m/ x. V, q3 P0 K; O; @; _2 [7 Nclose_positions = (mdt.min >= 30);5 T3 _! M0 b5 l( |! x2 l! q; F
}5 c# S' q0 F; B+ V/ ^
}7 e( W2 m# [+ n6 B* |
return ret;
8 U( w2 k0 F+ m9 _" k; M2 j( n" o0 W}
6 F" N4 f! w/ q/ ~//---/ ^2 |1 r. x3 b8 U T
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
T, D" ~& Z- r" B{- |+ O9 e/ v! T" P7 E* y+ R
if(PositionsTotal()) // Is there a position?# y8 o0 z t2 g/ k; [8 l: S
{
; }& `4 L$ c! M: Z9 H/ Y" d# ?double offset[1] = { 0 };
$ F |. w0 r; Y; Qif(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
9 K7 C. {' |3 |$ b1 I&& PositionSelect(_Symbol)) // Select the existing position!' k3 E9 R! }9 _* @; O' i) h
{
- ]3 j) R1 X/ S7 u' N# |) SENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
$ O2 I( T- _2 r% v m* |' w" cdouble SL = PositionGetDouble(POSITION_SL);
9 {: H1 V7 r! h! idouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));/ y. i' s5 }5 n
if(tipo == POSITION_TYPE_BUY)
1 I+ J3 L% R. ~. h{
" [- R( h) Q7 F9 V: \! Yif (cotacoes[1].high > cotacoes[0].high)
! } A! b2 ^8 Z" D8 V{% S/ J# V, F5 J) w! n5 z( k" ?% E7 L
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];0 N. |* s+ a6 V# w- {
info.NormalizePrice(sl);
- ^2 d! w% w0 pif (sl > SL)
, b6 G) T3 e! k: U4 b{& A* V& ]/ `: ^+ G" C6 `& [
negocios.PositionModify(_Symbol, sl, TP);
% {) N1 N) h# |7 m3 a* ]' Q8 U4 x}7 _0 [, |: y( _# W4 ~+ q
}
, H2 r, Z- r v0 }; o}
, C4 D5 R! }+ \* v0 relse // tipo == POSITION_TYPE_SELL
0 h. Q2 X5 G3 m M( {- R7 X' \{
% e6 K. X" z& o, l. wif (cotacoes[1].low < cotacoes[0].low)8 f9 e5 f, `' z- C( a
{
/ ~, R5 ]. w1 F& y! lreturn true;
. ] a8 z/ A% B0 c# s5 G. C% k}
. W: M! O- `5 d) `. w! @// there was no position
8 H9 ?/ \3 l3 Preturn false;
! G$ q6 _' C/ J) G}3 o, v: P/ n$ h
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。# z$ O7 S& C3 g. k$ N2 N5 k
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |