Здравствуйте Андрей, промучился, прошу вас создать заново или же поменять существующий индикатор.
Создал ветку на
форуму но там тихо.
Создается кнопка, при нажатии --> создаются 2 зоны:
Они зависят от уровня АТР (среднее АТР М1 период 10 свечей) и от
1-я зона(верхняя) от уровня лоу в данный момент на текущей свече + уровень атр
тобишь выбирается лоу уровень и прибавляется атр = верхняя зона
на примере это будет выглядеть так:
ТФ 1 минута
2-я(нижняя) зона аналогично только с хай
далее, необходимо сделать так, чтобы индикатор постоянно считывал уровень хай и лоу, а так же уровень атр, и при их изменении перерисовывал эти зоны.
Как я понял они и так перерисовываются при смене данных. Но на форуме мне подсказали пользовательскую функцию, когда при смене бара выводится true(Мне она потребовалась для того что когда свеча закончится зона не переходит на новую, и данные как бы зависают на предыдущей свече)и я сделал так что когда наступает новая свеча неприходилось выкл./вкл. кнопку для показа зон.
Теперь же при наступлении нового бара, зоны перерасчитываются на новый бай и считываются новый хай(или лоу) и атр, НО! только 1 раз. А нужно чтобы пересчитывались каждый тик(вдруг изменится хай, лоу или атр, а зоны на 1 месте)
Проверяю работоспособность так:
Закидываю на график, ставлю ТФ минуту, нажимаю кнопку(показ зон) --> зоны показываются --> далее если хай и лоу меняется зоны(в данный момент) не перерисовываются(А ДОЛЖНЫ), далее жду когда время закончится и настанет новая минута --> зоны перерисовываются на новый бар, но только, как я понял, в текущий момент(одноразово, моментально)
В общем выкладываю свой код, который частично ваш:
#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)
{
ObjectsDeleteAll(0,0,OBJ_RECTANGLE);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
if(!ObjectGetInteger(0,"KNOPKA",OBJPROP_STATE,false))
{
if(isNewBar(1) == false)
{
ObjectDelete("ТНмин");
ObjectDelete("ТНмин2");
}
}
else
{
if(isNewBar(1) == true)
{
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));
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);
}
}
//+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));
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");
}
}
}
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 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);
}
Комментарии (16)
35 AM2 Сообщений: 16247 - Андрей
Создается кнопка по нажатию на неё должны показываться 2 зоны, зона хай и зона лоу
Они строются так: высчитывается средний атр минуты iatr период 10 свечей, далее находится хай свечи и отсчитывается вниз число атр и 2-я зона наоборот — высчитывается лоу прибавляется средний атр.
Например:
атр = 300п, хай 1.5000, лоу 1.0000 --> значит зона хай 1.0300, зону лоу 1.4700
Толщину зоны сделайте 10 пунктов
На картинке это будет выглядеть так:
ВАЖНО:
1) Если хай, лоу или атр поменялися — зоны должны перестроиться
2) Если наступила новая свеча зоны с прошлой свечи должны удалиться и построиться на новых
Иными словами должны каждый раз быть актуальные зоны
3) Если же выключить кнопку(переключить в положение false) тогда зоны должны скрыться(или удалиться без разницы) не должны быть показаны.
4) это должен быть индикатор
5) Кнопка button и зоны OBJ_RECTANGLE
Редактирован: 8 августа 2020, 19:39
9 lafler356 Автор Сообщений: 305
35 AM2 Сообщений: 16247 - Андрей
35 AM2 Сообщений: 16247 - Андрей
9 lafler356 Автор Сообщений: 305
кнопка отжимается вручную
35 AM2 Сообщений: 16247 - Андрей
9 lafler356 Автор Сообщений: 305
Напишите пожалуйста код вызова этого индикатора в советнике.
double up = iCustom(
double dn = iCustom(
Или добавьте буферы в индикатор для последующего вызова.
16 ssg Сообщений: 817
это уже другой заказ
35 AM2 Сообщений: 16247 - Андрей
Да, пока что примитивненько, тем более, что ширина зоны не должна быть фиксирована.
Но может статься, что-то в этом есть. Редактирован: 9 августа 2020, 09:33
24 ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.
Конечно можно перенести расчет в советник или сделать его функцией.
Но как индикатор он в использовании предпочтительнее.
Шаман, привет.
Ширину зоны можно регулировать — input int pip=10;
Другое дело нужен механизм (способ, принцип)автоматического определение ширины этой зоны.
16 ssg Сообщений: 817
Истину глаголешь.
Лично для моих нужд это был бы доп. функционал, но лучше, чтоб это изначально на чём-то основывалось, а не на глазок да навскидочку.
24 ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.
23 igrun Сообщений: 1639 - igrun
24 ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.
16 ssg Сообщений: 817
8 Genri Сообщений: 378
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий