Отрисовка n последних баров в индикаторе. - страница 3

 
joo :

Нет, я не правильно понял. Можно.

И ни кто меня не поправил.


Есть в справке такой раздел - Направление индексации в массивах и таймсериях
 
Rosh :
Есть в справке такой раздел - Направление индексации в массивах и таймсериях

Да, спасибо. Там я был.

Кроме того, смотрел Функции обработки событий. Но до меня не дошло. Как то очень глубоко зарыта столь важная информация. Может стоит в справке "поднять на верх" что то типа:

"Индикаторные буферы и предопределенные массивы с ценовой информацией по умолчанию имеют прямое направление индексации. Направление индексации можно изменить функцией  ArraySetAsSeries() , в том числе и для предопределенных массивов" - Как то так.  


 

Вообще говоря, нельзя закладываться на какое-то умолчательное поведение, и об этом написано в функции ArrayGetAsSeries():

Примечание

Для проверки массива на принадлежность к таймсерии следует применять функцию ArrayIsSeries(). Массивы ценовых данных, переданных в качестве входных параметров в функцию OnCalculate(), не обязательно имеют направление индексации как у таймсерий. Нужное направление индексации можно установить функцией ArraySetAsSeries().



 

Кроме того, для функции OnCalculate() сказано:

В качестве массива price[] может быть передана одна из ценовых таймсерий либо рассчитанный буфер какого-либо индикатора. Чтобы определить направление индексации в массиве price[], необходимо вызывать функцию ArrayGetAsSeries(). Чтобы не зависеть от умолчаний, необходимо безусловно вызывать функцию ArraySetAsSeries() для тех массивов, с которыми предполагается работать.


 
Rosh :

Вообще говоря, нельзя закладываться на какое-то умолчательное поведение, и об этом написано в функции ArrayGetAsSeries():

.......

Ваша правда. Всё в справке есть. Всё - в смысле всё минимально необходимое. Да и задачи у справки справочные.

В общем, ждем учебник, с детальным "разжевыванием".

Участникам ветки - спасибо.

 

Поставил такой "тормоз" в индюк, чтобы считал только на новом баре, а не на каждом тике. Только в первый раз почему то не правильно отсчитывается время, дальше все нормально. Почему?

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//-------------------------------------------------------------------
#property indicator_label1  "Hi"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//-------------------------------------------------------------------
input int      History=100;
//-------------------------------------------------------------------
double         HiBuffer[];
datetime       TimeOpenBar=0;
//-------------------------------------------------------------------
int OnInit()
{
  TimeOpenBar=TimeCurrent();
  Print(TimeOpenBar);
//--- indicator buffers mapping
  ArraySetAsSeries(HiBuffer,true);
  SetIndexBuffer(0,HiBuffer,INDICATOR_DATA);
  PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1);
  PlotIndexSetString(0,PLOT_LABEL,"HiBuffer");
//---
  return(0);
}
//-------------------------------------------------------------------
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 i=0;
  int t=PeriodSeconds();
  int u=(int)TimeCurrent()-(int)TimeOpenBar;

  if ((int)TimeCurrent()-(int)TimeOpenBar>=t)
  {
    if (ArrayGetAsSeries(time)!=true)
      ArraySetAsSeries(time,true);
    if (ArrayGetAsSeries(open)!=true)
      ArraySetAsSeries(open,true);
    if (ArrayGetAsSeries(high)!=true)
      ArraySetAsSeries(high,true);
    if (ArrayGetAsSeries(low)!=true)
      ArraySetAsSeries(low,true);
    if (ArrayGetAsSeries(close)!=true)
      ArraySetAsSeries(close,true);
    while (i<History)
    {
      HiBuffer[i]=high[i];
      i++;
    }
    TimeOpenBar=time[0];
    Print("Просчитали индикатор",TimeCurrent());
  } else
  {
    Print("Время:",TimeCurrent(),"  Осталось ждать  ",t-u);
  }

  return(rates_total);
}
//-------------------------------------------------------------------

потом считается правильно:


 

Итоговый вариант индикатора. Доступ к ценовой информации как в привычном MQL4. Считает только заданное количество баров. Расчет выполняется только один раз на каждом баре, а не на каждом тике (если не было связи с сервером индикатор рассчитается только с последнего появившегося после конекта бара).
Отслеживать начало бара по тикам мне представляется ненадежным решением.

По моему,  более экономичного варианта придумать невозможно.

Или возможно

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//------------------------------------------------------------------------
#property indicator_label1  "Hi"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//------------------------------------------------------------------------
input int      History=100;
//------------------------------------------------------------------------
double         HiBuffer[];//буфер индикатора
datetime       TimeOpenBar=0;
bool           Flag=true;
//------------------------------------------------------------------------
int OnInit()
{
  TimeOpenBar=TimeCurrent();
//--- indicator buffers mapping
  ArraySetAsSeries(HiBuffer,true);
  SetIndexBuffer(0,HiBuffer,INDICATOR_DATA);
  PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1);
  PlotIndexSetString(0,PLOT_LABEL,"HiBuffer");
//---
  return(0);
}
//------------------------------------------------------------------------
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 i=0;
  //-------------------
  if (TimeCurrent()-TimeOpenBar>=PeriodSeconds())
  {
    Flag=true;
    TimeOpenBar=time[0];
  } 
  //Элзе и всё что внутри необязательно
  else
  { 
    Print("Время:",TimeCurrent());
  }
  //-------------------
  if (Flag==true)
  {
    if (ArrayGetAsSeries(time)!=true)
      ArraySetAsSeries(time,true);
    if (ArrayGetAsSeries(open)!=true)
      ArraySetAsSeries(open,true);
    if (ArrayGetAsSeries(high)!=true)
      ArraySetAsSeries(high,true);
    if (ArrayGetAsSeries(low)!=true)
      ArraySetAsSeries(low,true);
    if (ArrayGetAsSeries(close)!=true)
      ArraySetAsSeries(close,true);
    //-------------------Основной цикл индикатора-------------------------
    while (i<History)
    {
      HiBuffer[i]=high[i];
      i++;
    }
    //---------------Конец основного цикла индикатора---------------------
    TimeOpenBar=time[0];
    Flag=false;
    Print("Просчитали индикатор",TimeCurrent());//необязательно
  }
  return(rates_total);
}
//------------------------------------------------------------------------


PS Ухты! Движок форума оказывается сам ссылки на документацию ставит!