Guidance on coding button with SL/TP function

 

hi there,


i am new here and new to coding. 


I am trying to set a button that can automatically set a SL/TP based on points or ATR multiplier.

So far I have managed to get the SL based on points using the properties as a way to change it. I have a code at the end to capture the ATR, however I have not figured it out how to use that to actually be usable on the SL function.

So far i have also not figured it out how to input the TP (either via points or ATR value)


any help or direction is mostly welcome


thanks in advance


input double Fixed_Lot_Size = 0.01;   
input int InpStopLossPoints = 100; 
input double Risk_Percent = 0.5;
input bool Use_ATR = false;
input int ATR_Period = 14;
input double ATR_MultiplierSL = 1.00; 
input double ATR_MultiplierTP = 1.50; 
input int Magic_Number = 240622;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{

   ButtonCreate();

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

   ObjectDelete("BuyButton");
   ObjectDelete("SellButton");

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{

   datetime checkTime   =  TimeCurrent()-30;                   // Only looking at trades in last 30 seconds
   int      cnt         =  OrdersTotal();
for (int i=cnt-1; i>=0; i--) {
   if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderMagicNumber()==240622 && OrderStopLoss()==0
            && (OrderType()==ORDER_TYPE_BUY || OrderType()==ORDER_TYPE_SELL)) {
            // magic 0 = manual entry, sl 0 means not set
         if (OrderOpenTime()>checkTime) {                   // lets you override after 30 seconds
            double   stopLoss       =  InpStopLossPoints*SymbolInfoDouble(OrderSymbol(), SYMBOL_POINT);
            double   stopLossPrice  =  (OrderType()==ORDER_TYPE_BUY) ?
                                       OrderOpenPrice()-stopLoss :
                                       OrderOpenPrice()+stopLoss;
            stopLossPrice           =  NormalizeDouble(stopLossPrice, (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS));
            if (OrderModify(OrderTicket(), OrderOpenPrice(), stopLossPrice, OrderTakeProfit(), OrderExpiration())) {}
         }
      }
   }
}


}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{

   if(id == CHARTEVENT_OBJECT_CLICK && sparam == "BuyButton")
      PlaceOrder(OP_BUY);

   if(id == CHARTEVENT_OBJECT_CLICK && sparam == "SellButton")
      PlaceOrder(OP_SELL);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ButtonCreate()
{

   int chart_ID = 0;                                          //--- choice of window for button
   string name = "BuyButton";

   ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
   if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,0,0,0))

   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,50);      //--- set button coordinates
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,50);      //--- set button coordinates
   ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,60);          //--- set button size
   ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,30);          //--- set button size
   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,0);          //--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetString(chart_ID,name,OBJPROP_TEXT,"BUY");         //--- set the text
   ObjectSetString(chart_ID,name,OBJPROP_FONT,"Arial");       //--- set text font
   ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,12);       //--- set font size
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clrBlack);    //--- set text color
   ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,clrBlue);   //--- set background color
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,0);          //--- set border color


   string name2 = "SellButton";

   ObjectCreate(0,name2,OBJ_BUTTON,0,0,0);
   if(!ObjectCreate(chart_ID,name2,OBJ_BUTTON,0,0,0))

   ObjectSetInteger(chart_ID,name2,OBJPROP_XDISTANCE,50);     //--- set button coordinates
   ObjectSetInteger(chart_ID,name2,OBJPROP_YDISTANCE,81);     //--- set button coordinates
   ObjectSetInteger(chart_ID,name2,OBJPROP_XSIZE,60);         //--- set button size
   ObjectSetInteger(chart_ID,name2,OBJPROP_YSIZE,30);         //--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetInteger(chart_ID,name2,OBJPROP_CORNER,0);         //--- set the text
   ObjectSetString(chart_ID,name2,OBJPROP_TEXT,"SELL");       //--- set text font
   ObjectSetString(chart_ID,name2,OBJPROP_FONT,"Arial");      //--- set font size
   ObjectSetInteger(chart_ID,name2,OBJPROP_FONTSIZE,12);      //--- set font size
   ObjectSetInteger(chart_ID,name2,OBJPROP_COLOR,clrBlack);   //--- set text color
   ObjectSetInteger(chart_ID,name2,OBJPROP_BGCOLOR,clrRed);   //--- set background color
   ObjectSetInteger(chart_ID,name2,OBJPROP_ZORDER,0);         //--- set border color
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlaceOrder(int dir)
{
   if(dir==OP_BUY)
     {
       int ticket = OrderSend(Symbol(),dir,Fixed_Lot_Size,Ask,30,0,0,NULL,240622,0,0);
     }
   else
      if(dir==OP_SELL)
        {
          int ticket = OrderSend(Symbol(),dir,Fixed_Lot_Size,Bid,30,0,0,NULL,240622,0,0);
        }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+




/*
int GetStopLoss()
{
   int stopLoss = Stop_Loss_Points;
 
   if(Use_ATR == true)
     {
      double atr = iATR(_Symbol, _Period, ATR_Period, 1);
      stopLoss = (atr*ATR_MultiplierSL/_Point);
          
     }
   return stopLoss;

Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Types of Chart Events
Documentation on MQL5: Constants, Enumerations and Structures / Chart Constants / Types of Chart Events
  • www.mql5.com
Types of Chart Events - Chart Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
sargh:

hi there,


i am new here and new to coding. 


I am trying to set a button that can automatically set a SL/TP based on points or ATR multiplier.

So far I have managed to get the SL based on points using the properties as a way to change it. I have a code at the end to capture the ATR, however I have not figured it out how to use that to actually be usable on the SL function.

So far i have also not figured it out how to input the TP (either via points or ATR value)


any help or direction is mostly welcome


thanks in advance


The return value of iATR is in ticks.

Once you have the value, you can add or subtract it from a quote (price). Because you'll be performing arithmetic to arrive at the stoploss, you'll need to normalize the result before modifying the order with the result. Read this for more info on how to go about that.

Also, do not use _Point. Use tick size, instead. You can get that value by using

SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

The reason you don't want to use point is because it only tells you the decimal place, not the smallest change in price. It works in some markets, like Forex, because the smallest change in price is 0.00001 or 0.0001 but, in other markets, the tick size can be 0.25 while the point would be 0.01.

NormalizeDouble problem
NormalizeDouble problem
  • 2022.06.18
  • www.mql5.com
Do you guys have some other alternative for displaying a number in the chart window in a desired format other than NormalizeDouble function...
 
Alexander Martinez #: The return value of iATR is in ticks.

Incorrect! The values provided by iATR is price quote range, or a price change or price delta, or which ever name you use. It is NOT in ticks.

 
Fernando Carreiro #:

Incorrect! The values provided by iATR is price quote range, or a price change or price delta, or which ever name you use. It is NOT in ticks.

For all intents and purposes, your response provides nothing of value.

But I am curious: why not just help the guy out yourself? His question was sitting there for a week. You only chose to "contribute" when I offered to help. Considering our last exchange, this strikes me as rather peculiar.

 
Alexander Martinez #: But I am curious: why not just help the guy out yourself? His question was sitting there for a week. You only chose to "contribute" when I offered to help. Considering our last exchange, this strikes me as rather peculiar.

NB! I will refer to the OP as "they" as I don't know their gender ...

Because their query is too generalised and requests answers for multiple issues, and the code seems not to be theirs.

  • They request help for how to code a button.
  • They request help for using the ATR to set a value for S/L and T/P
  • They request help for setting the Take-Profit

The code itself does not compile and shows a mixture of code made by different people, which they seem to have repurposed but don't understand.

If they were able to code the stopless, then it stands to reason that they would with the same logic be able to code the take-profit, yet they state that they don't know how.

They claim to have created the function to calculate the stopless size from the iATR, but then don't know how to apply it.

In all, I get the sense of someone using snippets from other peoples code but not having the basic knowledge of coding to put it together.

My conclusion is that, what ever guidance we give, will not be sufficiently understood and that the "help" they want, is that someone just give them the final code with it all corrected for them.

Reason: