dclark24:
Hello,
I am running this ExpertMAMA and (...) performance results for June 2019-current day on S&P futures (even with the periodic big losses) is impressive!!
About the impressive losses you mentioned:
You want that someone here tells you why?
Please tell us what have you already analysed on the code, what do you suppose is happening, what you are sure it is happening.
Here we can talk about coding and help each other.
But I don't think anybody will get your code and run it, and analyse it, and fix it, if you don't provide a more specific situation to be discussed and talked here about it.
help us, and we help you.

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello,
I am running this ExpertMAMA and it is showing small but generally consistent profits. It is a quite complex code but has been around at least since 2011. The issue I am having is that every now and then it shows a large loss and when I review the code I could not figure out how to implement a stoploss (e.g. 10 points stoploss). Has anyone used this with stoplosses? Any ideas how to do so? I attach the initial file that is called: Expert.mqh which references a stoploss but it is not clear to me how to fix a value. By the way, if you want to play with it I can send you the main file and the remaining mqh files. Again the performance results for June 2019-current day on S&P futures (even with the periodic big losses) is impressive!!
/+------------------------------------------------------------------+ //| Expert.mqh | //| Copyright 2009-2017, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include "ExpertBase.mqh" #include "ExpertTrade.mqh" #include "ExpertSignal.mqh" #include "ExpertMoney.mqh" #include "ExpertTrailing.mqh" //+------------------------------------------------------------------+ //| enumerations | //+------------------------------------------------------------------+ //--- flags of expected events enum ENUM_TRADE_EVENTS { TRADE_EVENT_NO_EVENT =0, // no expected events TRADE_EVENT_POSITION_OPEN =0x1, // flag of expecting the "opening of position" event TRADE_EVENT_POSITION_VOLUME_CHANGE=0x2, // flag of expecting of the "modification of position volume" event TRADE_EVENT_POSITION_MODIFY =0x4, // flag of expecting of the "modification of stop order of position" event TRADE_EVENT_POSITION_CLOSE =0x8, // flag of expecting of the "closing of position" event TRADE_EVENT_POSITION_STOP_TAKE =0x10, // flag of expecting of the "triggering of stop order of position" TRADE_EVENT_ORDER_PLACE =0x20, // flag of expecting of the "placing of pending order" event TRADE_EVENT_ORDER_MODIFY =0x40, // flag of expecting of the "modification of pending order" event TRADE_EVENT_ORDER_DELETE =0x80, // flag of expecting of the "deletion of pending order" event TRADE_EVENT_ORDER_TRIGGER =0x100 // flag of expecting of the "triggering of pending order" event }; //+------------------------------------------------------------------+ //| Macro definitions. | //+------------------------------------------------------------------+ //--- check the expectation of event #define IS_WAITING_POSITION_OPENED ((m_waiting_event&TRADE_EVENT_POSITION_OPEN)!=0) #define IS_WAITING_POSITION_VOLUME_CHANGED ((m_waiting_event&TRADE_EVENT_POSITION_VOLUME_CHANGE)!=0) #define IS_WAITING_POSITION_MODIFIED ((m_waiting_event&TRADE_EVENT_POSITION_MODIFY)!=0) #define IS_WAITING_POSITION_CLOSED ((m_waiting_event&TRADE_EVENT_POSITION_CLOSE)!=0) #define IS_WAITING_POSITION_STOP_TAKE ((m_waiting_event&TRADE_EVENT_POSITION_STOP_TAKE)!=0) #define IS_WAITING_ORDER_PLACED ((m_waiting_event&TRADE_EVENT_ORDER_PLACE)!=0) #define IS_WAITING_ORDER_MODIFIED ((m_waiting_event&TRADE_EVENT_ORDER_MODIFY)!=0) #define IS_WAITING_ORDER_DELETED ((m_waiting_event&TRADE_EVENT_ORDER_DELETE)!=0) #define IS_WAITING_ORDER_TRIGGERED ((m_waiting_event&TRADE_EVENT_ORDER_TRIGGER)!=0) //+------------------------------------------------------------------+ //| Class CExpert. | //| Purpose: Base class expert advisor. | //| Derives from class CExpertBase. | //+------------------------------------------------------------------+ class CExpert : public CExpertBase { protected: int m_period_flags; // timeframe flags (as visible flags) int m_max_orders; // max number of orders (include position) MqlDateTime m_last_tick_time; // time of last tick datetime m_expiration; // time expiration order //--- history info int m_pos_tot; // number of open positions int m_deal_tot; // number of deals in history int m_ord_tot; // number of pending orders int m_hist_ord_tot; // number of orders in history datetime m_beg_date; // start date of history //--- int m_waiting_event; // flags of expected trade events //--- trading objects CExpertTrade *m_trade; // trading object CExpertSignal *m_signal; // trading signals object CExpertMoney *m_money; // money manager object CExpertTrailing *m_trailing; // trailing stops object bool m_check_volume; // check and decrease trading volume before OrderSend //--- indicators CIndicators m_indicators; // indicator collection to fast recalculations //--- market objects CPositionInfo m_position; // position info object COrderInfo m_order; // order info object //--- flags of handlers bool m_on_tick_process; // OnTick will be processed (default true) bool m_on_trade_process; // OnTrade will be processed (default false) bool m_on_timer_process; // OnTimer will be processed (default false) bool m_on_chart_event_process; // OnChartEvent will be processed (default false) bool m_on_book_event_process; // OnBookEvent will be processed (default false) public: CExpert(void); ~CExpert(void); //--- initialization bool Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic=0); void Magic(ulong value); void CheckVolumeBeforeTrade(const bool flag) { m_check_volume=flag; } //--- initialization trading objects virtual bool InitSignal(CExpertSignal *signal=NULL); virtual bool InitTrailing(CExpertTrailing *trailing=NULL); virtual bool InitMoney(CExpertMoney *money=NULL); virtual bool InitTrade(ulong magic,CExpertTrade *trade=NULL); //--- deinitialization virtual void Deinit(void); //--- methods of setting adjustable parameters void OnTickProcess(bool value) { m_on_tick_process=value; } void OnTradeProcess(bool value) { m_on_trade_process=value; } void OnTimerProcess(bool value) { m_on_timer_process=value; } void OnChartEventProcess(bool value) { m_on_chart_event_process=value; } void OnBookEventProcess(bool value) { m_on_book_event_process=value; } int MaxOrders(void) const { return(m_max_orders); } void MaxOrders(int value) { m_max_orders=value; } //--- methods of access to protected data CExpertSignal *Signal(void) const { return(m_signal); } //--- method of verification of settings virtual bool ValidationSettings(); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators=NULL); //--- event handlers virtual void OnTick(void); virtual void OnTrade(void); virtual void OnTimer(void); virtual void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam); virtual void OnBookEvent(const string &symbol); protected: //--- initialization virtual bool InitParameters(void) { return(true); } //--- deinitialization virtual void DeinitTrade(void); virtual void DeinitSignal(void); virtual void DeinitTrailing(void); virtual void DeinitMoney(void); virtual void DeinitIndicators(void); //--- refreshing virtual bool Refresh(void); //--- position select depending on netting or hedging virtual bool SelectPosition(void); //--- processing (main method) virtual bool Processing(void); //--- trade open positions check virtual bool CheckOpen(void); virtual bool CheckOpenLong(void); virtual bool CheckOpenShort(void); //--- trade open positions processing virtual bool OpenLong(double price,double sl,double tp); virtual bool OpenShort(double price,double sl,double tp); //--- trade reverse positions check virtual bool CheckReverse(void); virtual bool CheckReverseLong(void); virtual bool CheckReverseShort(void); //--- trade reverse positions processing virtual bool ReverseLong(double price,double sl,double tp); virtual bool ReverseShort(double price,double sl,double tp); //--- trade close positions check virtual bool CheckClose(void); virtual bool CheckCloseLong(void); virtual bool CheckCloseShort(void); //--- trade close positions processing virtual bool CloseAll(double lot); virtual bool Close(void); virtual bool CloseLong(double price); virtual bool CloseShort(double price); //--- trailing stop check virtual bool CheckTrailingStop(void); virtual bool CheckTrailingStopLong(void); virtual bool CheckTrailingStopShort(void); //--- trailing stop processing virtual bool TrailingStopLong(double sl,double tp); virtual bool TrailingStopShort(double sl,double tp); //--- trailing order check virtual bool CheckTrailingOrderLong(void); virtual bool CheckTrailingOrderShort(void); //--- trailing order processing virtual bool TrailingOrderLong(double delta); virtual bool TrailingOrderShort(double delta); //--- delete order check virtual bool CheckDeleteOrderLong(void); virtual bool CheckDeleteOrderShort(void); //--- delete order processing virtual bool DeleteOrders(void); virtual bool DeleteOrdersLong(void); virtual bool DeleteOrdersShort(void); virtual bool DeleteOrder(void); virtual bool DeleteOrderLong(void); virtual bool DeleteOrderShort(void); //--- lot for trade double LotOpenLong(double price,double sl); double LotOpenShort(double price,double sl); double LotReverse(double sl); double LotCheck(double volume,double price,ENUM_ORDER_TYPE order_type); //--- methods of working with trade history void PrepareHistoryDate(void); void HistoryPoint(bool from_check_trade=false); bool CheckTradeState(void); //--- set/reset waiting events void WaitEvent(ENUM_TRADE_EVENTS event) { m_waiting_event|=event; } void NoWaitEvent(ENUM_TRADE_EVENTS event) { m_waiting_event&=~event; } //--- trade events virtual bool TradeEventPositionStopTake(void) { return(true); } virtual bool TradeEventOrderTriggered(void) { return(true); } virtual bool TradeEventPositionOpened(void) { return(true); } virtual bool TradeEventPositionVolumeChanged(void) { return(true); } virtual bool TradeEventPositionModified(void) { return(true); } virtual bool TradeEventPositionClosed(void) { return(true); } virtual bool TradeEventOrderPlaced(void) { return(true); } virtual bool TradeEventOrderModified(void) { return(true); } virtual bool TradeEventOrderDeleted(void) { return(true); } virtual bool TradeEventNotIdentified(void) { return(true); } //--- timeframe functions void TimeframeAdd(ENUM_TIMEFRAMES period); int TimeframesFlags(MqlDateTime &time); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CExpert::CExpert(void) : m_period_flags(0), m_expiration(0), m_pos_tot(0), m_deal_tot(0), m_ord_tot(0), m_hist_ord_tot(0), m_beg_date(0), m_trade(NULL), m_signal(NULL), m_money(NULL), m_trailing(NULL), m_check_volume(false), m_on_tick_process(true), m_on_trade_process(false), m_on_timer_process(false), m_on_chart_event_process(false), m_on_book_event_process(false), m_max_orders(1) { m_other_symbol =true; m_other_period =true; m_adjusted_point =10; m_period =WRONG_VALUE; m_last_tick_time.min=-1; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CExpert::~CExpert(void) { Deinit(); } //+------------------------------------------------------------------+ //| Initialization and checking for input parameters | //+------------------------------------------------------------------+ bool CExpert::Init(string symbol,ENUM_TIMEFRAMES period,bool every_tick,ulong magic) { //--- returns false if the EA is initialized on a symbol/timeframe different from the current one if(symbol!=Symbol() || period!=Period()) { PrintFormat(__FUNCTION__+": wrong symbol or timeframe (must be %s:%s)",symbol,EnumToString(period)); return(false); } //--- initialize common information if(m_symbol==NULL) { if((m_symbol=new CSymbolInfo)==NULL) return(false); } if(!m_symbol.Name(symbol)) return(false); m_period =period; m_every_tick=every_tick; m_magic =magic; SetMarginMode(); if(every_tick) TimeframeAdd(WRONG_VALUE); // add all periods else TimeframeAdd(period); // add specified period //--- tuning for 3 or 5 digits int digits_adjust=(m_symbol.Digits()==3 || m_symbol.Digits()==5) ? 10 : 1; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- initializing objects expert if(!InitTrade(magic)) { Print(__FUNCTION__+": error initialization trade object"); return(false); } if(!InitSignal()) { Print(__FUNCTION__+": error initialization signal object"); return(false); } if(!InitTrailing()) { Print(__FUNCTION__+": error initialization trailing object"); return(false); } if(!InitMoney()) { Print(__FUNCTION__+": error initialization money object"); return(false); } if(!InitParameters()) { Print(__FUNCTION__+": error initialization parameters"); return(false); } //--- initialization for working with trade history PrepareHistoryDate(); HistoryPoint(); //--- primary initialization is successful, pass to the phase of tuning m_init_phase=INIT_PHASE_TUNING; //--- ok return(true); } //+------------------------------------------------------------------+ //| Sets magic number for object and its dependent objects | //+------------------------------------------------------------------+ void CExpert::Magic(ulong value) { if(m_trade!=NULL) m_trade.SetExpertMagicNumber(value); if(m_signal!=NULL) m_signal.Magic(value); if(m_money!=NULL) m_money.Magic(value); if(m_trailing!=NULL) m_trailing.Magic(value); //--- CExpertBase::Magic(value); } //+------------------------------------------------------------------+ //| Initialization trade object | //+------------------------------------------------------------------+ bool CExpert::InitTrade(ulong magic,CExpertTrade *trade=NULL) { //--- óäàëÿåì ñóùåñòâóþùèé îáúåêò if(m_trade!=NULL) delete m_trade; //--- if(trade==NULL) { if((m_trade=new CExpertTrade)==NULL) return(false); } else m_trade=trade; //--- tune trade object m_trade.SetSymbol(GetPointer(m_symbol)); m_trade.SetExpertMagicNumber(magic); m_trade.SetMarginMode(); //--- set default deviation for trading in adjusted points m_trade.SetDeviationInPoints((ulong)(3*m_adjusted_point/m_symbol.Point())); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialization signal object | //+------------------------------------------------------------------+ bool CExpert::InitSignal(CExpertSignal *signal) { if(m_signal!=NULL) delete m_signal; //--- if(signal==NULL) { if((m_signal=new CExpertSignal)==NULL) return(false); } else m_signal=signal; //--- initializing signal object if(!m_signal.Init(GetPointer(m_symbol),m_period,m_adjusted_point)) return(false); m_signal.EveryTick(m_every_tick); m_signal.Magic(m_magic); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialization trailing object | //+------------------------------------------------------------------+ bool CExpert::InitTrailing(CExpertTrailing *trailing) { if(m_trailing!=NULL) delete m_trailing; //--- if(trailing==NULL) { if((m_trailing=new CExpertTrailing)==NULL) return(false); } else m_trailing=trailing; //--- initializing trailing object if(!m_trailing.Init(GetPointer(m_symbol),m_period,m_adjusted_point)) return(false); m_trailing.EveryTick(m_every_tick); m_trailing.Magic(m_magic); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialization money object | //+------------------------------------------------------------------+ bool CExpert::InitMoney(CExpertMoney *money) { if(m_money!=NULL) delete m_money; //--- if(money==NULL) { if((m_money=new CExpertMoney)==NULL) return(false); } else m_money=money; //--- initializing money object if(!m_money.Init(GetPointer(m_symbol),m_period,m_adjusted_point)) return(false); m_money.EveryTick(m_every_tick); m_money.Magic(m_magic); //--- ok return(true); } //+------------------------------------------------------------------+ //| Validation settings | //+------------------------------------------------------------------+ bool CExpert::ValidationSettings(void) { if(!CExpertBase::ValidationSettings()) return(false); //--- Check signal parameters if(!m_signal.ValidationSettings()) { Print(__FUNCTION__+": error signal parameters"); return(false); } //--- Check trailing parameters if(!m_trailing.ValidationSettings()) { Print(__FUNCTION__+": error trailing parameters"); return(false); } //--- Check money parameters if(!m_money.ValidationSettings()) { Print(__FUNCTION__+": error money parameters"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialization indicators | //+------------------------------------------------------------------+ bool CExpert::InitIndicators(CIndicators *indicators) { //--- NULL always comes as the parameter, but here it's not significant for us CIndicators *indicators_ptr=GetPointer(m_indicators); //--- gather information about using of timeseries m_used_series|=m_signal.UsedSeries(); m_used_series|=m_trailing.UsedSeries(); m_used_series|=m_money.UsedSeries(); //--- create required timeseries if(!CExpertBase::InitIndicators(indicators_ptr)) return(false); m_signal.SetPriceSeries(m_open,m_high,m_low,m_close); m_signal.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume); if(!m_signal.InitIndicators(indicators_ptr)) { Print(__FUNCTION__+": error initialization indicators of signal object"); return(false); } m_trailing.SetPriceSeries(m_open,m_high,m_low,m_close); m_trailing.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume); if(!m_trailing.InitIndicators(indicators_ptr)) { Print(__FUNCTION__+": error initialization indicators of trailing object"); return(false); } m_money.SetPriceSeries(m_open,m_high,m_low,m_close); m_money.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume); if(!m_money.InitIndicators(indicators_ptr)) { Print(__FUNCTION__+": error initialization indicators of money object"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Deinitialization expert | //+------------------------------------------------------------------+ void CExpert::Deinit(void) { //--- delete trade class DeinitTrade(); //--- delete signal class DeinitSignal(); //--- delete trailing class DeinitTrailing(); //--- delete money class DeinitMoney(); //--- delete indicators collection DeinitIndicators(); } //+------------------------------------------------------------------+ //| Deinitialization trade object | //+------------------------------------------------------------------+ void CExpert::DeinitTrade(void) { if(m_trade!=NULL) { delete m_trade; m_trade=NULL; } } //+------------------------------------------------------------------+ //| Deinitialization signal object | //+------------------------------------------------------------------+ void CExpert::DeinitSignal(void) { if(m_signal!=NULL) { delete m_signal; m_signal=NULL; } } //+------------------------------------------------------------------+ //| Deinitialization trailing object | //+------------------------------------------------------------------+ void CExpert::DeinitTrailing(void) { if(m_trailing!=NULL) { delete m_trailing; m_trailing=NULL; } } //+------------------------------------------------------------------+ //| Deinitialization money object | //+------------------------------------------------------------------+ void CExpert::DeinitMoney(void) { if(m_money!=NULL) { delete m_money; m_money=NULL; } } //+------------------------------------------------------------------+ //| Deinitialization indicators | //+------------------------------------------------------------------+ void CExpert::DeinitIndicators(void) { m_indicators.Clear(); } //+------------------------------------------------------------------+ //| Refreshing data for processing | //+------------------------------------------------------------------+ bool CExpert::Refresh(void) { MqlDateTime time; //--- refresh rates if(!m_symbol.RefreshRates()) return(false); //--- check need processing TimeToStruct(m_symbol.Time(),time); if(m_period_flags!=WRONG_VALUE && m_period_flags!=0) if((m_period_flags&TimeframesFlags(time))==0) return(false); m_last_tick_time=time; //--- refresh indicators m_indicators.Refresh(); //--- ok return(true); } //+------------------------------------------------------------------+ //| Position select depending on netting or hedging | //+------------------------------------------------------------------+ bool CExpert::SelectPosition(void) { bool res=false; //--- if(IsHedging()) res=m_position.SelectByMagic(m_symbol.Name(),m_magic); else res=m_position.Select(m_symbol.Name()); //--- return(res); } //+------------------------------------------------------------------+ //| Main function | //+------------------------------------------------------------------+ bool CExpert::Processing(void) { //--- calculate signal direction once m_signal.SetDirection(); //--- check if open positions if(SelectPosition()) { //--- open position is available //--- check the possibility of reverse the position if(CheckReverse()) return(true); //--- check the possibility of closing the position/delete pending orders if(!CheckClose()) { //--- check the possibility of modifying the position if(CheckTrailingStop()) return(true); //--- return without operations return(false); } } //--- check if plased pending orders int total=OrdersTotal(); if(total!=0) { for(int i=total-1; i>=0; i--) { m_order.SelectByIndex(i); if(m_order.Symbol()!=m_symbol.Name()) continue; if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT || m_order.OrderType()==ORDER_TYPE_BUY_STOP) { //--- check the ability to delete a pending order to buy if(CheckDeleteOrderLong()) return(true); //--- check the possibility of modifying a pending order to buy if(CheckTrailingOrderLong()) return(true); } else { //--- check the ability to delete a pending order to sell if(CheckDeleteOrderShort()) return(true); //--- check the possibility of modifying a pending order to sell if(CheckTrailingOrderShort()) return(true); } //--- return without operations return(false); } } //--- check the possibility of opening a position/setting pending order if(CheckOpen()) return(true); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| OnTick handler | //+------------------------------------------------------------------+ void CExpert::OnTick(void) { //--- check process flag if(!m_on_tick_process) return; //--- updated quotes and indicators if(!Refresh()) return; //--- expert processing Processing(); } //+------------------------------------------------------------------+ //| OnTrade handler | //+------------------------------------------------------------------+ void CExpert::OnTrade(void) { //--- check process flag if(!m_on_trade_process) return; CheckTradeState(); } //+------------------------------------------------------------------+ //| OnTimer handler | //+------------------------------------------------------------------+ void CExpert::OnTimer(void) { //--- check process flag if(!m_on_timer_process) return; } //+------------------------------------------------------------------+ //| OnChartEvent handler | //+------------------------------------------------------------------+ void CExpert::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- check process flag if(!m_on_chart_event_process) return; } //+------------------------------------------------------------------+ //| OnBookEvent handler | //+------------------------------------------------------------------+ void CExpert::OnBookEvent(const string &symbol) { //--- check process flag if(!m_on_book_event_process) return; } //+------------------------------------------------------------------+ //| Check for position open or limit/stop order set | //+------------------------------------------------------------------+ bool CExpert::CheckOpen(void) { if(CheckOpenLong()) return(true); if(CheckOpenShort()) return(true); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for long position open or limit/stop order set | //+------------------------------------------------------------------+ bool CExpert::CheckOpenLong(void) { double price=EMPTY_VALUE; double sl=0.0; double tp=0.0; datetime expiration=TimeCurrent(); //--- check signal for long enter operations if(m_signal.CheckOpenLong(price,sl,tp,expiration)) { if(!m_trade.SetOrderExpiration(expiration)) m_expiration=expiration; return(OpenLong(price,sl,tp)); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for short position open or limit/stop order set | //+------------------------------------------------------------------+ bool CExpert::CheckOpenShort(void) { double price=EMPTY_VALUE; double sl=0.0; double tp=0.0; datetime expiration=TimeCurrent(); //--- check signal for short enter operations if(m_signal.CheckOpenShort(price,sl,tp,expiration)) { if(!m_trade.SetOrderExpiration(expiration)) m_expiration=expiration; return(OpenShort(price,sl,tp)); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Long position open or limit/stop order set | //+------------------------------------------------------------------+ bool CExpert::OpenLong(double price,double sl,double tp) { if(price==EMPTY_VALUE) return(false); //--- get lot for open double lot=LotOpenLong(price,sl); //--- check lot for open lot=LotCheck(lot,price,ORDER_TYPE_BUY); if(lot==0.0) return(false); //--- return(m_trade.Buy(lot,price,sl,tp)); } //+------------------------------------------------------------------+ //| Short position open or limit/stop order set | //+------------------------------------------------------------------+ bool CExpert::OpenShort(double price,double sl,double tp) { if(price==EMPTY_VALUE) return(false); //--- get lot for open double lot=LotOpenShort(price,sl); //--- check lot for open lot=LotCheck(lot,price,ORDER_TYPE_SELL); if(lot==0.0) return(false); //--- return(m_trade.Sell(lot,price,sl,tp)); } //+------------------------------------------------------------------+ //| Check for position reverse | //+------------------------------------------------------------------+ bool CExpert::CheckReverse(void) { if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- check the possibility of reverse the long position if(CheckReverseLong()) return(true); } else { //--- check the possibility of reverse the short position if(CheckReverseShort()) return(true); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for long position reverse | //+------------------------------------------------------------------+ bool CExpert::CheckReverseLong(void) { double price=EMPTY_VALUE; double sl=0.0; double tp=0.0; datetime expiration=TimeCurrent(); //--- check signal for long reverse operations if(m_signal.CheckReverseLong(price,sl,tp,expiration)) return(ReverseLong(price,sl,tp)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for short position reverse | //+------------------------------------------------------------------+ bool CExpert::CheckReverseShort(void) { double price=EMPTY_VALUE; double sl=0.0; double tp=0.0; datetime expiration=TimeCurrent(); //--- check signal for short reverse operations if(m_signal.CheckReverseShort(price,sl,tp,expiration)) return(ReverseShort(price,sl,tp)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Long position reverse | //+------------------------------------------------------------------+ bool CExpert::ReverseLong(double price,double sl,double tp) { if(price==EMPTY_VALUE) return(false); //--- get lot for reverse double lot=LotReverse(sl); //--- check lot if(lot==0.0) return(false); //--- bool result=true; if(IsHedging()) { //--- first close existing position lot-=m_position.Volume(); result=m_trade.PositionClose(m_position.Ticket()); } if(result) { lot=LotCheck(lot,price,ORDER_TYPE_SELL); if(lot==0.0) result=false; else result=m_trade.Sell(lot,price,sl,tp); } //--- return(result); } //+------------------------------------------------------------------+ //| Short position reverse | //+------------------------------------------------------------------+ bool CExpert::ReverseShort(double price,double sl,double tp) { if(price==EMPTY_VALUE) return(false); //--- get lot for reverse double lot=LotReverse(sl); //--- check lot if(lot==0.0) return(false); //--- bool result=true; if(IsHedging()) { //--- first close existing position lot-=m_position.Volume(); result=m_trade.PositionClose(m_position.Ticket()); } if(result) { lot=LotCheck(lot,price,ORDER_TYPE_BUY); if(lot==0.0) result=false; else result=m_trade.Buy(lot,price,sl,tp); } //--- return(result); } //+------------------------------------------------------------------+ //| Check for position close or limit/stop order delete | //+------------------------------------------------------------------+ bool CExpert::CheckClose(void) { double lot; //--- position must be selected before call if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0) return(CloseAll(lot)); //--- check for position type if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- check the possibility of closing the long position / delete pending orders to buy if(CheckCloseLong()) { DeleteOrdersLong(); return(true); } } else { //--- check the possibility of closing the short position / delete pending orders to sell if(CheckCloseShort()) { DeleteOrdersShort(); return(true); } } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for long position close or limit/stop order delete | //+------------------------------------------------------------------+ bool CExpert::CheckCloseLong(void) { double price=EMPTY_VALUE; //--- check for long close operations if(m_signal.CheckCloseLong(price)) return(CloseLong(price)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for short position close or limit/stop order delete | //+------------------------------------------------------------------+ bool CExpert::CheckCloseShort(void) { double price=EMPTY_VALUE; //--- check for short close operations if(m_signal.CheckCloseShort(price)) return(CloseShort(price)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Position close and orders delete | //+------------------------------------------------------------------+ bool CExpert::CloseAll(double lot) { bool result=false; //--- check for close operations if(IsHedging()) result=m_trade.PositionClose(m_position.Ticket()); else { if(m_position.PositionType()==POSITION_TYPE_BUY) result=m_trade.Sell(lot,0,0,0); else result=m_trade.Buy(lot,0,0,0); } result|=DeleteOrders(); //--- return(result); } //+------------------------------------------------------------------+ //| Position close | //+------------------------------------------------------------------+ bool CExpert::Close(void) { return(m_trade.PositionClose(m_symbol.Name())); } //+------------------------------------------------------------------+ //| Long position close | //+------------------------------------------------------------------+ bool CExpert::CloseLong(double price) { bool result=false; //--- if(price==EMPTY_VALUE) return(false); if(IsHedging()) result=m_trade.PositionClose(m_position.Ticket()); else result=m_trade.Sell(m_position.Volume(),price,0,0); //--- return(result); } //+------------------------------------------------------------------+ //| Short position close | //+------------------------------------------------------------------+ bool CExpert::CloseShort(double price) { bool result=false; //--- if(price==EMPTY_VALUE) return(false); if(IsHedging()) result=m_trade.PositionClose(m_position.Ticket()); else result=m_trade.Buy(m_position.Volume(),price,0,0); //--- return(result); } //+------------------------------------------------------------------+ //| Check for trailing stop/profit position | //+------------------------------------------------------------------+ bool CExpert::CheckTrailingStop(void) { //--- position must be selected before call if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- check the possibility of modifying the long position if(CheckTrailingStopLong()) return(true); } else { //--- check the possibility of modifying the short position if(CheckTrailingStopShort()) return(true); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for trailing stop/profit long position | //+------------------------------------------------------------------+ bool CExpert::CheckTrailingStopLong(void) { double sl=EMPTY_VALUE; double tp=EMPTY_VALUE; //--- check for long trailing stop operations if(m_trailing.CheckTrailingStopLong(GetPointer(m_position),sl,tp)) { double position_sl=m_position.StopLoss(); double position_tp=m_position.TakeProfit(); if(sl==EMPTY_VALUE) sl=position_sl; else sl=m_symbol.NormalizePrice(sl); if(tp==EMPTY_VALUE) tp=position_tp; else tp=m_symbol.NormalizePrice(tp); if(sl==position_sl && tp==position_tp) return(false); //--- long trailing stop operations return(TrailingStopLong(sl,tp)); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for trailing stop/profit short position | //+------------------------------------------------------------------+ bool CExpert::CheckTrailingStopShort(void) { double sl=EMPTY_VALUE; double tp=EMPTY_VALUE; //--- check for short trailing stop operations if(m_trailing.CheckTrailingStopShort(GetPointer(m_position),sl,tp)) { double position_sl=m_position.StopLoss(); double position_tp=m_position.TakeProfit(); if(sl==EMPTY_VALUE) sl=position_sl; else sl=m_symbol.NormalizePrice(sl); if(tp==EMPTY_VALUE) tp=position_tp; else tp=m_symbol.NormalizePrice(tp); if(sl==position_sl && tp==position_tp) return(false); //--- short trailing stop operations return(TrailingStopShort(sl,tp)); } //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Trailing stop/profit long position | //+------------------------------------------------------------------+ bool CExpert::TrailingStopLong(double sl,double tp) { bool result; //--- if(IsHedging()) result=m_trade.PositionModify(m_position.Ticket(),sl,tp); else result=m_trade.PositionModify(m_symbol.Name(),sl,tp); //--- return(result); } //+------------------------------------------------------------------+ //| Trailing stop/profit short position | //+------------------------------------------------------------------+ bool CExpert::TrailingStopShort(double sl,double tp) { bool result; //--- if(IsHedging()) result=m_trade.PositionModify(m_position.Ticket(),sl,tp); else result=m_trade.PositionModify(m_symbol.Name(),sl,tp); //--- return(result); } //+------------------------------------------------------------------+ //| Check for trailing long limit/stop order | //+------------------------------------------------------------------+ bool CExpert::CheckTrailingOrderLong(void) { double price; //--- check the possibility of modifying the long order if(m_signal.CheckTrailingOrderLong(GetPointer(m_order),price)) return(TrailingOrderLong(m_order.PriceOpen()-price)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for trailing short limit/stop order | //+------------------------------------------------------------------+ bool CExpert::CheckTrailingOrderShort(void) { double price; //--- check the possibility of modifying the short order if(m_signal.CheckTrailingOrderShort(GetPointer(m_order),price)) return(TrailingOrderShort(m_order.PriceOpen()-price)); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Trailing long limit/stop order | //+------------------------------------------------------------------+ bool CExpert::TrailingOrderLong(double delta) { ulong ticket=m_order.Ticket(); double price =m_symbol.NormalizePrice(m_order.PriceOpen()-delta); double sl =m_symbol.NormalizePrice(m_order.StopLoss()-delta); double tp =m_symbol.NormalizePrice(m_order.TakeProfit()-delta); //--- modifying the long order return(m_trade.OrderModify(ticket,price,sl,tp,m_order.TypeTime(),m_order.TimeExpiration())); } //+------------------------------------------------------------------+ //| Trailing short limit/stop order | //+------------------------------------------------------------------+ bool CExpert::TrailingOrderShort(double delta) { ulong ticket=m_order.Ticket(); double price =m_symbol.NormalizePrice(m_order.PriceOpen()-delta); double sl =m_symbol.NormalizePrice(m_order.StopLoss()-delta); double tp =m_symbol.NormalizePrice(m_order.TakeProfit()-delta); //--- modifying the short order return(m_trade.OrderModify(ticket,price,sl,tp,m_order.TypeTime(),m_order.TimeExpiration())); } //+------------------------------------------------------------------+ //| Check for delete long limit/stop order | //+------------------------------------------------------------------+ bool CExpert::CheckDeleteOrderLong(void) { double price; //--- check the possibility of deleting the long order if(m_expiration!=0 && TimeCurrent()>m_expiration) { m_expiration=0; return(DeleteOrderLong()); } if(m_signal.CheckCloseLong(price)) return(DeleteOrderLong()); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Check for delete short limit/stop order | //+------------------------------------------------------------------+ bool CExpert::CheckDeleteOrderShort(void) { double price; //--- check the possibility of deleting the short order if(m_expiration!=0 && TimeCurrent()>m_expiration) { m_expiration=0; return(DeleteOrderShort()); } if(m_signal.CheckCloseShort(price)) return(DeleteOrderShort()); //--- return without operations return(false); } //+------------------------------------------------------------------+ //| Delete all limit/stop orders | //+------------------------------------------------------------------+ bool CExpert::DeleteOrders(void) { bool result=true; int total=OrdersTotal(); //--- for(int i=total-1;i>=0;i--) if(m_order.Select(OrderGetTicket(i))) { if(m_order.Symbol()!=m_symbol.Name()) continue; result&=DeleteOrder(); } //--- return(result); } //+------------------------------------------------------------------+ //| Delete all limit/stop long orders | //+------------------------------------------------------------------+ bool CExpert::DeleteOrdersLong(void) { bool result=true; int total=OrdersTotal(); //--- for(int i=total-1;i>=0;i--) if(m_order.Select(OrderGetTicket(i))) { if(m_order.Symbol()!=m_symbol.Name()) continue; if(m_order.OrderType()!=ORDER_TYPE_BUY_STOP && m_order.OrderType()!=ORDER_TYPE_BUY_LIMIT) continue; result&=DeleteOrder(); } //--- return(result); } //+------------------------------------------------------------------+ //| Delete all limit/stop orders | //+------------------------------------------------------------------+ bool CExpert::DeleteOrdersShort(void) { bool result=true; int total=OrdersTotal(); //--- for(int i=total-1;i>=0;i--) if(m_order.Select(OrderGetTicket(i))) { if(m_order.Symbol()!=m_symbol.Name()) continue; if(m_order.OrderType()!=ORDER_TYPE_SELL_STOP && m_order.OrderType()!=ORDER_TYPE_SELL_LIMIT) continue; result&=DeleteOrder(); } //--- return(result); } //+------------------------------------------------------------------+ //| Delete limit/stop order | //+------------------------------------------------------------------+ bool CExpert::DeleteOrder(void) { return(m_trade.OrderDelete(m_order.Ticket())); } //+------------------------------------------------------------------+ //| Delete long limit/stop order | //+------------------------------------------------------------------+ bool CExpert::DeleteOrderLong(void) { return(m_trade.OrderDelete(m_order.Ticket())); } //+------------------------------------------------------------------+ //| Delete short limit/stop order | //+------------------------------------------------------------------+ bool CExpert::DeleteOrderShort(void) { return(m_trade.OrderDelete(m_order.Ticket())); } //+------------------------------------------------------------------+ //| Method of getting the lot for open long position. | //+------------------------------------------------------------------+ double CExpert::LotOpenLong(double price,double sl) { return(m_money.CheckOpenLong(price,sl)); } //+------------------------------------------------------------------+ //| Method of getting the lot for open short position. | //+------------------------------------------------------------------+ double CExpert::LotOpenShort(double price,double sl) { return(m_money.CheckOpenShort(price,sl)); } //+------------------------------------------------------------------+ //| Method of getting the lot for reverse position. | //+------------------------------------------------------------------+ double CExpert::LotReverse(double sl) { return(m_money.CheckReverse(GetPointer(m_position),sl)); }