启动交易模型,并构建 EA
+ W- s% y* v# B' C% B- Z在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
5 w+ o4 q$ H( u7 w: O为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
: d3 y) M( k. n3 {5 o, o以下是制定这些规则的代码。
: z2 ]. P& r7 i5 L- A% g4 F//--- Indicator ATR(1) with EMA(8) used for the stop level...! ], H& X% A0 R7 U: b8 Q, o
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
# L) n2 B% }( I V2 I4 {int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
2 g6 \& p/ Q$ L; [//--- Define a variable that indicates that we have a deal...
: b6 _ Z1 c' q7 \6 ?bool tem_tick = false;- k# `! W7 Z# c: j
//--- An auxiliary variable for opening a position
8 J2 P7 |( E2 R D' A( X2 ^#include<Trade/Trade.mqh>8 J: V1 J7 @) Y7 p6 A: ]
#include<Trade/SymbolInfo.mqh>
# C/ e7 R: V0 @2 I/ \/ ECTrade negocios;
1 P' f+ l! C' V4 N0 i9 x( G! kCSymbolInfo info;3 [' \6 ]" U% L
//--- Define in OnInit() the use of the timer every second
( Y4 J( I- G; X5 r//--- and start CTrade1 B) x5 I! @$ b% ?+ f3 S
int OnInit()& U3 S8 F& P: ~# V5 H
{
9 I% b: Z, H1 w `6 q7 I4 \//--- Set the fill type to keep a pending order. ?* p1 C- e0 k3 ^/ R- w
//--- until it is fully filled
' q0 g6 ]7 ~( s1 |8 X- Tnegocios.SetTypeFilling(ORDER_FILLING_RETURN);7 ?) |# J( E' o8 Y _. w
//--- Leave the fixed deviation at it is not used on B3 exchange
6 ~2 ]9 { z2 |) o v1 k% s- cnegocios.SetDeviationInPoints(5);9 V, V3 @3 s) `" ]8 U2 @3 Y
//--- Define the symbol in CSymbolInfo...
/ T, O/ I c/ F4 Pinfo.Name(_Symbol);" }7 x: E" k- [
//--- Set the timer...
% s2 N5 v/ o0 X8 U# L, CEventSetTimer(1);
, c/ F+ t5 E! `0 O$ s( T//--- Set the base of the random number to have equal tests...
( V, g" @* [7 z: }: m7 SMathSrand(0xDEAD);
9 {2 \5 g, u7 e, Rreturn(INIT_SUCCEEDED);$ s8 V. n3 H- [. A/ }( b& f) t: e
}
8 }7 G. h& f4 x! S+ m$ n9 m6 Y' P! @//--- Since we set a timer, we need to destroy it in OnDeInit().
% _; C# C- x3 M4 Qvoid OnDeinit(const int reason)! `: F* v$ D& Q0 H8 S3 S. O; T! u
{2 S- ~0 U+ f$ a* u- ?
EventKillTimer();8 ]+ e6 N- D2 y4 a( k9 v3 j4 C
}
8 `! K+ U4 ^8 X G% a//--- The OnTick function only informs us that we have a new deal
7 n% |2 M* A! ~4 p+ Bvoid OnTick()
& P/ D2 |: E8 O5 ~. r{
" @: c5 ?# y8 p3 j* h2 wtem_tick = true;7 S% ]! I# `, A' }) L
}( ?: Q6 d" Q) b4 M
//+------------------------------------------------------------------+
% O6 ^% ~, ?, M. @" c0 m//| Expert Advisor main function |! y$ s; u3 g5 {+ o( i
//+------------------------------------------------------------------+
. @8 S0 M4 _6 `' E6 d6 @( J3 Zvoid OnTimer()
$ N/ j9 t9 E# J: W{
$ y' l* V1 q4 }( v+ A% z9 bMqlRates cotacao[];, ~$ _' U9 d- p# A
return ;) w& {: M4 x; V+ ~
if (negocios_autorizados == false) // are we outside the trading window?
* B9 J% K6 z% T+ d* o2 lreturn ;
, f: ?5 p2 }2 F4 d; ^% \7 z//--- We are in the trading window, try to open a new position!
6 {9 l, d- p7 w" P" U* y9 hint sorteio = MathRand();
- c* \' N& Z! v* `7 L- l//--- Entry rule 1.1
! o" ^6 A6 k! L8 `" g4 m- w Aif(sorteio == 0 || sorteio == 32767)
% s. S: P* R4 r3 g+ N8 Creturn ;$ a0 r+ E n: ~, h7 F, M5 F
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
+ h3 s- a( u" S) s{. q i$ j# A7 S/ H' G
negocios.Buy(info.LotsMin(), _Symbol);# o$ ~3 n- |! L) s2 t
}
0 ^8 |) c4 u9 `. d+ {& O/ ]else // Draw rule 1.3 -- odd number - Sell) M3 o, ?5 J5 C: Q. i& z
{
/ Q) V% n. ^& gnegocios.Sell(info.LotsMin(), _Symbol);
: H& Y. r9 z6 [% t, O" H; B! Q}
- w; p" ~9 S5 c! X; E; ~' F) O}( Y6 j1 p' J' ?- F6 c
//--- Check if we have a new candlestick..., n+ V$ V% S3 F8 D7 z( D
bool tem_vela_nova(const MqlRates &rate)% I* O- ~( _5 m" g a3 E
{
7 o; ]2 c2 y- u/ V# e6 L+ M{) K% f& X$ d$ d# {0 e- r, O# F
ret = true;
/ v( z3 i8 W8 ^* N* v- O4 Sclose_positions = false;
( Q# u; Y& Y7 s, _) S}( z1 ] c% G/ ?: z/ p+ ]$ C3 U
else& m' ?6 g9 n7 D" I9 R; {
{
3 o' d) O0 O7 K: I5 Iif(mdt.hour == 16)
9 o3 y. ~: W. b$ C' [$ _& o, W! Vclose_positions = (mdt.min >= 30);
8 B% k8 |+ e3 P5 o: b- x* c}
' `5 b: U+ l* B \ Q. D}- `8 a- a% e5 K# ^+ @
return ret;
+ E+ }0 v3 n. j2 F}" d$ e* K. z3 V) G
//---
6 R ^7 @8 }: ?. k7 u; ^. wbool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
( D2 z e2 s/ b6 q( ?4 V{
8 g& p. }, e- S8 ]7 c3 Zif(PositionsTotal()) // Is there a position?
) J/ \6 o/ a: e# ~5 t1 o: s{
, X+ ~! Q3 d9 k1 ~- udouble offset[1] = { 0 };; k3 ^7 p+ y+ [7 K- T/ e* k1 p
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
: I3 m# I" A$ j&& PositionSelect(_Symbol)) // Select the existing position!& X+ g* o+ {3 X3 ?
{+ Q% y- T+ d" w, `! b- r7 p: C' Z
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
: g7 p% g) w0 o& Mdouble SL = PositionGetDouble(POSITION_SL);. ?' c8 g* o5 |( s8 e
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));: R, i1 e0 f5 U8 E9 \
if(tipo == POSITION_TYPE_BUY)
* h0 _3 `# W1 a- W+ N3 b{
9 r3 _$ P; l4 @7 p9 H4 } |! aif (cotacoes[1].high > cotacoes[0].high)
0 N( ^# H# o1 d4 v4 I( u" ?{/ p D) X+ n9 u9 M- i. e! E/ q3 Z
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];5 L+ S9 ?4 H9 e# s
info.NormalizePrice(sl);
; e9 X$ l5 r. J5 n6 H% h! B8 j8 Eif (sl > SL)5 i0 k- ^7 k5 Y
{# o& _5 N! z( N3 X: y/ n, ?
negocios.PositionModify(_Symbol, sl, TP);
, H+ o* V( G/ `) P% d+ i}9 R+ x3 t6 h' U8 G% u6 \9 ^
}
: o/ @% k* C& p9 d! _ A) o/ c} A3 C5 _& @3 L8 t" c( q; D
else // tipo == POSITION_TYPE_SELL7 S: e1 U+ @) [% [' p
{
" p/ P6 U# t1 j* cif (cotacoes[1].low < cotacoes[0].low)
' R3 d3 o/ f& e# M{
1 p0 u) z* ^# [- R% ~3 w; oreturn true;
" p* \7 r4 M" ~. i, E Q5 h! y4 {}
; S' u0 U" p! m// there was no position$ g7 N6 k5 w: j% n
return false;
. i$ l( `. f" f}
% f) A- ~# ?, R# E( r/ U我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
& L" c! S1 T! H: R4 M! ]9 B- h到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |