Здравствуйте.
Написал индикатор, добавляющий на график метку с номером последней свечи.
После добавления индикатора на график, изменении его свойств в настройках графика и смене тайм-фрейма ошибок не происходит. Но при смене инструмента (график привязан к таблице "Текущие торги"), на графике появляется дополнительная мистическая метка. Функция AddLabel не возвращает номер этой метки, ее нельзя удалить вручную (перетаскивать по графику можно) и с помощью функции DelLabel, но при этом она удаляется функцией DelAllLabels.
Добавляем индикатор на график и меняем инструмент. На графике появится новая метка и поверх нее еще одна мистическая. Мистическую перетаскиваем в сторону, заходим в настройки индикатора, меняем параметр "Отступ от максимума" (или просто меняем тайм-фрейм) и видим, что мистическая метка остается на месте а вторая изменяется.
По умолчанию, для удаления меток при их перерисовке, индикатор использует функцию DelLabel. Но, если в поле параметра "Удаление всех меток" поставить значение "да [да/нет]", то индикатор будет использовать функцию DelAllLabels и в таком случае, при изменении настроек индикатора или смене тайм-фрейма, мистическая метка будет удаляться.
Если я правильно понял, то данная проблема уже обсуждалась и была решена (topic3532)
Написал индикатор, добавляющий на график метку с номером последней свечи.
После добавления индикатора на график, изменении его свойств в настройках графика и смене тайм-фрейма ошибок не происходит. Но при смене инструмента (график привязан к таблице "Текущие торги"), на графике появляется дополнительная мистическая метка. Функция AddLabel не возвращает номер этой метки, ее нельзя удалить вручную (перетаскивать по графику можно) и с помощью функции DelLabel, но при этом она удаляется функцией DelAllLabels.
Добавляем индикатор на график и меняем инструмент. На графике появится новая метка и поверх нее еще одна мистическая. Мистическую перетаскиваем в сторону, заходим в настройки индикатора, меняем параметр "Отступ от максимума" (или просто меняем тайм-фрейм) и видим, что мистическая метка остается на месте а вторая изменяется.
По умолчанию, для удаления меток при их перерисовке, индикатор использует функцию DelLabel. Но, если в поле параметра "Удаление всех меток" поставить значение "да [да/нет]", то индикатор будет использовать функцию DelAllLabels и в таком случае, при изменении настроек индикатора или смене тайм-фрейма, мистическая метка будет удаляться.
Если я правильно понял, то данная проблема уже обсуждалась и была решена (topic3532)
Код |
---|
-- [[ Индикатор добавляет на график метку с номером последней свечи ]]-- -- Заметки: -- GetLabelParams возвращает таблицу с названиями параметров в нижнем регистре, тогда как эти параметры в функции AddLabel задаются в верхнем регистре. -- GetLabelParams возвращает значения всех параметров в строковом виде, несмотря на то, что часть параметров типа number. -- getDataSourceInfo().class_code работает только после вызова OnChangeSettings() -- getNumCandles() и getParamEx() работают только после вызова OnCalculate() Settings = {} Settings.Name = "- IndexCandleFF" Settings["Отступ от максимума"] = 100 Settings["Идентификатор графика"] = "one_graph" Settings["Удаление всех меток"] = "нет [да/нет]" TableLabel = {} index_old = 0 -- Функция OnCalculate вызывается несколько раз для каждой свечи. index_old нужен для того, что бы не захламлять таблицу TableLabel. flag_error = true -- В случае ошибки параметров в настройках индикатора, предотвращает повторный вывод сообщения об ошибке и добавление меток на график. flag_first = true -- Предотвращаем повторный вызов OnChangeSettings. flag_init = false -- Флаг для корректной работы getParamEx и getNumCandles del_labels = string.match(Settings["Удаление всех меток"], "(.*) .*") interval = 0 function isChartExist (chart_name) -- Возвращает true, если график с идентификатором "Идентификатор графика" существует, иначе false if chart_name == nil or chart_name == '' then return false end local n = getNumCandles (chart_name) if n == nil or n < 1 then return false end return true end function place_label(index) PrintDbgStr("place_label") local positionY = H(index) + Settings["Отступ от максимума"] local DateTime = T(index) local Y = DateTime.year local M = DateTime.month if #tostring(M) == 1 then M = '0'..M end local D = DateTime.day if #tostring(D) == 1 then D = '0'..D end local HO = DateTime.hour if #tostring(HO) == 1 then HO = '0'..HO end local MI = DateTime.min if #tostring(MI) == 1 then MI = '0'..MI end local SE = DateTime.sec if #tostring(SE) == 1 then SE = '0'..SE end label_params = {} -- label_params.IMAGE_PATH = getScriptPath() .. "\\1.bmp" label_params.YVALUE = positionY -- Значение параметра на оси Y, к которому будет привязана метка label_params.DATE = Y..M..D -- Дата в формате «ГГГГММДД», к которой привязана метка label_params.TIME = HO..MI..SE -- Время в формате «ЧЧММСС», к которому будет привязана метка label_params.TRANSPARENCY = 0 -- Прозрачность метки в процентах. Значение должно быть в промежутке [0; 100]. Применяется только для картинки. label_params.FONT_FACE_NAME = "Arial" -- Название шрифта (например «Arial») label_params.FONT_HEIGHT = 8 -- Размер шрифта label_params.TEXT = tostring(index) -- Если подпись не требуется то оставить строку пустой "" label_params.HINT = "Index candle" -- Текст всплывающей подсказки label_params.R = 0 -- Красная компонента цвета в формате RGB. Число в интервале [0;255] label_params.G = 0 -- Зеленая компонента цвета в формате RGB. Число в интервале [0;255] label_params.B = 0 -- Синяя компонента цвета в формате RGB. Число в интервале [0;255] label_params.TRANSPARENT_BACKGROUND = 1 table.insert(TableLabel, AddLabel(Settings["Идентификатор графика"], label_params)) -- Добавляем метку и запоминаем ее ID end function Init () PrintDbgStr("Init") flag_init = false return 1 end function OnDestroy () PrintDbgStr("OnDestroy") if del_labels == "да" then DelAllLabels(Settings["Идентификатор графика"]) else -- for label_id = 1, #TableLabel do -- DelLabel(Settings["Идентификатор графика"], TableLabel[label_id]) -- end for label_id = 1, 100000 do -- 100000 - максимально возможное количество меток на графике. local L = GetLabelParams(Settings["Идентификатор графика"], label_id) -- table or nil if L ~= nil then if L.hint == "Index candle" then DelLabel(Settings["Идентификатор графика"], label_id) end end end end index_old = 0 end function OnChangeSettings() -- Функция вызывается при редактировании свойств индикатора после нажатия кнопок «Применить» или «OK». PrintDbgStr("OnChangeSettings") if flag_init then -- При переходе на другой тайм-фрейм, сначала вызывается функция Init, затем OnChangeSettings затем OnCalculate, но для работы функций getParamEx и getNumCandles необходимо, что бы сначала была вызвана OnCalculate, поэтому, сначала игнорируем автоматический вызов OnChangeSettings, а затем после того как вызовется OnCalculate, вызываем ее сами. PrintDbgStr("OnChangeSettings_Body") del_labels = string.match(Settings["Удаление всех меток"], "(.*) .*") --[ Исключение ошибок в настройках графика ]-- if not isChartExist(Settings["Идентификатор графика"]) then if flag_error then message("Ошибка значения в поле: \"Идентификатор графика\"") flag_error = false end elseif del_labels ~= "да" and del_labels ~= "нет" then if flag_error then message("Ошибка значения в поле: \"Удаление всех меток\"") flag_error = false end else flag_error = true end --[ Удаление меток с графика ]-- if flag_error then OnDestroy() end --[ Задаем отступ для метки ]-- local sec_code = getDataSourceInfo().sec_code local class_code = getDataSourceInfo().class_code local step = getParamEx(class_code, sec_code, "SEC_PRICE_STEP").param_image -- Минимальный шаг цены local scale = tonumber(getParamEx(class_code, sec_code, "SEC_SCALE").param_image) -- Точность цены. if scale == nil then error("local ER: Для корректной работы индикатора необходимо установить соединение с сервером !") else if scale > 0 then step = tonumber("0."..step:match(",(.*)")) -- Заменяем запятую на точку и преобразуем строковый формат в числовой. end Settings["Отступ от максимума"] = step * Settings["Отступ от максимума"] end flag_first = false -- Предотвращаем повторный вызов OnChangeSettings. interval = getDataSourceInfo().interval end end function OnCalculate (index) -- Если изменился тайм-фрейм. При изменении тайм-фрейма необходимо удалить старые метки. if interval ~= getDataSourceInfo().interval then flag_init = true PrintDbgStr("interval") OnDestroy() interval = getDataSourceInfo().interval end if index > index_old then if flag_first then PrintDbgStr("flag_first") OnChangeSettings() end --[ Добавление меток на график ]-- if flag_error then if index == Size() then place_label(index) end end index_old = index end return end |