Проверка выставления заявки по отправленной транзакции QLua(Lua)

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

Блоки кода

Блок кода QLua

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

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

Проверка выставления заявки по отправленной транзакции QLua(Lua): 41 комментарий

  1. Доброго времени суток.
    Не могли бы вы подсказать, где можно найти перечисление возможных значений, таких параметров транзакции как ACTION и TYPE?

    1. Здравствуйте! Файл справки (находится в папке с терминалом квик) info.chm: "Раздел 6. Совместная работа с другими приложениями" - "Импорт транзакций" - "Формат .tri-файла с параметрами транзакций" и "Примеры строк, которые могут содержаться в файле"

  2. Приветствую Вас!
    А так ли необходима функция OnTransReply()? Не достаточно ли того что написано тут :

    local Res = sendTransaction(Transaction)
      if Res ~= '' then message('TransOpenPos(): Ошибка отправки транзакции: '..Res) else message('TransOpenPos(): Транзакция отправлена') end
    end
    Отправлена транзакция и хорошо. Дальше проверяем наличие чистой позиции по бумагам если сделка была совершена. Там и номер и время и кол-во бумаг смотрим.
    Может я чего-то не понимаю, разъясните! 🙂 
    ps: просто измучился я уже с этой функцией )))
    1. Здравствуйте!
      Смысл в том, что в Res появится ошибка только если сам терминал ее обнаружит, еще до отправки на сервер брокера. И если биржа отклонит данную транзакцию по какой-то причине, то мы об этом сможем только догадываться, ожидая результата. OnTransReply() решает эту проблему.

  3. Вот так ловчее, по моему:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    local OldTransReply = {}
    function OnTransReply(trans_reply)
    	local t_id = trans_reply.trans_id
    	if not OldTransReply[t_id] then -- транзакция не обработана
    		-- Если пришла информация по нашей транзакции
    		if t_id == trans_id then
    			local status = trans_reply.status
    			--Выводит в сообщении статусы выполнения транзакции
    			if status == 3 then -- транзакция выполнена
    				message('OnTransReply(): По транзакции №'..t_id..'\nУСПЕШНО ВЫСТАВЛЕНА заявка №'..trans_reply.order_num..'\nпо цене: '..trans_reply.price..' объемом '..trans_reply.quantity)
    				OldTransReply[t_id] = true -- больше по этой заявке не будут обрабатываться колбеки, даже после дисконекта
    			elseif status > 3 then -- произошла ошибка
    				message('OnTransReply(): ОШИБКА выставления заявки по транзакции №'..t_id..', текст ошибки: '..trans_reply.result_msg)
    				OldTransReply[t_id] = true -- больше по этой заявке не будут обрабатываться колбеки, даже после дисконекта
    			end
    		end
    	end
    end

    а вообще, на мой взгляд, OnTransReply нужна только для получения ошибки, обработки этой ошибки и коррекции заявки для повторного выставления, если ошибки нет, то и нечего в ней (функции) делать.

      1. Все переменные хранятся в таблицах lua, таблица с локальными переменными меньше, чем с глобальными (ровно такого размера, сколько вы объявили локальных переменных у себя в коде) и доступ к ним быстрее. Главное с областью видимости не перепутать.
        Т.е.:

        1
        
        local а = math.floor(10/3)

        При частом использовании будет работать медленнее, чем:

        1
        2
        
        local math_floor = math.floor--в начале кода взяли все функции из глобальных таблиц
        local a = math_floor(10/3)
        1. Спасибо.
          Т.е. раз интерпретатор, то и доступ к переменным не прямой, а последовательный, следовательно чем переменных больше, тем медленней выборка адреса для операции (производится поиск адреса по имени переменной в таблице переменных)?
          Скажем компилятор "С" вместо "math.floor(10/3)" влепит сразу адрес функции и загонит параметры с стек, а "перевалка" адреса функции в переменную может и удлинить бег кода.
          Но кажется где-то читал, что lua таки делает какую-то предкомпиляцию перед выполнением...

      1. Локальная переменная по своей сути локальна и храниться в таблице локальных переменных, вопрос где она объявлена, если в начале кода, то доступ к ней есть у всего кода, если внутри кода, то блоки написанные выше переменной ее не будут видеть, если внутри блока - то забывается сразу после выхода из блока (удаляется из таблицы локальных переменных).
        Глобальная переменная видна везде, т.к. заноситься в таблицу глобальных переменных на этапе компиляции.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        
        --глобальная переменная  "a":
        do a=10 end
        print (a)-->10
        --локальная переменная "a":
        do local a=10 end
        print (a)-->nil - не видна
        local a --объявляем до блока
        do 
        local x=10
        a=x
        end
        print (x)-->nil
        print(a)-->10

        Разница понятна между локальной и глобальной переменной?

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

          1. Да, с локальными переменными, а тем более локальными функциями надо быть оч. внимательным.
            Если функция объявлена локально и должна быть видна во всем коде, то пишем ее в начале кода.
            Если эта локальная функция хочет использовать внешние локальные переменные, то эти переменные надо поместить выше этой функции.
            Все просто.

      1. Здравствуйте, нет, должна быть объявлена выше main и функций, которые используют OldTransReply.
        Пользуйтесь вот таким шаблоном:

        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
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        
        --локальные переменные
        local exitflag
         
        -- и функции для calculate()
        local function round_down(v, s)
        	s = s or 1
        	return math.floor(v/s) * s
        end
         
        --торговый алгоритм
        local function calculate()
        	local avg = round_down((65.45+65+65.5)/3, 0.01)
        end
         
        --список событий
        local events = {}
         
        --обработчики событий
        local handlerevent = {}
        function handlerevent.OnTransReply(event)
        --лучше определять заявки по полю brokerref, оно есть всегда
        end
        function handlerevent.OnOrder(event)
        --лучше определять заявки по полю brokerref, оно есть всегда
        end
         
        function main()
        	local function parseevent(event)
        		if not event then return true end
        	--иначе вызвать обработчик события
        		handlerevent[event.event_key](event)
        	end
        	while not exitflag do
        		if #events > 0 then
        			repeat
        			until parseevent(table.sremove(events, 1)) or exitflag
                                if exitflag then break end
        		end
        		sleep(1)
        		calculate()
        	end
        end
         
        --события
        function OnTransReply(event)
        	event.event_key = "OnTransReply"
        	table.sinsert(events, event)
        end
        function OnOrder(event)
        	event.event_key = "OnOrder"
        	table.sinsert(events, event)
        end
        function OnStop()
        	exitflag = true
        end
        1. Спасибо за оперативный ответ ! Тоже к этому пришел, но решил уточнить 🙂
          А шаблон - это как раз то, чего и не хватало !
          Но пока сходу не разобрался. Вероятно, буду еще вопросы задавать, так что не обессудьте..)

          Большое Спасибо автору сайта за великолепный сайт - просто класс !!!

        2. Добрый вечер!
          Пытаюсь осмыслить Ваш шаблон. Предложенная Вами событийная модель меня сильно заинтересовала но, к сожалению, знаний в этой области не хватает.
          Хотелось бы посмотреть пример какого-либо простенького скрипта по данному шаблону (как описываются события, обработка событий, колбеки). Могли бы Вы его показать?

          1. таблица events это очередь. в нее кладется имя функции и таблица - параметр функции. в main из этой очереди достается значение, дальше в таблице handlerevent по имени ищется функция, и потом она вызывается с параметром:

            events = { {'a', {1, 2, 3}}, {'b', {4, 5, 6}}}
            handleevent = {a = function(tbl) ... end, b = function(tbl) ... end}

            чтобы добавить обработчики нужно добавить в таблицу handleent своих функций, чтобы их вызвать - в таблицу events нужно добавить элемент-таблицу состоящую из имени обработчика и таблицы-параметра для этого обработчика. что такое table.sinsert и table.sremove я не знаю, но подозреваю это "добавить в конец таблицы" и "достать из начала таблицы и удалить".

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

      1. Веселый вы человек, Дмитрий))
        OnTransReply(trans_reply) - не гарантирует, что можно уже выставлять заявку обратного направления, например - купил, и после получения ответа от биржи, что заявка исполнена - нельзя сразу выставить заявку на продажу. Соответственно, сама по себе функция OnTransReply() является чисто информативной и не белее

              1. Да дело не в этом, я посмотрел практически все ваши примеры, и многие рады и этому, но - это не правильно - значит вы намеренно вгоняете не опытных программистов в блуд, что само по себе - не хорошо)).

                1. Намеренно я точно никого никуда не вгоняю 🙂 Давайте конструктивную критику, с удовольствием внесу правки в статьи, я нигде не заявлял, что я отец-основатель терминала QUIK и что знаю все его потайные комнаты 🙂
                  На почту пишите сами, когда Вам будет удобно, с удовольствием пообщаюсь с Вами, если по делу.

                  1. Я так думаю каждый решает сам. Я пытаюсь проверять без OnTransReply(). Если здесь ошибки нет, то есть терминал не ругнулся

                    1
                    2
                    
                     local Res = sendTransaction(Transaction)
                      if Res ~= '' then message('TransOpenPos(): Ошибка отправки транзакции: '..Res) else message('TransOpenPos(): Транзакция отправлена') end

                    , то действую по схеме: если баланс в таблице заявок меньше рабочего (посланного транзакцией) объёма, то значит хоть одна заявка удовлетворена и далее в таблице сделок отслеживаем сколько же бумаг нам по этой заявке отдали и тут же смотрим полностью удовлетворён наш рабочий объём или сколько не добрали до него. Вот как-то так.

                  2. Я тоже считаю сделку совершённой только тогда, когда она появилась в OnTrade(), но все предыдущие шаги тоже отслеживаю (OnTransReply(), OnStopOrder(), OnOrder()), чтобы отлавливать возможные ошибки. Но как и написано в данной статье, для того, чтобы понять выставлена ли заявка (не сделка) по транзакции, достаточно OnTransReply().

                  1. Здравствуйте я новичек не подскажите где копать , взял простой скрипт на QLua попытался запустить на демку в квик выдает ошибку в окне (Ошибка TransOpt: Не найдено поле ,, Проверять лимиты ,, для транзакции ,, Ввод заявки ,, по классу ,,Опционы FORTS ,,
                    ) смотреть в коде скрипта или в квике ? хотя бы подсказку .
                    С ув.Андрей

                    1. Здравствуйте! В скрипте создается структура (массив) транзакции для отправки на сервер брокера, в ней должно быть поле проверки лимитов, а его там у Вас нет, потому квик и ругается перед отправкой. О том, какие поля и значения должны быть в транзакции читайте в файле справки info.chm (находится в папке с терминалом) в разделе "Совместная работа с другими приложениями" , подразделы: "Формат .tri-файла с параметрами транзакций", "Примеры строк, которые могут содержаться в файле"