mql5

Position stop-loss set to zero after position is generated


I'm trying to write some modules for calculating trailing stop-loss in MQL5. The issue I'm having is that, whenever I attempt to retrieve the stop-loss for a position, I get a value of zero. I know the position doesn't have a stop-loss of zero because the journal shows that it was generated with a non-zero SL:

CS  0   12:59:55.438    Trade   2022.01.03 17:00:00   market sell 0.1 EURUSD sl: 1.13358 (1.13062 / 1.13063 / 1.13062)
CS  0   12:59:55.438    Trades  2022.01.03 17:00:00   deal #2 sell 0.1 EURUSD at 1.13062 done (based on order #2)
CS  0   12:59:55.438    Trade   2022.01.03 17:00:00   deal performed [#2 sell 0.1 EURUSD at 1.13062]
CS  0   12:59:55.438    Trade   2022.01.03 17:00:00   order performed sell 0.1 at 1.13062 [#2 sell 0.1 EURUSD at 1.13062]

Furthermore, when I check the stop-loss of the position immediately after I enter it, by doing:

for (int i = 0; i < PositionsTotal(); i++) {
   
   if (PositionGetSymbol(i) != Symbol()) {
      continue;
   }
      
   ulong ticket = PositionGetTicket(i);
   PositionSelectByTicket(ticket);   
   PrintFormat("Position %d, Current SL: %f", ticket, PositionGetDouble(POSITION_SL));
}

This prints the following:

CS  0   12:59:55.439    test (EURUSD,H1)    2022.01.03 17:00:00   Position 2, Current SL: 1.133580

So, I can see that it's working, but only for the tick when the position was generated. Anytime after that, I get this:

CS  0   12:59:55.441    test (EURUSD,H1)    2022.01.03 18:00:00   Position 2, Current SL: 0.000000

So, what's going on here?


Solution

  • It turns out that this issue was caused by a completely separate problem. This is the code that was doing my trailing stop logic:

    ExitResult Exit() {
       ExitResult result;
       result.Result = EXIT_RESULT_CONTINUE;
       
       if (!m_calculator.Enabled()) {
          return result;
       }
       
       for (int i = 0; i < PositionsTotal(); i++) {
          if (PositionGetSymbol(i) != Symbol()) {
             continue;
          }
          
          ulong ticket = PositionGetTicket(i);
          PositionSelectByTicket(ticket);
          
          double newSL;
          ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
          int errCode = m_calculator.Calculate(i, pType, newSL);
          if (errCode != 0) {
             result.ErrorCode = errCode;
             result.Result = EXIT_RESULT_ERROR;
             break;
          }
          
          double existingSL = PositionGetDouble(POSITION_SL);
          
          if ((pType == POSITION_TYPE_BUY && newSL > existingSL) || (pType == POSITION_TYPE_SELL && newSL < existingSL)) {
             result.Order = CreateSltp(m_magic, ticket);
             result.Order.sl = newSL;
             result.Order.tp = PositionGetDouble(POSITION_TP);
             result.Result = EXIT_RESULT_EXIT;
             break;
          }
       }
       
       return result;
    }
    

    The issue here was that, if newSL was not modified by the call to Calculate, then it would contain its default value of 0. So, for any sell position, this would guarantee that the stop-loss would eventually be set to 0.

    All I had to do was include a Boolean flag in Calculate that would be true if the rule modified newSL and false otherwise. This fixed the issue.