Функция getParamEx возвращает нули по параметрам максимальная, минимальная цена для акций

Страницы: 1
RSS
Функция getParamEx возвращает нули по параметрам максимальная, минимальная цена для акций, проблемы с переходом на новую версию qlua
 
Установил quik 8.8.4.3 и запускаю скрипт, который ранее работал на 7й версии.

Функция getParamEx
 
Функция getParamEx стала возвращать нули по параметрам PRICEMIN и PRICEMAX для класса акций "TQBR"
Для облигаций "TQCB" работает нормально.

Как можно иначе получить максимальную цену дня по ценной бумаге?
 
Alexey,
Откройте в терминале QUIK Таблицу Текущих Торгов и добавьте туда параметры Мин и макс возможной цены по классу TQBR
Убедитесь что они там действительно есть и в них действительно есть числа, после чего повторите попытку запуска скрипта.
 
Цитата
Sergey Gorokhov написал:
Alexey,
Откройте в терминале QUIK Таблицу Текущих Торгов и добавьте туда параметры Мин и макс возможной цены по классу TQBR
Убедитесь что они там действительно есть и в них действительно есть числа, после чего повторите попытку запуска скрипта.
Спасибо за подсказку!
Разобрался.
Нужно добавить эти параметры в меню терминала "Система -> Заказ данных -> Поток котировок -> Фильтр параметров"
 
Продолжим тему. Получается, что в Lua-скрипте для получения верхней границы цены надо писать примерно так:
Код
local paramName = "priceMax"
if classCode == "TQBR" or classCode == "RTSIDX" then
    paramName = "Max" -- тут точно такое название параметра???
end
local param = getParamEx(classCode, secCode, paramName)

Какие ещё коды классов помимо TQBR и RTSIDX надо указать, чтобы это всё работало корректно?
 
И как понять название параметра на английском, если в справке они перечислены в разделе про QPile, а он уже не обновляется? Как называются параметры "Мин." и "Макс." внутри Qlua?

Не пора ли перенести эти описания в справку QLua и актуализировать?
 
Цитата
_sk_ написал:
Не пора ли перенести эти описания в справку QLua и актуализировать?
Щас арка очень обидится, но логика в таком расположении справки есть и она проста: функция getParamEx в qlua - всего лишь обертка над аналогичной функцией из qpile. Соответственно и на вопрос про названия параметров в qlua ответ очевиден, никак они не называются, qlua о них вообще ничего не знает, кроме того, что параметров три и это строки.
 
Вопрос, как узнать английское название для параметров Мин. и Макс. остаётся открытым.
 
Во прямо сейчас я вижу в ТТТ для класса RTSIDX и инструмента RTSI значения Мин. 1151,45 и Макс. 1165,58, но внутри QLua эти значения пока не смог получить.

А в потоке котировок для Акций вообще нет параметров Макс. и Мин. (есть Максимальная цена сделки и Минимальная цена сделки, но это же не то, кажется), при том, что сервер квик на аутсорсинге у Арки стоит и должен быть настроен как надо.
 
Похоже, что параметры "Мин." и "Макс." -- это что-то непонятное, а для акций TQBR и облигаций TQOB параметры "Мин. возм. цена" и "Макс. возм. цена" просто не транслируются.

Ещё вопрос, почему при запросе параметра last для TQBR и SBER за 10 минут до начала торгов мы видим нули:

Код
param = {param_image="0,00",param_type="1",param_value="0.000000",result="1",}

а не отсутствие результата result="0"? Это биржа нули транслирует или терминал нулём заполняет отсутствующее значение?
 
_sk_, добрый день!

Цитата
_sk_ написал:
И как понять название параметра на английском
Для определения наименований параметров на английском рекомендуется пользоваться выводом через DDE с формальными заголовками (именно это и будет наименованием параметра).
Актуализировать и собрать полную справку по доступным параметрам ТТП не представляется возможным в виду их огромного количества.

Параметры "Минимально возможная цена" и "Максимально возможная цена" - "PRICEMIN" и "PRICEMAX" соответственно.
Данные параметры могут не транслироваться для некоторых классов, это регулируется настройками брокера, так что с этим вопросом следует обратиться к нему.
Уточните пожалуйста, кто Ваш брокер?

Касательно нулей в параметре "Цена последней сделки", такое значение вполне возможно перед началом новой торговой сессии. Терминал отображает информацию, которая в него пришла.
 
Спасибо за ответ.

Хотелось бы иметь возможность без DDE обойтись. У меня нет Excel на компьютере, а LibreOffice не поддерживает эту давным давно устаревшую технологию.

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

Про настройки на стороне брокера я уточню у брокера.
 
Цитата
_sk_ написал:
Зарегистрируйте тогда пожелание о возможности выгрузки формальных заголовков в обычный текстовый файл выбором пункта меню.
А давайте другого пожелаем, чтоб нам дали функцию в луа типа STRING getClassParameters(STRING classcode). А то как-то непорядочек, количество параметров в getClassInfo есть, а самих их негде взять.

Цитата
_sk_ написал:
LibreOffice не поддерживает эту давным давно устаревшую технологию.
Можно довольно простую программку сделать для приема дде-соединения ради только имен столбцов.
 
Цитата
Anton написал:
пожелаем, чтоб нам дали функцию в луа типа STRING getClassParameters(STRING classcode).
Я другое хотел предложить: возвращать таблицу вида: {["Имя параметра"] = "Формальный заголовок", }
Но не знаю, насколько это юзабельно, поэтому не стал
 
Цитата
Старатель написал:
возвращать таблицу вида: {["Имя параметра"] = "Формальный заголовок", }
Так даже и поинтересней будет, возьмутся ли только делать. Насколько понимаю, оно все в одном из дат-файлов лежит, надо только достать и выдать юзеру, но кто знает, почему до сих пор не сделано, может там какие проблемы нерешаемые.
 
Цитата
Можно довольно простую программку сделать для приема дде-соединения ради только имен столбцов.

Я не умею, да и разбираться с устаревшими технологиями как-то не хочется.
Цитата
А давайте другого пожелаем, чтоб нам дали функцию в луа типа STRING  getClassParameters(STRING classcode). А то как-то непорядочек,  количество параметров в getClassInfo есть, а самих их негде взять.
Цитата
Я другое хотел предложить: возвращать таблицу вида: {["Имя параметра"] = "Формальный заголовок", }
Но не знаю, насколько это юзабельно, поэтому не стал

Наверное, это неплохие варианты. Надобность в таком, по-видимому, будет редкая (один раз запустил и всё). Как сделать по уму и наиболее просто, пусть разработчики подумают.
 
_sk_, здравствуйте!

Ваше пожелание зарегистрировано, мы постараемся его рассмотреть. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
 
Цитата
Roman Azarov написал:
_sk_, здравствуйте!

Ваше пожелание зарегистрировано, мы постараемся его рассмотреть. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Спасибо.
 
В общем, не стал я ждать милостей от природы, взял их и вся недолга. Тксть представляем новый скрипт, добавляющий в qlua функцию getClassParameters. Текущий вариант назовем бета-версией, тестирование было, но надо больше. О найденных глюках пишите здесь. Поддерживается квик 8.5 и новее.

Где взять.
Взять здесь. Ссылка будет живой две недели, кто не успел тот опоздал, пишите письма. После скачивания и распаковки архива рекомендуется проверить хотя бы один из хэшей файла getClassParameters.dll во избежание подмены длл злыми кулхацкерами.
Код
CRC32:   63D94B46
MD5:     11F727170E6CA11F54D78B389107B2CB
SHA-1:   DEB04CAD98C776542D37CA46A1E04595AEE69BC1
SHA-256: D568E9FB00920599774BB94ADD1F23A2B9E818DEA6FF67AE516BF4DBAEFE38AD
В луа-файлы тоже не грех заглянуть.

Как проверить.
Прежде чем кидаться кодить, проверьте, оно у вас вообще работает ли. Распакуйте весь архив куда-нибудь, главное чтобы все в одной папке лежало, и запустите скрипт getClassParametersTest.lua. Он покажет окно квика со всеми доступными параметрами всех доступных классов. Или не покажет, тогда просьба отписаться здесь.

Как использовать в своем скрипте.
1. Положить getClassParameters.dll и getClassParameters.lua рядом со своим скриптом (где бы он ни был).
2. В своем скрипте подключить длл: require('getClassParameters').
3. По мере необходимости дергать появившуюся глобальную функцию getClassParameters.

Описание функции.
Код
TABLE getClassParameters(STRING classcode)
Аргумент classcode - код класса, для которого нужно получить параметры. Возьмите его из getClassesList, разобрав полученную строку по запятым, или захардкодьте.
Функция возвращает луа-таблицу со всеми параметрами для запрошенного класса. Обратите внимание, что элементы считаются с 1, как принято в луа:
Код
result =
{
  [1] = { 'formal' = STRING, 'short' = STRING, 'long' = STRING, 'enum' = STRING },
  [2] = ...
}
Поля каждого элемента:
formal - формальное название параметра.
short - короткое название параметра.
long - длинное название параметра.
enum - для параметров, чьи возможные значения предопределены, список этих значений через вертикальную черту, для прочих пустая строка.

В случае ошибки функция не возвращает nil, а кидает луа-ошибку. Если это нежелательно, вызывайте с помощью pcall.
Как пример использования смотрите скрипт getClassParametersTest.lua из комплекта.

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

Поддержка.
Поддержка продукта, включая ответы на вопросы, может быть, а может и не быть, в зависимости от настроения левой пятки автора.
 
Проверил Ваш прототип. Думаю, что эта штука вполне может заменить рекомендуемый разработчиками подход с DDE-экспортом. Спасибо!

Отдельное уважение за скорость реакции!
 
_sk_,  спасибо на добром слове. Все ж впопыхах про особенности национальной DestroyTable забыл, надо getClassParametersTest.lua поменять:
Код
require('getClassParameters')

local run = true
local tid = nil

function OnStop()
   local t = tid
   tid = nil
   if t then
      DestroyTable(t)
   end
   run = false
end

local function newwnd()
   local tid = AllocTable()
   if not tid then error('AllocTable failed') end
   if not AddColumn(tid, 1, 'class code', true, QTABLE_STRING_TYPE, 15) then
      DestroyTable(tid)
      error('AddColumn failed')
   end
   if not AddColumn(tid, 2, 'formal name', true, QTABLE_STRING_TYPE, 25) then
      DestroyTable(tid)
      error('AddColumn failed')
   end
   if not AddColumn(tid, 3, 'short name', true, QTABLE_STRING_TYPE, 30) then
      DestroyTable(tid)
      error('AddColumn failed')
   end
   if not AddColumn(tid, 4, 'long name', true, QTABLE_STRING_TYPE, 60) then
      DestroyTable(tid)
      error('AddColumn failed')
   end
   if not AddColumn(tid, 5, 'enum values', true, QTABLE_STRING_TYPE, 240) then
      DestroyTable(tid)
      error('AddColumn failed')
   end
   if not CreateWindow(tid) then
      DestroyTable(tid)
      error('CreateWindow failed')
   end
   if not SetWindowCaption(tid, 'All available parameters') then
      DestroyTable(tid)
      error('SetWindowCaption failed')
   end
   return tid
end

local function popwnd(tid)
   local t = getClassesList()
   local clst = {}
   for s in string.gmatch(t, '([^,]+)') do
      table.insert(clst, s)
   end
   table.sort(clst)
   for k, v in ipairs(clst) do
      local prm = getClassParameters(v)
      for kk, vv in ipairs(prm) do
         local r = InsertRow(tid, -1)
         SetCell(tid, r, 1, v)
         SetCell(tid, r, 2, vv.formal)
         SetCell(tid, r, 3, vv.short)
         SetCell(tid, r, 4, vv.long)
         SetCell(tid, r, 5, vv.enum)
      end
   end
   SetSelectedRow(tid, 1)
end

function main()
   tid = newwnd()
   popwnd(tid)
   while run do
      if IsWindowClosed(tid) then
         OnStop()
         break
      end
      sleep(500)
   end
end
 
Про особенности национальной DestroyTable и, вообще, о корректной работе с окнами в QLua написал бы кто-нибудь хороший мануал с примерами и объяснениями, почему именно так надо. И на форум выложить на память и для начинающих. Или уже есть где такое в интернете?
 
Цитата
_sk_ написал:
хороший мануал с примерами и объяснениями, почему именно так надо
Весь мануал сведется к тому, что после OnStop квик синхронно ожидает завершения мейна, так что любая попытка вызвать функцию qlua, приводящую к отправке оконных сообщений, приведет к зависанию и принудительному завершению скрипта. Чтобы готового с примерами - вроде нет такого.

По-хорошему квик должен бы после OnStop отменять для скрипта колбеки, ставить таймер и возвращать управление вызвавшему коду, а уже по таймеру проверять состояние мейна и прибивать его по необходимости. Но один крайний случай есть, когда скрипт завершается в процессе закрытия квика, как только квик выйдет из WM_DESTROY, главное окно будет прибито и схема не сработает и, вполне вероятно, еще и наглючит. Поэтому, думаю, так и не делают.
 
Anton, Тоже не поможет - в момент останова скрипт может выполнять код какого-то обработчика, а не сидеть в мейне на sleep. Но, в любом случае, делать нужно именно "по-хорошему" - так наглючит уж никак не больше. А "по-плохому" скрипт должен периодически сохранять важные данные - по таймеру, по какому-нить OnTrade или даже по кнопке "Сохранить результаты".
 
Цитата
Владимир написал:
в момент останова скрипт может выполнять код какого-то обработчика
Не может, если OnStop вызван, ни один колбек ни в одном скрипте сейчас не выполняется. Но могут работать мейны. В том и суть, прогарантировать, что ни одного колбека скрипт больше не получит, выйти из обертки над OnStop и дать мейну доработать в нормальном окружении, а через возвращенное из OnStop число секунд убедиться, что мейн завершился, прибить если надо и закончить очистку скрипта.
 
Anton, Так тела колбеков и расположены в мейне! Впрочем, не проверял - я по-прежнему считаю функцию внутри цикла "колбеком" - это же фактически прерывание по таймеру. Так что, если я нажму на кнопку останова, а скрипт в это время будет обрабатывать прерывание OnTrade, то управление должно вернуться КУДА?
 
УХ ТЫ! Прямо пока писал про OnTrade, на одном из моих Квиков выскочило сообщение (у меня там сейчас стоит заглушка):
function OnTrade(trade)
message("OnTrade! "..trade.price.." "..trade.qty.." "..trade.value.." "..trade.sec_code.." "..trade.class_code);end;

Сообщение такое:
OnTrade! -141.0 1.0 -141.0 RUREQTV INSTR
Это что за пьяные выходки?  :smile:  (брокер - Сбер)
 
Цитата
Владимир написал:
Так тела колбеков и расположены в мейне!
Тела колбеков расположены в скрипте, а когда и кем они будут вызваны - это совсем другое дело, вон выше пример, если OnStop вызывает квик, он выполняется в потоке квика, а если я сам дергаю - то в потоке мейна. Тксть трюк исполнен профессионалами, не повторяйте дома.

Цитата
Владимир написал:
если я нажму на кнопку останова, а скрипт в это время будет обрабатывать прерывание OnTrade, то управление должно вернуться КУДА?
Чтобы вернуть управление, надо сначала получить управление. Вы жмете кнопку остановить, но главный поток квика занят в OnTrade, сообщения не обрабатываются. Вот выйдет скрипт из OnTrade, квик подергает сообщения из очереди, увидит нажатую кнопку и приступит к остановке скрипта.
 
Anton, Сильно сомневаюсь! OnStop ЮЗЕРА - это вовсе не OnStop Квика, равно как и другие обработчики - тем более, эмулятор прерывания по таймеру - это же самое важное прерывание в компе, высший приоритет! А тут какой-то дебил, вроде меня, начнёт там выполнять всякую хрень вроде задачи коммивояжёра - он что, Квик подвесит? Как говорил Станиславский, НЕ ВЕРЮ! Главный поток ОБЯЗАН получить управление по нажатию кнопки, причём НЕМЕДЛЕННО! Чем бы он там ни был занят в OnTrade.
 
Цитата
Владимир написал:
эмулятор прерывания по таймеру - это же самое важное прерывание в компе, высший приоритет!
Вы собрались железный таймер перехватывать? Дык он только для ядра. Поинтересуйтесь приоритетом сообщения WM_TIMER.

Цитата
Владимир написал:
он что, Квик подвесит?
Ага. Попробуйте, ежли не боитесь, только диспетчер задач сперва откройте
Код
function OnAllTrade()
  sleep(1000000)
end

Цитата
Владимир написал:
Главный поток ОБЯЗАН получить управление по нажатию кнопки, причём НЕМЕДЛЕННО!
Блажен кто верует.
 
Anton, Не, Вам я верю на слово. Одуреть! Воистину, программисты вымерли...
 
Anton, Правильно ли я понимаю, что при нажатии кнопки останова скрипта управление передастся именно в МОЙ обработчик OnStop, и если я туда воткну функцию записи результатов в файл (не занимаясь при этом "табличными" делами, требующие обращения к функциям основного потока), то ни одна собака не посмеет прервать мой обработчик, и файл результатов будет-таки гарантированно записан?
 
Цитата
Владимир написал:
то ни одна собака не посмеет прервать мой обработчик
Да, верно. Главный поток квика по нажатию кнопки стоп отдает все бразды в юзерский OnStop и пока тот не вернется, ничего дальше происходить не будет.
 
Цитата
_sk_ написал:
Спасибо за ответ.

Хотелось бы иметь возможность без DDE обойтись. У меня нет Excel на компьютере, а LibreOffice не поддерживает эту давным давно устаревшую технологию.

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

Про настройки на стороне брокера я уточню у брокера.
Добрый день!
Предложу более легкий способ получить DBName параметра из Таблицы текущие торги без использования DDE.
Заходим в настройки терминала "Система" -> "Настройки" -> "Основные настройки...", заходим в раздел "Программа" -> "Буфер обмена" и включаем настройки:
- Выводить заголовки столбцов
- Формальное представление данных
-- Формальное представление заголовков строк и столбцов

Теперь при копировании всей таблицы в буфер обмена (Ctrl+Shift+C) в буфер обмена буду копироваться DBName значения из Таблицы текущие торги, именно их нужно использовать в функции getParamEx()
Перед тем как задать вопрос, убедитесь, что решение Вашей задачи не описано в официальном мануале - 'Использование Lua в Рабочем месте QUIK.pdf' https://arqatech.com/upload/Public/quik_lua.zip
 
Спасибо. Это тоже вариант, который позволит узнать нужные заголовки.
Страницы: 1
Читают тему (гостей: 1)
Наверх