返回列表 发帖

MT4自带的EA:Moving Average 详解

MT4自带的EA:Moving Average 详解; v9 G  G$ f7 a5 R3 O, D1 i
; W; d- {! [$ X; u. J
//+------------------------------------------------------------------+* W4 o  e! ]: e+ l
//| Moving Average.mq4 |
6 t. u2 p/ G# j) @9 K& c//| Copyright ?2005, MetaQuotes Software Corp. |" q. S8 N* h3 Q  h. u
//+------------------------------------------------------------------+: N) X) [/ \, J; J% ~9 q( m
#define MAGICMA 20050610 //定义本EA操作的订单的唯一标识号码
' c, e5 v: @. C9 o! \: Y/ ^* ?
# c4 D4 d+ o; I$ A$ ]extern double Lots = 0.1;//每单的交易量  ^% |7 m( `# x3 v3 G+ P' h
extern double MaximumRisk = 0.02;//作者定义的最大风险参数
: Y8 X2 k! O' F& f- B. I( eextern double DecreaseFactor = 3;//作者定义的参数,作用要看程序中的用法
: J; ~- Z  ?/ F/ \extern double MovingPeriod = 10;//EA中使用的均线的周期9 U$ p/ l. ^1 F  E+ e7 V4 l$ p1 C
extern double MovingShift =3;//EA中使用的均线向左的K线偏移量
' g- ?" f9 N7 r( L1 k& M//+------------------------------------------------------------------+
/ c$ Y( O' p% x//| Calculate open positions |- p2 w! t( i( _9 }& S5 ~8 H
//+------------------------------------------------------------------+
/ m, e4 I* M5 \0 w" T6 w. xint CalculateCurrentOrders(string symbol)//函数作用,计算当前持仓订单的数量  g3 Z8 ~; x; o( S& q
{$ A9 j9 a0 ?$ z. Q
int buys=0,sells=0;//定义两个临时变量,准备用于后面的多空订单的个数计算# |( x# b+ d! K! K! F
//----1 P& M# S3 F- \1 m, E0 n
for(int i=0;i3 h+ Y- d1 F; }, W
{
+ B, ^+ g9 [. [6 S* r* Q* dif(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;//挑出持仓单的每一个订单位置
! n+ L7 r; Q" a( d, i1 qif(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)//根据订单位置,比较是否是当前K线商品以及订单唯一标识号是否和本程序设置的一致(用于避免EA误操作其他程序控制的持仓单)2 L  E: E; i+ J
{6 T+ Z4 Q; i1 ^5 {/ N! y
if(OrderType()==OP_BUY) buys++;//找到符合条件的持仓单后,如果是多单,则临时变量buys增加1
1 K8 I% Y% T2 N* G9 i$ Rif(OrderType()==OP_SELL) sells++;//找到符合条件的持仓单后,如果是空单,则临时变量sells增加1. }: U) a" U: ^  n
}
( C3 _1 f8 V. h9 y* V6 r4 @' E}
4 h) ~# e5 O+ g//---- return orders volume/ L) e& ^/ q. Q6 x0 u3 S
if(buys>0) return(buys);0 `% x$ ~+ B0 r( V5 h
else return(-sells);//本函数返回查询计算结束时的持仓单的个数。. a9 f% L& [% p# U  P% r
}, R: S! D1 t* A* d, H7 |
//+------------------------------------------------------------------+
! c3 {, `9 A* Q//| Calculate optimal lot size |
% Q) Y5 l0 k+ x8 }//+------------------------------------------------------------------+% `" \/ Y+ E: X* I' n! q8 V# o
double LotsOptimized()//函数目的,根据要求 计算出订单交易量
- }) O! n/ B( N, q( R{# G* V) X  B) \0 z. S. F; ~
double lot=Lots;' X& g7 {6 f9 M) J, n' p
int orders=HistoryTotal(); // history orders total 历史出场订单的个数/ y+ J# s' |9 @% L6 `7 S% p
int losses=0; // number of losses orders without a break- {/ |4 c9 t" a, {; {
//---- select lot size8 }2 y( ~) v( Y3 N; O
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);//通过风险系数的计算获得当前入场单应该采用的交易量( c8 d7 h: i: p5 E  R+ [
//---- calcuulate number of losses orders without a break  J0 z* w' m( k3 h
if(DecreaseFactor>0)& b. j' i2 }% Z6 t" H
{1 a7 I" N' {; d' Y
for(int i=orders-1;i>=0;i--)/ y8 `" W5 K+ i
{% O% q# ^! q3 t' O% I+ |
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }//循环查询出场单队列; F! a! R0 V% L+ @
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;//
* w$ \/ B! S. V$ k; \! u  {# D5 a//----. S: o/ A3 p, m+ y/ N- p
if(OrderProfit()>0) break;
3 ~% p. h5 n0 z: S' Kif(OrderProfit()<0) losses++;//循环计算所有出场亏损单的亏损总和
+ n" t$ M: _2 Y# G}( @7 {/ g+ I& Q3 y6 B7 }, {
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);//如果亏损额大于1,则下一入场单的交易量修正为新的计算结果。
; L4 N. o: c/ c9 I}
! G. ~! g' c2 G4 X) {! b: m//---- return lot size
7 p9 }5 ]% ^, M4 u9 s" Cif(lot<0.1) lot=0.1;//如果计算出的交易量小于帐户最小手数0.1,则下一入场单的交易手数使用0.1作为交易量
& R* t$ C8 A- S: Nreturn(lot);* ]* I7 j% L' s# y* L
}& {; M( v9 h' T$ @7 L
//+------------------------------------------------------------------+' {, W% f4 S+ S. ]6 G; R
//| Check for open order conditions |
) ~% Y2 z/ o( j9 x2 Z% G1 A//+------------------------------------------------------------------+
% x/ I* @7 Q2 T( J) N4 k9 _void CheckForOpen()//检查入场条件的情况并作处理
( I  G1 B8 Q* ]! \% E{
' l9 _2 a2 s7 [2 o5 B+ Tdouble ma;$ d$ _% n  t# r0 D6 y# Z1 d) s
int res;
: U1 V0 E* X1 o$ t! M* @//---- go trading only for first tiks of new bar
# v" v: x8 R  c  i, [. a- Oif(Volume[0]>1) return;//如果当前K线持仓量大于1,说明不是K线的开盘时间点,则直接返回 否则是K线第一个价格,则继续下面的过程
. F: v' P) F* k+ [//---- get Moving Average! D0 {8 ^- K1 X" K/ N$ b* r8 z
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);//获得当前的均线数值
- Y1 y) N. M, @0 Q( F//---- sell conditions
( ~6 @( B. u+ F& W6 |7 G9 Z0 T) Q, Rif(Open[1]>ma && Close[1]4 t5 l0 U- R5 u: x# L
{2 L# U1 l7 x* L
res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);5 b- p/ g/ I6 d1 v0 K/ v
return;
- b, o2 Z3 q% C}7 \  \+ A3 ?+ q9 Q
//---- buy conditions: E5 @3 w# y! O! }, P
if(Open[1]ma) //如当前K开盘价小于均线,而前一K收盘价大于均线,则发出入场空单
! M8 J. c/ |- K4 n& K/ ~& x# Y9 P{6 M0 @+ \: y: i6 U  t0 J# ?4 t( U
res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);. P& |# {" v& S, N4 a
return;% L2 }' ~( Z" R1 M9 n
}
9 g# R+ z$ J6 P5 z- |! Z//----
+ c" r& g8 V6 h" ?}: w6 Q8 H8 @) [! k' @2 J9 d
//+------------------------------------------------------------------+2 m; Z- v3 J" ]# m+ E3 F
//| Check for close order conditions |7 H9 f: Q- B* Q; ]/ l
//+------------------------------------------------------------------+0 ]7 R9 f' s1 e
void CheckForClose()//检查出场条件的情况并作处理
. [# w" I% T2 k* |4 n- ^: J{
* s7 M. @+ W. f" vdouble ma;
6 Q8 i' B$ T4 G, ?1 A//---- go trading only for first tiks of new bar. I) e% A' q$ q7 L
if(Volume[0]>1) return;
" ~3 X' h; ^- k! O3 a//---- get Moving Average! M& l8 p/ u1 K, R6 I
ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);5 m3 e6 d$ \7 ~. U0 j5 J
//----5 @7 ?4 O. ]  S) R( x4 d. g
for(int i=0;i
. E2 j# V/ k+ E0 o- |8 d{
8 F* Z$ r1 w( w- I& {4 @, zif(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;% C- Z. Q) l5 h; D
if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;
# V: N! l2 r, M! \+ |//---- check order type2 N2 Y5 I! J; H- j& E9 I
if(OrderType()==OP_BUY)
& R# D0 S3 B- K# e{( n* J) Y2 u, z1 M4 b5 E2 I* v7 {
if(Open[1]>ma && Close[1], D% A$ v9 Y: E6 C6 X4 S
break;
4 N8 `, P- j6 A* z" g- C1 O}
  @. F5 G: J0 }7 iif(OrderType()==OP_SELL)7 p2 z8 X; O  b1 N) Z7 x5 x7 @. _& @
{( T; V0 J& C# Q7 d$ [; C1 f
if(Open[1]ma) OrderClose(OrderTicket(),OrderLots(),Ask,3,White););//如果持仓是空单,则当当前K开盘价大于均线,而前一K收盘价小于均线,则发出平仓指令% M7 u2 o9 {" ?# B2 t
! Z& H: y6 i7 T6 f1 a7 j0 s$ r
break;
1 B: T, k: ~- t1 D8 B# B8 D}3 V1 ~  ?$ |& W8 \; C9 W
}1 T  h1 P0 @) S$ p6 g& b: r: \( t
//----, t' \. ]) V2 l: A3 _, z- S6 g  `! Z
}
. k$ a. a5 S0 m$ k2 U8 e& r. m$ B//+------------------------------------------------------------------+
, R3 X! Z3 J, r% w//| Start function |
2 U4 A8 d0 x' f. h' E//+------------------------------------------------------------------+4 Y' m3 s. [% X: H0 N; ], Q
void start()//主循环过程
7 o& u( M  `# k! u8 m! ]+ [{$ S1 \! ?( L, _3 {! i) e( K
//---- check for history and trading
' A: R0 O) W1 z4 y7 S, \# ]! yif(Bars<100 || IsTradeAllowed()==false) return;
& x: z6 u% U2 z  y//---- calculate open orders by current symbol
  c- N( [7 Q) N* Dif(CalculateCurrentOrders(Symbol())==0) CheckForOpen();, @, Q5 n5 b; C. G
else CheckForClose();
5 K, M1 P3 d  |2 m//----8 F; y3 G! A. M9 M! M( s
}4 [2 P! `' o# _/ s& v9 h/ `+ _* I
//+------------------------------------------------------------------+' |, M1 n7 P2 t+ d) r

! t" x3 f4 A- \6 P% u6 X3 x2 @' F. e8 i4 W) \: c6 F! i
汇茶外汇论坛
客服QQ:708853620;  
服务客户,诚信双赢;  汇茶外汇论坛

返回列表

站长推荐 关闭


EXNESS外汇平台开户流程

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


查看