Избранное трейдера chuikapridi
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
Настало время оптимизации алгоритма «Парного трейдинга». Прошлые наблюдения давали много ложных сигналов. Сократить их помогут скользящие средние. Мы построим z-оценку по спреду цен пары, сглаженному скользящими средними. Бэктестинг будем проводить в Quantopian, а весь код напишем на Python.
Рассмотрим разницу сигналов по z-оценке:
Опубликовал первую часть библиотеки для количественных трейдеров.
Первая версия простая, умеет рассчитывать кривую капитала по историческим сделкам, подключаться к источникам данных, учитывать комиссии при торговле на фондовой и срочной секции Московской биржи.
https://github.com/robostock/quantlibrary
Цели: добавить модуль расчета модельных портфелей по Марковицу и Блэку-Литерману, добавить инструменты машинного обучения.
Задача этого маленького проекта – создать маленькую библиотеку с открытым исходным кодом, в которой несложно разобраться с алгоритмом работы.
Все желающие могут присоединиться к проекту и внести свой вклад в уже написанный код или добавить собственные идеи.
P.S: Код доступен для использования в личных целях. В случае публикации обновлений библиотеки обязательна ссылка на первоисточник.
Использование кода в коммерческих целях запрещено
которым пользуюсь. Принцип торговли многим уже известный – парный трейдинг.
Активно торгую с августа-сентября 2016 года. Сумма на старте 150 тысяч примерно. Сейчас примерно 250-260 тысяч. А теперь обо всем по порядку.
Идея торговать на фондовом рынке возникла с конца 2015 года, когда полностью разочаровался с торговле на валютном рынке. Фондовый рынок и его относительно неплохое регулирование в нынешнее время сильно манило. На тот момент ничего не понимая как торговать на фондовом рынке, я начал изучать различного рода подходы к анализу и т.д. и т.п. Весь материал лежит на поверхности. Спустя пару месяцев обратил внимание на парный трейдинг, как на один из видов статистического арбитража. По парному трейдингу масса теории, даже проф.иностранной литературы от таких известных издательств как Wiley Finance. После недели использования Excel, я понял, что можно существуют хорошо коррелированные пары активов на бирже, которыми и можно торговать.
А вот далее самое интересное. Я сразу понял, что торговать всем этим вручную будет невозможно, да и лениво. Я начал искать уже созданное программное обеспечение для торговли. На рынке есть много интересных продуктов. Но по ряду причин я остановил свое внимание на продукте от компании Saturn Capital. Интерфейс программы дружелюбный и не требует долгих настроек. А самое главное – профессиональная команда разработчиков помогла мне поставить программу на компьютер, настроить и первое время сопровождать торговлю. Это помогло.
Статья с сайта www.miltonfmr.com, из которой можно взять некоторые приемы, пригодные даже для использования в высокочастотной торговле.
Многие трейдеры, создающие и правильно применяющие торговые системы с возвратом к среднему, получают хорошую прибыль. Факты говорят о том, что рынки двигаются в соответствии с паттернами, одним из которых является цикличность. Простыми словами, все, что двигалось вверх, должно пойти вниз и наоборот. Ничто не движется в одном направлении вечно. Применительно к рынкам, у нас есть два возможных исхода — тренд, либо определенный торговый диапазон с возвратом к среднему. В прошлых наших исследованиях было показано, что гэп на открытии определяет тренд на остаток дня в 30% случаев. Это значит что из 20 торговых дней мы имеем 6 трендовых дней без возврата к среднему. С другой стороны у нас есть 70% движения цены, которая имеет тенденцию к возврату к среднему значению несколько раз за день. Важно отметить, что эти 70% относятся к внутридневному движению цен.
Работаем с площадью. Алгоритм на WelathLab
Когда на графике куча скользяшек, складывается впечатление, что система держится на соплях и долго не протянет. Поэтому давно начал думать о каких-то универсальных индикаторах, которые бы измеряли сразу много параметров рынка.
Первое, что пришло в голову – это использовать площади на графике. Изначально идея была такой:
По задумке получившееся значение должно было отражать глубину рынка, то есть насколько сильно ходит рынок от локального хая/лоя до хая/лоя внутри дня. Если же мы добавим сюда время (за сколько рынок сходил), то получим индикатор флэта (маленькое значение + большой временной промежуток). По ходу построения индикатора возникали мысли о том, что всё это можно реализовать гораздо проще, и действительно – можно.