Нужные функции

Здесь буду выкладывать функции, которые могут пригодиться:

math_round() -- Округляет число до указанной точности
GetServerDateTime() -- Возвращает текущую дату/время сервера в виде таблицы datetime
StrToTime() -- Приводит время из строкового формата ЧЧ:ММ к формату datetime
CheckDemo() -- Узнать является ли терминал демо от компании Arqa, или демо брокера Открытие
GetTotalnet() -- Получает текущую чистую позицию по инструменту
GetEffectivePosPrice() -- Получает эффективную цену позиции по инструменту
GetCorrectPrice() -- Приводит переданную цену к требуемому для транзакции по инструменту виду
GetPriceForMarketOrder() -- Возвращает корректную цену для рыночной заявки по текущему инструменту
SetOrder() -- Выставляет обычную лимитную заявку
SetMarketOrder() -- Выставляет рыночную (по сути) заявку
CheckOrder() -- Проверяет наличие в системе заявки с определенным ID транзакции
GetOrderNum() -- Возвращает номер заявки по ее ID транзакции
WaitOrderComplete () -- Ожидает исполнения заявки по ID транзакции
Set_SL() -- Выставляет 'Стоп лимит' заявку
SetTP() -- Выставляет 'Тейк профит' заявку
SetTP_SL() -- Выставляет 'Тейк профит и Стоп лимит' заявку
CheckStopOrder() -- Проверяет наличие в системе стоп-заявки с определенным ID транзакции
GetStopOrderNum() -- Возвращает номер стоп-заявки по ее ID транзакции
CheckStopOrderActive() -- Проверяет по номеру активна ли стоп-заявка
Kill_SO() -- Снимает стоп-заявку
StackFIFO() -- Создает объект стека FIFO(Первым вошел, первым вышел)

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

Нужные функции: 43 комментария

  1. Здравствуйте. Подскажите как сделать так чтобы при выполнении условия (например нужная цена) выставилась стоп-заявка в одном количестве? А у меня получается что при наступлении выставляется стоп заявки одна за одной.

      1. Этот вопрос относится не к QLua, в частности, а к программированию, в целом, Вам нужно поучиться программировать алгоритмы, научиться объяснять компьютеру на ему понятном языке что Вы от него хотите. Оставьте на время заявки со стоп-заявками, а поучитесь основам, циклам, условным операторам (раздел меню слева "QLua(Lua) основы"). Попробуйте посчитать в цикле сумму чисел от 1 до 10 и вывести после этого результат в message(). Если хотите, то я могу с Вами лично по Skype позаниматься, стоит относительно недорого, а времени себе уйму сэкономите и сможете потом все, что угодно запрограммировать.

  2. Подскажите как сделать правильно. Если пишу вот так, то заявка отправляется:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    t = {
       ["CLASSCODE"]="SPBFUT",
       ["SECCODE"]="SRU7",
       ["ACTION"]="NEW_ORDER",
       ["ACCOUNT"]=ACCOUNT,
       ["TYPE"]="M",
       ["OPERATION"]=OPERATION,
       ["QUANTITY"]=QUANTITY,
       ["PRICE"]="0",
       ["TRANS_ID"]="1"
    }
    sendTransaction(t)

    А если через функцию, то пишет " unexpected symbol near '='". Если во всех полях проставить ==, заявка все равно не будет выставляться:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    function Trade()
       local t = {
          ["CLASSCODE"]="SPBFUT",
          ["SECCODE"]="SRU7",
          ["ACTION"]="NEW_ORDER",
          ["ACCOUNT"]=ACCOUNT,      
          ["TYPE"]="M",
          ["OPERATION"]=OPERATION,
          ["QUANTITY"]=QUANTITY,
          ["PRICE"]="0",
          ["TRANS_ID"]="1"
       }
       sendTransaction(t)
    end

    Тоже самое со стопом и т.п.

        1. знак == используется при проверке на равенство, например:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          
          A = 10   -- Присваиваем переменной A значение 10
          B = 10   -- Присваиваем переменной B значение 10
          -- ЕСЛИ A равно B ТО
          if A == B then
             -- Выводим сообщение
             message('A равно B')
          -- ИНАЧЕ
          else
             -- Выводим сообщение
             message('A не равно B')
          end

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

  3. Есть в роботе вот такая строка -

    1
    
     local Scale = tonumber(getSecurityInfo("SPBFUT", Fut).scale) -- Точность цены по инструменту

    - робот остается включенным до утра. В 9-05 МСК отключается из-за ошибки. Ругается именно на эту строку - пишет что то типа - попытка индексировать nil.

      1. Привет, рад тебя видеть, пробовал 3 дня по разному - зашел в тупик - ну вот спросил - ладно попробую в понедельник с другой темой - Спасибо. Нефть осваиваю.

        1. А так то проверял, всякие проверки делал - ну на nil то самая надежная наверное, к "гадалке не ходи" мозг я себе вынес так то, в очередной раз спасибо.

            1. 1
              
              CommFut = RtS(Comm_Fut * PS / SP)

              - я обратился к функции

              1
              2
              3
              4
              5
              6
              7
              8
              
              function RtS(price) -- Функция округляет значение price до шага цены инструмента
                 if getSecurityInfo("SPBFUT", Fut) ~= nil then
                    local Scale = tonumber(getSecurityInfo("SPBFUT", Fut).scale) -- Точность цены по инструменту
                    price = Round(price, Scale) -- Округляет число до необходимого количества знаков после запятой
                    price = Round(price / PS) * PS -- Корректирует на соответствие шагу цены
                    return price -- Возвращает результат
                 end
              end

              Вопрос, если в момент обращения в 9-05 МСК данных нет, значит CommFut присвоят nil или ни чего не произойдет?

                    1. ага проверил == nil, спасибо за наводку дальше сам, не сталкивался раньше, по этому и спрашиваю - вроде не сильно тебя нагрузил - Спасибо - с меня "магарыч" чуть позже.

  4. добрый вечер.
    в таблице состояние счета есть кнопка "закрыть все " закрывает позиции +снемает все стоп заявки.
    в Quik Lua есть что то подобное ?

  5. sCreator вообще, все что вы пишете на Луа в квик - квик уже 1 раз посчитал у себя на сервере, и поменял что нужно и послал в клиентское место, где опять сделал все то-же самое - распарсил байт-код в циферьки и букавки второй раз и отдал в QLua-машину, где вы начинаете считать уже по 3-му разу.
    И реализация типа "событийной модели" в квик отсутствует напрочь, кто-бы что ни говорил - ее нет. Квик получает пакет, а в ваш код отдает этот пакет построчно типа события идут, а они уже давным давно прошли - минус время, а если пакет толстый - то просто жесть. Вот отсюда и беруться 60-600 - пакет тоньше - толще до 1,8 секунды доходило (14 км от ЦОД мой ПК стоит - расстояние - что в метре что в 14 км - не играет роли никакой)

      1. QLUA.chm:
        "bit.test
        Функция проверяет состояние указанного бита в значении. Возвращает true, если бит равен «1», и false, если бит равен «0».
        BOOLEAN bit.test(NUMBER х, NUMBER n)
        где:
        х – значение;
        n – номер бита. Нумерация битов начинается с «0»."

        1. Ах вон что))
          А вы используете битовые флаги у себя в коде? Это дешевле, чем bolean (4 бита) и уж тем более дешевле, чем использование циферки или букавки (8 бит) в качестве флага. Только для квиК этот прирост по времени ничего не даст, потому как "не думай о секундах с высока..." и смело можно пользоваться и буковками и циферьками (даже целыми предложениями) в качестве установки своих флагов а не биты. Скорости все равно не прибавится. У меня все скрипты считают 1 раз в 1мс и чуть меньше 1 мс за итерацию цикла, а заявка на биржу попадает через 60 - 600 мс и толку от скорости расчета - никакой. Надеюсь, объяснил.

          1. А Вы смотрели что делает предложенная в разделе функция CheckBit() (смотрите 2 функцию с верху) которая повторяет функционал квиковской функциии bit.test
            или Вы вероятно именно ей проверяете флаги сделок (trade.flags) чтобы не экономить на битах?

            1. Я не использую функцию CheckBit() предложенную здесь - она медленная. Под конкретную таблицу сделана своя функция проверки флага, как-то статус заявки или операция обезличенной сделки.
              На второй пост - а я вас и не смешу. Время батенька - линейно, а не то, что вы там себе придумали. А в целях сэкономить память на битовых флагах - не смешите у вас 512 мб памяти стоит на ПК? Я вас умоляю...
              В квик - не целесообразно - раньше не было ни побитовых операций ни битовых флагов, и все работало прекрасно и по шустрее, чем сейчас. Если вы про экономию места в пакетах данных - да бросьте вы, никакого выигрыша от использования битовых флагов существенного нет, вернее - вообще нет. Какой-то идиот попросил Арку сделать, а они не поленились.
              А вот если вы используете битовый флаг для проверки своих условий - то прирост по времени будет, но тоже не существенный.

              1. Я прошу прощения, но я не говорил что я использую битовые флаги у себя. Вы высказали это предположение и доказываете мне прописные истины.
                Вернемся к первому моему вопросу.(расшифрую его подробнее)
                Среди предложенных здесь функций есть (вторая) функция CheckBit основанная на квиковской функции bit.band.
                Смена объявления функции на

                1
                2
                
                -- Функция проверяет установлен бит, или нет (возвращает true, или false)
                CheckBit = bit.test

                не изменит ее функционал. а проще вообще вместо нее использовать

                1
                
                bit.test(flags, _bit)

                И мой вопрос:
                в чем подвох, что не так с bit.test ?

                1. Подвоха нет никакого, возможно, вы имели в виду, что она выполняет те же действия что и функция из Qlua?
                  Если так, то CheckBit была написана раньше, чем появилась bit.test.
                  И они далеко не равны по своим действиям.

                  Если вы имели ввиду именно то, что вы написали - а написали вы переопределение bid.test в CheckBit:
                  CheckBit = bit.test, то разницы при вызове вашей CheckBit() и квиковской bit.test() не будет никакой и прироста по времени тоже никакого. Если цель переопределить функцию bit.test() все таки стоит с целью ускорения ее вызова, то сделать нужно так:
                  local CheckBit = bit.test
                  и далее спокойно пользоваться "ускоренной" CheckBit, которая ничем не будет отличатся от bit.test, только ускоренным доступом, потому как скорость доступа к локальным переменным в Луа быстрее, нежели к глобальным.
                  Без обид, правильно заданный вопрос 99,99% случаев быстрый и точный ответ. Не нужно думать что тут все телепаты)))

                  1. Спасибо за обстоятельный ответ. Я тоже уже для себя предположил что bit. test дописали потом.
                    Вы упомянули пугающую цифру 60 - 600 мс. Не поделитесь, такие колебания зависят от чего? Сервер, канал, клиент, луа? Активности торгов на бирже?

                    1. Нет дело не в Луа, Луа написан на чистом С и работает быстрее, чем C#. Ограниченный функционал - это да, это минус. Я повыше писал в цикле while is_run do sleep(1) end расчет торговой математики <<1мс.
                      Раньше у меня были боты на QPILE - беда в том, что он считал 1 раз в секунду, но и это я обошел, нагрузив 1 ядро на 100% бесконечным циклом. И скорость была 30-40 мс, чего вполне хватало.
                      Года 3-4 назад - моя заявка была первой, потом все остальные (и этот алгоритм до сих пор жив и зарабатывает). Потом биржа сказала - "ПостТрейдКонтроль!!!" и обязала брокеров его сделать, а это как раз, очень долгая функция. С другой стороны - на QPILE раза 3 - робот умудрялся купить в 2-3 раза больше, чем есть денег с маржой.
                      ПО брокера не успевало пересчитать лимиты.
                      Раньше я мучил провайдера, если вдруг пинг до сервера брокера был больше 1 мс. Протянул оптику до ПК, купил материнку с позолоченными контактами, короче вложился как следует. Скорость подросла до 20 мс от сигнала до заявки на бирже, а с этим пост-трейд-контролем все стало через ...опу.
                      Сейчас квик использую для просмотра сделок, ну и голосовой бот у меня сделан и говорит, профит или убыток, а торговый алгоритм - на C# перенес в ко-локацию(никогда не делайте! хфт на С# только С++ кроссплатформенный).
                      3 месяца тестов 4 - 20 мс через АСТС, сегодня еще "шаманил" - хочу завтра 1 мс выжать стабильно.
                      Винда - враг хфт №1, не даст наверное, придется свой сервак на Линуксе ставить в ко-локацию, потому как у брокера нету Линукса и вряд ли будет. Но пока и так хватит.

                    2. kalikazandr спасибо большое, есть над чем подумать.

  6. Все функции для округления цен до нужного шага цены сводятся в одну, вот так:
    function doStep (val, step)
    return math.floor(val/step + 0.5) * step
    end
    где step = getParamEx(CLASS_CODE, SEC_CODE, "SEC_PRICE_STEP").param_value)
    Можно применять для округления времени в формате POSIX, до текущего таймфрейма, H60 включительно,
    все, что выше H60 корректно округлятся не будет.