Мешает ли Вам продолжение работы расчетной части индикатора после его программного закрытия? - страница 3

 

Советник

#property   strict
#define     IndName           "Projects\\Temp\\ExpAndIndTest\\Indicator_08"
input    ulong    nTick       =  125;
input    int      MSTimerSet  =  100;
string   InicatorName         =  IndName+".ex5";
int      IndicatorHandle      =  -1;
int      Count                =  10;
ulong    gTick                =  0;

int OnInit(){
   GlobalVariableSet("Stop",0.0);
   GlobalVariableSet("IndCalc",0.0);
   int err=-1;
   int count=50;
   {while((err!=0)&&(count>0))
   {
      ResetLastError();
      EventSetMillisecondTimer(MSTimerSet);
      err=GetLastError();
      {if(err!=0)
      {
         Sleep(50);
      }}
      count--;
   }}
   return(INIT_SUCCEEDED);
}

void OnTimer(){
   OnTick();
}

void OnTick(){
   gTick++;
   {if(IndicatorHandle<0)
   {
      ResetLastError(); 
      IndicatorHandle=iCustom(   Symbol(),
                                 PERIOD_CURRENT,
                                 InicatorName
                                 );
      int nNewWindow=(int)ChartGetInteger(ChartID(),CHART_WINDOWS_TOTAL);
      ChartIndicatorAdd(ChartID(),nNewWindow,IndicatorHandle);
   }}
   gTick++;
   {if(gTick>nTick)
   {
      ExpertRemove();
   }}
}

void OnDeinit(const int reason){
   GlobalVariableSet("Stop",1.0);
   GlobalVariableSet("IndCalc",0.0);
   Indicator_Delete_Handle(IndicatorHandle);
   IndicatorRelease(IndicatorHandle);
   return;
}

bool Indicator_Delete_Handle(int iIndicatorHandle){
string   Chart_Indicator_Name;
   int Chart_Windows_Total=(int)ChartGetInteger(ChartID(),CHART_WINDOWS_TOTAL);
   {for(int nWindow=0;nWindow<Chart_Windows_Total;nWindow++)
   { 
      int Chart_Indicators_Total=ChartIndicatorsTotal(ChartID(),nWindow);
      {for(int nIndicator=0;nIndicator<Chart_Indicators_Total;nIndicator++)
      { 
         Chart_Indicator_Name=ChartIndicatorName(ChartID(),nWindow,nIndicator);
         int Indicator_Handle=ChartIndicatorGet(ChartID(),nWindow,Chart_Indicator_Name);
         {if(Indicator_Handle==iIndicatorHandle)
         {
            {if(ChartIndicatorDelete(ChartID(),nWindow,Chart_Indicator_Name))
            {
               return(true);     
            }}
         }}
      }}
   }}
   return(false);     
}
     
 

Индикатор

#property   strict
#property   indicator_separate_window
#property   indicator_buffers    1
#property   indicator_plots      0
#property   indicator_minimum    0
#property   indicator_maximum    100
#property   indicator_level1     50
#define     IndName              "Indicator_08"

int      MSTimerSet              =  50;
string   ThisIndicatorName       =  IndName;
int      ThisIndicatorHandle     =  -1;
double   ThisDataBuffer[];
ulong    gTick                   =  0;

int OnInit(){
   Print("OnInit()");
   gTick=0;
   {if(GlobalVariableGet("Stop")>0.0)
   {
      return(INIT_FAILED);
   }}
   int err=-1;
   int count=50;
   {while((err!=0)&&(count>0))
   {
      ResetLastError();
      EventSetMillisecondTimer(MSTimerSet);
      err=GetLastError();
      {if(err!=0)
      {
         Sleep(50);
      }}
      count--;
   }}
   IndicatorSetString(INDICATOR_SHORTNAME,ThisIndicatorName);
   SetIndexBuffer(0,ThisDataBuffer);
   ArraySetAsSeries(ThisDataBuffer,true);
   ThisIndicatorHandle=-1;
   ThisIndicatorName=IndName;
   return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total,
                 const int prev_calculated,
                 const int begin,
                 const double& price[]){
   On_Tick();
   return(rates_total);
}

void OnTimer(){
   On_Tick();
}

void On_Tick(){
   gTick++;
   Print("On_Tick(): gTick="+IntegerToString(gTick));
   {if(GlobalVariableGet("Stop")>0.0)
   {
      OnDeinit(777);
      return;
   }}
   {if(GlobalVariableGet("IndCalc")<1.0)
   {
      GlobalVariableSet("IndCalc",1.0);
   }}
   {if(GlobalVariableGet("IndCalc")<1.0)
   {
      return;
   }}
   {if(ThisIndicatorHandle<0)
   {
      ThisIndicatorHandle=ChartIndicatorGet(ChartID(),ChartWindowFind(ChartID(),ThisIndicatorName),ThisIndicatorName);
      {if(ThisIndicatorHandle<1)
      {
         return;
      }}
      ThisIndicatorName="";
      IndicatorName_Search_Handle(ThisIndicatorHandle,ThisIndicatorName); 
   }else{
      ThisDataBuffer[0]=SymbolInfoDouble(Symbol(),SYMBOL_BID);
   }}
}

void OnDeinit(const int reason){
   return;
}

bool IndicatorName_Search_Handle(int      iIndicatorHandle,
                                 string   &iChartIndicatorName){
   MqlParam IndicatorParametersArray[]; 
   ZeroMemory(IndicatorParametersArray);
   ENUM_INDICATOR iIndicatorType; 
   int iIndicatorParameters=IndicatorParameters(iIndicatorHandle,iIndicatorType,IndicatorParametersArray);
   {if(iIndicatorParameters<0)
   {
      iChartIndicatorName=""; 
      return(false);     
   }}
   iChartIndicatorName=IndicatorParametersArray[0].string_value;
   return(true); 
}  
 
Yury Kirillov:

Индикатор


Чтобы код не терялся - после кода что-нибудь набирайте на клавиатуре. Например я после кода вставляю "ds".

 
Vladimir Karputov:

Чтобы код не терялся - после кода что-нибудь набирайте на клавиатуре. Например я после кода вставляю "ds".


Я в курсе :-)

 
Yury Kirillov:

Вот почистил.

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

Добавьте эту строку в индикатор

void On_Tick(){
   gTick++;
   Print("On_Tick(): gTick="+IntegerToString(gTick));
   {if(GlobalVariableGet("Stop")>0.0)
   {
      OnDeinit(777);
      return;
   }}
   {if(GlobalVariableGet("IndCalc")<1.0)
   {
      GlobalVariableSet("IndCalc",1.0);
   }}
   {if(GlobalVariableGet("IndCalc")<1.0)
   {
      return;
   }}
   {if(ThisIndicatorHandle<0)
   {
      ThisIndicatorHandle=ChartIndicatorGet(ChartID(),ChartWindowFind(ChartID(),ThisIndicatorName),ThisIndicatorName);
      {if(ThisIndicatorHandle<1)
      {
         return;
      }}
      ThisIndicatorName="";
      IndicatorName_Search_Handle(ThisIndicatorHandle,ThisIndicatorName); 
      
      IndicatorRelease(ThisIndicatorHandle);
   }else{
      ThisDataBuffer[0]=SymbolInfoDouble(Symbol(),SYMBOL_BID);
   }}
}

ChartIndicatorGet самого себя увеличивает счетчик.


Что касается получения хендла самого себя, то его, как Вы делаете, не получить в общем случае, т.к. несколько копий одного и того же индикатора может быть запущено, но с разными входными параметрами. А короткое имя у них у всех будет совпадать. Хэндл и, соответственно, получение списка входных параметров, делается иначе. Посмотрите это здесь.

Init_Sync
Init_Sync
  • голосов: 25
  • 2017.04.17
  • fxsaber
  • www.mql5.com
Если в MT изменить таймфрейм или имя символа чарта, то все индикаторы на чарте выгрузятся с чарта и загрузятся на него снова. При этом, в отличие от MT4, в MT5 последовательность выгрузиться/загрузиться не определена из-за особенности внутренней архитектуры. Данное обстоятельство иногда вызывает не сразу очевидные проблемы, связанные с тем, что...
 
fxsaber:

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

Добавьте эту строку в индикатор

ChartIndicatorGet самого себя увеличивает счетчик.


Что касается получения хендла самого себя, то его, как Вы делаете, не получить в общем случае, т.к. несколько копий одного и того же индикатора может быть запущено, но с разными входными параметрами. А короткое имя у них у всех будет совпадать. Хэндл и, соответственно, получение списка входных параметров, делается иначе. Посмотрите это здесь.


За       IndicatorRelease(ThisIndicatorHandle);

спасибо большое, сейчас буду гонять - проверять.

А короткое имя нагенерируем уникальных любое количество - не проблема.

Ну извините за наглость, вопрос:

Где взять список какие функции и насколько увеличивают/уменьшают счетчик индикатора? 

 
Yury Kirillov:

Где взять список какие функции и насколько увеличивают/уменьшают счетчик индикатора? 

Не знаю, индикаторы не пишу.

Yury Kirillov:

А короткое имя нагенерируем уникальных любое количество - не проблема.

Есть просто универсальный способ.
 
fxsaber:

Не знаю, индикаторы не пишу.

Есть просто универсальный способ.

Видел в вашем примере кода https://www.mql5.com/ru/forum/190232/page2#comment_6014261

Это оно?

Библиотеки: Init_Sync
Библиотеки: Init_Sync
  • 2017.04.18
  • www.mql5.com
Init_Sync: Автор: fxsaber...
 
Yury Kirillov:

Видел в вашем примере кода https://www.mql5.com/ru/forum/190232/page2#comment_6014261

Это оно?

const int handle = INIT_SYNC::GetMyHandle();
 

Решение получено!

С подсказки fxsaber что ChartIndicatorGet() изменяет счетчик индикатора на +1 и после вызова

ThisIndicatorHandle=ChartIndicatorGet(ChartID(),ChartWindowFind(ChartID(),ThisIndicatorName),ThisIndicatorName);

необходимо использовать IndicatorRelease() для его изменения на -1

IndicatorRelease(ThisIndicatorHandle);

Однако остался нерешенный вопрос:

Где взять список какие функции и насколько увеличивают/уменьшают счетчик индикатора? 

Пока известен следующий список.

ФункцияИзменение счетчика индикатора
iCustom()
+1
ChartIndicatorAdd()
+1
ChartIndicatorDelete()
-1
IndicatorRelease()
-1
ChartIndicatorGet()
+1