指标: MACD 与零轴交叉 (彩色蜡烛) - 页 3

 
Andrey F. Zelinsky:

把你编辑的代码贴出来 -- 解释你做了哪些编辑 -- 让我们看看。

如果你有兴趣自己做,就有机会弄明白。


#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property version     "5.20"
#property description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//---
input double InpLots          =0.1; // Lots.
input int    InpTakeProfit    =50;  // 止盈(点数)
input int    InpTrailingStop  =30;  // 追踪止损位(点数)
input int    InpMACDOpenLevel =3;   // MACD 开放水平(点数)
input int    InpMACDCloseLevel=2;   // MACD 收盘水平(以点为单位)
input int    InpMATrendPeriod =26;  // MA 趋势期
//---
int ExtTimeOut=10; // 以秒为单位的交易操作间隔时间
//+------------------------------------------------------------------+
//| MACD 示例专家类|
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected:
   double            m_adjusted_point;             // 点值调整为 3 点或 5 点
   CTrade            m_trade;                      // 交易对象
   CSymbolInfo       m_symbol;                     // 符号信息对象
   CPositionInfo     m_position;                   // 交易位置对象
   CAccountInfo      m_account;                    // 账户信息包装器
   //--- 指标
   int               m_handle_macd;                // MACD 指标句柄
   
   //--- 指示器缓冲区
   double            m_buff_MACD_main[];           // MACD 指标主缓冲区
   
  
   //--- 用于处理的指标数据
   double            m_macd_current;
   double            m_macd_previous;
   

   //---
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public:
                     CSampleExpert(void);
                    ~CSampleExpert(void);
   bool              Init(void);
   void              Deinit(void);
   bool              Processing(void);

protected:
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };
//--- 全球专家
CSampleExpert ExtExpert;
//+------------------------------------------------------------------+
//| 构造函数|
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                     m_handle_macd(INVALID_HANDLE),
                                     
                                     m_macd_current(0),
                                     m_macd_previous(0),                                                                   
                                     m_macd_open_level(0),
                                     m_macd_close_level(0),
                                     m_traling_stop(0),
                                     m_take_profit(0)
  {
   ArraySetAsSeries(m_buff_MACD_main,true);
   
  
  }
//+------------------------------------------------------------------+
//| 销毁器|
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }
//+------------------------------------------------------------------+
//| 初始化并检查输入参数
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- 初始化通用信息
   m_symbol.Name(Symbol());              // 符号
   m_trade.SetExpertMagicNumber(12345);  // 魔术
//--- 调整 3 或 5 位数
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- 以调整后的点数设置交易默认偏差
   m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
   m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- 以调整后的点数设置交易默认偏差
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- 成功
   return(true);
  }
//+------------------------------------------------------------------+
//| 检查输入参数|
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- 初始数据检查
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- 检查批量是否正确
   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
      printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0 E-10)
     {
      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
      return(false);
     }
//--- 警告
   if(InpTakeProfit<=InpTrailingStop)
      printf("Warning: Trailing Stop must be less than Take Profit");
//--- 成功
   return(true);
  }
//+------------------------------------------------------------------+
//| 指标初始化|
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- 创建 MACD 指标
   if(m_handle_macd==INVALID_HANDLE)
      if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Error creating MACD indicator");
         return(false);
        }
//--- 创建 EMA 指标并将其添加到集合中
  
      
//--- 成功
   return(true);
  }
//+------------------------------------------------------------------+
//| 检查多头平仓|
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- 是否应该关闭?
   
      if(m_macd_current<0 && m_macd_previous>0)
         if(m_macd_current<m_macd_close_level)
           {
            //--- 关闭位置
            if(m_trade.PositionClose(Symbol()))
               printf("Long position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            //--- 已处理,无法修改
            res=true;
           }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 检查空头平仓|
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- 是否应该关闭?
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>m_macd_close_level)
           {
            //--- 关闭位置
            if(m_trade.PositionClose(Symbol()))
               printf("Short position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            //--- 已处理,无法修改
            res=true;
           }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 检查多头位置修改|
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- 检查跟踪止损
   if(InpTrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
           {
            //--- 修改位置
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Long position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- 已修改,必须退出专家
            res=true;
           }
        }
     }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 检查空头仓位是否被修改
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- 检查跟踪止损
   if(InpTrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
           {
            //--- 修改位置
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Short position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            //--- 已修改,必须退出专家
            res=true;
           }
        }
     }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 检查多头开仓|
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- 检查多头头寸(买入)的可能性
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))
           {
            double price=m_symbol.Ask();
            double tp   =m_symbol.Bid()+m_take_profit;
            //----检查免费资金
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- 打开位置
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            //--- 在任何情况下,我们都必须退出专家程序
            res=true;
           }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 检查空头开仓|
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//----检查空仓(卖出)的可能性
  
      if(m_macd_current<0 && m_macd_previous>0)
         if(m_macd_current<(m_macd_open_level) )
           {
            double price=m_symbol.Bid();
            double tp   =m_symbol.Ask()-m_take_profit;
            //----检查免费资金
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- 打开位置
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            //--- 在任何情况下,我们都必须退出专家程序
            res=true;
           }
//--- 结果
   return(res);
  }
//+------------------------------------------------------------------+
//| 如果处理了任何位置,主函数返回 true。
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- 刷新率
   if(!m_symbol.RefreshRates())
      return(false);
//--- 刷新指标
   if(BarsCalculated(m_handle_macd)<2 )
      return(false);
   if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 )
      
      
      return(false);
// m_indicators.Refresh();
//--- 简化编码并加快访问速度
//--- 数据被放入内部变量
   m_macd_current   =m_buff_MACD_main[0];
   m_macd_previous  =m_buff_MACD_main[1];
   
  
//--- 正确进入市场非常重要、 
//--- 但更重要的是正确退出.... 
//--- 首先检查位置是否存在 - 尝试选择它
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- 尝试关闭或修改多头仓位
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- 尝试关闭或修改空头头寸
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- 没有确定的开放位置
   else
     {
      //--- 检查多头头寸(买入)的可能性
      if(LongOpened())
         return(true);
      //----检查空仓(卖出)的可能性
      if(ShortOpened())
         return(true);
     }
//--- 退出,不进行位置处理
   return(false);
  }
//+------------------------------------------------------------------+
//| 专家初始化函数|
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- 创建所有必要的对象
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- secceed
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
// 专家新的刻度处理函数|
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // 上次交易处理时间 + 超时
//--- 如果超时则不处理
   if(TimeCurrent()>=limit_time)
     {
      //--- 检查数据
      
        {
         //--- 如果已处理,按超时时间(秒)更改限制时间
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

我删除了所有能找到的关于"移动平均线"和 "MACD 信号线 "的数据。

bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- 检查多头头寸(买入)的可能性
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))

在这个位置,给出的值不是 "0",而是中线。我在所有地方都将其替换为 "0",在卖出和收盘时都是如此。

Автоматический трейдинг и тестирование торговых стратегий
Автоматический трейдинг и тестирование торговых стратегий
  • www.mql5.com
Выберите подходящую торговую стратегию и оформите подписку на нее в пару кликов. Все Сигналы сопровождаются подробной статистикой и графиками. Станьте Поставщиком торговых сигналов и продавайте подписку тысячам трейдеров по всему миру. Наш сервис позволит вам хорошо зарабатывать на прибыльной стратегии даже при небольшом стартовом капитале...
 
Krivets:


删除我能找到的所有关于"移动平均线"和 "MACD 信号线 "的数据。

在这里,指定的平均线值不是 "0",而是 "0"。将其替换为 "0",在卖出和关闭痕迹时都是如此。


关于长示例:

bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- 检查多头头寸(买入)的可能性
   
      if(m_macd_current>0 && m_macd_previous<0)
         if(MathAbs(m_macd_current)>(m_macd_open_level))
           {

-- 突出显示的条件起什么作用?

 

以下是我对上述突出部分进行修正后的结果(关于开口的具体细节的小评论):


 
Andrey F. Zelinsky:

以长为例:

-- 突出显示的条件起什么作用?


MathAbs(m_macd_current)>m_macd_open_level - MACD指标 主线的当前值取模。

 
Krivets:

MathAbs(m_macd_current)>m_macd_open_level - MACD指标 主线的当前值模数


是的,只需删除或正确设置该条件即可 -- 上图是删除该条件后的 EA 性能图片

 
Andrey F. Zelinsky:

是的,但应删除或正确设置该条件 -- 上图是删除该条件后 EA 性能的图片。


我没有更改条件,但更改了其他值。

input double InpLots          =0.1; // Lots.
input int    InpTakeProfit    =0;  // 止盈(点数)
input int    InpTrailingStop  =0;  // 追踪止损位(点数)
input int    InpMACDOpenLevel =0;   // MACD 开放水平(点数)
input int    InpMACDCloseLevel=0;   // MACD 收盘水平(以点为单位)
input int    InpMATrendPeriod =26;  // MA 趋势期

我将 OpenLevel 和 Closelevel 改为 0。

我还禁用了止盈和止损。

 

通过穿越 "0 "建立头寸,但由于某种原因,交易在 10 点后关闭。最好是在第二根柱形图之后开仓,因为第一根柱形图没有形成,会出现假进场。

我还设置了交易时间不早于 60 秒,即 10 秒,并且每 10 秒在一分钟内进行一次买入或卖出,即一分钟 6 笔交易。您设置了 1 手,那么一分钟内就会有 6 手买入或卖出,这取决于 "0 "线的交叉点。

int ExtTimeOut=60; // 以秒为单位的交易操作间隔时间
 

我已经部分解决了这个问题,我将 TakeProfit 设置为 10000,它开始正常翻滚,但会错过一些交易。有必要添加一个功能,使翻滚发生在第二个条形图上,这样就会获得虚假交易,更有可能因为这个原因而错过交易。

如果 TakeProfit 设置为所需金额,例如在 "RTS "100 点时,它会在 TP 时关闭交易,并在指标越过 "0 "时开启新的交易。我在几分钟内进行了测试,因为有很多信号。