//+------------------------------------------------------------------+
//| 双均线交叉EA.mq4|
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#define OP_ALL -1
input ENUM_TIMEFRAMES 指定周期=PERIOD_CURRENT;
input double 开单手数=0.01;
input int 止损点数=0;
input int 止盈点数=0;
input int 开单距离=0; //开单价与均线1最大距离
input int 停止时长=0; //开单后停止时长(小时)
input string text2="------------------------"; //●---------开单规则---------
enum opls
{
单一持仓=0,
多空持仓=1,
};
input opls 持仓规则=多空持仓;
input bool 金叉开多=false;
input bool 死叉开空=false;
input string text3="------------------------"; //●---------平仓规则---------
enum clpl
{
盈利平仓=0,
盈亏都平=1,
};
input clpl 平仓规则=盈亏都平;
input bool 金叉平空=false;
input bool 死叉平多=false;
input string text4="------------------------"; //●---------移动止损设置---------
input int 移动止损启动点数=0;
input int 移动止损点数=0;
input string text0="------------------------"; //●---------均线参数设置---------
input int 均线1时间周期=12;
input int 均线2时间周期=26;
input int 平移=0;
input ENUM_MA_METHOD 移动平均=MODE_EMA;
input ENUM_APPLIED_PRICE 应用于=PRICE_CLOSE;
input string text1="------------------------"; //●---------其他参数设置---------
input string comment ="EA"; //注释
input int magic =210330; //订单识别码magic
int slippage=100;
string globalname;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
if(IsTesting()==true)
{
globalname=IntegerToString(AccountNumber())+Symbol()+"M31W"+IntegerToString(magic)+"test";
}
else
{
globalname=IntegerToString(AccountNumber())+Symbol()+"M31W"+IntegerToString(magic);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
if(IsTesting())
{
GlobalVariablesDeleteAll(globalname);
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
open();
close();
trailingstop();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void open()
{
if(GlobalVariableGet(globalname+"optime1")+停止时长*3600<TimeCurrent())
{
double ma1v0=iMA(NULL,指定周期,均线1时间周期,平移,移动平均,应用于,1);
double ma2v0=iMA(NULL,指定周期,均线2时间周期,平移,移动平均,应用于,1);
double ma1v1=iMA(NULL,指定周期,均线1时间周期,平移,移动平均,应用于,2);
double ma2v1=iMA(NULL,指定周期,均线2时间周期,平移,移动平均,应用于,2);
int btts=orderstotal(OP_BUY);
int stts=orderstotal(OP_SELL);
int atts=orderstotal(OP_ALL);
if(ma1v0>ma2v0 && ma1v1<ma2v1 && ma1v0+开单距离*_Point>Ask && w_open(OP_BUY)==true)
{
if(GlobalVariableGet(globalname+"optime0")!=iTime(NULL,指定周期,0))
{
if(ordersend(OP_BUY,开单手数,止损点数,止盈点数)>0)
{
GlobalVariableSet(globalname+"optime0",iTime(NULL,指定周期,0));
GlobalVariableSet(globalname+"optime1",TimeCurrent());
}
}
}
if(ma1v0<ma2v0 && ma1v1>ma2v1 && ma1v0-开单距离*_Point<Bid && w_open(OP_SELL)==true)
{
if(GlobalVariableGet(globalname+"optime0")!=iTime(NULL,指定周期,0))
{
if(ordersend(OP_SELL,开单手数,止损点数,止盈点数)>0)
{
GlobalVariableSet(globalname+"optime0",iTime(NULL,指定周期,0));
GlobalVariableSet(globalname+"optime1",TimeCurrent());
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool w_open(int type)
{
bool wtop=false;
if(type==OP_BUY)
{
if(金叉开多==true && ((持仓规则==多空持仓 && orderstotal(OP_BUY)==0) || (持仓规则==单一持仓 && orderstotal(OP_ALL)==0)))
{
wtop=true;
}
}
if(type==OP_SELL)
{
if(死叉开空==true && ((持仓规则==多空持仓 && orderstotal(OP_SELL)==0) || (持仓规则==单一持仓 && orderstotal(OP_ALL)==0)))
{
wtop=true;
}
}
return(wtop);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void close()
{
double ma1v0=iMA(NULL,指定周期,均线1时间周期,平移,移动平均,应用于,1);
double ma2v0=iMA(NULL,指定周期,均线2时间周期,平移,移动平均,应用于,1);
double ma1v1=iMA(NULL,指定周期,均线1时间周期,平移,移动平均,应用于,2);
double ma2v1=iMA(NULL,指定周期,均线2时间周期,平移,移动平均,应用于,2);
if(金叉平空==true && ma1v0>ma2v0 && ma1v1<ma2v1 && (平仓规则==盈亏都平 || (平仓规则==盈利平仓 && profit(OP_SELL)>0)))
{
orderclose(OP_SELL);
}
if(死叉平多==true && ma1v0<ma2v0 && ma1v1>ma2v1 && (平仓规则==盈亏都平 || (平仓规则==盈利平仓 && profit(OP_BUY)>0)))
{
orderclose(OP_BUY);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double profit(int type)
{
double profit=0;
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic && OrderType()==type)
{
profit+=OrderProfit();
}
}
}
return(profit);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void trailingstop()
{
if(移动止损启动点数>0)
{
for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic)
{
if(OrderType()==OP_BUY)
{
if(OrderClosePrice()-移动止损启动点数*_Point>=OrderOpenPrice())
{
double nsl=OrderClosePrice()-移动止损点数*_Point;
if(nsl>OrderStopLoss() || OrderStopLoss()==0)
{
bool m=OrderModify(OrderTicket(),OrderOpenPrice(),nsl,OrderTakeProfit(),0,clrNONE);
}
}
}
if(OrderType()==OP_SELL)
{
if(OrderClosePrice()+移动止损启动点数*_Point<=OrderOpenPrice())
{
double nsl=OrderClosePrice()+移动止损点数*_Point;
if(nsl<OrderStopLoss() || OrderStopLoss()==0)
{
bool m=OrderModify(OrderTicket(),OrderOpenPrice(),nsl,OrderTakeProfit(),0,clrNONE);
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| ordersend |
//+------------------------------------------------------------------+
int ordersend(int type,double lots,int slpoint,int tppoint)
{
ResetLastError();
double slprice=0,tpprice=0;
int tkt=-1;
double n=NormalizeDouble(lots/MarketInfo(_Symbol,MODE_MINLOT),0);
lots=MarketInfo(_Symbol,MODE_MINLOT)*n;
if(type==OP_BUY)
{
if(slpoint==0)slprice=0;
if(slpoint>0) slprice=NormalizeDouble(Ask-slpoint*_Point,_Digits);
if(tppoint==0)tpprice=0;
if(tppoint>0) tpprice=NormalizeDouble(Ask+tppoint*_Point,_Digits);
tkt=OrderSend(_Symbol,OP_BUY,lots,Ask,slippage,slprice,tpprice,comment,magic,0,clrRed);
if(tkt<0)
{
cuowu(_Symbol+" 发送订单失败:");
}
else
{
if(OrderSelect(tkt,SELECT_BY_TICKET))
{
double sl=0,tp=0;
if(slpoint>0) sl=NormalizeDouble(OrderOpenPrice()-slpoint*_Point,_Digits);
if(tppoint>0) tp=NormalizeDouble(OrderOpenPrice()+tppoint*_Point,_Digits);
if(OrderStopLoss()!=sl || OrderTakeProfit()!=tp)
{
bool m=OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,clrWhite);
}
}
}
}
if(type==OP_SELL)
{
if(slpoint==0)slprice=0;
if(slpoint>0) slprice=NormalizeDouble(Bid+slpoint*_Point,_Digits);
if(tppoint==0)tpprice=0;
if(tppoint>0) tpprice=NormalizeDouble(Bid-tppoint*_Point,_Digits);
tkt=OrderSend(_Symbol,OP_SELL,lots,Bid,slippage,slprice,tpprice,comment,magic,0,clrGreen);
if(tkt<0)
{
cuowu(_Symbol+" 发送订单失败:");
}
else
{
if(OrderSelect(tkt,SELECT_BY_TICKET))
{
double sl=0,tp=0;
if(slpoint>0) sl=NormalizeDouble(OrderOpenPrice()+slpoint*_Point,_Digits);
if(tppoint>0) tp=NormalizeDouble(OrderOpenPrice()-tppoint*_Point,_Digits);
if(OrderStopLoss()!=sl || OrderTakeProfit()!=tp)
{
bool m=OrderModify(OrderTicket(),OrderOpenPrice(),sl,tp,0,clrWhite);
}
}
}
}
return(tkt);
}
//+------------------------------------------------------------------+
//| orderstotal |
//+------------------------------------------------------------------+
int orderstotal(int type)
{
int a=0;
for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
{
if(OrderType()==OP_BUY && type==OP_BUY)
a++;
if(OrderType()==OP_SELL && type==OP_SELL)
a++;
if(OrderType()<=OP_SELL && type==OP_ALL)
a++;
}
}
}
return(a);
}
//+------------------------------------------------------------------+
//| order close |
//+------------------------------------------------------------------+
void orderclose(int type)
{
ResetLastError();
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==_Symbol && OrderMagicNumber()==magic)
{
if(OrderType()==OP_BUY && type==OP_BUY)
{
if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrWhite))
{
cuowu(IntegerToString(OrderTicket())+" 关闭订单失败:");
}
}
if(OrderType()==OP_SELL && type==OP_SELL)
{
if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrWhite))
{
cuowu(IntegerToString(OrderTicket())+" 关闭订单失败:");
}
}
if(OrderType()<=OP_SELL && type==OP_ALL)
{
if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,clrWhite))
{
cuowu(IntegerToString(OrderTicket())+" 关闭订单失败:");
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void cuowu(string text)
{
int code=GetLastError();
string cuowu;
if(code!=0)
switch(code)
{
case 0 :cuowu=" 错误代码:"+IntegerToString(0)+" 没有错误返回";break;
case 1 :cuowu=" 错误代码:"+IntegerToString(1)+" 没有错误返回但结果不明";break;
case 2 :cuowu=" 错误代码:"+IntegerToString(2)+" 一般错误";break;
case 3 :cuowu=" 错误代码:"+IntegerToString(3)+" 无效交易参量";break;
case 4 :cuowu=" 错误代码:"+IntegerToString(4)+" 交易服务器繁忙";break;
case 5 :cuowu=" 错误代码:"+IntegerToString(5)+" 客户终端旧版本";break;
case 6 :cuowu=" 错误代码:"+IntegerToString(6)+" 没有连接服务器";break;
case 7 :cuowu=" 错误代码:"+IntegerToString(7)+" 没有权限";break;
case 8 :cuowu=" 错误代码:"+IntegerToString(8)+" 请求过于频繁";break;
case 9 :cuowu=" 错误代码:"+IntegerToString(9)+" 交易运行故障";break;
case 64 :cuowu=" 错误代码:"+IntegerToString(64)+" 账户禁止";break;
case 65 :cuowu=" 错误代码:"+IntegerToString(65)+" 无效账户";break;
case 128 :cuowu=" 错误代码:"+IntegerToString(128)+" 交易超时";break;
case 129 :cuowu=" 错误代码:"+IntegerToString(129)+" 无效价格";break;
case 130 :cuowu=" 错误代码:"+IntegerToString(130)+" 参数不符合本品种要求";break;
case 131 :cuowu=" 错误代码:"+IntegerToString(131)+" 无效交易量";break;
case 132 :cuowu=" 错误代码:"+IntegerToString(132)+" 市场关闭";break;
case 133 :cuowu=" 错误代码:"+IntegerToString(133)+" 交易被禁止";break;
case 134 :cuowu=" 错误代码:"+IntegerToString(134)+" 资金不足";break;
case 135 :cuowu=" 错误代码:"+IntegerToString(135)+" 价格改变";break;
case 136 :cuowu=" 错误代码:"+IntegerToString(136)+" 建仓价过期";break;
case 137 :cuowu=" 错误代码:"+IntegerToString(137)+" 经纪繁忙";break;
case 138 :cuowu=" 错误代码:"+IntegerToString(138)+" 重新报价";break;
case 139 :cuowu=" 错误代码:"+IntegerToString(139)+" 订单被锁定";break;
case 140 :cuowu=" 错误代码:"+IntegerToString(140)+" 只允许看涨仓位";break;
case 141 :cuowu=" 错误代码:"+IntegerToString(141)+" 过多请求";break;
case 145 :cuowu=" 错误代码:"+IntegerToString(145)+" 因为过于接近市场,修改否定";break;
case 146 :cuowu=" 错误代码:"+IntegerToString(146)+" 交易文本已满";break;
case 147 :cuowu=" 错误代码:"+IntegerToString(147)+" 时间周期被经纪否定";break;
case 148 :cuowu=" 错误代码:"+IntegerToString(148)+" 开单和挂单总数已被经纪限定";break;
case 149 :cuowu=" 错误代码:"+IntegerToString(149)+" 当对冲备拒绝时,打开相对于现有的一个单置";break;
case 150 :cuowu=" 错误代码:"+IntegerToString(150)+" 把违反FIFO规定的单子平掉";break;
case 4000:cuowu=" 错误代码:"+IntegerToString(4000)+" 没有错误";break;
case 4001:cuowu=" 错误代码:"+IntegerToString(4001)+" 错误函数指示";break;
case 4002:cuowu=" 错误代码:"+IntegerToString(4002)+" 数组索引超出范围";break;
case 4003:cuowu=" 错误代码:"+IntegerToString(4003)+" 对于调用堆栈储存器函数没有足够内存";break;
case 4004:cuowu=" 错误代码:"+IntegerToString(4004)+" 循环堆栈储存器溢出";break;
case 4005:cuowu=" 错误代码:"+IntegerToString(4005)+" 对于堆栈储存器参量没有内存";break;
case 4006:cuowu=" 错误代码:"+IntegerToString(4006)+" 对于字行参量没有足够内存";break;
case 4007:cuowu=" 错误代码:"+IntegerToString(4007)+" 对于字行没有足够内存";break;
case 4008:cuowu=" 错误代码:"+IntegerToString(4008)+" 没有初始字行";break;
case 4009:cuowu=" 错误代码:"+IntegerToString(4009)+" 在数组中没有初始字串符";break;
case 4010:cuowu=" 错误代码:"+IntegerToString(4010)+" 对于数组没有内存";break;
case 4011:cuowu=" 错误代码:"+IntegerToString(4011)+" 字行过长";break;
case 4012:cuowu=" 错误代码:"+IntegerToString(4012)+" 余数划分为零";break;
case 4013:cuowu=" 错误代码:"+IntegerToString(4013)+" 零划分";break;
case 4014:cuowu=" 错误代码:"+IntegerToString(4014)+" 不明命令";break;
case 4015:cuowu=" 错误代码:"+IntegerToString(4015)+" 错误转换(没有常规错误)";break;
case 4016:cuowu=" 错误代码:"+IntegerToString(4016)+" 没有初始数组";break;
case 4017:cuowu=" 错误代码:"+IntegerToString(4017)+" 禁止调用DLL ";break;
case 4018:cuowu=" 错误代码:"+IntegerToString(4018)+" 数据库不能下载";break;
case 4019:cuowu=" 错误代码:"+IntegerToString(4019)+" 不能调用函数";break;
case 4020:cuowu=" 错误代码:"+IntegerToString(4020)+" 禁止调用智能交易函数";break;
case 4021:cuowu=" 错误代码:"+IntegerToString(4021)+" 对于来自函数的字行没有足够内存";break;
case 4022:cuowu=" 错误代码:"+IntegerToString(4022)+" 系统繁忙 (没有常规错误)";break;
case 4050:cuowu=" 错误代码:"+IntegerToString(4050)+" 无效计数参量函数";break;
case 4051:cuowu=" 错误代码:"+IntegerToString(4051)+" 无效参量值函数";break;
case 4052:cuowu=" 错误代码:"+IntegerToString(4052)+" 字行函数内部错误";break;
case 4053:cuowu=" 错误代码:"+IntegerToString(4053)+" 一些数组错误";break;
case 4054:cuowu=" 错误代码:"+IntegerToString(4054)+" 应用不正确数组";break;
case 4055:cuowu=" 错误代码:"+IntegerToString(4055)+" 自定义指标错误";break;
case 4056:cuowu=" 错误代码:"+IntegerToString(4056)+" 不协调数组";break;
case 4057:cuowu=" 错误代码:"+IntegerToString(4057)+" 整体变量过程错误";break;
case 4058:cuowu=" 错误代码:"+IntegerToString(4058)+" 整体变量未找到";break;
case 4059:cuowu=" 错误代码:"+IntegerToString(4059)+" 测试模式函数禁止";break;
case 4060:cuowu=" 错误代码:"+IntegerToString(4060)+" 没有确认函数";break;
case 4061:cuowu=" 错误代码:"+IntegerToString(4061)+" 发送邮件错误";break;
case 4062:cuowu=" 错误代码:"+IntegerToString(4062)+" 字行预计参量";break;
case 4063:cuowu=" 错误代码:"+IntegerToString(4063)+" 整数预计参量";break;
case 4064:cuowu=" 错误代码:"+IntegerToString(4064)+" 双预计参量";break;
case 4065:cuowu=" 错误代码:"+IntegerToString(4065)+" 数组作为预计参量";break;
case 4066:cuowu=" 错误代码:"+IntegerToString(4066)+" 刷新状态请求历史数据";break;
case 4067:cuowu=" 错误代码:"+IntegerToString(4067)+" 交易函数错误";break;
case 4099:cuowu=" 错误代码:"+IntegerToString(4099)+" 文件结束";break;
case 4100:cuowu=" 错误代码:"+IntegerToString(4100)+" 一些文件错误";break;
case 4101:cuowu=" 错误代码:"+IntegerToString(4101)+" 错误文件名称";break;
case 4102:cuowu=" 错误代码:"+IntegerToString(4102)+" 打开文件过多";break;
case 4103:cuowu=" 错误代码:"+IntegerToString(4103)+" 不能打开文件";break;
case 4104:cuowu=" 错误代码:"+IntegerToString(4104)+" 不协调文件";break;
case 4105:cuowu=" 错误代码:"+IntegerToString(4105)+" 没有选择订单";break;
case 4106:cuowu=" 错误代码:"+IntegerToString(4106)+" 不明货币对";break;
case 4107:cuowu=" 错误代码:"+IntegerToString(4107)+" 无效价格";break;
case 4108:cuowu=" 错误代码:"+IntegerToString(4108)+" 无效订单编码";break;
case 4109:cuowu=" 错误代码:"+IntegerToString(4109)+" 不允许交易";break;
case 4110:cuowu=" 错误代码:"+IntegerToString(4110)+" 不允许长期";break;
case 4111:cuowu=" 错误代码:"+IntegerToString(4111)+" 不允许短期";break;
case 4112:cuowu=" 错误代码:"+IntegerToString(4112)+" 不允许EA/自动交易";break;
case 4200:cuowu=" 错误代码:"+IntegerToString(4200)+" 订单已经存在";break;
case 4201:cuowu=" 错误代码:"+IntegerToString(4201)+" 不明订单属性";break;
case 4202:cuowu=" 错误代码:"+IntegerToString(4202)+" 订单不存在";break;
case 4203:cuowu=" 错误代码:"+IntegerToString(4203)+" 不明订单类型";break;
case 4204:cuowu=" 错误代码:"+IntegerToString(4204)+" 没有订单名称";break;
case 4205:cuowu=" 错误代码:"+IntegerToString(4205)+" 订单坐标错误";break;
case 4206:cuowu=" 错误代码:"+IntegerToString(4206)+" 没有指定子窗口";break;
case 4207:cuowu=" 错误代码:"+IntegerToString(4207)+" 订单一些函数错误";break;
case 4250:cuowu=" 错误代码:"+IntegerToString(4250)+" 错误设定发送通知到队列中";break;
case 4251:cuowu=" 错误代码:"+IntegerToString(4251)+" 无效参量- 空字符串传递到SendNotification()函数";break;
case 4252:cuowu=" 错误代码:"+IntegerToString(4252)+" 无效设置发送通知(未指定ID或未启用通知)";break;
case 4253:cuowu=" 错误代码:"+IntegerToString(4253)+" 通知发送过于频繁";break;
default :cuowu=" 错误代码:"+IntegerToString(code);break;
}
if(code!=0)
{
Print(text+cuowu);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
|