Ошибки, баги, вопросы - страница 2737

 

В МТ4, во время отладки индикаторов, отладчик намертво повисает если переключиться на график.

Воспроизводится, например, во время запуска отладки стандартного индикатора CCI.

1. Поставить точку останова;

2. Нажать F5;

3. Переключиться на график.

Результат - график отладчика зависает.

Также можно просто несколько раз нажать F5 во время отладки - график повисает.

Билд 1260.

Настройки отладчика:


 
Комментарии, не относящиеся к этой теме, были перенесены в "Вопросы от начинающих MQL4 MT4 MetaTrader 4".
 
Очень редко работаю с графическими объектами, возникла необходимость закрасить фон для OBJ_LABLE (установить OBJPROP_BGCOLOR) .
Как оказалось, установка цвета фона невозможна для  объекта типа OBJ_LABLE, необходимо использовать OBJ_EDIT.
При использовании  OBJ_EDIT возникла новая проблема - необходимость установить размер OBJPROP_XSIZE и OBJPROP_YSIZE, чтобы в соответствующие размеры объекта помещался весь текст.

Вопрос: как определить размер  OBJPROP_XSIZE и OBJPROP_YSIZE, что бы туда поместился весь текст?
Рассмотрел два варианта:
1. Создание объекта OBJ_LABLE, считывание размеров, удаление объекта OBJ_LABLE.
Не подходит из-за того, что считывание размеров возможно только после фактического создания объекта и не возможно, когда объект находится в очереди на ChartRedraw.

2. Использование TextSetFont с последующим TextGetSize.
Не подходит, так как результат кардинально отличается от результатов метода №1, отличия в 2.5 - 2.9 раз в зависимости от размера шрифта.
Возможно причина в 4К мониторе и 175% DPI.

#define PRINT(x) ; Print(#x, ":", string(x))
          
void SetLabel(long achart, string name, int wnd, string text, color clr, int x, int y, int corn=0, int fontsize=8, string font="Tahoma")
{
   ObjectCreate(achart, name, OBJ_LABEL, wnd, 0, 0); 
   ObjectSetInteger(achart, name, OBJPROP_CORNER, corn); 
   ObjectSetString(achart, name, OBJPROP_TEXT, text); ObjectSetInteger(achart, name, OBJPROP_COLOR, clr); 
   ObjectSetInteger(achart, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(achart, name, OBJPROP_FONT, font);
   ObjectSetInteger(achart, name, OBJPROP_SELECTABLE, false); 
   ObjectSetInteger(achart, name, OBJPROP_BORDER_TYPE, 0);
   ObjectSetInteger(achart, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(achart, name, OBJPROP_YDISTANCE, y);
}

void OnStart(){     
   string obj_name = "test_obj";   
   string text = "AAAA::BBBB";
   int font_size = 7;
   string font_name = "Tahoma";
   
   SetLabel(0, obj_name, 0, text, clrWhite, 100, 100, 0, font_size, font_name);
   ChartRedraw(0);
   Sleep(1000);
   
   uint dx_fixed_0 = int(ObjectGetInteger(0, obj_name, OBJPROP_XSIZE));
   uint dy_fixed_0 = int(ObjectGetInteger(0, obj_name, OBJPROP_YSIZE));
   ObjectDelete(0, obj_name);
   
   PRINT(dx_fixed_0);
   PRINT(dy_fixed_0);
   
   
   uint dx_fixed_1;
   uint dy_fixed_1;
   TextSetFont(font_name, -10 * font_size);
   TextGetSize(text, dx_fixed_1, dy_fixed_1);
   
   PRINT(1.0 * dx_fixed_0 / dx_fixed_1);  	// Result: 1.0
   PRINT(1.0 * dy_fixed_0 / dy_fixed_1);  	// Result: 1.0
}  


Спасибо Geess за решение.
Необходимо домножить на -10 размер шрафта при передаче в TextSetFont.

 
Sergey Dzyublik:
Очень редко работаю с графическими объектами, возникла необходимость закрасить фон для OBJ_LABLE (установить OBJPROP_BGCOLOR) .
Как оказалось, установка цвета фона невозможна для  объекта типа OBJ_LABLE, необходимо использовать OBJ_EDIT.
При использовании  OBJ_EDIT возникла новая проблема - необходимость установить размер OBJPROP_XSIZE и OBJPROP_YSIZE, чтобы в соответствующие размеры объекта помещался весь текст.

Вопрос: как определить размер  OBJPROP_XSIZE и OBJPROP_YSIZE, что бы туда поместился весь текст?
Рассмотрел два варианта:
1. Создание объекта OBJ_LABLE, считывание размеров, удаление объекта OBJ_LABLE.
Не подходит из-за того, что считывание размеров возможно только после фактического создания объекта и не возможно, когда объект находится в очереди на ChartRedraw.

2. Использование TextSetFont с последующим TextGetSize.
Не подходит, так как результат кардинально отличается от результатов метода №1, отличия в 2.5 - 2.9 раз в зависимости от размера шрифта.
Возможно причина в 4К мониторе и 175% DPI.

Во-первых, размер текста и размер объекта - это не одно и тоже. Как минимум должен существовать бордюр. И поэтому эти значения не могут совпадать.
Во-вторых, лучше использовать OBJ_BITMAP_LABEL, у которого нет никаких ограничений.
А если уж его использовать, то лучше тогда воспользоваться классом CCanvas.

#include <Canvas\Canvas.mqh>
          
void SetLabel(CCanvas &c, long achart, string name, int wnd, string text, color clr_text, color clr_bckgrnd, int x, int y, int corn=0, int fontsize=8, int border=2, string font="Tahoma", uchar transparency=0xFF)
{
   uint w,h;
   c.FontSet(font, fontsize);
   c.TextSize(text, w, h);
   if(!c.CreateBitmapLabel(achart,wnd,name,x,y,w+border*2,h+border*2,COLOR_FORMAT_ARGB_NORMALIZE))
      Print("Error creating canvas object: ", GetLastError());
   c.Erase(ColorToARGB(clr_bckgrnd,transparency));
   c.TextOut(border,border,text,ColorToARGB(clr_text,transparency));
   c.Update();
}

void OnStart(){     
   string obj_name = "test_obj";   
   string text = "AAAA::BBBB";
   int font_size = 17;
   string font_name = "Tahoma";
   CCanvas Can;
   SetLabel(Can,0, obj_name, 0, text, clrYellow, clrBlue, 100, 100, 0, font_size,3, font_name, 0x80);
   Sleep(10000);
   Can.Destroy();
}  

В результате получаем тот же  объект, только с большими возможностями. Например, добавив прозрачность текстовой метки.


 
Geess:

Во-первых, размер текста и размер объекта - это не одно и тоже. Как минимум должен существовать бордюр. И поэтому эти значения не могут совпадать.

Спасибо большое за помощь.
Адаптируется готовое решение под собственные нужды, по этому не видится необходимости во внедрении библиотек.
Изначально предложенное вами решение можно представить как:

void SetBitmapLabel(long achart, string name, int wnd, string text, color clr, color bgclr, int x, int y, int corn=0, int fontsize=8, string font="Tahoma", int border=2)
{
   uint w,h;
   TextSetFont(font,-10*fontsize,0,0);
   TextGetSize(text,w,h);
   w = w+border*2;
   h = h+border*2;
   
   uint pixels[];
   ArrayResize(pixels,w*h);
   ArrayInitialize(pixels,0);
   ENUM_COLOR_FORMAT color_format = COLOR_FORMAT_XRGB_NOALPHA;
   string resource_name="::"+name+(string)ChartID()+(string)(GetTickCount()+MathRand());
   
   ResourceCreate(resource_name,pixels,w,h,0,0,0,color_format);
   ObjectCreate(achart,name,OBJ_BITMAP_LABEL,wnd,0,0);
   ObjectSetInteger(achart,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(achart,name,OBJPROP_YDISTANCE,y);
   ObjectSetString(achart,name,OBJPROP_BMPFILE,resource_name);
   ArrayInitialize(pixels,ColorToARGB(bgclr));
   TextOut(text,border,border,0,pixels,w,h,ColorToARGB(clr),color_format);
   ResourceCreate(resource_name,pixels,w,h,0,0,0,color_format);
}

void SetLabel(long achart, string name, int wnd, string text, color clr, int x, int y, int corn=0, int fontsize=8, string font="Tahoma")
{
        ObjectCreate(achart, name, OBJ_LABEL, wnd, 0, 0); 
        ObjectSetInteger(achart, name, OBJPROP_CORNER, corn); 
        ObjectSetString(achart, name, OBJPROP_TEXT, text); ObjectSetInteger(achart, name, OBJPROP_COLOR, clr); 
        ObjectSetInteger(achart, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(achart, name, OBJPROP_FONT, font);
        ObjectSetInteger(achart, name, OBJPROP_SELECTABLE, false); 
        ObjectSetInteger(achart, name, OBJPROP_BORDER_TYPE, 0);
        ObjectSetInteger(achart, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(achart, name, OBJPROP_YDISTANCE, y);
}

void OnStart(){     
   string obj_name = "test_obj";   
   string text = "AAAA::BBBB";
   int font_size = 50;
   string font_name = "Tahoma";
   
   SetBitmapLabel(0, "BL" + obj_name, 0, text, clrRed, clrWhite, 100, 100, 0, font_size, font_name);
   SetLabel      (0, "L"  + obj_name, 0, text, clrRed,           100, 200, 0, font_size, font_name);
   ChartRedraw(0);
   Sleep(10000);
}  


К сожалению из-за дефекта в МТ5 - предложенное решение невозможно нормально использовать. 
Размер текста получается в 3 раза меньше необходимого на 4К мониторе с 175% Windows DPI.
Приходится домножать размер шрифта на DPI / 100% * [1.6 ... 1.8]

Спасибо Geess за решение.
Необходимо домножить на -10 размер шрафта при передаче в TextSetFont.




 
Sergey Dzyublik:

Спасибо большое за помощь.
Адаптируется готовое решение под собственные нужды, по этому не видится необходимости во внедрении библиотек.
Изначально предложенное вами решение можно представить как:


К сожалению из-за дефекта в МТ5 - предложенное решение невозможно нормально использовать. 
Размер текста получается в 3 раза меньше необходимого на 4К мониторе с 175% Windows DPI.
Приходится домножать размер шрифта на DPI / 100% * [1.6 ... 1.8]

https://www.mql5.com/ru/docs/objects/textsetfont


нужно делать так:

void SetBitmapLabel(long achart, string name, int wnd, string text, color clr, color bgclr, int x, int y, int corn=0, int fontsize=8, string font="Tahoma", int border=2, uchar transparency=0xFF)
{
   uint w,h;
   TextSetFont(font,-10*fontsize,0,0);
   TextGetSize(text,w,h);
   w = w+border*2;
   h = h+border*2;
   
   uint pixels[];
   ArrayResize(pixels,w*h);
   ArrayInitialize(pixels,0);
   ENUM_COLOR_FORMAT color_format = COLOR_FORMAT_ARGB_NORMALIZE;
   string resource_name="::"+name+(string)ChartID()+(string)(GetTickCount()+MathRand());
   
   ResourceCreate(resource_name,pixels,w,h,0,0,0,color_format);
   ObjectCreate(achart,name,OBJ_BITMAP_LABEL,wnd,0,0);
   ObjectSetInteger(achart,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(achart,name,OBJPROP_YDISTANCE,y);
   ObjectSetString(achart,name,OBJPROP_BMPFILE,resource_name);
   ObjectSetInteger(achart,name,OBJPROP_BACK,false);
   ArrayInitialize(pixels,ColorToARGB(bgclr, transparency));
   TextOut(text,border,border,0,pixels,w,h,ColorToARGB(clr, transparency),color_format);
   ResourceCreate(resource_name,pixels,w,h,0,0,0,color_format);
}

void SetLabel(long achart, string name, int wnd, string text, color clr, int x, int y, int corn=0, int fontsize=8, string font="Tahoma")
{
        ObjectCreate(achart, name, OBJ_LABEL, wnd, 0, 0); 
        ObjectSetInteger(achart, name, OBJPROP_CORNER, corn); 
        ObjectSetString(achart, name, OBJPROP_TEXT, text); ObjectSetInteger(achart, name, OBJPROP_COLOR, clr); 
        ObjectSetInteger(achart, name, OBJPROP_FONTSIZE, fontsize); ObjectSetString(achart, name, OBJPROP_FONT, font);
        ObjectSetInteger(achart, name, OBJPROP_SELECTABLE, false); 
        ObjectSetInteger(achart, name, OBJPROP_BORDER_TYPE, 0);
        ObjectSetInteger(achart, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(achart, name, OBJPROP_YDISTANCE, y);
}

void OnStart(){     
   string obj_name = "test_obj";   
   string text = "AAAA::BBBB";
   int font_size = 50;
   string font_name = "Tahoma";
   
   SetBitmapLabel(0, "BL" + obj_name, 0, text, clrRed, clrBlue, 100, 100, 0, font_size, font_name,2,0xA0);
   SetLabel      (0, "L"  + obj_name, 0, text, clrBlue,         100, 200, 0, font_size, font_name);
   ChartRedraw(0);
   Sleep(10000);
}



Не понимаю, почему Вам так нужен OBJ_LABEL? Вы же реализовали вариант без библиотек с OBJ_BITMAP_LABEL. В чем его преимущество? Вижу только ограниченность.

 
Цель
Geess:

https://www.mql5.com/ru/docs/objects/textsetfont
Не понимаю, почему Вам так нужен OBJ_LABEL? Вы же реализовали вариант без библиотек с OBJ_BITMAP_LABEL. В чем его преимущество? Вижу только ограниченность.

Спасибо большое еще раз.
Не знал, не видел, не читал, о умножении на -10. Проблема решена.
OBJ_LABEL использовался для наглядности проблемы и возможности ее воспроизведения.

 
Здравствуйте!

Подскажите пож-та в чём проблема.

 

Разные индикаторы, корректно работающие и обновляющиеся, синхронно начинают показывать что-то иное, не основывающиеся на графике цены, отображаемом в основном окне. Происходит это эпизодически, не каждый день.

Сначала грешил на индикаторы, но перепробовав разные, включая нативные MT5, начинаю подозревать сам терминал. Проблему наблюдаю давно, ещё с прошлого года, на разных версиях терминала. Сначала наблюдал на кастомной версии Альпари, теперь тоже самое на оригинальной версии. И на демо счёте, и на реальном ecn.

Брокер Альпари. MT5 билд 2363 от 13.03.2020. На других периодах не помню, но на M1 точно такое происходит.

Скрины:

«Слетевший» вариант. Кроме зигзага все индикаторы встроенные. Зигзаг с корректной работой с историей. Между собой показания индикаторов сходятся. Расходятся с ценами.

После обновления.

Версия МТ5

Файлы:
 

Добрый день.

Наткнулся на непонятную вещь и не пойму в чем дело.

Есть две функции, которые используются в разных стратегиях. По логике вещей код в проверках типа

if(m_position.PositionType()==POSITION_TYPE_SELL  && m_position.Magic()==magic)

выполняться не должен, если одно из условий не верно. Но он почему-то выполняется, если магик номер позиции и переданный в функцию магик НЕ РАВНЫ.

Вроде сравнение целочисленных типов происходит. Почему, не могу понять. Ниже на скриншоте журнала это видно.


void OpenNextBuyPositionBySignal(CTrade &m_trade,long magic,double ExtDP,double iuv,double imv,int itp,int isl,double etp,double esl,double ev,double &rev,string numstr,ulong &last_pt)
{
   for(int i=PositionsTotal()-1;i>=0;i--)
     if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
       if(m_position.Symbol()==m_symbol.Name())
       {
          if(m_position.PositionType()==POSITION_TYPE_SELL  && m_position.Magic()==magic)
          {
             if((m_position.Profit()+m_position.Swap()+m_position.Commission())<0)
             {
                if(IsSetBuy(magic,ExtDP)==true)
                {
                    double cdist=MathFloor(MathAbs((m_position.PriceOpen()-m_position.PriceCurrent())/ExtDP));
                    Print("#1122 cdist ",numstr,": ",cdist);
                    Print("#2211! m_position.PriceOpen(): ",m_position.PriceOpen());
                    Print("#2212! m_position.PriceCurrent(): ",m_position.PriceCurrent());
                    Print("#2213! ExtDP: ",ExtDP);
                    Print("#2214! magic: ",magic);
                    Print("#2215! ev: ",ev);
                    Print("#2216! iuv: ",iuv);
                    Print("#2217! m_position.Volume(): ",m_position.Volume());
                    Print("#2218! m_position.Magic(): ",m_position.Magic());
                    
                   
                    if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)<=imv)
                       ev=NormalizeDouble(m_position.Volume()+iuv*cdist,2);
                     if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)>imv)
                        ev=NormalizeDouble(imv,2);
                     rev=ev;
                     double sl=0.0;
                     double tp=0.0;
                     if(itp>0) tp=m_symbol.Ask()+etp;
                     if(isl>0) sl=m_symbol.Bid()-esl;
                     //m_trade.SetExpertMagicNumber(magic);
                     if(OpenBuy(m_trade,ev,sl,tp,numstr))
                     {
                        last_pt=POSITION_TYPE_BUY;
                        FileWrite(filehandle,numstr+", ",TimeCurrent(),", ",GetLastPositionsType(magic),", ",GetPositionTicket(magic,POSITION_TYPE_BUY)); 
                        Print("#516! Position BUY after down SELL "+numstr);                                 
                        //Sleep(3000);
                        continue;
                     }
                  }
               }
            }
            if(m_position.PositionType()==POSITION_TYPE_BUY  && m_position.Magic()==magic)
            {
               if((m_position.Profit()+m_position.Swap()+m_position.Commission())<0)
               {
                  if(IsSetBuy(magic,ExtDP)==true)
                  {
                     double cdist=MathFloor(MathAbs((m_position.PriceOpen()-m_position.PriceCurrent())/ExtDP));
                     Print("#1123 cdist ", numstr," : ",cdist);
                     Print("#3211! m_position.PriceOpen(): ",m_position.PriceOpen());
                     Print("#3212! m_position.PriceCurrent(): ",m_position.PriceCurrent());
                     Print("#3213! ExtDP: ",ExtDP);
                     Print("#3214! magic: ",magic);
                     Print("#3215! ev: ",ev);
                     Print("#3216! iuv: ",iuv);
                     Print("#3217! m_position.Volume(): ",m_position.Volume());
                     Print("#3218! m_position.Magic(): ",m_position.Magic());
                    
                     if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)<=imv)
                        ev=NormalizeDouble(m_position.Volume()+iuv*cdist,2);
                     if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)>imv)
                        ev=NormalizeDouble(imv,2); 
                     rev=ev;                          
                     double sl=0.0;
                     double tp=0.0;
                     if(itp>0) tp=m_symbol.Ask()+etp;
                     if(isl>0) sl=m_symbol.Bid()-esl;
                     //m_trade.SetExpertMagicNumber(magic);
                     if(OpenBuy(m_trade,ev,sl,tp,numstr))
                     {
                        last_pt=POSITION_TYPE_BUY;
                        FileWrite(filehandle,numstr+", ",TimeCurrent(),", ",GetLastPositionsType(magic),", ",GetPositionTicket(magic,POSITION_TYPE_BUY)); 
                        Print("#517! Position BUY After down BUY "+numstr);                                 
                        //Sleep(3000);
                        continue;
                     }
                  }
               } 
            }
         }
}


void OpenNextSellPositionBySignal(CTrade &m_trade,long magic,double ExtDP,double iuv,double imv,int itp,int isl,double etp,double esl,double ev,double &rev,string numstr,ulong &last_pt)
{
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name())
         {
            if(m_position.PositionType()==POSITION_TYPE_BUY  && m_position.Magic()==magic)
            {
               if((m_position.Profit()+m_position.Swap()+m_position.Commission())<0)
               {
                  if(IsSetSell(magic,ExtDP)==true)
                  {
                     double cdist=MathFloor(MathAbs((m_position.PriceCurrent()-m_position.PriceOpen())/ExtDP));
                     Print("#1124 cdist ", numstr," : ",cdist);
                     Print("#4211! m_position.PriceOpen(): ",m_position.PriceOpen());
                     Print("#4212! m_position.PriceCurrent(): ",m_position.PriceCurrent());
                     Print("#4213! ExtDP: ",ExtDP);
                     Print("#4214! magic: ",magic);
                     Print("#4215! ev: ",ev);
                     Print("#4216! iuv: ",iuv);
                     Print("#4217! m_position.Volume(): ",m_position.Volume());
                     Print("#4218! m_position.Magic(): ",m_position.Magic());
                   
                     if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)<=imv)
                        ev=NormalizeDouble(m_position.Volume()+iuv*cdist,2);
                     if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)>imv)
                        ev=NormalizeDouble(imv,2);
                     rev=ev;
                     double sl=0.0;
                     double tp=0.0;
                     if(itp>0) tp=m_symbol.Bid()-etp;
                     if(isl>0) sl=m_symbol.Ask()+esl;
                     //m_trade.SetExpertMagicNumber(magic);
                     if(OpenSell(m_trade,ev,sl,tp,numstr))
                     {
                        last_pt=POSITION_TYPE_SELL;
                        FileWrite(filehandle,numstr+", ",TimeCurrent(),", ",GetLastPositionsType(magic),", ",GetPositionTicket(magic,POSITION_TYPE_SELL)); 
                        Print("#518! Position SELL After down BUY "+numstr);                             
                        //Sleep(3000);
                        continue;
                      }
                   }
                }
             }
             if(m_position.PositionType()==POSITION_TYPE_SELL  && m_position.Magic()==magic)
             {
                if((m_position.Profit()+m_position.Swap()+m_position.Commission())<0)
                {
                   if(IsSetSell(magic,ExtDP)==true)
                   {
                      double cdist=MathFloor(MathAbs((m_position.PriceCurrent()-m_position.PriceOpen())/ExtDP));
                      Print("#1125 cdist ", numstr," : ",cdist);
                      Print("#5211! m_position.PriceOpen(): ",m_position.PriceOpen());
                      Print("#5212! m_position.PriceCurrent(): ",m_position.PriceCurrent());
                      Print("#5213! ExtDP: ",ExtDP);
                      Print("#5214! magic: ",magic);
                      Print("#5215! ev: ",ev);
                      Print("#5216! iuv: ",iuv);
                      Print("#5217! m_position.Volume(): ",m_position.Volume());
                      Print("#5218! m_position.Magic(): ",m_position.Magic());
                    
                      if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)<=imv)
                         ev=NormalizeDouble(m_position.Volume()+iuv*cdist,2);
                      if(NormalizeDouble(m_position.Volume()+iuv*cdist,2)>imv)
                         ev=NormalizeDouble(imv,2); 
                      rev=ev;                             
                      double sl=0.0;
                      double tp=0.0;
                      if(itp>0) tp=m_symbol.Bid()-etp;
                      if(isl>0) sl=m_symbol.Ask()+esl;
                      //m_trade.SetExpertMagicNumber(magic);
                      if(OpenSell(m_trade,ev,sl,tp,numstr))
                      {
                        last_pt=POSITION_TYPE_SELL;
                        FileWrite(filehandle,numstr+", ",TimeCurrent(),", ",GetLastPositionsType(magic),", ",GetPositionTicket(magic,POSITION_TYPE_SELL)); 
                        Print("#519! Position SELL After down SELL "+numstr);                                 
                        //Sleep(3000);
                        continue;
                      }
                   }
                }
             }
          }
}


журнал
Заранее спасибо за ответ.
Причина обращения: