<em id="8ntms"></em><progress id="8ntms"><track id="8ntms"></track></progress>
  • <em id="8ntms"></em>
    1. <tbody id="8ntms"><track id="8ntms"></track></tbody>
      1. 您現在的位置:程序化交易>> 外匯現貨>> 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;
          }
          }
          //---
          }
          //+------------------------------------------------------------------+


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

        相關文章

          沒有相關內容
        真钱三公