1、MT4 自带的 EA :Moving Average 详解 /+-+/| Moving Average.mq4 |/| Copyright ?2005, MetaQuotes Software Corp. |/| http:/ |/+-+#define MAGICMA 20050610 /定义本 EA 操作的订单的唯一标识号码,由此可以实现在同一账户上多系统操作,各操作 EA 的订单标识码不同,就不会互相误操作。凡是 EA 皆不可缺少,非常非常重要!/宏定义命令#define 用法http:/ double Lots = 0.1;/每单的交易量extern double MaximumRisk
2、 = 0.02;/本系统最大可以动用总资金的 2%extern double DecreaseFactor = 3;/作者定义的参数,作用要看程序中的用法extern double MovingPeriod = 10;/EA 中使用的均线的周期extern double MovingShift =3;/EA 中使用的均线向左的 K 线偏移量/extern 确定从外部程序输入的变量, 会直接显现输入数据窗口。数列本身不能作为外部变量。/+-+/| Calculate open positions |/+-+int CalculateCurrentOrders(string symbol)/函数作
3、用,计算当前持仓订单的数量int buys=0,sells=0;/定义两个临时变量,准备用于后面的多空订单的个数计算/-for(int i=0;i0) return(buys);else return(-sells);/本函数返回查询计算结束时的持仓单的个数.这种模式返回是假设不存在锁单的。/+-+/| Calculate optimal lot size |/+-+double LotsOptimized()/函数目的,根据要求 计算出订单交易量double lot=Lots;int orders=HistoryTotal(); / history orders total 历史出场订单的个
4、数int losses=0; / number of losses orders without a break/- select lot sizelot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);/通过风险系数的计算获得当前入场单应该采用的交易量,除以 1000 是因为大多货币对汇价都在这个附近。/- calcuulate number of losses orders without a breakif(DecreaseFactor0)for(int i=orders-1;i=0;i-)if(OrderSelect(
5、i,SELECT_BY_POS,MODE_HISTORY)=false) Print(“Error in history!“); break; /循环查询出场单队列if(OrderSymbol()!=Symbol() | OrderType()OP_SELL) continue;/-if(OrderProfit()0) break;if(OrderProfit()1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);/如果亏损额大于 1,则下一入场单的交易量修正为新的计算结果。/- return lot sizeif(lot1) ret
6、urn;/如果当前 K 线持仓量(成交量)大于 1,说明不是 K 线的开盘时间点,即当前 k 线还没收盘确定,则直接返回 否则是 K 线第一个价格,则继续下面的过程/- get Moving Average ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);/获得当前的均线数值/- sell conditionsif(Open1ma return;/-/+-+/| Check for close order conditions |/+-+void CheckForClose()/检查出场条件的情况并作处理double
7、 ma;/- 只在一个 k 收盘另一个新出现时交易if(Volume01) return;/- get Moving Average ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE,0);/-for(int i=0;ima );/如果持仓是空单,则当当前 K 开盘价大于均线,而前一 K 收盘价小于均线,则发出平仓指令break;/-/+-+/| Start function |/+-+void start()/主循环过程/- check for history and tradingif(BarsSignalCurrent
8、 这是入场语句 记得一定要判断入场是否成功,因为很多服务器由于滑点或者服务器价格变动而不能入场成功,所以,要判断入场不成功后作出提示。ticket就是定单入场是否成功的标记。if(ticket0) 大于 0 说明入场成功if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) Print(“BUY order opened : “,OrderOpenPrice();else Print(“Error opening BUY order : “,GetLastError(); 入场不成功,输出不成功的系统原因。return(0); 这里为什麽使用了返
9、回呢。因为一种情况是入场成功,那末直接返回等待下一个价格到来的时候再执行 start 函数,另一种情况是入场不成功,则返回也是等待下一个价格到来的时候在此执行入场操作。下面就是空单入场的判断了,大家自己对照观看即可/ check for short position (SELL) possibilityif(MacdCurrent0 else Print(“Error opening SELL order : “,GetLastError(); return(0); return(0);MT4 自带 EA:MACD Sample 详解-2002 步骤 3 集中程序的结果代码让我们打开智能交易的
10、设定:使用按钮打开”属性”菜单。在窗口内指定运行参量的外部设定:从先前部分集中全部代码:/+-+/| MACD Sample.mq4 |/| Copyright 2005, MetaQuotes Software Corp. |/| http:/ |/+-+extern double TakeProfit = 50;extern double Lots = 0.1;extern double TrailingStop = 30;extern double MACDOpenLevel=3;extern double MACDCloseLevel=2;extern double MATrendPe
11、riod=26;/+-+/| |/+-+int start() double MacdCurrent, MacdPrevious, SignalCurrent; double SignalPrevious, MaCurrent, MaPrevious; int cnt, ticket, total;/ 检测初始化数据 / 确定智能交易在图表中运行正常非常重要/ 用户在外部变量交易中不会产生任何错误/ 外部变量 (标准手数, 止损 ,赢利, / 追踪止损) 在这种情况下,我们检测图表中赢利水平要小于 100 柱 if(BarsSignalCurrent if(ticket0) if(OrderS
12、elect(ticket,SELECT_BY_TICKET,MODE_TRADES) Print(“BUY 定单开仓 : “,OrderOpenPrice(); else Print(“错误 BUY 定单开仓 : “,GetLastError(); return(0); / 尽可能检测卖空仓位(SELL) if(MacdCurrent0 else Print(“错误 SELL 定单开仓 : “,GetLastError(); return(0); return(0); / 正确进入市场很重要, / 但正确退出市场更重要. for(cnt=0;cnt0 /平仓 return(0); / 退出 /
13、 检测追踪止损 if(TrailingStop0) if(Bid-OrderOpenPrice()Point*TrailingStop) if(OrderStopLoss()SignalCurrent / 平仓 return(0); /退出 / 检测追踪止损 if(TrailingStop0) if(OrderOpenPrice()-Ask)(Point*TrailingStop) if(OrderStopLoss()(Ask+Point*TrailingStop) | (OrderStopLoss()=0) OrderModify(OrderTicket(),OrderOpenPrice()
14、,Ask+Point*TrailingStop,OrderTakeProfit(),0,Red); return(0); return(0); / 结束对于最后智能交易的确认,只需要指定外部变量值 “Lots = 1, “Stop Loss (S/L) = 0 (not used), “Take Profit (T/P) = 120 (appropriate for one-hour intervals), “Trailing Stop (T/S) = 30. 当然,你可以使用自己的值。按 “编写”按钮,如果没有任何错误信息出现 (你可以从 MetaEditor 的列表中复制), 按 “保存”
15、键保存智能交易。MT4 编程:自带的 DLL 范例 俺不是编程高手,而且时间和精力都很有限,因此编程对于我来说最理想的境界是“知其然“ ,而不必“知其所以然“。当然,如果程序出错,那就要好好研究一下“ 其所以然“了。所以每次编程都会经历一个预热的学习过程,看看范例- 然后温故而知新MT4 自带的DLL 范例,就放在在文件夹 MetaTrader 4EXPERTSSAMPLES 中。该范例值得细细研究,是因为它展示了如何使用 mq4 语言来调用 C+语言编写的 DLL。而我们需要重点留意的,就是调用 DLL 函数时所展现的函数参数的传递方式;显然,针对不同类型的变量,都有其不同的传递方式,实现的
16、结果亦各不相同。1)变量传递。对于 mq4 的 double/int 类型变量,与 C+的通讯只需要用到值传递。在 C+里我们要定义一个函数,如 func1(double x,int y);mq4 里我们必须在头文件里做一个函数声明:func1(double,int),调用的时候以相应的变量值作为参数,如 func1(10.56,8)。对于 mq4 的 String 类型,在 C+里可以用指针如 char *str 来代替 String 类型。在 C+里我们要定义一个函数,如 func2(char *str);mq4 里我们必须在头文件里做一个函数声明:func2(string),调用的时候以
17、字符串作为参数,如 func2(“something“)。2)数组的传递。对于 mq4 的 double/int 类型数组,C+通过指针来接收相应的参数。关于数组与指针,在网上查阅了很多论述:其实,在 C+中数据名作为函数形参时,等同于指向数组的指针!于是,下面 2 个函数是等效的:double sample1(double*); /在声明中,描述参数为(指向数组的)指针:double*;double sample1(double aa) /在函数中,以 aa(数组)来接收该指针。aa4=55.5;return(aa4);double sample2(double ); /在声明中,描述参数为
18、数组:double ;double sample2(double *aa) /在函数中,以*aa(指针)来接收该数组。aa4=55.5;return(aa4);当然,2 个函数的声明其实也是等效的。 mq4 中没有指针类型,所以传递数组的方式类似 sample2。3)行情数据的传递mq4 提供了 ArrayCopyRates 函数,用于复制一段走势图上的数据到一个二维数组,并返回复制柱子的总数。其第二维为固定的 6 个项目,从 0 到 5 分别为“时间、开盘价格、最低价格、最高价格、收盘价格、成交量” 。 如:double rates6;int totalRecords = ArrayCopy
19、Rates(rates,Symbol(),0);mq4 调用 DLL 函数的时候,把该数组作为参数,向 DLL 函数提供二维数组的指针,这也就是就 mq4 程序实现行情数据传递的默认方式。如:ArrayCopyRates(rates);price=GetRatesItemValue(rates,Bars,0,CLOSE_INDEX);对应地,我们在 C+代码中可以定义一个结构类型 RateInfo:struct RateInfo unsigned int time; /时间double open; /开盘价格double low; /最低价格double high; /最高价格double c
20、lose; /收盘价格double volume; /成交量;这里的 RateInfo 结构定义正好对应 mq4 里二维数组的第二维,在 DLL 函数里,结构指针 RateInfo*被映射为二维数组 double rates6。也就是说,当 mq4 调用 DLL 的时候,由操作系统根据内存指针完成了数据的访问,且结构定义中的 unsigned int 是从 double 类型转换后得到的。需要注意的是:mq4 数组顺序与 DLL 数组顺序完全相反。mq4 数组顺序是:从 Bars-1到 0;而传递到 DLL 后,数组顺序变为 0 到 Bars-1?MT4 自带 EA:MACD Sample 详
21、解-2001 MetaQuotes 语言 4 是需要“外部变量”辅助的。外部变量可以从外部设定,在智能交易程序源代码设定之后不可以修改。提供一个额外的灵活性。在我们的程序中,MATrendPeriod 变量作为外部变量指定。 在程序开始我们插入这个变量。 检测初始数据该代码部分通常使用在所有的智能交易中。因为是一个标准的检测: / 初始数据检测/ 确认智能交易运行正常非常重要/ 图表和用户设置不能出现任何错误 / 变量 (Lots, StopLoss, TakeProfit, / TrailingStop) 我们的情况需要检测 TakeProfit/ 图表中少于 100 柱 if(BarsSi
22、gnalCurrent if(ticket0) if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) Print(“BUY 开单 : “,OrderOpenPrice(); else Print(“错误 opening BUY order : “,GetLastError(); return(0); 附加的检验山丘的大小上面已经给出了描述。 MACDOpenLevel 变量是一个用户指定变量,它不可能改变程序文本,但是却有很大的灵活性。在程序开始我们插入这个变量的描述。可能是卖空仓位(SELL)?进入卖空仓位的条件: MACD 高于零,向上并且
23、穿过信号线向下。注解如下 : / 尽可能的检测卖空仓位(SELL) if(MacdCurrent0 if(ticket0) if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES) Print(“SELL 开单 : “,OrderOpenPrice(); else Print(“错误 SELL 定单开仓 : “,GetLastError(); return(0); return(0); 周期循环检验先前开仓 /进入市场的正确性非常重要 / 但是更重要的是安全退出 . for(cnt=0;cnt OrderSelect(cnt, SELECT_BY_
24、POS, MODE_TRADES); if(OrderType()0 /平仓 return(0); /退出 应该重设追踪止损马?我们设定追踪止损只有在仓位盈利已经超过追踪水平点,并且新的止损水平点好于先前的水平。 / 检测追踪止损 if(TrailingStop0) if(Bid-OrderOpenPrice()Point*TrailingStop) if(OrderStopLoss() OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop, OrderTakeProfit(),0,Green); return(0)
25、; 我们停止操作符。如果是卖空仓位 else /卖空仓位 应该平仓吗?退出卖空仓位的条件: MACD 穿过信号线,MACD 低于零,向上并且穿过信号线向下。 if(MacdCurrentSignalCurrent /平仓 return(0); / 退出 应该重设追踪止损吗?我们设定追踪止损只有在仓位盈利已经超过追踪水平点,并且新的止损水平点好于先前的水平。 / 检测追踪止损 if(TrailingStop0) if(OrderOpenPrice()-Ask)(Point*TrailingStop) if(OrderStopLoss()(Ask+Point*TrailingStop) | (Or
26、derStopLoss()=0) OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop, OrderTakeProfit(),0,Red); return(0); 关闭所有残留开仓。 return(0);编制自动交易系统的基本知识(2012-02-12 12:16:04) 分类: MT4 编程入门 编制自动交易系统的基本知识Introduction 介绍鉴于许多中国的交易者对交易系统了解不多,本文解释使用 MQ4 语言编制自动交易系统的基本知识.Title 编制自动交易系统的基本知识一个交易系统大致包括以下几个方面:
27、1 开仓策略,即什么条件满足时开仓, 如某条线和某条线上交叉或下交叉,2 平仓策略,即什么条件满足时平仓, 包括止赢设置,止损设置,和跟踪止赢设置三个方面.3 资金管理, 其中一个方面就是下单的大小4 时间管理, 如持仓时间,开平仓时间间隔等5 账户状态分析,如交易历史,当前资金/仓位/各仓为盈亏状态等.当然一个交易系统不必包括全部内容,本文做为入门知识也仅通过实例介绍交易系统程序的基本构成./#property copyright “Copyright 2007 , Dxd, China.“#define MAGICMA 200610011231/+-+/| 注意没有指标文件那些 prope
28、rty |/+-+extern int whichmethod = 1; /14 种下单方式 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; /最多单
29、仓持仓量限制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 (bb0) CTP()
30、; /跟踪止赢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=
31、NormalizeDouble(MaximumRisk * AccountBalance()/AccountLeverage(),1); /开仓量计算if(lotmaxLots) 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(),OrderLo
32、ts(),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() /在这个函数计算设置你的交易信号 这里使用 MAC
33、D 和 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=iMA
34、CD(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 / 买 Ma 在上升,Macd 在 0 线上,并且两线上交叉if(MacdCurrent0 /周五晚 11 点后不做if (OrdersTotal( ) = maxOpen) return ; /如果已持有开
35、仓次数达到最大,不做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*Poin
36、t,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,
37、LotsOptimized(),Ask,3,0,0,“,MAGICMA,0,Blue);break;if (res (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT) /开仓价格 当前止损和当前价格比较判断是否要修改跟踪止赢设置if (OrderStopLoss() (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT) /开仓价格当前止损和当前价格比较判断是否要修改跟踪止赢设置if (OrderStopLoss() (Ask + TrailingStop * MarketInfo(Or
38、derSymbol(), MODE_POINT) bs = OrderModify(OrderTicket(), OrderOpenPrice(),Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Tan);EA 框架模型,大部分地方做了注释现在我学会了 EA 基本的东西,并且按照框架思路 建立了 EA 框架模型,大部分地方做了注释。希望对大家有用;程序代码如下:/+-+/| ganendexins 模板.mq4 |/| Copyright ?2008, MetaQuotes Sof
39、tware Corp. |/| http:/ copyright “ganendexin“#property link “http:/“/- input parametersextern double TakeProfit=250.0;extern double Lots=0.1;extern double TrailingStop=35.0;/+-+/| expert initialization function |/+-+int init()/- /-return(0);/+-+/| expert deinitialization function |/+-+int deinit()/-
40、 /-return(0);/信号部分,下面这部分给出的是买卖信号,这个信号可以是自己编写的,也可以是用iCustom 来调用的。以后需要修改的大部分是在这里面改int Crossed (double line1 , double line2)static int last_direction = 0;static int current_direction = 0;if(line1line2)current_direction = 1; /upif(line10)/检查是否已经成交,重点是检查不是挂单 注意参数 MODE_TRADESif(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)/打印出开仓价格Print(“已 BUY,价格为: “,OrderOpenPrice();/如果建仓失败,打印出错误提示else Print(“建 BUY 仓失败: “,GetLastError(); /建仓失败后,立即返回,并进行一下次的计算 return(0);/如果卖单信号出现 ,注意,此时仍然是指在空仓状态下 if(isCrossed = 2)/建立