Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1343

 
Alexey Viktorov #:
Виталий, а зачем всё это? Надо имея > 1 окна индикатора получить номер окна и чего-то туда всунуть?

Да, верно.

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

  if(id==CHARTEVENT_OBJECT_CLICK && StringFind(sparam,(string)wndNum+"_butt")!=-1) {
    Alert("Window number:"+(string)wndNum," => Program name:"+prog_name," => Short name:"+short_name);
    ObjectSetInteger(0,sparam,OBJPROP_STATE,false);
  }

мт4 работает


мт5 только в одном - первом установленном, копии игнорирует 


 

Дошло уже до такого, ну ни в какую не решается задача недели :(

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
//#property indicator_width1  1

input ulong MASlow = __COUNTER__; // Период медленной МА

//+------------------------------------------------------------------+
int wndNum;
string prog_name,short_name;
double Label1Buffer[];
bool flag=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
  prog_name=MQLInfoString(MQL_PROGRAM_NAME);

  int q=0;
  for(int k=1; k<ChartGetInteger(0,CHART_WINDOWS_TOTAL); k++) {
    for(int e=0; e<ChartGetInteger(0,CHART_WINDOWS_TOTAL); e++) {
      if(ChartIndicatorName(0,k,e)==prog_name) {
        q++;
      }
    }
  }

  short_name="Set ("+(string)MASlow+")";
  IndicatorSetString(INDICATOR_SHORTNAME,short_name);
  wndNum=ChartWindowFind();
  
  wndNum=q;
  
  ButtonCreate(0,(string)wndNum+"_butt",44,18,40,14,CORNER_RIGHT_LOWER,"= "+(string)wndNum+" =","Alert","Arial",9,clrBlack,C'236,233,216',clrGray,false,false,false);
  
  SetIndexBuffer(0,Label1Buffer);
  PlotIndexSetInteger(0,PLOT_LINE_WIDTH,q+1);

  flag=true;

  Print("INIT SUCCEEDED: "+(string)wndNum," => Count: ",q);
//---
  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  ObjectsDeleteAll(0,(string)wndNum+"_butt");
  ChartRedraw();
}

//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
  for(int i = prev_calculated == 0 ? 0 : prev_calculated - 1; i < rates_total; i++) {
    Label1Buffer[i] = close[i];
  }
  if(flag==false) OnInit();
  return(rates_total);
}

//+------------------------------------------------------------------+
//| OnChartEvent function                                            |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
  if(id==CHARTEVENT_OBJECT_CLICK && StringFind(sparam,(string)wndNum+"_butt")!=-1) {
    Alert("Window number:"+(string)wndNum," => Program name:"+prog_name," => Short name:"+short_name);
    ObjectSetInteger(0,sparam,OBJPROP_STATE,false);
  }
  if(id==CHARTEVENT_CHART_CHANGE) {
    ButtonCreate(0,(string)wndNum+"_butt",44,18,40,14,CORNER_RIGHT_LOWER,"= "+(string)wndNum+" =","Alert","Arial",9,clrBlack,C'236,233,216',clrGray,false,false,false);
    OnInit();
  }
}

//===============================================================================================
//--------------------------------------- Создает кнопку ---------------------------------------+
//===============================================================================================
void ButtonCreate(long chart_ID=0,string nm="Button",int xd=0,int yd=0,int width=50,int height=18,int cr=0,
                  string text="Button",string tooltip="Button",string font="Arial",int font_size=9,color clr=clrBlack,
                  color back_clr=C'236,233,216',color border_clr=clrNONE,bool state=false,bool selection=true,bool selectable=true,bool bc=false)
{
  if(ObjectFind(chart_ID,nm)<0) {
    ObjectCreate(chart_ID,nm,OBJ_BUTTON,wndNum,0,0);
    ObjectSetInteger(chart_ID,nm,OBJPROP_XSIZE,width);
    ObjectSetInteger(chart_ID,nm,OBJPROP_YSIZE,height);
    ObjectSetInteger(chart_ID,nm,OBJPROP_CORNER,cr);
    ObjectSetString(chart_ID,nm,OBJPROP_TEXT,text);
    ObjectSetString(chart_ID,nm,OBJPROP_TOOLTIP,tooltip);
    ObjectSetString(chart_ID,nm,OBJPROP_FONT,font);
    ObjectSetInteger(chart_ID,nm,OBJPROP_FONTSIZE,font_size);
    ObjectSetInteger(chart_ID,nm,OBJPROP_COLOR,clr);
    ObjectSetInteger(chart_ID,nm,OBJPROP_BGCOLOR,back_clr);
    ObjectSetInteger(chart_ID,nm,OBJPROP_BORDER_COLOR,border_clr);
    ObjectSetInteger(chart_ID,nm,OBJPROP_BACK,bc);
    ObjectSetInteger(chart_ID,nm,OBJPROP_STATE,state);
    ObjectSetInteger(chart_ID,nm,OBJPROP_SELECTABLE,selectable);
    ObjectSetInteger(chart_ID,nm,OBJPROP_SELECTED,selection);
    ObjectSetInteger(chart_ID,nm,OBJPROP_HIDDEN,false);
    ObjectSetInteger(chart_ID,nm,OBJPROP_YDISTANCE,yd);
    ObjectSetInteger(chart_ID,nm,OBJPROP_ZORDER,10);
    ObjectSetInteger(chart_ID,nm,OBJPROP_XDISTANCE,xd);
    ChartRedraw();
  }
}
//+------------------------------------------------------------------+
 
Vitaly Muzichenko #:

Да, верно.

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

мт4 работает


мт5 только в одном - первом установленном, копии игнорирует 


Ну, видимо это следствие повышенной производительности… Зачем пересчитывать индикатор 100500 раз по прихоти не очень умного пользователя? Но вот так случилось, что от защиты страдают некоторые возможности.

Наверное надо ввести в короткое имя индикатора внешний параметр.

input int MAFast = 8;  // Период быстрой МА
input string shortName = "1";  // Префикс…
string short_name = "";
/********************************************************************\
|           Custom indicator initialization function                 |
\********************************************************************/
int OnInit()
 {
//--- indicator buffers mapping
  short_name = shortName+MQLInfoString(MQL_PROGRAM_NAME) + "=Set (" + (string)MASlow + "/" + (string)MAFast + ")";
  IndicatorSetString(INDICATOR_SHORTNAME, short_name);
  SetIndexBuffer(0, Label1Buffer, INDICATOR_DATA);
  Print("INIT_SUCCEEDED");
  return(INIT_SUCCEEDED);
 }/******************************************************************/

Так работает. Проверено.

 
Alexey Viktorov #:

Ну, видимо это следствие повышенной производительности… Зачем пересчитывать индикатор 100500 раз по прихоти не очень умного пользователя? Но вот так случилось, что от защиты страдают некоторые возможности.

Наверное надо ввести в короткое имя индикатора внешний параметр.

Так работает. Проверено.

Опять-же, нужно менять префикс при загрузке следующей копии?

 
Vitaly Muzichenko #:

Опять-же, нужно менять префикс при загрузке следующей копии?

а словами то можно озвучить какая цель?

кнопки можно и не на своем окне создавать и контролировать.


что это будет?

 
Igor Makanu #:

а словами то можно озвучить какая цель?

кнопки можно и не на своем окне создавать и контролировать.


что это будет?

Не знаю, но нужно именно так: Создать в своём подокне, и при клике получить номер этого подокна. Рисовать ничего не нужно, только кнопку, которая при клике выводит информацию в Алерт о номере подокна

 
Vitaly Muzichenko #:

Не знаю, но нужно именно так: Создать в своём подокне, и при клике получить номер этого подокна. Рисовать ничего не нужно, только кнопку, которая при клике выводит информацию в Алерт о номере подокна

проверил на своем первом исходнике:

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#include <Controls\Button.mqh>
CButton button;

//--- indicator buffers
double         Label1Buffer[];
input int MASlow = 21; // Период медленной МА
input int MAFast = 8;  // Период быстрой МА
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   string short_name = MQLInfoString(MQL_PROGRAM_NAME) + "=Set (" + (string)MASlow + "/" + (string)MAFast + ")";
   IndicatorSetString(INDICATOR_SHORTNAME, short_name);

  // IndicatorSetString(INDICATOR_SHORTNAME, "IndicatorSetString() Demo");
   SetIndexBuffer(0, Label1Buffer, INDICATOR_DATA);
   srand(GetTickCount());
   long c_id = ChartID();
   int c_wf = ChartWindowFind();
   Print(c_id, " / ", c_wf);
   button.Create(c_id, "button" + (string)rand(), c_wf, 10, 10, 100, 100);
   button.Text("Button");
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   for(int i = prev_calculated == 0 ? 0 : prev_calculated - 1; i < rates_total; i++)
   {
      Label1Buffer[i] = close[i];
   }
   return(rates_total);
}
//+------------------------------------------------------------------+


увы, все как Вы пишите - если запустить несколько копий этого индикатора с параметрами по умолчанию, то кнопка будет только на первом индикаторе  в подокне

а если изменить параметры при запуске, то все ОК


в общем непонятная ситуация

 
Igor Makanu #:

проверил на своем первом исходнике:

увы, все как Вы пишите - если запустить несколько копий этого индикатора с параметрами по умолчанию, то кнопка будет только на первом индикаторе  в подокне

а если изменить параметры при запуске, то все ОК

в общем непонятная ситуация

Вот тут и вопрос: Как сменить параметры автоматически, не влезая в настройки?

Пока ничего не получается ...

---

P.S. В идеале, но увы

input long MASlow = TimeLocal(); //
 
Vitaly Muzichenko #:

Пока ничего не получается ...

и не получится:

добавил в:

int OnInit()
{
   Print(__FUNCTION__);

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

 
Igor Makanu #:

и не получится:

добавил в:

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

Вот так и есть. Видать архитектура мт5 - кривая. В мт4 всё работает отменно.

Если решили в мт5 так сделать, тогда поставили-бы запрет на запуск копии индикатора с одинаковыми входными параметрами, а то вроде как он есть, а по факту его - нет.