//+------------------------------------------------------------------+ //| Samples.mqh | //| Copyright 2015, Vasiliy Sokolov. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Vasiliy Sokolov." #property link "http://www.mql5.com" #include #include //+------------------------------------------------------------------+ //| An example of a strategy based on two Moving Averages. | //| If the fast MA crosses the slow one from upside down | //| we buy, if from top bottom - we sell. | //+------------------------------------------------------------------+ class CMovingAverage : public CStrategy { private: bool IsTrackEvents(const MarketEvent &event); protected: virtual void InitBuy(const MarketEvent &event); virtual void InitSell(const MarketEvent &event); virtual void SupportBuy(const MarketEvent &event,CPosition *pos); virtual void SupportSell(const MarketEvent &event,CPosition *pos); virtual void OnSymbolChanged(string new_symbol); virtual void OnTimeframeChanged(ENUM_TIMEFRAMES new_tf); virtual string ExpertNameFull(void); virtual bool ParseXmlParams(CXmlElement *params); public: CIndMovingAverage FastMA; // Fast moving average CIndMovingAverage SlowMA; // Slow moving average CMovingAverage(void); }; //+------------------------------------------------------------------+ //| Initialization | //+------------------------------------------------------------------+ CMovingAverage::CMovingAverage(void) { } //+------------------------------------------------------------------+ //| React to symbol change | //+------------------------------------------------------------------+ void CMovingAverage::OnSymbolChanged(string new_symbol) { FastMA.Symbol(new_symbol); SlowMA.Symbol(new_symbol); } //+------------------------------------------------------------------+ //| React to timeframe change | //+------------------------------------------------------------------+ void CMovingAverage::OnTimeframeChanged(ENUM_TIMEFRAMES new_tf) { FastMA.Timeframe(new_tf); SlowMA.Timeframe(new_tf); } //+------------------------------------------------------------------+ //| The full unique name of the EA | //+------------------------------------------------------------------+ string CMovingAverage::ExpertNameFull(void) { string name=ExpertName(); name += "[" + ExpertSymbol(); name += "-" + StringSubstr(EnumToString(Timeframe()), 7); name += "-" + (string)FastMA.MaPeriod(); name += "-" + (string)SlowMA.MaPeriod(); name += "-" + StringSubstr(EnumToString(SlowMA.MaMethod()), 5); name += "]"; return name; } //+------------------------------------------------------------------+ //| We buy when the fast MA is above the slow one. | //+------------------------------------------------------------------+ void CMovingAverage::InitBuy(const MarketEvent &event) { if(!IsTrackEvents(event))return; // Handling only the required event! if(positions.open_buy > 0) return; // If there is at least one open position, no need to buy, as we've already bought! if(FastMA.OutValue(1) > SlowMA.OutValue(1)) // If no open buy positions, check if the fast MA is above the slow one: Trade.Buy(MM.GetLotFixed(), ExpertSymbol(), ""); // If above, buy. } //+------------------------------------------------------------------+ //| Close the long position when the fast MA is below the | //| slow one. | //+------------------------------------------------------------------+ void CMovingAverage::SupportBuy(const MarketEvent &event,CPosition *pos) { if(!IsTrackEvents(event))return; // Handling only the required event! if(FastMA.OutValue(1) < SlowMA.OutValue(1)) // If the fast MA is below the slow one - pos.CloseAtMarket("Exit by cross over"); // Close the position. } //+------------------------------------------------------------------+ //| We buy when the fast MA is above the slow one. | //+------------------------------------------------------------------+ void CMovingAverage::InitSell(const MarketEvent &event) { if(!IsTrackEvents(event))return; // Handling only the required event! if(positions.open_sell > 0) return; // If there is at least one short position, no need to sell, as we've already sold! if(FastMA.OutValue(1) < SlowMA.OutValue(1)) // If no open buy positions, check if the fast MA is above the slow one: Trade.Sell(1.0,ExpertSymbol(),""); // If above that , we buy. } //+------------------------------------------------------------------+ //| Close the short position when the fast MA is above the | //| the slow one. | //+------------------------------------------------------------------+ void CMovingAverage::SupportSell(const MarketEvent &event,CPosition *pos) { if(!IsTrackEvents(event))return; // Handling only the required event! if(FastMA.OutValue(1) > SlowMA.OutValue(1)) // If the fast MA is above the slow one - pos.CloseAtMarket("Exit by cross under"); // Close the position. } //+------------------------------------------------------------------+ //| Filters incoming events. If the passed event is not | //| processed by the strategy, returns false; if it is processed | //| returns true. | //+------------------------------------------------------------------+ bool CMovingAverage::IsTrackEvents(const MarketEvent &event) { //We handle only opening of a new bar on the working symbol and timeframe if(event.type != MARKET_EVENT_BAR_OPEN)return false; if(event.period != Timeframe())return false; if(event.symbol != ExpertSymbol())return false; return true; } //+------------------------------------------------------------------+ //| The strategy's specific parameters are parsed inside it in | //| this method overridden from CStrategy | //+------------------------------------------------------------------+ bool CMovingAverage::ParseXmlParams(CXmlElement *params) { bool res=true; for(int i=0; i