Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 122

 

Decided to add to the previous question.

1)

Suppose I have a signal - when the spread widens sharply (on the news)

Close all current trades

But the orders will not just close or open during the news.

Therefore, if we take a command, say, OrderClose, put it into a loop + Sleep (3000) and execute it until it closes

2)

If we bind an internal variable in the button and assign the value pressed/closed to the order opening possibility, will it work in real time?

 
trader781:

Decided to add to the previous question.

1)

Suppose I have a signal - when the spread widens sharply (on the news)

Close all current trades

But the orders will not just close or open during the news.

Therefore, if we take a command, say, OrderClose, put it into a loop + Sleep (3000) and execute it until it closes

2)

If we bind an internal variable in the button and assign the value pressed/closed to the order opening possibility, will it work in real time?

1) It's not Sleep(3000) but error handling that helps.
 

Greetings, I am writing an indicator which drawsorder history on a chart, code:

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

extern int        MagicNumber                = 1110;
extern datetime   HistoryOrdersFromDateTime  = 0;
extern color      SellColor                  = clrRed;
extern color      BuyColor                   = clrBlue;
extern color      ProfitColor                = clrWhite;
extern bool       DeleteHistoryOrders        = false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
  
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

void start()
{
   for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
      {
         if(HistoryOrdersFromDateTime<OrderCloseTime())
         {
            if((TimeCurrent()-OrderCloseTime())>60)
               HistoryOrders();
         }
      }
   }
}

void HistoryOrders()
{
   double b=OrderOpenPrice(), d=OrderClosePrice(), lots=OrderLots(), Profit=0;
   datetime a=OrderOpenTime(), c=OrderCloseTime(), close_time;
   string Ticket=(string)OrderTicket(), type="Sell", symbol=OrderSymbol(), comment=OrderComment(), Background;
   color col=SellColor;
   if(OrderType()==0) {col=BuyColor; type="Buy";}

   if(DeleteHistoryOrders==false)
   {
      //Начальная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJ_ARROW,0,a,b);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_ARROWCODE,1);
      
      //Линия  
      ObjectCreate("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJ_TREND,0,a,b,c,d);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_WIDTH,1);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_STYLE,STYLE_DOT);
      ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_RAY,0);
  
      //Конечная точка
      ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJ_ARROW,0,c,d);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
      ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_ARROWCODE,3);

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
      
      //Размер фона  
      for(int i=2; i<StringLen(DoubleToString(Profit,2)); i++)
         StringAdd(Background,"g");
      
      //Фон профита
      ObjectCreate("#"+Ticket+" Background",OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Background",Background,10,"Webdings",col);
      ObjectSet("#"+Ticket+" Background",OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Background",OBJPROP_TIME1,c+Period());
  
      //Профит
      ObjectCreate("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJ_TEXT,0,c,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_ANCHOR,ANCHOR_LOWER);
      ObjectSetText("#"+Ticket+" Profit: "+DoubleToString(Profit,2),DoubleToString(Profit,2),10,"Arial",ProfitColor);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_PRICE1,d);
      ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_TIME1,c+Period());
   } else ObjectsDeleteAll(0, "#"+Ticket+" ");  
}

void OnDeinit(const int reason)
{  
   //Удалаение истории ордеров
   for(int i=0; i<OrdersHistoryTotal(); i++)
   {
      DeleteHistoryOrders=true;
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
         HistoryOrders();
   }
}

The indicator draws single trades correctly (line>background>profit), but there is a small "bug" in the display of closed order sets (screenshot attached), lines are superimposed on the background and profit (line(1)>background>profit>line(2)>line(3)>line(4) .. . . .).

It should be as follows: (line(1)>line(2)>line(3)>line(4) . . . >fon>profit). Various tampering has not been successful, please help to refine.

Files:
 
ilnur17021992:

Greetings, I am writing an indicator that displaysorder history on a chart,


The indicator render a single deal correctly (line>background>profit), but in the display of a closed orders set, there is a small "shoosh" (I attach a screenshot), the lines (line(1)>background>profit>line(2)>line(3)>line(4) . . ...) are superimposed on the background and the profit. ).

It should be as follows: (line(1)>line(2)>line(3)>line(4) . . . >fon>profit). Various tambourines have not been successful, please help me to refine.

Try assigning lines and icons to the OBJPROP_BACK property in the background.
ObjectSetInteger - Графические объекты - Справочник MQL4
ObjectSetInteger - Графические объекты - Справочник MQL4
  • docs.mql4.com
ObjectSetInteger - Графические объекты - Справочник MQL4
 
Alexey Viktorov:
Try to assign property OBJPROP_BACK to lines and icons in the background.
This is not an option. The lines are drawn in the background (behind the candlesticks) while the drawing should be over the candlesticks: candlesticks>lines>profit background>profit
Files:
 
ilnur17021992:
Not an option, so the lines are in the background (behind the candlesticks), and the drawing should be over the candlesticks: candlesticks>lines>profit>profit background
Then only the sequence of drawing on the chart. Or, when drawing the background and profit, we should check existence of these objects by time, read profit value in OBJ_TEXT object and add it to the profit of the current order. Then we should delete background and profit and draw them again.
By the way, this will get rid of an additional cycle for profit calculation.

You can do this
      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               Ticket=(string)OrderTicket();
            }  
         }      
      }
you define the profit in the beginning together with all other order parameters.

ps Please. Place a picture with this button
 
Alexey Viktorov:
Then only the sequence of drawing on the chart. Or, when drawing background and profit, we should check the availability of these objects by time, read the value of profit in the OBJ_TEXT object and add it to the profit of the current order. Then we should delete background and profit and draw them again.
By the way, this will eliminate the need of an additional cycle for calculating profit.
You define the profit in the beginning together with all other order parameters.

How do I set this drawing sequence, say, first draw all points and the lines connecting them, and then proceed to draw the background and profit?

 
ilnur17021992:

How do I set this sequence of drawing, say, first draw all the points and lines connecting them, and then proceed to draw the background and profit?

Well, if by my first assumption, then so. And then I immediately had an impromptu thought and did not delete the first sentence, but I like the second one better.

You'd better consider this variant.

ObjectFind() then if the object is found ObjectGetString() convert it from text to number, add the profit of the last order to the obtained value, delete the obsolete OBJ_TEXT and draw a new one.
If it is the first or the only order closed on this bar, we simply draw
OBJ_TEXT and that is all.
To make things easier, we should specify the time of bar opening instead of the ticket. Or the ticket is needed for further work?

 
Alexey Viktorov:
Well, if on my first guess, it does. And then I immediately had an impromptu thought and didn't delete the first sentence, but I like the second one better.

You'd better consider this variant.

ObjectFind() then if the object is found ObjectGetString() translate it from text to number, add the profit of the last order to the obtained value, delete the obsolete OBJ_TEXT and draw a new one.
If it is the first or the only order closed on this bar, we simply draw
OBJ_TEXT and that is all.
To make things easier, we should specify the time of bar opening instead of the ticket. Or the ticket is needed for further work?

Yes the ticket is needed for later analysis of the story. Thanks for the tip on redrawing. Solved the problem a bit easier by adding this check and redrawing to the code:

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

I don't know if it is correct, but in principle it draws as it should be (lines>fon>profit):

 
ilnur17021992:

Yes, the ticket is needed to analyse the history later on. Solved the problem a little easier by adding such a check and redraw to the code:

      //Расчет профита
      for(int i=OrdersHistoryTotal()-1; i>=0; i--)
      {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
         {
            close_time=OrderCloseTime();
            //60 секунд разницы между закрытием первого и последнего ордера в сетке
            if(c<=close_time+60 && c>=close_time-60)
            {
               Profit+=OrderProfit()+OrderCommission()+OrderSwap();
               ProfitTicket=(string)OrderTicket();
               CountOrders++;
            }  
         }      
      }
      
      //Перерисовка фона и профита
      if(CountOrders>1)
      {  
         ObjectDelete("#"+Ticket+" Background");
         ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
         Ticket=ProfitTicket;      
      }

Basically it draws correctly (lines>background>profit):

Well, that's fine, I'm happy for you.
Reason: