启动交易模型,并构建 EA. o3 u# a; n2 g5 A) R& W$ }1 M3 I8 ] E0 v
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。/ J+ [" v' @7 q$ I! I
为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
" n7 {9 I& }- X" V以下是制定这些规则的代码。" c/ a% }9 d3 {: W
//--- Indicator ATR(1) with EMA(8) used for the stop level...1 }: `* m% K) `
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);
! j4 L& l! Z6 n7 H; E3 p) s* n, lint ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr); ]4 r# ^ |& T2 f
//--- Define a variable that indicates that we have a deal...9 S; r8 I% P9 Q6 I1 E
bool tem_tick = false;
5 M% u' G/ H4 ]- l1 W+ }9 N5 q//--- An auxiliary variable for opening a position8 w; J4 }/ S" \) [( {; u1 [+ c2 _/ z
#include<Trade/Trade.mqh>
' E% n' L. e3 t3 O& Y5 X% N#include<Trade/SymbolInfo.mqh>1 O/ w3 h. J; `) o1 \& G3 a4 o) f
CTrade negocios;
' p! }2 S; @1 u( [* KCSymbolInfo info;
% g' |+ ]) L, T# g8 H7 E, M//--- Define in OnInit() the use of the timer every second
1 |! P- ]5 ]' @//--- and start CTrade$ m$ d* H0 z) c: j
int OnInit()6 l0 ^! t7 G! j6 ^( M; B
{ h, q! i. w7 I+ F& k, W
//--- Set the fill type to keep a pending order" \: ~( `7 U7 I1 @2 b t
//--- until it is fully filled3 i- s% ~- r% Y1 Q1 f) f
negocios.SetTypeFilling(ORDER_FILLING_RETURN);
2 Y7 q' @1 u- ]& C//--- Leave the fixed deviation at it is not used on B3 exchange/ G& t+ W: h- `2 ~4 n" w0 U( e
negocios.SetDeviationInPoints(5);
) w$ Q; |9 Q8 \: t//--- Define the symbol in CSymbolInfo...: l+ { B( \) z) }
info.Name(_Symbol);
! F: r3 Z" ]6 m# V//--- Set the timer...
0 S+ M! z A4 B# sEventSetTimer(1);
) X2 G% J1 q* \9 X. y' R; W//--- Set the base of the random number to have equal tests...
5 o1 e8 q, E6 a3 YMathSrand(0xDEAD);
% Y7 H( {$ i8 M$ t7 mreturn(INIT_SUCCEEDED);
# H; y, S' H( `* q% z}9 m5 g% T4 c6 a. k9 y5 p4 z. X$ }
//--- Since we set a timer, we need to destroy it in OnDeInit().+ ?9 D, r) u2 H; F. {4 a
void OnDeinit(const int reason), @" U6 o/ M5 l- K
{8 k# Q- [) Z0 {" @0 `9 v1 Z3 @' a
EventKillTimer();
# y2 \% k, _/ o5 U* e}
. @( f! U/ l" q- g0 v* {//--- The OnTick function only informs us that we have a new deal
0 A& I$ B# m$ h. M0 s( V% }8 G# Hvoid OnTick()6 J: p+ q% h: c g/ F+ u/ I- W2 H
{$ |5 @2 P! v9 `- ~3 G/ J
tem_tick = true;
) W" {! U. n9 ^$ J: R% h" C( q}
* g" R4 d3 \( V% W: m7 T; @//+------------------------------------------------------------------+) r+ j5 D9 d& z' x* ]/ ~
//| Expert Advisor main function |& H7 p. w* {( I' A- i3 k0 R( w8 B
//+------------------------------------------------------------------+
% j# N5 x" e& m, F% {& x3 \void OnTimer()
* J+ X$ i/ o( f( m+ N{
% z- ~& m6 C$ xMqlRates cotacao[];
0 S4 t: I9 b: O. Z# ?+ I v5 k8 R8 [return ;
5 j" }$ c: ^& q* P. k: n. Z4 Sif (negocios_autorizados == false) // are we outside the trading window?
0 I) X& U, l& r0 j) t! u5 ? Breturn ;6 ^3 o, K7 O* k9 V
//--- We are in the trading window, try to open a new position!, @. b/ J: ^: w
int sorteio = MathRand();
3 p+ Q5 A; k3 S8 f/ |//--- Entry rule 1.1
- y& [) s4 y9 t2 Lif(sorteio == 0 || sorteio == 32767)
% ?3 i# i; B" f- R- d+ z0 Kreturn ;
U& m" w' J$ X, O0 D" O8 _if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy% y, a/ Y2 O$ m! H/ w% s0 _' N6 V
{
4 M2 r( L5 F+ [# O( b; J, p4 Xnegocios.Buy(info.LotsMin(), _Symbol);8 } R! |- l: }, B
}
( V9 A, v; t" o$ D- Aelse // Draw rule 1.3 -- odd number - Sell$ D5 C0 F5 n X( ~
{' q: h( K, Z* D: w
negocios.Sell(info.LotsMin(), _Symbol);, ~8 {6 H4 X: N/ i8 G& Y0 n( v
}
$ x$ x4 Z) _% V# ]}+ K" \3 `# }( K* J- S
//--- Check if we have a new candlestick...* [2 @# I& x' j( Q/ A& E$ |9 y
bool tem_vela_nova(const MqlRates &rate)& k0 \) p0 h. h# j' I1 i
{7 P# L! {7 z: H9 _8 N6 p
{
. L( G: X n, p! z4 f; J: pret = true;: a8 R) A- [) |( ^5 E' E! ?/ o
close_positions = false;
% ]! C2 _- K5 f% z- @} g$ @! ~$ U' P
else9 f$ c' ~9 ^3 t+ O
{
: Z* A% l: [8 cif(mdt.hour == 16)
* @: z4 [, u) Z: l6 xclose_positions = (mdt.min >= 30);
; \, V1 ~+ |. d4 g# v+ e) ?5 V}( M" l8 @( }/ R/ a- K" t
}$ Q4 S/ d- Y' E* E
return ret;6 B" d" [0 O4 Z& s: s
}
" U4 f- |7 M5 ?, [//---1 b% o. Y6 i \% b0 G. R! _
bool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
& R. c& c% S: `; G: D{
1 h- |' E8 f, s/ E4 Zif(PositionsTotal()) // Is there a position?
8 Z2 E3 _7 f Y{
7 d0 q5 M6 E+ R0 b" M4 Tdouble offset[1] = { 0 };
1 y: a' n! b. s8 W9 Dif(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?* d2 `7 ~! v8 @0 x
&& PositionSelect(_Symbol)) // Select the existing position!
6 C! o$ `1 P* c& c8 ~{+ d2 _8 A, o) T, E, g% b
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
1 @$ G2 f3 l+ @4 Pdouble SL = PositionGetDouble(POSITION_SL);
/ `' ?. C8 r$ u) B* T& }* Qdouble TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));1 s# {# q( \+ m/ N7 }
if(tipo == POSITION_TYPE_BUY)
8 A9 j4 s; ]0 I{
$ Q9 g3 U/ z6 D: b1 N" f; y4 uif (cotacoes[1].high > cotacoes[0].high)9 C/ Y3 ]2 ?% _, R. m
{% C& v$ z" _. M$ S$ p
double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];6 u+ L8 f0 k# L
info.NormalizePrice(sl);* |" j9 v# l9 T: y: q$ P- Z" R6 @" ~
if (sl > SL)0 K4 `" q0 b/ v* f% `
{. T0 X! ^' e. c$ E1 h) G
negocios.PositionModify(_Symbol, sl, TP);+ }! b, i' n# Q3 m5 l/ N
}" {# \* D8 Q" f& l6 q& [& t
}
$ E% f# h" W% R: \}
, J( @1 o$ Z6 ~) \. velse // tipo == POSITION_TYPE_SELL
' o" |3 f& _& R$ L/ i$ J{
6 Y; {$ U; }* a4 U3 Q) U# u) b( A9 d7 rif (cotacoes[1].low < cotacoes[0].low)/ a. W) s5 w$ t1 E, n& _$ ]) A% l
{2 U, ~. T3 U5 k8 [/ e8 ?
return true;2 w4 d9 k2 n- [0 L4 ], |5 ^9 {
}
) Y, q& q9 F! w% j// there was no position w7 M- s( T5 x& S/ d) t
return false;
; F9 P: C/ l% K) {9 T: t3 ^}
" x# u7 E* K: L- r! \" a Y我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。
7 T# x5 L. L% }* j6 h- g到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |