Бес Паники (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
nikolz написал:
Полагаю что тема про OnDestroy()  закрыта
Эта тема не ограничена метками. Не нужно её закрывать :) тем более что служба поддержки уверяет, что проблема решается...
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Да, и у Price нужно этот идентификатор тогда убрать, чтобы Quik точно знал, где убирать метки.
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
Сергей написал:
Поле Price - Дополнительно > вводим идентификатор "abcdef"
Почему Price? Это ветка стандартного графика, а не индикатора. Или у Вас индикатор так называется (имена/названия индикаторов/графиков лучше не дублировать, если что)?
В общем скорее всего именно в этом проблема, из-за чего не отрабатывал DelAllLabels().
Нужно выбрать именно тот индикатор, который создает метки и из которого вы хотите потом все метки удалить.
Попробуйте так:
Поле [ТутНазваниеВашегоИндикатора] -> Дополнительно -> вводим идентификатор "abcdef" (ну или другой, но точно такой же, как задан в коде индикатора)
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
Сергей написал:
Цитата
Бес Паники написал:
В методе GraphLabels:Clear() поле self.GraphId объекта GraphLabels содержит значение, переданное в Init() вызовом GraphLabels:Init(GRAPHID_TRADERTARGETS). Старые метки удаляются и создаются новые как раз по ci == 1
Спасибо, красивый вариант Но честно говоря не совсем уловил :)
GRAPHID_TRADERTARGETS - это метка из Settings ?
LabelSB, ...,  LabelBS - это что?

Это не полный скрипт. Только часть. Он выводит метками цели купли и продажи задач торгового робота. Весь скрипт состоит из различных файлов, в одном из файлов задано и значение GRAPHID_TRADERTARGETS. Просто в виде константы (констант настоящих в Lua нет, но таковой в общем то можно считать любое неизменяемое по коду значение). Т.е. в файле констант скрипта прописано
GRAPHID_TRADERTARGETS = 'AnyStringYouWantToBeGraphIdentifier'
(ну почти, значение, которое тут присваивается может быть любым).
Главное, чтобы точно такое же значение было указано в настройках (НЕ в Settings!!! Задавать в Settings - это альтернатива, опять же почти, варианту задавать константой).
Настройки имеются ввиду другие, а именно диалоговое окно редактирования графика Quik, набора индикаторов на графике, там у каждого графика есть вкладка "Дополнительно" и вот там есть поле "Идентификатор". Именно его нужно прописать.

[img]data:image/png;base64, *[/img]

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

Цитата
Сергей написал:
test_Example2.lua:190: attempt to index a nil value (global 'GraphLabels')
Туту GraphLabels - это таблица/объект. Его тоже нужно создавать/объявлять/декларировать, чтобы он стал доступен. Так удобно для громоздких скриптов упорядочивать функционал и данные и потом использовать  это в виде библиотек в различных скриптах. Это просто вариант реализации.
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
Сергей написал:
Например включение в OnCalculate(index)  строки   if index == 1 then  DelAllLabels(chart_tag)  end    не удаляет
chart_tag точно не меняется?
Вот пример как реализовано у меня и метки уверенно удаляются, долго морочился, пока не зафиксировал "chart_tag" в виде константы в коде.
Код
function Init()

    if FirstInit then
        FirstInit = false
        Logger:Init(true)
        GraphLabels:Init(GRAPHID_TRADERTARGETS)
    else 
        Log('Повторная инициализация')
    end
    
    return #(Settings.line)
    
end


function OnCalculate(ci)

    -- Настраиваемся
    if ci == 1 then

        local dsi = getDataSourceInfo()
        Board = dsi.class_code
        Ticker = dsi.sec_code

        GraphLabels:Clear()
        LabelSB = GraphLabels:Add()
        LabelSS = GraphLabels:Add()
        LabelBB = GraphLabels:Add()
        LabelBS = GraphLabels:Add()
        
        LinesHist = {}
        InitialCalcCandlesCnt = getNumCandles(GRAPHID_TRADERTARGETS)

        WhenUpdated = 0
        
    end

    -- Дальше собственно генерация данных...

end


-- Удаление всех меток
function GraphLabels:Clear()
    self.Labels = {}
    DelAllLabels(self.GraphId)
end

В методе GraphLabels:Clear() поле self.GraphId объекта GraphLabels содержит значение, переданное в Init() вызовом GraphLabels:Init(GRAPHID_TRADERTARGETS). Старые метки удаляются и создаются новые как раз по ci == 1

И на всякий случай - использую сборку Quik от брокера ВТБ, мало-ли, теоретически и в зависимости от сборок могут быть расхождения в работе терминалов.
 
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
Oleg Kuzembaev написал:
Старую метку в коде скрипта уже не найти и не удалить из кода скрипта, но это же не решение проблемы
По моему скромному опыту DelAllLabels(ID)  отрабатывает корректно и удаляет все метки (включая добавленные для предыдущего инструмента), если идентификатор графика задан в настройках графика (редактирование графика -> вкладка "дополнительно") и при вызове DelAllLabels указывается такой же идентификатор. Тогда снимаются и сложности с получением идентификатора графика, но появляется необходимость для каждого графика с таким индикатором клонировать индикатор (но не обязательно же весь клонировать, только некую индивидуальную часть и подгружать потом общую), чтобы каждый работал со своим графиком и идентификатором.
Как создать мост QLua-скрипта с другим C++ приложением? Вопрос концепта., Предлагаю такой подход, но есть вопросы.
 
Шутить изволите... ну Ок. Понадеялся, что Вам известны некие недокументированные объекты/таблицы/функции для транслировния значений глобальных переменных Lua между разными исполняемыми скриптами без дополнительных библиотек/файлов.
Как создать мост QLua-скрипта с другим C++ приложением? Вопрос концепта., Предлагаю такой подход, но есть вопросы.
 
Цитата
nikolz написал:
Для обмена между скриптами т е потоками main  в разных скриптах QUIK , использую глобальные переменные.
Подскажите пожалуйста где посмотреть подробнее про такой обмен данными в Quik между разными скриптами, запущенными по отдельности.
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
nikolz написал:
Задача смены лог файла при смене инструмента решается другим способом.
Конечно решается. И решена (вариант решения есть и в тексте предыдущего сообщения). Это просто пример/иллюстрация невозможности освободить ресурсы, когда индикатор фактически больше не работает, "ожидая" закрытия окна.
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Цитата
Oleg Kuzembaev написал:
Добрый день.

Не могли бы вы, пожалуйста, прислать на нашу почту  quiksupport@arqatech.com  часть или весь скрипт, в котором представлена описываемая процедура, а также описание и/или скриншоты с ошибкой возникающей в процессе?  

На почту присылать так себе идея, скрипт многомодульный, индикаторы увязаны с торговыми скриптами и имеют общие библиотеки/компоненты.
Там суть проблемы просто потеряется.

Подготовил простейший пример, когда требуется сохранить лог и от предыдущего исполняемого экземпляра скрипта индикатора и новому экземпляру тоже дать возможность вести лог. Для этого достаточно (казалось бы) переименовать старый лог-файл при открытии нового. НО!!! для этого, как минимум, нужно старый лог закрыть. И вот это как раз недоступно. Закрывать же каждый раз при записи очередной строки в лог (и соответственно открывать тоже) - совсем не вариант, так как логи бывают огромные и время выполнения логирования часто критично.
Код
Settings = {
   Name = 'Test',
   line = {
      {
         Name = 'Test',
         Color = RGB(255, 255, 0),
         Type = TYPE_LINE,
         Width = 1
      }
   }
}


oldLogFilePath = 'test_.log'
logFilePath = 'test.log'
logFile = nil


function Init()
   return #(Settings.line)
end


function OnDestroy()
   io.close(logFile)
end


function OnCalculate(ci)

   if logFile == nil then
      if FileExists(logFilePath) then
         
         if FileExists(oldLogFilePath) then
            os.remove(oldLogFilePath)
         end
         
         local renRes, renErr = os.rename(logFilePath, oldLogFilePath)
         if not renRes then
            message(renErr)
         end
         
      end
      logFile = io.open(logFilePath, 'w')
   end

   Log(tostring(ci))
   return ci
   
end


function Log(txt) 
   if logFile ~= nil then 
      logFile:write(txt, '\n')
   end
end


function FileExists(path)
   local f = io.open(path, "r")
   if f ~= nil then 
      io.close(f) 
      return true 
   else 
      return false 
   end
end

В данном примере, если бы OnDestroy() срабатывал, пусть даже не сразу (не проблема сделать пачку логов, выдавая имена по кругу) то все файлы в итоге были бы закрыты, а так, по факту, OnDestroy() похоже срабатывает только при закрытии приложения, возможно при закрытии окна графика (давно разбирался, уже не помню, когда срабатывает, зато ясно что при смене инструмента НЕ срабатывает). Проблема резко усугубляется, если индикатор не один, инструментов десятки, и графиков с индикаторами тоже далеко не один. И логирование - только одна из задач, когда нужно держать файл открытым пока выполняется скрипт.
При смене инструмента графика в Lua индикаторе OnDestroy() не вызывается
 
Уважаемая поддержка QUIK,
проблема, указанная в этом топике (отсутствие срабатывания OnDestroy() в индикаторах при смене инструмента) действительно не всегда решается контролем индекса свечи. Некоторые операция нужно выполнять именно по OnDestroy(). Например - закрывать файлы, которые открывает скрипт индикатора в процессе работы (так как объекты/таблицы/указатели/хэндлы доступны только в том экземпляре скрипта, который их открыл, не говоря уже о том, что закрывать из другого экземпляра - это мега-костыль само по себе). Иногда файлы перестают открываться вообще, если много раз менять инструменты. Помогает только перезапуск QUIK. Пожалуйста, реализуйте вызов OnDestroy(), чтобы можно было хотя бы очистить память и закрыть файлы, чтобы не копить в приложении выделенную память и хэнлы открытых файлов. Это не просто хотелка, это ошибка приложения QUIK.
Страницы: 1
Наверх