Quik Lua

Сайт продукта: https://forum.quik.ru/forum10/
Lua — язык программирования, который используется в программировании торговых роботов под популярный в России терминал Quik.
  1. Аватар Boris Litvinov
    Тест на стабильность системы транзакций для движка LUA

    стабильный круг без остановок связанных с защитными функциями не срабатывания,
    двойными транзакциями, рассинхронизацией. Тест дал минимум 300мск 
    Это на всё что способен сервак квик!!!
    Но опять же, на демо сервере. 
    Ускорил написание копи пестам, частей скрипта Sergey Pavlov
    З
    а что ему благодарен.
  2. Аватар Boris Litvinov
    Тиковый движок интрадей + простейший скальпер бот Lua

    Ранее рассмотрели движок, + простейший бот "контртренд"
    Рассмотрим работу простейшего скальпер, интрадей бота. На остове того же движка.
    Скоро продемонстрирую систему транзакций скальпера, его стабильность, скорость  и
    не возможности рассинхронизации с рынком,  поговорим о проскальзываниях!

    доступность написания, простота скрипта  торгового робота, не сложнее примера ниже
    Тиковый движок интрадей + простейший скальпер бот Lua




     

  3. Аватар Boris Litvinov
    Интрадей движок на lua, за выходные

    Понимаю что STOK SHARP для программистов. 
    +После тестов стабильности, пришел к вывожу что S# не стабилен!
    Развиваю конечно и эту ветку...
    Но.Решил переписать движки с Qpile на Lua. Который стабильней в разы. Собственным опытом.
    Движок интрадей — скальпер.

    А вот скрипт простейшего бота что на видео. Простота!
    Интрадей движок на lua, за выходные




     

  4. Аватар Nikolay_2323
    Реализация Алгоритма под Quik

    Добрый день!

    Ищу исполнителя по реализации алгоритма под Quik.
    Алгоритм не сложный. Расчертить уровни лесенкой и исполнять по ним входы/выходы.
    Предложения напишите в личку пожалуйста.




    Помогите, пожалуйста, плюсами с выводом на главную....

    Заранее спасибо!
  5. Аватар Настя Степанцовва
  6. Аватар AlexGood
    Установка индикаторов Квик

    Друзья, добрый вечер! Подскажите каким образом установить в Квик 7.14.1.7 пользовательские индикаторы (.lua)?
  7. Аватар Sergey Pavlov
    Как в квике получить текущую позицию по бумагам

    Коллеги! Помогите решить простую задачку.

    Дано: имеются позиции по бумагам (TQBR).

    Надо: получить текущую позицию по каждой бумаге при помощи LUA.

    Пробовал пользоваться таблицами depo_limits, firm_holding и account_balance.

    Хоть каких-то чисел добился лишь через таблицу depo_limits следующим кодом:
    pos1={}
    pos2={}
    for j=0,getNumberOf("DEPO_LIMITS")-1 do
     pos1[#pos1+1]=getItem("DEPO_LIMITS",j).sec_code
     pos2[#pos2+1]=getItem("DEPO_LIMITS",j).currentbal
    end
    Проблема такого варианта в том, что он показывает ненулевые значения в currentbal только для позиций, которые были открыты ранее (возможно, по которым прошло +2 дня). По позициям, которые были открыты сегодня, он точно показывает 0.

    Подскажите, как правильно решить эту задачку?

    Премного благодарен:)
  8. Аватар nicknh
    Индикаторы для Квика

    Всем привет.

    Я писал для себя несколько индикаторов для Квика. Все они здесь - https://github.com/nick-nh/qlua.
    Часть — подсмотренные и адаптированные идеи, часть сам писал. Никогда не думал их делать закрытыми.
    Возможно, кому-то будут полезными.

    Да простит меня Тимофей, дам ссылку на МФД, где я выкладывал их ранее c описанием.
    forum.mfd.ru/forum/poster/?id=85696
  9. Аватар Dzam
    Справочник Lua для Quik


    Справочник Lua для Quik

     
    В статье речь пойдет о новом справочнике luaq.ru
    У каждого разный подход к созданию роботов: одни заказывают у разработчиков, другие используют программы и строят алгоритмы из кубиков, третьи пишут сами использую языки программирования.

    Я хочу рассказать о проблемах и решениях написания роботов на языке Lua для платформы Quik. Я не храню в голове весь справочник функций, которые предоставляют языки и платформы. Почти у каждого есть свой online справочник (кроме quik Lua). Когда-то был сайт qlua.net (или .org). Но срок домена закончился и сайт ушел в другом направлении. Конечно можно открыть PDF версию справочника и искать там, но это не всегда удобно. Да и этих PDF несколько и иногда они ссылаются друг на друга. Предоставленные примеры скорее вызывают улыбку. Есть несколько огромных примеров работы с таблицами и «Пример реализации игры «Крестики-нолики»». Оба примера настраивают на торговый лад. :)
    Я периодически использовал ресурс https://quikluacsharp.ru очень полезный и хороший ресурс, где много всего. Но искать конкретные функции и их описание не так удобно. В итоге создал свой справочник, точнее свой ресурс www.luaq.ru
    Тут можно найти описание каждой функции, таблицы, на которые ссылается функция или ее параметры, а также бесплатно (пока бесплатно) заказать примеры для конкретных функций. Прошу любить и не жаловаться. Шутка. Жаловаться можно и нужно.
  10. Аватар Кирков Алексей
    lua

    Пост немного не по теме трейдинга, скорее его надо задавать программистам, но среди трейдеров таких полно, может поделитесь опытом.

    Многолетнее использование Lua в QUIK`е подтолкнуло к идее использовать скриптовый язык в других приложениях.
    Из всего немногочисленного набора того, что есть для C# удалось найти:
    — NLua — 18K скачиваний в NuGet
    — LuaInterface -?
    — NeoLua – 50k скачиваний в NuGet
    — LuBox – 1k скачиваний в NuGet

    Автор проекта LuaInterface давно не поддерживает проект и прямо говорит, что NLua успешно продолжает его дело.

    NeoLua – наиболее популярен среди программистов в NuGet.

    LuBox показался удобным и наиболее «молодым» проектом.

    Кто-нибудь из смартлабовцев использовал какую-то из этих библиотек для встраивания Lua-скриптов? Поделитесь опытом использования: плюсы, минусы, баги.

     

     

     

  11. Аватар GVS
  12. Аватар h.
    Баги QUIK. алготрейдерам

    Добрый день.
        Собирал, через коннектор(самописный) Lua и C++, дату с квика: лента, стакан, ои и пр.
        Обнаружил, что свернутый в трей КВИК начинает общаться с сервером раз в 10-15 сек.Баги QUIK.  алготрейдерам

        Пакеты трафика не анализировал через tcpdump и пр. проги, но по косвенным признакам: помимо нагрузки сети и «моргания лампочки модема  :-)», вижу, что и в записанном файле дата представленна неровными временными срезами.

        Уважаемые знатоки вопрос:
     1) есть ли, в настройках QUIK, возможность исправить вышеизложенное.
     2) присутсвует ли в МТ5 или (др. проги по совету)  такая проблема.
     3) какой софт вы используете.
  13. Аватар Sergey Pavlov
    Код робота на LUA для QUIK

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

    Предназначается для новичков в алготрейдинге, что-то типа болванки.

    Важно: выставление заявок я закомментировал, поэтому можете смело запускать этот скрит, он не натворит ужаса по счету.

    require"QL"
    
    log = "sbrf.log"
    seccode = "SRM6"
    lots_in_trade = 80
    accnt = ""
    better = -5
    chart = "sberbankxxx"
    is_run = true
    prev_datetime = {}
    len = 100
    basis = 9
    k_bal = {0,1,2,3}
    sell = false
    buy = false
    id = 0
    first = true
    
    function trade_signal(shift)
            number_of_candles = getNumCandles(chart)
            bars_temp,res,legend = getCandlesByIndex(chart,0,number_of_candles-2*len-shift,2*len)
            bars={}
    
            i=len
            j=2*len
            while i>=1 do
                    if bars_temp[j-1].datetime.hour>=10 then
                            sk=true
                            if bars_temp[j-1].datetime.hour==18 and bars_temp[j-1].datetime.min==45 then
                                    sk=false
                            end
                            if sk then
                                    bars[i]=bars_temp[j-1]
                                    i=i-1
                            end
                    end
                    j=j-1
            end
    
            t = len+1
    
            do_sell = false
            do_buy = true
    
            value = 0
            if do_sell then value = 1 end
            if do_buy then value = -1 end
            toLog(log,"value="..value.." on candle: "..bars[len].datetime.year.."-"..bars[len].datetime.month.."-"..bars[len].datetime.day.." "..bars[len].datetime.hour..":"..bars[len].datetime.min.."   O="..bars[len].open.." H="..bars[len].high.." L="..bars[len].low.." C="..bars[len].close.." V="..bars[len].volume)
            return value
    end
    
    function mysplit(inputstr, sep)
            if sep == nil then
                    sep = "%s"
            end
            local t={} ; i=1
            for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                    t[i] = str
                    i = i + 1
            end
            return t
    end
    
    function OnInit(path)
            log=getScriptPath()..'\\'..log
            toLog(log,"==========OnInit: START")
            toLog(log,"==========OnInit: FINISH")
    end
    
    function OnStop()
            is_run = false
            toLog(log,"==========OnStop: script finished manually")
    end
    
    function CheckBit(flags, bit)
       -- Проверяет, что переданные аргументы являются числами
       if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!"); end;
       if type(bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!"); end;
       local RevBitsStr  = ""; -- Перевернутое (задом наперед) строковое представление двоичного представления переданного десятичного числа (flags)
       local Fmod = 0; -- Остаток от деления
       local Go = true; -- Флаг работы цикла
       while Go do
          Fmod = math.fmod(flags, 2); -- Остаток от деления
          flags = math.floor(flags/2); -- Оставляет для следующей итерации цикла только целую часть от деления
          RevBitsStr = RevBitsStr ..tostring(Fmod); -- Добавляет справа остаток от деления
          if flags == 0 then Go = false; end; -- Если был последний бит, завершает цикл
       end;
       -- Возвращает значение бита
       local Result = RevBitsStr :sub(bit+1,bit+1);
       if Result == "0" then return 0;
       elseif Result == "1" then return 1;
       else return nil;
       end;
    end;
    
    function killorders(ccode,scode)
        for i=0,getNumberOf("orders")-1,1 do
            local t=getItem("orders", i)
            if t ~= nil and type(t) == "table" then
                if( t.seccode == scode and CheckBit(t.flags, 0) == 1) then
                    local transaction={
                        ["TRANS_ID"]=tostring(math.random(2000000000)),
                        ["ACTION"]="KILL_ORDER",
                        ["CLASSCODE"]=ccode,
                        ["SECCODE"]=scode,
                                            ["ACCOUNT"] = accnt,
                        ["ORDER_KEY"]=tostring(t.ordernum),
                    }
                                    res=sendTransaction(transaction)
                end
            end
        end
    end
    
    function killstoporders(ccode,scode)
        for i=0,getNumberOf("stop_orders")-1,1 do
            local t=getItem("stop_orders", i)
            if t ~= nil and type(t) == "table" then
                if( t.seccode == scode and CheckBit(t.flags, 0) == 1) then
                    local transaction={
                        ["TRANS_ID"]=tostring(math.random(2000000000)),
                        ["ACTION"]="KILL_STOP_ORDER",
                        ["CLASSCODE"]=ccode,
                        ["SECCODE"]=scode,
                                            ["ACCOUNT"] = accnt,
                        ["STOP_ORDER_KEY"]=tostring(t.ordernum),
                    }
                                    res=sendTransaction(transaction)
                end
            end
        end
    end
    
    
    function main()
            toLog(log,"==========main: START")
            while is_run do
                    if isConnected() == 1 then
                            ss = getInfoParam("SERVERTIME")
                            if string.len(ss) >= 5 then
                                    hh = mysplit(ss,":")
                                    str=hh[1]..hh[2]
                                    h = tonumber(str)
                                    if (h>=1000 and h<1400) or (h>=1405 and h<1845) or (h>=1905 and h<2350) then
                                            if first then
                                                    for ti = 50,2,-1 do     trade_signal(ti) end
                                                    if buy and not sell then message(seccode.." Current state: green and buy",1) end
                                                    if sell and not buy then message(seccode.." Current state: red and sell",1) end
                                                    if buy and sell then message(seccode.." ERROR: green and red",1) end
                                                    if not buy and not sell then message(seccode.." WARNING: nothing",1) end
                                                    first = false
                                            end
                                            prev_candle = getPrevCandle(chart,0)
                                            if not isEqual(prev_candle.datetime,prev_datetime) then
                                                    current_value = trade_signal(1)
    
                                                    if current_value ~= 0 then
                                                            optn = "B"
                                                            if current_value==1 then optn = "S" end
                                                            curvol=0
                                                            no=getNumberOf("FUTURES_CLIENT_HOLDING")
                                                            if no>0 then
                                                                    for i=0,no-1,1 do
                                                                            im=getItem("FUTURES_CLIENT_HOLDING", i)
                                                                            if im.sec_code==seccode then
                                                                            curvol=im.totalnet
                                                                            end
                                                                    end
                                                            end
                                                            trvol = -current_value*lots_in_trade-curvol
                                                            if trvol ~= 0 then
                                                                    killorders("SPBFUT",seccode)
                                                                    killstoporders("SPBFUT",seccode)
                                                                    f = io.open(getScriptPath().."\\sbrf2_pos.txt","r")
                                                                    sbrf2_pos=f:read("*n")
                                                                    f:close()
                                                                    f = io.open(getScriptPath().."\\sbrf3_pos.txt","r")
                                                                    sbrf3_pos=f:read("*n")
                                                                    f:close()
                                                                    pr,n,l = getCandlesByIndex ("futsber", 0, getNumCandles("futsber")-1, 1)
                                                                    local trans =
                                                                    {
                                                                            ["ACTION"] = "NEW_ORDER",
                                                                            ["CLASSCODE"] = "SPBFUT",
                                                                            ["SECCODE"] = seccode,
                                                                            ["ACCOUNT"] = accnt,
                                                                            ["OPERATION"] = optn,
                                                                            ["PRICE"] = toPrice(seccode,pr[0].close+current_value*better),
                                                                            ["QUANTITY"] = tostring(math.abs(curvol-sbrf2_pos-sbrf3_pos)),
                                                                            ["TRANS_ID"] = tostring(getTradeDate().month*100+getTradeDate().day+id)
                                                                    }
                                                                    id = id+1
                                                                    --res = sendTransaction(trans)
                                                                    message(seccode.." Send : " .. res, 2)
                                                                    toLog(log,"Send: ".. res)
                                                                    for btr=0,200,5 do
                                                                            local trans =
                                                                            {
                                                                                    ["ACTION"] = "NEW_STOP_ORDER",
                                                                                    ["CLASSCODE"] = "SPBFUT",
                                                                                    ["SECCODE"] = seccode,
                                                                                    ["ACCOUNT"] = accnt,
                                                                                    ["OPERATION"] = optn,
                                                                                    ["PRICE"] = toPrice(seccode,pr[0].close-current_value*btr),
                                                                                    ["STOPPRICE"] = toPrice(seccode,pr[0].close-current_value*(btr+better)),
                                                                                    ["QUANTITY"] = tostring(6),
                                                                                    ["TRANS_ID"] = tostring(getTradeDate().month*100+getTradeDate().day+id),
                                                                                    ["EXPIRY_DATE"] = "GTC"
                                                                            }
                                                                            id = id+1
                                                                            --res = sendTransaction(trans)
                                                                            message(seccode.." Send : " .. res, 2)
                                                                            toLog(log,"Send: ".. res)
                                                                    end
                                                                    if current_value == 1 then
                                                                            message(seccode..' RED: buy->sell',1)
                                                                            toLog(log,"RED signal")
                                                                    else
                                                                            message(seccode..' GREEN: sell->buy',1)
                                                                            toLog(log,"GREEN signal")
                                                                    end
                                                            else
                                                                    if current_value == 1 then
                                                                            message(seccode..' RED: buy->sell',1)
                                                                            toLog(log,"RED signal, but nothing to do")
                                                                    else
                                                                            message(seccode..' GREEN: sell->buy',1)
                                                                            toLog(log,"GREEN signal, but nothing to do")
                                                                    end
                                                            end
                                                    else
                                                            if buy and not sell then toLog(log,"Nothing to do. Current state: green and buy",1) end
                                                            if sell and not buy then toLog(log,"Nothing to do. Current state: red and sell",1) end
                                                            if buy and sell then toLog(log,"Nothing to do. ERROR: green and red",1) end
                                                            if not buy and not sell then toLog(log,"Nothing to do. WARNING: nothing",1) end
                                                    end
                                                    prev_datetime = prev_candle.datetime
                                            end
                                    end
                            end
                    end
                    sleep(5*1000)
            end
            toLog(log,"==========main: FINISH")
    end
    
  14. Аватар Albus
    Скорость серверов Открытия

    Мой друг несколько лет назад написал программу на Луа. Она выставляет в КВИК и сразу снимает 20 заявок. Это происходит по очереди, одна заявка за другой. Робот замеряет сколько времени ушло на выставление и сколько времени на снятие. Заявки ставятся далеко от рынка, поэтому сделок не происходит.
    Вот сегодняшний тест серверов брокера Открытие. Я арендую виртуалку с московским IP, так что все заявки выставляются из Москвы.
    Речь про эти сервера, которые можно выбирать при залогинивании в КВИК.
    Скорость серверов Открытия

    -1-
    Выделенный сервер с повышенной скоростью и мощным железом. Он платный. С него торгует мой робот, которому нужна скорость.
    Вот тест сервера:
    Скорость серверов Открытия
    Данные в секундах. То есть средняя задержка выставления заявки 71 миллисекунда. Средняя задержка снятия 61 миллисекунда. Это конечно не ХФТ, но всё равно неплохо.
    -2-
    Следующий сервер Открытия — «Сервер 1 Билайн». Он доступен для всех.
    Скорость серверов Открытия
    Как видите, робот всё равно ставит этому серверу твёрдую пятёрку. Потому что средняя задержка постановки 229 миллисекунд и средняя задержка снятия 213 миллисекунд — это очень хороший результат для обычного (не платного) сервера.

    -3-
    Следующий общедоступный сервер Открытия. Сервер 1 Макомнет.
    Скорость серверов Открытия
    Скорость почти такая же как у предыдущего.
    -4-
    Сервер с названием «Открытие сервер 3»
    Скорость серверов Открытия
    Цифры почти такие же. И опять робот ставит оценку «пять».
    -5-
    Открытие Сервер 4 Макомнет. Крутейший из бесплатных.
    Скорость серверов Открытия
    103 миллисекунды — средняя задержка выставления
    116 миллисекунд — средняя задержка снятия.
    Это самый быстрый результат среди бесплатных серверов Открытия. Он всего в два раза медленнее платного выделенного сервера. Мои роботы, которым не нужна высокая скорость, торгуют с него. 
    -6-
    И последний «Сервер 4 Реллайн». 
    Скорость серверов Открытия
    Задержка постановки 235
    Задержка снятия 203.
    То есть он обычный середнячок. «Пятёрка», но не «пять с плюсом».
    ----------
    Большой выбор серверов — это огромное преимущество для брокера. До Открытия я торговал в Неттрейдере. У них удобный личный кабинет, красиво считается доходность портфеля, наглядно учитываются сделки, но… сервер всего и один и постоянно глючит. Бывало что несколько дней подряд час-полтора КВИК не работал. И перескочить на другой сервер было нельзя, потому что сервер всего один. А каждое утро в 10-30 у них на этом сервере запускалась какая-то программа, может быть бэк офиса, может быть бухгалтерии, которая что-то интенсивно считала и вызывала дикие невыносимые тормоза в клиентских КВИКах. 
    Поэтому я сбежал от них в Открытие. 
    Такие дела. 
    Всем удачных торгов!
  15. Аватар jeremy
    Нужен робот для Quik

    Комрады, кто пишет для QUIK на lua/Qlua/qpile? К кому можно обращаться?
  16. Аватар 222
    Lua

    Всем добрый день. Появилась необходимость написать робота, но из языков программирования знаю только R, а говорят необходимо изучать lua.  Подскажите есть ли у кого опыт работы с данным языком, на сколько он сложен или возможно пойти по какому то другому пути?
     
  17. Аватар Трейдер Вася
  18. Аватар Трейдер Вася
    QLua. Как определить, открыта-ли таблица скрипта? Как сделать кнопки в таблице? Такое определение не работает if IsWindowClosed(t_id)==false then t = CreateWindow(t_id) end

    QLua. Как определить, открыта-ли таблица скрипта? Как сделать кнопки в таблице? Такое определение не работает if IsWindowClosed(t_id)==false then t = CreateWindow(t_id) end
  19. Аватар Трейдер Вася
  20. Аватар Трейдер Вася
    Qlua. Как с помощью функция OnTransReply и OnTrade получить информацию об открытии сделки или поступлении заявки?

    Qlua. Как с помощью функция OnTransReply и OnTrade получить информацию об открытии сделки или поступлении заявки?
  21. Аватар Трейдер Вася
    Qlua. Не срабатывает while Run and trans_Status == nil do sleep(1); end; в коде. Помогите пожалуйста настроить флажок открытия заявки и позиции.https://cloud.mail.ru/public/5YEP/aAot7CJjr

    Qlua. Не срабатывает while Run and trans_Status == nil do sleep(1); end; в коде. Помогите пожалуйста настроить флажок открытия заявки и позиции.https://cloud.mail.ru/public/5YEP/aAot7CJjr
  22. Аватар Albus
    Индикатор для парного трейдинга+рубле-бочка

    Как и обещал, выкладываю простой индикатор для анализа двух инструментов. Его можно использовать для любых пар на свой вкус.
    Вот например, Сбер обычный (вверху) против сбера привилегированного (посерёдке). Индикатор внизу — красный. Для его расчёта первый график поделён на второй.
    Индикатор=SBER/SBERP
    Индикатор для парного трейдинга+рубле-бочка
    Дивиденды по ним одинаковые, ценообразование одинаковое, однако по странной воле рынка в эти дни Сбер обычный слишком дёшев против сбера привилегированного. Красный график утоптан вниз, а ведь ещё недавно был намного выше. Это не совет, но если (вдруг!) вы думаете, что эта несправедливость скоро выровняется, вам надо купить SBER и шортануть на такой же объём SBERP. А ещё лучше шортануть фьючерс на SBERP, чтобы не платить брокеру за акции взятые в долг.
    ----------
    Итак, индикатор. Я дописал к коду комментарии, чтобы даже новичок не кодер мог разобраться.
    Скачать индикатор.
    Индикатор для парного трейдинга+рубле-бочка
    ----------
    План действий.
    1. Графики обоих инструментов надо впихнуть в одно окошко, как это вы видели у меня на рисунке. Это позволит качественно учитывать пропуски свечей, ведь пропуски свечей бывают часто. Если вы откроете графики каждый в своём окошке, это нарушит весь расчёт, так как будут делиться неправильные свечки. Будет неинформативный бред.
    Два графика в одном окошке — это обязательно. Делается это так:
    Индикатор для парного трейдинга+рубле-бочка
    2. К верхнему графику надо прикрутить идентификатор. По умолчанию — это циферка 1. В коде индикатора я написал где этот параметр можно поменять. Если вы захотите размножить этого робота на разные пары инструментов, этот навык пригодится.
    Идентификатор вписывается на ВЕРХНЕМ графике вот здесь:
    Индикатор для парного трейдинга+рубле-бочка
    3.  Дальше надо положить индикатор в правильное место: в папку LuaIndicators. КВИК умеет читать индикаторы только из неё. Если этой папки у вас нет, создайте её в той папке, где лежит КВИК.
    После этого индикатор появится в общем списке индикаторов. На рисунке он виден с названием !Sintetika
    Дальше этот индикатор надо прикрутить к правильном графику. Этот выбор делается вверху окошка там где зелёный овал.
    Индикатор для парного трейдинга+рубле-бочка
    Индикатор прикручивается к ДРУГОМУ графику, не к тому, которому вы присвоили идентификатор. Если правой кнопкой мышки кликнуть по нижнему графику, то он и выберется. Но можно задать вручную как на картинке.
    4. Нужно правильно задать множитель. Фьючерс Си стоит 57 000, а доллар рубль 57 рублей. То есть верхнюю цену надо сократить на три ноля. Эту задачу и решает параметр umnozhenie. Его можно поменять прямо в коде, а можно в настройках индикатора. Вот здесь:
    Индикатор для парного трейдинга+рубле-бочка
    Для SBER/SBERP его надо исправить на 1. В этом случае нули сокращать не нужно. Если оставить как есть — 1000 — , то внизу будут неправильные цифры как показывает зелёная стрелка.
    5. Параметр umnozhenie для разных пар:
    Si/USD_TOM=1000
    ФьючGAZP/GAZP=100 (в 1 фьючерсе 100 единиц базового актива — акций)
    SBER/SBERP=1
    Для любых других пар акций тоже можно ставить 1.
    Вот несколько примеров этого индикатора на разных инструментах.
    1. Фьючерс Сбер-обычка против акции Сбер-обычка. Множитель 100. Фьючерс торгуется дешевле акции, потому что во фьючерсе нет дивидендов. Часовик.
    Индикатор для парного трейдинга+рубле-бочка
    На вечорке акции не торгуются, поэтому будет удобно отфильтровать вечорку и утренний аукцион вот здесь:
    Индикатор для парного трейдинга+рубле-бочка
    2. Фьючерс Си против спотового доллар-рубля. Минутки.
    Индикатор для парного трейдинга+рубле-бочка
    Пишите о результатах, постараюсь помочь. На забывайте:
    1. Два графика впихиваются в одно окно
    2. Идентификатор «1» прикрепляем к верхнему графику, а сам индикатор к нижнему.
    3. Не забывайте ставить верный множитель.
    Удачи :)

    П.С. Добавлю ещё один индикатор: рубле-бочка. Может оказаться полезным. Он делает то же самое, только формула чуть другая: он перемножает два значения: Си умножает на брент и делит на 1000. Скачать рубле-бочку.
    Индикатор для парного трейдинга+рубле-бочка


  23. Аватар Трейдер Вася
    Вопрос по QLua. У одного брокера хорошо работает с квиком, у другого не срабатывает флаг открытия сделки. Как исправить?

    Вопрос по QLua. У одного брокера хорошо работает с квиком, у другого не срабатывает флаг открытия сделки. Как исправить?
  24. Аватар Трейдер Вася
    Как в QLua узнать количество открытых позиций с помощью функции getParamEx?

    Как в QLua узнать количество открытых позиций с помощью функции getParamEx?
  25. Аватар gardist
    Скрипт на qlua - Светофор

    По следам этого поста скрипт на qlua, называется «Светофор».
    Суть скрипта- отслеживать дистанцию до «дна», которое представляет собой лои 2008 года+накопленная инфляция.

    Подсветка строк:
    зеленым- цена ниже уровня инфляции
    желтым — до дна менее 50%
    красным — до дна более 80%

    В чем не смог разобраться:
    как получить лой 2008 года по акции (вбито вручную)
    как получить полное название компаний (вбито вручную)
    как сортировать таблицу (ctrl+клик не помогает)
    кто знает — подскажите!

    Как это выглядит в Квике:
    Скрипт на qlua - Светофор
    Бэктест на проливе 2014 года:
    Скрипт на qlua - Светофор

    Код:

    -- Обьявляем переменные
    sIsRun=true;
    sDate=0;
    sDno=0;
    sDistance=0;
    
    --Инфляция 2009-2016
    sInflation=88.77; 
    
    -- Массив с названием компаний
    aTickerName= {"Сбербанк", "Газпром", "Лукойл", 
                    "ГМКНорНик", "Система", 
                    "Аэрофлот", "Роснефть", "Транснф",
                    "ФСК ЕС", "РусГидро", "СеверСталь", 
                    "Новатек", "Магнит", "Татнефть",
                    "Сургнфтз-п", "М.видео", "ИнтерРАО",
                    "НЛМК", "ММК", "Россети", 
                    "Ростел", "МТС", "Уркалий"}
    
    -- Массив с тикерами
    aTickerList = {"SBER", "GAZP", "LKOH",
                "GMKN", "AFKS",
                "AFLT", "ROSN", "TRNFP",
                "FEES", "HYDR", "CHMF",
                "NVTK", "MGNT", "TATN",
                "SNGSP", "MVID", "IRAO",
                "NLMK", "MAGN", "RSTI", 
                "RTKM", "MTSS", "URKA"};
    
    -- Массив с лоями 2008 года
    aTickerLow2008={14, 86, 740,
                1228, 4.5,
                20, 94, 6728,
                 0.054, 0.4, 80,
                50, 312, 32.63,
                 5.16, 24, 0.54,
                 20, 4.5, 0.6,
                14, 100, 25};
    
    function main()
            -- Создает таблицу
            CreateTable();
    
            -- Основной цикл
            while sIsRun do
                    -- Дата и время
                    sDate=getInfoParam('TRADEDATE').." "..getInfoParam('SERVERTIME');
                    -- Перебираем компании: k -порядковый номер, v - название тикера
                    for k,v in pairs(aTickerList) do
    
                       -- Крайняя цена
                       sBID=tonumber(getParamEx("TQBR", v, "LAST").param_value);
                       -- Расчетное дно
                       sDno=math.floor(((aTickerLow2008[k]*(sInflation+100))/100)*100)/100;
                       -- Сколько до дна %
                       sDistance=math.floor((100-((sDno*100)/sBID))*100)/100;
    
                       -- Вставляем данные в табличку
                       SetCell(t_id, k, 0, tostring(sDate));
                       SetCell(t_id, k, 1, tostring(aTickerName[k]));
                       SetCell(t_id, k, 2, tostring(v));
                       SetCell(t_id, k, 3, tostring(sBID));
                       SetCell(t_id, k, 4, tostring(sDno));
                       SetCell(t_id, k, 5, tostring(sDistance));
    
                      -- Раскрашиваем желтым
                       if sDistance<50 then 
                            Yellow(k);
                       end;
                      -- Раскрашиваем красным
                       if sDistance>80 then 
                            Red(k);
                       end;
                      -- Раскрашиваем зеленым
                       if sDistance<0 then 
                            Green(k);
                       end;
    
    
                    end;
    
                    -- Спим
                    sleep(50000);
            end;
    end;
    
    
    --- Функция создает таблицу
    function CreateTable()
            -- Получает доступный id для создания
            t_id = AllocTable();    
            -- Добавляет 6 колонок
            AddColumn(t_id, 0, "Дата", true, QTABLE_INT_TYPE, 15);
            AddColumn(t_id, 1, "Название", true, QTABLE_INT_TYPE, 15);
            AddColumn(t_id, 2, "Ticker", true, QTABLE_INT_TYPE, 15);
            AddColumn(t_id, 3, "BID", true, QTABLE_INT_TYPE, 15);
            AddColumn(t_id, 4, "Расчетное дно", true, QTABLE_INT_TYPE, 15);
            AddColumn(t_id, 5, "Сколько до дна (%)", true, QTABLE_INT_TYPE, 15);
            -- Создаем
            t = CreateWindow(t_id);
            -- Даем заголовок       
            SetWindowCaption(t_id, "Компании");
       -- Добавляет строку
          for k,v in pairs(aTickerList) do
            InsertRow(t_id, k);
          end
    end;
    
    --- Функции по раскраске ячеек таблицы
    function Red(col)
     for i=0, 5 do
            SetColor(t_id, col, i, RGB(255,168,164), RGB(0,0,0), RGB(255,168,164), RGB(0,0,0));
     end;
    end;
    function Green(col)
     for i=0, 5 do
            SetColor(t_id, col, i, RGB(157,241,163), RGB(0,0,0), RGB(157,241,163), RGB(0,0,0));
     end;
    end;
    function Yellow(col)
     for i=0, 5 do
            SetColor(t_id, col, i, RGB(249,247,172), RGB(0,0,0), RGB(249,247,172), RGB(0,0,0));
     end;
    end;
    
    -- Функция вызывается когда пользователь останавливает скрипт
    function OnStop()
       sIsRun = false;
    end;
    


    ссылка на скрипт
     
    P.S.: не является рекомендацией к покупке/продаже акций, использование программы на ваш страх и риск.

    Кросспост rffx.ru


Чтобы купить акции, выберите надежного брокера: