启动交易模型,并构建 EA& h2 Y* h {% _
在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。
- |5 k. a$ x8 a& m5 D2 g为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。
. z8 `! h4 p& v X. x! a. Q以下是制定这些规则的代码。% b3 Z, \- u+ X9 S- J+ O: x# r+ M
//--- Indicator ATR(1) with EMA(8) used for the stop level...; d3 E4 @. f" v1 \
int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1);1 q+ e' N1 o) C- k
int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr);) a, o/ W- ~: u
//--- Define a variable that indicates that we have a deal...
& `4 x2 b# d# R8 v# abool tem_tick = false;$ J, a7 M9 Q! x7 Q, W7 G6 |
//--- An auxiliary variable for opening a position' z; ]: p( e3 v; d6 ?3 y# g' S0 ^
#include<Trade/Trade.mqh>- \" x: T" |& j, _
#include<Trade/SymbolInfo.mqh>
4 }2 m( s2 g: I/ r9 m, C+ b$ \ nCTrade negocios;
- U; @" M% r% {/ M* A1 YCSymbolInfo info;8 N r( u! T* `( U" u3 l) d% ~
//--- Define in OnInit() the use of the timer every second& k& n3 ?9 v h" \" P
//--- and start CTrade6 m# f, X+ }" y: `3 A* M+ x# T
int OnInit()
! R6 _4 f) u3 q3 e$ S{
* [( d1 Q% x9 M* C//--- Set the fill type to keep a pending order; Q) I1 i! ~* z& L) S# q8 i
//--- until it is fully filled
! h t5 m5 v. l# H1 @negocios.SetTypeFilling(ORDER_FILLING_RETURN);4 ^2 e+ _0 D3 O+ \( j
//--- Leave the fixed deviation at it is not used on B3 exchange
* ?7 Z. c! t) L# K, mnegocios.SetDeviationInPoints(5);! I* C2 m6 Y# t; [' M
//--- Define the symbol in CSymbolInfo...
' _% M) M3 C: u5 W: Oinfo.Name(_Symbol);2 W4 D2 C0 f1 o0 c
//--- Set the timer...
# Y" A2 U" Z' aEventSetTimer(1);
$ T/ w; U) C9 `* p, l9 [//--- Set the base of the random number to have equal tests...) p' S& u$ D2 Q4 B9 v
MathSrand(0xDEAD);
, v$ C$ B5 O9 D9 J4 a4 y) Yreturn(INIT_SUCCEEDED);
$ Z* E5 x4 N* V) [1 f4 |}) \- s- J0 r2 I; |; k) p6 n; Z0 k
//--- Since we set a timer, we need to destroy it in OnDeInit().( f$ x v, x/ D$ C: s. G
void OnDeinit(const int reason)
/ X0 W; e W6 ^! u, N+ |9 r- H{
! V7 P2 b4 c, T. i* c- w# u. z' zEventKillTimer();2 Y) M( ^" W7 ?0 \+ W# C
}. T+ @6 R$ q$ j6 E* ~
//--- The OnTick function only informs us that we have a new deal9 E) Q4 S1 l" D, x9 {7 |6 _
void OnTick()( ?' P5 R- g; W ^$ p M! i
{8 I! N) n" s" S) K9 @& R
tem_tick = true;
# M$ c8 T* e2 N}. h- i7 w" d& H1 A6 d( ]( |: b
//+------------------------------------------------------------------+
. w( H, W8 x0 S: I1 `5 ]//| Expert Advisor main function |
' y9 h5 X9 \! f5 w% s. z& t$ @$ D! \//+------------------------------------------------------------------+
" m1 z* S2 b: M' p0 |void OnTimer()
/ f# s3 A: g& @( h* r& d' y. P) s( X+ g{
) F* m! Z" R; C- n$ uMqlRates cotacao[];
6 \/ F( @( H/ }6 Z g) p1 I- N# ^return ;8 ^0 {' N% ?3 L' P
if (negocios_autorizados == false) // are we outside the trading window?
: S% f, Z( t- x0 z% s& Mreturn ;
. S7 ~' W; @3 u6 x# @5 s/ z' \//--- We are in the trading window, try to open a new position!# Q2 S& y7 Z& M& ~8 n0 B, B5 u
int sorteio = MathRand();
0 B) [+ @& T$ L" i: Z8 Q//--- Entry rule 1.1, T" I$ U6 k8 ?6 |/ ?7 v
if(sorteio == 0 || sorteio == 32767)
; V% M P k( Wreturn ;! K: h- N( K$ R. n: o; V1 F9 y7 e
if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy
; u2 D6 N9 Z" Z0 o8 u% C# u7 k9 R{
8 x0 T% ]& j( z4 d, [negocios.Buy(info.LotsMin(), _Symbol);
2 a- V/ W m3 q0 S, u# c% l! `4 x}6 G$ n$ K- o7 M7 s S5 p F: r* {
else // Draw rule 1.3 -- odd number - Sell
0 d0 O5 R: R5 O7 B! I{2 p, A# a$ }- O% {; k
negocios.Sell(info.LotsMin(), _Symbol);
9 ^5 ^1 C! g& Y/ D P5 W}# \9 R3 ?+ I/ }0 y
}
4 C8 C, ~1 F9 V9 `//--- Check if we have a new candlestick...
' y/ w3 _5 e( L4 k \3 ubool tem_vela_nova(const MqlRates &rate)* _5 B% p: x! R: ~) ^
{0 z w( ~; V$ C; E' v4 j( N
{ ]' F+ w- z* S+ y2 d* e$ K. f$ h+ \
ret = true; z6 w' S0 D7 V. }& U- }/ V
close_positions = false;) e# u2 X5 M! A1 D8 D
}
- b2 p; C3 h$ m9 V& uelse/ K( {3 Z$ `8 l, i
{
$ s' u' y3 v* w# V# Qif(mdt.hour == 16)9 w4 S+ W- s% |/ ~+ s* ?
close_positions = (mdt.min >= 30);
4 k% ]- A( t8 B0 d}
: }4 C* Z, e& g& [- a}" b# p. F0 c, s. c
return ret;
) U% p* W! V" c% t}
; t4 L$ v- N4 |. i q//---
5 g7 Y/ `4 ~2 ]7 Q8 e- N! abool arruma_stop_em_posicoes(const MqlRates &cotacoes[])
/ W$ }. c$ z3 E{7 b! f9 ~! e# _, b, `
if(PositionsTotal()) // Is there a position?
2 P! Z5 f6 v: l- L" [" C{: \/ z, Z9 M( E! e/ ]
double offset[1] = { 0 };4 G& v y8 F% F3 j3 Z
if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied?
& h; ?/ r) I8 |% y6 ]& [&& PositionSelect(_Symbol)) // Select the existing position!
! F; k- F* V$ j) x! j( k# P{0 f2 D+ o, u* T% w5 G+ _( M: z k$ \4 u
ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);5 H( ^& {+ o% I
double SL = PositionGetDouble(POSITION_SL);
1 s+ C9 N" L5 X' C9 @; [: ?double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP));5 t: u3 s! K5 A
if(tipo == POSITION_TYPE_BUY): m1 i0 O. p9 u2 Y1 r X9 E' T. F
{; D a5 ]2 M% [6 o( e, }+ _, Y1 g
if (cotacoes[1].high > cotacoes[0].high)
: x6 a" ^/ [ `) d$ s c{
& d5 U& w6 R% i2 odouble sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0];
( i# h C3 t2 [9 Qinfo.NormalizePrice(sl);5 |. H6 p' ~* A7 t- F
if (sl > SL)
' S- h$ h% g* l2 m6 y{& x1 @/ e& ~6 p2 O
negocios.PositionModify(_Symbol, sl, TP);' ~( H, l% Z3 @9 q \" d
} D& e8 @8 e( }, t3 g4 \; w
}* j7 P7 S; y9 J; v9 A8 x& h
}
, b' i" h9 i9 velse // tipo == POSITION_TYPE_SELL8 | ]# s% F# ?9 J
{
" V" s8 D; C8 N8 z; s6 u4 `if (cotacoes[1].low < cotacoes[0].low)
# h$ n% A/ _3 P& q! q& U{
8 x& q2 z1 ?# W3 u2 j& ~4 ^return true;
0 Y$ M; q2 c# z8 u) `2 M}% c# I7 b8 m g
// there was no position
9 U0 y, l" v4 h( n7 i$ B" areturn false;! x; b3 E" e u' z& u* J5 [
}, K3 U; C6 g4 ?* U& G
我们简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。+ _/ r5 _# [1 I; A' U+ m; l$ ?
到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。 |