Пожалуйста помогите добиться проверки данных построянно

 

Добрый день, подскажите пожалуйста как сделать обновление хай, лоу или атр

Имеется код, в нем при нажатии на кнопку зоны строются, но вот беда они строются по текущему ДАННЫМ В ДАННЫЙ МОМЕНТ ВРЕМЕНИ (ХАЙ ЛОУ и АТР)
Если же Хай, Лоу или Атр сменились зоны значения не поменяют


Пожалуйста помогите, что можно сделать
Спасибо всем кто дочитал

#property copyright "Copyright 2017"
#property link      "http://www.ya.ru"
#property version   "1.00"
#property strict
#property indicator_chart_window

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   PutButton("KNOPKA",20,50,"Kropo4ka");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  
   if(reason != REASON_CHARTCHANGE && reason != REASON_CLOSE)
     {
   ObjectsDeleteAll(0,0,OBJ_RECTANGLE);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutRect(string name,datetime t1,double p1,datetime t2,double p2,color clr)
  {
   ObjectDelete(0,name);
//--- создадим прямоугольник по заданным координатам
   ObjectCreate(0,name,OBJ_RECTANGLE,0,t1,p1,t2,p2);
//--- установим цвет прямоугольника
   ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 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[])
  {
//---

                  datetime t2=0;
                  double Hi=0,Lo=0,ATRM=0;
                  t2=iTime(NULL,PERIOD_M1,0);
                  Hi=iHigh(NULL,PERIOD_M1,0);
                  Lo=iLow(NULL,PERIOD_M1,0);
                  ATRM = (NormalizeDouble(iATR(NULL,PERIOD_M1,10,0)/_Point,0));

         if(ObjectGetInteger(0,"KNOPKA",OBJPROP_STATE,true))
           {
                  if(isNewBar(1) == true)
                  {                     
                     DrawTXT("мин","текст 1",t2,Lo+(ATRM*_Point),Black);
                     DrawTXT("мин2","текст 2",t2,Hi-(ATRM*_Point)/100*90,Black);
                     PutRect("ТНмин",t2+60,Lo+ATRM*_Point,t2,Lo+(ATRM*_Point)/100*90,Black);
                     PutRect("ТНмин2",t2+60,Hi-ATRM*_Point,t2,Hi-(ATRM*_Point)/100*90,Black);  
                  }
           }
         else
           {
                  if(isNewBar(1) == false)
                  {
                     ObjectDelete("ТНмин");
                     ObjectDelete("ТНмин2");
                     ObjectDelete("мин");
                     ObjectDelete("мин2");
                  }
           }
         //+Comment(ATRM*_Point);

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK)
     {     
     
     
      if(ObjectFind(0,"KNOPKA")==0)
         if(GetState("KNOPKA"))
           {
               datetime t2=0;
               double Hi=0,Lo=0,ATRM=0;
               t2=iTime(NULL,PERIOD_M1,0);
               Hi=iHigh(NULL,PERIOD_M1,0);
               Lo=iLow(NULL,PERIOD_M1,0);
               ATRM = (NormalizeDouble(iATR(NULL,PERIOD_M1,10,0)/_Point,0));
                  
               DrawTXT("мин","текст 1",t2,Lo+(ATRM*_Point),Black);
               DrawTXT("мин2","текст 2",t2,Hi-(ATRM*_Point)/100*90,Black);
               PutRect("ТНмин",t2+60,Lo+ATRM*_Point,t2,Lo+(ATRM*_Point)/100*90,Black);
               PutRect("ТНмин2",t2+60,Hi-ATRM*_Point,t2,Hi-(ATRM*_Point)/100*90,Black);  
           }
           else
           {
               ObjectDelete("мин");
               ObjectDelete("мин2");
               ObjectDelete("ТНмин");
               ObjectDelete("ТНмин2");
           }

     }       
  }
  
  
void PutButton(string name,int x,int y,string text)
  {
   ObjectCreate(0,name,OBJ_BUTTON,0,0,0);
//--- установим координаты кнопки
   ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
//--- установим размер кнопки
   ObjectSetInteger(0,name,OBJPROP_XSIZE,20);
   ObjectSetInteger(0,name,OBJPROP_YSIZE,30);
//--- установим угол графика, относительно которого будут определяться координаты точки
   ObjectSetInteger(0,name,OBJPROP_CORNER,2);
//--- установим текст
   ObjectSetString(0,name,OBJPROP_TEXT,text);
//--- установим шрифт текста
   ObjectSetString(0,name,OBJPROP_FONT,"Arial");
//--- установим размер шрифта
   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,9);
//--- установим цвет текста
   ObjectSetInteger(0,name,OBJPROP_COLOR,Red);
//--- установим цвет фона
   ObjectSetInteger(0,name,OBJPROP_BGCOLOR,White);
//--- установим цвет границы
   ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,Blue);
//--- скроем (true) или отобразим (false) имя графического объекта в списке объектов
   ObjectSetInteger(0,name,OBJPROP_HIDDEN,false);
  }  

//+------------------------------------------------------------------+
//| Возвращает true, если появился новый бар для пары символ/период  |
//+------------------------------------------------------------------+
bool isNewBar(int tf)
  {
//--- в статической переменной будем помнить время открытия последнего бара
   static datetime last_time=0;
   
//--- текущее время
   datetime lastbar_time=SeriesInfoInteger(_Symbol,tf,SERIES_LASTBAR_DATE);

//--- если это первый вызов функции
   if(last_time==0)
     {
      //--- установим время и выйдем 
      last_time=lastbar_time;
      return(false);
     }

//--- если время отличается
   if(last_time!=lastbar_time)
     {
      //--- запомним время и вернем true
      last_time=lastbar_time;
      return(true);
     }
//--- дошли до этого места - значит бар не новый, вернем false
   return(false);
  }


//+---------------------Кнопки показа окн----------------------------+
bool GetState(string aName)
  {
   long value=0;
   ObjectGetInteger(0,aName,OBJPROP_STATE,0,value);
   return  (bool)value;
  }
  
void DrawTXT(string name,string text,datetime time,double price,color clr,ENUM_ANCHOR_POINT ANCHOR_=ANCHOR_LEFT_LOWER,int size=8)
  {
      ObjectDelete(0,name);
      ObjectCreate(0,name,OBJ_TEXT,0,time,price);
      ObjectSetString(0,name,OBJPROP_TEXT,text);
      ObjectSetInteger(0,name,OBJPROP_BACK,true);
      ObjectSetString(0,name,OBJPROP_FONT,"Comic Sans MS");
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,size);
      ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_);
      ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(0,name,OBJPROP_SELECTED,false);
      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);
  }
 
vebster005:

Добрый день, подскажите пожалуйста как сделать обновление хай, лоу или атр

Имеется код, в нем при нажатии на кнопку зоны строются, но вот беда они строются по текущему ДАННЫМ В ДАННЫЙ МОМЕНТ ВРЕМЕНИ (ХАЙ ЛОУ и АТР)
Если же Хай, Лоу или Атр сменились зоны значения не поменяют


Пожалуйста помогите, что можно сделать
Спасибо всем кто дочитал

В коде имеется проверка на новый бар (isNewBar). Она не позволяет менять данные чаще, чем 1 раз на один бар. Уберите ее и данные будут обновляться с каждым тиком.

P. S. В функции DrawTXT лучше использовать изменение свойств объекта, если он уже существует, а не удаление объекта и его новое создание. Иначе получите мерцание графического объекта. Особенно хорошо это видно в визуализаторе.
Основы тестирования в MetaTrader 5
Основы тестирования в MetaTrader 5
  • www.mql5.com
Идея автоматической торговли привлекательна тем, что торговый робот может без устали работать 24 часа в сутки и семь дней в неделю. Робот не знает усталости, сомнений и страха,  ему не ведомы психологические проблемы. Достаточно четко формализовать торговые правила и реализовать их в виде алгоритмов, и робот готов неустанно трудиться. Но прежде...
 
vebster005:

Добрый день, подскажите пожалуйста как сделать обновление хай, лоу или атр

Имеется код, в нем при нажатии на кнопку зоны строются, но вот беда они строются по текущему ДАННЫМ В ДАННЫЙ МОМЕНТ ВРЕМЕНИ (ХАЙ ЛОУ и АТР)
Если же Хай, Лоу или Атр сменились зоны значения не поменяют


Пожалуйста помогите, что можно сделать
Спасибо всем кто дочитал

из OnCalculate возвращайте или 0 или rates_total-1 (что нить разумное меньшее чем rates_total), тогда OnCalculate будет вызываться каждый тик, а не только при открытии баров

 
Ihor Herasko:


P. S. В функции DrawTXT лучше использовать изменение свойств объекта, если он уже существует, а не удаление объекта и его новое создание.

Я уже говорил ему об этом в другой теме. Он ничего не слышит и понимать не хочет. Не дождавшись ответа типа «делай с нами, делай как мы…» решил создать отдельную тему. А тут опять такие-же ответы…………

 
Maxim Kuznetsov:

из OnCalculate возвращайте или 0 или rates_total-1 (что нить разумное меньшее чем rates_total), тогда OnCalculate будет вызываться каждый тик, а не только при открытии баров

не понятно что это даст?

то, что Вы вернули после расчетов в  rates_total, это значение Вы получаете в prev_calculated на следующем тике

 
Igor Makanu:

не понятно что это даст?

то, что Вы вернули после расчетов в  rates_total, это значение Вы получаете в prev_calculated на следующем тике

если возвращать ровно rates_total - то OnCalculate будет вызван только на баре (на открытии), а не на тике.

логика у терминала  примерно такая - каждый тик, если число баров не равно тому что вернул OnCalculate, то надо его вызвать. То есть OnCalculate должен(был, по замыслу) возвращать сколько баров рассчитаны навсегда.

 
Maxim Kuznetsov:

если возвращать ровно rates_total - то OnCalculate будет вызван только на баре (на открытии), а не на тике.

Вы ошибаетесь, каждый тик запускается  OnCalculate(), не зависит от того, что Вы считали, что заполняли в индикаторные буфера  и что возвращали на предыдущем тике при выходе через return

Maxim Kuznetsov:

логика у терминала  примерно такая - каждый тик, если число баров не равно тому что вернул OnCalculate, то надо его вызвать. То есть OnCalculate должен(был, по замыслу) возвращать сколько баров рассчитаны навсегда.

там нет логики, все проще:

- пришел тик вызов OnCalculate()

- переключили ТФ - запуск OnCalculate()

- вызвали из ЕА индикатор - запуск OnCalculate()


терминал ничего не контролирует, только инициирует запуск  OnCalculate()

программист сам контролирует и расчитывает необходимое количество баров, примерно так нужно делать чтобы каждый тик пересчитывать бар №1 и бар №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,limit;
//--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
   if(prev_calculated==0)limit=rates_total-1; else limit=rates_total-prev_calculated+1;
//--- Основной цикл расчета
//Print("limit = ",limit);
   for(i=limit; i>=0; i--)
   {

    }
//---
  return(rates_total);

  }
 
Ребят спасибо всем кто откликнулся, но вот вопрос в чем функция isNewBar как раз нужна для того чтобы зоны перестраивались на новый бар, а старые удалялись
в другом случае зоны остаются на месте как только кончается бар. а чтобы они построились на новом баре необходимо нажать кнопку 2 раза. Пожалуйста поясните вот этот момент.
Спасибо
 
Ребят, перечитал все комментарии, вроде как работает, спасибо большое вы очень помогли, не мог разобраться почему так работает около 2 недель, СПАСИБО!!!!! могли бы написать более точнее или может кинуть ссылку о возвращении в онкалькулятор
 
vebster005:
Ребят спасибо всем кто откликнулся, но вот вопрос в чем функция isNewBar как раз нужна для того чтобы зоны перестраивались на новый бар, а старые удалялись
в другом случае зоны остаются на месте как только кончается бар. а чтобы они построились на новом баре необходимо нажать кнопку 2 раза. Пожалуйста поясните вот этот момент.
Спасибо

Как вот вам ответить чтобы не обидеть? Вот ведь объяснял всё

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Помогите пожалуйста с 1 проблемой

Alexey Viktorov, 2020.08.24 08:01

Два вопроса:

Вот это как читается?

if(!ObjectGetInteger(0,"KNOPKA",OBJPROP_STATE,false))

По моему «если не false» равно «если true» зачем было писать именно так?

Зачем объекты удалять и создавать новые? Разве не проще поменять им координаты?

И после проверки состояния кнопки, «если нажата» то в конце этого блока её обязательно вернуть в исходное положение

ObjectSetInteger(0, "KNOPKA", OBJPROP_STATE, false)

Руками кнопку нажимаешь, программно её отжимаешь. Что в этом непонятного¿¿¿
Причина обращения: