每个用用MT4的人可能都多多少少有听到过"EA“这个东东,那EA是啥呢,如果你百度EA,那么印入你眼帘的可能就会是
对没错这就是出了烂橘子的那个EA(顺便说一下有木有一起打BF1(*^▽^*)),这当然不是我们要找的EA,我们这里所说的EA( Expert Advisors) 指的是MT4自带的智能交易系统,可以实现全自动交易,代替人工24小时执行自己所写的交易策略。EA是以MQL4语言为基础的,官方解释说MQL4语言是基于C语言所开发,所以很多用法都和C语言相同,但是也有一些区别例如:
没有运算地址;
没有 do ... while 语句;
没有 goto ... 语句;
没有 [条件][表达式 1]:[表达式 2] 语句;
没有复合数据类型 (结构);
复合负值是不允许的,例如:val1=val2=0; arr[i++]=val; cond=(cnt=OrdersTotal)>0; 等等;
逻辑表达式的计算完成前不可以提前终止。
所以如果有C语言基础的话,上手是很快的,目前网上关于MQL4的教材很少,很多都是类似于字典一样的,并不解释语法以及用法,仅仅将所有函数解释,如果你通读了MQL4的中文手册,那么你回过头来看自带的MACD Sample可能也会一头雾水,看得懂每一个函数却不知道它要表达什么,在MQL4社区里倒是有一些教程,但很多都是英文版本,仅有的一些中文版本也是机翻,所以我就找了很多关于示例的解读,经过研究后发现很多都是2012年以前的版本,里面会出现类似于:
extern double Lots = 0.1;
extern double TrailingStop = 30;
extern double MACDOpenLevel=3;
extern double MACDCloseLevel=2;
extern double MATrendPeriod=26;
但是回到目前版本的MT4示例:
input double TakeProfit =30;
input double Lots =0.1;
input double TrailingStop =20;
input double MACDOpenLevel =3;
input double MACDCloseLevel=2;
input double MATrendPeriod =26;
#property copyright "2005-2014, MetaQuotes Software Corp."
#property link "http://www.mql4.com"//前面两行为版权信息,如果只是自用的话,完全可以删除
input double TakeProfit =30;//input代表输入变量,用户可以通过窗口进行修改,而double指的是后面的变量名是浮点数(可以简单理解为小数)TakeProfit为获利点数
input double Lots =0.1;//前面input和double同上下面不再解释,Lots为每一单交易的手数
input double TrailingStop =20;//TrailingStop为止损点数
input double MACDOpenLevel =3;//MACDOpenLevel为自己设定的开仓指数,本例为3
input double MACDCloseLevel=2;//MACD平仓指数
input double MATrendPeriod =26;//均线趋势周期=26根K线线
总结一下,input函数主要用于一些需要在优化时方便修改的指标,可以在回测时很方便的直接修改,而double主要用于数值,浮点数都要用到它。
void OnTick(void)//此处的void意思为空值,等待赋值,新版MQL4的模板中取消了int start函数所以就不要在苦苦寻找start函数了。
{
double MacdCurrent,MacdPrevious;//给定自定义浮点数类型变量,分别是目前的MACD值和上一次MACD值
double SignalCurrent,SignalPrevious;//定义目前的信号值和前一次信号值
double MaCurrent,MaPrevious;//定义自定义函数变量目前MA值和前一次MA值
int cnt,ticket,total;//int函数是代表整数,int后面的所赋值的变量均为整数 cnt这个变量在后面会用到 ticket仓位 total总数
if(Bars<100)
{
Print("bars less than 100");
return;//此处为判定若柱子数量少于100,则不执行后续函数直接返回,如果是自用,此处代码也可忽略不写(bars为柱子的意思)
}
if(TakeProfit<10)
{
Print("TakeProfit less than 10");
return;//同上获利若小于10,直接返回自用可不写
此处用到了if函数,做了一个简单的循环和判定,如果有C语言基础的话,这句话应该一看就懂,翻译过来就是当柱子数量少于100时,在屏幕下方打出柱子少于100,并且返回开头,当设定获利少于10时,打出获利少于10并返回开头。
MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);//利用imacd函数对前面的已经自定义的函数进行赋值,括号中的数值是imacd函数所需要的一些设定参数
MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);//本行和下方代码作用同第一行
SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);
iMACD函数需要以下几个参数int iMACD(
string symbol, // 交易品种名称symbol意思为当前交易品种
ENUM_TIMEFRAMES period, // 周期
int fast_ema_period, // 快速移动平均数周期
int slow_ema_period, // 慢速移动平均数周期
int signal_period, // 不同点的平均周期
ENUM_APPLIED_PRICE applied_price // 价格或者处理器的类型
);
所以imacd里面NULL就代表当前的交易品种,函数中PRICE_CLOSE指的是采用收盘价,0,12,26,9这几个参数一般是固定的,若变量为Macd那么后面的MODE就为MODE_MAIN,如果为signal那么MODE就为MODE_SIGNAL,最后一位数字是指shift也就是0代表
当前1代表前一次。
iMA函数主要是下列几个参数
int iMA( string symbol, // 交易品种名称 ENUM_TIMEFRAMES period, // 周期 int ma_period, // 平均周期 int ma_shift, // 平移 ENUM_MA_METHOD ma_method, // 平滑类型 ENUM_APPLIED_PRICE applied_price // 价格或者处理程序类型 );
iMA函数主要作为一个处理器存在,所参数沿用i'MACD函数的total=OrdersTotal(); if(total<1) { //此处给total赋值。OrdersTotal函数的意思为获取当前的仓位数量,所以total变量的意思就是当前的仓位数并与1比较即确认若果当前没有开仓则进行下一步。 if(AccountFreeMargin()<(1000*Lots)) { Print("We have no money. Free Margin = ",AccountFreeMargin()); return;//AccountFreeMargin函数是获取当前账户保证金余额,并判断当前的保证金余额是否足够开仓。
if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious
(MACDOpenLevel*Point) && MaCurrent>MaPrevious) //此处是对多头开仓条件的判定,如果(当前MACD<0 并且 当前MACD>当前的信号值
且前次MACD<前次信号,并且取当前MACD绝对值>开仓水平*点 且当前均线>前次均线) MACD处于0轴以下(熊市)+MACD与信号形成金叉+MACD的绝对值>MACD开仓水平值*点数+均线上升(零下金叉+均线上行)
{ ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);//OrderSend函数即为开仓函数可利用该函数进行多头或
空头开仓,当前货币对,多仓,开仓量,卖价,滑点=3,没有设置止损,止盈=卖价+设置的止盈点,“名称”,订单号,限挂单=0,绿色箭头显示 if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice()); } //如果ticket大于0则说明开仓成功,则输出多头仓位 else Print("Error opening BUY order : ",GetLastError()); return; } //若ticket小于0则说明开仓失败,输出错误原因
if(MacdCurrent>0 && MacdCurrent
SignalPrevious && MacdCurrent>(MACDOpenLevel*Point) && MaCurrent //如果(当前MACD>0 并且 当前MACD<当前信号 并且 前一次MACD>前次信号 且 当前MACD>MACD水平*点 且当前MAC<前次MA) MACD处于0线以上+MACD与信号形成死叉+MACD值>MACD开仓水平值*点数+均线下降--(零上死叉+均线下行) { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red);
//同上,OP_SELL为卖单,Bid为买价,其余部分同buy单 if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice()); } else Print("Error opening SELL order : ",GetLastError()); } return;
//确认开仓是否成功,解释同上
for(cnt=0;cnt
0 && MacdCurrent SignalPrevious && MacdCurrent>(MACDCloseLevel*Point))//自动平仓的条件 { if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet)) Print("OrderClose error ",GetLastError());//检测仓位是否关闭成功,!OrderClose表示否定的意思,即若!OrderClose为真,则说明失败 return;
if(TrailingStop>0)//TrailingStop在函数一开始就赋值过,表示止损 { if(Bid-OrderOpenPrice()>Point*TrailingStop)//Bid表示买价,OrderOpenPrice表示开仓价,所以是持仓单的开仓价格。
//意思为买价-订单开仓价>移动止损*点数 { if(OrderStopLoss()
{ if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green)) //修改订单(订单索引,开仓价格,买价-移动止损*点数,止盈价格,限价单格,使用绿色箭头显示) Print("OrderModify error ",GetLastError());//若!OrderModify为真则输出错误信息 return;//返回上一层 } } } }
else //空头判定 { if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious
(MACDCloseLevel*Point))//当前的MACD<0 并且 当前MACD>当前信号值 并且前一次MACD<前次信号 且 MACD与信号线形成金叉 且取绝对值(当前MACD)>MACD平仓水平*点 { if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet)) Print("OrderClose error ",GetLastError());//同多头检查错误 return; } if(TrailingStop>0) { if((OrderOpenPrice()-Ask)>(Point*TrailingStop)) { if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red)) Print("OrderModify error ",GetLastError());//同多头,检查止损 return; } } } } } } //--- }
以上就是对于整个MACD Sample的解读,如果有什么问题可以一起讨论哈