启动交易模型,并构建 EA% B( w G5 q1 c6 f' U) L; T
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
& u j: _; ~# u4 f+ H为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
) U. F8 |, `' U# J# j以下是制定这些规则的代码。
7 M" ?* w* J/ A8 N4 b//--- Indicator ATR(1) with EMA(8) used for the stop level...6 ^' @, R9 S# W. ~% @
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);( h) s* ]0 i3 B/ \# W' \
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);
: `9 V% ~' c" r: {: u' M- [' G8 J//--- Define a variable that indicates that we have a deal...$ S2 W' l- K2 Q# R& u
bool tem_tick = false;
8 s0 _5 T8 K+ V0 f/ J//--- An auxiliary variable for opening a position
- a; W% B4 ?% \# X7 f& d#include<Trade/Trade.mqh>/ ^, p" ^' I/ t1 {9 `& _! r
#include<Trade/SymbolInfo.mqh>: w* ?, @4 {- k; `) D" Q) M* h4 j" ^4 i9 F
CTrade negocios;
& H" F/ Y! x1 n* L# W! aCSymbolInfo info;) S$ s+ ]8 ? ?% d( v; o2 f9 F
//--- Define in OnInit() the use of the timer every second6 z0 p7 n* P& A' M
//--- and start CTrade
% l5 ~1 P; G) i: g X$ l6 }% T$ gint OnInit()0 P4 U9 J0 b: H5 S7 i
{2 U8 @& c8 q$ n) N( h' u
//--- Set the fill type to keep a pending order
. `2 ^7 [4 G; D//--- until it is fully filled
: ~2 O) z+ F$ `" z" [! g( {! {negocios.SetTypeFilling(ORDER_FILLING_RETURN);+ {" {( d, E8 M
//--- Leave the fixed deviation at it is not used on B3 exchange4 Q4 e3 W# R/ q# r. N
negocios.SetDeviationInPoints(5);" _0 B( F4 s- u' `: g) j- X
//--- Define the symbol in CSymbolInfo...
" ]" q1 y+ v% U+ y c5 _& |info.Name(_Symbol);
0 y- H! ?9 L+ ^5 ?" e6 \//--- Set the timer...% w. j& i7 S; w9 B4 d
EventSetTimer(1);
7 N% j9 W- l0 o6 N5 i% q//--- Set the base of the random number to have equal tests...
7 I- Z# h* S. h H; R' @MathSrand(0xDEAD);; p! A/ M' ^& Q3 e' C: Z% z# S
return(INIT_SUCCEEDED); b( h" z# [3 r! ]
}# q$ f* `4 O# o6 E
//--- Since we set a timer, we need to destroy it in OnDeInit().) G6 e6 C ~- M9 m: M4 n
void OnDeinit(const int reason)
2 C& O/ M* p" O: l# ?. }% `2 ]{4 O% |. p& v8 `+ y( n
EventKillTimer();
9 B; x1 M0 m+ B" g) m: O}
5 R* O+ \' y+ K5 u: n/ `# y; l//--- The OnTick function only informs us that we have a new deal: |8 p7 X" P5 g: B
void OnTick(). M* z3 B; |* X$ s+ Q
{
' y0 |4 R5 c# n/ Rtem_tick = true;" T# s7 g8 ~( U! t7 T9 O
}5 [6 D4 t2 t, o9 b7 ~8 q
//+------------------------------------------------------------------+9 M5 e0 w3 T8 t: _5 \9 C9 N7 n7 I# m
//| Expert Advisor main function |. U5 q, |; ]5 ]3 j" J! w
//+------------------------------------------------------------------+
2 M! H5 z- A0 P& }6 U `% bvoid OnTimer()
Z( j5 t6 p# J- s{) F2 S2 e, C6 G: m0 Z
MqlRates cotacao[];
9 ~0 S4 d% ]- P9 `. Qreturn ;, w! s( y G9 |9 `# T9 i: q
if (negocios_autorizados == false) // are we outside the trading window?
( p# R. b. k$ U1 l- mreturn ;, P+ K' i9 x' N. m5 y
//--- We are in the trading window, try to open a new position! |- o; _$ k$ e' m. ? C5 q
int sorteio = MathRand();+ [, _$ n. W8 P
//--- Entry rule 1.1
' d8 X# n" M8 ~6 Y$ Bif(sorteio == 0 || sorteio == 32767)- ~2 B, j6 _* s ~( l
return ;
0 p, ]6 o8 `. N3 Q$ y/ ^if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy/ i" h2 R* }* ^3 N
{
{2 N ^3 ?& G$ B; i+ v/ Xnegocios.Buy(info.LotsMin(), _Symbol);
; J* x! z/ K) R! Z* p}. W8 ^% ~$ A- r/ Q+ g
else // Draw rule 1.3 -- odd number - Sell
/ b5 X! A/ r) v7 F. i{9 x) N+ h& G8 y( B" q% t$ G9 ^
negocios.Sell(info.LotsMin(), _Symbol);
! y% n: n5 G/ _ U; V/ k7 a/ H}
3 [ ~6 z8 i& V}
' e. p4 N, z) S; A/ c8 H; f//--- Check if we have a new candlestick...4 r, A( P! ]; e! J9 L2 h3 {& \
bool tem_vela_nova(const MqlRates &rate)
5 x- C$ W( U+ n! W{2 x1 V$ r) l# j- H7 F7 Z4 D/ @) \& X
{
O% f9 G# e: Q% Lret = true;. v) a/ g% p, l& t) f: T
close_positions = false;' i2 N0 z- h1 C7 @7 Q( x G
}
) h, l$ f* s, V4 [7 j' welse% G& m6 q3 d& m6 S0 P. s* Y: Q
{0 T$ X4 g( S7 U4 q3 t; n
if(mdt.hour == 16)0 t. r: e: t! ~: E1 b" T1 {
close_positions = (mdt.min >= 30);
( Z; D8 j, d& u* P b; V4 @3 f0 \}
/ x& U# o6 j1 n}. o/ n7 W# T$ h6 p; f+ I4 _9 i+ H2 T
return ret;
% {, Q0 n0 ]1 R4 [) V+ L- e}3 d3 W. O1 q. C% `
//---% ^! g( u. Y8 \4 ]) d& x0 I
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
, z8 N3 X$ x) W{' D% z2 k; S ]: N. H/ q/ d
if(PositionsTotal()) // Is there a position?' Y/ p' Q# _9 n& w6 I# N
{
# z, v" x9 i5 [: I5 U; }double offset[1] = { 0 };
% w3 O3 w4 p9 b0 k% {% `% }if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
+ f6 u+ Y6 ?8 H2 u2 J) U' f&& PositionSelect(_Symbol)) // Select the existing position!
6 l) B8 v" Y# a, g# F! s( o+ P{
6 j+ K1 B1 [8 |ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
6 u i! [ B5 gdouble SL = PositionGetDouble(POSITION_SL);* Z2 S2 u8 m2 A0 g: @% U4 D) R
double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));
) m& I5 v6 V# H( Eif(tipo == POSITION_TYPE_BUY)# s+ X% Z2 b: ]9 _6 t
{) X; \ L9 y' E
if (cotacoes[1].high > cotacoes[0].high)
5 `) d' I1 i7 w( Z' N7 K7 X) f{
, F' V$ V) j6 A+ }4 cdouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
. F. s9 o4 u2 X' Y" n0 _0 d5 einfo.NormalizePrice(sl);7 q6 a! x! I+ q& d# G, x+ O
if (sl > SL)
- f8 f, A' A6 l( y' I) x{
6 u$ ^: P. L; S0 T$ n2 s/ O4 xnegocios.PositionModify(_Symbol, sl, TP);. _) O! W; H( m
}4 L# A# U0 P7 Y% o; W- {
}; k, s+ `# K! P; l3 j4 U5 a
}5 t t8 A" G) i, Q b$ \$ ~. d! O
else // tipo == POSITION_TYPE_SELL
8 X1 o9 B. S1 |( _{
- V5 I6 l- q" ]7 d9 H7 a# ]if (cotacoes[1].low < cotacoes[0].low) t ?' {: b+ g; Q, s3 n
{
; N) \9 K' P2 T0 ?: V$ I( Oreturn true;
& o( B4 G# J4 S( U! }}
' H9 B) U* B" f' z// there was no position- i% i, E1 r4 {( Y
return false;
7 G& c! E9 U' G9 I}9 p' o: d) ^5 Z! C5 H, d
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。' e4 d% _" b$ e1 w
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |