Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 122

 

Решил дополнить предыдущий вопрос.

1) 

Допустим у меня сигнал - при резком расширении спреда (на новостях)

закрыть все текущие сделки

Но на новостях ордера просто так закрыть или открыть не дадут.

поэтому если взять команду допустим OrderClose засунуть в цикл + Sleep (3000) и выполнять до тех пор пока не закроется

2)

если в кнопке привязать внутреннюю переменную и привязать значение нажата\отжата к возможности открытия ордера будет ли это работать в реальном времени?

 
trader781:

Решил дополнить предыдущий вопрос.

1) 

Допустим у меня сигнал - при резком расширении спреда (на новостях)

закрыть все текущие сделки

Но на новостях ордера просто так закрыть или открыть не дадут.

поэтому если взять команду допустим OrderClose засунуть в цикл + Sleep (3000) и выполнять до тех пор пока не закроется

2)

если в кнопке привязать внутреннюю переменную и привязать значение нажата\отжата к возможности открытия ордера будет ли это работать в реальном времени?

1) Помогает не Sleep(3000) а обработка ошибок.
 

Приветствую, пишу индикатор, который отрисовывает историю ордеров на графике, код:

//+------------------------------------------------------------------+
//|                                                      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();
   }
}

 Единичный сделки индикатор отрисовывает правильно (линия>фон>профит), а вот в отображении закрытых сеток ордеров есть небольшой "косяк" (скрин прилагаю), на фон и профит накладываются линии (линия(1)>фон>профит>линия(2)>линия(3)>линия(4) . . . ). 

Должно быть так: (линия(1)>линия(2)>линия(3)>линия(4) . . . >фон>профит). Различные танцы с бубном не привели к успеху, помогите доработать.

Файлы:
 
ilnur17021992:

Приветствую, пишу индикатор, который отрисовывает историю ордеров на графике,


Единичный сделки индикатор отрисовывает правильно (линия>фон>профит), а вот в отображении закрытых сеток ордеров есть небольшой "косяк" (скрин прилагаю), на фон и профит накладываются линии (линия(1)>фон>профит>линия(2)>линия(3)>линия(4) . . . ). 

Должно быть так: (линия(1)>линия(2)>линия(3)>линия(4) . . . >фон>профит). Различные танцы с бубном не привели к успеху, помогите доработать.

Попробуй линиям и значкам присваивать свойство OBJPROP_BACK на заднем плане.
ObjectSetInteger - Графические объекты - Справочник MQL4
ObjectSetInteger - Графические объекты - Справочник MQL4
  • docs.mql4.com
ObjectSetInteger - Графические объекты - Справочник MQL4
 
Alexey Viktorov:
Попробуй линиям и значкам присваивать свойство OBJPROP_BACK на заднем плане.
Не вариант, так линии становятся на заднем плане (за свечами), а нужно что б отрисовка была поверх свечей: свечи>линии>фон профита>профит
Файлы:
 
ilnur17021992:
Не вариант, так линии становятся на заднем плане (за свечами), а нужно что б отрисовка была поверх свечей: свечи>линии>фон профита>профит
Тогда только последовательность нанесения на график. Или при нанесении фона и профита проверять наличие этих объектов по времени, читать значение профита в объекте OBJ_TEXT и плюсовать к профиту текущего ордера. Потом удалять фон и профит и заново рисовать.
К стати это избавит от дополнительного цикла для подсчёта профита.

Вот этого
      //Расчет профита
      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();
            }  
         }      
      }
а профит определяешь в начале вместе с остальными параметрами ордера.

ps просьба. Размещай картинки через эту кнопку
 
Alexey Viktorov:
Тогда только последовательность нанесения на график. Или при нанесении фона и профита проверять наличие этих объектов по времени, читать значение профита в объекте OBJ_TEXT и плюсовать к профиту текущего ордера. Потом удалять фон и профит и заново рисовать.
К стати это избавит от дополнительного цикла для подсчёта профита.
а профит определяешь в начале вместе с остальными параметрами ордера.

 Как задать такую последовательность отрисовки, допустим, сначала отрисовываем все точки и линии соединяющие их, а после приступить к отрисовке фона и профита?

 
ilnur17021992:

 Как задать такую последовательность отрисовки, допустим, сначала отрисовываем все точки и линии соединяющие их, а после приступить к отрисовке фона и профита?

Ну, если по первому моему предположению, то так. А потом у меня сразу мелькнул экспромт и я не стал удалять первое предложение, но второе мне больше нравится.

Лучше рассмотри этот вариант.

ObjectFind() потом если объект найден ObjectGetString() перевод из текста в число, к полученному плюсуем профит последнего ордера, удаляем устаревший OBJ_TEXT и рисуем новый.
Если-же это первый или единственный ордер закрытый на этом баре, то просто рисуется
OBJ_TEXT и всё.
А для упрощения имя задать не тикет, а время открытия бара. Или тикет нужен для последующей работы?

 
Alexey Viktorov:
Ну, если по первому моему предположению, то так. А потом у меня сразу мелькнул экспромт и я не стал удалять первое предложение, но второе мне больше нравится.

Лучше рассмотри этот вариант.

ObjectFind() потом если объект найден ObjectGetString() перевод из текста в число, к полученному плюсуем профит последнего ордера, удаляем устаревший OBJ_TEXT и рисуем новый.
Если-же это первый или единственный ордер закрытый на этом баре, то просто рисуется
OBJ_TEXT и всё.
А для упрощения имя задать не тикет, а время открытия бара. Или тикет нужен для последующей работы?

Да тикет нужен для последующего анализа истории. Спасибо, что наталкнули на перерисовку. Решил проблему немного проще, добавив в код такую проверку и перерисовку:

      //Расчет профита
      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;      
      }

 Не знаю на сколько это правильно, но в принципе отрисовывает как надо (линии>фон>профит):

 

 
ilnur17021992:

Да тикет нужен для последующего анализа истории. Решил проблему немного проще, добавив в код такую проверку и перерисовку:

 

      //Расчет профита
      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;      
      }

 В принципе отрисовывает правильно (линии>фон>профит):

 

Ну и прекрасно, я рад за тебя.