function to close open trades with current profit.

 

This functions goal is to close all open trades that are in profit -- AND the worst trade with worst loss, designated by "worst" as the ticket number.

The worst trade is closing, however only some of the profit trades are closing! Maybe I am just tired, but i can not see why! HELP. If i have failed to give details of any missing variables, just ask for it and i will post it. EDIT: there are no errors in logs, journal or expert tabs.

void CloseTrades(int no2close = 999, bool party = false)
  {
   bool closeAll = ((IsFridayTrue() && equ0>MaxEqu[2])) && equ0>0.00 && equ0>bal0+eqplus*1.618034;
   if(iTime(_Symbol,PERIOD_M1,0)<=dt[0])
      if(doalerts(closeAll,no2close,party))
         dt[0]=iTime(_Symbol,PERIOD_M1,0);
   ulong tk;
   int neg = 0, otyp = 9;
   const double half = iStartLots * 0.5;
   uint worst=no2close!=999 && no2close>=1?(uint)worsTics[0]:0;
   for(int k=total-1; k>=0; k--)
     {
      if(position.SelectByIndex(k))
        {
         otyp = position.Type();
         if(otyp!=POSITION_TYPE_SELL && otyp!=POSITION_TYPE_BUY)
            continue;
         tk=position.Ticket();
         sw=position.Swap();
         pft=position.Profit();
         xcm=-iStartLots*6;
         ltv=(!party?position.Volume():NormalizeDouble(fmax(position.Volume()/2,0.01),2));
         xcm*=(ltv/iStartLots);
         net = pft+sw+xcm;
         if(net>0.00 || no2close == 999 || tk==worst)
           {
            if(tk==worst)
               ++neg;
            if(!party || net>0.00 || ltv<half)
              {
               if(trade.PositionClose(tk)==true)
                  continue;
              }
            else
               if(trade.PositionClosePartial(tk,ltv,-1)>0)
                  continue;
           }
         else
            if(net<-minLoss && neg<no2close)
              {
               for(int i = 0; i<no2close; ++i)
                 {
                  tk=position.Ticket();
                  if((worsTics[i]>0 && tk==worsTics[i]) || tk==worst)
                    {
                     ++neg;
                     if((!party  || ltv<half) && trade.PositionClose(tk)==true)
                        continue;
                     else
                        if(trade.PositionClosePartial(tk,ltv,-1)==true)
                           continue;
                    }
                 }
              }
        }
     }
   osd_to_be_called = true;
  }
 
         xcm=-iStartLots*6;
What's that ?
 
Alain Verleyen #:
What's that ?
$6 commission for 1 standard lot; multiplied by iStartlot which is the tradesize -- to get the commission for the current, selected trade.
 

maybe because your "net" variable is rarely a value above zero due to "xcm" often dragging the value below zero

btw, your code is cryptic and not nice for an outside observer to read, only to you it it might be fine to read

 

This is how you determine a profit trade:

net = pft+sw+xcm;
if(net>0.00 ...

Perhaps the not closed trades are with a profit > 0 but not enough and you are induced in error, thinking they should close but they should not.

Do you call the function with party = true or = false?
 
Conor Mcnamara #:


Frederic Metraux #:


i have 10 trades that have stayed open after this function was called -- all open, with $10 profits, above commissions and swaps.

party is false by default, as defined at top of function -- and is rarely true.

EDIT: the "doalerts" function reports the state of party and total number of worst (losing and rarely more than 1) trades that are closed in an alert box.

 

here's the doalerts function. NOTE: that i am sure that the above function was working 100% before I added this doalerts function. I will check if it still works in tester later today -- without this function. but maybe an expert can tell me that some line in the below causes the close trades funct to malfunction?

//+------------------------------------------------------------------+
bool doalerts(bool docloseAll, int numClose, bool party)
  {
   bool done = MQLInfoInteger(MQL_TESTER);
   if(!done)
     {
      done=true;
      if(iTime(_Symbol,PERIOD_M1,0)<=dt[0])
         return false;
      Alert("Profit from Ronz TSL closed trades since previous Group TSL= "+DoubleToString(tsltotal,2)); //+" - "+DoubleToString(ccount*iMinimalProfit*1.62,2)+" = "+DoubleToString(tsltotal-(ccount*iMinimalProfit*1.62),2));
      //      if(docloseAll || party)
      Alert("Closing "+(string)numClose+" DD trades and closeall condition is "+(docloseAll==true?"TRUE":"FALSE")+ "; Partial DD Trade:  "+(party==true?"TRUE":"FALSE"));


      return true;
     }
   else
      return true;

   return false;
  }
 


I submitted your code to chatgpt. (don't blame me, I believe it helps). Maybe the AI nailed the problem. :)

1. The continue statements

Inside the main loop ( for(int k=total-1; k>=0; k--) ), you have many continue; calls immediately after a PositionClose(...) or PositionClosePartial(...) .

That means after attempting to close a trade, you skip directly to the next iteration of the for loop, without verifying whether the close was actually successful.

trade.PositionClose(tk) and trade.PositionClosePartial(...) can fail (e.g. due to requotes, no liquidity, trade context busy, etc.). If they fail, you just continue anyway, leaving the trade open. That explains "not all trades that should be closed are closed."

2. The worsTics loop

In the block:

for(int i = 0; i<no2close; ++i)
  {
   tk=position.Ticket();
   if((worsTics[i]>0 && tk==worsTics[i]) || tk==worst)

You're looping i up to no2close , but still referencing the same currently selected position.Ticket() ( tk ) inside. That means the loop does not iterate through positions; it's just checking the same ticket repeatedly against multiple worsTics[i] .

So only if tk matches one of those entries will it close — but the others remain untouched, because you never advance position.SelectByIndex(...) inside that inner loop.

This creates a false impression that you’re checking multiple positions, when in fact you’re only checking the currently selected one repeatedly.

 

you wrote

for(int k=total-1; k>=0; k--)
Where do you get total? Use the PositionsTotal() instead. I think this is where the problem is. Maybe total is smaller than the PositionsTotal()?
 

Try this one:

void CloseTradesAndDeepestLoser(bool party = false)
{
   bool closeAll = ((IsFridayTrue() && equ0 > MaxEqu[2])) 
                   && equ0 > 0.00 
                   && equ0 > bal0 + eqplus * 1.618034;

   if (iTime(_Symbol, PERIOD_M1, 0) <= dt[0])
   {
      if (doalerts(closeAll, no2close, party))
         dt[0] = iTime(_Symbol, PERIOD_M1, 0);
   }

   ulong worstTicket = 0;
   double worstNet = 0.0;
   double sw, pft, ltv, xcm, net;

   int totalPositions = PositionsTotal();

   // --- 2. Loop through all positions ---
   for (int k = totalPositions - 1; k >= 0; k--)
   {
      if (!position.SelectByIndex(k))
         continue;

      int otyp = position.Type();
      if (otyp != POSITION_TYPE_SELL && otyp != POSITION_TYPE_BUY)
         continue;

      ulong tk  = position.Ticket();
      sw  = position.Swap();
      pft = position.Profit();
      ltv = (!party ? position.Volume() : NormalizeDouble(fmax(position.Volume() / 2, 0.01), 2));
      xcm = -iStartLots * 6 * (ltv / iStartLots);
      net = pft + sw + xcm;

      // --- 2a. Close profitable / allowed trades ---
      if (net > 0.00 || no2close == 999)
      {
         bool fullClose = (!party || net > 0.00 || ltv < iStartLots * 0.5);

         if (fullClose)
         {
            if (!trade.PositionClose(tk))
               Print("Failed to close ticket ", tk, " err=", GetLastError());
         }
         else
         {
            if (trade.PositionClosePartial(tk, ltv, -1) <= 0)
               Print("Failed to partial-close ticket ", tk, " err=", GetLastError());
         }
      }

      // --- 2b. Track the deepest loser ---
      if (worstTicket == 0 || net < worstNet)
      {
         worstTicket = tk;
         worstNet = net;
      }
   }
// --- 3. Close deepest loser (if negative) ---
   if (worstTicket > 0 && worstNet < 0.0)
   {
      position.Select(worstTicket);
      ltv = (!party ? position.Volume() : NormalizeDouble(fmax(position.Volume() / 2, 0.01), 2));
      bool fullClose = (!party || ltv < iStartLots * 0.5);

      if (fullClose)
      {
         if (!trade.PositionClose(worstTicket))
            Print("Failed to close deepest loser ticket ", worstTicket, " err=", GetLastError());
      }
      else
      {
         if (trade.PositionClosePartial(worstTicket, ltv, -1) <= 0)
            Print("Failed to partial-close deepest loser ticket ", worstTicket, " err=", GetLastError());
      }
   }

   osd_to_be_called = true;
}
 
Frederic Metraux #:

Try this one:

a lot there to read. thanks. i will check you your points soon. Thanks for the critiqueing and advice.