Take Profit Issue with my bot

 

I have this script that is supposed to be used for risk management on my trading account. However, I have an issue taking profit. The script calculates the tp levels of 1:1,1:2, and 1:3 once a stop loss has been inputed by the user. My first tp level works flawlessy and using the same structure my tp2 should work the same way. It takes too much partial profit numerous amounts of times. During testing even when changing the lot size it doesn't calculate the right volume of trade to close anymore. Has anyone else been having this issue?\


Here is my code:


//----------------------------------------------Project Description------------------------------------------------------------------//

//----------------------------------------------------------------------------------------------------------------------------------//

//AUTHOR: Colen James

//LAST REVISED DATE: 11/29/2022

//DISCLAIMER: WHILE TRADING THE FINANCIAL MARKETS THERE IS HIGH RISK INVOLED, THE CREATOR OF THIS SCRIPT IS NOT RESPONSIBLE FOR ACCOUNT PERFORMANCE, THIS IS ONLY A TOOL



//This expert advisor was created to monitor a traders risk management and to automatically enforce it for the user.

//This script will utilize take partial take profits and stop a trailing stop loss

//Will act on a trade made and calculate:

//       .Take Profit Levels:

//          -> TP 1:1 (move stop loss to break even, take 1/3 of overall trade lots off)

//          -> TP 1:2 (take another 1/3 of the position size out of the trade, stop loss stays at break even)

//          -> TP 1:whatever (take the last 1/3 of the position out of the trade)

//        .Display TP's as lines on the chart as well as the prices they are set at on the side in text on the chart

//          -> colors will change based on if the Tp was hit or not





//----------------------------------------------Intialization/Imports------------------------------------------------------------------//

//----------------------------------------------------------------------------------------------------------------------------------//

#include <Trade\Trade.mqh>

#include <Indicators\Oscilators.mqh>

#include <ChartObjects\ChartObject.mqh>

//creates instance of Ctrade

CTrade trade;

//checks if the tp has been hit

bool check1, check2, check3;

int counter =0;



//--------------------------------------------------Start of OnTick() Function----------------------------------------------------//

//     DESCRIPTION: function that wiill be triggered for every new tick on the chart

//-------------------------------------------------------------------------------------------------------------------------------//



void OnTick()

  {

    //calls checkPositions

    checkPositions();

      

    if(PositionsTotal()==0)

    {

      trade.Buy(3.0,_Symbol,0.0,NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID)-125*_Point,_Digits),0.0,NULL);

    }

  }





//--------------------------------------------------Start of checkPositions() Function----------------------------------------------------//

//     DESCRIPTION: Will check the open positons available and get the information that corresponds with the indexed open position

//-------------------------------------------------------------------------------------------------------------------------------//

void checkPositions()

{

    //iterates through all the open positions

    for(int i = PositionsTotal() - 1; i >= 0; i--)

    {

      //gets the unsigned ticket number of indexed position

      ulong ticket = PositionGetTicket(i);

     

      //checks if the ticket number is valid

      if(ticket>0)

      {

         //selects the position by ticket for further operation

          PositionSelectByTicket(ticket);

          //stores the trade type of the position indexed

          ENUM_POSITION_TYPE tradeType = PositionGetInteger(POSITION_TYPE);

          //stores the stop loss of the indexed position

          double stopLossPrice = NormalizeDouble(PositionGetDouble(POSITION_SL),_Digits);

          //stores open price of indexed position

          double openPositionPrice = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits);

          //stoploss in pips

          double stopLoss = NormalizeDouble(MathAbs(stopLossPrice-openPositionPrice),_Digits);

         

          //call the setTp function to calculate the take profit values for this position based on the stopLoss

          setTP(ticket, stopLoss,openPositionPrice,tradeType,stopLossPrice);

      }

     }

}





//---------------------------------------------Start of setTP() Function----------------------------------------------------------//

//     DESCRIPTION: will get the TP values based on the stoploss that is found for the indexed position

//-------------------------------------------------------------------------------------------------------------------------------//

void setTP(ulong ticket,double stopLoss, double openPositionPrice, ENUM_POSITION_TYPE tradeType, double stopLossPrice)

{

   //keeps track of the take profit levels

   double tp1,tp2,tp3;

 

   //determines the tp values based on the trade type

   if(EnumToString(tradeType) == "POSITION_TYPE_BUY")

   {

      //set up take profit levels based on stop loss and type of trade(buy)

      tp1 = openPositionPrice + stopLoss;

      tp2 = openPositionPrice + stopLoss*2;

      tp3 = openPositionPrice + stopLoss*3;

   }

   if(EnumToString(tradeType) == "POSITION_TYPE_SELL")

   {

      //set up take profit levels based on stop loss and type of trade(sell)

      tp1 = openPositionPrice - stopLoss;

      tp2 = openPositionPrice - stopLoss*2;

      tp3 = openPositionPrice - stopLoss*3;

   }

   

   Comment(EnumToString(tradeType) + " : " + (string)ticket + "\n",

   "STOP LOSS PRICE:"+(string)stopLossPrice + "\n",

   "TP1:"+(string)tp1 + "\n",

   "TP2:"+(string)tp2 + "\n",

   "TP3:"+(string)tp3 + "\n"

   );

   

   //calls displaySettings to set up graphics

   displaySettings(tp1,tp2,tp3);

   //calls the takeProfit() function

   takeProfit(ticket,tp1,tp2,tp3,tradeType);

 

}





//---------------------------------------------Start of takeProfit() Function----------------------------------------------------------//

//     DESCRIPTION: will Take Profits from positions opened and change the tp object to green if it is met

//-------------------------------------------------------------------------------------------------------------------------------//

void takeProfit(ulong ticket, double tp1, double tp2, double tp3, ENUM_POSITION_TYPE tradeType)

{

   PositionSelectByTicket(ticket);

   //gets the current position of the currency pair I am indexed on

   double currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

   //gets the position volume used

   double volume = NormalizeDouble(PositionGetDouble(POSITION_VOLUME),_Digits);

   //stores open price of indexed position

   double openPositionPrice = NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits);

   

   //if the position indexed is a buy trade

   if(EnumToString(tradeType) == "POSITION_TYPE_BUY")

   {

      //IF TP1 IS HIT

      //if the position reaches the TP1

      //then move the stop loss to break even, and take partial profit (33% of position volume)

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition > tp1 && ObjectGetInteger(0,"TP1",OBJPROP_COLOR,0)!= "Green")

      {

         //Take Partial Profit

         trade.PositionClosePartial(ticket,volume/3.0,2);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP1",OBJPROP_COLOR,clrGreen);      //set object colour

      }

     

      //IF TP2 IS HIT

      //if the position reaches the TP2

      //then move the stop loss to break even, and take partial profit (50% of remaining position volume)

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition > tp2 && ObjectGetInteger(0,"TP2",OBJPROP_COLOR,0)!= "Green")

      {

         //Take Profit

         trade.PositionClosePartial(ticket,NormalizeDouble(volume/2.0,_Digits),2);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP2",OBJPROP_COLOR,clrGreen);      //set object colour

         breakEven(openPositionPrice);

         Sleep(10000);

      }

     

      //IF TP3 IS HIT

      //if the position reaches the TP3

      //close the position the trade is over

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition >= tp3)

      {

         //close the Position

         trade.PositionClose(ticket);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP3",OBJPROP_COLOR,clrGreen);      //set object colour  

         //deletes yellow BE stoploss object

         ObjectDelete(0,"BE StopLoss");

      }

     

      //IF BREAKEVEN IS HIT

      //if the current position goes past the tp1 in the oppposite direction after hitting tp1 and tp2

      //close the remaining volume of the position

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition <= tp1 && ObjectGetInteger(0,"TP1",OBJPROP_COLOR,0) == "Green" && ObjectGetInteger(0,"TP2",OBJPROP_COLOR,0) == "Green")

      {

         //close the Position

         trade.PositionClose(ticket);

         ObjectSetInteger(0,"BE StopLoss",OBJPROP_COLOR,clrRed);                                //set object colour

      }

   }

   

   //if the position indexed is a sell trade

   if(EnumToString(tradeType) == "POSITION_TYPE_SELL")

   {

      //IF TP1 IS HIT

      //if the position reaches the TP1

      //take partial profit (33% of position volume)

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition < tp1 && ObjectGetInteger(0,"TP1",OBJPROP_COLOR,0)!= "Green")

      {

         //Take Partial Profit

         trade.PositionClosePartial(ticket,volume/3.0);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP1",OBJPROP_COLOR,clrGreen);      //set object colour

      }

     

      //IF TP2 IS HIT

      //if the position reaches the TP2

      //then move the stop loss to break even, and take partial profit (50% of remaining position volume)

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition < tp2 && ObjectGetInteger(0,"TP2",OBJPROP_COLOR,0)!= "Green")

      {

         //Take Profit

         trade.PositionClosePartial(ticket,volume/2.0);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP2",OBJPROP_COLOR,clrGreen);      //set object colour

         breakEven(openPositionPrice);

      }

     

      //IF TP3 IS HIT

      //if the position reaches the TP3

      //close the position

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition <= tp3)

      {

         //close the Position

         trade.PositionClose(ticket);

         //Changes the color of the TP line if met

         ObjectSetInteger(0,"TP3",OBJPROP_COLOR,clrGreen);      //set object colour

         //Deletes the break even stop loss

         ObjectDelete(0,"BE StopLoss");

         counter++;  

      }

     

      //IF BREAKEVEN IS HIT

      //if the current position goes past the tp1 in the oppposite direction after hitting tp1 and tp2

      //close the remaining volume of the position

      currentPosition = NormalizeDouble(PositionGetDouble(POSITION_PRICE_CURRENT),_Digits);

      if(currentPosition >= tp1 && ObjectGetInteger(0,"TP1",OBJPROP_COLOR,0) == "Green" && ObjectGetInteger(0,"TP2",OBJPROP_COLOR,0) == "Green")

      {

         //close the Position

         trade.PositionClose(ticket);

         ObjectSetInteger(0,"BE StopLoss",OBJPROP_COLOR,clrRed);                                //set object colour  

      }

   }

}



//---------------------------------------------Start of displaySettings() Function----------------------------------------------------------//

//     DESCRIPTION: will create a new line for

//-----------------------------------------------------------------------------------------------------------------------------------------//

void breakEven(double openPositionPrice)

{

   //Get TP1 and display that position as a white line on chart and on the side of the chart as a number (ex: TP1: 1.165)

   ObjectCreate(0,"BE StopLoss",OBJ_HLINE,0,0,openPositionPrice); //set object properties

   ObjectSetInteger(0,"BE StopLoss",OBJPROP_WIDTH,4);                                      //set object width

   ObjectSetInteger(0,"BE StopLoss",OBJPROP_COLOR,clrYellow);                                //set object colour

}





//---------------------------------------------Start of displaySettings() Function----------------------------------------------------------//

//     DESCRIPTION: will display stop loss, TP1, TP2, TP3 in specified color both in text and on the chart until they are

//                  reached and the text will turn green and print a green line where the TP was met.

//-----------------------------------------------------------------------------------------------------------------------------------------//

void displaySettings(double tp1, double tp2, double tp3)

{



   //if the object isn't found with the names "TP1", "TP2", or "TP3"

   //create new horizontal line objects with the corresponding tp value

   if(ObjectFind(0,"TP1")<0 || ObjectFind(0,"TP2")<0 || ObjectFind(0,"TP3")<0)

   {

      //Get TP1 and display that position as a white line on chart and on the side of the chart as a number (ex: TP1: 1.165)

      ObjectCreate(0,"TP1",OBJ_HLINE,0,0,tp1); //set object properties

      ObjectSetInteger(0,"TP1",OBJPROP_WIDTH,2);              //set object width

      ObjectSetInteger(0,"TP1",OBJPROP_COLOR,clrIndigo);      //set object colour

   

      //Get TP1 and display that position as a white line on chart and on the side of the chart as a number (ex: TP1: 1.165)

      ObjectCreate(0,"TP2",OBJ_HLINE,0,0,tp2); //set object properties

      ObjectSetInteger(0,"TP2",OBJPROP_WIDTH,2);              //set object width

      ObjectSetInteger(0,"TP2",OBJPROP_COLOR,clrIndigo);      //set object colour



      //Get TP1 and display that position as a white line on chart and on the side of the chart as a number (ex: TP1: 1.165)

      ObjectCreate(0,"TP3",OBJ_HLINE,0,0,tp3); //set object properties

      ObjectSetInteger(0,"TP3",OBJPROP_WIDTH,2);              //set object width

      ObjectSetInteger(0,"TP3",OBJPROP_COLOR,clrIndigo);      //set object colour      

    }

    //if the objects are already present update them as needed

    else

    {

      //if SL has changed then move the objects to their new price values

      if(ObjectGetDouble(0,"TP1",OBJPROP_PRICE,0)!=tp1 || (ObjectGetDouble(0,"TP2",OBJPROP_PRICE,0)!=tp2) || (ObjectGetDouble(0,"TP3",OBJPROP_PRICE,0)!=tp3))

      {

         ObjectMove(0,"TP1",0,NULL,tp1);

         ObjectMove(0,"TP2",0,NULL,tp2);

         ObjectMove(0,"TP3",0,NULL,tp3);

         ObjectSetInteger(0,"TP1",OBJPROP_COLOR,clrIndigo);      //set object colour

         ObjectSetInteger(0,"TP2",OBJPROP_COLOR,clrIndigo);      //set object colour

         ObjectSetInteger(0,"TP3",OBJPROP_COLOR,clrIndigo);      //set object colour

      }

    }

 }
Files:
bot.PNG  81 kb
 

Please edit your post - use the CODE button (Alt-S)!

Use the CODE button

 
  1. Please edit your (original) post and use the CODE button (or Alt+S)! (For large amounts of code, attach it.)
              General rules and best pratices of the Forum. - General - MQL5 programming forum (2019)
              Messages Editor

  2.      tp1 = openPositionPrice + stopLoss;
         tp2 = openPositionPrice + stopLoss*2;
         tp3 = openPositionPrice + stopLoss*3;
    
          tp1 = openPositionPrice - stopLoss;
          tp2 = openPositionPrice - stopLoss*2;
          tp3 = openPositionPrice - stopLoss*3;

    You buy at the Ask and sell at the Bid. Pending Buy Stop orders become market orders when hit by the Ask.

    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid / OrderClosePrice reaches it. Using Ask±n, makes your SL shorter and your TP longer, by the spread. Don't you want the specified amount used in either direction?

    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask / OrderClosePrice reaches it. To trigger close to a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25

    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)

      Most brokers with variable spreads widen considerably at end of day (5 PM ET) ± 30 minutes.
      My GBPJPY shows average spread = 26 points, average maximum spread = 134.
      My EURCHF shows average spread = 18 points, average maximum spread = 106.
      (your broker will be similar).
                Is it reasonable to have such a huge spreads (20 PIP spreads) in EURCHF? - General - MQL5 programming forum (2022)

  3.  trade.PositionClosePartial(ticket,volume/3.0,2);

    You can't just use OrderLots()/3 because that is not a multiple of LotStep, and you can't close or have remaining less than MinLot.

  4. 4Show Investments: It takes too much partial profit numerous amounts of times.

    Of course it does. You compute your TP based on the SL. Which is why the first works. When you close the first, you move the SL to BE. The next tick your computed TP2 is wrong. Remember the original values, do not recompute them.

Reason: