Как вывести значение цены в пользовательском TOOLTIP - страница 2

 
Eugeni Neumoin:

Говорите вариант опробован - покажите на картинке результат

Вот:

string g_strTrendLineName = "TEST_TREND_LINE";

int OnInit() 
{ 
   ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
   ShowTrendLine(g_strTrendLineName, Time[20], Low[20], Time[1], Low[1], "", clrBlue, 2, STYLE_SOLID);
   return INIT_SUCCEEDED; 
} 

void OnDeinit(const int reason)
{
   ObjectDelete(0, g_strTrendLineName);   
}



void OnTick() 
{ 
} 

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
   if (id != CHARTEVENT_MOUSE_MOVE)
      return;
      
   double fPrice = 0.0;
   datetime dtTime = 0;
   int nSubWindow = -1;
   if (!ChartXYToTimePrice(0, int(lparam), int(dparam), nSubWindow, dtTime, fPrice))
      return;
      
   ObjectSetString(0, g_strTrendLineName, OBJPROP_TOOLTIP, "Текущая цена: " + DoubleToString(fPrice, Digits()));
   ChartRedraw();
}

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Displaying the trend line                                                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowTrendLine(string name, datetime time1, double price1, datetime time2, double price2, string toolTip, color clr, int width, ENUM_LINE_STYLE style)
{
   if (ObjectFind(0, name) < 0)
   {
      ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_BACK, false);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
      ObjectSetInteger(0, name, OBJPROP_STYLE, style);
      ObjectSetInteger(0, name, OBJPROP_RAY, false);
      ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
      ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
      ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
      return;
   }
   
   ObjectMove(0, name, 0, time1, price1);
   ObjectMove(0, name, 1, time2, price2);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
   ObjectSetString(0, name, OBJPROP_TOOLTIP, toolTip);
}

Урезано с варианта со множеством объектов. Все работает корректно.

 
Eugeni Neumoin:

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


Не нужно перерисовывать все. Только тот отрезок, над которым мышь находится.

Кстати, еще один вариант. Он универсальный и простой до безобразия: не заполняйте подсказку. Терминал ее сам заполнит и сам выведет нужную цену.

 
Ihor Herasko:


Кстати, еще один вариант. Он универсальный и простой до безобразия: не заполняйте подсказку. Терминал ее сам заполнит и сам выведет нужную цену.

В этом варианте не выводится необходимая информация. Также подсказка будет выведена не с той информацией, которая необходима для каждой конкретной линии.
 
Eugeni Neumoin:
В этом варианте не выводится необходимая информация. Также подсказка будет выведена не с той информацией, которая необходима для каждой конкретной линии.

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

 
Ihor Herasko:

Не нужно перерисовывать все. Только тот отрезок, над которым мышь находится.


Вы не представляете, во что это выливается.

Проще сделать нейросеть... или лучше займусь созданием автомата по выводу волн Эллиотта... тем более, что вся информация собрана. Осталось все перенести в код.

 
Ihor Herasko:

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

Вот картинки с тултипами:


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

В одном из постов выше они были представлены.

 
Eugeni Neumoin:

Вы не представляете, во что это выливается.

Ну почему же не представляю? Я же говорю - задача решена для множества (более тысячи) объектов различной конфигурации, не только для линий, но и для дуг, стрелок и т. д. Ведь все их координаты известны (если объект перемещается, то в массив вносятся изменения). Вот они и хранятся в массиве. Достаточно пройтись по массиву и сравнить текущее положение курсора с уже вычисленными координатами с поправкой на область отображения объекта. Кроме того, не нужно забывать, что далеко не все объекты из этой тысячи находятся в видимой области графика. Это значительно сужает круг поиска объекта.

Я не говорю, что решение вообще простое, но оно и не относится к категории высокой сложности. Это обычная задача среднего уровня. На выходе же получаем достаточно шустро работающую программу.

 
Eugeni Neumoin:

Вот картинки с тултипами:


Ну тогда способ с отлавливанием положения курсора мыши вполне подойдет. Тем более, что Вы оперируете всего лишь линиями, для которых достаточно знаний уравнения прямой - математика 5-го класса. Если дуги добавите, то там увеличивается область, принадлежащая объекту. В этом случае, возможно, будет происходить перекрытие областей и однозначно идентифицировать объект не получится. Но для этой задачи не страшно - измените подсказки не у одного, а у двух-трех объектов, у которых области перекрыты. А терминал уже сам разберется, для какого именно объекта выводить подсказку.

 

Спасибо. Громоздко получается. Было бы интересней, если б в терминале была возможность без перерисовки линий обновлять тултипы.

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

А при перемещении мыши просто обновлять тултип

 ObjectSetString(0,nameLine,OBJPROP_TOOLTIP,переменная с измененным значением тултипа)

И не надо перерисовывать сами объекты.

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

 
Eugeni Neumoin:

Спасибо. Громоздко получается. Было бы интересней, если б в терминале была возможность без перерисовки линий обновлять тултипы.

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

Да, массив структур, каждая из которых описывает один объект (не только подсказка, но и все необходимые сведения об объекте - координаты, область действия и сама подсказка). Об этом я и говорил выше.

А при перемещении мыши просто обновлять тултип

И не надо перерисовывать сами объекты.

В моем примере так и есть.

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

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