Мой индикатор исчезает при переходе на новый график таймфрейма - страница 2

 

Спасибо за ваше объяснение.

Теперь я вижу это лучше.

SCFX

 

Привет,

Я чешу голову от этой безумной ошибки.

До сих пор этот простой индикатор из 4 рядов кода исчезает, когда я меняю таймфрейм.

Как ни странно, я уже применил все предложения, размещенные здесь, но все равно ничего не получилось.

Я чувствую себя так плохо...

Пожалуйста, помогите мне.

Большое спасибо,

SCFX

//+------------------------------------------------------------------+
//|                                                        H_roc.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//#property indicator_minimum -3.5
//#property indicator_maximum 3.5
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "boring"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
//--- indicator buffers
double         boring[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,boring);
   
          
//---
   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[])
  {

//----

   int limit=rates_total-prev_calculated;
   if(limit<=0) limit=300;
//---
 
 for(int i=1;i<=limit  ;i++)
{  if(   MathAbs(Close[i]-Open[i])/(High[i]-Low[i])<0.50
     ) 
      boring[i]=Close[i];
    
}  
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
scfx:

Привет,

Я чешу голову от этой безумной ошибки.

До сих пор этот простой индикатор из 4 рядов кода исчезает, когда я меняю таймфрейм.

Как ни странно, я уже применил все предложения, размещенные здесь, но все равно ничего не получилось.

Я чувствую себя так плохо...

Пожалуйста, помогите мне.

Большое спасибо,

SCFX



2014.06.15 11:26:39.908 нулевое деление в 'test.mq4' (59,44)
 
angevoyageur:
2014.06.15 11:26:39.908 нулевое деление в 'test.mq4' (59,44)


Спасибо за ответ.

На моем журнале нет такого уведомления, но когда я меняю TF, этот индикатор удаляется.

Пока не могу исправить.

SCFX

2014.05.18 08:41:31.080Пользовательский индикатор H_889_boring GBPUSD,H1: удален
2014.05.18 08:41:25.441 Пользовательский индикатор H_889_boring GBPUSD,H4: успешно загружен

 
scfx:

Я все еще не могу исправить это.

SCFX

Это потому, что вы не очень стараетесь.

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

for(int i=1;i<=limit  ;i++)
{  if(   MathAbs(Close[i]-Open[i])/(High[i]-Low[i])<0.50
     ) // what is this parentheses doing here ? How can you expect to write code that works if you are this sloppy about it ?
      boring[i]=Close[i];
    
}  

Это все, что вы можете сделать, чтобы найти причину проблемы.

  • Вы сказали, что проверили вкладку журнала, а заглянули ли вы во вкладку экспертов рядом с ней?
  • Я уже говорил вам на прошлой неделе, что ваш код вызывает array out of range, вы посмотрели, что это значит?
  • В metaeditor есть отладчик, вы можете попробовать научиться использовать его для отладки кода.
  • Вы можете использовать Print(), чтобы проверить, какие значения переменных были во время выполнения кода.

Если бы вы перешли на вкладку "Эксперты", то там было бы сказано, что ваш индикатор сделал нулевое деление на этой линии, смена таймфреймов здесь ни при чем.

if(   MathAbs(Close[i]-Open[i])/(High[i]-Low[i])<0.50

Это означает, что High[i]-Low[i] по какой-то причине был равен нулю. Если вы посмотрите на индикатор на графике, вы увидите, что индикатор нарисовал некоторые из своих значений, а затем остановился на баре, где есть только один тик. Если есть только один тик high[i] == low[i], то это вызвало бы нулевое деление.

Теперь убедитесь, что значение high[i]-low[i] не используется, если оно равно нулю.

   int limit=rates_total-prev_calculated;
   if(limit<=0) limit=300;
//---
   for(int i=1;i<=limit  ;i++)
   {
    if(High[i] - Low[i] == 0) continue; // --------------- skip this bar
    
    if( MathAbs(Close[i]-Open[i])/(High[i]-Low[i])<0.50 ) 
    {boring[i]=Close[i];
   }}
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Теперь вы увидите, что на вкладке "Эксперты" показано, что код больше не делится на ноль, но выдает ошибку array out of range на этой строке.

if(high[i] - low[i] == 0)  

Что же произойдет, если убрать все вычисления и условия для проверки цикла?

   int limit=rates_total-prev_calculated;
   if(limit<=0) limit=300;
//---

   for(int i=1;i<=limit  ;i++)
   { 
    boring[i]=Close[i];
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Теперь вкладка experts снова сообщает об ошибке array out of range, на этот раз в этой строке:

boring[i]=Close[i];

Теперь вы знаете, что ваш код приводит к выходу массива за пределы диапазона каждый раз, когда в цикле используется массив цен. Итак, выясните, что не так с циклом и почему Close[i], Low[i], High[i] выходят за пределы диапазона. Вы видите, что индикатор рисует до конца графика, поэтому ошибка должна быть в конце, в самых высоких индексах массива.

   int limit=rates_total-prev_calculated; // what is the value of limit in this calculation when prev_calulated == 0 ?
   if(limit<=0) limit=300;
//---

   for(int i=1;i<=limit;i++) // how does the value of limit compare with the highest available Close[] array index ?

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

@ scfx

Единственный человек, который может исправить, это вы. Или зайдите на https://www.mql5.com/en/job

и опубликуйте работу там.

 
SDC:
...

Пожалуйста, SDC, не нужно быть таким суровым, даже если вы правы.
 
angevoyageur:

Пожалуйста, SDC, не нужно быть таким суровым, даже если вы правы.

lol Я немного переформулировал свой пост ;)

 

Извините, я ввел вас в заблуждение, прошу прощения, индикатор может быть закодирован таким образом:

int limit = -1;
   if( prev_calculated == 0 ) limit =  rates_total - 3000;// will calculate 3000 Bars
  if( prev_calculated > 0 )   limit = rates_total-prev_calculated;

 for(int i=limit;  i>=0; i--)
   {
    if(High[i] - Low[i] == 0) continue; // --------------- skip this bar
    

// Please test it, check if it's OK;
// Put the indicator in a backtest EA, say MACDSample, to check it
 

Если график имеет менее 3000 баров, он все равно будетвне диапазона.

Причина обращения: