expert advisor - miscellaneous questions - page 24

 

It's already in the example.

When you close the order you use the boolean return value of OrderClose() function, and if the function was successful, you can remove the objects related to the order.

                           bool close=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrBlue);
                             {
                              if(close==0)
                                {
                                 Alert(" Order Close Error! # "+IntegerToString(OrderTicket()));
                                }
                              if(close==1)
                                {
                                 Alert(" Order: "+IntegerToString(OrderTicket())+" Closed due to TP Profit = "+DoubleToString(OrderProfit(),2));
                                 ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
                                 ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
                                }
                             }
 
Marco vd Heijden:

It's already in the example.
When you close the order you use the boolean return value of OrderClose() function, and if the function was successful, you can remove the objects related to the order.

I already know it, I already tried it. Maybe I did something wrong. I will try once again, but before I want to ask I would not like to use OrderClose(). ( sometimes I close orders by the manually )
Q:    So, can I delete order objects after order closed without OrderClose()?

Thanks in advance. 

 

Well the return value of Order Close() function decides if the action was successful or not so if you close the order manually you will have to design and use a slightly different mechanism.

You can make a shadow copy of the order list and compare it to the actual list, and whenever something changes because you closed a order manually, look for what has changed and then remove those objects.

But an easier way might be to check if the OrderTicket() still exists in the active order pool so when it vanishes because you closed the order manually, the objects will be automatically removed.

So it depends on how you want to set it up.

At this point i would say you would have to try and look beyond what you want to do with it eventually because the direction you take is somewhat related to additional tasks you might want to add later.


Since the creation of the Objects is already fully automated, i suggest you do the same for the removal of objects then you do not have to worry about it in the future.

For this you can simply use

OrdersHistoryTotal()

And the history pool

MODE_HISTORY

It's simple, the order history pool is scanned, and at each cycle the code will look to see if any objects related to the OrderTicket() number exists, and if there is a match, the objects are automatically deleted.

To do this you only have to add another loop but this time over the history pool.

See example.

//+------------------------------------------------------------------+
//|                                                ObjectsRemove.mq4 |
//|      Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

static input int takeprofit=500;// Take Profit
static input int stoploss=500;  // Stop Loss
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(1);

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

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

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   for(int order=OrdersTotal(); order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS);
        {
         if(selected==1)
           {
            if(Symbol()==OrderSymbol()) // only for current chart symbol
              {
               switch(OrderType())
                 {
                  case OP_BUY: // for buy order
                    {
                     // if objects not found - create them
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()+takeprofit*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()-stoploss*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
                       }
                     // if objects exist
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
                       {
                        if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
                       {
                        if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                    }
                  break;

                  case OP_SELL: // for sell order
                    {
                     // if objects not found - create them
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()+stoploss*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
                       }
                     // if objects exist
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
                       {
                        if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
                       {
                        if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                    }
                  break;
                 }
              }
           }
        }
     }
//+------------------------------------------------------------------+
//--- delete objects when order is closed
   for(int order=OrdersHistoryTotal()-1; order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
        {
         if(selected==1)
           {
            // if objects are still found - Delete them
            if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
              {
               ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
              }
            if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
              {
               ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
              }
           }
        }
     }
//+------------------------------------------------------------------+    
  } // end OnTimer() function
//+------------------------------------------------------------------+

So now you have the fully automated addition of virtual take profit and stoploss lines, and also the fully automated removal of these lines.

Of course this example is continuously scanning the history pool...

Additionally you could add an integer thats holds the number of orders, which is then compared against OrdersTotal(), and whenever something changes you run the object removal code.

Or, you could add a simple counter (60) then the piece of code will only check once a minute, if anything needs to be removed.

 

Hey Man! That works perfectly! Thanks a lot!

I just little changed. So far it works with no problems.

//--- delete objects when order is closed
   for(int order=OrdersHistoryTotal()-1; order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
        {
         if(selected==1)
           {
            // if objects are still found - Delete them
            ObjectsDeleteAll( 0, "#" + IntegerToString( OrderTicket() ) ); // for arrows
            ObjectsDeleteAll( 0, _prefix + " #" + IntegerToString( OrderTicket() ) ); // order, sl, tp, price objects
           }
        }
     }

If something wrong please let me know about that.
Once again thanks a lot Man!

 

Maybe no one understand my question. But I still need good comment for it. So now I am trying to clarify my question with image.
Question: Also Stop Loss, Take Profit Lines front of Trade Panel Objects. I know that caused from last time creates object. But if you understand me, please let me know how can I do Trade Panel object should be front all of other objects without " Stop Loss and Take Profit " Lines.

Objects mixed 

I know I can use OBJPROP_BACK, but I do not want to use it.  I just need to see line and price like both of them. I hope I will get good comment for it.


Open, Stop Loss, Take Profit, price lines " Create and Delete " that all of them in a function. So just now I am trying to split it, because I need to put that function in OnChartEvent(). But before I need to ask.
Q:   If I put that function in OnChartEvent() - so that function could not effects to my manually Orders?

I am working on it now.

Please help me, thanks in advance.

 

No Onchartevent() will only execute the code when there is a chart event it's not like the OnTImer() function.

So you have to know exactly what you are doing.

For example if you are using the scanning code :

if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))

To check if price has crossed your line this will not work in OnChartEvent().

Also if you want to use the automated example

if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
   {
     ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
     ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
   }

This will not work or create the objects.

You will have to re write the code.

Also, you can set the H_LINE objects to OBJPROP_BACK this is no problem you will still see them and they will be under your panel.

 

Really nice and useful comment, now I know for sure I should try at least once for know what I could do additionally.

Thanks for your quickly response and helpful comment.

 
Marco vd Heijden:

You will have to re write the code.

( I already read carefully your comment but I just wanted to try once - finally as you said it does not work like the OnTimer(). )

Omg! Should I change everything in that codes of block?
Now I have four functions. I just try to put them in OnChartEvent(). I already tried I just see one thing updates this is just Print() for stop loss, take profit prices.
OrderModify() does not work in it.

I will start to try something again for this issue in 8 - 10 hours.
I just really need good comments, I hope I will get it.

Thanks so much in advance.

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_DRAG) // I already tried with take profit object - there was not any effects
     {
      SL_TPcreateobjects();
      SL_TPdrags();
      SL_TPmodify();
      deleteobjs();
     }
  }
// if objects not found - create them
SL_TPcreateobjects()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(Symbol()!=OrderSymbol()) continue;

      if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
        {
         ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,takeprofit);
        }
     }
  }
// if objects exist
SL_TPdrags()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(Symbol()!=OrderSymbol()) continue;

      if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
        {
         if(TP_Price!=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
           {
            TP_drag=1;
            TP_Price=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0);
           }
         if(TP_drag==1)
           {
            if(TP_Price==ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
              {
               Print("Take Profit Price:",DoubleToString(TP_Price,Digits));
               TP_drag=0;
              }
           }
        }
     }
  }
// order closed - delete junks
deleteobjs()
{
  for(int i=OrdersHistoryTotal()-1; i>=0; i--)
    {
     bool Selected=OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
     if(Selected==1)
       {
        ObjectsDeleteAll(0,"#"+IntegerToString(OrderTicket())+"-TP");
       }
    }
}
// ordermodify()
SL_TPmodify()
{
  Order_Modify=OrderModify(OrderTicket(),OrderOpenPrice(),SL_Price,TP_Price,0,CLR_NONE);
}
//+------------------------------------------------------------------+
 

Those function will only be executed when a chartevent happens.

At least that is what you are showing here.

Chartevent is just a trigger to an interrupt routine when somebody presses a button or something else on the chart.

Now you have taken the fully automated example and put it under a button, nothing will happen if nobody presses it.

 
Marco vd Heijden:

Those function will only be executed when a chartevent happens.
At least that is what you are showing here.
Chartevent is just a trigger to an interrupt routine when somebody presses a button or something else on the chart.
Now you have taken the fully automated example and put it under a button, nothing will happen if nobody presses it.

It's possible your latest comment looks like so simple, but actually that comment showed me right way.
So now I solve my issue which one I try to use drag.

And now I am starting to research about some other graphical objects moves with that HLine object.

Thanks so much more man!
All the best to you! 


honest_knave:

Also, think about how often you move the line. Is it once a second? Probably not.
Put your code in OnChartEvent():

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_DRAG && sparam=="line") // the chart event of dragging the line
Thanks a lot Man! So that your this comment really helped me a lot!
Reason: