Open Opposite order once sl is hit

 

Hello your help will be highly appreciated, I have coding a function that triggers opposite ordertype when a trade closses in loss but not working at all. That is if we have buy order active and the order closses either by sl or opposite close and it resulis in loss then sell order will open at the price where order was closed vice versa for buy; Kindly help;

void sl_hit()
  {
       for(int n=OrdersHistoryTotal()-1; n>=0; n--)        
          {
           if(!OrderSelect(n,SELECT_BY_POS,MODE_HISTORY)) continue;
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
                if(TimeCurrent() - OrderCloseTime() == 0)  
                 {
                  if(OrderType()==OP_BUY && OrderClosePrice()<=OrderOpenPrice()) 
                    { 
                        SELL();
                    }
                  
                  else if(OrderType()==OP_SELL && OrderClosePrice()>=OrderOpenPrice()) 
                    {
                       BUY();
                    }
                 }
          }
  }
 

You can place a pending order in the opposite direction at the stop loss of the current market order. This pending order will be activated at the same time as the stop loss. But you need to monitor the pending order and delete this pending order in case the current market order was closed not by stoploss. This is the best solution, but it is relatively difficult to implement.

You can also save one spread if your broker allows you to use OrderCloseBy. This is an even cooler solution, but also more difficult to implement.

 
Vladislav Boyko #:

You can place a pending order in the opposite direction at the stop loss of the current market order. This pending order will be activated at the same time as the stop loss. But you need to monitor the pending order and delete this pending order in case the current market order was closed not by stoploss. This is the best solution, but it is relatively difficult to implement.

You can also save one spread if your broker allows you to use OrderCloseBy. This is an even cooler solution, but also more difficult to implement.

Thank you for your reply I'll try to implement both and seee what works

 
Ernest Akoyi #:

Thank you for your reply I'll try to implement both and seee what works

In the case of OrderCloseBy (if you are going to try to implement it), the logic is that the pending order should have a double lot. And a stop loss is not needed for a market order. When the EA detects opposing market orders (pending order triggered), it should close one market order with another (using OrderCloseBy). Due to the double lot of the order that was pending, after OrderCloseBy you will only have one market order with the required lot.

But be prepared for a lot of research and coding, as this logic is the most complex of all possible ones to implement. And before you start implementing, make sure that your broker allows you to use OrderCloseBy, so that you don’t have any unpleasant surprises later.

 

I described the 2 coolest ways. Your logic may also work somehow, but the opening price of a new order and the closing price of an old order will almost always be different in this case.

The most obvious problem with your implementation is with this line

Forum on trading, automated trading systems and testing trading strategies

Open Opposite order once sl is hit

Ernest Akoyi, 2024.04.08 16:49

void sl_hit()
  {
       for(int n=OrdersHistoryTotal()-1; n>=0; n--)        
          {
           if(!OrderSelect(n,SELECT_BY_POS,MODE_HISTORY)) continue;
            if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
                if(TimeCurrent() - OrderCloseTime() == 0)

This condition will almost never be met, since some time will pass from the moment the order is closed until the advisor receives a new tick.

It looks like you are trying to select the last closed order. This condition is not suitable for this. Look for examples of how to do this correctly.

 
Vladislav Boyko #:

I described the 2 coolest ways. Your logic may also work somehow, but the opening price of a new order and the closing price of an old order will almost always be different in this case.

The most obvious problem with your implementation is with this line

This condition will almost never be met, since some time will pass from the moment the order is closed until the advisor receives a new tick.

It looks like you are trying to select the last closed order. This condition is not suitable for this. Look for examples of how to do this correctly.

TThank you bro I implemented the pending order function and is working. Thank you

 
Ernest Akoyi:

Hello your help will be highly appreciated, I have coding a function that triggers opposite ordertype when a trade closses in loss but not working at all. That is if we have buy order active and the order closses either by sl or opposite close and it resulis in loss then sell order will open at the price where order was closed vice versa for buy; Kindly help;

Hi, simply you have to get the latest data in the history and open an opposite trade based on the data. 

If the last closed trade is a buy and it is a loss open a sell @ closed price

if the last closed trade is a sell and it is a loss open a buy @ closed price

If the last trade is a buy and is closed in profit EA won't do anything.

If the last trade is a sell and is closed in profit EA won't do anything.

You only need the last buy/sell trade data in the history.

//+------------------------------------------------------------------+
//|                                  ///SK_EA_Get_Last_Trade_Data/// |
//+------------------------------------------------------------------+
#define   Version   "1.00"
#property version   Version
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

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

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int    latest_order_type  = -1;
   double latest_close_price =  0;
   double latest_profit      =  0;
   Get_Latest_Trade_Data(latest_order_type,latest_profit,latest_close_price);

   if(latest_order_type == OP_BUY && latest_profit<0)
      Print(
         "SELL!"+
         " | latest_close_price: "+DoubleToString(latest_close_price,_Digits)+
         " | last trade was a buy, profit: "+DoubleToString(latest_profit,2)
      );
   if(latest_order_type == OP_SELL && latest_profit<0)
      Print(
         "BUY!"+
         " | latest_close_price: "+DoubleToString(latest_close_price,_Digits)+
         " | last trade was a sell, profit: "+DoubleToString(latest_profit,2)
      );

  }
//+------------------------------------------------------------------+
//| Get the Latest Trade Data | Trade Data Voids/Functions           |
//+------------------------------------------------------------------+
void Get_Latest_Trade_Data(int &latest_order_type,double &latest_profit,double &latest_close_price)
  {
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         if(
            OrderSymbol() == _Symbol &&
            (OrderType() == OP_BUY || OrderType() == OP_SELL)
         )
           {
            latest_order_type  = OrderType();
            latest_close_price = OrderClosePrice();
            latest_profit      = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
            break;
           }
  }
//+------------------------------------------------------------------+
//| End                                                              |
//+------------------------------------------------------------------+
 
Soheil Kord #:

Hi, simply you have to get the latest data in the history and open an opposite trade based on the data. 

If the last closed trade is a buy and it is a loss open a sell @ closed price

if the last closed trade is a sell and it is a loss open a buy @ closed price

If the last trade is a buy and is closed in profit EA won't do anything.

If the last trade is a sell and is closed in profit EA won't do anything.

You only need the last buy/sell trade data in the history.

Hello did exactly these but not working

 
#property strict

class PositionsList
{
   public:
      ulong tickets[];
   public:
      PositionsList()
      {
         ArrayResize(tickets,0);
      }
      ~PositionsList(){};
      int Size()
      {  
         return ArraySize(tickets);
      }
      void Add(ulong ticket)
      {  
         int size = ArraySize(tickets);
         ArrayResize(tickets, size+1);
         tickets[size]=ticket;
      }
      void Remove(ulong ticket)
      {  
         int index=IndexOf(ticket);
         if(index==-1) return;
         int size = ArraySize(tickets);
         tickets[index]=tickets[size-1];
         ArrayResize(tickets, size-1);
      }
      int IndexOf(ulong ticket)
      {  
         int size = ArraySize(tickets);
         for(int i=0;i<size;i++)
            if(tickets[i]==ticket) return i;
         return -1;
      }   
};

PositionsList *list;

int OnInit()
  {
   list = new PositionsList();
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   delete list;
   EventKillTimer();   
  }
  
void OnTimer()
{
   for(int i=OrdersTotal()-1;i>=0;i--)
   {
      if(OrderSelect(i, SELECT_BY_POS)==false) continue;
      if(list.IndexOf(OrderTicket())==-1)
      {
         list.Add(OrderTicket());
      }
   }
   for(int i=list.Size()-1;i>=0;i--)
   {
      if(OrderSelect((int)list.tickets[i], SELECT_BY_TICKET)==false) 
      {
         list.Remove(list.tickets[i]);
      }
      if(OrderCloseTime()!=0)
      {
         list.Remove(list.tickets[i]);



      if(OrderType()==OP_BUY && OrderClosePrice()<=OrderStopLoss())
      {
         SLHit(OrderTicket());
      }
      if(OrderType()==OP_SELL && OrderClosePrice()>=OrderStopLoss())
      {
         SLHit(OrderTicket());
      }
      }    } } void SLHit(ulong ticket) {   Print("SL Hit: ", ticket);     }
I didn't test it...
 
Ernest Akoyi #:

Hello did exactly these but not working

My code does not open buy/sell orders, you have to complete it yourself.

My code prints buy or sell situation according to your criteria. Change Prints to OrderSend().

 
Yashar Seyyedin #:
I didn't test it...

Thank you your help is appreaciated

Reason: