Получение данных из таблиц QUIK в QLua(Lua)

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 10, среднее: 3,80 из 5)
Загрузка...

QUIK-Qlua-poluchenie-dannyh Для получения данных из таблиц терминала QUIK удобно пользоваться 3-мя функциями: getItem(), getNumberOf() и getParamEx().

Пример:

-- Перебирает строки таблицы "Позиции по клиентским счетам (фьючерсы)", ищет Текущие чистые позиции по инструменту "RIH5"
for i = 0,getNumberOf("FUTURES_CLIENT_HOLDING") - 1 do
   -- ЕСЛИ строка по нужному инструменту И чистая позиция не равна нулю ТО
   if getItem("FUTURES_CLIENT_HOLDING",i).sec_code == "RIH5" and getItem("FUTURES_CLIENT_HOLDING",i).totalnet ~= 0 then
      -- ЕСЛИ текущая чистая позиция > 0, ТО открыта длинная позиция (BUY)
      if getItem("FUTURES_CLIENT_HOLDING",i).totalnet > 0 then 
         IsBuy = true;
         BuyVol = getItem("FUTURES_CLIENT_HOLDING",i).totalnet;	-- Количество лотов в позиции BUY				
      else   -- ИНАЧЕ открыта короткая позиция (SELL)
         IsSell = true;
         SellVol = math.abs(getItem("FUTURES_CLIENT_HOLDING",i).totalnet); -- Количество лотов в позиции SELL
      end;
   end;
end;

Далее перечислены таблицы, их идентификаторы и поля, к которым можно обращаться:

Фирмы:
Классы:
Инструменты:
Торговые счета:
Коды клиентов:
Обезличенные сделки (Таблица всех сделок):
Денежные позиции:
Заявки:
Позиции по клиентским счетам (фьючерсы):
Лимиты по фьючерсам:
Лимиты по денежным средствам:
Лимиты по бумагам:
Сделки:
Стоп-заявки:
Заявки на внебиржевые сделки:
Сделки для исполнения:
Отчеты по сделкам для исполнения:
Текущие позиции по бумагам:
Текущие позиции по клиентским счетам:
Обязательства и требования по деньгам:
Обязательства и требования по активам:
Для получения значений всех параметров биржевой информации из таблицы "Текущие торги" существует специальная функция
getParamEx (STRING class_code, STRING sec_code, STRING param_name),
которая принимает 3 параметра:
   - Код класса
   - Код инструмента
   - Имя параметра из таблицы "Текущие торги".

Функция возвращает таблицу Lua со следующими полями:
   param_type    STRING Тип данных параметра, используемый в таблице "Текущие торги". Возможные значения: 
      «1» - DOUBLE ,
      «2» - LONG, 
      «3» - CHAR, 
      «4» - перечислимый тип, 
      «5» - время, 
      «6» - дата 
 
   param_value   STRING Значение параметра. Для param_type = 3 значение параметра равно «0», в остальных случаях – числовое представление. Для перечислимых типов значение равно порядковому значению перечисления  

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

Пример использования:

Status =  tonumber(getParamEx("SPBFUT",  "RIM5", "STATUS").param_value);
-- Выводит сообщение о текущем состоянии
if Status == 1 then message("RIM5 торгуется"); else message("RIM5 не торгуется"); end;
Список возможных идентификаторов параметров, передаваемых в функцию getParamEx()

Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!

Добавить комментарий

Получение данных из таблиц QUIK в QLua(Lua): 382 комментария

  1. Здравствуйте! Существует ли ограничение на длинну строки в LUA ? Дело в том что я пытаюсь получить в строку данные о заявках из таблицы orders вот так :

    1
    2
    3
    4
    5
    6
    7
    8
    
    OrdersTable = "";
    AllRows = tonumber(getNumberOf("orders"));
    if AllRows > 0 then
    	for i=1, AllRows-1, 1 do
    	BidRow = getItem("orders", i)
    	OrdersTable = OrdersTable..tostring("-"..BidRow.trans_id)..";"..BidRow.class_code..";"..BidRow.sec_code..";"..tostring(tonumber(BidRow.flags))..";"
    	end;
    end;

    В итоге данные вроде бы попадают правильно но не полностью. Когда заявок становится более 60 они просто не попадают в строку, получается примерно так :

    ... 1105575;TQBR;SBER;26;-;1105576;TQBR;SBE <- обрезано.

    Или ошибка в цикле ?

    1. Здрасте! На сколько мне известно ограничение есть, но этого ограничения тяжело достичь тем способом, который вы используете.
      Вы не совсем правильно используете функцию tostring
      tostring("-"..BidRow.trans_id) => "-"..tostring(BidRow.trans_id) - вот так - правильно, а в вашем случае, если BidRow.trans_id = nil, то луа сгенерирует исключение попытки склеить строку с "nil"
      попробуйте так:
      local OrdersTable= {}
      for i=1, getNumberOf("orders")-1 do -- при "прямом" цикле не нужно указывать шаг прохода
      local item = getItem("orders", i)
      if item then
      OrdersTable[#OrdersTable+1] = item .trans_id
      OrdersTable[#OrdersTable+1] = item .class_code
      -- и т.д.
      -- и перенос строки добавим для каждой строки item
      OrdersTable[#OrdersTable+1] = "\n"
      end
      end
      local str = table.concat(OrdersTable, ";")

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     	-- функция контроля статуса сессии
    	SessionStatus = tonumber(getItem (futures_client_holding, SecCode).session_status)
    	getItem (futures_client_holding, SecCode).session_status
    	if SessionStatus == 0 then StateChecksum = StateChecksum +	0
    	elseif SessionStatus == 1 then StateChecksum = StateChecksum +	4 		-- Основная сессия
    	elseif SessionStatus == 2 then StateChecksum = StateChecksum +	8 		-- Промклиринг
    	elseif SessionStatus == 3 then StateChecksum = StateChecksum +	12 		-- Завершился промклиринг (началась первая вечерняя (14:05 - 18:45) сессия)
    	elseif SessionStatus == 4 or SessionStatus == 5 then
    	StateChecksum = StateChecksum +	16 										-- Основной клиринг
    	elseif SessionStatus == 6 then StateChecksum = StateChecksum +	20 		-- Завершился основной клиринг (началась дополнительная вечерняя (19:00 - 23:50) сессия)
    	elseif SessionStatus == 7 then StateChecksum = StateChecksum +	24 		-- Завершилась вечерняя сессия
    	end

    Проблема с получением параметра session_status.
    Может я зря заморачиваюсь и достаточно было бы определить статус торгов (да/нет), через функцию
    getParamEx (ClassCode, SecCode, "STATUS") , а дальше играть со временем сервера, но хочется, чтобы было все красиво и ни чего лишнего.

    1. Здравствуйте! Во первых, вообще не понятно что это такое Вы написали:

      1
      2
      
      SessionStatus = tonumber(getItem (futures_client_holding, SecCode).session_status)
      getItem (futures_client_holding, SecCode).session_status

      futures_client_holding - это название таблицы, строка, должна быть в кавычках
      в каком из примеров Вы видели, чтобы в функцию getItem вторым параметром передавался код бумаги?
      откуда Вы взяли, что в таблице futures_client_holding есть поле session_status ?
      Без обид, но освойте сначала базовые понятия программирования, прежде чем писать робота. Программирование - это не сочинение на свободную тему своими словами, а точная наука, где каждый знак, символ, имеют свое определенное значение.

      Здесь https://quikluacsharp.ru/nuzhnye-funktsii/ есть функция GetServerDateTime, которая возвращает текущие дату/время сервера, ее Вам будет достаточно, тем более, статус сессии Вам не скажет, что через 5 минут торги закончатся и роботу нужно закрыть позиции.

      1. Спасибо! Строка 2 случайно затесалась . На счет таблицы Вы правы. Здесь нужна таблица текущих торгов. И в целом Вы правы, нечего усложнять пока не разобрался, что к чему.

          1. Да, легче. Но, как я заметил очень часто время окончания клиринга переносится на 5 минут. Хотелось, чтобы робот это автоматически отлавливал. Для стратегии которую я сейчас реализую на М15, это несущественно и может быть реализовано через обработку системного времени, но в дальнейшем я планировал использовать этот блок функций для скальперской стратегии и там, я думаю, это будет существенно.

  3. А как получить данные из таблицы "Клиентский портфель" Хотел получить "полную стоимость портфеля" или "текущие средства" на фондовом рынке. Думал что это getNumberOf("ACCOUNT_POSITIONS") .currentpos. Но ничего не выходит. Вообще цель узнать общее количество средств на фондовой секции, т.е. активы + свободные средства.

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

          1. getPortfolioInfo - функция для получения значений параметров таблицы «Клиентский портфель»
            getPortfolioInfoEx - функция для получения значений параметров таблицы «Клиентский портфель» с учетом вида лимита

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

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

  5. Здравствуйте! Вот для фьючерсов есть текущая чистая позиция:futures_client_holding-totalnet, а для акций? Может- account_balance- а дальше что? Она находится в таблице "состояние счета", а как ее оттуда получить?

      1. Благодарю. Как я понимаю подобное справедливо для SearchItems и практически для всех функций, верно ?
        т.е. почти всегда стоит проверять на "nill" ?