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


Некоторое время назад после подробного обсуждения с коллегами вопроса "Нормален ли рынок и если ненормален, то какой он на самом деле?" от других коллег прозвучало недоумение: "А зачем тебе копаться в этих дебрях? Какой в этом смысл?". Короткий ответ будет неполным, а полный ответ с примерами и философским вопросом может оказаться интересен (или даже полезен коллегам).
Как работает научное мышление: необходимо не просто запомнить формулу (зачастую даже собственно запоминание формулы даже не является целью изучения вопроса). Фокус будет находиться на методе получения этой формулы. Причем должны быть абсолютно прояснены все подробности: почему? откуда это следует? какие есть ограничения? и т.д.
В этом видео уроке мы продолжим изучать программу optionworkshop, поговорим о роллировании позиции и определим, сколько нам принесла наша позиция.
Видео урок 1 — тут
Видео урок 2 — тут
В этой статье я хочу рассказать об одной стратегии парного трейдинга и торговом роботе MultiConnect с помощью которого наши друзья и партнеры «ФК Викинг» активно торгуют арбитражные стратегии на Санкт-Петербургской Бирже.
Парный трейдинг и статистический арбитраж зародился в Америке в шестидесятых годах прошлого века, сначала такой принцип торговли был доступен ограниченному кругу трейдеров, пришедших в этот бизнес с кафедр математических университетов. С помощью статарбитража сколачивались огромные состояния, открывались транснациональные хедж фонды. Во многом электронная биржевая торговля, какой мы видим ее сейчас, обязана статистическому арбитражу. Об этих временах и нравах на Уолл-стрит, о зарождении, взлетах и падениях некоторых хеджфондов очень интересно написал Скотт Паттерсон в своей книге «Кванты» https://smart-lab.ru/books/kvanty-patterson/.
В основе нашей стратегии также лежит идея торговли акциями друг против друга – т.е. когда мы покупаем одну компанию, одновременно продаем другую, торгуем спред акций. По сути, создается синтетический инструмент, который менее подвержен трендовым движениям, стремится к паритету. Были отобраны акции одного сектора, банковского – JP MorganChase (JPM) и Bank of Amerika (BAC). Компании фундаментально схожи между собой, два крупнейших банка, воздействие на сектор вызывает движение в обеих бумагах, что обеспечивает приемлемые риски, но при этом мы ловим расхождения в цене, вызванные факторами, воздействующими лишь на одну из компаний или рыночными неэффективностями. При этом есть одна интересная идея – торговать через Санкт-Петербургскую Биржу, где торги начинаются с 10 утра по Москве и продолжаются до закрытия постмаркета в Америке. Это позволяет ловить ценовые неэффективности до того, как подключатся американские «коллеги» — зачастую утром выходит отчетность и появляются новости, напрямую влияющие как на отдельно взятую компанию, так и на весь рынок в целом. Комиссии на СПБирже более чем конкурентны: 0.01 процент от суммы сделки, что дает возможность торговать пары акций с небольшим шагом спреда между этими бумагами.

--переменные
keyRateCB = 7.5
classCode = "TQOB"
function CreateTable()
t_id = AllocTable()
AddColumn(t_id, 0, "Бумага", true, QTABLE_STRING_TYPE, 15)
AddColumn(t_id, 1, "Цена", true, QTABLE_DOUBLE_TYPE, 15)
AddColumn(t_id, 2, "Доходность, %", true, QTABLE_DOUBLE_TYPE, 15)
AddColumn(t_id, 3, "Дюрация, лет", true, QTABLE_DOUBLE_TYPE, 15)
AddColumn(t_id, 4, "Купон, %", true, QTABLE_DOUBLE_TYPE, 15)
AddColumn(t_id, 5, "Премия к ЦБ, бп", true, QTABLE_INT_TYPE, 15)
AddColumn(t_id, 6, "Погашение", true, QTABLE_STRING_TYPE, 15)
t = CreateWindow(t_id)
SetWindowCaption(t_id, "ОФЗ")
end
function string.split(str, sep)
local fields = {}
str:gsub(string.format("([^%s]+)", sep), function(f_c) fields[#fields + 1] = f_c end)
return fields
end
function getParamNumber(code, param)
return tonumber(getParamEx(classCode, code, param).param_value)
end
function formatData(prm)
return string.format("%02d.%02d.%04d", prm%100, (prm%10000)/100, prm/10000)
end
CreateTable()
arr = {}
sec_list = getClassSecurities(classCode)
sec_listTable = string.split(sec_list, ',')
j = 0
for i = 1, #sec_listTable do
secCode = sec_listTable[i]
securityInfo = getSecurityInfo(classCode, secCode)
short_name = securityInfo.short_name
if short_name:find("ОФЗ 26") ~= nil then
j = j + 1
r = {}
r["short_name"] = short_name
r["price"] = getParamNumber(securityInfo.code, "PREVPRICE")
r["yield"] = getParamNumber(securityInfo.code, "YIELD")
r["duration"] = getParamNumber(securityInfo.code, "DURATION")/365
couponvalue = getParamNumber(securityInfo.code, "COUPONVALUE")
couponperiod = getParamNumber(securityInfo.code, "COUPONPERIOD")
r["coupon"] = ((365/couponperiod) * couponvalue)/10
r["bonus"] = (r["yield"] - keyRateCB)*100
r["mat_date"] = getParamNumber(securityInfo.code, "MAT_DATE")
table.insert(arr, j, r)
end
end
table.sort(arr, function(a,b) return a["duration"] < b["duration"] end)
for j = 1, #arr do
row = InsertRow(t_id, -1)
SetCell(t_id, row, 0, arr[j]["short_name"])
price = arr[j]["price"]
SetCell(t_id, row, 1, string.format("%.2f", price), price)
yield = arr[j]["yield"]
SetCell(t_id, row, 2, string.format("%.2f", yield), yield)
duration = arr[j]["duration"]
SetCell(t_id, row, 3, string.format("%.2f", duration), duration)
coupon = arr[j]["coupon"]
SetCell(t_id, row, 4, string.format("%.2f", coupon), coupon)
bonus = arr[j]["bonus"]
SetCell(t_id, row, 5, string.format("%.0f", bonus), bonus)
mat_date = arr[j]["mat_date"]
SetCell(t_id, row, 6, formatData(mat_date), mat_date)
end
