Student Question: How to add StopLoss and TakeProfit?

 
//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
CTrade trade;



//+------------------------------------------------------------------+
//| Execute Once                                                     |
//+------------------------------------------------------------------+


void OnInit()
  {
   
   //Test
   
   Alert("Expert Advisor has been launched");
   
   
   
   //StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
   TakeProfit = 60;
   StopLoss = 30;
   
   TakeProfitLevel = Bid + TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Bid - StopLoss*Point(); // Stop loss value defined
   
   /*
   //Code For 5-Digit Brokers
   //Here we are assuming that the TakeProfit and StopLoss are entered in Pips
   
   TakeProfitLevel = Bid + TakeProfit*Point*10;   //0.00001 * 10 = 0.0001
   StopLossLevel = Bid - StopLoss*Point*10;
   */
   
   
   
 
   //Order Setup
   
   int MagicNumber=123456; //--- set MagicNumber for your orders identification
   trade.SetExpertMagicNumber(MagicNumber);

   int deviation=10; //--- set available slippage in points when buying/selling
   trade.SetDeviationInPoints(deviation);
 
   trade.SetTypeFilling(ORDER_FILLING_RETURN); //--- order filling mode, the mode allowed by the server should be used
 
   trade.LogLevel(1); //--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own
   
   trade.SetAsyncMode(true); //--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()
   
   
   
   
   //Trading Critera 
 
   int x = 0;
   
   if (x == 1){
      HeraBuy();
   }
   
   else{
      HeraSell();
   }   
   
   
  }




//+------------------------------------------------------------------+
//| End                                                             |
//+------------------------------------------------------------------+


void OnDeinit(const int reason)
  {
      
      Alert("Expert Advisor terminated");
      
  }
  
  
  
 
//+------------------------------------------------------------------+
//| Main Loop                                                        |
//+------------------------------------------------------------------+  



void OnTick()
  {
      
      /*
      double Bid;
      Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
      Alert("Your new Bid price is: " + string(Bid)); //Display the bid price continuously
      */
   
  }
  
  
  
  
  
  
 
  
  //+------------------------------------------------------------------+
//| External Functions                                               |
//+------------------------------------------------------------------+


int HeraSell(){
   Alert("Hera is Selling");

   if(!trade.Sell(0.1))
     {
      //--- failure message
      Print("Sell() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Sell() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

   return(0);
}



int HeraBuy(){
   Alert("Hera is Buying");
   
   if(!trade.Buy(0.1))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }
     
   return(0);
}


Hi Everyone,

One of our students wants to practise Algo trading and building robots. They are wondering how they would add a stoploss and a takeprofit to their code

they think they have most of it but just don't know how to finish it.


If you can help that would be most appricated :)


Thanks

 

Forum on trading, automated trading systems and testing trading strategies

How to start with MQL5

Vladimir Karputov, 2019.10.16 17:28

Simple script: it opens a BUY position. In this case, you can set Stop loss and Take profit.

Please note - Stop loss and Take profit must be normalized using the method CSymbolInfo::NormalizePrice

//+------------------------------------------------------------------+
//|                                         Open Positions SL TP.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property script_show_inputs
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input ushort   InpStopLoss          = 15;          // Stop Loss, in pips (1.00045-1.00055=1 pips)
input ushort   InpTakeProfit        = 46;          // Take Profit, in pips (1.00045-1.00055=1 pips)
input ulong    InpDeviation         = 10;          // Deviation, in points (1.00045-1.00055=10 points)
//---
input ulong    InpMagic             = 397752952;   // Magic number
//---
double   m_stop_loss                = 0.0;         // Stop Loss      -> double
double   m_take_profit              = 0.0;         // Take Profit    -> double
double   m_adjusted_point;                         // point value adjusted for 3 or 5 points
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return;
     }
   RefreshRates();
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//--- 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;

   m_stop_loss             = InpStopLoss              * m_adjusted_point;
   m_take_profit           = InpTakeProfit            * m_adjusted_point;
//--- open buy
   double sl=(m_stop_loss==0.0)?0.0:m_symbol.Ask()-m_stop_loss;
   double tp=(m_take_profit==0.0)?0.0:m_symbol.Ask()+m_take_profit;
   m_trade.Buy(m_symbol.LotsMin(),
               m_symbol.Name(),
               m_symbol.Ask(),
               m_symbol.NormalizePrice(sl),
               m_symbol.NormalizePrice(tp));
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+

 
If desired, this script can be easily converted into an expert.
 

Our student says that they have found a way to do it thanks to this post --> https://www.mql5.com/en/articles/481

and of course people commenting but now has code that complies correctly but does not work when it runs!!! why would that be take a look :)



//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+

#include <Trade\Trade.mqh>
CTrade trade;



//+------------------------------------------------------------------+
//| Execute Once                                                     |
//+------------------------------------------------------------------+


void OnInit()
  {
   
   //Test
   
   Alert("Expert Advisor has been launched");
   
   
   
 
   //Order Setup
   
   int MagicNumber=123456; //--- set MagicNumber for your orders identification
   trade.SetExpertMagicNumber(MagicNumber);

   int deviation=10; //--- set available slippage in points when buying/selling
   trade.SetDeviationInPoints(deviation);
 
   trade.SetTypeFilling(ORDER_FILLING_RETURN); //--- order filling mode, the mode allowed by the server should be used
 
   trade.LogLevel(1); //--- logging mode: it would be better not to declare this method at all, the class will set the best mode on its own
   
   trade.SetAsyncMode(true); //--- what function is to be used for trading: true - OrderSendAsync(), false - OrderSend()
   
   
   
   
   //Trading Critera 
 
   int x = 0;
   
   if (x == 1){
      HeraBuy();
   }
   
   else{
      HeraSell();
   }   
   
   
  }




//+------------------------------------------------------------------+
//| End                                                             |
//+------------------------------------------------------------------+


void OnDeinit(const int reason)
  {
      
      Alert("Expert Advisor terminated");
      
  }
  
  
  
 
//+------------------------------------------------------------------+
//| Main Loop                                                        |
//+------------------------------------------------------------------+  



void OnTick()
  {
      
      /*
      double Bid;
      Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
      Alert("Your new Bid price is: " + string(Bid)); //Display the bid price continuously
      */
   
  }
  
  
  
  
  
  
 
  
//+------------------------------------------------------------------+
//| External Functions                                               |
//+------------------------------------------------------------------+


int HeraSell(){
   Alert("Hera is Selling");
   
   
   //StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
   TakeProfit = 60;
   StopLoss = 30;
   
   TakeProfitLevel = Bid + TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Bid - StopLoss*Point(); // Stop loss value defined
   
   /*
   //Code For 5-Digit Brokers
   //Here we are assuming that the TakeProfit and StopLoss are entered in Pips
   
   TakeProfitLevel = Bid + TakeProfit*Point*10;   //0.00001 * 10 = 0.0001
   StopLossLevel = Bid - StopLoss*Point*10;
   */
   
   
   
   if(!trade.Sell(0.1,_Symbol,Ask,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Sell() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Sell() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

   return(0);
}



int HeraBuy(){
   Alert("Hera is Buying");
   
   
   //StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
   TakeProfit = 60;
   StopLoss = 30;
   
   TakeProfitLevel = Bid + TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Bid - StopLoss*Point(); // Stop loss value defined
   
   /*
   //Code For 5-Digit Brokers
   //Here we are assuming that the TakeProfit and StopLoss are entered in Pips
   
   TakeProfitLevel = Bid + TakeProfit*Point*10;   //0.00001 * 10 = 0.0001
   StopLossLevel = Bid - StopLoss*Point*10;
   */
   
   
   
   if(!trade.Buy(0.1,_Symbol,Bid,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }
     
   return(0);
}
 

Well, if you are too lazy to read:

//+------------------------------------------------------------------+
//| Sell                                                             |
//+------------------------------------------------------------------+
int HeraSell()
  {
   Alert("Hera is Selling");
//--- StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);

   TakeProfit = 60;
   StopLoss = 30;

   TakeProfitLevel = Bid - TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Bid + StopLoss*Point(); // Stop loss value defined

   if(!trade.Sell(0.1,_Symbol,Ask,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Sell() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Sell() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Buy                                                              |
//+------------------------------------------------------------------+
int HeraBuy()
  {
   Alert("Hera is Buying");
//--- StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);

   TakeProfit = 60;
   StopLoss = 30;

   TakeProfitLevel = Ask + TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Ask - StopLoss*Point(); // Stop loss value defined

   if(!trade.Buy(0.1,_Symbol,Bid,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }
   return(0);
  }
 
Vladimir Karputov:

Well, if you are too lazy to read:

Thanks Vladimir your help is greatly appreciated, our students post their problems through our account and this student is still a beginner

and wasn't quite sure what you meant in your last post with code but is still very interest in learning.

 

Also the student says that they have made the edits but the order still won’t go through? would you possibly know why? and what resources would you suggest for a beginner :)

 
NUWETIS :

Thanks Vladimir your help is greatly appreciated, our students post their problems through our account and this student is still a beginner

and wasn't quite sure what you meant in your last post with code but is still very interest in learning.

 

Also the student says that they have made the edits but the order still won’t go through? would you possibly know why? and what resources would you suggest for a beginner :)

It is not always possible to execute a trading order the first time. The price may change or something else ... All these cases need to be handled.

Here's what the help says open BUY:

Successful completion of the Buy(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode() and value returned by ResultDeal().

Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Trade Server Return Codes
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Trade Server Return Codes
  • www.mql5.com
when attempting to fully or partially close a position if the total volume of the already present close orders and the newly placed one exceeds the current position volume The number of open positions simultaneously present on an account can be limited by the server settings. After a limit is reached, the server returns the...
 
Vladimir Karputov:

It is not always possible to execute a trading order the first time. The price may change or something else ... All these cases need to be handled.

Here's what the help says open BUY:

Successful completion of the Buy(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode() and value returned by ResultDeal().



cheers thanks to your link we saw that the problem was -> 

10021

TRADE_RETCODE_PRICE_OFF

There are no quotes to process the request


but this keeps appearing after our student added the stop loss and take profit params. before that it worked perfectly 

 
Vladimir Karputov:

It is not always possible to execute a trading order the first time. The price may change or something else ... All these cases need to be handled.

Here's what the help says open BUY:

Successful completion of the Buy(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode() and value returned by ResultDeal().

we changed part of the code.....from _Symbol in the parameters to "GBPUSD" and we get a new error which is

10016

TRADE_RETCODE_INVALID_STOPS

Invalid stops in the request

 
NUWETIS :

we changed part of the code.....from _Symbol in the parameters to "GBPUSD" and we get a new error which is

10016

TRADE_RETCODE_INVALID_STOPS

Invalid stops in the request

I can’t read minds and look into someone else’s head :).

I have no idea what exactly you wrote there.

 
Vladimir Karputov:

I can’t read minds and look into someone else’s head :).

I have no idea what exactly you wrote there.


Sorry and not a problem I was refering to this when I mentioned the 10016 error for invalid stops in the request:


10016

TRADE_RETCODE_INVALID_STOPS

Invalid stops in the request


//+------------------------------------------------------------------+
//| External Functions                                               |
//+------------------------------------------------------------------+


int HeraSell(){
   Alert("Hera is Selling");
   
   
   //StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
   TakeProfit = 60;
   StopLoss = 60;
   
   TakeProfitLevel = Bid - TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Bid + StopLoss*Point(); // Stop loss value defined
   
   /*
   //Code For 5-Digit Brokers
   //Here we are assuming that the TakeProfit and StopLoss are entered in Pips
   
   TakeProfitLevel = Bid + TakeProfit*Point*10;   //0.00001 * 10 = 0.0001
   StopLossLevel = Bid - StopLoss*Point*10;
   */
   
   
   
   if(!trade.Sell(0.1,"GBPUSD",Ask,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Sell() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Sell() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }

   return(0);
}



int HeraBuy(){
   Alert("Hera is Buying");
   
   
   //StopLoss & TakeProfit Setup
   double Bid;
   double Ask;

   double TakeProfit;
   double StopLoss;

   double TakeProfitLevel;
   double StopLossLevel;

   Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   
   TakeProfit = 60;
   StopLoss = 60;
   
   TakeProfitLevel = Ask + TakeProfit*Point();   //0.0001 // Take Profit value defined
   StopLossLevel = Ask - StopLoss*Point(); // Stop loss value defined
   
   /*
   //Code For 5-Digit Brokers
   //Here we are assuming that the TakeProfit and StopLoss are entered in Pips
   
   TakeProfitLevel = Bid + TakeProfit*Point*10;   //0.00001 * 10 = 0.0001
   StopLossLevel = Bid - StopLoss*Point*10;
   */
   
   
   
   if(!trade.Buy(0.1,"GBPUSD",Bid,StopLossLevel,TakeProfitLevel))
     {
      //--- failure message
      Print("Buy() method failed. Return code=",trade.ResultRetcode(),
            ". Code description: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Buy() method executed successfully. Return code=",trade.ResultRetcode(),
            " (",trade.ResultRetcodeDescription(),")");
     }
     
   return(0);
}


can you see whats still wrong? probably just a silly mistake.

Reason: