首页学院交易策略EA智能交易文章详细

MT4自带EA:Moving Average详解与实战分析

外汇网2021-06-17 09:41:07 413
汇外网 - 全球专业的黄金外汇门户导航行情资讯网站

一、均线穿越交易系统EA详解

MT4平台自带了一个自动交易的EA指标,那就是Moving Average ,下面详细解释该系统每条语句的功能表明,以便深入认识EA的编程内核。

//+-----------------------------------------------------------------------------+

//| Moving Average.mq4 |

//| Copyright 2005-2014, MetaQuotes Software Corp. |

//| http://www.mql4.com|

//+-----------------------------------------------------------------------------+

#property copyright "2005-2014, MetaQuotes Software Corp."

#property link "http://www.mql4.com"

#property description "Moving Average sample expert advisor"

#define MAGICMA 20131111

// 宏定义命令#define用法,定义本EA操作的订单的唯一标识号码,自此可以达到在与一账户上多系统操作,各操作EA的订单标识码不同,就不会互相误操作。凡是EA皆不可缺少,非常非常重要!

//--- Inputs

input double Lots =0.1; // 每单的交易量

input double MaximumRisk =0.02; // 本系统最大风险系数,即可以动用总资金的2%

input double DecreaseFactor=3; // 下挫因子

input int MovingPeriod =12; // 均线的计算周期=12,为MA务必的参数之一

input int MovingShift =6; // 均线转移量=6,为MA务必的参数之一

// input 确定从外部程序输入的变量, 会直接显现输入报告窗口。数列自身不能作为外部变量。

注意:iMA中的MovingShift(均线偏移量)是指均线指标在图上绘制时向左、右移动的K线个数,首要为了使图中结果更好看,并没有将对MA的计算数值造成改变。其中,该参数为正时,代表向右移动;为负数,则代表向左移动。

//+------------------------------------------------------------------+

//| Calculate open positions |

//| 自定义函数(返回-整数型报告) 仓单查询与统计 |

//+------------------------------------------------------------------+

int CalculateCurrentOrders(string symbol) // 函数作用:计算目前持仓单的数量

{

int buys=0,sells=0;

// 定义两个局部变量,整数型,buys——多单数,sells——空单数,用于订单的统计

//----

for(int i=0;i

i++) // 计次循环(i=0至订单数目,i=i+1)- 循环检测目前的订单队列

{

if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; // 假使 没有本系统交易的仓单类型,则跳出循环

if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA) //假使持仓单货币对是目前货币对 且持仓单编号是本系统编号时分析这个订单是不是目前EA操作的,避免EA误操作其余程序控制的持仓单。

{

if(OrderType()==OP_BUY) buys++; // 假使 仓单类型=多单,则:在多单数上加1;

if(OrderType()==OP_SELL) sells++; // 假使 仓单类型=空单,则,在空单数上加1。

}

}

// ---- return orders volume-返回订单数目

if(buys>0) return(buys);

// 假使 多单>0,则返回(多单数)

else return(-sells);

// 否则,返回(-空单数)

// 本函数返回查询计算终结时的持仓单的个数,该种模式返回是如果不存在锁单的。

}

//+------------------------------------------------------------------+

//|Calculate optimal lot size |

//|自定义函数(返回-小数型报告) 资金管理 |

//+------------------------------------------------------------------+

double LotsOptimized() //开仓量计算函数(依据要求计算出订单交易量,小数型)

{

double lot=Lots; // 定义局部变量los 小数型

int orders=HistoryTotal();

// history orders total 历史平仓单数(已平仓)

int losses=0; // number of losses orders without a break-亏损单

//---- select lot size

lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);

//计算 开仓下单量=帐户可用资金*最大风险系数(=2%)/1000.0,并将结果保留小数点1名

(通过风险系数的计算得到目前入场单应当采取的交易量,除以1000是由于大多货币对汇率价格都在这个附近。)

//---- calcuulate number of losses orders without a break-计算亏损单数目

if(DecreaseFactor>0) // 假使 下挫因子(=3)>0

{

for(int i=orders-1;i>=0;i--) // 计次循环(i=历史平仓单数-1,到i=0, 递减1)

{

if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)

{

Print("Error in history!");

break;

}

// 假使 没有本系统交易记录,输出“无交易历史!”

if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; // 假使 订单的货币对不是目前货币对,或者 订单类型为挂单时,继续运行

// 订单类型为整数型,0-BUY,1-SELL,2-BUYLIMT,3-BUYSTOP,4-SELLLIMT,5-SELLSTOP,其中“>OP_SELL”代表挂单

if(OrderProfit()>0) break; // 假使 盈利单数目>0,跳出循环

if(OrderProfit()<0) losses++;// 假使 盈利单数目<0,则在:亏损单数上加1

}

if(losses>1)

lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);

// 假使 亏损单数>1时,则从新计算下单量,并保留小数点后1名,其计算公式为:下单量=(lot-lot*losses/DecreaseFactor(=3))。

}

//---- return lot size-返回下单量

if(lot<0.1) lot=0.1; // 假使 算出的交易量差于0.1手,则 取交易量为0.1手

return(lot);

// 返回(下单量)

}

//+------------------------------------------------------------------+

//| Check for open order conditions |

//| 自定义函数(无返回值) 开仓策略 |

//+------------------------------------------------------------------+

void CheckForOpen() // 开仓检查(分析开仓条件及其处理)

{

double ma; // 定义局部变量ma为小数型

int res; // 定义局部变量res为整数型

//---- go trading only for first tiks of new bar ---- 只有在新K线的第一次报价时实施

if(Volume[0]>1) return;

// 假使目前K线的成交价次数大于1时,返回

(不是K线的开盘时间点,即目前k线还没收盘确定,则直接返回;否则,假使是K线第一个成交价,则朝下继续运行)

// ---- get Moving Average – 获取均线数值

ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PR洲际交易所_CLOSE,0);

// 获取目前以收盘价为基准计算出的均线数值

iMA(NULL,0,12,6,MOD_SMA,PR洲际交易所_CLOSE,0)

// ---- sell conditions-出售条件

if(Open[1]>ma && Close[1]

{

res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red);

// 发送仓单(目前货币对,出售方向,开仓量计算(),买价,滑点=3,无止损,无止赢,订单编号,标上红色箭头)

return; // 返回

}

// ---- buy conditions - 购入条件

if(Open[1]ma) // 假使前1根K线上穿均线(即K线的开盘价差于均线值、收盘价大于均线值)

{

res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);

// 发送仓单(目前货币对,购入方向,开仓量计算(),卖价,滑点=3,无止损,无止赢,订单编号,标上蓝色箭头)

return; // 返回

}

//----

}

//+------------------------------------------------------------------+

//| Check for close order conditions |

//| 自定义函数(无返回值) 平仓策略 |

//+------------------------------------------------------------------+

void CheckForClose() // 平仓检查(分析平仓条件及其处理)

{

double ma; // 定义局部变量ma小数型

//---- 只在一个k收盘其他新显现时交易

if(Volume[0]>1) return; // 假使目前K线的成交价次数>1时,则返回

//---- get Moving Average // 获取均线数值

ma=iMA(NULL,0,MovingPeriod,MovingShift,MODE_SMA,PR洲际交易所_CLOSE,0);

// 获取目前以收盘价为基准计算出的均线数值

for(int i=0;i

i++) // 计次循环(变量i=1至定单总数,每次递增1)

{

if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break; // 假使 没有本系统所交易的仓单时,跳出循环

if(OrderMagicNumber()!=MAGICMA || OrderSymbol()!=Symbol()) continue;

// 假使 仓单编号不是本系统编号,或者 仓单货币对不是目前货币对时,继续选择

if(OrderType()==OP_BUY) // 假使是多单

{

if(Open[1]>ma && Close[1]

{

if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,White));

// 假使第1根K线开盘价下穿均线(即开盘价好于均价而收盘价差于均价),则执行多头平仓(仓单编号,持仓数量,买价,滑点=3,用白色箭头表明)

Print("OrderClose error ",GetLastError());

}

break; // 跳出循环

}

if(OrderType()==OP_SELL) // 假使是空单

{

if(Open[1]ma)

{

if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,White))

// 假使第1根K线开盘价上穿均线(即开盘价差于均价而收盘价好于均价),则执行空头平仓(仓单编号,持仓数量,卖价,滑点=3,用白色箭头表明)

Print("OrderClose error ",GetLastError());

}

break; // 跳出循环

}

}

//----

}

//+------------------------------------------------------------------+

//|OnTick function |

//+------------------------------------------------------------------+

void OnTick() //主程序—-每次成交价所驱使的运算过程

{

//--- check for history and trading 对交易历史执行检查

if(Bars<100 || IsTradeAllowed()==false)

return;

// 假使K线数少于100根,或者假使允许智能交易交易=假时,返回

//--- calculate open orders by current symbol 计算目前货币对的开仓订单

if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();

// 假使 计算出目前货币对开仓订单数=0 (即没有仓单),则执行开仓检查。

else CheckForClose();

// 否则(即目前已经有仓单时),则执行平仓检查。

//---

}

//+------------------------------------------------------------------+

二、本EA策略分析

依据本EA系统的源代码可以分析出:它运用的策略如下:

1、技术指标:12期均线系统;

2、滑点数:3个点;

3、开平仓法则:K线上穿均线时,无持仓单,则开多单;有空单时,则平空单;

K线下穿均线时,无持仓单,则开空单;有多单时,则平多单。

4、图上标识:开多仓时,在图中标示红色箭头;平仓时,则标示白色箭头;

开空仓时,在图中标未蓝色箭头;平仓时,则标示白色箭头。

三、该系统在模拟交易中的结果分析

以上对该EA系统执行了详细的解析,从中可以看出EA系统的基本结构与有关策略。下面是该EA在模拟盘中1分钟K线图欧元兑美元(欧元对美元)中的开仓、平仓结果图。在该系统的模拟交易过程中,差不多体现了本策略的操作思想,其中四个下单中,两个空单和两个多单,如下图所示。

标签:

随机快审展示
加入快审,优先展示

加入VIP