Вопрос-ответ

Автор записи: Дмитрий (Admin)
1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 5, среднее: 5,00 из 5)
Загрузка...
LogoNew
Если Ваш вопрос не имеет отношения к какой-то определенной статье на данном сайте, то, пожалуйста, задавайте его в комментариях здесь.

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

Вопрос-ответ: 2 168 комментариев

  1. Здравствуйте!
    Может кто работал с метками. В справочнике QLUA есть функция AddLabel которая принимает таблицу параметров метки. В этой таблице есть параметр:
    TRANSPARENCY DOUBLE Прозрачность метки в процентах. Значение должно быть в промежутке [0; 100]
    Что то я не могу понять за что он отвечает, прозрачность метки он не устанавливает, пробовал разные варианты.
    Это я не могу понять принцип его работы, или данный параметр не работает?

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

      Хорошо. Тогда будет другой вопрос.
      А вообще возможно ли на языке C++ рисовать на графике?
      Вообще идея такая:
      1. Найти окно Квика
      2. В этом окне найти элементы.
      3. Отыскать среди найденных элементов нужный график
      4. Добавить \ внедрить еще один элемент, в элемент графика.
      Как это сделать программно не спрашиваю, пока не представляю, вопрос в том реально ли вообще такое. Ну допустим bitmap создать на c++ и разместить его на графике Квика.
      Как отыскать именно тот график который нужен, среди всех открытых, это уже потом буду решать...

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

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

    1. Откуда берете последнюю цену?
      Есть функция OnAllTrade - вызывается терминалом QUIK при получении обезличенной сделки. Это и есть цена последней сделки.
      Но не известно как устроен Ваш робот, Вы пишите "...до обновления в таблице", предполагаю что робот берет последнюю цену из какой то таблицы, а не использует OnAllTrade.
      В таком случае задержка не поможет. Последовательность будет такой:
      1. Начинает выполнятся код Вашего робота.
      2. Робот получает цену из таблицы и выполняет расчет.
      3. Робот завершает вычисление
      4. Квик отправляется обновлять таблицу
      Даже если Вы установите задержку в 100 000 сек, все равно цена не обновится в таблице.
      Скорее всего код робота и квик работают в одном потоке, по этому будет так:
      1. Начинает выполнятся код Вашего робота.
      2. Робот ждет 100 000 сек
      3. Робот получает цену из таблицы и выполняет расчет.
      4. Робот завершает вычисление
      5. Квик отправляется обновлять таблицу
      И как понимаете ни какие проверки тоже не помогут, Квик не пойдет обновлять таблицу, пока Вам робот не закончит вычисление.
      Так что нужно переписать алгоритм так, что бы робот производил вычисление в функции обратного вызова OnAllTrade.
      Тогда выполнение будет таким.
      1. Придет сделка в терминал
      2. Квик вызывает OnAllTrade и передает цену сделки
      3. Робот использует эту цену как цена последней сделки в своих расчетах.
      4. Функция OnAllTrade завершает свое выполнение.
      5. Квик отправляется обновлять таблицы и графики, но роботу это уже не важно, он все посчитал.

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

          1. Хм, хотя сейчас alltrade.price и так использую, но после сигнала к сделки, сама сделка проходит по другой цене, а расчет идет по цене сигнала.
            function OnAllTrade(alltrade)
            P = tonumber(alltrade.price)
            if R and D and G then
            sena_bay = tonumber(P) и это неверная цена получается.
            Вот поэтому хотел последнюю цену получать в таблице, вроде бы пробовал через getParamEx(). Точно непомню, под рукой нет той части кода.

            1. А почему решили что цена не верная?
              Одно дело если Вы отправили заявку по цене 20450 на покупку, а сделка прошла по цене 20445. Так это нормально, просто пока заявка шла на биржу, появился продавец, который хотел продать по 20445, вот он Вам и продал, а Вам выгодно, Вы же дешевле купили.
              Вы посмотрите какую цену в заявке указываете, когда ее на рынок отправляете.
              Так же не забывайте что в Квике не совсем реальность находится.
              Сначала сделка происходит на бирже, потом информация об этой сделке приходит брокеру, потом брокер направляет информацию в терминал, а вот только потом терминал вызывает OnAllTrade, робот считает и формирует заявку с ценой XXX отправляет заявку брокеру, брокер отправляет заявку на биржу и биржа ее исполняет, или в очередь ставит, ну или отклоняет, завит от заявки.

      1. Здравствуйте, я ей редко пользуюсь, но подключается, как обычно при помощи require, в ней много разных модулей, например, если Вы хотите работать с модулем luacom, который позволяет взаимодействовать, например с Excel, то самый простой способ, это закинуть саму библиотеку luacom.dll (найти ее перед этим в LuaForWindows установленной) в папку со скриптом, или в корень терминала Quik и использовать ее примерно так в скрипте, еще желательно подключать библиотеку w32, она, вроде бы, на сайте quik2dde есть и оборачивать все вызовы luacom:

        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
        
        FPath = 'C:\\QuikExport.xlsx'
        Excel = nil
         
        main = function()   
           require('luacom')
           require('w32')
         
           w32.CoInitialize()
         
           Excel = luacom.CreateObject("Excel.Application")
           Excel.Visible = true
         
           Excel.Workbooks:Add()      
           local sheets = Excel.Worksheets
           local sheet = sheets:Add()
           sheet.Cells(1,1).Value2 = 'Какое-то значение'
         
           Excel.Workbooks(1).SaveAs(FPath, FPath) 
         
           Excel.DisplayAlerts = false
           Excel:Quit()
           Excel = nil
         
           w32.CoUninitialize()
        end
  3. Чтобы не быть голословным прилагаю часть кода:

    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
    
    is_run = true
    Div = 1
    function main()
       while is_run do
            if (идет условие) then
                    Tradefunc()    -- вызывается функция выставления рыночной заявки
    	         Sleep(10000)   -- после проведенной транзакции выполнение должно перейти к этой строке и скрипт должен продолжиться, но происходит обрыв видимо до этого места....
           end
           sleep(500)
    end
     
    function Tradefunc()
       transaction = {
       		   ["ACCOUNT"] = Account,
    		   ["CLIENT_CODE"] = Clientcode,
    		   ["ACTION"] = "NEW_ORDER",
      		   ["CLASSCODE"] = Classcode,
    		   ["TYPE"] = "M",
      		   ["SECCODE"] = Seccode,
      		   ["OPERATION"] = Direction,
      		   ["PRICE"] = "0",
      		   ["QUANTITY"] = Quantity,
      		   ["TRANS_ID"] = "1"
    	         }
       for i = 1, Div do        --  цикл нужен для разрыва во времени выставления заявок в 2 сек, но т.к. Div = 1, то транзакция будет одна 
          Transaction = sendTransaction(transaction)
          sleep(2000)
          Tradetimefunc()     -- функция определения торгового времени
          if (Trade_time==false) then    -- если не торговое время, то больше не выставлять заявки
             break
          end
       end
    end
      1. Дмитрий, спасибо большое за обратную связь,
        обнаружил глупую ошибку (в 7 строке прилагаемого кода ошибка в регистре написания sleep).
        Надеюсь, что это решит возникшую проблему, несмотря на то, что компилятор quik не указывал на какие-либо ошибки.
        Обратные функции за исключением onStop() не использую. А все пользовательские функции вызываются из функции main(), соответственно не должны влиять на работоспособность системы quik.

          1. Я ориентируюсь на окно запуска скрипта (внизу есть дополнительное окно с выявленными ошибками выполнения скрипта). Вы, наверное, имеете в виду окно сообщений/оповещений? Она вроде пустая, попробую запустить перед запуском скрипта.

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

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

      1. Дмитрий,
        В том то и дело, что функция main зациклена, и пока не будет нажата кнопка остановить, скрипт должен работать.
        Единственное, что у меня вызывает сомнения, это то, что после выставления заявки, идет функция sleep() с длительностью в 10 секунд. Проверял, что если запустить простейший код и добавить в него sleep(10000), то квик виснет намертво. Хотя во время работы торгового скрипта, никаких провисаний не замечено, а остановка происходит сразу же после сообщения о выставлении заявки в квике. Складывается ощущение, что выполнение скиипта просто не доходит до функции sleep() и обрывается сразу после выполнения транзакции...

        1. Если sleep() поставить в main, то ничего не будет, а если в какой-нибудь коллбек, типа OnTrade, то квик повиснет на время паузы, все потому, что для функции main выделяется отдельный поток, который работает параллельно с потоком терминала, а все коллбеки работают в том же потоке, что и интерфейс терминала. Можете показать свой скрипт, так быстрее будет найти причину.

  5. здравствуйте
    подскажите как при удалении заявки определить что она не активна и её удалить не удастся, удаляю так
    function delete_order(class_code,sec_code,a_num)
    if a_num=="" then
    return
    end
    t = {
    ["CLASSCODE"]=class_code,
    ["SECCODE"]=sec_code,
    ["ACTION"]="KILL_ORDER",
    ["TRANS_ID"]="1",
    ["ORDER_KEY"]=tostring(a_num)
    }
    local res = sendTransaction(t)
    if res ~= '' then --если ошибка
    file:write(os.date()..'Поля отправляемой транзакции:\n')
    for key,value in pairs(t) do sd_file[i]:write(os.date()..key..':'..tostring(value).."\n")
    end
    file:write(os.date()..'ОШИБКА транзакции при удален заявк: '..res.."\n\n") --проверка что транзакция прошла
    message("Ошибка транзакции при удален заявк: "..res,1)
    file:write(" Выполнилась без ошибок функция delete_order"\n\n")
    end
    return
    end

    терминал пишет что заявку нельзя удалить, как эту ситуацию в программе определить?

      1. этот поиск замедлит работу функции и всего робота, а нельзя ли это проконтролировать через функции обратного вызова, например через OnTransReply или ещё как то?

          1. а как именно в OnTransReply отследить такую ситуацию? я там проверяю tranzakc.status, если он не равен 3 то произошла ошибка, например торговлю остановили, и если таких ошибок произошло несколько то ставлю робота на паузу

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

                1. Не знаю что подсказать, ставить робота на паузу не лучший вариант, нужно понять какая конкретно ошибка и принимать меры по ее устранению, отсидеться, авось само пройдет, так себе решение 🙂

                  1. почему на паузу то, ни на какую паузу не ставлю. вот например выставилась заявка или нет я узнаю не через поиск этой заявки в таблице заявок, а через OnOrder. Так же хочу отловить ситуацию когда заявку не возможно снять, т.е. робот отсылает приказ на снятие заявки, далее ждём когда придёт сигнал от OnOrder что заявка снята, но если заявку нельзя снять то сигнал не придёт, вот эту ситуацию и хочу отловить через OnTransReply, но как именно не знаю, вот вас об этом и спрашиваю)

                    1. OnTransReply не вызывается, когда Вы пытаетесь снять неактивную заявку, вот такими простыми тестовыми скриптами такие вещи можно быстро проверять, чтобы не ждать ответа:

                      1
                      2
                      3
                      4
                      5
                      6
                      7
                      8
                      9
                      10
                      11
                      12
                      13
                      14
                      15
                      16
                      17
                      
                      main = function()
                         -- Заполняет структуру для отправки транзакции на снятие заявки
                         local T = {}
                         T['TRANS_ID']           = '1'
                         T['CLASSCODE']          = 'QJSIM'
                         T['SECCODE']            = 'SBER'
                         T['ACTION']             = 'KILL_ORDER'        -- Тип заявки 
                         T['ORDER_KEY']          = '4226141780'      -- Номер заявки, снимаемой из торговой системы
                       
                         -- Отправляет транзакцию
                         local Res = sendTransaction(T)
                         message('Res:'..Res)
                      end 
                       
                      OnTransReply = function(reply)
                         message('OnTransReply')
                      end

                      Следовательно, единственный вариант, это перед попыткой снятия заявки искать ее в таблице и смотреть активна она, или нет