Избранное трейдера chuikapridi

по

Код робота на 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
  • обсудить на форуме:
  • Quik Lua

Бэктестинг: парный трейдинг по сглаженным сигналам

Настало время оптимизации алгоритма «Парного трейдинга». Прошлые наблюдения давали много ложных сигналов. Сократить их помогут скользящие средние. Мы построим z-оценку по спреду цен пары, сглаженному скользящими средними. Бэктестинг будем проводить в Quantopian, а весь код напишем на Python.

Рассмотрим разницу сигналов по z-оценке:

  • Спред цен.
  • Спред доходности.
  • Скользящие средние на спреде цен.
  • Скользящие средние на спреде доходности.


( Читать дальше )

quantlib

Опубликовал первую часть библиотеки для количественных трейдеров.

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

https://github.com/robostock/quantlibrary

Цели: добавить модуль расчета модельных портфелей по Марковицу и Блэку-Литерману, добавить инструменты машинного обучения.

Задача этого маленького проекта – создать маленькую библиотеку с открытым исходным кодом, в которой несложно разобраться с алгоритмом работы.

Все желающие могут присоединиться к проекту и внести свой вклад в уже написанный код или добавить собственные идеи.

 

P.S: Код доступен для использования в личных целях. В случае публикации обновлений библиотеки обязательна ссылка на первоисточник.

Использование кода в коммерческих целях запрещено


Парный трейдинг

    • 26 июня 2017, 10:44
    • |
    • Mansiy
  • Еще

которым пользуюсь. Принцип торговли многим уже известный – парный трейдинг.

Активно торгую с августа-сентября 2016 года. Сумма на старте 150 тысяч примерно. Сейчас примерно 250-260 тысяч. А теперь обо всем по порядку.

 

Идея торговать на фондовом рынке возникла с конца 2015 года, когда полностью разочаровался с торговле на валютном рынке. Фондовый рынок и его относительно неплохое регулирование в нынешнее время сильно манило. На тот момент ничего не понимая как торговать на фондовом рынке, я начал изучать различного рода подходы к анализу и т.д. и т.п. Весь материал лежит на поверхности. Спустя пару месяцев обратил внимание на парный трейдинг, как на один из видов статистического арбитража. По парному трейдингу масса теории, даже проф.иностранной литературы от таких известных издательств как Wiley Finance. После недели использования Excel, я понял, что можно существуют хорошо коррелированные пары активов на бирже, которыми и можно торговать.

 

А вот далее самое интересное. Я сразу понял, что торговать всем этим вручную будет невозможно, да и лениво. Я начал искать уже созданное программное обеспечение для торговли. На рынке есть много интересных продуктов. Но по ряду причин я остановил свое внимание на продукте от компании Saturn Capital. Интерфейс программы дружелюбный и не требует долгих настроек. А самое главное – профессиональная команда разработчиков помогла мне поставить программу на компьютер, настроить и первое время сопровождать торговлю. Это помогло.



( Читать дальше )

Торговая система с возвратом к среднему

Торговая система с возвратом к среднему

Статья с сайта www.miltonfmr.com, из которой можно взять некоторые приемы, пригодные даже для использования в высокочастотной торговле.

Многие трейдеры, создающие и правильно применяющие торговые системы с возвратом к среднему, получают хорошую прибыль. Факты говорят о том, что рынки двигаются в соответствии с паттернами, одним из которых является цикличность. Простыми словами, все, что двигалось вверх, должно пойти вниз и наоборот. Ничто не движется в одном направлении вечно. Применительно к рынкам, у нас есть два возможных исхода — тренд, либо определенный торговый диапазон с возвратом к среднему. В прошлых наших исследованиях было показано, что гэп на открытии определяет тренд на остаток дня в 30% случаев. Это значит что из 20 торговых дней мы имеем 6 трендовых дней без возврата к среднему. С другой стороны у нас есть 70% движения цены, которая имеет тенденцию к возврату к среднему значению несколько раз за день. Важно отметить, что эти 70% относятся к внутридневному движению цен.



( Читать дальше )

Работаем с площадью. Алгоритм на WelathLab

Работаем с площадью. Алгоритм на WelathLab
Работаем с площадью. Алгоритм на WelathLab


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

Первое, что пришло в голову – это использовать площади на графике. Изначально идея была такой:

  1. Строим кривую по хаям и по лоям
  2. С помощью интерполяции находим промежуточные значения нашей кривой для большей точности.
  3. Аппроксимировать получившуюся кривую.
  4. Взять интеграл от получившейся в третьем шаге функции.

По задумке получившееся значение должно было отражать глубину рынка, то есть насколько сильно ходит рынок от локального хая/лоя до хая/лоя внутри дня. Если же мы добавим сюда время (за сколько рынок сходил), то получим индикатор флэта (маленькое значение + большой временной промежуток).  По ходу построения индикатора возникали мысли о том, что всё это можно реализовать гораздо проще, и действительно – можно.
Работаем с площадью. Алгоритм на WelathLab



( Читать дальше )

Простейшая стратегия 2MA — наоборот

Погонял намедни простейшие скрипты в ТСЛабе: пересечение двух скользящих средних (с парой прикруток, но основной алгоритм классический), и вот таки шо получилось (гонял фьюч сбера за последний год).
Если, как и положено по книжкам, покупать когда быстрая МА пересекает медленную снизу, и шортить наоборот, то получается вот так.

Простейшая стратегия 2MA — наоборот

Если же пойти в обратку, то есть покупать там где сингал шорт, и шортовать при сигнале «лонг», то вот так:

Простейшая стратегия 2MA — наоборот

( Читать дальше )

Майним Эфириум

Майним Эфириум
На волне хайпа вокруг криптовалют заинтересовался майнингом и решил наконец попробовать себя в этом деле.

Биткоин отпал сразу т. к. для его добычи нужны специализированные ASIC-и, заточенные под алгоритм SHA-256 или Scrypt.

Вторая по популярности криптовалюта — это Ethereum, для её майнинга используются более сложные алгоритмы, чем для биткойна, поэтому с помощью ASIC-ов её майнить невозможно, а значит майнинг на GPU более рационален.

Прежде чем начинать майнинг, нужно убедиться в прибыльности этого процесса. Идём на страницу Etherium Mining Profitability Calculator, выбираем валюту, задаём характеристики своей видеокарты и смотрим расчётный профит от поиска хэшей. Оценить производительность некоторых видеокарт в добыче эфира можно в статье Ethereum Mining GPU Performance Roundup. Вкратце:

1) Майнить лучше на видеокартах AMD, нежели NVidia.

( Читать дальше )

Работает ли математика на бирже? Итоги публичной торговли за 3,5 года

Существует много споров о том, работает ли математика в трейдинге или нет? Можно ли, опираясь на исторические данные о рынке, стабильно зарабатывать деньги на бирже? Моя реальность и мои факты говорят о том, что это возможно, кто бы что там ни рассуждал, водя вилами по воде. Выкладываю результаты торговли своих роботов, которые являются этому доказательством. Не тесты, а именно реальные результаты, подтвержденные брокером. Решение — запускать стратегию в работу или нет, как раз принимается на основании тестов на истории. Можно ли сказать, что 42 месяца статистики — это случайный результат или все таки есть какая то закономерность на рынках с положительным математическим ожиданием? Что это, ошибка выжившего или мнение одураченного случайностью управляющего? Решать вам.

Хаос — это высшая форма порядка. И случайный характер рынка не говорит, о том, что на нем нельзя зарабатывать. 

Итак, прошло ровно 3,5 года или 42 месяца с начала запуска публичной торговли на портале comon.ru. За этот период портфель торговых роботов заработал инвесторам +222,5% с учетом капитализации процентов. За всю историю максимальная просадка в моменте составляла 23%. Плюс к этому облигации приносят ежегодно около 5% в год. Май выдался удачным и ударным месяцем, благодаря росту волатильности на нашем фондовом рынке роботы наколотили +10,2%. И с начала 2017 года доходность составила +21,3% за 5 месяцев.

( Читать дальше )

....все тэги
UPDONW
Новый дизайн