On-chart independent close button for every open position - page 2

 
Ehsansia: I felt a necessity to code an EA that creates a close button for every open position directly on the chart and at the right most corner of the screen,
Why, when all you had to do is right click on a line?
 
whroeder1:
Why, when all you had to do is right click on a line?

I think this is more handy and easier. Sometimes, when the market is volatile (I'm a scalper), it's kind of hard to quickly right click and the close. This is a one click process which is indeed faster and more convenient as well.

On the other hand, since I'm new to MQL, I thought this could be a good project for me to learn more about coding and by the way, I haven't seen a similar EA. I think my idea is new.

 
Keith Watford:
Yes, just remember that when you use ChartTimePriceToXY the co-ordinates will relate to the Upper left corner. It doesn't matter in this case because you are only interested in the y co-ordinate and you are anchored to an upper corner.

I've managed to come to this point so far but nothing is happening on the chart.

int OnInit()
  {
//---
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam){

   int indexPos = OrdersTotal();
   while (indexPos>0 && OrderSelect(indexPos,SELECT_BY_POS,MODE_TRADES)) {
      if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
      
            int      x     = 0;
            int      y     = 0;
            datetime dt    = TimeCurrent();
            double   price = OrderOpenPrice();
            int      window= 0;
            if(ChartTimePriceToXY(0,window,dt,price,x,y)){
               ObjectCreate(0,"Tiny"+IntegerToString(indexPos),OBJ_BUTTON,0,0,0);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_CORNER,1);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_XDISTANCE,0);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_YDISTANCE,NormalizeDouble(price,5));
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_XSIZE,15);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_YSIZE,12);
               ObjectSetString(0,"Tiny"+IntegerToString(indexPos),OBJPROP_TEXT,"X");
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_COLOR, C'60,60,60');
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_BGCOLOR, C'238,171,171');
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_BORDER_TYPE,BORDER_FLAT);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_BACK,false);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_HIDDEN,true);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_STATE,false);
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_FONTSIZE,8);
            }
      }
      indexPos--;
   }
}
 

I think that your code should be in a function that is called from OnTick when necessary.

and your index should be OrdersTotal()-1 because the index starts at 0


   int indexPos = OrdersTotal()-1;
   while (indexPos>=0 && OrderSelect(indexPos,SELECT_BY_POS,MODE_TRADES)) {




      if (OrderType() == OP_BUY || OrderType() == OP_SELL) {


You should also test for OrderSymbol()



               //ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_YDISTANCE,NormalizeDouble(price,5));
               ObjectSetInteger(0,"Tiny"+IntegerToString(indexPos),OBJPROP_YDISTANCE,y)


Set the correct  value that you retrieved from ChartTimePriceToXY()


Now I would suggest that you get the orderdetails and store them in a globally declared array.

Maybe store OrdersTotal()+OrdersHistoryTotal() and update the array when the value changes

The array should be 2 dimensional (double) or a struct so that you store the ticket number and the price

Maybe name the button "Tiny"+IntegerToString(ticket), then when a button is pressed you will know from the sparam which ticket to close.


I think that you should first concentrate on the code for the array, before worrying about the buttons. Just my opinion.

 
Keith Watford:

I think that your code should be in a function that is called from OnTick when necessary.

and your index should be OrdersTotal()-1 because the index starts at 0...

I think I'm almost half way there. Thanks to your instructions, I moved the button creation code into OnTick() and it's working now.




The buttons get created but now the problem is that when I change to a different timeframe or when I scroll the chart to the left side and the hight of the display changes, the buttons don't stick to their right location in "Y" axis. They wait for the next tick's arrival to adjust to their right locations.

I think if I define the whole button creation process in a function and then call it inside OnChartEvent() while checking the id to be "CHARTEVENT_CHART_CHANGE" that will correct the issue.

Then remains the job of connecting these buttons to their respective orders so that when I click on it, the belonging open position get's closed. I believe your solution ("Tiny"+IntegerToString(ticket)) with &sparam will work correctly for this issue.
 
Keith Watford:

I think that your code should be in a function that is called from OnTick when necessary.

and your index should be OrdersTotal()-1 because the index starts at 0...

Keith, It's almost done. Shows winning and losing positions in different colors and the previous problem in regard with refreshing the buttons' position also solved.




Thanks to your guidance, this was a fun project for me but I've got neck ache due to long screen time :-)

I appreciate your attention and guidance.

 
Nice work. Congrats to both of you.
 
Ehsansia:

Keith, It's almost done. Shows winning and losing positions in different colors and the previous problem in regard with refreshing the buttons' position also solved.

Thanks to your guidance, this was a fun project for me but I've got neck ache due to long screen time :-)

I appreciate your attention and guidance.

Well, I have to say that I'm impressed. I agree with Alain, it is nice work.

I am sure that the first time that I attempted coding something similar took me much longer.

It is really nice to see someone apply themselves to the task in hand and not expect to be spoon fed

 
Alain Verleyen:
Nice work. Congrats to both of you.
Thank you. It was a nice experience for me.
 
Keith Watford:

Well, I have to say that I'm impressed. I agree with Alain, it is nice work.

I am sure that the first time that I attempted coding something similar took me much longer.

It is really nice to see someone apply themselves to the task in hand and not expect to be spoon fed

Keith,

Thank you for the compliments. I've to confess, this was actually my second work with MQL language. I've created my own order management panel which has made the life much easier for me. Thanks to your knowledge and excellent guidance, trading is like a breeze for me now. Having this one-click close button on chart was another step forward. Now I can get rid of the terminal window and focus on a full-screen chart which has everything I need to trade effectively without dealing with any of metatrader's spacious panels and windows. I spent almost a week for this panel.


I've to say also that I have moderate experience in coding for the web, using HTML, CSS, Javascript, PHP and Jquery and a little of Python, so in general, I'm not totally new to programming so to speak. I've found MQL easy to learn, although I'm still at the beginning and there are many functions that I'm not familiar with yet.

Thank you Keith

Cheers

Reason: