
第一篇 创建新文件
1、打开 MetaEditor (如何打开自己想办法)呵呵,假使这个都打不开,拜托下面的也不用看了。也许你不适合研究这个。
2、选择文件-->新文件 打开文件创建页面。
3、选择第二项 客户指标 然后点下一步。
注:这个页面可以创建6种文件。我们常用的有 《客户指标》,《脚本》,《智能交易系统》三种。我们先从指标开始。
4、输入名字,作者等等。(支持中文)临时不添加参数。
注:这个位置可以添加用户变量以后讲解。
5、下一步 我们先建一个主窗口指标 所以这个页面什么都不用操作
注:这个位置可以添加指标“线”。以后提到。
6、点击完成。
ok新的指标文件生成了。但还没有任何有用的代码。初始化代码齐全。
//+------------------------------------------------------------------+
//| MT4指标编辑.mq4 |
//| ldj |
//| [url]http://www.metaquotes.net[/url] |
//+------------------------------------------------------------------+
#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 |
//| [url]http://www.metaquotes.net[/url] |
//+------------------------------------------------------------------+
这部分中前面的 “//” 两个斜线 表明后面的是注释语句,不参与事实运行。
第二部分 预处理语句 这部分规定了指标的窗口性质。如下:
#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_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(int i=0; i
{Buffer1=iMACD(NULL,0,Fast,Slow,Signal,PR洲际交易所_CLOSE,MODE_MAIN,i);Buffer2=iMACD(NULL,0,Fast,Slow,Signal,PR洲际交易所_CLOSE,MODE_SIGNAL,i);Buffer3=Buffer1 - Buffer2;}return(0);}MACD1下面我们来逐渐达到这个指标。我们要形成双线MACD和一个柱状指标。所以我们在副图上要形成3个指标线。主指标信号指标柱状指标1、第一步证实指标表明的窗口#property indicator_separate_window// #property indicator_chart_window这条代码决定了指标在副图窗口表明。下面那条注释语句表明在主图窗口也就是K线图上表明。2、预定义3个缓冲区来表明这三个指标线#property indicator_buffers 3#property indicator_color1 White#property indicator_color2 Red#property indicator_color3 Silver#property indicator_buffers 3 语句预定义三个指标缓存区。#property indicator_color1 White#property indicator_color2 Red#property indicator_color3 Silver这三条语句为这三个指标预定义了三种颜色。3、定义这三个指标的数组变量。double Buffer1[];double Buffer2[];double Buffer3[];double定义一个浮点变量。由于是一组数所以要定义一个数组“[]”。4、在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);IndicatorBuffers(3);//定义缓冲区的数量最多八个。由于这个指标只需要三个主缓冲区。所有这个有无都可以。有些需要辅助数组就需要定义这个。以后用到的时机再提起。SetIndexStyle(0,DRAW_LINE,0,1);//定义指标的表明形式。DRAW_LINE标示画线指标。看下这个内置函数的定义SetIndexStyle( int index, int type, int style=EMPTY, int width=EMPTY, color clr=CLR_NONE)index:索引号。0就是第一个指标线1就是第二个指标线。type: 指标类型 下面是可选参数均为MT4的标准常量。DRAW_LINE = 0 画线DRAW_SECTION = 1 画线段DRAW_HISTOGRAM = 2 画柱状图DRAW_ARROW = 3 画箭头符号(需要设置符号代码)DRAW_ZIGZAG = 4 画锯齿图DRAW_NONE = 12 不画图style:指标线型 0~4的选择。也可以不要,默觉得0。Width:指标线宽 1~5的选择。也可以不要,默觉得1。clr: 指标颜色 一般用#property indicator_color1 White语句定义。前面定义了所以我们这里没有定义。SetIndexBuffer(0,Buffer1);//为定义的指标变量数组标记索引号。就是使他们一一对应。0号索引对应Buffer1[]变量。依此类推IndicatorShortName("MACD("+Fast+","+Slow+","+Signal+")");//设置指标表明的名称,内容是用+号连接的字符串。就是当鼠标放在指标上所目睹的指标名称。与文件名不有关。SetIndexLabel(0,"MACD_MAIN");//设置指标的标记。就是当鼠标放在指标线上表明的第三行的名称。这条语句的意思是0号索引对应的指标变量标记是MACD_MAIN。其余类推。IndicatorDigits(Digits+2);//定义指标的小数点位数数值是整数。这里Digits是MT4的预定义变量。其值为目前货币兑的小数位。主函数体int start(){int limit,counted_bars=IndicatorCounted();if(counted_bars<0) return(-1);if(counted_bars>0) counted_bars--;limit=Bars-counted_bars;for(int i=0; i{Buffer1=iMACD(NULL,0,Fast,Slow,Signal,PR洲际交易所_CLOSE,MODE_MAIN,i);Buffer2=iMACD(NULL,0,Fast,Slow,Signal,PR洲际交易所_CLOSE,MODE_SIGNAL,i);Buffer3=Buffer1 - Buffer2;}return(0);}1、int limit,counted_bars=IndicatorCounted();//定义两个整形变量,并给counted_bars变量负数。这里面IndicatorCounted()函数是mt4内置函数不需要参数,其返回值为已经计算过的指标数组数量。假使指标错误则这个函数会返回一个负值。2、if(counted_bars<0) return(-1);//假使条件成立表明指标调用运行错误。则退出程序。3、if(counted_bars>0) counted_bars--;//从已经计算的指标中移除最后一条。这条语句用来修正counted_bars致使已经计算的最后一个数值可以在接下去的运算中从新计算一次。4、limit=Bars-counted_bars;//计算需要计算的指标报告的柱数。这里需要表明。在mt4中指标数组的索引和K线的索引标记相同,是从后向前递增的从0开使的整数。也就是说,最后一条K线的索引是0同期K线所对应的指标索引也是0。那么倒数第2条的索引标记为1。倒数第三条的索引标记为2。这一点一定要理解清楚。不然写程序的时机就会发生错误。语句中的Bars是mt4预定义变量,其值是目前图表中K线的条数。这里详细说下为何有个counted_bars--;的语句,这个语句的意思是对变量counted_bars执行自减一操作。由于主函数是每次价格变动就会运行一次。当运行完成后。IndicatorCounted()值应当等于Bars也就是K线的条数假使没有上面的自减一操作,那么当价格变动有了新的收盘价但并没有生成新的K线。这时候计算limit的值将=0.那么下面的for循环体将不会再计算最后一条k线相对应的指标数值。事实上这个是需要计算的(由于有了新的收盘价)。而有了自减一的操作就可以对最有一个,也就是目前K线对应的指标值执行运算。(不晓得能看明白不自己逐渐捉摸捉摸)。这个自减一是必需的。5、for(int i=0; i有关for循环的运行不作解释。各位自己找资料学习。6、Buffer1[ i ]=iMACD(NULL,0,Fast,Slow,Signal,PR洲际交易所_CLOSE,MODE_MAIN,i);//调用MACD指标函数为Buffer1数组负数。看下iMACD()这个内置指标函数的定义。iMACD( string symbol, int timeframe, int fast_ema_period, int slow_ema_period, int signal_period, int applied_price, int mode, int shift)symbol: 货币标识。通用指标用NULL常量。timeframe: 计算所根据的图表时间周期 。0表明根据目前图表周期。fast_ema_period: 快线周期slow_ema_period: 慢线周期signal_period: 信号线周期applied_price: 计算所用价格模式mode: 指标索引模式。MACD指标有两条线,所以这个位置有0,1两个选择。也可以用mt4预定义常量。shift: 索引号这里Buffer1取macd主线报告。Buffer2取macd信号线报告。7、Buffer3[ i ]=Buffer1[ i ] - Buffer2[ i ];//计算MACD两条线之间的距离。8、这里用到了外部变量。也可以叫用户自定义变量。该种变量在加载图表的时机可以修改。extern int Fast = 10;extern int Slow = 22;extern int Signal = 7;extern 核心字表明后面定义的变量是外部变量。华丽的分割线2=======================================================问答题瞬间的光辉/bull本帖隐藏的内容需要回复才可以浏览-------------------------------------------------------------------------------------------------------------------------------------------瞬间的光辉questions感激的没话说呀!牛版夜间12点还回答我的困难,而且回答的那么详细!牛版的解释我觉得是:所有论坛的大神中最无私最热心帮助别人的。为了让许多的新手迅速的入门EA,我决定做牛版帖子的追问者。牛版的帖子非常易懂,一般新手都能看懂70%,仍有那30%的疑问,就由我来补问吧!int OrderSend( string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment=NULL, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE)comment参数有什么作用?A:这参数本意是用于记录这个订单的描述信息,程序只能在订单入场的时机设定他。同期系统会在这个订单发生止损 止赢或者拆单的时机自动修改这里的内容。我一直想寻求一个函数能够返回我下的订单能否已经被止损或止赢了,问了好多人均为同样的回答:OrdersTotal()<1就表明你下的订单平仓了,换句话说就是被止损或止赢了。但是前提是我只能同期做一单,假使我同期做好几单呢,这怎么分析我下的其中一单已经止损或止赢了。今天看了牛版有关comment参数的解释,有了启发:comment参数有什么作用?A:这参数本意是用于记录这个订单的描述信息,程序只能在订单入场的时机设定他。同期系统会在这个订单发生止损 止赢或者拆单的时机自动修改这里的内容。既然订单发生止损 止赢或者拆单的时机自动修改这里的内容。那我可以在下单的时机给comment赋值”on”,当订单生成后我可以用OrderComment()函数实时获取它的comment值假使不等于”on”那就表明订单已经止损或止赢了。MacdCurrent=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_MAIN,0);这句中你NULL是空货币吗?0代表0M吗?NULL和0有具体意思吗?我们自己用的时机需要具体化吧?A:Null表明目前图形上的货币牛版只回答了NULL,那0呢,是不是也代表目前目前时段呢!呵呵!给我留作业了吧!华丽的分割线2=======================================================EA的基本框架/+------------------------------------------------------------------+//| Designed by bull, China |//| Copyright 2007, bull |//| bbs.520fx.com |//+------------------------------------------------------------------+#property copyright "Copyright 2007 , bull, China."#property link "bbs.520fx.com"#define MAGICMA//+------------------------------------------------------------------+//| 注意没有指标文件那些property |//+------------------------------------------------------------------+extern int whichmethod = 1; //1~4 种下单方式 1 仅开仓, 2 有止损无止赢, 3 有止赢无止损, 4 有止赢也有止损extern double TakeProfit = 100; //止赢点数extern double StopLoss = 20; //止损点数extern double MaximumRisk = 0.3; //资金控制,控制下单量extern double TrailingStop =25; //追踪止赢点数设置extern int maxOpen = 3; //最多开仓次数制约extern int maxLots = 5; //最多单仓持仓量制约extern int bb = 0; //非零就允许追踪止赢extern double MATrendPeriod=26;//运用26均线 开仓条件参数 本例子int i, p2, xxx,p1, res;double Lots;datetime lasttime; //时间控制, 仅当一个时间周期完成才检查条件int init() //初始化{Lots = 1;lasttime = NULL;return(0);}int deinit() { return(0);} //反初始化//主程序int start(){CheckForOpen();//开仓 平仓 条件检查 和操作if (bb>0) CTP();//追踪止赢return(0);}//+------下面是各子程序--------------------------------------------+double LotsOptimized() //确定下单量,开仓调用 资金控制{double lot=Lots;int orders=HistoryTotal();// history orders totalint losses=0; // number of losses orders without a break//MarketInfo(Symbol(),MODE_MINLOT);有关信息//MarketInfo(Symbol(),MODE_MAXLOT);//MarketInfo(Symbol(),MODE_LOTSTEP);lot=NormalizeDouble(MaximumRisk * AccountBalance()/AccountLeverage(),1);//开仓量计算if(lot<0.1) lot=0.1;if(lot>maxLots) lot=maxLots;return(lot);}//平仓持有的买单void CloseBuy(){if (OrdersTotal( ) > 0 ){for(i=OrdersTotal()-1;i>=0;i--){if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;if(OrderType()==OP_BUY){OrderClose(OrderTicket(),OrderLots(),Bid,3,White);Sleep(5000);}}}}//平仓持有的卖单void CloseSell(){if (OrdersTotal( ) > 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,PR洲际交易所_CLOSE,MODE_MAIN,0);MacdPrevious=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_MAIN,1);SignalCurrent=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_SIGNAL,0);SignalPrevious=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_SIGNAL,1);MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PR洲际交易所_CLOSE,0);MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PR洲际交易所_CLOSE,1);if(MacdCurrent<0 & MacdCurrent>SignalCurrent && MacdPrevious& MaCurrent>MaPrevious)return (1);// 买 Ma在上升,Macd在0线上,而且两线上交叉if(MacdCurrent>0 & MacdCurrentSignalPrevious& MaCurrentreturn (-1);// 卖return (0);//不交易}int nowbuyorsell = 0;void CheckForOpen(){if (Time[0] == lasttime ) return; //每时间周期检查一次 时间控制lasttime = Time[0];nowbuyorsell = buyorsell();//获取买卖信号if (nowbuyorsell == 1) //买 先终结已卖的CloseSell();if (nowbuyorsell == -1) //卖 先终结已买的CloseBuy();if (TimeDayOfWeek(CurTime()) == 1){if (TimeHour(CurTime()) < 3 ) return; //星期一早8点前不做 具体决定于你的时区和服务器的时区 时间控制}if (TimeDayOfWeek(CurTime()) == 5){if (TimeHour(CurTime()) > 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 <=0){error=GetLastError();if(error==134)Print("Received 134 Error after OrderSend() !! ");// not enough moneyif(error==135) RefreshRates();// prices have changed}Sleep(5000);return ;}if (nowbuyorsell == -1) //卖{switch (whichmethod){case 1: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);break;case 2: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,0,"",MAGICMA,0,Red);break;case 3: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,Bid-TakeProfit*Point,"",MAGICMA,0,Red);break;case 4: res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGICMA,0,Red);break;default : res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);break;}if (res <=0){error=GetLastError();if(error==134) Print("Received 134 Error after OrderSend() !! ");// not enough moneyif(error==135) RefreshRates();// prices have changed}Sleep(5000);return ;}}void CTP() //追踪止赢{bool bs = false;for (int i = 0; i < OrdersTotal();i++){if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;if (OrderType() == OP_BUY){if ((Bid - OrderOpenPrice()) > (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))) //开仓价格 目前止损和目前价格比较分析能否要修改追踪止赢设置{if (OrderStopLoss() < Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)){bs = OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Green);}}}else if (OrderType() == OP_SELL){if ((OrderOpenPrice() - Ask) > (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<100){Print("bars less than 100");return(0);}以上是说假使目前图形的K线个数少于100 则不执行运算 直接返回。该种情形一般不会显现,所以我们自己写程序的时机可以不写这部分。if(TakeProfit<10){Print("TakeProfit less than 10");return(0);// check TakeProfit}以上这段意思是参数TakeProfit移动止损点数的设定假使差于10点,则发出报警,并返回不执行运算。这是为了防止乱设数值,引起后面计算的错误。这部分,假使程序导致我们自己运用,预期不会犯该种低级错误,所以写程序的时机也可以忽视不写。下面这段:MacdCurrent=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_MAIN,0);MacdPrevious=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_MAIN,1);SignalCurrent=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_SIGNAL,0);SignalPrevious=iMACD(NULL,0,12,26,9,PR洲际交易所_CLOSE,MODE_SIGNAL,1);MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PR洲际交易所_CLOSE,0);MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PR洲际交易所_CLOSE,1);这部分是变量赋值部分,等于提早计算出为后面用到的目前MACD数值以及MA数值,如此提早写出来在后面直接运用赋值后的变量就很清楚了。是很好的编程习惯。再下面开始最首要的程序逻辑部分,首先遇到的就是我们上面说过的通过仓位函数得到目前状态的部分。total=OrdersTotal();通过函数得到目前持仓单的个数,假使持仓单个数差于1,则表明是空仓状态,那末就执行多头和空头的入场条件分析,假使满足条件则执行入场。代码如下:if(total<1){// no opened orders identifiedif(AccountFreeMargin()<(1000*Lots)) 这句诗分析保证金余量能否够下单,假使不够则直接返回,并没有执行后续入场分析{Print("We have no money. Free Margin = ", AccountFreeMargin());return(0);}// check for long position (BUY) possibilityif(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPreviousMathAbs(MacdCurrent)>(MACDOpenLevel*Point) && MaCurrent>MaPrevious) 这句就是多头入场条件的分析,可以目睹2个技巧,1、交叉的数学意思是“前面再下后面在上”或反之 2、MA往上趋势 的数学意思是目前K线的MA大于上一K线的MA数值{ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd sample",16384,0,Green);这是入场语句记得一定要分析入场能否成功,由于很多服务器受于滑点或者服务器价格变动而不能入场成功,所以,要分析入场不成功后做出提示。ticket就是定单入场能否成功的标记。if(ticket>0) 大于0表明入场成功{if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());}else Print("Error opening BUY order : ",GetLastError());入场不成功,输出不成功的系统原因。return(0);这里为何运用了返回呢。由于一种情形是入场成功,那末直接返回等候下一个价格来临的时机再实施start函数,其他情形是入场不成功,则返回也是等候下一个价格来临的时机在此实施入场操作。}下面就是空单入场的分析了,大家自己对照观看即可// check for short position (SELL) possibilityif(MacdCurrent>0 && MacdCurrentSignalPrevious &&MacdCurrent>(MACDOpenLevel*Point) && MaCurrent{ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd sample",16384,0,Red);if(ticket>0){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();//通过自定义函数得到目前持仓单的交易类型 买 卖//自定义函数中做了处理,假使没有发现目前有持仓 则返回-1if (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<0){Print("多单入场失利"+GetLastError());return(0);//推出此次start函数的实施}}elseif (TradeOrNo(2))//空单入场条件{Ticket=OrderSend(Symbol(),OP_SELL,每单手数,Bid,滑点偏移点数,Bid+SL*Point,0,"",Magic,0,0);if(Ticket<0){Print("空单入场失利"+GetLastError());return(0);}}return;}else//===============持仓阶段==========================={switch(OrderTypeNow){case OP_BUY://多单持仓情形下,满足空单入场条件if (TradeOrNo(2)){if(OrderClose(Tick,OrderLots(),Bid,滑点偏移点数)==false)//平掉多单持仓单{Print("翻转发生 多头平仓失利"+GetLastError());return;}else//平仓后,反手建立空单{Ticket=OrderSend(Symbol(),OP_SELL,每单手数,Bid,滑点偏移点数,Bid+SL*Point,0,"",Magic,0,0);if(Ticket<0){Print("空单反手建仓失利"+GetLastError());return(0);}}}else //分析移动止损{if (Ask>StopLost+2*TrailingStop*Point){OrderModify(Tick,OrderOpenPrice(),StopLost+TrailingStop*Point,0,0,CLR_NONE);return;}}break;case OP_SELL:if (TradeOrNo(1)){if(OrderClose(Tick,OrderLots(),Ask,滑点偏移点数)==false)//平掉空单持仓单{Print("翻转发生 空头平仓失利"+GetLastError());return;}else//平仓后,反手建立多单{Ticket=OrderSend(Symbol(),OP_BUY,每单手数,Ask,滑点偏移点数,Ask-SL*Point,0,"",Magic,0,0);if(Ticket<0){Print("多单反手建仓失利"+GetLastError());return(0);}}}else //分析移动止损{if (Bid{OrderModify(Tick,OrderOpenPrice(),StopLost-TrailingStop*Point,0,0,CLR_NONE);return;}}break;}return;}return(-1);}//=================自定义函数部分======================================int GetOrderTypeHolding()//从近期持仓单提取订单类型,假使没有持仓单,则觉得是止赢出场或程序刚开始运行返回-1{int Type=-1;//int temptime=0;for(int i=OrdersTotal()-1;i>=0;i--){OrderSelect(i, SELECT_BY_POS, MODE_TRADES);if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic ){Type=OrderType();Tick=OrderTicket();StopLost=OrderStopLoss();}}return(Type);}//======================================================bool TradeOrNo(int Type)//分析目前指定方向的入场条件能否成立{double NHigh=High[iHighest(Symbol(),0,MODE_HIGH,N,2)];double NLow=Low[iLowest(Symbol(),0,MODE_LOW,N,2)];switch(Type){case 1://分析多单入场条件能否成立if (Close[1]>NHigh)//做多条件成立{return(true);}break;case 2:if (Close[1]{return(true);}break;}return(false);}