Experts: eaBreakeven

 

eaBreakeven:

eaBreakeven is an EA that moves the Stop Loss to breakeven and simultaneously plays the sound, when the Stop Loss is changed. EA manages the positions for the current chart currency pair only, i.e. if you attach in on the GBPUSD chart, it will manage only GBPUSD positions.


Input parameters

  • Breakeven in points - profit of the position, when this expert moves the Stop Loss to breakeven.
  • Breakeven distance in points - the distance value where the Stop Loss is set. For example, if the opening price of a short position is 1.9873, and this parameter is set to 5 points, then eaBreakeven will change the Stop Loss to 1.9868.
  • Magic Number - managed orders ID. If 0 then EA will manage all the positions for the current symbol.
  • Enable / disable playing sound - enable/disable audio playback when a break-even occurs.
  • Sound file name - the name of the sound file in the \Sounds folder.

Author: Alexey Lopatin

 

Errors:

  1. The loop should be reversed.
  2. PositionSelect should be removed from the code.

 
fxsaber:

Mistakes:

  1. The loop should be reversed.
  2. PositionSelect should be removed from the code.


Arguments to the studio.

 
Alexey Lopatin:

Arguments, please.

It takes a long time to explain about the loop. And PositionSelect is unnecessary after PositionGetSymbol, because the selection has already been made, if LastError is OK. But PositionSelect is also evil on a hedge account.

The best option is to always use this instead of the above-mentioned ones.

if (PositionGetTicket(i))


Also latest_price for any position direction could be taken via POSITION_PRICE_CURRENT.


And this condition

if(latest_price.bid-price_open>=Breakeven*point && new_stoploss>stoploss && latest_price.bid-new_stoploss>stop_level)

can be triggered even in cases (due to double peculiarities) when nothing needs to be modified.


In general, you can rewrite it a bit more compactly and without errors. I would do it MT4-style.

#include <MT4Orders.mqh>     // https://www.mql5.com/en/code/16006
#include <Price_Compare.mqh> // https://www.mql5.com/en/code/16169

input int    Breakeven           = 15;           //Breakeven in points
input int    Distance            = 5;            //Breakeven distance in points from open price of position
input int    MagicNumber         = 16112017;     //Magic number
input bool   EnableSound         = true;         //Enable/disable playing sound when breakeven is set
input string SoundFile           = "alert1.wav"; //Sound file name

void OnTick()
{
  DoBreakeven();
}

double GetNewStopLoss()
{
  const double point = SymbolInfoDouble(OrderSymbol(), SYMBOL_POINT);  
  const double stop_level = SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_STOPS_LEVEL) * point;
  
  const double price_open = OrderOpenPrice();
  const double latest_price = OrderClosePrice();  
  const double stoploss = OrderStopLoss();

  double new_stoploss = 0;
  
  //--- Move stop-loss at breakven price + Distance, if position profit greater than Breakeven points 
  return(((OrderType() == OP_BUY)  && (CP(latest_price - price_open, point) >= Breakeven * point) &&
                                      (CP(new_stoploss = price_open + Distance * point, point) > stoploss) &&
                                      (CP(latest_price - new_stoploss, point) > stop_level)) ||
         ((OrderType() == OP_SELL) && (CP(price_open - latest_price, point) >= Breakeven * point) &&
                                      ((CP(new_stoploss = price_open - Distance * point, point) < stoploss) || !stoploss) &&
                                      (CP(new_stoploss - latest_price, point) > stop_level))
         ? NormalizeDouble(new_stoploss, (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS)) : 0);
}

void DoBreakeven()
{
//If Breakeven is negative, then disable breakeven function
  if (Breakeven >= 0)      
  //Loop for positions
    for (int i = OrdersTotal() - 1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (!MagicNumber || (OrderMagicNumber() == MagicNumber)))
      {
        const double new_stoploss = GetNewStopLoss();
        
        if (new_stoploss)      
        {
          if (!OrderModify(OrderTicket(), OrderOpenPrice(), new_stoploss, OrderTakeProfit(), OrderExpiration()))
            Print(GetLastError());
          else if(EnableSound)
            PlaySound(SoundFile);
        }
      }
}
 

Thanks for the reply with the example. Always glad to learn something new for myself.

But here it would be interesting to know why PositionSelect is evil on a hedge account?

 
Alexey Lopatin:

But here it would be interesting to know why PositionSelect on the hash count is evil?

Because the symbol does not uniquely define the position.

 
caolyhuynh:
 
5000000
 
caolyhuynh: