Избранное трейдера Максим
Предлагаю вашему вниманию пробный пост о применении data mining к текстам, спарсенным из блогов Смартлаба.
Идея исследования: ежемесячно парсить все посты со Смартлаба и применять к ним метод BigARTM из класса методов тематического моделирования.
Методы тематического моделирования (детальное описание: Воронцов К.В. Вероятностное тематическое моделирование: обзор моделей и аддитивная регуляризация) позволяют группировать слова («термы», «токены») из множества документов по темам.
Интерпретация тем – дело исследователя. К сожалению, не всегда удаётся проинтерпретировать набор слов, т.е. по этому набору назвать тему. Я буду приводить как наборы слов по темам, так и мою интерпретацию тем. Вы же при желании сможете дать свою интерпретацию.
В дальнейшем – при накоплении статистики – можно искать связи между событиями и их отражением или не отражением в виде постов на Смартлабе.
В октябре 2018 на смартлабе было опубликовано свыше 4000 постов.
Друзья, приветствую.
Те, кто следит за моей лентой, помнят, что ещё недавно я бился с возвратом НДФЛ по ИИС за 2017 год. Подробности можно найти по ссылкам ниже. Чудо произошло и «НДФЛ» мне упал на счёт 9.11.2018.
Сегодня я хочу опубликовать мой результат инвестиций с учетом взносов (которые кстати поступали неравномерно на мой счёт ИИС), по аналогии с прошлогодней публикацией.
Итак, общая доходность инвестиций за период с 03.11.2016 по 09.11.2018 составила 28,7%, что эквивалентно 13,3% годовых.
На мой взгляд – это отличный результат по нескольким причинам:
ТС(t) или Торговая система (t) - это свод правил и условий совершения трейдером тех или иных торговых операций на финансовом рынке, например продажи или покупки фьючерса US500 на срочном рынке Московской биржи (МОЕХ). А о том, что означает (t) — можно будет узнать в конце этого поста …
Добавили тут на днях в ТСЛаб возможность штатным образом случайные числа получать. В связи с чем возникла идея устроить небольшой стресс тест стратегиям, заменив имеющееся управление позицией выходом по рынку через случайное количество баров.
Я считаю, что то, что принято называть переоптимизацией, кроется как раз в управлении позицией. Если подумать, то в точке входа подгонки не может быть по определению. Ведь задача как раз найти такое соотношение параметров, которое работает в нашу сторону как можно чаще. И чем сильнее будет подгонка под идеальный сетап — тем лучше, тем точнее мы опишем желаемую ситуацию. А вот с выходом всё иначе. Тут уже есть конкретные точки входа и конкретный набор свечей на истории… И вот как раз тут может быть подгонка параметров стопа, тейка, трейлинга и т.п. под эти конкретные ситуации..
Подгонка может быть столь сильной, что за ней вполне может спрятаться полное отсутствие положительного смещения вероятности в точке входа…
Вот мне и стало интересно, что если выход из позиции будет произвольным? Тогда, по идее, значительный перевес положительных исходов может намекать на наличие положительного смещения вероятности в точке входа.
Для эксперимента взял 2 стратегии на Ri. Одна, проверенная девятью месяцами реала и подтвердившая свою профпригодность на сегодняшний день, и другая — простая, состряпанная на скорую руку, стратегия по скользяшкам с максимальным фиттингом (оптимизация точки входа одновременно с трейлингом по широкому диапазону параметров на всей истории за один проход). Везде стоит комиссия 20п.
Итак, изначальная эквити «проверенной» стратегии выглядит так:
Очень часто люди не могут найти действенную торговую стратегию, которая бы работала на большинстве рынков и была бы эффективна длительное время. Трейдерские форумы заполнены поисками торгового “Грааля”, многие разрабатывают сверхсложные схемы, изучают теорию хаоса или теорию нечетких множеств. Как мне кажется, все гораздо проще и ниже я хотел бы привести пример такой стратегии. Этой стратегией я пользуюсь уже несколько лет и на собственном торговом опыте убедился в ее стабильной прибыльности. Казалось бы, какой смысл мне делиться информацией подобного рода? Ведь если все будут пользоваться этой стратегией, то она неизбежно потеряет большую часть своей прибыльности или даже будет приносить убыток? На самом деле, конечно, не все так просто. Я абсолютно уверен, что даже после того, как данная стратегия будет описана, большинство людей не будут ей пользоваться, а те, кто решится на ее использование, не сможет торговать на ее основе, прежде всего, из-за элементарного отсутствия дисциплины. Итак, заканчиваю введение и перехожу непосредственно к конкретике. Моя торговая стратегия базируется на следующих трех принципах:
Settings = { Name = "GAZPROM_USD", tag = "GAZP", tag1 = "GAZP_USDRUB", line= { {Name = "line1", Color = RGB(0, 0, 255), Type = 1,Width = 1} } } vPrice=1; function Init() return 1 end function OnCalculate(index) local vOutFlag=0; local vGazp =(getCandlesByIndex(Settings.tag, 0, index-1, 1)[0].close or 1) ; local vUSDRUB=(getCandlesByIndex(Settings.tag1, 0, index-1, 1)[0].close or 1); if vGazp>0 then vOutFlag=1; else vOutFlag=0; end; if vUSDRUB>0 then vOutFlag=1; else vOutFlag=0; end; if vOutFlag > 0 then local Out = vGazp/vUSDRUB; vPrice=Out; end; return vPrice end3. В Квике создаем график с курсом доллара (USDRUB_TOM).
--переменные 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