Индикатор от индикатора - страница 3

 

Всё!!! Здаюсь... ковырял ковырял справку, но так и не смог получить нужного результата. Собственно Сам вопрос. Может ктонибудь просто сказать. Чувачёк, в твоих индикаторах нужно вот тут поставить вот это, потому что то-то, а вот тут поставить вот это, потому что такто. Это действительно будет помощь. Потому как время идёт, а я тупо не догоняю как исправить код..... Заранее благодарен.

Описание. Основной индикатор "Секвента" в одном из буферов формирует сигнал 1 покупаем -1 продаём, в остальное время буфер равен нулю.

Как только пришёл сигнал начинаем запрашивать смежные индикаторе (в нашем случае AD) на предмет текущих значений.

Проблема в том что при компиле в принт выводит одни значение АД, в тестере на том же самом месте значения абсалютно другие.

Первый индикатор Секвента, второй организовывает вызов АД в момент поступления сигнала.

Ну не понимаю я как это сделать, помощи прошу просто.....

Файлы:
 

Неужто перевелись богатыри на руси??? И подсказать не кому???

 

Ну где же вы профессионалы??? Подскажите хоть в чём проблема? Хуже всего когда всё написано правильно, а всё равно не работает.

 
Mihail Marchukajtes:

Ну где же вы профессионалы??? Подскажите хоть в чём проблема? Хуже всего когда всё написано правильно, а всё равно не работает.

А может проблема в вычислении индикатора? Почему-бы не взять стандартный iAD и не мудрить с вычислениями?

Вот показания стандартного и вашего индикаторов по реальным объёмам.


Как видите расхождения есть. Да и вычисление организовано... Зачем пытаться подогнать под стандарт mql4 и менять направление индексации?.

 
Alexey Viktorov:

А может проблема в вычислении индикатора? Почему-бы не взять стандартный iAD и не мудрить с вычислениями?

Вот показания стандартного и вашего индикаторов по реальным объёмам.


Как видите расхождения есть. Да и вычисление организовано... Зачем пытаться подогнать под стандарт mql4 и менять направление индексации?.


Со стандартным такаяже беда.....

 

Я правильно понимаю, что индикатор правильно рассчитывает на истории значения, как в тестере, так и на реальных данных (у меня так получилось), если расчет идет на чарте VTBR-12.17?

А вот расчет при появлении нового бара отличается от тестера и реальных данных?

При этом индикатор Вы вызываете не на том инструменте, на котором идет расчет?

Соответстено проблема возникает из-за рассинхронизации баров на двух инструментах.

Тогда, почему бы не копировать значение индикатора AD не по индексу буфера, а по времени? Копировать можно сразу за последние 15 минут, если дыра большая, а потом посмотреть где кончаются нули в буфере и от туда уже вычислить  последнее значение.

Обращение по начальной и конечной датам требуемого интервала времени

int  CopyBuffer( 
   int       indicator_handle,     // handle индикатора 
   int       buffer_num,           // номер буфера индикатора 
   datetime  start_time,           // с какой даты 
   datetime  stop_time,            // по какую дату 
   double    buffer[]              // массив, куда будут скопированы данные 
   );
 

Нет. Различия между компиляцией и тестером.

В момент компиляции или сохранения данных на диск с помощью скрипта сохраняются одни данные, а в тестере и на реале дургие. Согласен что проблема с ориентацией между массивами. Думаю по времекни обращение можно попролбовать как вариант, но думаю результат будет точно такойже. Мне так кажется. чуть позже проверю. Или проблема во времени расчёта нидикатора. В тестере и реале, просто не успевает просчитаться. Причём если делаю вызов без использования базового индикатора, то всё вроде как правильно, когда начинаю сохранять данные в определённый момент, по сигналу базового индюка. Начинается свистоплятска. Потому как где нужно, я уже все массивы перевернул.... Как то так....

 

В поисках проблемы немного изменил Ваш индикатор,

//+------------------------------------------------------------------+
//| 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[])
  {
//---
/*
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(time,true);
*/  
   if(rates_total<=1)
   {
      return(rates_total);
   }   
//--- last counted bar will be recounted
   if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчёта индикатора
     {
      limit=rates_total-5; // стартовый номер для расчёта всех баров
        }else{
      limit=rates_total-prev_calculated; // стартовый номер для расчёта новых баров
     }
///////  


  if(b!=rates_total)
    {
    for(int i=rates_total-limit;i<rates_total && !IsStopped();i++)
     {    
       b=rates_total;   
           Print ("AD время  ",time[i],"   ","Время на VTBR-12.17 ", iTime("VTBR-12.17",PERIOD_CURRENT,rates_total-i-1)," ",AD(rates_total-i-1),"  ",i,"  ",rates_total);
           
     }      
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
double Sig(int index)
  {
   double MA[1];
   ResetLastError();
   if(CopyBuffer(MA_handle1,3,index,1,MA)<0)
     {
      Print("Buy Failed to copy Sig(",index,"), error code ",GetLastError());
      return(0.0);
     }
   return NormalizeDouble(MA[0],Digits());
  }




  double AD(int index)
  {
  double MA[1];
  ResetLastError();
   if(CopyBuffer(MA_handle,0,index,1,MA)<0)
     {
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      return(0.0);
     }
     
   return NormalizeDouble(MA[0],Digits());
  }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
  if(index < 0) return(-1);
  datetime ArrTime[1];
  ResetLastError();
   if(CopyTime(symbol,tf,index,1,ArrTime)>0)
      return(ArrTime[0]);
   else return(-1);
  }


Запустил индикатор на графике  Si-12.17  минутки и вот что увидел в логе:

2017.12.09 14:12:51.754 Train (Si-12.17,M1) AD время  2017.12.08 23:47:00   Время на VTBR-12.17 2017.12.08 23:43:00 -26890.0  81496  81499

2017.12.09 14:12:51.754 Train (Si-12.17,M1) AD время  2017.12.08 23:48:00   Время на VTBR-12.17 2017.12.08 23:48:00 -26890.0  81497  81499

2017.12.09 14:12:51.754 Train (Si-12.17,M1) AD время  2017.12.08 23:49:00   Время на VTBR-12.17 2017.12.08 23:49:00 -26902.0  81498  81499

А если посмотреть на график VTBR-12.17, то можно увидеть, что свечи со временем 23:47 просто нет в природе - есть 23:43 и сразу 23:48. Отсюда и проблемы. Вам надо решить, что делать в такой ситуации - ждать появление свечи или же брать информацию от последней свечи.
 

Если представить индикатор в таком формате

//+------------------------------------------------------------------+
//|                                                        Train.mq5 |
//|                                                       nikelodeon |
//|                         https://www.mql5.com/ru/users/nikelodeon |
//+------------------------------------------------------------------+
#property copyright "nikelodeon"
#property link      "https://www.mql5.com/ru/users/nikelodeon"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_width1   2
#property indicator_color1   Red

double Buffer0[];
int limit,b;
int MA_handle,MA_handle1;
int    bars_calculated=0;
int BarsMin=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
      SetIndexBuffer(0,Buffer0,INDICATOR_DATA);// Назначение массива буферу
   ArraySetAsSeries(Buffer0,true);

   MA_handle1=iCustom(_Symbol,0,"Musor\\TDSEQUENTA_by_nikelodeon",5,5);
   MA_handle =iAD("VTBR-12.17",_Period, VOLUME_REAL);  
   if((MA_handle==INVALID_HANDLE))
     {
      PrintFormat("Failed to create handle of the MA_handle indicator for the symbol %s/%s, error code %d",
                  Symbol(),EnumToString(Period()),GetLastError());
      return(INIT_FAILED);
     }
     BarsMin=MathMin(Bars(_Symbol,PERIOD_CURRENT),Bars("VTBR-12.17",PERIOD_CURRENT))-10;
Print("Минимум баров=",BarsMin);

//---
   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[])
  {
//---
//--- check for rates
   if(rates_total<10) return(0);
//--- preliminary calculations
   if(prev_calculated==0) limit=BarsMin;
   else limit=prev_calculated;
//--- the main loop of calculations

if(prev_calculated==0) //Рассчет на истории
{
   for(int i=limit;i<rates_total && !IsStopped();i++)
     {
       int Corr=rates_total-i-1;
       Print ("Рассчет на истории");
       Print ("Текущее время ",time[i]," Время на VTBR-12.17 ",iTime("VTBR-12.17",PERIOD_CURRENT,Corr)," AD=",AD(Corr)," i=",i," BarAll=",rates_total," BarCalc=",prev_calculated," Corr=",Corr);           
       Print("Минимум баров=",BarsMin);
     }
}

if(prev_calculated!=0) //Расчет по текущим данным
{
   for(int i=prev_calculated;i<rates_total && !IsStopped();i++)
     {
           int Corr=rates_total-i-1;
           Print ("Расчет по текущим данным");
           Print ("Текущее время ",time[i]," Время на VTBR-12.17 ",iTime("VTBR-12.17",PERIOD_CURRENT,Corr)," AD=",AD(Corr)," i=",i," BarAll=",rates_total,"  BarCalc=",prev_calculated," Corr=",Corr);              
     }
}

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
double Sig(int index)
  {
   double MA[1];
   ResetLastError();
   if(CopyBuffer(MA_handle1,3,index,1,MA)<0)
     {
      Print("Buy Failed to copy Sig(",index,"), error code ",GetLastError());
      return(0.0);
     }
   return NormalizeDouble(MA[0],Digits());
  }




  double AD(int index)
  {
  double MA[1];
  ResetLastError();
   if(CopyBuffer(MA_handle,0,index,1,MA)<0)
     {
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      return(0.0);
     }
     
   return NormalizeDouble(MA[0],Digits());
  }




//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
  if(index < 0) return(-1);
  datetime ArrTime[1];
  ResetLastError();
   if(CopyTime(symbol,tf,index,1,ArrTime)>0)
      return(ArrTime[0]);
   else return(-1);
  }

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

Поэтому расчеты по текущем данным будут идти в блоке "Расчет по текущим данным", и думаю, они будут совпадать, как в тестере, так и в реале.

 

Спасибо! Попробую рассмотреть чуть позже Ваш вариант...

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