• <menu id="iiemy"><menu id="iiemy"></menu></menu>
    您現在的位置:程序化交易>> 外匯現貨>> MT5>> MT5知識>>正文內容

    MACD Sample ---真正的用面向對象的思路來寫EA [MT4]

    • 我初步看了下系統自帶的MACD Sample EA,這個實例其實用原來MT4的方式實現起來很簡單。
      但是我看了系統自帶的代碼:簡直和C++代碼沒什么區別了:
      首先應用頭文件或者說是庫文件。這些文件其實都是類庫文件,每個類里面自帶了許多處理方法
      接著定義一個類
      然后吧一些變量和方法都封裝到類中。
      最后void OnTick()程序實體部分簡單的不可想象:
      就是定義一個類的實例,然后調用一個類的方法就完了。
      以后有時間我好好分析分析。
      //+------------------------------------------------------------------+
      //| MACD Sample.mq5 |
      //| Copyright 2001-2009, MetaQuotes Software Corp. |
      //| http://www.mql5.com |
      //+------------------------------------------------------------------+
      #property copyright "Copyright 2001-2009, MetaQuotes Software Corp."
      #property link "http://www.mql5.com"
      #property version "5.04"
      #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>
      #include <Indicators\Indicators.mqh>

      //---
      input double InpLots =0.1; // Lots
      input int InpTakeProfit =50; // Take Profit (in pips)
      input int InpTrailingStop =30; // Trailing Stop Level (in pips)
      input double InpMACDOpenLevel =0.3; // MACD open level
      input double InpMACDCloseLevel=0.2; // MACD close level
      input int InpMATrendPeriod =26; // MA trend period
      //---
      int ExtTimeOut=10; // time out in seconds between trade operations
      //+------------------------------------------------------------------+
      //| MACD Sample expert class |
      //+------------------------------------------------------------------+
      class CSampleExpert
      {
      protected:
      double m_adjusted_point; // point value adjusted for 3 or 5 points
      CTrade m_trade; // trading object
      CSymbolInfo m_symbol; // symbol info object
      CPositionInfo m_position; // trade position object
      CAccountInfo m_account; // account info wrapper
      //--- indicators
      CIndicators *m_indicators; // indicator collection to fast recalculations
      CiMACD *m_MACD; // MACD indicator object
      CiMA *m_EMA; // moving average indicator object
      //--- indicator data for processing
      double m_macd_current;
      double m_macd_previous;
      double m_signal_current;
      double m_signal_previous;
      double m_ema_current;
      double m_ema_previous;
      public:
      CSampleExpert();
      ~CSampleExpert() { Deinit(); }
      bool Init();
      void Deinit();
      bool Processing();
      protected:
      bool InitCheckParameters(int digits_adjust);
      bool InitIndicators();
      bool LongClosed();
      bool ShortClosed();
      bool LongModified();
      bool ShortModified();
      bool LongOpened();
      bool ShortOpened();
      };
      //---
      CSampleExpert ExtExpert;
      //+------------------------------------------------------------------+
      //| Constructor |
      //+------------------------------------------------------------------+
      CSampleExpert::CSampleExpert()
      {
      //---
      m_adjusted_point=0;
      m_indicators=NULL;
      m_MACD=NULL;
      m_EMA =NULL;
      //---
      m_macd_current =0;
      m_macd_previous =0;
      m_signal_current =0;
      m_signal_previous=0;
      m_ema_current =0;
      m_ema_previous =0;
      //---
      }
      //+------------------------------------------------------------------+
      //| Initialization and checking for input parameters |
      //+------------------------------------------------------------------+
      bool CSampleExpert::Init()
      {
      //--- initialize common information
      m_symbol.Name(Symbol()); // symbol
      m_trade.SetExpertMagicNumber(12345); // magic
      //--- tuning for 3 or 5 digits
      int digits_adjust=1;
      if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10;
      m_adjusted_point=m_symbol.Point()*digits_adjust;
      //--- set default deviation for trading in adjusted points
      m_trade.SetDeviationInPoints(3*digits_adjust);
      //---
      if(!InitCheckParameters(digits_adjust)) return(false);
      if(!InitIndicators()) return(false);
      //--- ok
      return(true);
      }
      //+------------------------------------------------------------------+
      //| Checking for input parameters |
      //+------------------------------------------------------------------+
      bool CSampleExpert::InitCheckParameters(int digits_adjust)
      {
      //--- initial data checks
      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);
      }
      //--- check for right lots amount
      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(MathMod(InpLots,m_symbol.LotsStep()))>1.0E-15)
      {
      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
      return(false);
      }
      //--- warning
      if(InpTakeProfit<=InpTrailingStop)
      printf("Warning: Trailing Stop must be greater than Take Profit");
      //--- ok
      return(true);
      }
      //+------------------------------------------------------------------+
      //| Initialization of the indicators |
      //+------------------------------------------------------------------+
      bool CSampleExpert::InitIndicators()
      {
      //--- create indicators collection
      if(m_indicators==NULL)
      if((m_indicators=new CIndicators)==NULL)
      {
      printf("Error creating indicators collection");
      return(false);
      }
      //--- create MACD indicator and add it to collection
      if(m_MACD==NULL)
      if((m_MACD=new CiMACD)==NULL)
      {
      printf("Error creating MACD indicator");
      return(false);
      }
      if(!m_indicators.Add(m_MACD))
      {
      printf("Error adding MACD indicator to collection");
      return(false);
      }
      //--- initialize MACD indicator
      if(!m_MACD.Create(NULL,0,12,26,9,PRICE_CLOSE))
      {
      printf("Error MACD indicator init");
      return(false);
      }
      m_MACD.BuffSize(2);
      //--- create EMA indicator and add it to collection
      if(m_EMA==NULL)
      if((m_EMA=new CiMA)==NULL)
      {
      printf("Error creating EMA indicator");
      return(false);
      }
      if(!m_indicators.Add(m_EMA))
      {
      printf("Error adding EMA indicator to collection");
      return(false);
      }
      //--- initialize EMA indicator
      if(!m_EMA.Create(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))
      {
      printf("Error EMA indicator init");
      return(false);
      }
      m_EMA.BuffSize(2);
      //--- ok
      return(true);
      }
      //+------------------------------------------------------------------+
      //| Function for deleting of dynamic objects |
      //+------------------------------------------------------------------+
      void CSampleExpert::Deinit()
      {
      //--- delete indicators collection
      if(m_indicators!=NULL)
      {
      delete m_indicators;
      m_indicators=NULL;
      m_MACD=NULL;
      m_EMA =NULL;
      }
      //---
      }
      //+------------------------------------------------------------------+
      //| Check for long position closing |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongClosed()
      {
      bool res=false;
      //--- should it be closed?
      if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
      if(m_macd_current>InpMACDCloseLevel*m_adjusted_point)
      {
      //--- close position
      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());
      //--- processed and cannot be modified
      res=true;
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| Check for short position closing |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortClosed()
      {
      bool res=false;
      //--- should it be closed?
      if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
      if(MathAbs(m_macd_current)>InpMACDCloseLevel*m_adjusted_point)
      {
      //--- close position
      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());
      //--- processed and cannot be modified
      res=true;
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| Check for long position modifying |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongModified()
      {
      bool res=false;
      //--- check for trailing stop
      if(InpTrailingStop>0)
      {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
      {
      if(m_position.StopLoss()<m_symbol.Bid()-m_adjusted_point*InpTrailingStop || m_position.StopLoss()==0.0)
      {
      double sl=m_symbol.Bid()-m_adjusted_point*InpTrailingStop;
      double tp=m_position.TakeProfit();
      //--- modify position
      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);
      }
      //--- modified and must exit from expert
      res=true;
      }
      }
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| Check for short position modifying |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortModified()
      {
      bool res=false;
      //--- check for trailing stop
      if(InpTrailingStop>0)
      {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
      {
      if((m_position.StopLoss()>(m_symbol.Ask()+m_adjusted_point*InpTrailingStop)) || m_position.StopLoss()==0.0)
      {
      double sl=m_symbol.Ask()+m_adjusted_point*InpTrailingStop;
      double tp=m_position.TakeProfit();
      //--- modify position
      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);
      }
      //--- modified and must exit from expert
      res=true;
      }
      }
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| Check for long position opening |
      //+------------------------------------------------------------------+
      bool CSampleExpert::LongOpened()
      {
      bool res=false;
      //--- check for long position (BUY) possibility
      if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
      if(MathAbs(m_macd_current)>(InpMACDOpenLevel*m_adjusted_point) && m_ema_current>m_ema_previous)
      {
      //--- check for free money
      if(m_account.FreeMarginCheck(Symbol(),0,InpLots)<0.0)
      printf("We have no money. Free Margin = %f",m_account.FreeMargin());
      else
      {
      double price=m_symbol.Ask();
      double tp =m_symbol.Ask()+InpTakeProfit*m_adjusted_point;
      //--- open position
      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);
      }
      }
      //--- in any case we must exit from expert
      res=true;
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| Check for short position opening |
      //+------------------------------------------------------------------+
      bool CSampleExpert::ShortOpened()
      {
      bool res=false;
      //--- check for short position (SELL) possibility
      if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
      if(m_macd_current>(InpMACDOpenLevel*m_adjusted_point) && m_ema_current<m_ema_previous)
      {
      //--- check for free money
      if(m_account.FreeMarginCheck(Symbol(),0,InpLots)<0.0)
      printf("We have no money. Free Margin = %f",m_account.FreeMargin());
      else
      {
      double price=m_symbol.Bid();
      double tp =m_symbol.Bid()-InpTakeProfit*m_adjusted_point;
      //--- open position
      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);
      }
      }
      //--- in any case we must exit from expert
      res=true;
      }
      //---
      return(res);
      }
      //+------------------------------------------------------------------+
      //| main function returns true if any position processed |
      //+------------------------------------------------------------------+
      bool CSampleExpert::Processing()
      {
      //--- refresh rates
      if(!m_symbol.RefreshRates()) return(false);
      //--- refresh indicators
      m_indicators.Refresh();
      //--- to simplify the coding and speed up access
      //--- data are put into internal variables
      m_macd_current =m_MACD.Main(0);
      m_macd_previous =m_MACD.Main(1);
      m_signal_current =m_MACD.Signal(0);
      m_signal_previous=m_MACD.Signal(1);
      m_ema_current =m_EMA.Main(0);
      m_ema_previous =m_EMA.Main(1);
      //--- it is important to enter the market correctly,
      //--- but it is more important to exit it correctly...
      //--- first check if position exists - try to select it
      if(m_position.Select(Symbol()))
      {
      if(m_position.PositionType()==OP_BUY)
      {
      //--- try to close or modify long position
      if(LongClosed()) return(true);
      if(LongModified()) return(true);
      }
      else
      {
      //--- try to close or modify short position
      if(ShortClosed()) return(true);
      if(ShortModified()) return(true);
      }
      }
      //--- no opened position identified
      else
      {
      //--- check for long position (BUY) possibility
      if(LongOpened()) return(true);
      //--- check for short position (SELL) possibility
      if(ShortOpened()) return(true);
      }
      //--- exit without position processing
      return(false);
      }
      //+------------------------------------------------------------------+
      //| Expert initialization function |
      //+------------------------------------------------------------------+
      int OnInit()
      {
      //--- create all necessary objects
      if(!ExtExpert.Init())
      {
      ExtExpert.Deinit();
      return(-1);
      }
      //--- ok
      return(0);
      }
      //+------------------------------------------------------------------+
      //| Expert deinitialization function |
      //+------------------------------------------------------------------+
      void OnDeinit(const int reason)
      {
      ExtExpert.Deinit();
      }
      //+------------------------------------------------------------------+
      //| Expert new tick handling function |
      //+------------------------------------------------------------------+
      void OnTick()
      {
      static datetime limit_time=0; // last trade processing time + timeout
      //--- don't process if timeout
      if(TimeCurrent()>=limit_time)
      {
      //--- check for data
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
      {
      //--- change limit time by timeout in seconds if processed
      if(ExtExpert.Processing()) limit_time=TimeCurrent()+ExtTimeOut;
      }
      }
      //---
      }
      //+------------------------------------------------------------------+


    【字體: 】【打印文章】【查看評論

    相關文章

      沒有相關內容
    人妻专区免费视频,俄罗斯啪啪到高潮喷水,国色天香社区直播在线观看
  • <menu id="iiemy"><menu id="iiemy"></menu></menu>