返回列表 发帖

MT4自带的EA:Moving Average 详解

MT4自带的EA:Moving Average 详解4 R, W0 N- G6 m( I$ u- p/ p
) C8 s4 Y: f# ^- I; g! d
//+------------------------------------------------------------------+, j- w5 |& G4 X; r5 j$ p
//| Moving Average.mq4 |, R+ n5 n+ E/ F- K& R+ V
//| Copyright ?2005, MetaQuotes Software Corp. |
3 n2 y2 j% r$ s' [  S//+------------------------------------------------------------------+
1 ~8 V6 k# d0 p9 e7 e#define MAGICMA 20050610 //定义本EA操作的订单的唯一标识号码. m, Q# D1 ?7 c( u

3 ^2 K2 p" T& v; X# ^% textern double Lots = 0.1;//每单的交易量
' J! C& {: L1 W/ ^2 R3 [) {extern double MaximumRisk = 0.02;//作者定义的最大风险参数+ p8 N& ~2 `! H' f' z3 P& _
extern double DecreaseFactor = 3;//作者定义的参数,作用要看程序中的用法
7 f) F+ t8 K) D- V5 [. Hextern double MovingPeriod = 10;//EA中使用的均线的周期* I/ x/ b9 o$ J. m; J
extern double MovingShift =3;//EA中使用的均线向左的K线偏移量7 m' J6 \" H" V3 {8 r
//+------------------------------------------------------------------+. p  K# Y! _" [* D! A
//| Calculate open positions |9 s% I/ ^6 X# }
//+------------------------------------------------------------------+
' }3 ~: A: _+ N  ?int CalculateCurrentOrders(string symbol)//函数作用,计算当前持仓订单的数量
( `8 G7 S, B7 y. g+ \0 g  s{
3 [: V5 ?6 P$ c: H6 y0 R0 `int buys=0,sells=0;//定义两个临时变量,准备用于后面的多空订单的个数计算0 L9 T! X- V: i2 H
//----2 z7 K- M3 l% @4 B
for(int i=0;i
- O* N$ G$ x8 {: e1 y: f4 D( u{
7 ]* K) l1 S) [if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;//挑出持仓单的每一个订单位置- u1 }# X8 }  Z2 I
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)//根据订单位置,比较是否是当前K线商品以及订单唯一标识号是否和本程序设置的一致(用于避免EA误操作其他程序控制的持仓单)8 F  W' Z- b3 b7 U9 E7 r
{: s1 p+ i# G% W2 P' ~# Z" z
if(OrderType()==OP_BUY) buys++;//找到符合条件的持仓单后,如果是多单,则临时变量buys增加1$ j1 d/ O; }, Q5 g  B/ f9 K
if(OrderType()==OP_SELL) sells++;//找到符合条件的持仓单后,如果是空单,则临时变量sells增加1- e: e0 w" ?5 Z2 W5 f
}( ?9 `2 J9 Y- Z5 G% P
}' ^$ V6 J# s6 y" Y4 {: `$ }
//---- return orders volume
3 r4 x" B& ~& ~3 Nif(buys>0) return(buys);* q5 a. D* p2 t. A" S' B' z8 e
else return(-sells);//本函数返回查询计算结束时的持仓单的个数。
" f5 S3 Q) Z2 H" u. u" t3 d( B4 V}
7 |# g! J. V# V  w  o9 ^: F7 Z//+------------------------------------------------------------------+
, l& |1 J5 t0 o) r5 @& O//| Calculate optimal lot size |
7 X7 @' a0 K% T) Q% i, l5 j" W//+------------------------------------------------------------------+1 u9 D' L( G: ~3 W; G& F
double LotsOptimized()//函数目的,根据要求 计算出订单交易量+ ^1 t9 R# K; u2 f" J: _
{
0 f1 O' {' d" M4 u7 f1 Adouble lot=Lots;" c( Y4 K- A* ^) t! `2 ?
int orders=HistoryTotal(); // history orders total 历史出场订单的个数
! V4 r4 ^& W+ A& a6 @7 }int losses=0; // number of losses orders without a break; Q' q* D& I. x, I5 S
//---- select lot size/ S! M6 y9 s/ h4 z1 h5 V
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);//通过风险系数的计算获得当前入场单应该采用的交易量# |% a' _+ I" @4 g3 D7 O  F, e7 Z
//---- calcuulate number of losses orders without a break
* a3 ?1 ~& E9 vif(DecreaseFactor>0)
1 N6 e0 b- B0 |/ ?9 y, r{
4 R# |) K$ U: d- xfor(int i=orders-1;i>=0;i--)
* m& i, A  P3 }& s* a# o{# ~: q7 u8 |$ _6 h+ d$ [- Q
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }//循环查询出场单队列$ ^9 Y' K" S+ E& C$ D' Y
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;//% w8 s0 k0 Z$ ^# P6 b% L! |* w
//----
5 J, f6 c9 l' c* y9 K) q0 T  j/ qif(OrderProfit()>0) break;
" D6 l/ V) a8 Kif(OrderProfit()<0) losses++;//循环计算所有出场亏损单的亏损总和
6 A  P& p4 X( h+ z% i$ B; _( U}
# {: u" C% X$ n: k, Aif(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);//如果亏损额大于1,则下一入场单的交易量修正为新的计算结果。
/ ^" V( _0 Q: A; m' Z/ C, o}& L; I( s: m- P
//---- return lot size
  }$ A. n3 f# qif(lot<0.1) lot=0.1;//如果计算出的交易量小于帐户最小手数0.1,则下一入场单的交易手数使用0.1作为交易量) I2 D; F! W6 Z4 k
return(lot);1 j9 P4 c6 \7 m& R6 L8 H
}
; h, l; [* D5 T- R0 R  k& Q: s//+------------------------------------------------------------------+
. Z* x7 {: s2 k. z4 D  L//| Check for open order conditions |
5 Y' f7 g  n  \//+------------------------------------------------------------------+
) c( M1 C# {! z. d1 y+ x2 mvoid CheckForOpen()//检查入场条件的情况并作处理" \  s% g- s: M- U4 E
{
6 K/ H  U# K: J* ^0 ?/ Kdouble ma;% n6 j, ]: g4 i% N$ Y% P+ q; {' |% s  y
int res;
' D, h& q) _% x+ m( @& L2 Q//---- go trading only for first tiks of new bar( @3 Y& M  f! F5 \4 F0 L% a
if(Volume[0]>1) return;//如果当前K线持仓量大于1,说明不是K线的开盘时间点,则直接返回 否则是K线第一个价格,则继续下面的过程
& b: Z) `- F7 b' j//---- get Moving Average; {0 J5 _  f& o  y+ w
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);//获得当前的均线数值! v- @: b4 M9 g, f1 |& V0 h; q
//---- sell conditions
$ U2 Q1 e. _' x; O: y' T4 x7 B3 Iif(Open[1]>ma && Close[1]! t9 `3 `1 I! @4 D. d# G- N
{
8 v3 j; E) A1 l: rres=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);
. ~7 O" e  \8 l+ ?" Treturn;
& a' v. `$ p* _}  y/ O' z6 ^+ S* |% B; N) ~% S2 k
//---- buy conditions- B) X1 K+ N3 r1 i5 ]7 t
if(Open[1]ma) //如当前K开盘价小于均线,而前一K收盘价大于均线,则发出入场空单  Q+ B! J* ]  K$ D( Q1 k; W
{5 I/ B1 k+ ?% W
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);
7 A0 U1 P$ w7 l6 ]5 @- C  a' Ereturn;% E: _4 L% G5 E% k- W
}
! y' P. `! C% I//----# H7 E) g" j/ Q
}
1 T& F' X- w. U4 g5 f' c1 H8 q//+------------------------------------------------------------------+
- y+ a* V8 _" b7 u//| Check for close order conditions |7 W+ ^0 U, K/ C# Z+ V$ r& Z
//+------------------------------------------------------------------+
, \2 F* B1 l0 `- \void CheckForClose()//检查出场条件的情况并作处理' b! U  G: b" u0 G( V0 e6 \4 j4 S6 x2 B
{
. r7 |- @3 k* m0 b  l. I( Udouble ma;
+ ?. q& G" t; `, l5 g! g' G//---- go trading only for first tiks of new bar
( L$ ^5 `5 ]; u, xif(Volume[0]>1) return;( m$ R/ M( F- M# P
//---- get Moving Average
2 A8 q3 R7 ^4 p" ]ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);
5 n( |3 ^5 R8 I/ G//----0 x9 b4 w+ ~- @% K  V- _
for(int i=0;i) u6 n& f. e+ j/ x7 T
{
& c5 E/ b& X9 K$ Jif(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
/ g7 u6 h9 D5 d$ Kif(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
# _. `8 i7 Q: {& G% [8 \//---- check order type0 N- u- @/ m! u) R
if(OrderType()==OP_BUY)5 ?- g5 ?7 R/ A7 k0 N- x
{: V6 V! k; t- ]" Y
if(Open[1]>ma && Close[1]
+ W1 Z" u: y9 d4 v6 `break;7 y6 p7 B  M# l9 S' ^
}* R1 [  l/ v  ]. p+ D, X
if(OrderType()==OP_SELL)% h+ G1 |- C/ I) n$ C( i' u
{
' T# V  C3 w# P" yif(Open[1]ma) OrderClose(OrderTicket(),OrderLots(),Ask,3,White););//如果持仓是空单,则当当前K开盘价大于均线,而前一K收盘价小于均线,则发出平仓指令4 c* D1 I% W$ `2 a

* j8 J) _" n9 D$ Sbreak;
6 d; W  C' W5 k" q7 Z5 \& g1 u/ M}
$ Y( h) ~; H/ X  d& {}
9 Y  c! X' x  m7 t//----1 [+ Y! C' L4 Y( x
}* k- u, g# h: E
//+------------------------------------------------------------------+! v4 I% k& w, p3 Z1 W
//| Start function |/ B/ p1 t+ d9 s
//+------------------------------------------------------------------+. I  l5 p$ Y2 Y
void start()//主循环过程+ w! }0 I8 Y* [) ?4 Z: T
{4 M" e( x2 S! ?' }$ T; z- Y- R% P, d
//---- check for history and trading, T. I( e! b( N( g+ B- d/ _
if(Bars<100 || IsTradeAllowed()==false) return;  m; A3 ~9 O" g  o1 t7 P
//---- calculate open orders by current symbol" C1 C0 |+ O  a# W/ g, V: D) M6 B
if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();/ I, A: o* u( X0 [" h: q; E# Z
else CheckForClose();' p- }0 v4 f  l9 b$ S0 z; }
//----& m+ V4 J  i& ^/ s: b
}1 l+ ^0 @8 k! R0 J1 \
//+------------------------------------------------------------------+
) _1 Q9 P* O$ g3 Q2 ^- a
  n1 L% t0 a: H5 P! [( e
/ Q; n! ~2 F2 F8 P) n$ F汇茶外汇论坛
客服QQ:708853620;  
服务客户,诚信双赢;  汇茶外汇论坛

返回列表

站长推荐 关闭


EXNESS外汇平台开户流程

EXNESS外汇平台开户流程 EXNESS(杠杆高达1:1000,可交易外汇、期货、股票等,点差0.4点起,没有任何交易限制)。取款瞬间到帐。 ...


查看