第一篇 创建新文件
1、打开 MetaEditor (如何打开自己想办法)呵呵,如果这个都打不开,拜托下面的也不用看了。也许你不适合研究这个。
2、选择文件-->新文件 打开文件创建页面。
3、选择第二项 客户指标 然后点下一步。
注:这个页面可以创建6种文件。我们常用的有 《客户指标》,《脚本》,《智能交易系统》三种。我们先从指标开始。
4、输入名字,作者等等。(支持中文)暂时不添加参数。
注:这个位置可以添加用户变量以后讲解。
5、下一步 我们先建一个主窗口指标 所以这个页面什么都不用操作
注:这个位置可以添加指标“线”。以后提及。
6、点击完成。
ok新的指标文件生成了。但还没有任何有用的代码。初始化代码齐全。
//+------------------------------------------------------------------+
//| MT4指标编辑.mq4 |
//| ldj |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright \"ldj\"
#property link \"http://www.metaquotes.net\"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
//----
return(0);
}
//+------------------------------------------------------------------+
上面的就是刚刚新建的一个指标文件。
第一部分 指标注释 只是一个说明,有没有都不影响指标运行。
//+------------------------------------------------------------------+
//| MT4指标编辑.mq4 |
//| ldj |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
这部分中前面的 “//” 两个斜线 说明后面的是注释语句,不参与实际运行。
第二部分 预处理语句 这部分规定了指标的窗口性质。如下:
#property copyright \"ldj\"
#property link \"http://www.metaquotes.net\"
#property indicator_chart_window
#号表示后面是预处理语句。
property 的意思是定义mt4内部变量的性质。变量名是mt4定义好的只能用固定的变量名。
例如:版权变量 copyright 链接变量 link 以及指标窗口类型变量indicator_chart_window等等。
其中窗口类型变量有indicator_chart_window(主窗口)indicator_separate_window(副窗口)两个这里只能用一个不能两个同时用
这部分内容一般不需要修改。
第三部分 初始化函数(加载函数)
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
//----
return(0);
}
这个函数中的代码只在只在指标(EA)加载的时候执行一次。用于对一些变量的初始化。
去初注释函数体为
int init()
{
return(0);
}
第三部分 卸载函数
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
当去初指标(EA)的时候执行一次。用于去除一些控件。
去除注释函数体为
int deinit()
{
return(0);
}
第四部分 主函数,每当价格变化时就调用执行一次。主要执行代码都在这里。
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
//----
//----
return(0);
}
第五部分 子函数。有些指标和EA含有子函数。我习惯写在后面。
华丽的分割线
===================================================================
#property indicator_buffers 3
#property indicator_separate_window
#property indicator_color1 White
#property indicator_color2 Red
#property indicator_color3 Silver
double Buffer1[];
double Buffer2[];
double Buffer3[];
extern int Fast = 10;
extern int Slow = 22;
extern int Signal = 7;
int init()
{
SetIndexStyle(0,DRAW_LINE,0,1);
SetIndexStyle(1,DRAW_LINE,0,1);
SetIndexStyle(2,DRAW_HISTOGRAM,0,1);
SetIndexBuffer(0,Buffer1);
SetIndexBuffer(1,Buffer2);
SetIndexBuffer(2,Buffer3);
IndicatorShortName(\"MACD(\"+Fast+\",\"+Slow+\",\"+Signal+\")\");
SetIndexLabel(0,\"MACD_MAIN\");
SetIndexLabel(1,\"MACD_SIGNAL\");
SetIndexLabel(2,\"MAIN-SIGNAL\");
IndicatorDigits(Digits+2);
return(0);
}
int deinit()
{
return(0);
}
int start()
{
int limit,counted_bars=IndicatorCounted();
if(counted_bars0) counted_bars--;
limit=Bars-counted_bars;
for(int i=0; i 0 )
{
for(i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
if(OrderType()==OP_SELL)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
Sleep(5000);
}
}
}
}
//判断是否买或卖或平仓
int buyorsell() //在这个函数计算设置你的交易信号 这里使用MACD 和MA 做例子
{
double MacdCurrent, MacdPrevious, SignalCurrent;
double SignalPrevious, MaCurrent, MaPrevious;
MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
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);
if(MacdCurrentSignalCurrent && MacdPreviousMaPrevious)
return (1); // 买 Ma在上升,Macd在0线上,并且两线上交叉
if(MacdCurrent>0 && MacdCurrentSignalPrevious
&& MaCurrent 19 ) return; //周五晚11点后不做
}
if (OrdersTotal( ) >= maxOpen) return ;
//如果已持有开仓次数达到最大,不做
if (nowbuyorsell==0) return; //不交易
TradeOK(); //去下单交易
}
void TradeOK() //去下单交易
{
int error ;
if (nowbuyorsell == 1) //买
{
switch (whichmethod)
{
case 1: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,\"\",MAGICMA,0,Blue);break;
case 2: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,0,\"\",MAGICMA,0,Blue); break;
case 3: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,Ask+TakeProfit*Point,\"\",MAGICMA,0,Blue);break;
case 4: res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,\"\",MAGICMA,0,Blue);break;
default : res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,\"\",MAGICMA,0,Blue);break;
}
if (res (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))) //开仓价格 当前止损和当前价格比较判断是否要修改跟踪止赢设置
{
if ((OrderStopLoss()) > (Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)))
{
bs = OrderModify(OrderTicket(), OrderOpenPrice(),
Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Tan);
}
}
}
}
}
华丽的分割线
=====================================================================
EA中文注释
原帖由 白色流星 于 2007-12-1 20:58 发表
首先我们先解读一下系统自带的MACDEA~这个相对简单~
//+------------------------------------------------------------------+
//| MACD Sample.mq4 |
//| ...
extern double TakeProfit = 50;盈利目标点数
extern double Lots = 0.1; 每单入场的手数
extern double TrailingStop = 30; 追踪止损的点数
extern double MACDOpenLevel=3; MACD开仓的参考位置
extern double MACDCloseLevel=2; MACD出场的参考位置
extern double MATrendPeriod=26; 条件中使用的MA均线的周期数
程序最上面extern开始的这些数据都是程序参数,也就是在使用者调用的时候可以修改的部分。
这个EA是个常见的技术指标条件入场,条件出场 同时又移动止损功能的完成示意,很适合初学者研究。
先总结这个程序的基本条件的意思 以方便大家对号入座,尽快理解。
多头入场条件:
MACD小于0 并且 小于指定的参数MACDOpenLevel并且 MACD讯号下下穿基准线(死叉) 并且 MA向上趋势
多头出场条件:
MACD大于0 并且 大于指定的参数MACDCloseLevel 并且 MACD信号线上传基准线(金叉)
空头入场条件:
MACD大于0 并且 大于指定的参数MACDOpenLevel并且 MACD讯号线上穿基准线(金叉) 并且 MA向下趋势
空头出场条件:
MACD小于0 并且 小于制定的参数MACDCloseLevel并且 MACD讯号线下穿基准线(死叉)
=============================================================
有了以上的初步了解,下面开始进行EA程序基本结构的分析:
1、start()函数是最重要的执行部分,每来一个价格 此函数都自动执行一次,所以主要的逻辑结构都在这个函数里
2、程序的基本流程都是按照以下步骤进行,我们先牢牢记住这个结构,然后再对号入座去理解程序。
先判断当前自身的仓位状态,因为start函数式循环运行的,所以中间的每个步骤都会使用start函数,因此,当函数开始的时候我们首先要通过MT4的仓位操作函数获得当前的仓位状态,并进一步根据状态进行不同分支的计算。
程序开始的以下两个部分不重要 简单说一下:
if(Bars(MACDOpenLevel*Point) && MaCurrent0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print(\"SELL order opened : \",OrderOpenPrice());
}
else Print(\"Error opening SELL order : \",GetLastError());
return(0);
}
return(0);
}
华丽的分割线
===================================================================================
EA中文注释2
#property copyright \"Copyright ?2007, 520FX Corp.\" //指标版权信息
#property link \"http://www.520fx.com\" //指标联系的网站链接
//=====可调参数部分==============
#define Magic 20090101 //预定义的常量 Magic用于后面程序里的开仓动作时标记在订单里面的一个符号,用于区别其他EA程序下的单 防止混乱
extern int N=50; //参数 后面程序里用它作为N根K线的数量
extern int SL=100;//参数 后面程序里下单的时候用这个设置的点数作为入场时订单的止损价格。
extern int TrailingStop=30;//参数 后面程序里用这个作为移动止损的点数设置
extern double 每单手数=0.1;//参数 表示后面下单的仓位的大小
extern int 滑点偏移点数=3;//参数 表示下单时 服务器端的价格与当前看到的价格相差的范围,如果在此范围内,则允许以服务器端的价格成交
//----全局变量===================
int Tick;//用于记录订单的唯一编号
double StopLost;//用于记录止损
//========主函数部分开始============
int start()//主函数 没来一个价格这个函数就运行一次
{
int Ticket; //局部变量 用于记录每次下单后的状态,用于判断下单动作是否成功,如果不成功则做相应处理和提示
int OrderTypeNow=GetOrderTypeHolding();//通过自定义函数得到当前持仓单的交易类型 买 卖
//自定义函数中做了处理,如果没有发现当前有持仓 则返回-1
if (OrderTypeNow==-1)//空仓阶段 -1表示没有持仓的状态
{
if (TradeOrNo(1))//多单入场条件 自定义函数TradeOrNo(1)参数1 表示针对多单的方向进行判断是否满足入场条件
{
Ticket=OrderSend(Symbol(),OP_BUY,每单手数,Ask,滑点偏移点数,Ask-SL*Point,0,\"\",Magic,0,0);//多单入场
//Ticket表示入场动作的执行结果,如果小于0表示入场动作失败
if(Ticket |