Как узнать, что индикатор загружен из шаблона? - страница 2

 
Artyom Kuraev:

Проблема возникает из-за того, что часть линий может быть удалена вручную пользователем (следовательно пересчитать по исходным данным и расставить нужное количество линий невозможно.

Шаблон сохраняется не программно. Пользователь сам шаблон сохраняет. Но сохраняет его вместе с теми линиями, которые существовали в момент сохранения шаблона.
Далее, когда этот шаблон применяется, эти линии отображаются все на тех же уровнях.
Логично было бы удалить эти линии в момент инициализации индикатора, но сделать это мешает следующее условие: при смене таймфрейма индикатор не должен изменять существующие на графике линии.

Для того, чтобы индикатор не изменил линии при смене таймфрейма, при первой инициализации на графике создается объект, который служит индикатором того, впервые загружается индикатор или повторно.

Так как при сохранении шаблона пользователем этот объект на графике существует, то при запуске индикатора из шаблона, индикатор ничего не пересчитывает.


Таким образом, чтобы решить задачу, нужно найти ответ на один из двух вопросов:
Либо 1. Как в момент сохранения шаблона запретить сохранять в шаблон созданный объект-метку повторной инициализации?
Либо 2. Как в момент инициализации узнать, что индикатор загружен из шаблона, чтобы запустить пересчет и удаление лишних объектов?

Не проверял, но на уровне идеи

возможно поможет

OBJPROP_CREATETIME


при загрузке проверить все объекты которые потенциально могут быть созданы и оттуда получить время загрузки шаблона. И по нему как-то соориентироваться, какие линии при пересчётах пересоздавать а какие нет

 
Artyom Kuraev:

Проблема возникает из-за того, что часть линий может быть удалена вручную пользователем (следовательно пересчитать по исходным данным и расставить нужное количество линий невозможно.

Шаблон сохраняется не программно. Пользователь сам шаблон сохраняет. Но сохраняет его вместе с теми линиями, которые существовали в момент сохранения шаблона.
Далее, когда этот шаблон применяется, эти линии отображаются все на тех же уровнях.
Логично было бы удалить эти линии в момент инициализации индикатора, но сделать это мешает следующее условие: при смене таймфрейма индикатор не должен изменять существующие на графике линии.

Для того, чтобы индикатор не изменил линии при смене таймфрейма, при первой инициализации на графике создается объект, который служит индикатором того, впервые загружается индикатор или повторно.

Так как при сохранении шаблона пользователем этот объект на графике существует, то при запуске индикатора из шаблона, индикатор ничего не пересчитывает.


Таким образом, чтобы решить задачу, нужно найти ответ на один из двух вопросов:
Либо 1. Как в момент сохранения шаблона запретить сохранять в шаблон созданный объект-метку повторной инициализации?
Либо 2. Как в момент инициализации узнать, что индикатор загружен из шаблона, чтобы запустить пересчет и удаление лишних объектов?

Артём, не обижайся, но эти объяснения так и толкают на твоё-же выражение

Artyom Kuraev:

... (видимо по его мнению я программист-Ванга)...

Я говорил о проверке причины деинициализации в OnInit()

int OnInit()
  {
//--- indicator buffers mapping
   if(UninitializeReason() != REASON_CHARTCHANGE) // или 3
    // создаём линии или ещё чего-то
//---
   return(INIT_SUCCEEDED);
  }

REASON_TEMPLATE

7

Применен другой шаблон графика


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

 
Alexey Viktorov:

Артём, не обижайся, но эти объяснения так и толкают на твоё-же выражение

Я говорил о проверке причины деинициализации в OnInit()

REASON_TEMPLATE

7

Применен другой шаблон графика


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

Аааа, то есть указанная тобой функция доступна в онините?

Я думал, ею можно только в деините пользоваться, а при инициализации забывается это значение.
В документации не прописана область видимости переменной, поэтому затупил.
Цены нет твоему совету!!!!! Спасибо!!!!!!!!!!!!!!!!!!!!!!!!!!!
Тогда и объект никакой не нужен в программе!

 
Artyom Kuraev:

Аааа, то есть указанная тобой функция доступна в онините?

Я думал, ею можно только в деините пользоваться, а при инициализации забывается это значение.
В документации не прописана область видимости переменной, поэтому затупил.
Цены нет твоему совету!!!!! Спасибо!!!!!!!!!!!!!!!!!!!!!!!!!!!
Тогда и объект никакой не нужен в программе!

НЕ переменной!!! а вызов функции...

Предопределённая переменная reason действительно доступна только в

void OnDeinit(const int reason);
 
Alexey Viktorov:

НЕ переменной!!! а вызов функции...

Предопределённая переменная reason действительно доступна только в

Алексей, функция не работает для нужных событий, только при изменении периода графика и при смене внешних настроек.

При применении шаблона UninitializeReason возвращает 0...

 
Artyom Kuraev:

Алексей, функция не работает для нужных событий, только при изменении периода графика и при смене внешних настроек.

При применении шаблона UninitializeReason возвращает 0...

Значит с применением шаблона загружается новая копия индикатора. В общем-то вполне естественно.
 
Alexey Viktorov:
Значит с применением шаблона загружается новая копия индикатора. В общем-то вполне естественно.

Еще ничего не потеряно)) В OnDeinit ведь получаем этот код деинициализации. А далее - дело техники: пишем в глобальную переменную или в файл, что индикатор отключается, т. к. применен новый шаблон. А в OnInit читаем соответствующую переменную (или файл) и узнаем предыдущую причину отключения от графика. Вот таким образом и ловится событие смены шаблона.

 
Ihor Herasko:

Еще ничего не потеряно)) В OnDeinit ведь получаем этот код деинициализации. А далее - дело техники: пишем в глобальную переменную или в файл, что индикатор отключается, т. к. применен новый шаблон. А в OnInit читаем соответствующую переменную (или файл) и узнаем предыдущую причину отключения от графика. Вот таким образом и ловится событие смены шаблона.

Если я правильно помню там ещё проблема с очень большим количеством копий индикатора. А во вторых, я просто не понимаю почему не возможно обойтись простой проверкой, линии есть или их нет. Если надо временно обойтись без линий, то пусть перезапускает индикатор после удаления линий. И в ините линии нарисуются. В общем вариантов несколько.

 
Alexey Viktorov:

Если я правильно помню там ещё проблема с очень большим количеством копий индикатора. А во вторых, я просто не понимаю почему не возможно обойтись простой проверкой, линии есть или их нет. Если надо временно обойтись без линий, то пусть перезапускает индикатор после удаления линий. И в ините линии нарисуются. В общем вариантов несколько.

Да, именно большое количество копий (до 200 графиков одновременно) может создать большую путаницу в глобальных переменных, поэтому работу с ними лучше исключить. Хотя, если бы каждый открытый график имел бы свой системный номер, то можно было  бы и с ними поработать, но я такого не припомню.

А что касается перезапуска, проблема как раз в том и состоит, чтобы узнать причину вызова oninit в самой этой функции.

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

 
Artyom Kuraev:

Да, именно большое количество копий (до 200 графиков одновременно) может создать большую путаницу в глобальных переменных, поэтому работу с ними лучше исключить. Хотя, если бы каждый открытый график имел бы свой системный номер, то можно было  бы и с ними поработать, но я такого не припомню.

А что касается перезапуска, проблема как раз в том и состоит, чтобы узнать причину вызова oninit в самой этой функции.

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

void OnDeinit(const int reason)
 {
  GlobalVariableSet((string)ChartID(), reason);
 }

Правда не знаю как сейчас в mql4, а mql5 имеет какую-то последовательность выполнения OnInit и OnDeinit и не всегда OnDeinit раньше чем OnInit.

И всё-же я не понимаю таких танцев с бубном.

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

Но если просто повторный вызов при существующих линиях, что мешает просто проверить их наличие? Не наличие контрольного выстрела, а наличие головы...