启动交易模型,并构建 EA2 e0 Y. i& L% h; |" z' [+ s
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。1 f( ]; p. h1 T
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。 O9 A) A9 o7 W& ^
以下是制定这些规则的代码。
! T) H9 \* j0 [ C$ D7 u) W d//--- Indicator ATR(1) with EMA(8) used for the stop level...
a5 o( k9 n6 j8 ]8 Nint ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);, _- b' ~0 }; `$ u1 I
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
3 e1 v: o+ E' x \9 |2 l3 Q//--- Define a variable that indicates that we have a deal...7 b. P3 M0 B# x: ]9 [1 R3 c
bool tem_tick = false;
6 b: Y; R+ p- B- {7 V//--- An auxiliary variable for opening a position
: B- [2 P. Y( p0 p! D#include<Trade/Trade.mqh>$ m- E: z* L7 m; ?
#include<Trade/SymbolInfo.mqh> o: t% C6 O7 O9 o/ ?7 T% V
CTrade negocios; d4 p; @- i$ o* [8 p7 Y
CSymbolInfo info;
# Q+ c. v q6 Z//--- Define in OnInit() the use of the timer every second6 ~* u- B8 r/ }5 C. V0 A% b
//--- and start CTrade8 A) Y: S) x& n! B+ z8 \ r9 I
int OnInit()$ v0 P w5 O# J- b8 Z- r) r8 Q$ g& R
{) u, u, ?3 w8 l% {6 Q
//--- Set the fill type to keep a pending order
( S8 U" |: v$ ~* K5 W//--- until it is fully filled
: E4 s5 k/ k6 @7 o! q. k% xnegocios.SetTypeFilling(ORDER_FILLING_RETURN);
. e1 h6 y$ h7 x1 b% Q0 N8 b//--- Leave the fixed deviation at it is not used on B3 exchange1 u' O$ ~8 P2 H7 s. { U5 j1 I
negocios.SetDeviationInPoints(5);
# A% m' I- Y2 @2 q//--- Define the symbol in CSymbolInfo...8 d1 }( n9 O! b ~" e% W: G
info.Name(_Symbol);
! E S7 I- }2 ~' A9 n# Y9 m6 j//--- Set the timer...
4 A2 w9 t8 U2 q' ^EventSetTimer(1);
$ D# @( @ a+ C: F) x+ q//--- Set the base of the random number to have equal tests...
7 g; Y. x K) [5 pMathSrand(0xDEAD);
5 ]" j! |+ P6 S# E' G7 a" Greturn(INIT_SUCCEEDED);
G6 w# F3 p3 q" w& n+ j" ?$ o}
3 O! A& t; N' n" o) n2 D//--- Since we set a timer, we need to destroy it in OnDeInit().3 S/ ]5 A; q& z
void OnDeinit(const int reason)+ i% r+ e7 m: E, k8 w
{
% \% u4 n2 m4 d1 e8 MEventKillTimer();3 @' [ O" Y8 J% ~6 E7 h* I, A
}
8 J$ t# x$ _: }' Y% }# @9 W2 f//--- The OnTick function only informs us that we have a new deal
* a1 \# w: f1 c' d) w8 _void OnTick()
' |! s0 ~+ S8 P" h{
; o5 c% ]# D1 `; o; Vtem_tick = true;
' t: g! }7 C4 J0 Q+ Z, r+ j* {0 {}# a/ B- L' q9 R: b+ U
//+------------------------------------------------------------------+! P C% v- n8 F
//| Expert Advisor main function |, \" U; S6 B @
//+------------------------------------------------------------------+3 y) x4 Z. i D3 G3 O
void OnTimer()5 N* Q7 R# U$ j* U+ {/ e
{# M' E/ J4 W' v
MqlRates cotacao[];
3 e/ _6 _- W/ d; I6 K7 areturn ; y( Z! z; k2 E/ K. @4 ]8 ?9 l
if (negocios_autorizados == false) // are we outside the trading window?0 r0 d# Y# |3 N8 \
return ;
: |( D+ X, b: `: L* D//--- We are in the trading window, try to open a new position!0 R2 U- Z$ b( e( P
int sorteio = MathRand();
2 N% h1 _0 a$ s" b( t$ P7 |: {6 ^//--- Entry rule 1.1
' H. M% t, z" x$ a0 t6 Lif(sorteio == 0 || sorteio == 32767)/ D8 G3 J% O) `
return ;7 Q9 P; Z& `* e# D( \% N
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy( I: K/ k) T0 D E6 \
{4 S& Y% q5 k) A
negocios.Buy(info.LotsMin(), _Symbol);3 f% E& U+ E( }3 M2 Q8 L0 \- X5 v1 W
}3 n9 g! U" J9 e+ o' G' c1 ^
else // Draw rule 1.3 -- odd number - Sell
- `. R- k+ w2 V) X2 C, ^% H' v{
# t# V! |7 \7 {# T& enegocios.Sell(info.LotsMin(), _Symbol);
3 b$ z; {# O7 l8 }}
3 u* u; F) `4 `, z- E2 C1 Y}
, O9 q1 ^7 S) a% h# z- m//--- Check if we have a new candlestick...& j% H6 ^7 P' i" x- k
bool tem_vela_nova(const MqlRates &rate)+ N+ B$ W" w, g! F, I0 U# a
{# R& e! Y. N( g* v7 J2 B" t" N
{
9 `% c& K; F8 A' F2 V9 ^ret = true;
3 K3 y# D4 {$ b. E& b$ t7 N" Zclose_positions = false;' z7 U: @1 v1 x$ E2 @
}; S. i. W6 b9 k; w9 n* q7 `$ u
else6 `- y3 b; y3 y
{
, K1 Q0 j7 B4 r3 bif(mdt.hour == 16)4 u3 Z/ W6 W7 ?; v! L' m1 r4 {) {
close_positions = (mdt.min >= 30);6 T0 Q3 Y: F$ `6 Z
}
- N# E; |: u: Q9 [}
% }, `3 c% v7 t# z& Treturn ret;
- h" X9 B0 F% ]3 v6 |5 M}; X' ]' i- m8 f$ Q& y" \. b& Q
//---% M; G$ V0 _* `; `4 |9 K
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
7 i5 c5 O9 I. V% E1 K/ N6 p, W+ z{
+ J D! K2 E# a$ S2 K8 A5 { m$ V. yif(PositionsTotal()) // Is there a position?: m/ Y6 m# C6 t) r) \2 S g) x
{+ ^+ @% [& _5 x6 d
double offset[1] = { 0 };
4 m8 w2 P; t; a9 O, u: T* Rif(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?3 S; W4 ] X" I# ~0 C
&& PositionSelect(_Symbol)) // Select the existing position!1 z. M+ P; q3 @8 e. n) a
{4 a4 `: t! w& V8 n4 C: d
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);# X# g# e' `: N f; N
double SL = PositionGetDouble(POSITION_SL);5 Z& ?* L8 S: Z" R/ B/ a3 i1 m% |+ f
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));+ \2 w; } p# ~- t. O7 N
if(tipo == POSITION_TYPE_BUY)
& E7 ]0 o1 p Z# ?8 T1 Q; S{, u- c; \" W8 Y! |3 _! f) L
if (cotacoes[1].high > cotacoes[0].high)
3 i& z- _7 v2 G# Y" R9 G8 N5 M{
0 M" z1 _$ c7 tdouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
" x8 `% ]: G7 ^5 U, M' cinfo.NormalizePrice(sl);
$ b0 h( O+ S+ j; G e& D: Y5 Yif (sl > SL)5 i2 p4 H( f! t# s1 f$ _
{
3 q X- d. ^: X5 X. D x3 I. ynegocios.PositionModify(_Symbol, sl, TP);
( j" s& U/ r* F g# V( \}6 z# A/ F2 T4 D/ a% G
}
2 R" m4 {: b1 h9 E* |, i}7 r, P: M5 {6 y2 D/ N% g0 n
else // tipo == POSITION_TYPE_SELL! r- r. x& n6 ] }
{ H1 ~# } j) M( }
if (cotacoes[1].low < cotacoes[0].low)
0 V' w& Y3 u) ]8 A: D2 f{' K& {/ ~4 f( u' U; _: @- P2 d
return true;6 e1 v3 B0 |1 G, S) n
}
/ s) H9 U: T, K+ x( u// there was no position: d' S6 V8 |2 B' k# O+ ^ t \
return false;
% @3 g8 K/ p1 K2 ]! d s" I}- {9 W) x7 I2 f) s
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。* _2 @1 @4 e" b W. D
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |