智能交易网,程序化交易,自动交易,量化交易

 找回密码
 注册

QQ登录

只需一步,快速开始

手机短信登录

参加MT4智能交易编程培训,7课免费在线试听MT4指标,EA代写,或EA指标加密账户远程验证服务 最完善商业MT4跟单系统(0.1秒极速响应不漏单)
为论坛做贡献有奖学金,奖学金可直接换真钱 扫本站微信公 众号部分视频课程指标EA免费得智能交易网MT4操盘神器,扫公众号免费得
查看: 952|回复: 0

请教老师,把指标改成EA,无法开仓,问题出在哪里呢?

[复制链接]
发表于 2018-7-4 20:42:24 | 显示全部楼层 |阅读模式
指标如下:
//+------------------------------------------------------------------+
//|                                                      macd柱背离.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property indicator_separate_window //显示在副图
#property indicator_buffers 5 //定义5个数组
#property indicator_color1 LimeGreen //第1线颜色—橙绿色
#property indicator_color2 FireBrick //第2线颜色—火砖色
#property indicator_color3 Green //第3线颜色—绿色
#property indicator_color4 Red //第4线颜色—红色


//---- input parameters 外部参数设置
extern string separator1 = "*** OSMA Settings ***"; //MACD柱线设置
extern int fastEMA = 12; //快线周期数
extern int slowEMA = 26; //慢线周期数
extern int signal = 9; //移动周期数
extern string separator2 = "*** Indicator Settings ***"; //指标设置
extern bool drawDivergenceLines = true; //画背离线=真
extern bool displayAlert = true; //信号显示=真
extern int FastEMA = 12;
extern int SlowEMA = 26;
extern int SignalEMA = 9;

//---- buffers 数组定义—小数型
double upOsMA[]; //MACD柱线上升
double downOsMA[]; //MACD柱线下降
double bullishDivergence[]; //牛背离
double bearishDivergence[]; //熊背离
double OsMA[]; //MACD柱线

//----
static datetime lastAlertTime; //静止变量-时间日期型:最后报警时间
//+------------------------------------------------------------------+


//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init() //加载时运行
{
//---- indicators
SetIndexStyle(0, DRAW_HISTOGRAM, STYLE_SOLID, 2);
//指标类型(索引-0,画柱线,实心线,宽-2像素)
SetIndexStyle(1, DRAW_HISTOGRAM, STYLE_SOLID, 2);
//指标类型(索引-1,画柱线,实心线,宽-2像素)
SetIndexStyle(2, DRAW_ARROW);
//指标类型(索引-2,画箭头)
SetIndexStyle(3, DRAW_ARROW);
//指标类型(索引-3,画箭头)
SetIndexStyle(4, DRAW_NONE);
//指标类型(索引-4,不画线)
//----
SetIndexBuffer(0, upOsMA); //指标索引(索引-0,MACD柱线上升)
SetIndexBuffer(1, downOsMA); //指标索引(索引-1,MACD柱线下降)
SetIndexBuffer(2, bullishDivergence); //指标索引(索引-2,牛背离)
SetIndexBuffer(3, bearishDivergence); //指标索引(索引-3,熊背离)
SetIndexBuffer(4, OsMA); //指标索引(索引-4,MACD柱线)
//----
SetIndexArrow(2, 233); //箭头类型(索引-2,编号233)
SetIndexArrow(3, 234); //箭头类型(索引-3,编号234)
//----
IndicatorDigits(Digits + 2); //指标取小数点位数(取当前货币兑的小数位+2),如果当前货币对的小数位为5位,则指标小数位:5+2=7,则取小数后7位进行保留,以便计算中产生“四舍五入”,进行计列。
IndicatorShortName("macd柱背离(" + fastEMA + "," + slowEMA + "," + signal + ")"); //指标简称(“macd柱背离(快速EMA,慢速EMA,移动周期)”)
return(0);
}
//+------------------------------------------------------------------+


//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit() //卸载时运行
{
for(int i = ObjectsTotal() - 1; i >= 0; i--) //循环检查(对象总数-1,0,递减1)
{
string label = ObjectName(i); //变量-文本型:标签=对象名称(i)
if(StringSubstr(label, 0, 14) != "DivergenceLine")
//如果(提取文本(标签,从0字符开始,取字符长度=14)≠“背离线”)
continue; //继续
ObjectDelete(label); //删除对象(标签)
}
return(0);
}
//+------------------------------------------------------------------+


//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() //主函数
{
int countedBars = IndicatorCounted(); //计算K线数=K线总数函数()
if(countedBars < 0) // 如果(计算K线数< 0)
countedBars = 0; //计算K线数=0
CalculateIndicator(countedBars); //指标计算(计算K线数)-自定义函数调用
return(0);
}
//+------------------------------------------------------------------+
//| 自定义函数-无返回型:指标计算 |
//+------------------------------------------------------------------+
void CalculateIndicator(int countedBars) //自定义函数:指标计算(计算K线数)
{
for(int i = Bars - countedBars; i >= 0; i--) //循环检查(i=K线数-计算K线数,0,i=i-1)
{
CalculateOsMA(i); //计算MACD柱线(i)-自定义函数
CatchBullishDivergence(i + 2); //捕捉牛背离函数(i+2)-自定义函数
CatchBearishDivergence(i + 2); //捕捉熊背离函数(i+2)-自定义函数
}
}
//+------------------------------------------------------------------+
//| 自定义函数-无返回型:计算MACD柱线 |
//+------------------------------------------------------------------+
void CalculateOsMA(int i) //自定义函数:计算MACD柱线
{

OsMA= iOsMA(NULL, 0, fastEMA, slowEMA, signal, PRICE_CLOSE, i);

//MACD柱线=调用MACD柱线函数(当前货币对,当前图表,快速EMA,慢速EMA,移动周期,收盘价,i)
if(OsMA > 0) //如果(MACD柱线>0)
{
upOsMA = OsMA; //MACD柱线上升= MACD柱线
downOsMA = 0; //MACD柱线下降=0
}
else
if(OsMA < 0) //如果(MACD柱线<0)
{
downOsMA = OsMA; //MACD柱线下降=MACD柱线
upOsMA = 0; //MACD柱线上升=0
}
else
{
upOsMA = 0; //MACD柱线上升=0
downOsMA = 0; //MACD柱线下降=0
}
}

//+------------------------------------------------------------------+
//| 自定义函数-无返回型:捕捉牛背离函数 |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift) //捕捉牛背离函数(K线序号)
{
if(IsIndicatorTrough(shift) == false) //如果(是否是指标的波谷(K线序号)=假)
return;
int currentTrough = shift; //变量-整数型:当前波谷=K线序号
int lastTrough = GetIndicatorLastTrough(shift);
//变量-整数型:上次波谷=获取指标的上次波谷(K线序号)
if(OsMA[currentTrough] > OsMA[lastTrough] && Low[currentTrough] < Low[lastTrough])
//如果(MACD柱线[当前波谷]> MACD柱线[上次波谷] 且 K线低价[当前波谷] > K线低价[上次波谷])
{
bullishDivergence[currentTrough] = OsMA[currentTrough];
//牛背离[当前波谷]=MACD柱线[当前波谷]
if(drawDivergenceLines == true) //如果(画背离线=真)
{
DrawPriceTrendLine(Time[currentTrough], Time[lastTrough],
Low[currentTrough], Low[lastTrough], Green, STYLE_SOLID);
//画价格趋势线(位置[当前波谷],位置[上次波谷],最低价[当前波谷],最低价[上次波谷],绿色,实线)
DrawIndicatorTrendLine(Time[currentTrough], Time[lastTrough],
OsMA[currentTrough],OsMA[lastTrough], Green, STYLE_SOLID);
//画指标趋势线(位置[当前波谷],位置[上次波谷],MACD柱线[当前波谷],MACD柱线[上次波谷],绿色,实线)
}
if(displayAlert == true) //如果(显示信号=真)
DisplayAlert("Classical bullish divergence on: ", currentTrough);
//显示信号(“标准牛背离出现:”,当前波谷)
}

}
//+------------------------------------------------------------------+
//| 自定义函数-无返回型:捕捉熊背离函数 |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift) //捕捉熊背离函数(K线序号)
{
if(IsIndicatorPeak(shift) == false) //如果(是否是指标的波峰(K线序号)=假)
return;
int currentPeak = shift; //当前波峰=K线序号
int lastPeak = GetIndicatorLastPeak(shift); //上次波峰=获取指标的上次波峰(K线序号)
if(OsMA[currentPeak] < OsMA[lastPeak] && High[currentPeak] > High[lastPeak])
//如果(MACD柱线[当前波峰]<MACD柱线[上次波峰] 且最高价[当前波峰]>最高价[上次波峰])
{
bearishDivergence[currentPeak] = OsMA[currentPeak];
//熊背离[当前波峰]=MACD柱线[当前波峰]
if(drawDivergenceLines == true) //如果(画背离线=真)
{
DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], High[currentPeak],
High[lastPeak], Red, STYLE_SOLID);
//画价格趋势线(位置[当前波峰],位置[上次波峰],最高价[当前波峰],最高价[上次波峰],红色,实线)
DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], OsMA[currentPeak],
OsMA[lastPeak], Red, STYLE_SOLID);
//画指标趋势线(位置[当前波峰],位置[上次波峰],MACD柱线[当前波峰],MACD柱线[上次波峰],红色,实线)
}
if(displayAlert == true) //如果(信号显示=真)
DisplayAlert("Classical bearish divergence on: ", currentPeak);
//信号显示(“标准熊背离出现:”+当前波峰)
}

}
//+------------------------------------------------------------------+
//| 自定义函数-逻辑型:判断指标波峰函数 |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift) //判断指标是否为波峰(K线序号)
{
if(OsMA[shift] > 0 && OsMA[shift] > OsMA[shift+1] && OsMA[shift] > OsMA[shift-1])
//如果(MACD柱线[K线序号]>0 且 MACD柱线[K线序号]> MACD柱线[K线序号+1] 且MACD柱线[K线序号]> MACD柱线[K线序号-1])
{
for(int i = shift + 1; i < Bars; i++) //循环查找(i=K线序号+1,i<K线数;i=i+1)
{
if(OsMA < 0) //如果(MACD柱线<0)
return(true);
if(OsMA > OsMA[shift]) //如果(MACD柱线>MACD柱线[K线序号])
break; //跳转
}
}
return(false); //返回(假)
}
//+------------------------------------------------------------------+
//| 自定义函数-逻辑型:判断指标波谷函数 |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift) //判断指标是否为波谷(K线序号)
{
if(OsMA[shift] < 0 && OsMA[shift] < OsMA[shift+1] && OsMA[shift] < OsMA[shift-1])
//如果(MACD柱线[K线序号]<0 且 MACD柱线[K线序号]< MACD柱线[K线序号+1] 且MACD柱线[K线序号]><MACD柱线[K线序号-1])
{
for(int i = shift + 1; i < Bars; i++) //循环查找(i=K线序号+1,i<K线数;i=i+1)
{
if(OsMA > 0) //如果(MACD柱线>0)
return(true);
if(OsMA < OsMA[shift]) //如果(MACD柱线>MACD柱线[K线序号])
break; //跳转
}
}
return(false); //返回(假)
}
//+------------------------------------------------------------------+
//| 自定义函数-整数型:获取指标上次波峰 |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift) //获取指标上次波峰(K线序号)
{
for(int i = shift + 5; i < Bars; i++) //循环查找(i=K线序号+5;i<K线数;i=i+1)
{
if(OsMA >= OsMA[i+1] && OsMA > OsMA[i+2] &&
OsMA >= OsMA[i-1] && OsMA > OsMA[i-2])
//如果(MACD柱线 >=MACD柱线[i+1] 且MACD柱线>MACD柱线[i+2]
//且MACD柱线 >=MACD柱线[i-1] 且MACD柱线>MACD柱线[i-2])
return(i); //返回(i)
}
return(-1); //返回(-1)
}
//+------------------------------------------------------------------+
//| 自定义函数-整数型:获取指标上次波谷 |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift) //获取指标上次波谷(K线序号)
{
for(int i = shift + 5; i < Bars; i++) //循环查找(i=K线序号+5;i<K线数;i=i+1))
{
if(OsMA <= OsMA[i+1] && OsMA < OsMA[i+2] &&
OsMA <= OsMA[i-1] && OsMA < OsMA[i-2])
//如果(MACD柱线 <=MACD柱线[i+1] 且MACD柱线<MACD柱线[i+2]
//且MACD柱线 <=MACD柱线[i-1] 且MACD柱线<MACD柱线[i-2])
return(i); //返回(i)
}
return(-1); //返回(-1)
}
//+------------------------------------------------------------------+
//|自定义函数-无返回型:警示信号显示 |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift) //警示信号显示(通知,K线序号)
{
if(shift <= 2 && Time[shift] != lastAlertTime)
//如果(K线序号<=2 且 位置[K线序号]≠上次信号位置)
{
lastAlertTime = Time[shift]; //上次信号位置=位置[K线序号]
Alert(message, Symbol(), " , ", Period(), " minutes chart");
//弹出警告窗口(通知,当前货币对,“,”当前周期,“分钟计算”)
}
}
//+------------------------------------------------------------------+
//| 自定义函数-无返回型:画价格趋线 |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
//画价格趋线(X1-时间日期型,X2-时间日期型,Y1-小数型,Y2-小数型,线条颜色,线条类型-小数型)
{
string label = "DivergenceLine2.1# " + DoubleToStr(x1, 0);
//标签=“背离线2.1#”+小数到文本(X1,0)
ObjectDelete(label); //删除对象(标签)
ObjectCreate(label, OBJ_TREND, 0, x1, y1, x2, y2, 0, 0);
//创建对象(标签,趋势线,0,X1,Y1,X2,Y2,0,0,)
ObjectSet(label, OBJPROP_RAY, 0); //对象属性设置(标签,射线,0)
ObjectSet(label, OBJPROP_COLOR, lineColor); //对象属性设置(标签,颜色,线条颜色)
ObjectSet(label, OBJPROP_STYLE, style); //对象属性设置(标签,线条类型,类型)
}
//+------------------------------------------------------------------+
//| 自定义函数-无返回型:画指标趋势线 |
//+------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1, datetime x2, double y1,
double y2, color lineColor, double style)
//画指标趋势线(X1-时间日期型,X2-时间日期型,Y1-小数型,Y2-小数型,线条颜色,类型-小数型)
{
int indicatorWindow = WindowFind("macd柱背离(" + fastEMA + "," + slowEMA + "," + signal + ")");
//指标窗口数=指标检查(“macd柱背离(”+快线EMA+“,”+慢线EMA+“,”+移动周期+“)”)
if(indicatorWindow < 0)
//如果(指标窗口数)<0
return;
string label = "DivergenceLine2.1$# " + DoubleToStr(x1, 0);
//标签内容=“背离线2.1$#”+数值到文本(X1,0)
ObjectDelete(label);
//删除对象(标签)
ObjectCreate(label, OBJ_TREND, indicatorWindow, x1, y1, x2, y2, 0, 0);
//创建对象(标签,趋线,指标窗口,X1,Y1,X2,Y2,0,0)
ObjectSet(label, OBJPROP_RAY, 0);
//对象属性设置(标签,射线,0)
ObjectSet(label, OBJPROP_COLOR, lineColor);
//对象属性设置(标签,颜色,线条颜色)
ObjectSet(label, OBJPROP_STYLE, style);
//对象属性设置(标签,线条类型,类型)
}
//+-----------------------------------------------------------------




EA是利用系统自带的MACD Sample,修改开仓条件,其源码如下:

//+------------------------------------------------------------------+
//|                                                       macd背离.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
input double TakeProfit    =50;
input double Lots          =0.1;
input double TrailingStop  =30;
input double MACDOpenLevel =3;
input double MACDCloseLevel=2;
input int    MATrendPeriod =26;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   double MacdCurrent,MacdPrevious;
   double SignalCurrent,SignalPrevious;
   double MaCurrent,MaPrevious;
   int    cnt,ticket,total;
  
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external
// variables (Lots, StopLoss, TakeProfit,
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
   if(Bars<100)
     {
      Print("bars less than 100");
      return;
     }
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return;
     }
//--- to simplify the coding and speed up access data are put into internal variables

   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);
   total=OrdersTotal();
   if(total<1)
     {
      //--- no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ",AccountFreeMargin());
         return;
        }
      //--- check for long position (BUY) possibility
     double up0=iCustom(NULL,0,"MACD柱背离",2,0);
     double down0=iCustom(NULL,0,"MACD柱背离",3,0);
      if(up0<10000 )
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,"macd背离",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("BUY order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }
      //--- check for short position (SELL) possibility
      if(down0<10000 )
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,"macd背离",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());
        }
      //--- exit from the "no opened orders" block
      return;
     }
//--- it is important to enter the market correctly, but it is more important to exit it correctly...   
   for(cnt=0;cnt<total;cnt++)
     {
      if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
      if(OrderType()<=OP_SELL &&   // check for opened position
         OrderSymbol()==Symbol())  // check for symbol
        {
         //--- long position is opened
         if(OrderType()==OP_BUY)
           {
            //--- should it be closed?
            if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious &&
               MacdCurrent>(MACDCloseLevel*Point))
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
                  Print("OrderClose error ",GetLastError());
               return;
              }
            //--- check for trailing stop
            if(TrailingStop>0)
              {
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     //--- modify order and exit
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
         else // go to short position
           {
            //--- should it be closed?
            if(MacdCurrent<0 && MacdCurrent>SignalCurrent &&
               MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point))
              {
               //--- close order and exit
               if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))
                  Print("OrderClose error ",GetLastError());
               return;
              }
            //--- check for trailing stop
            if(TrailingStop>0)
              {
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     //--- modify order and exit
                     if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red))
                        Print("OrderModify error ",GetLastError());
                     return;
                    }
                 }
              }
           }
        }
     }
//---
  }
//+------------------------------------------------------------------+
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|sitemap|智能交易网,程序化交易,自动交易,量化交易 ( 苏ICP备08108698号,苏州智德金网络科技股份有限公司版权所有 )

GMT+8, 2019-10-14 08:43 , Processed in 0.043370 second(s), 15 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表