Поиск в таблицах quik
Qlua имеет встроенную функцию getOrderByNumber(STRING class_code, NUMBER order_id). Однако кроме ордеров, но номеру часто приходится искать и стоп-зявки и сделки. Функция SearchItem позволяет исполнять быстрый поиск по любым quik-таблицам, но мне удобнее сделать на ее основе отдельные функции поиска, аналогичные getOrderByNumber()
Пара примеров.
-- Получение таблицы стоп-ордера по его номеру
-- Возвращает таблицу стоп-зявки или nil
function getStopOrderByNumber(stop_order_number,from,to)
local index_table = SearchItems("stop_orders",
from or 0,
to or getNumberOf("stop_orders")-1,
function(t)
return t.order_num == stop_order_number
end)
if index_table then
return getItem("stop_orders",index_table[1])
end
end
-- Получение таблицы стоп-ордера по номеру порожденной им заявки
-- Возвращает таблицу стоп-заявки или nil
function getStopOrderByOrderNumber(order_number,from,to)
local index_table = SearchItems("stop_orders",
from or 0,
to or getNumberOf("stop_orders")-1,
function(t)
return t.linkedorder == order_number
end)
if index_table then
return getItem("stop_orders",index_table[1])
end
end
Функции поиска getItem() и SearchItems() могут работать только с определенным перечнем таблиц, о чем последний раз указано в Руководстве QLUA 8.0 и что проверено мной при написании скрипта. Следует ли из этого, что нужно пользоваться библиотечными функциями LUA для обработки нужных и не оговоренных в Руководстве таблиц? То же - и о созданных нестандартных таблицах QUIK?
Все как в руководстве quik: функции работают только с таблицами из указанного вами перечня и не работают во всех остальных случаях.
Поэтому для поиска, скажем по пользовательско го таблице, созданной из луа, нужно писать собственные функции.
Вторая часть вопроса: "Следует ли из этого, что нужно пользоваться библиот ечными функциями LUA (не QLUA) для обработки нужных и не оговоренных в Руководстве таблиц? То же - и о созданных пользователем нестандартных таблицах QUIK?Прочел Ваш ответ 2 раза. Понял, что пишем сами, ручками.
Медленно, не торопясь, с перерывами на пиво. Главное - не устать )
Вопрос: догадываюсь, что, в принципе, можно организовать поиск в таблице "orders" по полю flags?
Поскольку операции с битовыми переменными для меня пока еще не очень привычны, прошу по-дружески подсказать, как корректно прописать функцию-фильтр
function(t) return t.flags == ... end
в функции поиска SearchItems(). Вот как раз это многоточие и есть суть вопроса.
(хочу выбрать из таблицы заявок те, которые "зависли", т.е. не являются "ИСПОЛНЕННЫМИ" и не "СНЯТЫ")
Спасибо заранее за помощь!
Смотрим документацию по назначению полей
бит 0 (0x1) Заявка активна, иначе – не активна
бит 1 (0x2) Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена
бит 2 (0x4) Заявка на продажу, иначе – на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL)
бит 3 (0x8) Заявка лимитированная, иначе – рыночная
бит 4 (0x10) Разрешить / запретить сделки по разным ценам
бит 5 (0x20) Исполнить заявку немедленно или снять (FILL OR KILL)
бит 6 (0x40) Заявка маркет-мейкера. Для адресных заявок – заявка отправлена контрагенту
бит 7 (0x80) Для адресных заявок – заявка получена от контрагента
бит 8 (0x100) Снять остаток
бит 9 (0x200) Айсберг-заявка
То есть у активной заявки бит с номером 0 должен быть равен 1
смотрим функцию bit.test
Функция проверяет состояние указанного бита в значении. Возвращает true, если бит равен «1», и false, если бит равен «0».
BOOLEAN bit.test(NUMBER х, NUMBER n)
где:
х – значение;
n – номер бита. Нумерация битов начинается с «0».
Пишем функцию сравнения для SearchItems:
compare = function(flg)
return bit.test(flg,0)
end
Вызов:
SearchItems("orders", 0, getNumberOf("or ders")-1, compare, "flags")
Как-то так....
За вечер-утро я родил вот такой вариант:
function CheckBit(flags, _bit) -- Определение числа в битовое значение
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" then error("Ошибка!! ! Checkbit: 1-й аргумент не число!") end
if type(_bit) ~= "number" then error("Ошибка!! ! Checkbit: 2-й аргумент не число!") end
if _bit == 0 then _bit = 0x1
elseif _bit == 1 then _bit = 0x2
elseif _bit == 2 then _bit = 0x4
elseif _bit == 3 then _bit = 0x8
elseif _bit == 4 then _bit = 0x10
elseif _bit == 5 then _bit = 0x20
elseif _bit == 6 then _bit = 0x40
elseif _bit == 7 then _bit = 0x80
elseif _bit == 8 then _bit = 0x100
elseif _bit == 9 then _bit = 0x200
elseif _bit == 10 then _bit = 0x400
elseif _bit == 11 then _bit = 0x800
elseif _bit == 12 then _bit = 0x1000
elseif _bit == 13 then _bit = 0x2000
elseif _bit == 14 then _bit = 0x4000
elseif _bit == 15 then _bit = 0x8000
elseif _bit == 16 then _bit = 0x10000
elseif _bit == 17 then _bit = 0x20000
elseif _bit == 18 then _bit = 0x40000
elseif _bit == 19 then _bit = 0x80000
elseif _bit == 20 then _bit = 0x100000
end
if bit.band(flags, _bit ) == _bit then return true
else return false
end
end
function getOrderByFlags ()
local index_table = SearchItems("or ders",
from or 0,
to or getNumberOf("or ders")-1,
function(t)
return not (not CheckBit(orders .flags, 0) and not CheckBit(orders .flags, 1)) or (CheckBit(orders .flags, 1))
end)
if index_table then
return getItem("orders ", index_table)
end
end
Длинно как-то...
Не корысти ради, а истины для прошу оценить. Важно мне для самооценки.
Спасибо!
Ну здорово, наверное.. Много всего, богато..
я так понимаю, что для универсализации функции
compare = function(flg) нужно её дополнить номером бита и сделать так:
compare = function(flg, n_bit)
return bit.test(flg,n_bit)
end
А вызов:
SearchItems("orders", 0, getNumberOf("or ders")-1, compare, "flags")
организовать в построчном цикле.
Правильно?
Ведь Ваш пример касается только бита "0"?
Впрямую так нельзя.
Просто мне кажется неудобным под каждое значение бита для каждого parameters в SearchItems писать свою compare(). Завтра потестирую Ваш вариант и мой.
compare = function(flg, n_bit)
return bit.test(flg, n_bit)
end
function getOrderByFlags ()
local res_table = {}
local index_table = SearchItems("or ders",
from or 0,
to or getNumberOf("or ders")-1,
function(t)
return not ((not compare(t.flags , 0) and not compare(t.flags , 1)) or (compare(t.flags , 1)))
end)
if index_table then
for i = 1, #index_table do
res_table = getItem("orders ", index_table)
end
return res_table
end
end
Спасибо за помощь!
(мой вариант тоже работает, но медленнее на 4мс)
bot4sale.ru/.../...)
"Хвостик" к функции поиска (чтобы вывести не таблицу индексов, а готовую таблицу "зависших" ордеров):
function getOrderByFlags ()
local res_table = {}
local index_table = SearchItems("or ders",
from or 0,
to or getNumberOf("or ders")-1,
function(t)
return not (not CheckBit(t.flag s, 0) and not CheckBit(t.flag s, 1)) or (CheckBit(t.flag s, 1))
end)
if index_table then
for i = 1, #index_table do
res_table = getItem("orders ", index_table )
end
return res_table
end
end
(почему-то не отображается индекс "i" в индексируемых значениях выводимой таблицы)
RSS лента комментариев этой записи