Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 99 сообщений
Cообщения с меткой

торговые стратегии - Самое интересное в блогах

Следующие 30  »
tanuuusa

Заработок на бинарных опционах 2016

Суббота, 21 Мая 2016 г. 11:53 (ссылка)


опционы10 (300x84, 1Kb)



Многих давно интересует вопрос о том, возможно ли заработать в интернете. Некоторые даже пытаются это сделать, но получается заработать реальные деньги далеко не у каждого. А бывает так, что поверят в очередной лохотрон — отнесут им свои кровно заработанные рублики — и плакали эти денежки горькими слезами. Нельзя всем верить безоговорочно. В интернете любят разводить на деньги доверчивых товарищей. И надо помнить, что "легких денег не бывает"! Не стоит забывать и о бесплатном сыре в мышеловке.



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



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



Обязательно посмотрите ролик, где успешный бизнесмен Максим Акелов делится своими полезными знаниями.







Не стоит верить и сайтам-лохотронам, которые обещают, что всё якобы просто:"Вверх— вниз...и всё, деньги рекой потекут к Вам". Это не казино, чтобы угадать. Это реальный валютный рынок. Без определенных знаний, например, тут делать нечего. Если Вы будете знать и понимать , что такое  бинарные опционы стратегия , бинарные опционы на автомате и другие моменты, тогда можно смело начинать зарабатывать.



Есть еще такой важный момент, надо уяснить, что сначала необходимо сделать вложения. И не вкладывать последние копейки, над которыми Вы будете постоянно трястись...Не надо. И со 100 долларами тут делать нечего. С Вас просто их вытрясут и всё — на этом Ваши попытки разбогатеть бесславно закончатся. Самый надежный старт начинается с тысячи долларов и тогда флаг Вам в руки! Успехов всем в интересном и самом доходном виде заработка в интернете! 



Комментарии (6)КомментироватьВ цитатник или сообщество
Оделайна

Зарабатываем, сидя дома, на бинарных опционах

Пятница, 20 Мая 2016 г. 21:37 (ссылка)


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





Существует большое, точнее, огромное количество способов, которые могут, в ускоренном режиме, изменить в лучшую сторону своё материальное положение. Нужно просто знать конкретные сайты в интернете, а также некоторые стратегические тонкости. Так, например, есть бинарные опционы, которые являются на сегодня один из самых продвинутым способов заработка. Но чтобы дело на этом поприще пошло удачно, неплохо бы пройти обучение торговле на бинарных опционах. Но только у того наставника, который в этом деле является профессионалом.







Пройдя курс обучения, вы уже сможете разбираться во всех нюансах, которые касаются к данному виду заработка. После чего можно с успехом избежать «подводных камней», которые встретятся на вашем пути. Ведь, как свидетельствует опыт, в таком деле, как бинарные опционы, стратегия, правильно и своевременно выбранная, решает многое. После обучения с этим делом будет справиться легко.



Комментарии (1)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Машинное обучение: что нужно знать о создании стратегий для торговли на бирже. Часть IV

Четверг, 14 Апреля 2016 г. 15:07 (ссылка)





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



Сегодня же речь пойдет об использовании для этих целей технологий дата майнинга и машинного обучения.



В 1996 году компьютер Deep Blue впервые победил чемпиона мира по шахматам. Прошло еще 20 лет и программа AlphaGo победила в серии с лучшим игроком в Го, уступив лишь одну игру. Deep Blue представлял собой модель-ориентированную систему с жестким набором шахматных правил. AlphaGo же использует технологии Data Mining. Это нейронная сеть, обученная на примерах тысячи партий Го. В отличие от шахмат, в этой игре пространство выбора вариантов настолько огромно, что простой перебор не поможет. Поэтому прорыв произошел не за счет совершенствования «железа», а исключительно благодаря новому софту.



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



Принципы машинного обучения



В основе обучающего алгоритма заложена концепция шаблонов. Обычно это исторические данные о ценах. Каждый шаблон состоит из n переменных x1… xn, обычно называемых маркерами предсказания (предикторами) или просто параметрами. В качестве таких предикторов могут выступать ценовой возврат последних n-делений или набор классических индикаторов, а также любые другие функции кривой цен. Каждый шаблон включает целевую величину y — например, прибыль следующей сделки после применения шаблона или следующее движение цены. В процессе обучения алгоритм узнает, как получить целевую величину, основываясь на предикторах. Это знание хранится в структуре данных, именуемой в нашем случае моделью, индивидуальной для каждого алгоритма. Эта модель может быть функцией языка C, описывающей правила прогнозирования, выработанные в процессе обучения. Или это может быть набор соединений в нейронной сети.



Обучение:  x1… xn, y  =>  модель

Предсказание:  x1… xn, модель  =>  y


Предикторы должны аккуратно обрабатывать информацию, которая необходима для предсказания целевой величины. Они обязаны отвечать двум формальным условиям: все значения этих маркеров должны быть одного порядка (например, -1… +1 для алгоритмов на R или -100… +100 для алгоритмов на языке Zorro). Это значит, что до отправки торговому «движку» их нужно нормализовать. Во-вторых, шаблоны должны быть сбалансированы, то есть равномерно распределены по всем значениям целевой величины. Шаблонов, описывающих выигрышный вариант, должно быть столько же, сколько и проигрышный.



Регрессивные алгоритмы предсказывают числовые значения, такие как величина следующего изменения цены. Классификационные алгоритмы генерируют класс качественных шаблонов. Например, связанных с прибылью или убытком. Ряд алгоритмов нейронных сетей или опорных векторов могут одновременно работать в обеих версиях. Некоторые алгоритмы не нуждаются в целевой величине для разделения шаблонов на классы. Это так называемое обучение без учителя (unsupervised learning), в отличие от обычного с учителем (supervised learning).



Какие бы сигналы мы не использовали в качестве маркеров предсказания в сфере финансов, большинство из них будет содержать много шума и мало полезной информации. Поэтому финансовое прогнозирование – самая сложная задача в машинном обучении. Более сложные алгоритмы не всегда дают более качественный результат. Для конечного успеха критичным является выбор предикторов. На этот случай в стратегии интеллектуального анализа предусмотрен алгоритм предварительного отбора, который выбирает несколько полезных маркеров предсказаний из множества вариантов. Этот отбор может проходить на основе их корреляции, значимости или просто берутся те, что прошли тест.



Далее мы поговорим о наиболее популярных методиках интеллектуального анализа, используемых в мире финансов.



Метод проб и ошибок



Большинство торговых систем, которые компания автора блога Financial Hacker разрабатывает для своих клиентов, изначально основаны не на финансовой модели. Заказчик хочет получать сигналы для совершения транзакций, опирающиеся на конкретные технические индикаторы, фильтруемые через индикаторы с использованием еще большего числа технических индикаторов. Обычно, никто толком не может ответить на вопрос о том, как это месиво индикаторов может являться рабочей стратегией. Ответ, как правило, такой: «Просто поверьте. Я так вручную торгую уже много лет, и все работает».



На самом деле, все так и есть. По крайней мере, в некоторых случаях. Хотя многие эти системы не были прошли форвардный анализ (некоторые — даже элементарный бэктест), большинство неплохо справляется со своими задачами. Клиент систематически экспериментирует с техническими индикаторами, пока не найдет нужную комбинацию, которая работает на реальном рынке с выбранными активами. Метод проб и ошибок – это классический вариант интеллектуального анализа. Просто он производится человеком, а не машиной. Иногда это дает хороший результат.



Свечные паттерны



Нет смысла останавливаться на разборе устаревших методик, типа японских свечных паттернов, которые были популярны 200 лет назад. Современный эквивалент свечных паттернов – это безиндикаторный анализ price action. В нем трейдеры все еще пытаются найти паттерн, предсказывающий движение цены. Но в данном случае они анализируют современные ценовые кривые. Для этой цели существует набор специальных программ. Они подбирают подходящие паттерны по заложенным пользователем критериям и используют их для построения функции. В системе Zorro это может выглядеть так:



int detect(double* sig)
{
if(sig[1]code>


Функция C делает возврат 1, когда сигнал соответствует одному из паттернов. В ином случае значение – 0. По этому коду можно видеть, что это не самый быстрый путь поиска паттернов. Альтернативный вариант – вначале сортировать сигналы по их значению, затем проверять порядок сортировки.



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



Линейная регрессия



Смысл работы большинство сложных алгоритмов машинного обучения прост: нужно предсказать переменную целевую величину y через линейную комбинацию предикторов x1 … xn.



image



Коэффициент an рассчитывается для минимизации суммы квадратов различий между истинным значением y обучающего шаблона и предсказываемыми значениями y по следующей формуле:



image



Для нормального распределения шаблонов минимизация возможна через математическую матрицу, поэтому никакой итерации не требуется. В случае n = 1 с одной переменной предиктора x формула регрессии упрощается до:



image



Это является простой линейной регрессией. Она применяется на большинстве торговых платформ. Если y = цена, а x = время, то она часто используется как альтернатива скользящим средним. Есть еще полиноминальная регрессия, когда все еще есть один предиктор x, но есть и x2 и в более высокой степени. Таким образом, xn == xn.



image



Перцепция



Нередко этот метод рассматривают как нейронную сеть с одним нейроном. На самом деле перцепция – это та же функция регрессии, которую мы рассмотрели выше. Но с двоичным результатом. Поэтому ее еще называют логической регрессией. Хотя, по сути, это алгоритм классификации. Функция advise(PERCEPTRON, …) в Zorro генерирует C-код, делающий возврат 100 или -100, в зависимости от того, расположен ли предсказанный результат в рамках или за рамками установленного порога.



int predict(double* sig)
{
if(-27.99*sig[0] + 1.24*sig[1] - 3.54*sig[2] > -21.50)
return 100;
else
return -100;
}


В этом фрагменте видно, что массив sig эквивалентен нашим маркерам предсказания xn в формуле регрессии, а числовые множители – это коэффициенты an.



Нейронные сети



Линейная или логическая регрессия может решить лишь линейные проблемы. Многие просто не работают с такой категорией вопросов. Искусственная нейронная сеть (ИНС) призвана решать нелинейные проблемы. Она представляет собой пучок перцептронов, соединенных в набор слоев. Каждый из них является нейроном сети. Вот как выглядят инпуты и аутпуты такой сети:



image



Нейронная сеть обучается через распознавание коэффициента, который бы минимизировал расхождение между шаблоном предсказания и шаблоном цели. Но теперь нам нужно задействовать еще и процесс аппроксимации. Обычно он применяется вместе с методом обратного распространения ошибки от входных данных к выходным, по пути оптимизируя нагрузку.



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



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




  • число скрытых слоев;

  • число нейронов для каждого скрытого слоя;

  • число циклов обратного распространения, или эпох;

  • скорость обучения, ширина шага одной эпохи;

  • моментум;

  • функция активации.



Функция активации имитирует порог перцептора. Для обратного распространения ошибки нужна непрерывно дифференцируемая функция, которая генерирует «мягкий» шаг на определенное значение x. Для этого обычно используются функции sigmoidtanh, или softmax. В нашем примере функция может быть использована для регрессии и предсказания числовых значений вместо двоичного выхода.



Глубокое обучение



Если речь идет о множестве скрытых слоев и тысячах нейронов, то это уже глубокое обучение. Здесь стандартное обратное распространение не работает. В последние несколько лет появились несколько популярных методик обучения такой огромной системы. Обычно они включают этап пред-обучения скрытых слоев для достижения нужного эффекта. Один из вариантов – машина Больцмана – неконтролируемый классифицирующий алгоритм со специальной структурой сети, где отсутствуют соединения между скрытыми нейронами. Разреженный автокодировщик (Sparse Autoencoder) – другой вариант, он использует стандартную структуру сети и предобучает скрытые слои через воспроизводство сигналов инпута для аутпута слоев с минимальным, насколько это возможно, количеством активных соединений. Такие методы уже позволяют решать серьезные задачи. Ну, например, побеждать лучшего в мире игрока в го.



Ниже пример скрипта на R, использующий автокодировщик с тремя скрытыми слоями для определения сигналов трейдинга с помощью функции neural() пакета Zorro:



library('deepnet', quietly = T) 
library('caret', quietly = T)

# called by Zorro for training
neural.train = function(model,XY)
{
XY <- as.matrix(XY)
X <- XY[,-ncol(XY)] # predictors
Y <- XY[,ncol(XY)] # target
Y <- ifelse(Y > 0,1,0) # convert -1..1 to 0..1
Models[[model]] <<- sae.dnn.train(X,Y,
hidden = c(20,20,20),
activationfun = "tanh",
learningrate = 0.5,
momentum = 0.5,
learningrate_scale = 1.0,
output = "sigm",
sae_output = "linear",
numepochs = 100,
batchsize = 100,
hidden_dropout = 0,
visible_dropout = 0)
}

# called by Zorro for prediction
neural.predict = function(model,X)
{
if(is.vector(X)) X <- t(X) # transpose horizontal vector
return(nn.predict(Models[[model]],X))
}

# called by Zorro for saving the models
neural.save = function(name)
{
save(Models,file=name) # save trained models
}

# called by Zorro for initialization
neural.init = function()
{
set.seed(365)
Models <<- vector("list")
}

# quick OOS test for experimenting with the settings
Test = function()
{
neural.init()
XY <<- read.csv('C:/Project/Zorro/Data/signals0.csv',header = F)
splits <- nrow(XY)*0.8
XY.tr <<- head(XY,splits) # training set
XY.ts <<- tail(XY,-splits) # test set
neural.train(1,XY.tr)
X <<- XY.ts[,-ncol(XY.ts)]
Y <<- XY.ts[,ncol(XY.ts)]
Y.ob <<- ifelse(Y > 0,1,0)
Y <<- neural.predict(1,X)
Y.pr <<- ifelse(Y > 0.5,1,0)
confusionMatrix(Y.pr,Y.ob) # display prediction accuracy
}


Метод опорных векторов



Также как и нейронная сеть, метод опорных векторов – это расширенный вариант линейной регрессии. Взглянем на эту формулу еще раз:



image



Маркеры предсказания xn можно рассматривать как координаты пространства с n измерениями. Привязав целевую величину y к фиксированному значению, мы определим плоскость или, как ее еще называют – гиперплоскость. Она отделяет шаблоны с y > 0 от шаблонов с y < 0. Коэффициент an может быть рассчитан как максимальное расстояние от плоскости к ближайшему шаблону, называемому опорным вектором. Таким образом, мы получаем бинарный классификатор с оптимальным делением шаблонов на выигрышные и проигрышные.



Есть небольшая проблема: обычно эти шаблоны нельзя отделить линейно, они рассредоточены в нашем пространстве маркеров нерегулярно. Мы не можем поместить в него ровную плоскость. Если бы и могли, то есть более простой способ определить плоскость – линейный дискриминантный анализ. Но в большинстве случаем мы вынуждены воспользоваться уловкой, которую предоставляет метод опорных векторов: добавить больше измерений в наше пространство. После этого алгоритм производит больше маркеров с помощью функции ядра, которая объединяет два любых предиктора в новый маркер. Чем больше измерений будет добавлено, тем легче разделить шаблоны с помощью гиперплоскости. Затем эта плоскость трансформируется обратно в исходное пространство с n измерениями, обрастая по пути складками. Для того чтобы функция ядра не сбивалась и работала оптимально, процесс должен выполняться без фактического вычисления параметров такого преобразования.



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




  • функция ядра: обычно используют радиальную базисную функцию ядра, но у вас есть выбор, можно использовать полиномиальный, сигмоидный или линейный вариант;

  • гамма, ширина захвата радиальной базисной функции ядра;

  • параметр стоимости C, «штраф» за неверную классификацию шаблонов в процессе обучения.



Метод k ближайших соседей



В сравнении с опорными векторами, это довольно простой алгоритм с кучей уникальных возможностей. Он не требует обучения. Поэтому шаблоны в данном случае – это модель. В трейдинговых системах он позволяет обучаться непрерывно через добавление большего количества шаблонов. Метод ближайших соседей производит расчет расстояния от текущих значений маркеров к ближайшим k-шаблонам. В пространстве с n измерениями это расстояние рассчитывается по двум измерениям:



image



Алгоритм просто предсказывает целевую величину по среднему значению целевых переменных k ближайшего шаблона, распределенных по их обратным расстояниям. Его можно использовать как для классификации, так и для регрессии. Заимствованные из графических редакторов штуки (например, адаптивное двоичное дерево) помогут отыскать ближайшего соседа довольно быстро. Раньше такие вещи часто использовали в программирование игрушек, когда нужно было запустить самообучение интеллекта врага. Можно использовать для наших целей функцию knn в R или написать свою на C.



Метод k-средних



Метод k-средних использует алгоритм аппроксимации для неконтролируемой классификации. Он в чем-то очень похож на предыдущий метод. Для разделения шаблонов алгоритм первым делом размещает случайные отметки k в пространстве маркеров. Затем этим точкам назначаются все ближайшие к ним шаблоны. Следующий шаг: эти точки перемещаются к среднему значению ближайших шаблонов. И мы получаем новое распределение шаблонов, теперь определенные шаблоны становятся ближе к другим отметкам. Процесс повторяется, пока распределение не станет неизменным. То есть каждая отметка будет располагаться в точности по среднему значению ближайших шаблонов. Следовательно, у нас в наличие класс k-шаблонов, каждый из которых в непосредственной близости от одной из k-точек. Алгоритм простой, но он может привести к неожиданно хорошим результатам.



Наивный байесовский классификатор



Следующий алгоритм использует теорему Байеса для классификации шаблонов по нечисловым признакам (событиям), так же, как уже обговоренный метод свечных паттернов. Предположим, у нас есть событие X, проявляющее себя в 80% случаях удачных шаблонов. Что можно из этого извлечь? Подсчитать вероятность выигрыша варианта, содержащего X. Она не будет равна 0,8, как это можно было бы предположить. Действие этой вероятности может быть рассчитано по байесовской теореме:



image



P(Y|X) — это вероятность того, что событие Y (выигрыш) появляется во всех шаблонах, содержащих событие X. Она будет равна вероятности появления X во всех выигрышных шаблонах (то есть 0,8) умноженной на вероятность проявления Y во всех шаблонах (в нашем случае 0,5, если вы внимательно прочли советы по балансировке шаблонов) и разделенной на вероятность наличия X во всех имеющихся шаблонах.



Если мы в меру наивны и предполагаем, что все события X независимы друг от друга, мы можем подсчитать общую вероятность того, что определенный шаблон будет выигрышным, по следующей формуле, используя коэффициент масштабирования s:



image



Для того чтобы формула сработала, нужно разделить маркеры предсказаний так, чтобы они были максимально независимы друг от друга. А это и есть самое главное препятствие для использования теоремы Байеса в трейдинге. В большинстве случаев два события будут, так или иначе, зависеть друг от друга.



Метод байесовского классификатора доступен в пакете e1071 для языка R.



Дерево принятия решения и дерево регрессии



Оба дерева нацелены на предсказание числовых значений на выходе, основываясь на серии решений да/нет. Ответ в каждом случае зависит от наличия или отсутствия события (в варианте нечисловых признаков) или от сравнения значений маркеров предсказания с фиксированным порогом. Стандартная функция дерева на Zorro будет выглядеть так:



int tree(double* sig)
{
if(sig[1] <= 12.938) {
if(sig[0] <= 0.953) return -70;
else {
if(sig[2] <= 43) return 25;
else {
if(sig[3] <= 0.962) return -67;
else return 15;
}
}
}
else {
if(sig[3] <= 0.732) return -71;
else {
if(sig[1] > 30.61) return 27;
else {
if(sig[2] > 46) return 80;
else return -62;
}
}
}
}


Как это дерево возникает из набора шаблонов? Есть несколько методов. Zorro предпочитает метод информационной шенноновской энтропии. Для начала он проверяет один из маркеров, допустим, x1. Он устанавливает гиперплоскость по формуле x1 = t . Эта плоскость отделяет шаблоны со значением x1 > t от шаблонов со значением x1 < t. Разделительный порог t является выборочным, поэтому информационный прирост (отношение информационной энтропии всего пространства к сумме информационных энтропий двух разделенных субпространств) будет максимальным. Это тот случай, когда шаблоны в субпространствах более схожи друг с другом, чем шаблоны в целом пространстве.



Затем процесс запускается для следующего маркера x2, тогда уже две гиперплоскости расщепляют два субпространства. В каждом случае условием для этого является сравнение маркера с установленным порогом. В скором времени мы получаем разветвленное дерево с тысячами сравнений. Следом процесс запускается в обратном направлении, нам нужно подрезать дерево, удалив все решения, которые не ведут к существенному информационному приросту. Наконец, получается относительно небольшое дерево, как в примере кода выше.



Дерево решений может быть применено по-разному. Но его нельзя использовать в качестве решения всех проблем, так как его плоскости деления всегда параллельны осям пространства маркеров. Это ограничивает возможности делать точные предсказания. Для регрессии его также можно использовать. Например, для определения доли шаблонов, привязанных к определенной ветке дерева. Дерево Zorro – это дерево регрессии. Самый распространенный алгоритма классификации по методу дерева — C5.0, доступный в пакете C50 для R.



Заключение



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



Каждую неделю в специализированных изданиях появляется новая статья о методах машинного обучения. К выводам этих статей стоит относиться с долей скепсиса. Многие из них обещают фантастический уровень отдачи в 70-85% прибыли. Если бы все это было правдой, количество миллиардеров среди математиков бы уже зашкаливало. В реальности удачных стратегий, основанных на машинном обучении до обидного мало.



Другие материалы по теме алгоритмической торговли в блоге ITinvest:







Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/281603/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
tanuuusa

Хотите заработать на бинарных опционах?

Воскресенье, 21 Февраля 2016 г. 15:26 (ссылка)


Всем доброе время суток! Уверена, от лишних денег вряд ли кто откажется. Если Вы решитесь начать зарабатывать в интернете — весьма надежный и на данный отрезок времени и самый популярный — заработок на бинарных опционах 2016,  который абсолютно реален. Здесь царствуют огромные деньги. Нужен только подключенный интернет, все действия происходят онлайн. Но, естественно, не стоит, если Вы в этих БО  ничего не понимаете, сразу, сломя голову, окунаться в эту кухню. Надо понять что такое бинарные опционы, торговые системы и многое другое. На первый взгляд всё кажется совсем легко, надо лишь правильно сделать прогноз о понижении или повышении позиций активов(ценных бумаг, любой валюты, каких-то товаров и др.). Ключевым моментом является правильный выбор брокера. Для воодушевления посмотрите видео.







Безусловно, а это даже не обсуждается, что просто так сесть за компьютер и начать зарабатывать большие деньги, — это из области домыслов, так не бывает. Всему надо учиться. Необходимо подробно ознакомиться и изучить материал про заработок на опционах, уметь делать анализ рынка, изучить торговые стратегии. Поэтому стОит пройти обучение торговли на бинарных опционах и Вам станет ясен принцип этих самых загадочных бинарных опционов. В дальнейшем Вы даже сможете с успехом работать, используя бесплатный робот для бинарных опционов. Это очень удобно. Подробности смотрите на сайте fx-gold.net.



Комментарии (8)КомментироватьВ цитатник или сообщество
Tanyusha100

Заработок на Бинарных Опционах 2016...

Среда, 03 Февраля 2016 г. 16:51 (ссылка)



Заработок на Бинарных Опционах 2016...

















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



4897960_0_f3d4b_d801bcfb_orig (75x104, 10Kb)





 



Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Владимир_Шильников

Первая и главная предпосылка успеха на рынке торговли на бинарных опционах - это терпение.

Вторник, 26 Января 2016 г. 17:28 (ссылка)

Ashampoo_Snap_2016.01.26_17h20m01s_001_ (284x76, 4Kb)При покупке акций в выбранной компании предполагается, что в недалеком будущем акции, возрастая в цене, принесут хорошую прибыль. Однако, располагать крупными вложениями может далеко не каждый вкладчик, ведь ценные бумаги стоят больших денег.
Бинарные опционы этим и привлекательны, на них можно инвестировать столько средств, сколько вам удобно. Когда опцион закрылся в пользу трейдера, то в этом случае доход колеблется от 70 до 90 процентов, причем, размер прибыли аналогичен сделанным вложениям. Любой заработок на бинарных опционах 2016 это ваша сделка, и возможность получить хороший доход. Бинарные опционы всегда привлекают своей простотой и возможностью зарабатывать практически мгновенно, не дожидаясь определенного периода, чтобы узнать баланс.
rss_bot_by_leoblanchette-150x150 (150x150, 8Kb)


Чтобы узнать, реально ли можно заработать на бинарных опционах, можно, прислушиваясь к мнению экспертов или опытных трейдеров. Для более успешного оперирования найдите свой информационный источник обучение торговли на бинарных опционах, например, читайте финансовую аналитику, изучайте стратегии торговли опционами, инструменты прогнозирования рынка.
Первая и главная предпосылка успеха на рынке - это терпение.
Метки:   Комментарии (2)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Событийно-ориентированный бэктестинг на Python шаг за шагом. Часть 3

Четверг, 10 Сентября 2015 г. 15:10 (ссылка)





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



Сегодня мы опишем объект NaivePortfolio, который отвечает за отслеживание позиций в портфолио и на основе поступающих сигналов генерирует приказы с ограниченным количеством акций.



Отслеживание позиций и работа с ордерами



Система управления ордерами является одним из самых сложных компонентов событийно-ориентированного бэктестера. Ее роль заключается в отслеживании текущих рыночных позиций и их рыночной стоимости. Таким образом на основе данных, полученных из соответствующего компонента бэктестера, рассчитывается ликвидационная стоимость позиции.



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



Объект Portfolio должен уметь обрабатывать объекты SignalEvent, генерировать объекты OrderEvent и интерпретировать объекты FillEvent, чтобы обновлять позиции. Таким образом, нет ничего удивительного в том, что объекты Portfolio обычно являются наиболее объемными элементами системы бэктестинта с точки зрения строк кода.



Реализация



Создадим новый файл portfolio.py и импортируем необходимые библиотеки — те же реализации абстрактного базового класса, что мы использовали ранее. Нужно импортировать функцию floor из библиотеки math, чтобы генерировать целочисленные приказы. Также необходимы объекты FillEvent и OrderEvent — объект Portfolio обрабатывает каждый из них.



# portfolio.py

import datetime
import numpy as np
import pandas as pd
import Queue

from abc import ABCMeta, abstractmethod
from math import floor

from event import FillEvent, OrderEvent


Создается абстрактный базовый класс для Portfolio и два абстрактных метода update_signal и update_fill. Первый обрабатывает новые торговые сигналы, которые забираются из очереди событий, а последний работает с информацией об исполненных ордерах, получаемых из движка объекта-обработчика.



# portfolio.py

class Portfolio(object):
"""
Класс Portfolio обрабатывает позиции и рыночную стоимость всех инструментов на основе баров: секунда, минута, 5 минут, 30 мин, 60 минут или день.
"""

__metaclass__ = ABCMeta

@abstractmethod
def update_signal(self, event):
"""
Использует SignalEvent для генерации новых ордеров в соответствие с логикой портфолио.

"""
raise NotImplementedError("Should implement update_signal()")

@abstractmethod
def update_fill(self, event):
"""
Обновляет текущие позиции и зарезервированные средства в портфолио на основе FillEvent.

"""
raise NotImplementedError("Should implement update_fill()")



Главный объект сегодняшней статьи — класс NaivePortfolio. Он создан для расчета размеров позиций и зарезервированных средств и обработки торговых приказов в простой манере — просто отправляя их в брокерскую торговую систему с заданным количеством акций. В реальном мире все сложнее, но подобные упрощения помогают понять, как должна функционировать система обработки приказов портфолио в событийно-ориентированных продуктах.



NaivePortfolio требует величину начального капитала — в примере она установлена на $100000. Также необходимо задать день и время начала работы.



Портфолио содержит all_positions и current_positions. Первый элемент хранит список всех предыдущий позиций, записанных по временной метке рыночного события. Позиция — это просто количество финансвого инструмента. Негативные позиции означают, что акции проданы «в короткую». Второй элемент хранит словарь, содержащий текущие позиции для последнего обновления баров.



В добавок к элементами, отвечающим за позиции, в портфолио хранится информация о текущей рыночной стоимости открытых позиций (holdings). «Текущая рыночная стоимость» в данном случае означает цену закрытия, полученную из текущего бара, которая является приблизительной, но достаточно правдоподобной на данный момент. Элемент all_holdings хранит исторический список стоимости всех позиций, а current_holdings хранит наиболее свежий словарь значений:



# portfolio.py

class NaivePortfolio(Portfolio):
"""

Объект NaivePortfolio создан для слепой (т.е. без всякого риск-менеджмента) отправки приказов на покупку/продажу установленного количество акций, в брокерскую систему. Используется для тестирования простых стратегий вроде BuyAndHoldStrategy.
"""

def __init__(self, bars, events, start_date, initial_capital=100000.0):
"""
Инициализирует портфолио на основе информации из баров и очереди событий. Также включает дату и время начала и размер начального капитала (в долларах, если не указана другая валюта).

Parameters:
bars - The DataHandler object with current market data.
events - The Event Queue object.
start_date - The start date (bar) of the portfolio.
initial_capital - The starting capital in USD.
"""
self.bars = bars
self.events = events
self.symbol_list = self.bars.symbol_list
self.start_date = start_date
self.initial_capital = initial_capital

self.all_positions = self.construct_all_positions()
self.current_positions = dict( (k,v) for k, v in [(s, 0) for s in self.symbol_list] )

self.all_holdings = self.construct_all_holdings()
self.current_holdings = self.construct_current_holdings()


Следующий метод construct_all_positions просто создает словарь для каждого финансового инструмента, устанавливает каждое значение в ноль а затем добавляет ключ даты и времени. Используется генераторы словарей Python.



# portfolio.py

def construct_all_positions(self):
"""
Конструирует список позиций, используя start_date для определения момента, с которой должен начинаться временной индекс.
"""
d = dict( (k,v) for k, v in [(s, 0) for s in self.symbol_list] )
d['datetime'] = self.start_date
return [d]


Метож construct_all_hldings похож на описанный выше, но добавляет некоторые дополнительные ключи для свободных средств, комиссий и остаток денег на счету после совершения сделок, общую уплаченную комиссию и общий объём имеющихся активов (открытые позиции и деньги). Короткие позиции рассматриваются как «негативные». Величины starting cash и total account равняются первоначальному капиталу:



# portfolio.py

def construct_all_holdings(self):
"""
Конструирует список величин текущей стоимости позиций, используя start_date для определения момента, с которой должен начинаться временной индекс.
"""
d = dict( (k,v) for k, v in [(s, 0.0) for s in self.symbol_list] )
d['datetime'] = self.start_date
d['cash'] = self.initial_capital
d['commission'] = 0.0
d['total'] = self.initial_capital
return [d]


Метод construct_current_holdings практически идентичен предыдущему, за исключением того, что не «оборачивает» словарь в список:



# portfolio.py

def construct_current_holdings(self):
"""
Конструирует словарь, который будет содержать мгновенное значение портфолио по всем инструментам.

"""
d = dict( (k,v) for k, v in [(s, 0.0) for s in self.symbol_list] )
d['cash'] = self.initial_capital
d['commission'] = 0.0
d['total'] = self.initial_capital
return d


На каждом «ударе сердца», то есть при каждом запросе рыночных данных из объекта DataHandler, портфолио должно обновлять текущее рыночное значение удерживаемых позиций. В сценарии реального трейдинга эту информацию можно загрузать и парсить напрямую из брокерской системы, но для системы бэктестинга необходимо отдельно высчитывать эти значения.



К сожалению, из-за спредов бидов/асков и ликвидности, такой вещи, как «текущее рыночное значение» не существует. Поэтому необходимо его оценивать умножая количество удерживаемого актива на «цену». В нашем примере используется цена закрытия предыдущего полученного бара.Для стратегий торговли внутри дня это довольно реалистичный подход, но для торговли на временных промежутках больше дня, все уже не столь правдоподобно, поскольку цена открытия может значительно отличаться от цены открытия следующего бара.



Метод update_timeindex отвечает за обработку текущей стоимости новых позиций. Он получает последние цены из обработчика рыночных данных и создает новый словарь инструментов, которые представляют текущие позиции, и приравнивая «новые» позиции к «текущим» позициям. Эта схема меняется только при получении FillEvent. После этого метод присоединяет набор текущих позиций к списку all_positions. Затем величины текущей стоимости обновляются схожим образом за исключением того, что рыночное значение вычисляется с помощью умножения числа текущих позиций на цену закрытия последнего бара (self.current_positions[s] * bars[s][0][5]). Новые полученные значения добавляются к списку all_holdings:



# portfolio.py

def update_timeindex(self, event):
"""
Добавляет новую запись в матрицу позиций для текущего бара рыночных данных. Отражает ПРЕДЫДУЩИЙ бар, т.е. на этой стадии известны все рыночные данные (OLHCVI). Используется MarketEvent из очередий событий.

"""
bars = {}
for sym in self.symbol_list:
bars[sym] = self.bars.get_latest_bars(sym, N=1)

# Update positions
dp = dict( (k,v) for k, v in [(s, 0) for s in self.symbol_list] )
dp['datetime'] = bars[self.symbol_list[0]][0][1]

for s in self.symbol_list:
dp[s] = self.current_positions[s]

# Append the current positions
self.all_positions.append(dp)

# Update holdings
dh = dict( (k,v) for k, v in [(s, 0) for s in self.symbol_list] )
dh['datetime'] = bars[self.symbol_list[0]][0][1]
dh['cash'] = self.current_holdings['cash']
dh['commission'] = self.current_holdings['commission']
dh['total'] = self.current_holdings['cash']

for s in self.symbol_list:
# Approximation to the real value
market_value = self.current_positions[s] * bars[s][0][5]
dh[s] = market_value
dh['total'] += market_value

# Append the current holdings
self.all_holdings.append(dh)


Метод update_positions_from_fill определяет, каким конкретно был FillEvent (покупка или продажа), а затем обновляет словарь current_positions, добавляя или удаляя соответствующее количество акций:



# portfolio.py

def update_positions_from_fill(self, fill):
"""
Обрабатывает объект FillEvent и обновляет матрицу позиций так, чтобы она отражала новые позиции.

Parameters:
fill - The FillEvent object to update the positions with.
"""
# Check whether the fill is a buy or sell
fill_dir = 0
if fill.direction == 'BUY':
fill_dir = 1
if fill.direction == 'SELL':
fill_dir = -1

#Список позиций обновляется новыми значениями
self.current_positions[fill.symbol] += fill_dir*fill.quantity


Соответствующий метод update_holdings_from_fill похож на описанный выше, но обновляет величину holdings. Для симуляции стоимости исполнения, метод не использует цену, связанную с FillEvent. Почему так просиходит? В среде бэктестинга цена исполнения на самом деле неизвестна, а значит ее нужно предположить. Таким образом, цена исполнения устанавливается как «текущая рыночная цена» (цена закрытия последнего бара). Значение текущих позиций для конкретного инструмента потом приравнивается к цене исполнения, умноженной на количество ценных бумаг в ордере.



После определения цены исполнения текущее значение holdings, доступных средств и общих величин могут обновляться. Также обновляется общая комиссия:



# portfolio.py

def update_holdings_from_fill(self, fill):
"""
Использует объект FillEvent и обновляет матрицу holdings для отображения изменений.

Параметры:
fill - Объект FillEvent, который используется для обновлений.
"""
# Check whether the fill is a buy or sell
fill_dir = 0
if fill.direction == 'BUY':
fill_dir = 1
if fill.direction == 'SELL':
fill_dir = -1

# Update holdings list with new quantities
fill_cost = self.bars.get_latest_bars(fill.symbol)[0][5] # Close price
cost = fill_dir * fill_cost * fill.quantity
self.current_holdings[fill.symbol] += cost
self.current_holdings['commission'] += fill.commission
self.current_holdings['cash'] -= (cost + fill.commission)
self.current_holdings['total'] -= (cost + fill.commission)


Далее реализуется абстрактный метод update_fill из абстрактного базового класса Portfolio. Он просто исполняет два предыдущих метода update_positions_from_fill и update_holdings_from_fill:



# portfolio.py

def update_fill(self, event):
"""
Обновляет текущие позиции в портфолио и их рыночную стоимость на основе FillEvent.

"""
if event.type == 'FILL':
self.update_positions_from_fill(event)
self.update_holdings_from_fill(event)



Объект Portfolio должен не только обратывать события FillEvent, но еще и генерировать OrderEvent при получении сигнальных событий SignalEvent. Метод generate_naive_order использует сигнал на открытие длинной или короткой позиции, целевой финансовый инструмент и затем посылает соответствующий ордер со 100 акциями нужного актива. 100 здесь — произвольное значение. В ходе реальной торговли оно было бы определено системой риск-менеджмента или модулем расчета величины позиций. Однако в NaivePortfolio можно «наивно» посылать приказы прямо после получения сигналов без всякого риск-менеджмента.



Метод обрабатывает открытие длинных и коротких позиций, а также выход из них на основе текущего количество и конкретного финансового инструмента. Затем генерируется соответствующий объект OrderEvent:



# portfolio.py

def generate_naive_order(self, signal):
"""
Просто передает OrderEvent как постоянное число акций на основе сигнального объекта без анализа рисков.

Параметры:
signal - Сигнальная информация SignalEvent.
"""
order = None

symbol = signal.symbol
direction = signal.signal_type
strength = signal.strength

mkt_quantity = floor(100 * strength)
cur_quantity = self.current_positions[symbol]
order_type = 'MKT'

if direction == 'LONG' and cur_quantity == 0:
order = OrderEvent(symbol, order_type, mkt_quantity, 'BUY')
if direction == 'SHORT' and cur_quantity == 0:
order = OrderEvent(symbol, order_type, mkt_quantity, 'SELL')

if direction == 'EXIT' and cur_quantity > 0:
order = OrderEvent(symbol, order_type, abs(cur_quantity), 'SELL')
if direction == 'EXIT' and cur_quantity < 0:
order = OrderEvent(symbol, order_type, abs(cur_quantity), 'BUY')
return order


Метод update_signal просто вызывает описанный выше метод и добавляет сгенерированный приказ в очередь событий.



# portfolio.py

def update_signal(self, event):
"""
На основе SignalEvent генерирует новые приказы в соответствии с логикой портфолио.

"""
if event.type == 'SIGNAL':
order_event = self.generate_naive_order(event)
self.events.put(order_event)


Финальный метод в NaivePortfolio — это генерации кривой капитала. Создается поток с информацией о прибыли, что полезно для расчетов производительности стратегии, затем кривая нормализуется на процентной основе. Первоначальный размер счета устанавливается раным 1.0:



# portfolio.py

def create_equity_curve_dataframe(self):
"""
Создает pandas DataFrame из списка словарей all_holdings.

"""
curve = pd.DataFrame(self.all_holdings)
curve.set_index('datetime', inplace=True)
curve['returns'] = curve['total'].pct_change()
curve['equity_curve'] = (1.0+curve['returns']).cumprod()
self.equity_curve = curve


Объект Portfolio — это наиболее сложный аспект всего событийно-ориентированного бэктестера. Несмотря на сложность, обработка позиций здесь реализована на очень простом уровне.



В следующей статье мы рассмотрим последнюю часть событийно-ориентированной системы исторического тестирования — объект ExecutionHandler, который использует объекты OrderEvent для создания из них FillEvent.



Продолжение следует…



P. S. Ранее в нашем блоге на Хабре мы уже рассматривали различные этапы разработки торговых систем. ITinvest и наши партнеры проводят онлайн-курсы по данной тематике.

Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/266623/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Зарабатывающая идея реального форекс-робота

Вторник, 08 Сентября 2015 г. 19:12 (ссылка)

Общеизвестно, что заработать на форекс невозможно. Изменения курсов валют носят случайный характер, а комиссия брокера уменьшает вероятность положительного итогового заработка, часто делая ее совсем непривлекательной, - ниже, чем в казино, например. Тем не менее, я содержу себя и свои проекты исключительно за счет форекс уже три года, я шел к этому около 7 лет и, вспоминая этот путь, решил написать заметку для тех, кого привлекает эта антинаучная возможность заработка.



Речь пойдет не о чудесных Граалях, продаваемых в интернете, не о высокочастотной торговле и не о «безрисковых» вложениях в мифические ТОП-20 лучших трейдеров. Только хардкор: мы проводим многочисленные торговые операции, кто-то вручную, кто-то - автоматически, и получаем в результате этих операций положительный прирост счета при статистически значимом количестве сделок.



Люди поступают рефлекторно, и рефлексы одинаковы у всех. Приобретенные рефлексы также записываются у всех одинаково. Любой торговец, торгует он на форекс или на товарной или фьючерсной бирже, учится на своем опыте, а чаще хуже - пытается дополнительно почерпнуть что-то из умных книг, таким образом быстрее перенимая «лучшие практики» мира спекулянтов.



Получив некий торговый опыт, трейдер пытается проецировать его на свои будущие сделки, а в его голове формируется своеобразное «лекало», по которому он старается действовать. Не важно, какие временные периоды, торговые инструменты и виды анализа он использует. Это самое лекало учитывает только два основных исхода: «угадал» и «не угадал». В зависимости от каждого конкретного испытания трейдерской удачи, лекало незначительно изменяется, усовершенствуется с учетом этого исхода.



Технически подкованные спекулянты используют различные средства автоматизации - нейронные сети, алгоритмы принятия решений, а то и просто голые методы управления капиталом, такие как мартингейл, например. Независимо от выбранного способа построения торговых правил, всех разработчиков торговых алгоритмов (стратегий) объединяет одна цель - заработать денег. Но цель эта искажается при постановке задачи: делать ставки, которые будут угадывать как можно чаще. В этом и заключается безнадежная ошибка построителей торговых граалей - угадать невозможно.



Многие трейдеры люто поспорят со мной, но я отважусь высказать мнение, что попытка научиться «угадывать» больше чем в 50% случаев на основании любого объема исторических данных (прежнего опыта), чутья или технического или фундаментального анализа обречены на неудачу. Просто в силу того, что график цены отображает случайный процесс с соответствующим распределением исходов.



Нельзя угадать результат случайного процесса. Может повезти или нет, но итог будет один - при разумном управлении капиталом каждая сделка в среднем будет уносить сумму, равную накладным расходам на сделку (спред, комиссия, проскальзывание и т.д.). Имеется в виду статистически значимое количество сделок - истории о двух годах прибыльной торговли при сотне–другой–третьей сделок могут говорить только о везении. Да, на миллионы трейдеров всегда найдутся десятки везунчиков с историями успеха. Проследите, что будет с ними еще через столько же сделок, и увидите, как гармония возвращается в жизнь.



Может показаться, что я пытаюсь поставить крест на идее заработка на форекс в принципе, но - нет! Однако следует отказаться от желания «угадать» в пользу желания «заработать».



График движения цены демонстрирует нам некоторые очевидные аномалии в распределении вероятностей, они проявляются, например, в длинных безоткатных движениях цены в одном направлении. Такие движения случаются при выходе сильных экономических новостей, и в трейдерском мире эти аномалии называют «хвостами» на графике распределения вероятностей. Вот, например, показательный случай, наблюдаемый в день подготовки статьи:





Но это - результат внешнего воздействия. Гораздо интереснее другое: даже при наличии «хвостов» распределение вероятностей настолько близко к нормальному, что заработать на знании о хвостах не получается. То есть не удается покрыть даже заявленные брокером накладные расходы, не говоря уж о реальных затратах, включающих расширения спреда, исполнения по худшей цене и т.д. Скрытый текст ниже экспериментально подтверждает бесперспективность хвостов.



Да, есть некий перекос, но совокупный разум спекулянтов своими действиями как бы приводит распределение к нормальному. Вот здесь и появляется возможность заработать!



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





У каждого из нас в школе был набор подобных вещиц. При всей неправильности и нелогичности их форм, обводить эти фигурки карандашом очень легко и приятно. Сложнее будет подстроиться и точно скопировать уникальные загогулины произвольного рисунка. Для создания же новых осмысленных форм они практически непригодны. Лекала профессиональных трейдеров намного проще представленных выше фигур, они прямолинейны и имеют всего два–три изгиба - трейдер быстро привыкает к ним и никогда уже им не изменяет.



Прелесть шаблонов поведения спекулянтов в том, что они имеют всего одну степень свободы - вертикальное движение от одного уровня цены до другого. Уровни имеют «магическое» свойство - они дают человеку иллюзию понимания происходящего в данный момент, провоцируя его на конкретные действия. Остальные параметры реального рынка (время, торговый объем и т.д.) не дают таких четких ориентиров, как уровни, поэтому имеют сравнительно слабое обучающее влияние на шаблоны поведения.





График в левой части рисунка показывает типичную рыночную ситуацию. Цена подходит к уровню предыдущего максимума (верхняя штриховая линия), а трейдеры всего мира стоят перед выбором: купить или продать в этот момент? Момент на рисунке обозначен красным кругом.



Статистически вероятность достижения ценой предыдущего минимума равна вероятности достижения симметричного уровня выше текущей точки (см. правую часть рисунка).



Проверка равновероятности достижения симметричных уровней и бесперспективности хвостов.
Для тестирования на исторических данных напишем простейшего робота, который будет открывать сделки при пробитии «канала»: диапазона цены, ограниченного штриховыми линиями на картинке выше. Закрывать сделки робот будет при достижении одного из симметричных уровней - противоположной границы канала или равноудаленной от нее линии сверху.



Если вероятности достижения уровней не 50/50, то мы будем получать какой-то определенный финансовый результат на ощутимом множестве сделок - положительный или отрицательный. В частности, если упомянутые выше «хвосты» действительно не укладываются в нормальное распределение, то открытие на пробое канала наружу будет приносить устойчивую прибыль.



Ниже приведены результаты серии тестов на исторических данных для двух вариантов условной комиссии брокера: 1 пункт (слева) и 7 пунктов (справа). Для справки: 7 пунктов - это минимальная, заявляемая в рекламе, комиссия брокера форекс по самой ликвидной паре EURUSD; реальные же значения отличаются минимум в 2 раза и составляют от 14 до 27 пунктов.





Робот был запущен на различных периодах графиков цены, чтобы получить серию независимых испытаний на истории котировок за 15 лет. В ходе каждого теста просчитано от 4000 до 15500 сделок (чем больше период графика, тем меньше сделок успевает открыть робот).



Для тестов с комиссией 1 пункт мы имеем средний коэффициент прибыли (Profit factor) 1,008. На одной из картинок при этом график баланса имеет ярко выраженный тренд, а общий микроскопический перекос идет в сторону прибыли. Испытания в условиях идеального брокера дают коэффициент прибыли 0,992. То есть влияние отклонения распределения вероятностей от нормального настолько мало, что заработать только на знании о его существовании не получится.



Обратите внимание, что чем больше сделок совершает робот, тем сильнее прибита вниз кривая баланса, особенно это заметно на нижнем правом графике - 15500 сделок с комиссией 7 пунктов неузнаваемо изменили результат в сравнении с условно нулевой комиссией (нижний левый график).



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



Однако трейдер, открыв позицию в ту или иную сторону, при принятии дальнейших решений будет учитывать прежде всего направление своего входа. Проще говоря, тот, кто купил, руководствуясь конкретно этой картинкой, продаст потом (в среднем) по известной заранее цене; тот же, кто продал, купит по другой цене, тоже заранее известной.



Человеку кажется, что он принимает решения о закрытии позиции, руководствуясь оперативной обстановкой, но на самом деле, зная точку и направление его входа в рынок, можно уже в момент входа предсказать точки его выхода.



Если точнее, заранее известно две цены выхода: для прибыльной и убыточной сделки. На форексе большинство трейдеров закрывают прибыльную сделку достаточно быстро, не накапливая прибыль, но готовы терпеть убытки и не закрывать позицию вплоть до полной потери депозита.



Доказательство несимметричности сумм прибыльных и убыточных сделок.
На рисунке приведены количество и суммарная прибыль сделок для разных размеров выигрыша. Сумма выигрыша измеряется в пунктах. По горизонтальной оси отложены суммы выигрышей: от 0 до 5 пунктов, свыше 5 до 10 пунктов, свыше 10 до 20 и т.д. То же самое для проигрышей.



В выборке присутствовали самые разные торговые инструменты, взято статистически значимое количество сделок за длительный период, и эта выборка в любой форекс-компании будет практически одинакова.





Из рисунка видно, что убыточных сделок в два раза меньше прибыльных, но суммы их вполне уравновешены. Разница обусловлена накладными расходами, которые составляют около 15 пунктов на сделку. Пики количества сделок и, особенно, сумм выигрыша/проигрыша заметно несимметричны: убыточные сделки гораздо длиннее, что и требовалось доказать.



Графически это проиллюстрировано на следующем рисунке: трейдеры, угадавшие с направлением открытия сделки (покупка или продажа), будут фиксировать прибыль в зеленой зоне. Не угадавшие будут фиксировать убыток позже по времени - в красной зоне.





Зарабатывающая идея состоит в том, что между этими двумя зонами часто возникает некая непустая зона (далее - Нейтральная зона), попав в которую, цена неизбежно пройдет ее всю. Это произойдет потому, что отложенные ордера, которые фиксируют убыток в красной зоне, «притянут» к себе цену. Помните, выше я заявил, что действия трейдеров корректируют распределение вероятностей? Это гипотеза, которую я проверил на практике - она реально работает, и вы можете сразу этим пользоваться! (Я потратил 5 лет на вывод и доказательство этого.)



Исходя из вышесказанного, если мы фиксируем прибыль или убыток между зеленой и красной зонами, то мы работаем чуть лучше среднестатистического спекулянта, а поскольку спекулянт работает в 0 (без учета комиссии брокера), то мы работаем в плюс.



Не важно, угадали мы с направлением сделки или нет, закрылись мы в плюс или в минус. Как только цена оказалась в Нейтральной зоне - всё, шаблон сработал, и можно без раздумий закрывать сделку. Даже при большом количестве убыточных сделок подряд за ними последует некоторое количество прибыльных, и результат торговли будет положительным. Разумеется, чтобы положительное математическое ожидание отчетливо проявилось, количество сделок должно быть статистически значимым.



«Покажи стейтмент!»
Такое издевательское приветствие принято в среде трейдеров, когда собеседник требует реальное подтверждение неких заявлений. Вот пример статистики одного реального счета, публично работающего чуть меньше трех лет. Ссылку на счет я здесь не привожу, чтобы не рекламировать конкретного брокера (все они принципиально одинаковые), но любой желающий может проверить достоверность данных, обратившись ко мне лично.





Счет был изначально пополнен на 3000 USD, после чего из него постепенно выводили прибыль, выведя всего 14500 USD. Максимальный временный проигрыш составлял 86% от остатка средств на счете - это результат самой длинной полосы «неугаданных сделок», по окончании которой положительное мат. ожидание вывело счет к новым вершинам доходности. Кстати, расчетный максимальный проигрыш, при котором еще возможна нормальная работа системы, - 95%.

Усредненная картина по сделкам (6920 штук на момент написания статьи) приведена ниже:





Выигравших сделок всего 46.8%, но средняя прибыль превышает средний убыток почти в полтора раза, отражая, на сколько эта торговая система работает лучше среднестатистического торговца форекс.



Теперь вернемся к шаблонам поведения спекулянтов, которые позволят нам лучше выделить нижнюю границу зеленой зоны (где мы будем фиксировать убыток) и верхнюю границу красной зоны (там следует фиксировать прибыль). Рынок постоянно меняется, работает с разной амплитудой, разной ликвидностью, разной напряженностью его участников и т.д. Но механизм принятия решений участником рынка не меняется, будь то человек или торговый робот, который всего–навсего позволяет человеку быстрее выплачивать комиссию своему брокеру. Это относится и к высокочастотному трейдингу тоже (фронт–раннеров и прочих мошенников мы в расчет не берем).



Так вот, участник рынка корректирует свое видение ситуации, основываясь на прежнем опыте, причем более свежие эпизоды имеют большее влияние на его решения. Шаблон поведения един, но его параметры постоянно плавают в небольших пределах, корректируются в свете последних событий. Под этот процесс необходимо подстроиться, учитывая минимально достаточный набор исторических данных. Если анализировать много данных, то мы получим большой объем вычислений при ничтожной полезности значительной их части.



Самый важный момент при работе с шаблонами - они имеют кумулятивный эффект, поэтому, выбрав для работы определенный временной интервал (например, период 50 баров на пятиминутном графике), необходимо четко отрабатывать каждое совпадение шаблона, не пропуская ни единой возможности.



Физический смысл предыдущего абзаца, если очень упрощенно, таков: каждая корректировка шаблона в голове спекулянта происходит с учетом нескольких прошлых корректировок, и иногда шаблон изменяется радикально. Злость или эйфория по разные стороны баррикад (у купивших и продавших) накапливается, и временами общий психоз очень выгодно расширяет Нейтральную зону. Такие случаи нельзя пропускать!



Кстати, огромная масса трейдеров рассматривает рынок в разных масштабах, поэтому то, что мы видим на нашей картинке, является лишь незначительным эпизодом в более крупном плане, который, в свою очередь, тоже является фрагментом большой картины… И так далее. Поэтому очень важно рассматривать строго ограниченный участок графика, а также до предела его упростить (нет времени, нет объемов, нет изгибов и прочего, а есть только несколько уровней, обозначенных локальными экстремумами).



Шаблон, работающий на выбранном нами участке, будет так же работать в любом другом масштабе, и тогда всё, что нам остается - делать много-много сделок и зарабатывать.



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



В следующей статье, если она появится, я расскажу о реалиях и предрассудках форекс (и не только его); почему вы не станете сразу долларовым миллионером, даже имея прибыльную торговую систему; что нужно принимать во внимание, если вы отважитесь пытаться заработать в этой индустрии развлечений, и кое–что еще. Спасибо за внимание!



Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/266457/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Событийно-ориентированный бэктестинг на Python шаг за шагом. Часть 2

Вторник, 04 Августа 2015 г. 14:03 (ссылка)





В предыдущей статье мы поговорили о том, что такое событийно-ориентированная система бэктестинга и разобрали иерархию классов, которую необходимо для нее разработать. Сегодня речь пойдет о том, как подобные системы используют рыночные данные как в контексте исторического тестирования, так и для «живой» работы на бирже.



Работа с рыночными данными



Одной из задач при создании событийно ориентированной торговой системы является минимизация необходимости писать разный код для одних и тех же задач в контексте тестирования на исторических данных и для реальной торговли. В идеале, следует использовать единую методологию генерации сигналов и управления портфолио для каждого из этих случаев. Чтобы этого добиться, объект Strategy, который генерирует торговые сигналы (Signals), и объект Portfolio, который на их основе генерирует ордера (Orders), должны использовать один интерфейс доступа к рыночным данным как в контексте исторического тестирования, так и работы в реальном времени.



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



Среди таких подклассов могут быть HistoricCSVDataHandler, QuandlDataHandler, SecuritiesMasterDataHandler, InteractiveBrokersMarketFeedDataHandler и так далее. Здесь мы рассмотрим только создание обработчика CSV с историческими данными, который будет загружать соответствующий CSV-файл финансовых данных внутри дня в формате баров (значения цены Low, High, Close, а также объем торгов Volume и открытый интерес OpenInterest). На основе этих данных при каждом «ударе сердца» системы (heartbeat) можно уже проводить углубленный анализ компонентами Strategy и Portfolio, что позволит избежать различных искажений.



На первом шаге нужно импортировать требуемые библиотеки, в частности pandas и abstract base class. Поскольку DataHandler генерирует события MarketEvents, нужно также импортировать и event.py:



# data.py

import datetime
import os, os.path
import pandas as pd

from abc import ABCMeta, abstractmethod

from event import MarketEvent


DataHandler — это абстрактный базовый класс (АБК), что означает невозможность создания экземпляра напрямую. Это можно сделать только с помощью подклассов. Обоснование этого заключается в том, что АБК, предоставляет интерфейс для подлежащих подклассов DataHandler, который они должны использовать, что позволяет добиться совместимости с другими классами, с которыми может осуществляться взаимодействие.



Чтобы Python «понял», что имеет дело с абстрактным базовым классом, мы будем использовать свойство _metaclass_. Также с помощью декоратора @abstractmethod указывается, что метод будет переопределен в подклассах (в точности аналогично полностью виртуальному методу в C++).



Два интересующих нас метода — это get_latest_bars и update_bars. Первый из них возвращает последние N баров из текущей временной метки «удара сердца» системы, что полезно для осуществления вычислений для классов Strategy. Последний метод предоставляет механизм анализа для наложения информацию бара на новую структуру данных, что полностью позволяет избавиться от прогнозных искажений. Если произойдет попытка созданий экземпляра класса, возникнет исключение:



# data.py

class DataHandler(object):
"""
DataHandler — абстрактный базовый класс, предоставляющий интерфейс для всех наследованных обработчиков (для живой торговли и работы с историческими данными)

Цель (выделенного) объекта DataHandler заключается в выводе сгенерированного набора баров (OLHCVI) для каждого запрощенного финансового инструмента.

Это нужно для получения понимания о том, как будет функционировать стратегия, при использовании реальных торговых данных. Таким образом реальная и историческая система во всем наборе инструментов бэктестинга рассматриваются одинаково.
"""

__metaclass__ = ABCMeta

@abstractmethod
def get_latest_bars(self, symbol, N=1):
"""
Возвращает последние N баров из списка latest_symbol или меньше, если столько баров еще недоступно.
"""
raise NotImplementedError("Should implement get_latest_bars()")

@abstractmethod
def update_bars(self):
"""
Накладывает последний бар на последнюю структуру инструмента для всех инструментов в списке.
"""
raise NotImplementedError("Should implement update_bars()")


После описания класса DataHandler следующим шагом является создание обработчика для исторических CSV-файлов. HistoricCSVDataHandler будет брать множество CSV-файлов (по одному для каждого финансового инструмента) и конвертировать их в словарь фреймов DataFrames для pandas.



Обработчику нужно несколько параметров — очередь событий (Event Queue), в которую публиковать рыночную информацию MarketEvent, абсолютный путь к CSV-файлам и список инструментов. Вот так выглядит инициализация класса:



# data.py

class HistoricCSVDataHandler(DataHandler):
"""
HistoricCSVDataHandler создан для чтения CSV-файло с диска и создания интерфейса для получения «последнего» бара, как при реальной торговле.

"""

def __init__(self, events, csv_dir, symbol_list):
"""
Инициализирует обработчик исторических данных запросом местоположения CSV-файлов и списка инструментов.

Предполагается, что все файлы имеют форму 'symbol.csv', где symbol — это строка списка.


Параметры:
events - очередь событий.
csv_dir - Абсолютный путь к директории с CSV-файлами.
symbol_list - Список строк инструментов.
"""
self.events = events
self.csv_dir = csv_dir
self.symbol_list = symbol_list

self.symbol_data = {}
self.latest_symbol_data = {}
self.continue_backtest = True

self._open_convert_csv_files()



Он будет пытаться открыть файлы в формате “SYMBOL.csv”, в которым SYMBOL — это тикер инструмента. Использованный здесь формат совпадает с предлагаемым поставщиком данных DTN IQFeed, но его легко можно модифицировать для работы с другими форматами. Открытие файлов обрабатывается методом _open_convert_csv_files.



Одно из преимуществ использования пакета pandas для хранения данных внутри HistoricCSVDataHandler заключается в том, что индексы всех отслеживаемых инструментов можно слить воедино. Это позволяет интерполировать даже отсутствующие данные, что полезно для побарового сравнения инструментов (бывает нужно в стратегиях mean reversion). При комбинировании индексов для инструментов используются методы union и reindex:



# data.py

def _open_convert_csv_files(self):
"""
Открывает CSV-файлы из директории, конвертирует их в pandas DataFrames внутри словаря инструментов.

Для данного обработчика предположим, что данные берутся из фида DTN IQFeed, и работа идет с этим форматом.
"""
comb_index = None
for s in self.symbol_list:
# Загрузка CSV-файла без заголовочной информации, индексированный по дате

self.symbol_data[s] = pd.io.parsers.read_csv(
os.path.join(self.csv_dir, '%s.csv' % s),
header=0, index_col=0,
names=['datetime','open','low','high','close','volume','oi']
)

# Комбинируется индекс для «подкладывания» значений
if comb_index is None:
comb_index = self.symbol_data[s].index
else:
comb_index.union(self.symbol_data[s].index)

# Set the latest symbol_data to None
self.latest_symbol_data[s] = []

# Reindex the dataframes
for s in self.symbol_list:
self.symbol_data[s] = self.symbol_data[s].reindex(index=comb_index, method='pad').iterrows()


Метод _get_new_bar создает генератор для создания форматированной версии данных в барах. Это означается, что последующие вызовы метода результируются в новом баре (и так до того момента, пока не будет достигнут конец строки данных по инструментам):



# data.py

def _get_new_bar(self, symbol):
"""
Возвращает последний бар из дата-фида в формате:
(sybmbol, datetime, open, low, high, close, volume).
"""
for b in self.symbol_data[symbol]:
yield tuple([symbol, datetime.datetime.strptime(b[0], '%Y-%m-%d %H:%M:%S'),
b[1][0], b[1][1], b[1][2], b[1][3], b[1][4]])




Первый абстрактный метод из DataHаndler, который нужно реализовать — это get_latest_bars. Он просто выводит список последних N баров из структуры latest_symbol_data. Установка N = 1 позволяет получать текущий бар:



# data.py

def get_latest_bars(self, symbol, N=1):
"""
Возвращает N последних баров из списка latest_symbol, или N-k, если доступно меньше.

"""
try:
bars_list = self.latest_symbol_data[symbol]
except KeyError:
print "That symbol is not available in the historical data set."
else:
return bars_list[-N:]


Последний метод — update_bars, это второй абстрактный метод из DataHandler. Он генерирует события (MarketEvent), которые попадают в очередь, как последние бары добавляются в latest_symbol_data:



# data.py

def update_bars(self):
"""
Отправляет последний бар в структуру данных инструментов для всех инструментов в списке.
"""
for s in self.symbol_list:
try:
bar = self._get_new_bar(s).next()
except StopIteration:
self.continue_backtest = False
else:
if bar is not None:
self.latest_symbol_data[s].append(bar)
self.events.put(MarketEvent())


Таким образом, у нас есть DataHandler — выделенный объект, который используется остальными компонентами системы для отслеживания рыночных данных. Для работы объектам Stragety, Portfolio и ExecutionHandler требуется текущая рыночная информация, поэтому имеет смысл работать с ней централизованно, чтобы избежать возможного дублировани хранения.



От информации до торгового сигнала: стратегия



Объект Strategy инкапсулирует все вычисления, связанные с обработкой рыночных данных, для создания рекомендательных сигналов объекту Portfolio. На этой стадии разработки событийно ориентированного бэктестера нет понятий индикаторов или фильтров, которые используются в техническом анализе. Для их реализации можно создать отдельную структуру данных, но это уже выходит за рамки данной статьи.



Иерархия стратегии относительно проста — она состоит из абстрактного базового класса с единственным виртуальным методом для создания объектов SignalEvents. Для создания иерархии стратегии необходимо импортировать NumPy, pandas, объект Queue, инструмент abstract base tools и SignalEvent:



# strategy.py

import datetime
import numpy as np
import pandas as pd
import Queue

from abc import ABCMeta, abstractmethod

from event import SignalEvent


Абстрактный базовый класс Strategy определяет виртуальный метод calculate_signals. Он используется для обработки создания объектов SignalEvent на основе обновлений рыночных данных:



# strategy.py

class Strategy(object):
"""
Strategy — абстрактный базовый класс, предоставляющий интерфейс для подлежащих (наследованных) объектов для обработки стратегии.


Цель выделенного объекта Strategy заключается в генерировании сигнальных объектов для конкретных инструментов на основе входящих баров (OLHCVI), сгенерированных объектом DataHandler.

Эту конфигурацию можно использовать как для работы с историческими данными, так и для работы на реальном рынке — объект Strategy не зависит от от источника данных, он получает бары из очереди.

"""

__metaclass__ = ABCMeta

@abstractmethod
def calculate_signals(self):
"""
Предоставляет механизмы для вычисления списка сигналов.

"""
raise NotImplementedError("Should implement calculate_signals()")


Определение абстрактного базового класса Strategy довольно проста. Первый пример использования подклассов в объекте Strategy заключается в использовании стратегий buy и hold и создании соответствующего класса BuyAndHoldStrategy. Он будет покупать конкретную акцию в определенный день и удерживает позицию. Таким образом на одну акцию генерируется только один сигнал.



Конструктор (__init__) требует наличия обработчика рыночных данных bars и объекта очереди событий events:



# strategy.py

class BuyAndHoldStrategy(Strategy):
"""
Крайне простая стратегия, которая входит в длинную позициию при полуении бара и никогда из нее не выходит.

Используется в качестве механизма тестирования класса Strategy и бенчмарка для сравнения разных стратегий.
"""

def __init__(self, bars, events):
"""
Инициализирует стратегию buy and hold.

Параметры:
bars - Объект DataHandler, который предоставляет информацию о барах
events - Объект очереди событий.
"""
self.bars = bars
self.symbol_list = self.bars.symbol_list
self.events = events

# Когда получен сигнал на покупку и удержание акции, устанавливается в True
self.bought = self._calculate_initial_bought()



При инициализации стратегии BuyAndHoldStrategy в словаре bought содержится набор ключей для каждого инструмента, которые установлены в False. Когда определенный инструмент покупается (открывается длинная позиция), то ключ переводится в положение True. Это позволяет объекту Strategy понимать, открыта ли позиция:



# strategy.py

def _calculate_initial_bought(self):
"""
Добавляются ключи в словарь bought и устанавливаются в False.
"""
bought = {}
for s in self.symbol_list:
bought[s] = False
return bought


Виртуальный метод calculate_signals имплементирован именно в этом классе. Метод проходит по всем инструментам в списке и получает последний бар из обработчика bars. Затем он проверяет, был ли инструмент «куплен» (находимся ли мы в рынке по нему, или нет), а затем создается сигнальный объект SignalEvent. Затем он помещается в очередь событий, а словарь bought обновляется соответствующей информацией (True для купленного инструмента):



# strategy.py

def calculate_signals(self, event):
"""
Для "Buy and Hold" генерируем один сигнал на инструмент. Это значит, что мы только открываем длинные позиции с момента инициализации стратегии.

Параметры:
event - Объект MarketEvent.
"""
if event.type == 'MARKET':
for s in self.symbol_list:
bars = self.bars.get_latest_bars(s, N=1)
if bars is not None and bars != []:
if self.bought[s] == False:
# (Symbol, Datetime, Type = LONG, SHORT or EXIT)
signal = SignalEvent(bars[0][0], bars[0][1], 'LONG')
self.events.put(signal)
self.bought[s] = True


Это очень простая стратегия, но ее достаточно для того, чтобы продемонстрировать природу иерархии событийно ориентированной стратегии. В следующей статьей мы рассмотрим более сложные стратегии, например, парную торговлю. Также в следующей статье речь пойдет о создании иерархии Portfolio, которая будет отслеживать прибыль и убыток по позициям (profit and loss, PnL).



Продолжение следует…



P. S. Ранее в нашем блоге на Хабре мы уже рассматривали различные этапы разработки торговых систем. Есть и онлайн-курсы по данной тематике.

Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/264141/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Событийно-ориентированный бэктестинг на Python шаг за шагом. Часть 1

Понедельник, 20 Июля 2015 г. 15:26 (ссылка)





Ранее в нашем блоге на Хабре мы рассматривали различные этапы разработки торговых систем (есть и онлайн-курсы по теме), среди которых одним из наиболее важных является тестирование на исторических данных (бэктестинг). Сегодня речь пойдет о практической релизации событийно-ориентированного бэктест-модуля с помощью Python.



Событийно-ориентированный софт



Прежде, чем погрузиться в разработку бэктестера, следует разобраться с понятием событийно-ориентированных систем. Одним из наиболее очевидных примеров подобных программ являются компьютерные игры. В видеоигре есть множество компонентов, которые взаимодействуют друг с другом в режиме реального времени с высоким фреймрейтом. Справляться с нагрузкой помогает осуществление всех вычислений внутри «бесконечной» петли, которую еще называют петлей событий или игровой петлей.



На каждом тике петли вызывается функция для получения последнего события, которое было сгенерировано каким-либо действием в игре. В зависимости от природы этого события (нажатие клавиши, клик мыши) предпринимается последующее действие, которое либо прерывает петлю, либо создает дополнительные события, и процесс продолжается. Проиллюстрировать все это можно таким псевдокодом:



while True:  # Петля продолжается бесконечно
new_event = get_new_event() # Получаем последнее событие

# В зависимости от типа события выполняем действие
if new_event.type == "LEFT_MOUSE_CLICK":
open_menu()
elif new_event.type == "ESCAPE_KEY_PRESS":
quit_game()
elif new_event.type == "UP_KEY_PRESS":
move_player_north()
# ... and many more events

redraw_screen() # Обновляем экран для отображения соответствующей анимации
tick(50) # Ждем 50 миллисекунд


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



Почему именно событийно-ориентированный бэктестер



Событийно-ориентированные системы обладают рядом преимуществ перед векторизированным подходом:




  • Повторное использование кода. Благодаря своей природе событийно-ориентированный модуль тестирования может быть использован как для работы с историческими данными, так и при реальной торговле на бирже при необходимости лишь минимальной «доводки» компонентов. В случае векторизированных бэктестеров нам необходимо иметь весь набор данных сразу для проведения статистического анализа.

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

  • Реализм. Событийно-ориентированные бэктестеры позволяют значительно кастомизировать процесс выполнения ордеров и оптимизировать транзакционные издержки. Важно уметь работать с базовыми типами ордеров (market, limit) и более сложными (market-on-open, MOO и market-on-close, MOC) — таким образом можно создаться «кастомный» обработчик исключений.



Однако не все так безоблачно, и у событийно-ориентированных систем есь свои недостатки. Во-первых, их значительно сложнее создавать и тестировать — больше «подвижных частей», а значит и больше багов. Поэтому для их создания рекомендуется применять разработку через тестирование. Во-вторых, они работают медленнее векторизированных систем.



Обзор бэктестера



Чтобы применить событийно-ориентированный подход, прежде всего необходимо разобраться с частями нашей системы, которые будут отвечать за определенные участки работы:




  • Событие (event) — это фундаментальная единица класса событийно-ориентированной системы. Содержит тип (например, «MARKET», «SIGNAL», «ORDER» или «FILL»), который влияет на то, как событие будет обрабатываться в петле.

  • Очередь событий (event queue) — in-memory-объект Python, который хранит все объекты подклассов Event, сгенерированные остальными частями системы.

  • DataHandler — это абстрактный базовый класс (АБК), который представляет собой интерфейс для обработки исторических и текущих рыночных данных. Это повышает гибкость системы, поскольку модули стратегии и управления портфолио могут быть использованы как для тестирования на исторических данных так и для работы на «живом» рынке. DataHandler генерирует событие MarketEvent при каждом «ударе сердца» (heartbeat) системы.

  • Модуль стратегии (Strategy) — еще один АБК, который представляет собой интерфейс для забора рыночных данных и генерации на их основе сигнальных событий (SignalEvent), которые используются объектом Portfolio. SignalEvent содержит символ биржевого тикера, направление ордера (Long, Short) и временную метку.

  • Portfolio — также АБК, отвечающий за обработку приказов, связанных с текущей и последующими позициями, подразумевающимися стратегией (Strategy). Сюда же входит риск-менеджмент портфолио, включая контроль размеров позиций и анализ секторов рынка. В более сложных реализациях эта часть работы может быть передана классу RiskManagement. Portfolio берет SignalEvent из очереди и генерирует события ордеров (OrderEvent), которые также попадают в очередь.

  • ExecutionHandler — в нашем случае симулирует соединение с брокерской системой. Задача обработчика заключается в том, чтобы брать события OrderEvent из очереди, выполнять их (в режиме симуляции или через реальное подключение к брокеру). Когда ордер выполнен, обработчик создает событие FillEvent, которое описывает транзакцию, включая комиссии брокера и биржи, а также проскальзывание (если оно учитывается в модели).

  • Петля (Loop) — все описанные компоненты включены в петлю событий, которая обрабатывает все типы событий, направляя их к соответствующему модулю системы.



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



Ниже представлен кусок кода на Python, который демонстрирует практическую работу бэктестера. В коде возникают две петли. Внешняя петля используется для придания бэктестеру сердцебиения (heartbeat). В онлайн-трейдинге это означает частоту, с которой происходит запрос рыночных данных. Для стратегий тестирования на исторических данных — это не обязательный компонент, поскольку рыночные данные вливаются в систему по частям — см. строку bars.update_bars().



Внутренняя петля нужна для обработки событий из объекта Queue. Конкретные события делегируются соответствующим компонентам в очередь последовательно добавляются новые события. Когда очередь пустеем петля сердцебиения делает новый виток:



# Объявление компонентнов с соответствующими параметрами
bars = DataHandler(..)
strategy = Strategy(..)
port = Portfolio(..)
broker = ExecutionHandler(..)

while True:
# Обновляем бары (код для бэктестинга, а не живой торговли)
if bars.continue_backtest == True:
bars.update_bars()
else:
break

# Обрабатываем события
while True:
try:
event = events.get(False)
except Queue.Empty:
break
else:
if event is not None:
if event.type == 'MARKET':
strategy.calculate_signals(event)
port.update_timeindex(event)

elif event.type == 'SIGNAL':
port.update_signal(event)

elif event.type == 'ORDER':
broker.execute_order(event)

elif event.type == 'FILL':
port.update_fill(event)

# следующий удар сердца через 10 минут
time.sleep(10*60)



Классы событий



В описанной схеме есть четыре типа событий:




  • MarketEvent — инициируется, когда внешняя петля начинает новый «удар сердца». Оно возникает, когда объект DataHandler получает новое обновление рыночных данных для любых отслеживаемых финансовых инструментов. Оно используется для того, чтобы запустить генерацию торговых сигналов объектом Strategy. Объект события содержит идентификатор того, что это рыночное событие, и никакой другой структуры.

  • SignalEvent — объект Strategy использует рыночную информацию для создания нового сигнального события SignalEvent. Это событие содержит символ тикера, временную метку генерации и направление ордера (long или short). Такие сигнальные события используются объектом Portfolio в качестве своеобразных подсказок на тему того, как торговать.

  • OrderEvent — когда объект Portfolio получает SignalEvent, он использует такие события для более широкого контекста портфолио (расчет рисков и размера позиции). Все это приводит к созданию OrderEvent, который затем посылается в ExecutionHandler.

  • FillEvent — когда ExecutionHandler получает OrderEvent, он обязан его выполнить. После того, как произошла транзакция, создается событие FillEvent, которое описывает стоимость покупки или продажи и траназкционные издержки (проскальзывания, комиссии и т.п.)



Родительский класс называется Event — это базовый класс, который не предоставляет никакой функциональности или специального интерфейса. В дальнейших реализациях класс Event с большой долей вероятности станет сложнее, поэтому стоит предусмотреть такую возможность заранее, создав иерархию классов:



# event.py

class Event(object):
"""
Event — это базовый класс, обеспечивающий интерфейс для последующих (наследованных) событий, которые активируют последующие события в торговой инфраструктуре.
"""
pass


MarketEvent наследует от Event и несет в себе чуточку больше, чем простая самоидентификация типа ‘MARKET’:



# event.py

class MarketEvent(Event):
"""
Обрабатывает событие получние нового обновления рыночной информации с соответствущими барами.
"""

def __init__(self):
"""
Инициализирует MarketEvent.
"""
self.type = 'MARKET'


SignalEvent требует наличия символа тикера, временной метки и направления ордера, которые объект портфолио может использовать в качестве «совета» при торговле:



# event.py

class SignalEvent(Event):
"""
Обрабатывает событие отправки Signal из объекта Strategy. Его получает объект Portfolio, который предпринимает нужное действие.
"""

def __init__(self, symbol, datetime, signal_type):
"""
Инициализирует SignalEvent.

Параметры:
symbol - Символ тикера, например для Google — 'GOOG'.
datetime - временная метка момента генерации сигнала.
signal_type - 'LONG' или 'SHORT'.
"""

self.type = 'SIGNAL'
self.symbol = symbol
self.datetime = datetime
self.signal_type = signal_type


OrderEvent сложнее, чем SignalEvent, и содержит дополнительное поле для указания количества единиц финансового инструмента в ордере. Количество определяется ограничениями объекта Portfolio. Вдобавок OrderEvent содержит метод print_order(), который используется для вывода информация в консоль при необходимости:



# event.py

class OrderEvent(Event):
"""
Обрабатывает событие отправки приказа Order в торговый движок. Приказ содержит тикер (например, GOOG), тип (market или limit), количество и направление.
"""

def __init__(self, symbol, order_type, quantity, direction):
"""
Инициализирует тип приказа (маркет MKT или лимит LMT), также устанавливается число единиц финансового инструмента и направление ордера (BUY или SELL).

Параметры:
symbol - Инструмент, сделку с которым нужно осуществить.
order_type - 'MKT' или 'LMT' для приказов Market или Limit.
quantity - Не-негативное целое (integer) для определения количества единиц инструмента.
direction - 'BUY' или 'SELL' для длинной или короткой позиции.
"""

self.type = 'ORDER'
self.symbol = symbol
self.order_type = order_type
self.quantity = quantity
self.direction = direction

def print_order(self):
"""
Выводит значения, содержащиеся в приказе Order.
"""
print "Order: Symbol=%s, Type=%s, Quantity=%s, Direction=%s" % \
(self.symbol, self.order_type, self.quantity, self.direction)


FillEvent — это Event повышенной сложности. Оно содержит временную метку исполнения приказа, тикер и информациб о бирже, на которой он был исполнен, количество единиц финансового инструмента (акций, фьючерсов и т.п.), фактическую цену сделки и сопутствующие комиссии.



Сопутствующие издержки вычисляются с помощью API брокерской системы (у ITinvest есть свой API-интерфейс). В нашем примере используется система американского брокера, комиссия которого составляет минимум $1.30 с ордера с единой ставкой от $0,013 или $0,08 за акцию в зависимости от того, превышает ли количество акций 500 единиц или нет.



# event.py

class FillEvent(Event):
"""
Инкапсулирует понятие исполненного ордера (Filled Order), возвращаемое брокером.
Хранит количество единиц инструмента, которые были куплены/проданы по конкретной цене.
Также хранит комиссии сделки.
"""

def __init__(self, timeindex, symbol, exchange, quantity,
direction, fill_cost, commission=None):
"""
Инициализирует объек FillEvent.
Устанавливает тикер, биржевую площадку, количество, направление, цены и (опционально) комиссии.

Если информация о комиссиях отсутствиет, то объект Fill вычислит их на основе объема сделки
и информации о тарифах брокерах (полученной через API)

Параметры:
timeindex - Разрешение баров в момент выполнения ордера.
symbol - Инструмент, по которому прошла сделка.
exchange - Биржа, на которой была осуществлена сделка.
quantity - Количество единиц инструмента в сделке.
direction - Направление исполнения ('BUY' или 'SELL')
fill_cost - Размер обеспечения.
commission - Опциональная комиссия, информация отправляемая бркоером.
"""

self.type = 'FILL'
self.timeindex = timeindex
self.symbol = symbol
self.exchange = exchange
self.quantity = quantity
self.direction = direction
self.fill_cost = fill_cost

# Calculate commission
if commission is None:
self.commission = self.calculate_ib_commission()
else:
self.commission = commission

def calculate_ib_commission(self):
"""
Вычисляет издержки торговли на основе данных API брокера (в нашем случае, американского, т.е. цены в долларах).

Не включает комиссии биржи.
"""
full_cost = 1.3
if self.quantity <= 500:
full_cost = max(1.3, 0.013 * self.quantity)
else: # Greater than 500
full_cost = max(1.3, 0.008 * self.quantity)
full_cost = min(full_cost, 0.5 / 100.0 * self.quantity * self.fill_cost)
return full_cost


На сегодня все, спасибо за внимание. В следующей части мы поговорим об использовании рыночной информации (класс DataHandler) для тестирования на исторических данных и при реальной торговле.



Продолжение следует…

Original source: habrahabr.ru (comments, light).

http://habrahabr.ru/post/263097/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
heregirl

Самая прибыльная торговая стратегия опционов 2015

Суббота, 30 Мая 2015 г. 07:09 (ссылка)

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

Читать далее...
Комментарии (0)КомментироватьВ цитатник или сообщество
Вечерком

Бесплатный робот для бинарных опционов

Среда, 27 Мая 2015 г. 22:00 (ссылка)


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

Но в свою очередь, хочу заметить, что не стоит верить всем без исключения, а лучше всего обращать внимание на торговые стратегии, которые рекомендуют вам друзья или очень близкие люди.

Исходя из этих соображений, я решила предложить вам воспользоваться ссылкой бинарные опционы стратегии и познакомиться с одной из самых прибыльных стратегий бинарных опционов «High-power option 2015», которая уже помогла заработать многим моим знакомым.







Ну а если вы еще не уверенны в своих силах и боитесь наделать глупых ошибок, то воспользуйтесь услугами бесплатного советника для бинарных опционов – “ATS-binary-2014″, о котором вы можете получить дополнительную информацию, посетив сайт, воспользовавшись предложенной ссылкой.

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

Комментарии (0)КомментироватьВ цитатник или сообщество
Khushi24

Бесплатный робот для бинарных опционов

Вторник, 21 Апреля 2015 г. 08:40 (ссылка)






Работа на бинарных опционах предполагает постоянный анализ графиков, исследований, которые позволят с максимальной точностью определить рост или спадание цены на тот или иной актив. Для того, чтобы правильно прогнозы были максимально точными, советую обратить внимание на бинарные опционы стратегии, которые станут вашим надежным советником. Торговые стратегии, которые показали свою эффективность дадут вам четкое представление того, в какую сторону на данный момент будет двигаться график. Для того, чтобы найти свою стратегию, советую ознакомиться с обзорами стратегических советников. Кроме того, вам понадобиться бесплатный робот для бинарных опционов , который гарантирует хороший и что самое главное – стабильный заработок на опционах. На самом деле, если уметь пользоваться инструментами, знать, когда лучше делать ставки и когда цена колеблется меньше всего, можно выйти на высокий заработок.

Комментарии (0)КомментироватьВ цитатник или сообщество
Maria2406

Бесплатный робот для бинарных опционов

Среда, 08 Апреля 2015 г. 10:00 (ссылка)


Стратегии для бинарных опционов позволяют с большой долей вероятности определить дальнейшее колебание курса и сделать правильные ставки. На самом деле точность прогнозов зависит от многих факторов, в том числе и от времени, когда вы делаете ставку. Опытные брокеры тщательно выбирают время истечения опциона и уже тогда определяются со ставкой, анализируя свои предыдущие результаты. Изучить бинарные опционы стратегии, с помощью которых можно значительно увеличить свои шансы, вы можете на сайте fx-gold.net.







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

Комментарии (1)КомментироватьВ цитатник или сообщество
SuperFamily

Самая прибыльная торговая стратегия опционов 2015

Суббота, 28 Марта 2015 г. 13:55 (ссылка)


2835299_Izmenenie_razmera_Samaya_pribilnaya_torgovaya_strategiya_opcinov_20153 (700x450, 35Kb)/3180456_binarnie (600x159, 27Kb)



2835299_Samaya_pribilnaya_torgovaya_strategiya_opcinov_2015 (312x157, 149Kb)На правах рекламы... На сегодня я не прорублю окно в Америку, если заявлю, что бинарный опцион – выгодный способ заработка. А чтобы зарабатывать таким образом, надо знать насколько упадёт или вырастет цена того или иного актива: золота, нефти, валюты, стоимости акций.


 


Людям, которые в этом разбираются и зарабатывают миллионы, я завидовал всегда, но для себя понимал, что зарабатывать таким образом может не каждый желающий, стать трейдером было моей нереальной мечтой. Однако, в наше прогрессивное время торговля бинарными опционами стала более доступной всем, кто имеет желание зарабатывать таким образом себе на жизнь.


 


Торговля бинарными опционами привлекательна многим, например, прибыль ждать долго не придется, на это может уйти минута, а не год, как в случае с банковским вкладом. Учитывая все нюансы, разобраться самостоятельно с  подобным способом зарабатывания денег будет трудно, но есть специалисты, которые могут помочь в этом. Советник для бинарных опционов “ATS-binary-2014″ и оказывает такую помощь желающим разобраться во всех нюансах данной стратегии.


 


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


 


2835299__1_ (453x248, 29Kb)Самая прибыльная торговая стратегия бинарных опционов 2015 года представлена на страничке бинарные опционы стратегии. Чтобы разобраться в доступных стратегиях, надо прежде всего знать, что все стратегии бинарных опционов содержат в себе:


 


Актив, чтобы организовать торговлю,


время, на которое заключена сделка,


правила открытия позиций,


название технических индикаторов,


анализ важнейших макроэкономических событий.


 


Споров вокруг самой выгодной стратегии ведеться немало, но следует обратить внимание на новую разработку  «High-power option 2015» - это довольно простая стратегия,  для изучения которой нужно приложить немного терпения, внимания, которые в дальнейшем окупятся с лихвой.


 


Брокер торговых опционов Optitrade24 просто создан для торговли по такой стратегии, ведь среди его преимуществ - наличие стратегического советника для немедленного анализа любого актива посредством различных индикаторов. 








2835299_Izmenenie_razmera_Samaya_pribilnaya_torgovaya_strategiya_opcinov_2015_ (700x500, 34Kb)

Комментарии (0)КомментироватьВ цитатник или сообщество
Gloritta

Бесплатный робот для бинарных опционов

Четверг, 26 Марта 2015 г. 10:37 (ссылка)






С чего начинать в заработке на бинарных опционах? Этот вопрос волнует многих начинающих трейдеров. Ведь, как показывает практика, даже малейшее отклонение от реальных показателей в ставке может сыграть не в твою пользу, и тогда ты теряешь деньги. Не стоит полагаться на удачу. Ведь опытные трейдеры используют инструменты для прогнозирования курса и скачка цен на те или иные активы. Изучить бинарные опционы стратегии можно на сайте и здесь же найти обзоры лучших брокеров, с которым можно безопасно сотрудничать. Кроме стратегий или советников, вам также поможет бесплатный робот для бинарных опционов , ознакомиться с которым вы можете на сайт, посвященному работе с опционами и заработку на них. Опытные трейдеры поделятся с вами своими наработками, вы узнаете, как грамотно делать ставки. Даже время ставки имеет значение в конечном результате для получения прибыли.


Комментарии (1)КомментироватьВ цитатник или сообщество

Следующие 30  »

<торговые стратегии - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda