<ins id="d3tjn"><th id="d3tjn"><delect id="d3tjn"></delect></th></ins>

        <strike id="d3tjn"><span id="d3tjn"><ol id="d3tjn"></ol></span></strike>

        <output id="d3tjn"></output>

            您現在的位置:程序化交易>> 外匯現貨>> 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;
              }
              }
              //---
              }
              //+------------------------------------------------------------------+


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

            相關文章

              沒有相關內容
            男男乱J伦高H小说

                <ins id="d3tjn"><th id="d3tjn"><delect id="d3tjn"></delect></th></ins>

                  <strike id="d3tjn"><span id="d3tjn"><ol id="d3tjn"></ol></span></strike>

                  <output id="d3tjn"></output>