OnTakeProfit & OnStopLoss instead of OnTradeTransaction() - page 2

 

Hi,

Kl_Urt: thanks for your code. This is similar to my code which I'm using for a while.

I define a class with special methods:

#include <myTrade/DealInfo.mqh>
typedef void(*fct_TA)(const MqlTradeTransaction &trans);
class CTransaction {
private:
  fct_TA  m_fct_OnTrigger;
  fct_TA  m_fct_OnBuy;
  fct_TA  m_fct_OnSell;

  fct_TA  m_fct_OnSL;
  fct_TA  m_fct_OnSLBuy;
  fct_TA  m_fct_OnSLSell;

  fct_TA  m_fct_OnTP;
  fct_TA  m_fct_OnTPBuy;
  fct_TA  m_fct_OnTPSell;

public:
  CTransaction() {
    m_fct_OnTrigger =NULL; // Buy or Sell event
    m_fct_OnBuy     =NULL;
    m_fct_OnSell    =NULL;

    m_fct_OnSL      =NULL; // hit SL :-(
    m_fct_OnSLBuy   =NULL;
    m_fct_OnSLSell  =NULL;

    m_fct_OnTP      =NULL; // hit TP :-)
    m_fct_OnTPBuy   =NULL;
    m_fct_OnTPSell  =NULL;
  }
  ~CTransaction() {
  }


  void Set_OnTrigger (fct_TA f) {
    m_fct_OnTrigger = f;
  }
  void Set_OnBuy (fct_TA f) {
    m_fct_OnBuy = f;
  }
  void Set_OnSell (fct_TA f) {
    m_fct_OnSell = f;
  }

  void Set_OnSL (fct_TA f) {
    m_fct_OnSL = f;
  }
  void Set_OnSLBuy (fct_TA f) {
    m_fct_OnSLBuy = f;
  }
  void Set_OnSLSell (fct_TA f) {
    m_fct_OnSLSell = f;
  }

  void Set_OnTP (fct_TA f) {
    m_fct_OnTP = f;
  }
  void Set_OnTPBuy (fct_TA f) {
    m_fct_OnTPBuy = f;
  }
  void Set_OnTPSell (fct_TA f) {
    m_fct_OnTPSell = f;
  }

  
  void OnTradeTransaction (const MqlTradeTransaction &trans) {
    myDealInfo di;
    switch (trans.type) {
    case TRADE_TRANSACTION_DEAL_ADD:
      if (di.SelectByTicket(trans.deal)) {
        switch (di.Entry()) {
        case DEAL_ENTRY_IN:
          if (di.Reason() == DEAL_REASON_EXPERT) {
            if (m_fct_OnTrigger!=NULL) m_fct_OnTrigger (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
              if (m_fct_OnBuy!=NULL) m_fct_OnBuy (trans);   
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnSell!=NULL) m_fct_OnSell (trans);         
              break;
            }
          }
          break;


        case DEAL_ENTRY_OUT:
          switch (di.Reason()) {
          case DEAL_REASON_SL:
            if (m_fct_OnSL!=NULL)  m_fct_OnSL (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
             if (m_fct_OnSLBuy!=NULL)  m_fct_OnSLBuy (trans);
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnSLSell!=NULL) m_fct_OnSLSell (trans);
              break;
            }
            break;
          case DEAL_REASON_TP:
            if (m_fct_OnTP!=NULL)  m_fct_OnTP (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
              if (m_fct_OnTPBuy!=NULL) m_fct_OnTPBuy (trans);
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnTPSell!=NULL) m_fct_OnTPSell (trans);
              break;
            }
            break;
          }
          break;
        }
      }
      break;
    }
  }
};


Usage of this class can be:


CTransaction  *g_TA;

void OnBuy(const MqlTradeTransaction &trans);
void OnSell(const MqlTradeTransaction &trans);
void OnSL(const MqlTradeTransaction &trans);

int OnInit() {
  g_TA = new CTransaction();
  g_TA.Set_OnBuy  (OnBuy);
  g_TA.Set_OnSell (OnSell);
  g_TA.Set_OnSL   (OnSL);
  ...
}
void OnDeinit(const int reason) {
  delete g_TA;
  ...
}

void OnBuy (const MqlTradeTransaction &trans) {
  Print ("Buy event");
  // Handle Buy event
   ...
}
void OnSell (const MqlTradeTransaction &trans) {
  Print ("Sell event");
  // Handle Sell event
   ...
}
void OnSL (const MqlTradeTransaction &trans) {
  Print ("SL event");
  // Handle SL event
   ...
}

void OnTradeTransaction (const MqlTradeTransaction &trans, 
                         const MqlTradeRequest &request, 
                         const MqlTradeResult &result)  {
  g_TA.OnTradeTransaction (trans);
}
 

Hi @Dr Matthias Hammelsbeck

Would you share the customized DealInfo.mqh file, too?

Thanks & Regards

 
spottypegasus:

Hi @Dr Matthias Hammelsbeck

Would you share the customized DealInfo.mqh file, too?

Thanks & Regards

Yes. Please see the attached file

Files:
 
Dr Matthias Hammelsbeck:

Yes. Please see the attached file

Great! Thanks a bunch!
 

I need to have an OnClosePosition event when a position is closed manually....

Can this be done through OnTradeTransaction event?

Can someone show me how it is done?

Thanks & Regards

 
spottypegasus:

I need to have an OnClosePosition event when a position is closed manually....

Can this be done through OnTradeTransaction event?

Can someone show me how it is done?

Thanks & Regards

Printing out all in OnTradeTransaction did not trigger "close position" MANUALLY....

It only triggers close position when TP or SL is hit!

The following is my OnTradeTransaction code in order to catch the deal type or result code, but none was fired when I close a position MANUALLY...

Hope somebody can help me with it...

Thanks & regards...

//+------------------------------------------------------------------+ 

//| TradeTransaction function                                        | 

//+------------------------------------------------------------------+ 

void OnTradeTransaction(const MqlTradeTransaction & trans,
                        const MqlTradeRequest & request,
                        const MqlTradeResult & result)

{
     Print(GetRetcodeID(result.retcode)); // TRADE_RETCODE_POSITION_CLOSED
     Print(GetDealDescription(trans.deal_type));
}                        


//+------------------------------------------------------------------+ 

//| convert numeric response codes to string mnemonics               | 

//+------------------------------------------------------------------+ 

string GetRetcodeID(int retcode) 
  { 
   switch(retcode) 

     { 
      case 10004: return("TRADE_RETCODE_REQUOTE");              
      case 10006: return("TRADE_RETCODE_REJECT");               
      case 10007: return("TRADE_RETCODE_CANCEL");               
      case 10008: return("TRADE_RETCODE_PLACED");               
      case 10009: return("TRADE_RETCODE_DONE");                 
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");         
      case 10011: return("TRADE_RETCODE_ERROR");                
      case 10012: return("TRADE_RETCODE_TIMEOUT");              
      case 10013: return("TRADE_RETCODE_INVALID");              
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");       
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");        
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");        
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");       
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");        
      case 10019: return("TRADE_RETCODE_NO_MONEY");             
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");        
      case 10021: return("TRADE_RETCODE_PRICE_OFF");            
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");   
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");        
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");    
      case 10025: return("TRADE_RETCODE_NO_CHANGES");           
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");   
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");   
      case 10028: return("TRADE_RETCODE_LOCKED");               
      case 10029: return("TRADE_RETCODE_FROZEN");               
      case 10030: return("TRADE_RETCODE_INVALID_FILL");         
      case 10031: return("TRADE_RETCODE_CONNECTION");           
      case 10032: return("TRADE_RETCODE_ONLY_REAL");            
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");         
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");         
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");        
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");      
      default: 
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode)); 
     } 

//--- 

  }


string GetDealDescription(int deal_type)
  {

//---

   switch(deal_type)
     {
      case DEAL_TYPE_BALANCE:                  return ("balance");
      case DEAL_TYPE_CREDIT:                   return ("credit");
      case DEAL_TYPE_CHARGE:                   return ("charge");
      case DEAL_TYPE_CORRECTION:               return ("correction");
      case DEAL_TYPE_BUY:                      return ("buy"); 
      case DEAL_TYPE_SELL:                     return ("sell"); 
      case DEAL_TYPE_BONUS:                    return ("bonus");
      case DEAL_TYPE_COMMISSION:               return ("additional commission");
      case DEAL_TYPE_COMMISSION_DAILY:         return ("daily commission");
      case DEAL_TYPE_COMMISSION_MONTHLY:       return ("monthly commission");
      case DEAL_TYPE_COMMISSION_AGENT_DAILY:   return ("daily agent commission");
      case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: return ("monthly agent commission");
      case DEAL_TYPE_INTEREST:                 return ("interest rate");
      case DEAL_TYPE_BUY_CANCELED:             return ("cancelled buy deal"); 
      case DEAL_TYPE_SELL_CANCELED:            return ("cancelled sell deal"); 
      default: 
         return("DEAL_TYPE_UNKNOWN="+IntegerToString(deal_type)); 
     }

}
 

Hi,

please see the content of the header file myTrade/Transaction.mqh:

#include <myTrade/DealInfo.mqh>
typedef void(*fct_TA)(const MqlTradeTransaction &trans);
class CTransaction {
private:
  fct_TA  m_fct_OnTrigger;
  fct_TA  m_fct_OnBuy;
  fct_TA  m_fct_OnSell;

  fct_TA  m_fct_OnSL;
  fct_TA  m_fct_OnSLBuy;
  fct_TA  m_fct_OnSLSell;

  fct_TA  m_fct_OnTP;
  fct_TA  m_fct_OnTPBuy;
  fct_TA  m_fct_OnTPSell;


  fct_TA  m_fct_OnOpenPositionManually;
  fct_TA  m_fct_OnClosePositionManually;

public:
  CTransaction() {
    m_fct_OnTrigger                =NULL; // Buy or Sell event
    m_fct_OnBuy                    =NULL;
    m_fct_OnSell                   =NULL;

    m_fct_OnSL                     =NULL; // hit SL :-(
    m_fct_OnSLBuy                  =NULL;
    m_fct_OnSLSell                 =NULL;

    m_fct_OnTP                     =NULL; // hit TP :-)
    m_fct_OnTPBuy                  =NULL;
    m_fct_OnTPSell                 =NULL;

    m_fct_OnOpenPositionManually   =NULL;
    m_fct_OnClosePositionManually  =NULL;
  }
  ~CTransaction() {
  }


  void Set_OnTrigger (fct_TA f) {
    m_fct_OnTrigger = f;
  }
  void Set_OnBuy (fct_TA f) {
    m_fct_OnBuy = f;
  }
  void Set_OnSell (fct_TA f) {
    m_fct_OnSell = f;
  }

  void Set_OnSL (fct_TA f) {
    m_fct_OnSL = f;
  }
  void Set_OnSLBuy (fct_TA f) {
    m_fct_OnSLBuy = f;
  }
  void Set_OnSLSell (fct_TA f) {
    m_fct_OnSLSell = f;
  }

  void Set_OnTP (fct_TA f) {
    m_fct_OnTP = f;
  }
  void Set_OnTPBuy (fct_TA f) {
    m_fct_OnTPBuy = f;
  }
  void Set_OnTPSell (fct_TA f) {
    m_fct_OnTPSell = f;
  }

  void Set_OnOpenPositionManually (fct_TA f) {
    m_fct_OnOpenPositionManually = f;
  }
  void Set_OnClosePositionManually (fct_TA f) {
    m_fct_OnClosePositionManually = f;
  }

  
  void OnTradeTransaction (const MqlTradeTransaction &trans) {
    myDealInfo di;
    switch (trans.type) {
    case TRADE_TRANSACTION_DEAL_ADD:
      if (di.SelectByTicket(trans.deal)) {
        switch (di.Entry()) {
        case DEAL_ENTRY_IN:
          switch (di.Reason()) {
          case DEAL_REASON_EXPERT:
            if (m_fct_OnTrigger!=NULL) m_fct_OnTrigger (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
              if (m_fct_OnBuy!=NULL) m_fct_OnBuy (trans);   
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnSell!=NULL) m_fct_OnSell (trans);         
              break;
            }
            break;
          case DEAL_REASON_CLIENT:
            if (m_fct_OnOpenPositionManually!=NULL)  m_fct_OnOpenPositionManually (trans);
            break;
          }
          break;
          
          
        case DEAL_ENTRY_OUT:
          switch (di.Reason()) {
          case DEAL_REASON_SL:
            if (m_fct_OnSL!=NULL)  m_fct_OnSL (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
             if (m_fct_OnSLBuy!=NULL)  m_fct_OnSLBuy (trans);
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnSLSell!=NULL) m_fct_OnSLSell (trans);
              break;
            }
            break;
          case DEAL_REASON_TP:
            if (m_fct_OnTP!=NULL)  m_fct_OnTP (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
              if (m_fct_OnTPBuy!=NULL) m_fct_OnTPBuy (trans);
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnTPSell!=NULL) m_fct_OnTPSell (trans);
              break;
            }
            break;
          case DEAL_REASON_CLIENT:
            if (m_fct_OnClosePositionManually!=NULL)  m_fct_OnClosePositionManually (trans);
            break;
          }
          break;
        }
      }
      break;
    }
  }


};


Usage of this header can be:

#include <myTrade/Transaction.mqh>
CTransaction  *g_TA;

void OnOpenPositionManually(const MqlTradeTransaction &trans);
void OnClosePositionManually(const MqlTradeTransaction &trans);

int OnInit() {
   g_TA = new CTransaction();
   g_TA.Set_OnOpenPositionManually (OnOpenPositionManually);
   g_TA.Set_OnClosePositionManually (OnClosePositionManually);
   return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
   delete g_TA;
}
void OnOpenPositionManually(const MqlTradeTransaction &trans) {
   Print ("Open Position Event");
}
void OnClosePositionManually(const MqlTradeTransaction &trans) {
   Print ("Close Position Event");
}
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result) {
   g_TA.OnTradeTransaction (trans);
}
 
Dr Matthias Hammelsbeck:

Hi,

please see the content of the header file myTrade/Transaction.mqh:


Usage of this header can be:

Thanks for your help.... It worked! :-)

But one thing I need to ask you...

What is the need of putting DEAL_REASON_EXPERT & DEAL_REASON_CLIENT in the DEAL_ENTRY_IN block?

In my case, I don't care if BUY or SELL is done manually or by EA... Isn't that so in most cases?

Having that said, we don't need the OnOpenPositionManually event because by omitting the DEAL_REASON_EXPERT & DEAL_REASON_CLIENT in the DEAL_ENTRY_IN block covers it already...

The following is my DEAL_ENTRY_IN block of code and it worked as I wanted...

Regards,

.
.
.
        case DEAL_ENTRY_IN:
//          switch (di.Reason()) {
//          case DEAL_REASON_EXPERT:
            if (m_fct_OnTrigger!=NULL) m_fct_OnTrigger (trans);
            switch (trans.deal_type) {
            case DEAL_TYPE_BUY:
              if (m_fct_OnBuy!=NULL) m_fct_OnBuy (trans);   
              break;
            case DEAL_TYPE_SELL:
              if (m_fct_OnSell!=NULL) m_fct_OnSell (trans);         
              break;
            }
            break;

//          case DEAL_REASON_CLIENT:
//            if (m_fct_OnOpenPositionManually!=NULL)  m_fct_OnOpenPositionManually (trans);
//            break;
//          }
//          break;

.
.
.
          
 
spottypegasus:

Thanks for your help.... It worked! :-)

But one thing I need to ask you...

What is the need of putting DEAL_REASON_EXPERT & DEAL_REASON_CLIENT in the DEAL_ENTRY_IN block?

Because I want to distinguish between opening an order manually by the terminal and automatically by an expert advisor.

Matthias

 
Dr Matthias Hammelsbeck:

Because I want to distinguish between opening an order manually by the terminal and automatically by an expert advisor.

Matthias

OK, gotcha!


Thanks again for your help...


Regards,

Reason: