Функция для работы с битовыми флагами в Qlua(Lua)

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

Qlua-основы

Сейчас в QLua появилась встроенная функция bit.test, которая решает ту же задачу, т.е. смысла в использовании функции CheckBit больше нет !


true - флаг установлен
false - флаг не установлен

-- Функция проверяет установлен бит, или нет (возвращает true, или false)
CheckBit = function(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
Пример использования

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

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

Функция для работы с битовыми флагами в Qlua(Lua): 22 комментария

  1. Дмитрий добрый день. Помогите разобраться. Хочу сохранять активные заявки в файл, чтобы при отключениях связи, перезагрузке терминала и пр. всегда знать отправленные ордера. Для этого написал так:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    OpenOrd	= {{}} -- массив активных заявок
     
    function main()
    if getNumberOf("orders") > 0 then
    	for i = 0,getNumberOf("orders") - 1 do
    		if  (_________________) then
    			OpenOrd[i].Operation = GetBuySell(getItem("orders",i).flags)
    			OpenOrd[i].Qty = getItem("orders",i).qty
    			OpenOrd[i].Price = getItem("orders",i).price
    		end
    	end
    end
    end
     
    function GetBuySell(flags)
      if TestBit(flags, 2) then
        return 'S'
      else
        return 'B'
      end
    end
     
    function TestBit(x, bit_num)
      local p = 2 ^ bit_num
      return x % (p + p) >= p
    end

    Как правильно написать условие?
    Как я понял, может быть два состояния:
    - заявка активная (когда не наливали вообще)
    - заявка частично исполненная

    Если я пишу только условие для проверки активности заявки - TestBit((getItem("orders",i).flags), 0), то могу упустить частично исполненные заявки.
    Чтобы их вычислить, нужна проверка, как понял, такая - ( not TestBit((getItem("orders",i).flags), 0) and not TestBit((getItem("orders",i).flags), 1) ), но как тогда корректно совместить эти два условия?

      1. Да, верно, спасибо, так наверное проще, но у снятых заявок баланс тоже не нулевой. Тогда стоит написать так?

        1
        2
        3
        4
        5
        6
        7
        
        if getItem("orders",i).balance ~= 0 then
        	if getItem("orders",i).qty ~= getItem("orders",i).balance then
        	OpenOrd[i].Operation = GetBuySell(getItem("orders",i).flags)
        	OpenOrd[i].Qty = getItem("orders",i).qty - getItem("orders",i).balance
        	OpenOrd[i].Price = getItem("orders",i).price
        	end
        end

        Пробовал так:

        1
        
        if getItem("orders",i).balance ~= 0 and not TestBit((getItem("orders",i).flags), 1) then

        но почему-то получаю ошибку: test.lua:7: attempt to index field '?' (a nil value)
        Из-за чего она возникает?

          1. Значение GetBuySell(getItem("orders",i).flags) он показывает верно, а ругается на OpenOrd[i].Operation...
            Если закомментировать ошибку, ругается дальше на OpenOrd[i].Qty и OpenOrd[i].Price. Неправильно объявил массив?

  2. • бит 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) Айсберг-заявка
    Число 11001 означает, что включены следующие флаги:
    • Заявка активна.
    • Заявка лимитированная.
    • Возможно исполнение заявки несколькими сделками.

    Можно поподробнее- как соотнести число 11001 с битами!!!?

      1. А какое отношение имеет число 11001 к (0x1) Заявка активна, иначе – не активна, (0x2) Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена, (0x4) Заявка на продажу, иначе – на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL) и т.д. и почему в скобках не двоичные числа тогда? Можно поподробнее все вот это разжевать и дать ссылку на прочтение этого раздела?

        1. Если бит0(первая цифра справа) установлен в 1, то заявка активна, если в 0, заявка неактивна.

          "бит 1 (0x2) Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена" означает, что если данный бит равен "0" и бит0 равен "0", т.е. на конце "00", то заявка исполнена.

          Такого раздела создатели терминала QUIK не создали, описание значений бит есть в qlua.chm(файл в папке с терминалом), раздел "Структуры данных", на сколько я понимаю, сначала идет порядковый номер бита в двоичной системе, а в скобках в шестнадцатеричной. Я, к сожалению, не помню уже как в этих системах исчисления все устроено, данная функция вполне дает понять установлен определенный бит, или нет, мне этого достаточно для создания скриптов.

        2. Я вижу это так: поле flags в возвращаемых таблицах имеет тип NUMBER, т.е это число, которое можно представить как в двоичной системе, так и в шестнадцатеричной, как и в любой другой, разработчики QLua дали такое описание, видимо, для удобства (кому-то удобней в двоичной значение бита искать, кому-то в шестнадцатеричной). По этому они сначала указали индекс бита, т.е. бит 0 соответствует первому биту в двоичной системе, и значение этого бита соответствует значению бита (0x1) в шестнадцатеричной системе, и дальше все по такому же принципу.

  3. Спасибо большое, что не забыли о моей просьбе ) Буквально час назад самостоятельно разобрался, как именно работают эти флаги в двоичном представлении. Не понял только нумерацию битов в стоп-ордерах:
    -- бит 0 (0x1) Заявка активна, иначе не активна
    -- бит 1 (0x2) Заявка снята. Если не установлен и значение бита 0 равно 0, то заявка исполнена
    -- бит 2 (0x4) Заявка на продажу, иначе – на покупку
    -- бит 3 (0x8) Лимитированная заявка
    -- бит 5 (0x20) Стоп-заявка ожидает активации
    -- бит 6 (0x40) Стоп-заявка с другого сервера
    -- бит 8 (0x100) Устанавливается в случае стоп-заявки типа тейк-профита по заявке, в случае когда исходная заявка частично исполнена и по выставленной тейк-профит заявке на исполненную часть заявки выполнилось условие активации
    -- бит 9 (0x200) Стоп-заявка активирована вручную
    -- бит 10 (0x400) Стоп-заявка сработала, но была отвергнута торговой системой
    -- бит 11 (0x800) Стоп-заявка сработала, но не прошла контроль лимитов
    -- бит 12 (0x1000) Стоп-заявка снята, так как снята связанная заявка
    -- бит 13 (0x2000) Стоп-заявка снята, так как связанная заявка исполнена
    -- бит 15 (0x8000) Идет расчет минимума-максимума

    Видно, что отсутствуют некоторые номера, например после 3 идет сразу 5. Как тогда быть в такой ситуации: флаг = 29, стоп заявка активна. В бинарном виде: 11101. Нумеруем с 0 до 4, с конца. Получаем:
    0 бит = 1 (заявка активна), 1 бит = 0, не снята, 3 бит = 1 (лимитированная), 4 бит = 1, но в таблице расшифровок он отсутствует, следующий после 3 бит идет 5 бит (ожидает активации). Вот неясности именно с 3м и 4м битами. Как может быть, что заявка лимитированная, если она условная. Ведь лимитированной может быть только прямая заявка или я не прав? И по поводу 4 бита. Его нет в таблице, но во флаге он равен 1. Верно ли понимать, что для него надо брать расшифровку из таблице для 5 бита? В этом случае смысл не теряется, заявка действительно ждет активации по условию в ней.

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