Проект Meta COT - новые горизонты анализа отчетов CFTC в терминале MetaTrader 4

Vasiliy Sokolov | 15 октября, 2009

Введение

Движение рыночных цен определяется не субъективными волнами Эллиота, линиями Ганна и уровнями Фибоначчи, не техническими индикаторами, ни один из которых не содержит ни бита новой информации по сравнению с графиком цены формата OHLCV. Движение биржевых цен определяет фундаментальный закон спроса и предложения. Сколь ни банальным может показаться это утверждение, однако уровни спроса и предложения определяют цену.

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

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

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

По прошествии более двух лет с момента выхода русскоязычного издания книги в свет, для самой распространенной торговой платформы в РФ - MetaTrader 4, так и не появился универсальный, удобный, открытый комплекс программного обеспечения, поддерживающий эту концепцию. Эта статья заполняет этот разрыв. Теперь любой желающий может заставить теорию, изложенную в книге Ларри Вильямса работать на практике, - в своем терминале MetaTrader.

Методика анализа текущей рыночной ситуации на основе отчетов по сделкам трейдеров относится к фундаментальному виду анализа.

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

Во-вторых, такой анализ считается непараметризированным, а значит крайне субъективным.

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

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

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


1. Рынок как уравновешивающая функция цен


1.1 Закон спроса и предложения

Рынок – это институт, или механизм, сводящий вместе покупателей (предъявителей спроса) и продавцов (тех, кто обеспечивает предложение) отдельных товаров и услуг.[3]

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


Общая величина предложения

Цена за бушель (в долл.)

Общая величина спроса за неделю

Избыток (+) или нехватка (-)

12 000

5

2 000

+10 000

10 000

4

4 000

+6 000

7 000

3

7 000

0

4 000

2

11 000

-7 000

1 000

1

16 000

-15 000


Таблица 1-1. Рыночное предложение кукурузы и спрос на неё (в тыс. бушелей)


Здесь представлена взаимосвязь между продавцами и покупателями кукурузы, выраженная через ее цену и объем поставок. Продавцы желают продать свой товар как можно дороже, а покупатели купить их товар как можно дешевле. В данном случае, при цене 5 долларов за бушель, желающих продать кукурузу будет весьма много. Их совокупное предложение составит 12 000 бушелей. Но проблема продавцов заключается в том, что при такой высокой цене на их товар не найдется столько желающих его купить. При такой высокой цене найдется покупателей только на 2 000 бушелей. Остальные 10 000 бушелей (12 000 – 2 000 = 10 000) останутся нереализованными, что вызовет излишки товара у продавцов при одновременном дефиците товара у покупателей. Такая цена неспособна удержаться на рынке. Многие продавцы станут снижать цены, только чтобы избавится от излишков товара и получить хоть меньшие, но зато реальные деньги. К ним присоединятся другие продавцы, желающие упредить своих коллег-конкурентов. Начнется конкуренция между продавцами, которая вызовет снижение цен [3].

Теперь рассмотрим противоположенный вариант. На этот раз предположим, что цена кукурузы крайне низка и составляет всего 1 доллар за бушель. При такой цене от желающих купить кукурузу не будет отбоя. Их совокупный спрос составит 16 000 бушелей. Только вот желающих продать по такой цене будет гораздо меньше. Совокупное предложение (продажи) составит всего 1 000 бушелей, что опять-таки вызовет дефицит товара у покупателей в размере 15 000 бушелей, при одновременном излишке у продавцов. И снова такая цена не способна удержаться на рынке. Некоторые из покупателей начнут приобретать кукурузу по более высокой цене, желая заполучить необходимый им товар. К этим покупателям начнут присоединятся их коллеги, предвидящие дальнейшей рост цены и желающие быть одними из первых, кто купил относительно дешево. Начнется конкуренция между покупателями, которая вызовет повышение цен [3].

Теперь для наглядности изобразим взаимосвязанные функции Спроса и Предложения на графике:



График 1-2. Функции спроса и предложения


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

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

Рассмотрим пример, когда предложение увеличится при неизменном спросе (точки А-B на графике 1-3, a). В этом случае цена упадет (p1<p2), ведь товара станет больше и начнется конкуренция между продавцами. С другой стороны желающих купить товар по более выгодной цене появится больше (q3>q2).

Теперь рассмотрим случай, когда предложение уменьшиться (точки А-С на графике 1-3a). Это вызовет повышение цен, ведь товара станет меньше и начнется конкуренция между покупателями (p3>p2). Конечно желающих купить более дорогой товар станет меньше.



Рисунок 1-3a. Изменение предложения при неизменном спросе


То же верно и для спроса – когда он увеличивается (точки A-B на графике 1-3б), цена начинает расти, а значит, желающих продать товар по более высокой цене станет больше, что выразится в увеличении совокупного предложения (q3>q2). В обратной ситуации, когда спрос начнет уменьшаться, цена будет падать, желающих продавать по низкой цене будет все меньше, и таким образом, совокупное количество предложения будет уменьшаться (q1<q2).



Рисунок 1-3б. Изменение спроса при неизменном предложении


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

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

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

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

4. Спрос растет, предложение падает. При возрастающем спросе цена будет увеличиваться, ровно как она будет увеличиваться при сокращающемся предложении. В итоге цена будет расти больше, чем от каждого фактора в отдельности.

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




График 1-4. Спрос и предложение в динамике


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



График 1-5. Фазы рынка


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

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

2. Фаза средних цен. В этой фазе с одной стороны обеспечивается приемлемый уровень цен при достаточно высоком объеме. В этой фазе нет дефицита у покупателей как и нет излишков у продавцов. Именно здесь находится точка равновесных цены и количества товара [3]. Такая усредненная точка показана на графике.

3. Фаза высоких цен. Характеризуется высокими ценами (P) при одновременно высоких объемах (Q). Реальное предложение со стороны производителей товара будет высоким, в то время как спрос со стороны покупателей будет ограниченным. Нежелание у покупателей приобретать товар дорого и желание производителей продавать товар дорого вызовут конкуренцию производителей, которая в конечном счете приведет к падению цены.

Иными словами, закон спроса и предложения определяет возвратно-трендовое движение рынка. В среднесрочном периоде (очень приблизительно в масштабе времени 1-1,5 года) рынок будет идти от фазы низких цен к фазе высоких цен или наоборот, то есть будет трендовым. В долгосрочном периоде (от года и более) рынок будет идти до фазы высоких или низких цен, сталкиваться с сопротивлением покупателей или продавцов и под их действием разворачиваться назад, т.е. он будет контртрендовым. Движение рынка можно образно сравнить с дыханием. После полного выдоха очень сложно найти еще хотя бы немного воздуха в легких, чтобы продолжить его выдыхать.

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

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

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


1.2 Цена – первая переменная уравнения спроса и предложения

Обратимся за примером низких и высоких цен к недельному графику сахара:



График 1-6. Сахар, недельные бары


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

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

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

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

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

Вот график доходности элементарной системы основанной на индикаторе RSI:



График 1-7. Доходность робота, основанного на индикаторе RSI. EURUSD, дневные бары, 2000-2009 гг.


Система элементарна. Если 7-ми периодичный RSI достигает 80 процентов, то открывается сделка Sell. Если же RSI достигает 20%, то открывается сделка Buy. Нестандартный период выбран для того, чтобы было совершено больше сделок. Стоп равен 100 пунктам, а выход осуществляется по уровню прибыли в 200 пунктов. Тестирование проводилось на EURUSD, с 2000 по 2009 год, на дневных барах. Лот на всех сделках фиксированный – 0.1 лота.

Выводы однозначны: одной цены явно недостаточно для определения фазы рынка. Необходима вторая переменная уравнения спроса и предложения – объем рынка.


1.3 Открытый интерес – вторая переменная уравнения спроса и предложения

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

Открытый интерес – это количество контрактов находящихся на фьючерсном и/или опционном рынке и некомпенсированных сделкой, поставкой, исполнением и т.п. Открытый интерес является суммой всех длинных или коротких позиций [1]. Так например, если сумма всех длинных позиций на рынке равна 1000 контрактов, то это означает что сумма всех коротких позиций на этом же рынке тоже равна 1000 контрактов, а открытый интерес составляет те же 1000 контрактов. Формула открытого интереса представлена ниже:

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

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

Открытый интерес подсчитывается ежедневно в конце каждой сессии на всех фьючерсных рынках. Эта информация не является закрытой и она, как правило, доступна на официальных сайтах бирж. Так же данные по открытому интересу можно получить подписавшись на платную рассылку сигналов типа e-Signal. Для пользователей MetaTrader данные по открытому интересу для более чем 40 рынков можно получить с помощью индикатора «Meta COT: Net Position», входящим в состав Meta COT. Более подробно о том, как пользоваться этим индикатором Вы узнаете в третьей части.

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

Теперь давайте посмотрим на динамику открытого интереса на золото за длительный период времени:



График 1-8. Золото. Недельный график


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

То, что верно для золота, верно и для любого другого товара, закон спроса и предложения работает на любом открытом рынке:



График 1-9. Соевая мука. Недельный график



График 1-10. Казначейские бонды. Недельный график


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

На экстремально высоких уровнях открытого интереса постарайтесь зашортить.

На экстремально низких уровнях открытого интереса постарайтесь купить.


2. Структура рынка

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

2.1 Хеджеры и спекулянты – неотъемлемые части рыночной структуры.

Итак, рынок постоянно и эффективно находит точку пересечения спроса и предложения. Эта точка является консенсусом цены актива, то есть той ценой при которой продавцы готовы продать определенный объем товара, а покупатели купить этот объем товара. Под действием постоянно меняющихся фундаментальных, политических, случайных и прочих факторов уровень спроса и предложения находится в постоянной динамики. Исходя из закона спроса и предложения, цена на актив также находится в постоянном движении. Следовательно, существует определенная вероятность что будущая стоимость актива будет либо больше либо меньше текущей. Раз цена может изменятся со временем, то активу, для которого эта цена установлена, присуща ценовая неопределенность в будущем. Такую ценовую неопределенность стоимости актива в будущем принято называть риском [6].

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

Если этот товар зерно, то его владельцем может быть фирма General Mills, а если золото – то например компания Barrick Gold Corp. Так как риск изменения цены высокий, а основной вид дохода этих компаний заключен в разнице между себестоимостью их продукции и ценой ее реализации, они заинтересованы в уменьшении риска, который возникает в следствии владения товаром. Для этого производители используют операции хеджирования на товарных и финансовых рынках. По сути дела производители продают свой риск желающим его купить. Вместе с риском покупатели приобретают возможность получения дохода от благоприятного изменения цены (премия за риск).

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

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

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

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

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

2.2 Анализ отчетов комиссии по торговле товарными фьючерсами

У любого желающего есть возможность наблюдать за позициями хеджеров и спекулянтов, благодаря американской правительственной организации Commodity Futures Trading Comission – CFTC. Дело в том, что любое частное или юридическое лицо обязано отправлять отчет о совершаемых ею сделках на товарных биржах, если объем этих сделок составит или превысит установленный уровень определенный комиссией. Один раз в неделю комиссия составляет отчет по совокупным позициям трейдеров.

Каждый такой отчет публикуется на официальном сайте компании: www.cftc.gov. Отчет составляется по состоянию на каждый вторник, а публикуется в пятницу поздно вечером по московскому времени. Сам отчет представлен в нескольких видах: таблицы Exсel, текстовом файле-таблице формата CSV, а также в виде простого табличного текста. Также возможно скачать историю отчетов за длительный период времени в форматах Exсel и CSV. Отчеты составляются как по фьючерсным сделкам, так и по фьючерсным и опционным сделками. Сами по себе отчеты имеют краткую и расширенную форму. Расширенная форма отличается от краткой наличием дополнительной статистикой а также данными по урожайности для некоторых сельскохозяйственных культур. В практике анализа отчетов CFTC используются файлы Exсel или CSV, в них указана полная форма отчетов. Теперь давайте взглянем на краткий отчет по пшенице за 4 августа 2009 года:



Таблица 2-1. Отчет по пшенице за 04.08.2009 (только фьючерсы)


Вверху отчет содержит название товара, в данном случае это пшеница, торгуемая на Чикагской товарной бирже, вид отчета, - только фьючерсы, и дату, - 4 августа 2009 года. Сама таблица состоит из четырех основных колонок. В каждой из них представлена совокупная короткая и длинная позиция каждой из трех групп трейдеров. К первой группе трейдеров относятся крупные спекулянты. В отчетах они называются некоммерческими трейдерами (NON-COMMERCIAL). Мы видим, что на 4 августа 2009 года у крупных спекулянтов было 75 933 контракта, в то время как на короткой стороне у них находилось 97 574 контракта. Это говорит о том, что их совокупная или чистая позиция была короткой и составляла -21 641 контракт. Как правило, это не типичная ситуация для спекулянтов.

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

Где NetPosition – чистая или совокупная позиция трейдеров, i – категория трейдеров, например крупные некоммерческие трейдеры или крупные коммерческие трейдеры.

Далее следует количество контрактов крупных некоммерческих трейдеров находящихся в так называемом спрэде (spreads) или покрытии. Вот что пишет по этому поводу Ларри Вильямс: «Если некоммерческий трейдер держит фьючерсами на евро/доллар 2 000 длинных контрактов и 1 500 коротких контрактов, то 500 контрактов войдут в категорию «Длинные» и 1 500 контрактов в категорию «Покрытие» [1]. Если говорить проще, то покрытие показывает количество как длинных так и коротких контрактов.

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

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

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

Давайте рассмотрим конкретную ситуацию на примере нашего отчета по пшенице. На длинной стороне у операторов находится 166 518 контрактов, в то время как на длинной 130 979 контрактов. Их чистая позиция составляет 35 539 контрактов, т.е. является длинной. Зачастую это означает, что цена на товар находится на низком уровне, т.к. операторы меньше продают чем покупают. В любом случае для точного определения ситуации необходимо использовать график их чистой позиции за длительный период времени.

Колонка «Total» содержит совокупные длинные и совокупные короткие позиции коммерческих и не коммерческих трейдеров. Практического интереса она не представляет.

Колонка «Nonreportable Positions», содержит количество длинных и коротких неподотчетных позиций трейдеров. По сути эта графа отражает позиции мелких спекулянтов, чьи позиции слишком малы, чтобы попасть в группу спекулянтов. Эти позиции высчитываются синтетическим расчетом – от значения открытого интереса (OI) отнимается совокупные длинные и совокупные короткие позиции подотчетных трейдеров. В нашем случае OI составляет 322 431 контракт, в то время как подотчетных длинных контрактов всего 279 239 контрактов, это означает что 29 194 контракта держат на длинной стороне не подотчетные лица (322 431 – 279 239). Те же вычисления можно привести для короткой стороны: 322 431 - 279 339 = 43 092 контракта.

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

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



Таблица 2-2. Краткий отчет по пшенице 04.08.2009. Фьючерсы и опционы


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

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



График 2-3. Полный отчет по фьючерсам и опционам на пшеницу за 04.08.2009


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


2.3 Наблюдаем за позициями крупных хеджеров

Итак, настало время составить статистику покупок и продаж хеджеров и проследить за их действиями в течении длительного периода времени. Для примера используем ценовой график уже знакомой нам пшеницы с наложенным на него индикатором, показывающим длинные и короткие позиции операторов. График состоит из недельных баров и охватывает период с середины 2001 по середину 2009 года:



График 2-4. Пшеница, длинные и короткие позиции операторов, недельные бары


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



График 2-5. Чистые позиции операторов. Недельные бары


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

Обратите внимание на экстремально высокую чистую позицию операторов в конце 2005 года! Никогда еще до этого ни после того, операторы не имели такого высокого значения чистой позиции. А теперь посмотрите, что происходило с рынком после этого. Началось неумолимое движение вверх, продолжавшееся более 2 лет. В результате цена поднялась более чем на 700 (!) долларов. Здесь были и другие моменты, указывающие нам на благоприятную возможность для спекуляции.

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

Ключевыми словами здесь являются «незадолго после этого». Не забывайте, что этот индикатор не рассчитывается с помощью цены. Он полностью от нее независим. Мы могли бы убрать график цены, но индикатор чистой позиции операторов все равно показывал бы те же значения. Цена – последнее рыночное изменение. Сначала меняется баланс сил спроса и предложения, а еще до этого меняется умонастроения крупных участников рынка. Наблюдая за тем, что делают операторы, мы наблюдаем за изменением рынка еще на ранней стадии, когда изменения цены еще не последовало. Это дает нам уникальное преимущество занять место в еще полупустом вагончике будущего тренда-локомотива. Когда поезд тронется, многие опоздают на него, но только не трейдеры использующие отчеты комиссии!

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



График 2-6. Золото, чистые позиции операторов. Недельные бары


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

Обратите внимание на то сумасшествие что творилось с золотом в конце 2008 года. После сильного падения закончившегося в первых числах сентября, начался неожиданный подъем. Фактически за один день золото взметнуло вверх на 90 долларов! После чего до конца сентября находилось на высокой ценовой отметке, правда весьма не долго. Вскоре после этого случился новый обвал, и в конце октября золото обновило свой годовой минимум.

Могли бы мы хотя бы частично предсказать эту тряску? Вполне, и все благодаря использованию отчетов по сделкам трейдеров. Обратите внимание, что не задолго до бычьей пятницы (именно в этот день золото «неожиданно» поднялось на 90 долларов), операторы практически перестали продавать этот металл. На этом рынке они являются производителями товара, и все эти годы не было бы ни одной недели, когда их покупки превышали бы продажи. Фактически своим отказом от продаж они вызвали панику среди золотых быков. Возник дефицит металла взметнувший цены вверх.

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



График 2-7. Серебро и чистые позиции операторов. Недельные бары


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

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


2.4 Индекс чистой позиции

Что считать «относительно» высоким уровнем чистой позиции, а что низким? Как правильно заметил Ларри Вильямс, пол для одного является потолком для другого. Поэтому необходимо использовать нормализованный индикатор, который бы четко говорил о том, в какой фазе находятся отслеживаемые нами позиции. Такой индикатор существует, он называется COT Index. Индекс представляет из себя не что иное как обычный стохастический осциллятор, рассчитанный для значений отслеживаемых позиций. Напомню его формулу [1]:


Т.е. текущий уровень цен сравнивается с максимальной амплитудой цен за три года. Индекс может рассчитывается за любой период времени, а не только за три года. Принято использовать период не менее 26 недель, т.е. полугодовой индекс. В более долгосрочных сделках используется 156 недельный или трех летний индекс. Индекс показывает относительную текущую силу в процентах, по сравнению с выбранным периодом. Пример расчета индекса для операторов приведен ниже, цифры означают количество контрактов [1]:


Значение текущей недели

350

Минимальное значение за последние три года

-150

Разность

200

Максимальное значение за последние три года

750

Минимальное значение за последние три года

-150

Разность

600

Индекс = (200/600)x100=0,33x100=33%;

Т.е. в данном случае операторы настроены скорее по медвежьи чем по бычьи. Если индекс достигает экстремально низких уровней, т.е. находится в нижних 20%, то рынок склонен к падению. Если индекс достигает экстремально высоких уровней, т.е. находится в верхних 80%, то рынок склонен к развороту вверх. Чтобы убедится в этом, давайте взглянем на тот же график серебра, но уже с помощью 156 недельного индекса:



График 2-8. Серебро и 156-недельный индекс операторов. Недельные бары


Можно использовать и более низкие пороговые уровни, например 75% и 25%. Смысл будет неизменным, индикатор будет указывать на потенциальные зоны перекупленности и перепроданности.
Как ни странно, но период индекса не сильно изменяет картину динамики отслеживаемых позиций. Вот пример нескольких индексов с различными периодами усреднения для серебра:




График 2-9. Различные периоды индекса операторов для серебра. Недельные бары



Здесь используется (сверху вниз) 156 недельный, 104 недельный, 52 недельный и 26 недельные индексы операторов. Только 26 недельный индекс показывает более частую амплитуду движения. Остальные виды усреднения практически не изменяют вид индикатора. Какой период усреднения использовать зависит от личных предпочтений каждого. Можно, например, использовать 156 недельный период усреднения, он показывает динамику изменения позиций достаточно широко, и в то же время дает четкий процентный результат бычьего настроя отслеживаемых позиций.

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


2.5 Структура открытого интереса

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

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

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

OI = Noncommercial Traders Long + Noncommercial Traders Spreading + Operators Long + Nonre-portable Long;
OI = Noncommercial Traders Short + Noncommercial Traders Spreading + Operators Short + Nonre-portable Short;

Теперь обратимся к отчету за 4 августа 2009 по фьючерсам на евро и рассчитаем открытый интерес для этого рынка используя эти две формулы:



Таблица 2-10. Отчет по фьючерсам на евро за 4 августа 2009 года


OI = 61 443 + 946 + 22 984 + 52 864 = 138 237;
OI = 34 337 + 946 + 72 454 + 30 500 = 138 237;

Независимо от формулы подсчета уровня открытого интереса, результат один и тот же. Однако можно заметить, что в данном случае, длинные позиции в основном удерживают крупные неком-мерческие трейдеры (61 337 контрактов), в то время как операторы предпочитают шортить (52 864 контракта). Логичным продолжением анализа структуры открытого интереса был бы расчет доли каждой из этих трех групп в открытом интересе. Например, доля коротких позиций операторов за представленный период составила 52,4 % от открытого интереса (78 454 / 138237 x 100%). Этот показатель представлен в разделе «Percent of open interest for each category of traders».

Однако интерес представляет динамика изменения доли каждой из трех групп трейдеров. Если собрать эту информацию за длительный период времени можно построить соответсвующий график. Расчетом такого графика занимается индикатор «Meta Cot: Percent Position in OI». Он рассчитывает эти данные для каждой из трех групп трейдеров.

На рисунке 2-14 изображен долгосрочный график фьючерса на японскую йену. Всякий раз, когда доля короткой позиции операторов составляла 70% и более от открытого интереса йена была близка к своему развороту вниз. Красной пунктирной линией отмечены такие моменты. Тоже верно и для разворотов вверх. Практически всякий раз, когда доля коротких позиций операторов была ниже 30% от открытого интереса, рынок был близок к своему дну, а зачастую после этого начинали свое движение долгосрочные бычьи тренды.



График 2-11. Доля короткой позиции операторов в открытом интересе. Японская йена, недельные бары


Ларри Вильямс в своей книге «Секреты торговли на фьючерсном рынке» [1] предлагает связать значения открытого интереса и чистой позиции операторов в один индикатор. В самом деле, если относительная чистая позиция операторов достаточно низкая и в то же время они держат существенную долю рынка то можно предположить, что рынок близок к своему максимуму и в скором времени произойдет разворот вниз. Такой индикатор рассчитывается по формуле:

Stochastic Oscillator (Net Operators / OI);

Иными словами чистая позиция операторов делиться на открытый интерес, эти данные собираются за длительный период времени, и на их основе рассчитывается стохастический осциллятор. Этот индикатор получил название индекс операторов Вильямса (Williams Commercial Index), или просто WILLCO. Сам Ларри Вильямс рекомендует использовать 26 периодное или полугодовое усреднение, однако можно использовать и другие виды усреднения, например годовое (52-недельное) или трех летнее (156-недельное).

Принцип его использования тот же, что и индекса COT, всякий раз когда его значение превышает 80% - ждите разворот рынка вниз, всякий раз когда его значение ниже 20% - ждите разворота рынка вверх. На рисунке 2-15 представлен индикатор WILLCO применительно к японской йене. На графике красными пунктирными линиями показаны те же самые уровни, которые были отмечены самим Ларри Вильямсом на этом же самом графике [1]:



График 2-12. 26-недельный WILLCO и недельный график японской йены

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



График 2-13. 156 недельный WILLCO и недельный график казначейских бондов


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


2.6 Индикаторы изменения моментума

Этот индикатор предложил использовать Стэфан Брис, в своей книге «The Commitments of Traders bible». Его принцип действия прост, он представляет разницу между текущим COT-индексом и этим же индексом 6 периодов назад, вот его формула:

COT-Index (p) – COT-Index(p-n);

Где p – текущий уровень индекса, n – период равный 6.

Замечу, что дельта индекса может быть в принципе любой, а не только 6-периодной. Кроме того, индекс можно рассчитать для всех участников фьючерсного рынка, и даже для самого открытого интереса. Этот индикатор получил название Movement Index, или просто индекс движения. В основном он применяется для подтверждения завершения коррекции на долгосрочных трендах. Показания интерпретировать просто. Если значения индекса поднимается выше 40% - текущее нисходящее движение подходит к концу. Ожидается подъем цен. Если значение индекса опускается ниже 40% - текущее восходящее движение подходит к концу. Ожидается снижение цен. Давайте поработаем с этим индикатором на примере фьючерса на евро:



График 2-14. Movement Index EURO


Евро за прошедшие годы имело устойчивый повышательный тренд. Синими стрелками указаны места, где индикатор пересекал 40% барьер. Обратите внимание на невероятную точность индикатора, всякий раз после того, как индикатор пробивал 40% уровень, цена завершала свою коррекцию, и евро продолжал расти. Показания индикатора к продажам не были столь точны. Однако за-астую, после того как movement index пробивал нижнюю границу -40%, начиналась коррекция. Необходимо учитывать реактивность индикатора. Он является своего рода барометром моментума COT. Он хорошо показывает турбулентность рынка. Его применение особенно хорошо в агрессивной и менее долгосрочной торговле.

Следующий индикатор является экспериментальным и до этого времени нигде не описывался. Ларри Вильямс в девятой главе его книги исследует изменение открытого интереса на фоне действия операторов. При этом не совсем ясно как конкретно использовать эту взаимосвязь. На одних примерах Ларри Вильямс показывает дивергенцию/конвергенцию. На других делает вывод о том, что увеличения продаж или покупок операторов также увеличивает уровень OI. Исследование индекса движения подтолкнуло на мысль о том, что вполне возможно следить за изменением позиций операторов на фоне изменения уровня открытого интереса. Наиболее интересными представляются следующие модели взаимодействий:

1. уровень открытых позиций падает – уровень чистой позиции операторов растет.

2. уровень открытых позиций растет – уровень чистой позиции операторов падает.

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

Movement Index (Operators) – Movement Index (Open Interest);

В целом, его показания похожи на показания простого Movement Index, как и показания WILLCO похожи на показания COT Index. Здесь приблизительным критическим уровнем будут значения 60% и -60% соответственно. Его анализ проводится по тем же правилам что и обычный индекс движения. Рассмотрим поведение этого индекса на примере евро:



График 2-15. Spread Movement Index EURO


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


2.7 Наблюдаем за позициями крупных товарных фондов

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

По некоторым оценкам наиболее часто фонды выбирают 26-недельный максимум/минимум [1,79]. Фонды входят на рынок постепенно, используя технику наращивания позиций, к тому же многие фонды используют более долгосрочные стратегии входа. Например, если цена достигла своего 26-недельного максимума, некоторые из фондов открывают длинные позиции. Затем цена двигается дальше наверх и достигает своего 52-недельного максимума. Более осторожные фонды включаются в игру и входят в лонг, вместе с ними наращивают свои позиции фонды заключившие длинные сделки ранее. Наконец цена достигает своего 156-недельного максимума. К этому моменту кто хотел – тот купил. Все. Больше покупателей не осталось.

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

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

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

Давайте изучим действия крупных некоммерческих трейдеров исходя из вышеизложенной концепции с помощью трех летнего индекс примененного на этот раз к чистой позиции некоммерческий трейдеров:



График 2-16. Скотина и чистая позиция некоммерческих трейдеров


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

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



График 2-17. Хлопок и 156-недельный индекс чистой позиции некоммерческих трейдеров


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


2.8 Наблюдаем за позициями мелких спекулянтов


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



Таблица 2-18. Доля мелких спекулянтов в кратком отчете по пшенице


Как видно из отчета общее количество крупных участников рынка невелико. На короткой стороне – 286, на длинной – 304. 286 участников рынка держат 91.8 % всех длинных позиций а 304 трейдера 88.5 % всех коротких позиций. Можно ли назвать этих крупных участников рынка толпой? Не думаю. Зато многочисленные трейдеры не попадающие в отчет комиссии и есть те самые мелкие спекулянты, создающие рыночную толпу.

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



Рисунок 2-19. Чистая позиция мелких спекулянтов по фьючерсам на британский фунт

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

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


3. Техническая реализация


3.1 Задачи и структура проекта MetaCOT

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

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

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

2. Универсальность. Комплекс включает в себя все инструменты анализа данных CFTC описываемые в книге Ларри Вильямса, включая его индикатор WILLCO, который к слову сказать от-сутствует во всех прочих проектах. Более того, набор включает в себя специальные скрипты, группирующие информацию особым образом. В итоге Вы можете в автоматическом режиме объединять различные инструменты и даже создавать новые! Кроме того, архитектура проекта разработана таким образом, что создавать новые индикаторы COT на основе проекта не составит труда. Основные данные COT за требуемую дату можно получить с помощью одной единственной функции. А уже эти данные можно с легкостью использовать для расчета другого индикатора.

3. Автоматизация. Данные CFTC крайне объемны. Они содержат информацию о сотни рынках, к тому же информация по каждому рынку разбросана по разным файлам и годам. С помощью скриптов Meta COT теперь это не будет являться проблемой. Все что теперь необходимо делать, это скачивать один раз в неделю обновленный файл с сайта CFTC и запускать скрипт. Данные будут автоматически извлечены, сгруппированы и готовы к использованию.

4. Простота. Все индикаторы и скрипты создавались исключительно средствами языка программирования MQL, без помощи сторонних динамических библиотек. Применялись максимально простые алгоритмы организации и расчетов данных. Использовалась возможность специализации. Так на основе скриптов были разработаны программы по группировке, объединению, вы-воду и созданию новых данных. А уже эти данные использовались при построении индикаторов.

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

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


Название файла

Тип

Размещение

Назначение

Meta COT Script Build.mq4

Скрипт

..\Meta Trader\experts\scripts\

Основной, независимый скрипт подготовки данных. Создает набор файлов из стандартных CSV-файлов доступных на сервере CFTC.gov. Каждый созданный файл включает в себя информацию по одному инструменту. Название созданного файла соответствует названию инструмента.

Meta COT Script Concatenate.mq4

Скрипт

..\Meta Trader\experts\scripts\

Независимый скрипт. Объединяет несколько файлов в один на основе истории. Например, файл «COT - SUGAR NO. 11 - NEW YORK BOARD OF TRADE .csv» включающий в себя данные за период 2005.01.04-2007.08.28 и файл «COT - SUGAR NO. 11 - ICE FUTURES U.S. .csv» включающий в себя данные за период 2007.09.04-2009.09.01 будут преобразованы в файл «SUGAR CONCATENATE», включающий данные за период 2005.01.04 по 2009.09.01.

Meta COT Script Agregation.mq4

Скрипт

..\Meta Trader\experts\scripts\

Независимый скрипт. Объединяет несколько файлов в один на основе суммирования их значений. Например фалы «COT - WHEAT - CHICAGO BOARD OF TRADE .csv», «COT - WHEAT - KANSAS CITY BOARD OF TRADE .csv», « COT - WHEAT - MINNEAPOLIS GRAIN EXCHANGE .csv» будут преобразованы в один файл «WHEAT AGREGATION» содержащий сумму значений всех трех файлов.

Meta COT Script Report.mq4

Скрипт

..\Meta Trader\experts\scripts\

Для работы скрипта необходима библиотека «cotlib.mq4». Создает файл-отчет CSV, включающий в себя расчет всех индикаторов. Периоды усреднения и название инструмента выбираются в настройках скрипта. Может пригодится для анализа данных в прочих программных комплексах.

Meta COT Absolute Position.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает абсолютные позиции трейдеров всех категорий, включая открытый интерес.

Meta COT Net Position.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает чистые позиции трейдеров всех категорий, включая открытый интерес.

Meta COT Index.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает COT индекс всех категорий трейдеров, включая индекс открытого интереса. Период расчета устанавливается в настройках скрипта.

Meta COT Percent Position in OI.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает отношение чистой позиции каждой категории трейдеров к открытому интересу.

Meta COT WILLCO.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает WILLCO индекс расчитанный для всех категорий трейдеров. Период расчета устанавливается в настройках скрипта.

Meta COT Movement Index.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает индекс ускорения для каждой категории трейдеров включая открытый интерес, на основе COT индекса. Период расчета и размер дельты устанавливается в настройках скрипта.

Meta COT Spread Movement Index.mq4

Индикатор

..\Meta Trader\experts\indicators\

Для работы индикатора необходима библиотека «cotlib.mq4». Отображает индекс ускорения каждой категории трейдеров по отношению к такому же индексу ускорения открытого интереса.

Meta COT Expert.mq4

Эксперт

..\Meta Trader\experts\

Для работы советника необходима библиотека «cotlib.mq4». Тестирует COT индикаторы на исторических данных.

cotlib.mq4

Библиотека

..\Meta Trader\experts\libraries\

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

CONCATENATE.ini

Файл-список

..\Meta Trader\experts\files\

Файл-список, содержащий название файлов-перечислений для объединения по времени.

COT - * CONCATENATE.ini

Файлы-перечисления

..\Meta Trader\experts\files\

Файлы перечисления, содержащие списки файлов, которые необходимо объединить по времени.

AGREGATION.ini

Файл-список

..\Meta Trader\experts\files\

Файл-список, содержащий название файлов-перечислений для суммирования.

COT - * AGREGATION.ini

Файлы-перечисления

..\Meta Trader\experts\files\

Файлы перечисления, содержащие списки файлов, которые необходимо просуммировать.

Таблица 3-1. Набор файлов Meta COT и пути их расположения.


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


3.2 Загрузка данных и создание отчетов

Все данные для работы индикаторов, как должно уже быть Вам известно, предоставляются некоммерческой организацией CFTC. Эти данные еженедельно публикуются на официальном сайте этой организации. Составляется несколько видов отчетов. Первый вид отчетов называется «Futures Only Reports», и включает в себя данные по сделкам совершенных только по фьючерсам. Второй вид отчета называется «Futures-and-Options Combined Reports» и включает в себя отчеты по фьючерсам и опционам.

Он представляет более полную информацию о том, что происходит на рынке. Его использование предпочтительней. Также имеется специальный вид отчета, называемый «Commodity Index Trader Supplement». Его основное отличие в том, что он составляется для ограниченного круга сельскохозяйственных рынков, и, самое важное, включает в себя четвертую категорию трейдеров, так называемых Commodity Index Traders (CIT).

Эти трейдеры занимают промежуточное положение. С одной стороны их позиции в отчетах «Futures Only Reports» и «Futures-and-Options Combined Reports» относятся к хеджерам, с другой - их поведение похоже на поведение крупных хедж-фондов. В целом, они являются нетто-покупателями, в отличие от классических хеджеров, которые в целом являются нетто-продавцами. Существует мнение, что именно эта категория трейдеров вносит панику на рынок. Резкие обвалы и подъемы – во многом их рук дело. Они обладают достаточной покупательной способностью, чтобы двинуть рынок в ту или иную сторону, в то же время основная их цель – получение спекулятивной прибыли. Данные по этой категории трейдеров доступны с 2007 года в форматах Exel и CSV. Пока, из-за малой истории их покупок и продаж, изучение их поведения – дело будущего. В настоящий момент этот вид отчета не поддерживается проектом.

Отчеты публикуются в нескольких форматах. Во-первых, это собственно таблицы отчеты. В этом формате не существует отчета «Commodity Index Trader Supplement», который Доступен только в виде EXEL и CSV файлов. Вид этих таблиц должен уже быть Вам знаком:



Рисунок 3-3. Фрагмент отчета COT в Exсel-формате


Также применяются обычные таблицы Exсel. В них содержаться те же самые данные, что и в обычном отчете, с той лишь разницей, что данные собраны за длительный период времени. Фрагмент этой таблицы представлен на рисунке 3-2:



Рисунок 3-3. Фрагмент отчета COT в Exсel-формате


Также комиссия публикует свои отчеты в формате CSV. Этот формат представляет из себя обычный текстовой файл с расширением «txt», данные в котором записываются через запятую. Это единственный формат, с которым работает Meta COT, поэтому этот формат необходимо описать более подробно. На рисунке 3-4 представлен отрывок такого файла:



Рисунок 3-4. Фрагмент отчета COT в CSV формате


Его структура может показаться хаотичной, но это не так. Файл состоит из строк и колонок. Количество колонок в файле – 128, количество строк зависит от количества инструментов и периода отчета. Обычно один файл-отчет содержит в себе данные за один год. Так например, отчет скаченный в этом формате в сентябре 2009 года, будет содержать данные с января 2009 года по сентябрь 2009 года (дата написания статьи). Первая строка состоит из 128 колонок, каждая из которых является названием соответствующего ряда колонок. Основой для построения данных являются файлы CSV.

Теперь приступим к созданию нужных нам графиков. Данные COT удобно рассматривать за длительный период времени. Давайте подготовим данные с 2000 года по настоящее время. Итак, необходимо зайти браузером на страницу http://cftc.gov/MarketReports/CommitmentsofTraders/HistoricalCompressed/index.htm или перейти по разделам Home > Market Reports > Commitments of Traders, сайта CFTC.gov. Внизу страницы будут таблицы указанные на рисунке:



Рисунок 3-5. Архив данных


На странице представлены два вида отчета, только по фьючерсам, и по фьючерсам и опционам. Так как мы хотим построить данные с 2000 года, то резонно использовать второй вид отчета по фьючерсам и опционам (до 1995 года можно использовать только отчеты по фьючерсам). Однако форматы отчетов одинаковые, и вы можете использовать любой из этих двух видов. Скачайте себе на компьютер девять текстовых файлов начиная с 2009 и заканчивая 2000 годом. В последующем вы также можете скачивать один файл включающий в себя данные с 1995 по 2008 год и один файл 2009 года, однако в этом случае получившихся инструментов будет гораздо больше. Одна из ссылок на файл обведена на рисунки красным кружком. Скаченные файлы необходимо распаковать в каталог ..\Meta Trader\experts\files\.

Все файлы в архивах имеют одно и то же название annualof.txt, поэтому их необходимо переименовать. Название файлов может быть любым, однако эти названия необходимо зарегистрировать в специальном настроечном файле проекта names.ini. Он крайне прост и представляет из себя простое перечисление файлов, которое необходимо обработать. Так например, если файл за 2009 год называется 2009_Futures-and-Options.txt, за 2008 год называется 2008_Futures-and-Options.txt и так далее, то список обрабатываемых файлов будет выглядеть следующим образом:



Рисунок 3-6. Список файлов для извлечения данных COT


Если Вы переименуете скаченные файлы так же как указано в примере, то Вам не придется редактировать файл names.ini, по умолчанию скрипт будет работать именно с этим набором файлов. Если, по каким-то причинам Вам будет необходимо использовать другие имена, то вбейте новые названия файлов в names.ini, вместо тех, что указаны по умолчанию. Итак, в каталоге \files у Вас должны находится 9 файлов, так как указано на рисунке 3-6:



Рисунок 3-7. Содержание каталога MetaTrader\experts\files


Cодержание файла names.ini должно быть таким же как на рисунке 3-05. Важное замечание: порядок названий файлов-отчетов в файле nemes.ini имеет значение. Названия файлов должны быть перечислены в порядке убывания. Т.е. первым должен идти файл за 2009 год, а последним за 2000.

Теперь, когда данные подготовлены, настало время запусить скрипт Meta COT Script Build. Он работает в автоматическом режиме, а единственный параметр который он имеет – это название файла списка имен. В данном случае название файла names.ini, но название может быть любым. Это необходимо для гибкого решения некоторых задач.

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

Сначала можно получить данные по фьючерсам запустив скрипт с параметром names_list равным «names_futures.ini». После этого их необходимо будет сохранить в другом каталоге. Затем, когда нужные данные будут получены, запустиь скрипт вновь, но на этот раз с параметром names_list равным «names_option.ini». Будут сгенерированы данные для фьючерсов и опционов.

Через некоторое время после того, как Вы запустите скрипт, в каталоге files появятся множество файлов-отчетов в формате CSV. Каждый такой файл будет иметь вид «COT – Название рынка – Название биржи .CSV».

Многие из файлов будут неполные. Отчеты COT по некоторым рынкам имеют особенность ненадолго появляться, чтобы потом исчезнуть навсегда. Тем не менее, имеется достаточное количество инструментов, отчеты по которым выходят стабильно и регулярно. Позже мы рассмотрим инстру-менты входящие в отчет более подробно, а сейчас обратим внимание на сгенерированные файлы. Рассмотрим формат полученных файлов на примере одного из них: «COT - NEW ZEALAND DOLLAR - CHICAGO MERCANTILE EXCHANGE .csv». В этом файле, как несложно догадаться, находится нужная нам информация для фьючерса на новозеландский доллар. Попробуем открыть его в блокноте и посмотреть как он устроен:



Рисунок 3-8. Новозеландский доллар


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

I – Название инструмента;
II – Дата, на момент которой составляется отчет.;
III – Открытый интерес;
IV – Длинные позиции некоммерческих трейдеров;
V – Короткие позиции некоммерческих трейдеров;
VI – Покрытие некоммерческих трейдеров;
VII – Длинные позиции операторов;
VIII – Короткие позиции операторов;
IX – Совокупное количество длинных позиций подотчетных трейдеров;
X – Совокупное количество коротких позиций подотчетных трейдеров;
XI – Длинные позиции неподотчетных трейдеров;
XII – Короткие позиции неподотчетных трейдров.
Это все данные которые понадобятся для построения индикаторов COT.

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

Например инструменты «COT - SUGAR NO. 11 - COFFEE SUGAR AND COCOA EXCHANGE» и «COT - SUGAR NO. 11 - COFFEESUGAR AND COCOA EXCHANGE» - совершенно разные для программы, и она создаст два различных соответствующих названиям инструментов файла. Разберемся на примере сахара. После запуска скрипта Meta COT Script Build в каталоге \files среди многих файлов появятся следущие:

COT - SUGAR NO. 11 - COFFEE SUGAR AND COCOA EXCHANGE .csv
COT - SUGAR NO. 11 - COFFEESUGAR AND COCOA EXCHANGE .csv
COT - SUGAR NO. 11 - ICE FUTURES U.S. .csv
COT - SUGAR NO. 11 - NEW YORK BOARD OF TRADE .csv
COT - SUGAR NO. 14 - COFFEE SUGAR AND COCOA EXCHANGE .csv

Последний файл относится к другому классу сахара, и содержит слишком мало данных, чтобы их можно было использовать, поэтому этот файл можно сразу удалить. Как видно из названий, первый и второй файлы – один и тот же инструмент, просто комиссия некоторое время создавала отчеты по этому инструменту с грамматической ошибкой, что и повлияло на создание второго файла. Третий и четвертый файл содержат позиции по тому же сахару, но уже на других площадках: «ICE FUTURES» и «NEW YORK BOARD OF TRADE». Если открыть все эти файлы то можно выявить хронологию торгов сахара:


Название файлов сахара

Дата начала торгов

Дата окончания торгов

COT - SUGAR NO. 11 - ICE FUTURES U.S. .csv

2007.09.04

2009.09.01

COT - SUGAR NO. 11 - NEW YORK BOARD OF TRADE .csv

2005.01.04

2007.08.28

COT - SUGAR NO. 11 - COFFEE SUGAR AND COCOA EXCHANGE .csv

2003.02.25

2004.12.28

COT - SUGAR NO. 11 - COFFEESUGAR AND COCOA EXCHANGE .csv

2003.01.07

2003.02.14

Таблица 3-9. Файлы-отчеты относящиеся к сахару


Как видно из хронологии торгов, все файлы данных описывают один и тот же товар, поэтому логично объединить все эти файлы в один непрерывный файл-отчет. Этим занимается скрипт Meta COT Script Concatenate. Для его работы с файлами сахара необходимо создать специальный файл перечислений, например SUGAR CONCATENATE.ini. В нем должны быть перечислены все файлы сахара, которые необходимо объединить в единой хронологической последовательности.

Название файла перечисления (SUGAR CONCATENATE.ini) необходимо внести в центральный файл-список CONCATENATE.ini. Этот файл содержит названия всех файлов-перечислений, хро-нологии которых необходимо объединить. В поставке MetaCOT уже вкючены соответствующие файлы-перечисления, они имеют следующий формат: COT – НАЗВАНИЕ ИНСТРУМЕНТА CONCATENATE.ini. Эти названия занесены в файл-список CONCATENATE.ini.

После того, как все желаемые файлы-перечисления подготовлены и занесены в файл-список, можно запустить скрипт Meta COT Script Concatenate. После его непродолжительной работы будут созданы объединенные файлы, имеющие те же названия что и файлы перечисления, но имеющие формат SCV.

Для лучшего понимания логики обработки посмотрим на рисунок 3-10. На нем в качестве иерархии представлены файлы CONCATENATE.ini, SUGAR CONCATENATE.ini и некоторые другие:



Рисунок 3-10. Взаимосвязь файла concatenate.ini с файлами перечислениями


3.3 Объединенные отчеты – новый инструмент анализа

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

Логично предположить, что действия всех участников на этих рынках будут также примерно одинаковыми. Тогда не лучше ли сложить отчеты по сделкам трейдеров на этих рынках в один совокупный отчет? Так например, если операторы имеют 20 100 контрактов на рынке живой скотины и 15 200 контрактов на рынке скотины на убой, то совокупная их позиция на рынке крупного рогатого скота как такового составит 35 300 контрактов. Такое сложение можно провести для всех участников рынка, как для коротких так и для длинных позиций.

Можно пойти дальше, и сложить действия всех участников для рынков имеющих общую разновидность. Как насчет того, чтобы сложить отчеты по всем валютным фьючерсам в один отчет, и таким образом получить свой вариант индекса доллара? Или можно сложить отчеты всех фондовых ин-дексов начиная от S&P 500 и заканчивая Dow Jons 30. Получившиеся инструменты будут содержать гораздо большие объемы, и включать в себя мнения участников не только по одному конкретному рынку, но и по отрасли в целом!

Эта идея была удивительно прекрасна, чтобы она не осталась нереализованной. И представьте, инструмент, способный складывать отчеты подобным образом существует и входит в набор MetaCOT. Он называется Meta COT Script Agregation. Действует он по тому же принципу что и Meta COT Script Concatenate, с той лишь разницей, что сложение отчетов происходит по другому алгоритму. Итак, для его работы также необходимо указать инструменты, значения которых необходимо просуммировать, названия файлов этих инструментов должны быть перечислены в одном файле, в свою очередь название этого файла должно быть занесено в файл-список, содержащий перечисления всех подобных файлов.

Давайте попробуем создать свой индекс доллара. Создадим файл Dollar Index Agrega-tion.ini. Занесем в него названия сгенерированных отчетов для всех валютных фьючерсов:

COT - EURO FX CONCATENATE.csv
COT - BRITISH POUND STERLING CONCATENATE.csv
COT - JAPANESE YEN CONCATENETE.csv
COT - AUSTRALIAN DOLLAR CONCATENATE.csv
COT - CANADIAN DOLLAR CONCATENATE.csv
COT - SWISS FRANC CONCATENATE.csv

Замечу, что сами эти файлы были в свою очередь объединены скриптом Meta COT Script Concatenate. После того, как названия занесены, можно сохранить файл под названием COT – DOLLAR INDEX AGREGATION.ini в директории Meta Trader/expert/files. Название может быть любым, но мы будем использовать это. Далее необходимо создать файл AGREGATION.ini. В нем указать название нашего объединения: COT – DOLLAR INDEX AGREGATION.ini.

Теперь можно сохранить файл и запустить скрипт Meta COT Script Agregator. Единственный параметр, который имеет скрипт – это собственно название файла-списка, который ему нужно обработать. Так как файл-список в нашем случае называется AGREGATION.ini, то этот параметр должен быть равен одноименному файлу. Скрипт просуммирует значения всех инструментов входящих в файл-перечисление COT – DOLLAR INDEX AGREGATION.ini, в данном случае шесть файлов-отчетов по всем валютам, и создаст новый - COT – DOLLAR INDEX AGREGATION.csv. Этот файл и будет содержать сумму отчетов по всем валютным фьючерсам.

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

Однако некоторые отчеты могут не содержать данных за определенный период по сравнению с другими отчетами, входящими в общий список обработки. В этом случае программа идентифици-рует такой временной разрыв, о чем и проинформирует Вас сообщением во время выполнения программы: «--> Обнаружен разрыв: 21.04.2004.». В этой ситуации нет ничего страшного, более того она типична и происходит регулярно. В этом случае программа просуммирует данные всех прочих инструментов и создаст отчет включающий дату 21.04.2004 куда эти данные будут входить, кроме того в эту дату попадут данные из отчета с отсутствющей датой, но за ближайший ранний (старый) период. Это будет первая дата, попавшая в обработку. Например, в совокупный отчет за 21.04.2004 попадут данные за 14.04.2004 по отчету, данных по которому за 21 апреля нет.

При объединении отчетов следует проявлять осторожность. В то время как по одной группе инст-рументов, стоимость одного контракта может быть примерно одинаковой, по другой – различаться значительно. Простой пример: индекс S&P500 и два фьючерсных контракта на него: E-mini S&P500 и собственно полноразмерный S&P500. Один электронный фьючерсный контракт равен значению индекса * 5$, полноразмерный – значению индекса * 25$. Несмотря на то, что большой рынок-близнец уступает своему маленькому электронному двойнику в части количества контрактов, их капитализация может быть равна и даже полноразмерный S&P500 может быть более капитализиро-ван. Вопрос о грамотном сложении значений с различных рынков остается открыт, и требует продолжительной доработки, однако базовый инструмент по сложению есть уже сегодня и его можно применять, хотя и с осторожностью.


3.4 Индикаторы

Все индикаторы устроены по одному принципу, и содержат в себе одно и то же ядро. Все данные загружает ядро индикатора, затем на основе данных, ядро подсчитывает значения всех индикаторов входящих в MetaCOT. Каждый индикатор показывает только те значения, которые определены его задачей, однако фактически внутри своего кода он содержит значения всех возможных индикаторов. Такой подход оказался крайне удачным, особенно при проектировании робота. Так как основная расчетная часть робота, библиотека cotlib.mq4 высчитывает все возможные значения индикаторов, то их можно указать в параметрах оптимизации!

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

Теперь, когда все файлы-отчеты подготовлены, осталось загрузить их в индикаторы. Все индикаторы однотипны, структура их параметров одна. Рассмотрим это на примере индикатора Meta COT Net Position:


Тип переменной

Название переменной

Значение переменной

по умолчанию

Описание переменной

intperiod

156

Период расчета индикатора. Применяется в индикаторах, требующих период усреднения (COT Index, WILLCO и т.д.). Обычно равен 156 недельному усреднению.

boolShowNoncomm

false

Если переменная установлена в положение true, индикатор отобразит значение чистой позиции некоммерческих трейдеров

boolShowOperators

true

Если переменная установлена в положение true, индикатор отобразит индекс чистой позиции операторов

boolShowNonrep

false

Если переменная установлена в положение true, индикатор отобразит индекс чистой позиции неподотчетной публики.

boolShowOI

true

Если переменная установлена в положение true, индикатор отобразит индекс открытого интереса.

boolload_cot_file

false

Если переменная установлена в положение true, индикатор загрузит подготовленный файл-отчет, название которого определено переменной cot_file.

stringcot_file

cot-sample.txt

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

stringsettings

settings.txt

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

Таблица 3-11. Переменные индикатора Meta COT Net Position


Во-первых, все индикаторы требующие расчетного периода для своей работы имеют внешнюю переменную period. По умолчанию она равна наиболее распространенному периоду усреднения – трехлетнему или 156-недельному.

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

В-третьих, индикаторы содержат три переменных: load_cot_file, cot_file, settings. На них необходимо остановиться подробнее. Для всех индикаторов создан так называемый файл соответствий, по умолчанию называемый settings.ini. Дело в том, что крайне неудобно каждый раз вручную выбирать название отчета, который необходимо загрузить для анализа выбранного графика. Для каждого инструмента необходим свой отчет. Файл settings.ini определяет, какой именно отчет необходимо загрузить, для анализа текущего графика. Например, если переменная load_cot_file установлена в значение false, а Вы запускаете индикатор Meta COT Net Position на графике GBPUSD, то индикатор автоматически выберет отчет под названием COT - BRITISH POUND STERLING CONCATENATE.csv и загрузит его график. Все это возможно благодаря простому файлу, который соотносит название инструмента, с названием отчета. По умолчанию в поставку Meta COT уже включен такой файл. Это обычный CSV-файл следущего формата:

название файла-отчета; название индикатора; первые значащие символы инструмента 1; первые значащие символы инструмента N

Т.е. если например Вы хотите, чтобы индикатор автоматически загружал отчет COT - SWISS FRANC CONCATENATE.csv, всякий раз, когда Вы загружали индикатор на графиках 6S и USDCHF, Вам необходимо внести следущую строку в файл setting.ini:

COT - SWISS FRANC CONCATENATE.csv;SWISS FRANC;6S;USDCHF

В данном случае символ «6S» - собирательное название фьючерсов на различные даты поставки по швейцарскому франку. Например, швейцарский франк торгуется на контрактах 6S_CONT; 6SU9; 6SU9#I; 6SZ9; 6SZ9#I; Первый из них - непрерывный фьючерс для тестирования стратегий. Системе достаточно указать только первые значащие символы инструмента (в данном случае 6S), чтобы индикаторы грузили один и тот же отчет для всех фьючерсов швейцарского франка. Последняя строка является своего рода «заглушкой». Если весь файл перебран, а соответствующих отчетов так и не найдено, название последнего отчета отобразиться в окне индикатора. В данном случае вместо названия отчета использовано предупреждающее сообщение: «ОТЧЕТ ДЛЯ ИНСТРУМЕНТА НЕ НАЙДЕН!». В этом случае будет загружен отчет определяемый переменной cot_file, независимо от значения переменной load_cot_file.

Обратите внимание, что точка с запятой в конце строки не ставиться. В этом случае индикатор загрузит отчет COT - SWISS FRANC CONCATENATE.csv, а название индикатора приобретет вид: Meta COT Index (156): SWISS FRANC. Название «SWISS FRANK» взято из второй колонки строки, период усреднения определенный переменной period, указан в скобках. Полное содержимое файла setting.ini, настроенное для работы с конкретным брокером можно увидеть на рисунке 3-8. Названия инструментов вашего брокера может отличаться от названий, приведенных на рисунке 3-8. Вам необходимо выяснить названия инструментов Вашего брокера и внести их в файл settings.ini, по правилам описанным выше.

Бывают ситуации, когда для анализа инструмента необходимо загрузить определенный файл-отчет не соответствующий значениям по умолчанию. В этом случае необходимо перевести переменную load_cot_file, в значение true, затем указать название необходимого файла-отчета в переменной cot_file. Индикатор загрузит требуемый файл-отчет независимо от названия текущего инструмента.



Рисунок 3-8. Содержимое файла settings.ini, настроенного для работы с определенным брокером


Для решение широкого круга задач, можно привлекать к анализу данных сторонние программы, например Microsoft Exсel. В этих случаях удобно воспользоваться вычислениями Meta COT и загрузить в стороннюю программу файл данных содержащий значения всех индикаторов для необходимого инструмента. Для этих задач был создан скрипт Meta COT Script Report. Принцип его работы скорее напоминает индикатор – для его работы необходима библиотека cotlib.mq4. Он имеет такие же параметры, как и индикаторы: период расчета (period) и значение movement index (movement_index). После того, как он будет запущен на текущем инструменте, в директории \files создастся файл Meta COT Report НАЗВАНИЕ ОТЧЕТА.csv. Этот файл будет содержать значения всех индикаторов вместе с базовыми значениями для текущего инструмента.

Теперь, когда все индикаторы настроены и работают, настало время удалить все отчеты. Дело в том, что Meta COT не обновляет данные, а каждый раз создает их набор «с нуля» или до записывая к существующим. Это означает, что перед тем как запускать скрипты подготовки данных, старые данные должны быть удалены. К сожалению Meta Trader не обладает встроенными средствами работы с файловой системой и удаление файлов приходится делегировать самой системе Windows. Наиболее удобный способ для этого – создание пакетного файла команд или bat-файла. Такой файл уже существует в поставке и называется erase_cot.bat. Он содержит всего одну строчку:

erase COT*.csv

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

После завершения удаления, процедуру создания файлов можно повторить заново и круг замкнется.


3.5 Исходный код

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

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

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

Механизм получения данных из SCV отчета комиссии реализован в независимой (программно не связанной с проектом) программе Meta COT Script Build. Алгоритм программы крайне простой, что практически гарантирует высокую степень её управляемости и дальнейшей модификации. Вначале программа открывает список названий файлов, которые ей необходимо обработать. Названия файлов содержаться в файле указанном в ее единственном параметре (по умолчанию names.ini). Считав название первого файла, скрипт пытается открыть одноименный файл в директории. Если файл существует, и открытие происходит корректно, скрипт начинает считывать файл в формате SCV, т.е. колонка за колонкой, окончание строки обнуляет счетчик колонок. Когда счетчик колонок указывает на нужный номер колонки (проверяется специальной функцией), её значения сразу заносятся в итоговый файл, а после ставится точка с запятой.

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

Получается что программа ничего не знает ни о названиях фьючерсов ни об их количестве ни о порядке их группировки. В принципе названия всех инструментов могли бы располагаться в случайном порядке, в произвольном количестве и быть разбросанным по разным файлам (на практике исходные данные организованы именно по такому принципу). Итоговый результат всегда будет одним и тем же: один инструмент – один файл-отчет. Ниже представлен исходный код Meta COT Script Build:

#property copyright "Copyright © 2009, C-4, All Rights Reserved."
#property link      "vs-box@mail.ru"
#property show_inputs
//Ассоциации
#define Market_and_Exchange_Names 1
#define As_of_Date_in_Form_YYMMDD 2
#define As_of_Date_in_Form_YYYY_MM_DD 3
#define CFTC_Contract_Market_Code 4
#define CFTC_Market_Code_in_Initials 5
#define CFTC_Region_Code 6
#define CFTC_Commodity_Code 7
#define Open_Interest_All 8
#define Nonc_Positions_Long_All 9
#define Nonc_Positions_Short_All 10
#define Nonc_Positions_Spreading_All 11
#define Commercial_Positions_Long_All 12
#define Commercial_Positions_Short_All 13
#define Total_Reportable_Pos_Long 14
#define Total_Reportable_Pos_Short 15
#define Nonrep_Positions_Long_All 16
#define Nonrep_Positions_Short_All 17

extern string name_list="names.ini";
//string normalize_name;
int a;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int CFileNames,
   cot_file,
   tools_data;

   int column,
   column_now,
   column_string;
   int cot;
   bool IsOldInfo=true;
   string name_cotfile;
   string data,data2,
   normalize_name,
   string_cot;

   CFileNames=FileOpen(name_list,FILE_READ|FILE_CSV);
   if(TrueFileName(CFileNames,name_list)==false)return(1);
   Print("Список фалов открыт: ",CFileNames);
//Открываем список файлов-отчетов COT по очереди
   while(FileIsEnding(CFileNames)==false)
     {
      cot++;
      name_cotfile=FileReadString(CFileNames);
      cot_file=FileOpen(name_cotfile,FILE_READ|FILE_CSV,",");
      if(TrueFileName(cot_file,name_cotfile)==false)return(1);
      else Print("Файл найден");

      // Первую строку пропускаем
      while(FileIsLineEnding(cot_file)==false)
        {
         column++;
         FileReadString(cot_file);
        }

      while(FileIsEnding(cot_file)==false)
        {
         data=FileReadString(cot_file);
         column_string++;
         if(FileIsLineEnding(cot_file)==true || FileIsEnding(cot_file)==true)
           {
            column_string=0;
            FileWrite(tools_data,string_cot);
            FileClose(tools_data);
            string_cot="";
           }
         else
           {
            if(TrueDataNew(column_string)==true)
              {//здесь вставляем проверку на лишнюю запятую в названии
               data=NormalizeData(data);
               if(column_string==Market_and_Exchange_Names)
                 {

                  data2=FileReadString(cot_file);        // Смотри комментарий 1!
                  if(CheckValidColumn(data2)==true)      //
                     data=data+NormalizeColumn(data2);   //
                  else column_string++;
                  //data=NormalizeNames(data);
                  tools_data=FileOpen("COT - "+data+".csv",FILE_READ|FILE_WRITE|FILE_CSV);
                  TrueFileName(tools_data,data);
                  FileSeek(tools_data,0,SEEK_END);
                  string_cot=string_cot+data;
                 }
               else
                 {
                  if(column_string==As_of_Date_in_Form_YYYY_MM_DD)data=ConvertData(data);
                  string_cot=string_cot+";"+data;
                 }
              }
           }
        }
      Print("Всего строк: ",column);
     }
   Print(a);
   return(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string ConvertData(string data)
  {
   string c_data="";
   int strlen=StringLen(data);
   int char;
   for(int i=0;i<strlen;i++)
     {
      char=StringGetChar(data,i);
      if(char=='-')c_data=c_data+".";
      else c_data=StringConcatenate(c_data,CharToStr(char));
     }
   return(c_data);
  }
// Если текущая ячейка необходима для агрегированного отчета COT, возвращает true,
// в противном случае возвращает false. Список используемых ячеек оформлен в виде
// определений define
bool TrueDataNew(int column_string)
  {
   switch(column_string)
     {
      case Market_and_Exchange_Names:
      case As_of_Date_in_Form_YYYY_MM_DD:
      case Open_Interest_All:
      case Nonc_Positions_Long_All:
      case Nonc_Positions_Short_All:
      case Nonc_Positions_Spreading_All:
      case Commercial_Positions_Long_All:
      case Commercial_Positions_Short_All:
      case Total_Reportable_Pos_Long:
      case Total_Reportable_Pos_Short:
      case Nonrep_Positions_Long_All:
      case Nonrep_Positions_Short_All:
         return(true);
      default:
         return(false);
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string NormalizeData(string file_name)
  {

   int char;
   int strlen;
   string normalize_name="";
   string normalize_name_p="";
   strlen=StringLen(file_name);
   for(int i=0;i<strlen;i++)
     {
      char=StringGetChar(file_name,i);
      switch(char)
        {
         case '/':
         case '\\':
         case ':':
         case '*':
         case '\"':
         case '<':
         case '>':
         case '|':
         case ';':
            break;
         default:
            // Если последний символ строки пробел - то удаляем его.
            //if(char==" "&&i==strlen-1)break;
            normalize_name=StringConcatenate(normalize_name,CharToStr(char));
        }
     }
   return(normalize_name);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string NormalizeNames(string data)
  {
   int strlen=StringLen(data);
   string n_data;
   data=StringTrimRight(data);
   if(CharToStr(StringGetChar(data,strlen-1))==".")StringSetChar(data,strlen-1,"");
   return(data);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool TrueFileName(int handle,string filename)
  {
   if(handle==-1)
     {
      Print("Не удалось открыть файл: ",filename," Последняя полученная ошибка: ",GetLastEr-ror());
      return(false);
     }
   else return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CheckValidColumn(string column_name)
  {
   int strlen=StringLen(column_name);
   if(StringFind(column_name,"\"")!=-1){a++;return(true);}
   return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string NormalizeColumn(string column)
  {
   string n_column;
   int char;
   int strlen=StringLen(column);
   for(int i=0;i<strlen;i++)
     {
      char=StringGetChar(column,i);
      if(char=='\"')continue;
      else n_column=StringConcatenate(n_column,CharToStr(char));
     }
   return(n_column);
  }
//+------------------------------------------------------------------+

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

1. Определение – описание констант препроцессора, таблицы данных (набор массивов);

2. Инициализация – подсчет размера загружаемых данных и перераспределение размера массивов (функция init_data());

3. Загрузка данных из файла отчета (функция load_data());

4. Подсчет значений всех индикаторов на основе данных отчета (функция count_data());

В качестве метода доступа к значениям индикаторов используется функция get_data(int type, int bar). Она имеет два параметра: номер индикатора, значения которого необходимо вернуть и номер бара, для которого требуется получить значение индикатора. Например, если необходимо получить значение индикатора WILLCO рассчитанного по данным операторов, для текущего бара (bar=0), то вызов функции будет таков: get_data(WILLCO_OPERATORS, 0); «WILLCO_OPERATORS» здесь является именованным определением целочисленной константы, задающейся в командах препроцессора.

Период усреднения для всех рассчитываемых индикаторов один и тот же и должен быть выбран до инициализации индикатора (после изменения входных па-раметров, инициализация индикатора происходит автоматически). Файл, который требуется счи-тать, определяется автоматически функцией void settings_load(void). Она открывает файл настроек (по умолчанию settings.ini) и пытается найти текущий инструмент (Symbol()) в списке инструментов принадлежащих к требуемому отчету. Если какой-либо отчет соответствует названию текущего инструмента, функия загрузит его, если ни один отчет для текущего инструмента не найден – будет загружен инструмент по умолчанию (параметр name).

#property copyright "Copyright © 2009, C-4, All Rights Reserved."
#property link      "vs-box@mail.ru"

// Возможные значения параметра "type" функции get_data()
#define OI                    0
#define NONCOMM_LONG          1
#define NONCOMM_SHORT         2
#define OPERATORS_LONG        3
#define OPERATORS_SHORT       4
#define NONREP_LONG           5
#define NONREP_SHORT          6
#define NET_NONCOMM           7
#define NET_OPERATORS         8
#define NET_NONREP            9
#define OI_NONCOMM_LONG       10
#define OI_NONCOMM_SHORT      11
#define OI_OPERATORS_LONG     12
#define OI_OPERATORS_SHORT    13
#define OI_NONREP_LONG        14
#define OI_NONREP_SHORT       15
#define WILLCO_NONCOMM        16
#define WILLCO_OPERATORS      17
#define WILLCO_NONREP         18
#define INDEX_OI              19
#define INDEX_NONCOMM         20
#define INDEX_OPERATORS       21
#define INDEX_NONREP          22
#define MOVEMENT_NONCOMM      23
#define MOVEMENT_OPERATORS    24
#define MOVEMENT_NONREP       25
#define MOVEMENT_OI           26
#define OI_NET_NONCOMM        27
#define OI_NET_OPERATORS      28
#define OI_NET_NONREP         29


extern bool   load_cot_file=false;
extern string cot_file="COT - U.S. DOLLAR CONCATENATE.csv";
extern string settings="settings.ini";
string name;
bool error=false;
int column;
bool DrawData=true;
bool LoadData=true;


//**********************************************************************************************************
//                                     ТАБЛИЦА ДАННЫХ COT
int n_str;                    //содержит кол-во строк

                              // Массив содержит дату
datetime realize_data[];
// Массивы содержат обсолютные позиции 
double open_interest[];       // Открытый интерес
double noncomm_long[];        // Длинные позиции некоммерческих трейдеров
double noncomm_short[];       // Короткие позиции некоммерческих трейдеров
double noncomm_spread[];      // Покрытие некоммерческих трейдеров
double operators_long[];      // Длинные позиции некоммерческих трейдеров (операторов)
double operators_short[];     // Короткие позиции некоммерческих трейдеров (операторов)
double nonrep_long[];         // Длинные позиции неподотчетных трейдеров (публики)
double nonrep_short[];        // Короткие опзиции неподотчетных трейдеров (публики)

                              // Массивы содержат результат деления обсолютной длинной и короткой позиции 
                              // каждой из трех групп трейдеров на открытый интерес
double oi_noncomm_long[];     // Открытый интерес / Длинные позиции некоммерческих трейдеров
double oi_noncomm_short[];    // Открытый интерес / Короткие позиции некоммерческих трейдеров
double oi_operators_long[];   // Открытый интерес / Длинные позиции некоммерческих трейдеров (операторов)
double oi_operators_short[];  // Открытый интерес / Короткие позиции некоммерческих трейдеров (операторов)
double oi_nonrep_long[];      // Открытый интерес / Длинные позиции неподотчетных трейдеров (публики)
double oi_nonrep_short[];     // Открытый интерес / Короткие опзиции неподотчетных трейдеров (публики)

                              // Массивы содержат результат деления чистой позиции каждой из трех групп 
                              // трейдеров на открытый интерес, используется для построения индекса WILLCO
double oi_net_noncomm[];
double oi_net_operators[];
double oi_net_nonrep[];

// Массивы содержат чистые позиции коммерческих трейдеров, операторов и не подотчетной публики
double net_noncomm[];         // Чистые позиции некоммерческих трейдеров
double net_operators[];       // Чистые позиции коммерческих трейдеров
double net_nonrep[];          // Чистые позиции неподотчетных трейдеров

                              // Массивы содержат индекс чистых позиций каждой из трех групп
double index_oi[];            // Индекс открытого интереса
double index_ncomm[];         // Индекс некоммерческих трейдеров
double index_operators[];     // Индекс коммерческих трейдеров (операторов)
double index_nonrep[];        // Инддекс неподотчетных трейдеров (публики)

                              // Массивы содержат стохастический осциллятор, высчитанный
                              // из отношения открытого интереса к чистой позиции каждой
                              // из трех групп Stohastic(OI/NET_POSITION)
double willco_ncomm[];        // 
double willco_operators[];    //
double willco_nonrep[];       //

                              //MOVEMENT INDEX
double movement_oi[];
double movement_ncomm[];
double movement_operators[];
double movement_nonrep[];
//**********************************************************************************************************
//
bool init_data()
  {
   string data;
   int handle_cotfile;
   int str;
   settings_load();
   handle_cotfile=FileOpen(cot_file,FILE_READ|FILE_CSV);
//handle_cotfile=FileOpen("COT - U.S. DOLLAR CONCATENATE.csv",FILE_READ|FILE_CSV);
   if(handle_cotfile==-1)
     {
      Print("Не удалось загрузить файл. Дальнейшее продолжение невозможно ",cot_file);
      Print(GetLastError());
      return(false);
     }
   while(FileIsEnding(handle_cotfile)==false)
     {
      data=FileReadString(handle_cotfile);
      if(FileIsLineEnding(handle_cotfile) && data!="")str++;
     }
   ArrayResize(realize_data,str);

   ArrayResize(open_interest,str);
   ArrayResize(noncomm_long,str);
   ArrayResize(noncomm_short,str);
   ArrayResize(noncomm_spread,str);
   ArrayResize(operators_long,str);
   ArrayResize(operators_short,str);
   ArrayResize(nonrep_long,str);
   ArrayResize(nonrep_short,str);

   ArrayResize(oi_noncomm_long,str);
   ArrayResize(oi_noncomm_short,str);
   ArrayResize(oi_operators_long,str);
   ArrayResize(oi_operators_short,str);
   ArrayResize(oi_nonrep_long,str);
   ArrayResize(oi_nonrep_short,str);

   ArrayResize(oi_net_noncomm,str);
   ArrayResize(oi_net_operators,str);
   ArrayResize(oi_net_nonrep,str);

   ArrayResize(net_noncomm,str);
   ArrayResize(net_operators,str);
   ArrayResize(net_nonrep,str);

   ArrayResize(index_oi,str);
   ArrayResize(index_ncomm,str);
   ArrayResize(index_operators,str);
   ArrayResize(index_nonrep,str);

   ArrayResize(willco_ncomm,str);
   ArrayResize(willco_operators,str);
   ArrayResize(willco_nonrep,str);

   ArrayResize(movement_oi,str);
   ArrayResize(movement_ncomm,str);
   ArrayResize(movement_operators,str);
   ArrayResize(movement_nonrep,str);

   FileClose(handle_cotfile);
   return(true);
  }

void settings_load()
  {
   int h_set,_column;
   string set,sname;
   if(load_cot_file==true)return;
   h_set=FileOpen(settings,FILE_READ|FILE_CSV,";");
//FileOpen("\Temp\Cot_file.txt",FILE_WRITE,FILE_CSV);
   if(h_set==-1)return;
   while(FileIsEnding(h_set)==false)
     {
      set=FileReadString(h_set);
      _column++;
      if(set==Symbol() && _column!=1){cot_file=sname;return;}
      if(_column==2 && set!="")name=set;    // Вторая колонка - желаемое название индикатора
      if(FileIsLineEnding(h_set)==true)_column=0;
      if(_column==1)sname=set;

     }
   FileClose(h_set);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void load_data()
  {
   datetime data_realize;
   int handle_cotfile;
   string data;
   handle_cotfile=FileOpen(cot_file,FILE_READ|FILE_CSV,";");
   Print("Файл найден");
   while(FileIsEnding(handle_cotfile)==false)
     {
      data=FileReadString(handle_cotfile);
      column++;
      if(FileIsLineEnding(handle_cotfile)==true || FileIsEnding(handle_cotfile)==true)
        {//column=12 - обнуляет раньше времени
         if(column==12)
            nonrep_short[n_str]=StrToDouble(data);
         column=0;
         if(data!="")n_str++;
        }
      else
        {
         switch(column)
           {
            case 2:
               realize_data[n_str]=StrToTime(data);
               break;
            case 3:
               open_interest[n_str]=StrToDouble(data);
               //Print(open_interest[n_str]);
               break;
            case 4:
               noncomm_long[n_str]=StrToDouble(data);
               break;
            case 5:
               noncomm_short[n_str]=StrToDouble(data);
               break;
            case 6:
               noncomm_spread[n_str]=StrToDouble(data);
               break;
            case 7:
               operators_long[n_str]=StrToDouble(data);
               break;
            case 8:
               operators_short[n_str]=StrToDouble(data);
               break;
            case 11:
               nonrep_long[n_str]=StrToDouble(data);
               break;
           }
        }
     }
   FileClose(handle_cotfile);
   Print("Файл загружен");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void count_data()
  {
   int    max,
   min;
   double delta;

   for(int i=0;i<n_str;i++)
     {
      index_oi[i]=EMPTY_VALUE;
      index_ncomm[i]=EMPTY_VALUE;
      index_operators[i]=EMPTY_VALUE;
      index_nonrep[i]=EMPTY_VALUE;
      willco_ncomm[i]=EMPTY_VALUE;
      willco_operators[i]=EMPTY_VALUE;
      willco_nonrep[i]=EMPTY_VALUE;
      movement_ncomm[i]=EMPTY_VALUE;
      movement_operators[i]=EMPTY_VALUE;
      movement_nonrep[i]=EMPTY_VALUE;
     }
   for(i=0;i<n_str;i++)
     {
      if(open_interest[i]==0)
        {
         oi_noncomm_long[i]=0;
         oi_noncomm_short[i]=0;
         oi_operators_long[i]=0;
         oi_operators_short[i]=0;
         oi_nonrep_long[i]=0;
         oi_nonrep_short[i]=0;
        }
      else
        {
         oi_noncomm_long[i]=noncomm_long[i]/open_interest[i];
         oi_noncomm_short[i]=noncomm_short[i]/open_interest[i];
         oi_operators_long[i]=operators_long[i]/open_interest[i];
         oi_operators_short[i]=operators_short[i]/open_interest[i];
         oi_nonrep_long[i]=nonrep_long[i]/open_interest[i];
         oi_nonrep_short[i]=nonrep_short[i]/open_interest[i];
        }

      net_noncomm[i]=noncomm_long[i]-noncomm_short[i];
      net_operators[i]=operators_long[i]-operators_short[i];
      net_nonrep[i]=nonrep_long[i]-nonrep_short[i];

      if(open_interest[i]==0)
        {
         oi_net_noncomm[i]=0;
         oi_net_operators[i]=0;
         oi_net_nonrep[i]=0;
        }
      else
        {
         oi_net_noncomm[i]=net_noncomm[i]/open_interest[i];
         oi_net_operators[i]=net_operators[i]/open_interest[i];
         oi_net_nonrep[i]=net_nonrep[i]/open_interest[i];
        }
     }

   for(i=0;i<n_str-period;i++)
     {

      max=ArrayMaximum(open_interest,period,i);
      min=ArrayMinimum(open_interest,period,i);
      delta=open_interest[max]-open_interest[min];
      if(delta==0)delta=1;
      index_oi[i]=(open_interest[i]-open_interest[min])/delta*100;

      max=ArrayMaximum(net_noncomm,period,i);
      min=ArrayMinimum(net_noncomm,period,i);
      delta=net_noncomm[max]-net_noncomm[min];
      if(delta==0)delta=1;
      index_ncomm[i]=(net_noncomm[i]-net_noncomm[min])/delta*100;

      max=ArrayMaximum(net_operators,period,i);
      min=ArrayMinimum(net_operators,period,i);
      delta=net_operators[max]-net_operators[min];
      if(delta==0)delta=1;
      index_operators[i]=(net_operators[i]-net_operators[min])/delta*100;

      max=ArrayMaximum(net_nonrep,period,i);
      min=ArrayMinimum(net_nonrep,period,i);
      delta=net_nonrep[max]-net_nonrep[min];
      if(delta==0)delta=1;
      index_nonrep[i]=(net_nonrep[i]-net_nonrep[min])/delta*100;

      max=ArrayMaximum(oi_net_noncomm,period,i);
      min=ArrayMinimum(oi_net_noncomm,period,i);
      delta=oi_net_noncomm[max]-oi_net_noncomm[min];
      if(delta==0)delta=1;
      willco_ncomm[i]=(oi_net_noncomm[i]-oi_net_noncomm[min])/delta*100;

      max=ArrayMaximum(oi_net_operators,period,i);
      min=ArrayMinimum(oi_net_operators,period,i);
      delta=oi_net_operators[max]-oi_net_operators[min];
      if(delta==0)delta=1;
      willco_operators[i]=(oi_net_operators[i]-oi_net_operators[min])/delta*100;

      max=ArrayMaximum(oi_net_nonrep,period,i);
      min=ArrayMinimum(oi_net_nonrep,period,i);
      delta=oi_net_nonrep[max]-oi_net_nonrep[min];
      if(delta==0)delta=1;
      willco_nonrep[i]=(oi_net_nonrep[i]-oi_net_nonrep[min])/delta*100;
     }
   for(i=0;i<n_str-period-movement_index;i++)
     {
      movement_oi[i]=index_oi[i]-index_oi[i-movement_index];
      movement_ncomm[i]=index_ncomm[i]-index_ncomm[i-movement_index];
      movement_operators[i]=index_operators[i]-index_operators[i-movement_index];
      movement_nonrep[i]=index_nonrep[i]-index_nonrep[i-movement_index];
     }
  }
// Возвращает одно из значений COT таблицы 
// определенное переменной "type" для бара "bar"
double get_data(int type,int bar)
  {
   double data;
   int i_data=get_cot(bar);
   if(i_data==EMPTY_VALUE)return(EMPTY_VALUE);
   switch(type)
     {
      case OI:
         return(open_interest[i_data]);
      case NONCOMM_LONG:
         return(noncomm_long[i_data]+noncomm_spread[i_data]);
         //return(noncomm_long[i_data]);
      case NONCOMM_SHORT:
         return(noncomm_short[i_data]+noncomm_spread[i_data]);
         //return(noncomm_short[i_data]);
      case OPERATORS_LONG:
         return(operators_long[i_data]);
      case OPERATORS_SHORT:
         return(operators_short[i_data]);
      case NONREP_LONG:
         return(nonrep_long[i_data]);
      case NONREP_SHORT:
         return(nonrep_short[i_data]);
      case NET_NONCOMM:
         return(net_noncomm[i_data]);
      case NET_OPERATORS:
         return(net_operators[i_data]);
      case NET_NONREP:
         return(net_nonrep[i_data]);
      case INDEX_OI:
         return(index_oi[i_data]);
      case INDEX_NONCOMM:
         return(index_ncomm[i_data]);
      case INDEX_OPERATORS:
         return(index_operators[i_data]);
      case INDEX_NONREP:
         return(index_nonrep[i_data]);
      case OI_NONCOMM_LONG:
         return(oi_noncomm_long[i_data]);
      case OI_NONCOMM_SHORT:
         return(oi_noncomm_short[i_data]);
      case OI_OPERATORS_LONG:
         return(oi_operators_long[i_data]);
      case OI_OPERATORS_SHORT:
         return(oi_operators_short[i_data]);
      case OI_NONREP_LONG:
         return(oi_nonrep_long[i_data]);
      case OI_NONREP_SHORT:
         return(oi_nonrep_short[i_data]);
      case WILLCO_NONCOMM:
         return(willco_ncomm[i_data]);
      case WILLCO_OPERATORS:
         return(willco_operators[i_data]);
      case WILLCO_NONREP:
         return(willco_nonrep[i_data]);
      case OI_NET_NONCOMM:
         return(oi_net_nonrep[i_data]);
      case OI_NET_OPERATORS:
         return(oi_net_operators[i_data]);
      case OI_NET_NONREP:
         return(oi_net_nonrep[i_data]);
      case MOVEMENT_NONCOMM:
         return(movement_ncomm[i_data]);
      case MOVEMENT_OPERATORS:
         return(movement_operators[i_data]);
      case MOVEMENT_NONREP:
         return(movement_nonrep[i_data]);
      case MOVEMENT_OI:
         return(movement_oi[i_data]);
     }
   return(EMPTY_VALUE);
  }
// Возвращает номер ячейке в массиве, в котором эти данные хранятся, 
// Возвращает значение EMPTY_VALUE, если не удалось найти бар
int get_cot(int i)
  {
   datetime tbar=iTime(Symbol(),0,i);
   for(int k=0;k<n_str;k++)
      if(realize_data[k]<tbar)return(k);
   return(EMPTY_VALUE);
  }
// Возвращает бар для которого известно последнее значение COT данных
int get_lastdata()
  {
   return(iBarShift(Symbol(),0,realize_data[n_str-1],false));
  }
// Возвращает строку без расширения и первых 6 символов
// (было "COT - FileName.csv" стало "FileName")
string str_trim(string fname)
  {
   int strlen=StringLen(fname)-1;
   int char;
   string str;
   for(int i=strlen;i>0;i--)
     {
      char=StringGetChar(fname,i);
      if(char=='.')
        {
         for(int b=6;b<i;b++) // поменять на b=0 если не требуется
                              // удалять первые 6 символов
            str=str+CharToStr(StringGetChar(fname,b));
         return(str);
        }
     }
   return(fname);
  }
//+------------------------------------------------------------------+

Код самих индикаторов тривиален и различается только количеством инициализированных буферов и первым параметром функции get_data() . Использовать функцию IndicatorCounted() в них нецелесообразно, так как все значения подсчитываются заранее, на этапе инициализации. В начале, на этапе инициализации, вызываются основные функции библиотеки cotlib.mq4, затем настраивается сам вид графиков, после чего управление передается функции start(). Она в свою очередь единожды запускает функцию build_data(), которая отображает в окне индикатора данные за период, который охватывает отчет. В качестве примера приведем исходный код индикатора WILLCO:

#property copyright "Copyright © 2009, C-4, All Rights Reserved."
#property link      "vs-box@mail.ru"

#property indicator_separate_window
#property  indicator_buffers 3
#property  indicator_color1  Green
#property  indicator_color2  Red
#property  indicator_color3  Blue

extern int  period=52;
int movement_index=6;
extern bool Show_iNoncomm=false;
extern bool Show_iOperators=true;
extern bool Show_iNonrep=false;

double i_willco_noncomm[];
double i_willco_operators[];
double i_willco_nonrep[];

#include <cotlib.mq4>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   if(init_data()==false)error=true;
   if(error==false)load_data();
   if(error==false)count_data();
//if(error==false)count_index(period);
   SetParam();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(error==true)Print("Не удалось загрузить данные. Дальнейшая работа невозможна");
   if(DrawData==true)build_data();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetParam()
  {
   SetIndexStyle(0,DRAW_LINE);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexStyle(2,DRAW_LINE);
   IndicatorDigits(2);
   SetIndexEmptyValue(0,EMPTY_VALUE);
   SetIndexEmptyValue(1,EMPTY_VALUE);
   SetIndexEmptyValue(2,EMPTY_VALUE);
   SetLevelValue(0,0.0);
   SetLevelValue(1,20.0);
   SetLevelValue(2,80.0);
   SetLevelValue(3,100.0);
   if(load_cot_file==true)IndicatorShortName(StringConcatenate("Meta COT WILLCO (",period,"): ",str_trim(cot_file)));
   else IndicatorShortName(StringConcatenate("Meta COT WILLCO (",period,"): ",name));
   if(Show_iNoncomm==true)
     {
      SetIndexBuffer(0,i_willco_noncomm);
      SetIndexLabel(0,"WILLCO: Noncommercial Traders");
     }
   if(Show_iOperators==true)
     {
      SetIndexBuffer(1,i_willco_operators);
      SetIndexLabel(1,"WILLCO: Operators Traders");
     }
   if(Show_iNonrep==true)
     {
      SetIndexBuffer(2,i_willco_nonrep);
      SetIndexLabel(2,"WILLCO: Nonrep Traders");
     }
  }

void build_data()
  {
   int end_data=get_lastdata();
   for(int i=0;i<end_data;i++)
     {
      if(Show_iNoncomm)
        {
         i_willco_noncomm[i]=get_data(WILLCO_NONCOMM,i);
         if(Show_iOperators)i_willco_operators[i]=get_data(WILLCO_OPERATORS,i);
         if(Show_iNonrep)i_willco_nonrep[i]=get_data(WILLCO_NONREP,i);
        }
      DrawData=false;
     }
//+------------------------------------------------------------------+

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

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

#property copyright "Copyright © 2009, C-4, All Rights Reserved."
#property link      "vs-box@mail.ru"

#define EQU_NO           0
#define EQU_YES          1

#define DATA            1
#define OI              2
#define NONCOMM_LONG    3
#define NONCOMM_SHORT   4
#define SPREADING       5
#define OPERATORS_LONG  6
#define OPERATORS_SHORT 7
#define ALL_LONG        8
#define ALL_SHORT       9
#define NONREP_LONG     10
#define NONREP_SHORT    11

extern string s_list="AGREGATION.ini";
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int      h_list;                    // Дескриптор файла-списка 
                                       // (в нем находятся названия файлов-перечислений)
                                       // string   s_list;                    // Название файла-списка.

   int      h_enumeration;             // Дискриптор файла перечислений
   string   s_enumeration;             // Строка названия файла перечислений

   int      h_rezult;                  // Дискриптор файла-выхода
   string   s_rezult;                  // Название файла-выхода

   int      h_temp;                    // Временный дескриптор конечных файлов (один на всех)
                                       // используется для подсчета кол-ва файлов   
   string   s_temp;                    // Временная строка-название конечных файлов (одна на всех), 
                                       // используется для подсчета кол-ва файлов

   int      h_file[];                  // Массив постоянных дискрипторов конечных файлов.                   
   string   s_file[];                  // Массив названий конечных файлов

   datetime data[],data_all;
   int      oi[],oi_all,
   noncomm_long[],noncomm_long_all,
   noncomm_short[],noncomm_short_all,
   spreading[],spreading_all,
   operators_long[],operators_long_all,
   operators_short[],operators_short_all,
   all_long[],all_long_all,
   all_short[],all_short_all,
   nonrep_long[],nonrep_long_all,
   nonrep_short[],nonrep_short_all;

   int      str;                       // Содежрит количество конечных файлов
   int      n;                         // Содержит текущий номер конечного файла
   int      column;                    // Содежрит номер колонки
   int      frnz_str[];                // Содержит "замароженные" дискрипторы файлов*
   double   count;                     // Подсчитывает количество строк в каждом конечном файле
   string   tmp;                       // Содержит текстовую строку-ячейку полученную из конечного файла

   h_list=FileOpen(s_list,FILE_READ|FILE_CSV);                    // Открываем список файлов
   if(h_list==-1){Print("Список файлов не найден");return(0);}
   while(FileIsEnding(h_list)==false)
     {                            // Читаем его построчно
      s_enumeration=FileReadString(h_list);                       // Каждая строка имя файла-перечислений
      Print("---------------<<",s_enumeration,">>---------------");
      h_enumeration=FileOpen(s_enumeration,FILE_READ|FILE_CSV);   // Пытаемся открыть файл-перечислений
      if(h_enumeration==-1)
        {
         Print("Файл перечислений не найден ",s_enumeration);
         continue;                                                // Если файла-перечислений не сущесвует - то пропускаем его
        }

      s_rezult=StringConcatenate(ConvertName(s_enumeration),".csv");
      h_rezult=FileOpen(s_rezult,FILE_WRITE|FILE_CSV);
      if(h_rezult==-1)
        {
         Print("Не удалось создать результирующий файл: ",s_rezult,"; ",GetLastError());
         continue;
        }
      while(FileIsEnding(h_enumeration)==false)
        {
         s_temp=FileReadString(h_enumeration);                  // Считываем построчно файл-перечислений, 
                                                                // каждая строка - имя конечного файла
         h_temp=FileOpen(s_temp,FILE_READ|FILE_CSV);            // Пытаемся открыть конечный файл
         if(h_temp==-1)continue;        // Если конечный файл не существует - то пропускаем его
         str++;                                                 // Иначе количество обрабатываемых файлов увеличиваем на 1.
                                                                // Print("--> ",s_temp);
         while(FileIsEnding(h_temp)==false)
           {
            tmp=FileReadString(h_temp);
            if(tmp!="")count++;
           }
         Print("--> ",s_temp," ",count/12);
         count=0;
         FileClose(h_temp);                                    // Закрываем конечный файл
        }//End While (подсчет файлов-перечислений)
      FileSeek(h_enumeration,0,SEEK_SET);

      ArrayResize(h_file,str);
      ArrayResize(s_file,str);
      ArrayResize(data,str);
      ArrayResize(oi,str);
      ArrayResize(noncomm_long,str);
      ArrayResize(noncomm_short,str);
      ArrayResize(spreading,str);
      ArrayResize(operators_long,str);
      ArrayResize(operators_short,str);
      ArrayResize(all_long,str);
      ArrayResize(all_short,str);
      ArrayResize(nonrep_long,str);
      ArrayResize(nonrep_short,str);
      ArrayResize(frnz_str,str);
      while(FileIsEnding(h_enumeration)==false)
        {
         s_file[n]=FileReadString(h_enumeration);              // Считываем построчно файл-перечислений,
                                                               // каждая строка - имя конечного файла
                                                               // Print(str,"; ",s_file[n]);
         h_file[n]=FileOpen(s_file[n],FILE_READ|FILE_CSV);     // Пытаемся открыть конечный файл
         if(h_file[n]==-1){Print("Файл не найден");continue;}  // Если конечный файл не сущесвует - то пропускаем его
         n++;
        }// End While(откырие файлов-перечислений)   
      //for(n=0;n<str;n++){
      //   Print(n,"; ",s_file[n]);
      //}
      // К текущему моменту имеем список конечных файлов (s_file[]) 
      // и их дескрипторов (h_file[]) содержащихся
      // в одном из файле перечислений. Теперь объединяем эти файлы в один:
      while(FileIsEnding(h_file[0])==false)
        {                        // В качестве сигнала окончания файла служит конец первого файла 
                                 // (предплолагается, что файлы одинаковые)
         for(int i=0;i<str;i++)
           {                     // Читаем по колонке из каждого файла входящего в файл-перечислений.
            if(frnz_str[i]==1)continue;
            tmp=FileReadString(h_file[i]);
            switch(column)
              {
               case DATA:            data[i]=StrToTime(tmp);
               case OI:              oi[i]=StrToInteger(tmp);
               case NONCOMM_LONG:    noncomm_long[i]=StrToInteger(tmp);
               case NONCOMM_SHORT:   noncomm_short[i]=StrToInteger(tmp);
               case SPREADING:       spreading[i]=StrToInteger(tmp);
               case OPERATORS_LONG:  operators_long[i]=StrToInteger(tmp);
               case OPERATORS_SHORT: operators_short[i]=StrToInteger(tmp);
               case ALL_LONG:        all_long[i]=StrToInteger(tmp);
               case ALL_SHORT:       all_short[i]=StrToInteger(tmp);
               case NONREP_LONG:     nonrep_long[i]=StrToInteger(tmp);
               case NONREP_SHORT:    nonrep_short[i]=StrToInteger(tmp);
              }
           }// End For()
         //Print(h_file[0], ";  ",s_file[0]);
         column++;
         if(FileIsLineEnding(h_file[0])==true || FileIsEnding(h_file[0])==true)
           {  // Если строка закончилась - сравниваем даты строк всех файлов, если равны, то объединяем их
            column=0;
            if(tmp=="")continue;
            for(int k=0;k<str;k++)
              {
               if(data[0]>data[k])
                  frnz_str[k]=1;
               if(data[0]<data[k])
                  frnz_str[0]=1;
               if(data[0]==data[k])frnz_str[k]=0;
               if(data[0]!=data[k])
                 {
                  Print("Обнаружен Разрыв: ",TimeToStr(data[0],TIME_DATE),"; ",TimeToStr(data[k],TIME_DATE));
                  continue;
                 }
              }

            for(k=0;k<str;k++)
              {
               data_all=data[0];
               oi_all+=oi[k];
               noncomm_long_all+=noncomm_long[k];
               noncomm_short_all+=noncomm_short[k];
               spreading_all+=spreading[k];
               operators_long_all+=operators_long[k];
               operators_short_all+=operators_short[k];
               all_long_all+=all_long[k];
               all_short_all+=all_short[k];
               nonrep_long_all+=nonrep_long[k];
               nonrep_short_all+=nonrep_short[k];
              }
            FileWrite(h_rezult,ConvertName(s_enumeration),
                      TimeToStr(data_all,TIME_DATE),
                      oi_all,
                      noncomm_long_all,
                      noncomm_short_all,
                      spreading_all,
                      operators_long_all,
                      operators_short_all,
                      all_long_all,
                      all_short_all,
                      nonrep_long_all,
                      nonrep_short_all);
            //Print(TimeToStr(data_all,TIME_DATE),";  ",oi_all);
            data_all=0;
            oi_all=0;
            noncomm_long_all=0;
            noncomm_short_all=0;
            spreading_all=0;
            operators_long_all=0;
            operators_short_all=0;
            all_long_all=0;
            all_short_all=0;
            nonrep_long_all=0;
            nonrep_short_all=0;
           }

        }// End While(сумматор)

      // Обнуляем результаты
      FileClose(h_enumeration);
      FileClose(h_rezult);
/*for(int j=0;j<str;j++){
         FileClose(h_file[j]);
         noncomm_long[j]=0;
         noncomm_short[j]=0;
         spreading[j]=0;
         operators_long[j]=0;
         operators_short[j]=0;
         all_long[j]=0;
         all_short[j]=0;
         nonrep_long[j]=0;
         nonrep_short[j]=0;
      }*/

      n=0;str=0;
     } //End While(список файлов перечислений)

  }// End Programm   
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string ConvertName(string str)
  {
   string str_cnv;
   int strlen=StringLen(str);
   int char;
   for(int i=0;i<strlen-4;i++)
     {
      char=StringGetChar(str,i);
      str_cnv=StringConcatenate(str_cnv,CharToStr(char));
     }
   return(str_cnv);
  }
//+------------------------------------------------------------------+

По аналогичному принципу устроена программа по временному объединению отчетов – Meta COT Script Concatenate, хотя из-за более простой задачи ее алгоритм значительно «легче»:

#property copyright "Copyright © 2009, C-4, All Rights Reserved."
#property link      "vs-box@mail.ru"

extern string FilesList="CONCATENATE.ini";
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    h_list,h_file,h_cont,h_rezult;   // Дескрипторы файлов
   int    column;
   string s_list,s_file,s_cont,s_rezult,   // Строки, содержащие названия файлов
   string_cont,string_cont_f;
   h_list=FileOpen(FilesList,FILE_READ|FILE_CSV);      // Открываем список файлов
   if(h_list==-1){Print("Список файлов ("+FilesList+") не найден");return(0);}
   while(FileIsEnding(h_list)==false)
     {                  // Читаем его построчно
      s_list=FileReadString(h_list);                      // Каждая строка имя файла
      Print(s_list);
      h_file=FileOpen(s_list,FILE_READ|FILE_CSV);         // Пытаемся открыть файл с именем строки
      if(h_list==-1){Print("Файл "+s_list+" не найден");continue;}  // Если файла по имени строки
                                                                    // не сущесвует - то пропускаем его
                                                                    // s_rezult="COT - CONT - "+s_list;
      s_rezult=get_rezultname(s_list);
      h_rezult=FileOpen(s_rezult,FILE_WRITE|FILE_READ|FILE_CSV);
      while(FileIsEnding(h_file)==false)
        {
         s_file=FileReadString(h_file);
         //Print(s_file);
         h_cont=FileOpen(s_file,FILE_READ|FILE_CSV,';');
         if(h_cont==-1){Print("Файл данных "+s_file+" не найден");continue;}
         else Print("Загружаю файл данных "+s_file+"...");

         while(FileIsEnding(h_cont)==false)
           {
            string_cont=FileReadString(h_cont);
            if(string_cont=="")continue;
            if(FileIsLineEnding(h_cont)==true)
              {
               string_cont_f=string_cont_f+";"+string_cont;
               FileWrite(h_rezult,string_cont_f);
               string_cont_f="";
               column=0;
              }
            else
              {
               //if(string_cont=="")continue;
               if(column==0)string_cont_f=string_cont_f+string_cont;
               else string_cont_f=string_cont_f+";"+string_cont;
               column++;
              }
           }
         FileClose(h_cont);
        }
      FileClose(h_file);
      FileClose(h_rezult);
     }
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string get_rezultname(string fname)
  {
   int strlen=StringLen(fname)-1;
   int char;
   string str;
   for(int i=strlen;i>0;i--)
     {
      char=StringGetChar(fname,i);
      if(char=='.')
        {
         for(int b=0;b<i;b++)
            str=str+CharToStr(StringGetChar(fname,b));
         str=str+".csv";
         return(str);
        }
     }
   return("COT - CONT - "+fname);
  }
//+------------------------------------------------------------------+


4. Заставляем теорию работать!

4.1 Минута и товарный трейдер готов к работе

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

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

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

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

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

Вот некоторые свойства, которыми должна обладать торговая система для эффективной эксплуатация информацией CFTC:

1. Быть прибыльной или хотя бы нейтральной, даже без использования фильтров CFTC.

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

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

4. Техника должна быть контр трендовой по отношению к текущему локальному тренду. Сигналы CFTC к продаже будут появляться на продолжительных бычьих трендах или в крайнем случае на сильных откатах от основного движения. Сигналы к покупке будут также противоположены основному тренду или в крайнем случае локальному откату.

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

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

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

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

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

Это устранит субъективность и сделает анализ рынков гораздо проще. Итак, благоприятной ситуацией для покупки будет считаться холодный рынок с низким уровнем продаж у операторов. Холодный рынок означает, что уровень открытого интереса в данный момент крайне мал, а значит имеется потенциал роста. Будем также искать противоположенную ситуацию для продажи: рынок должен быть хорошенько разогрет (уровень ОИ крайне высокий), в то время как операторы показывают рекордный уровень продаж. Обратимся к индикаторам йены для идентификации этих моментов:



Рисунок 4-1. Индекс открытого интереса и операторов

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



График 4-2. Индекс операторов и ОИ вместе с графиком цены

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

Также, если Вы заметили, на графике были обозначены сигналы, значения которых не достигали отметок в 20 и 80%. Эти уровни не являются не зыблемыми столпами технического анализа. Для одного рынка, возможно, подойдет более низкое значение для другого - более высокое. Тоже относиться к индикаторам – нет и никогда не будет универсального для всех рынков и 100% работающего всегда и везде средства определения будущего.

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


ИНСТРУМЕНТ

ФАЙЛЫ ДАННЫХ CSV

сельскохозяйственные товарные рынки

1

СВИНИНА ПОСТНАЯ

COT - LEAN HOGS - CHICAGO MERCANTILE EXCHANGE

2

КРУПНЫЙ РОГАТЫЙ СКОТ НА ОТКОРМ

COT - FEEDER CATTLE - CHICAGO MERCANTILE EXCHANGE

3

КРУПНЫЙ РОГАТЫЙ СКОТ (ЖИВОЙ)

COT - LIVE CATTLE - CHICAGO MERCANTILE EXCHANGE

4

МОЛОКО (КЛАСС 3)

COT - MILK CONCATENATE

5

ПШЕНИЦА (ЧИКАГСКАЯ ТОВАРНАЯ БИРЖА)

COT - WHEAT - CHICAGO BOARD OF TRADE

6

ПШЕНИЦА (КАНЗАСКАЯ ТОВАРНАЯ БИРЖА)

COT - WHEAT - KANSAS CITY BOARD OF TRADE

7

ПЩЕНИЦА (ТОВАРНАЯ БИРЖА МИНИАПОЛИСА)

COT - WHEAT - MINNEAPOLIS GRAIN EXCHANGE

8

ОВЕС

COT - OATS - CHICAGO BOARD OF TRADE

9

НЕОБРАБОТАННЫЙ РИС

COT - ROUGH RICE - CHICAGO BOARD OF TRADE

10

САХАР №11

COT - SUGAR CONCATENATE

11

КОФЕ (КЛАСС "С")

COT - COFFEE C CONCATENATE

12

КОКАО

COT - COCOA CONCATENATE

13

ХЛОПОК №2

COT - COTTON 2 CONCATENATE

14

СОЕВАЯ МУКА

COT - SOYBEAN MEAL - CHICAGO BOARD OF TRADE

15

СОЕВЫЕ БОМЫ (МИНИ)

COT - MINI SOYBEANS - CHICAGO BOARD OF TRADE

16

СОЕВОЕ МАСЛО

COT - SOYBEAN OIL - CHICAGO BOARD OF TRADE

17

СОЕВЫЕ БОБЫ

COT - SOYBEANS - CHICAGO BOARD OF TRADE

18

МАСЛО (СЛИВОЧНОЕ)

COT - BUTTER (CASH SETTLED) - CHICAGO MERCANTILE EXCHANGE

19

ЗАМОРОЖЕННЫЙ КОНЦЕНТРИРОВАННЫЙ АПЕЛЬСИНОВЫЙ СОК

COT - FRZN CONCENTRATED ORANGE JUICE CONCATENATE

20

ДЕЛОВАЯ ДРЕВЕСИНА ПЕРЕМЕННОЙ ДЛИНЫ

COT - LUMBER CONCATENATE

металлы

21

МЕДЬ (ЧИСТОТА №1)

COT - COPPER-GRADE #1 - COMMODITY EXCHANGE INC.

22

СЕРЕБРО

COT - SILVER - COMMODITY EXCHANGE INC.

23

ЗОЛОТО

COT - GOLD - COMMODITY EXCHANGE INC.

24

ПЛАТИНА

COT - PLATINUM - NEW YORK MERCANTILE EXCHANGE

25

ПАЛЛАДИЙ

COT - PALLADIUM - NEW YORK MERCANTILE EXCHANGE

валюты

26

АВСТРАЛИЙСКИЙ ДОЛЛАР

COT - AUSTRALIAN DOLLAR CONCATENATE

27

КАНАДСКИЙ ДОЛЛАР

COT - CANADIAN DOLLAR CONCATENATE

28

БРИТАНСКИЙ ФУНТ СТЕРЛИНГОВ

COT - BRITISH POUND STERLING CONCATENATE

29

ЕВРО

COT - EURO FX CONCATENATE

30

ЯПОНСКАЯ ЙЕНА

COT - JAPANESE YEN CONCATENETE

31

МЕКСИКАНСКОЕ ПЬЕСО

COT - MEXICAN PESO CONCATENATE

32

НОВОЗЕЛАНДСКИЙ ДОЛЛАР

COT - NEW ZEALAND DOLLAR - CHICAGO MERCANTILE EXCHANGE

33

ЩВЕЙЦАРСКИЙ ФРАНК

COT - SWISS FRANC CONCATENATE

34

РОССИЙСКИЙ РУБЛЬ

COT - RUSSIAN RUBLE - CHICAGO MERCANTILE EXCHANGE

35

ИНДЕКС АМЕРИКАНСКОГО ДОЛЛАРА

COT - U.S. DOLLAR CONCATENATE

индексы

36

DOW JONES INDUSTRIAL

COT - DOW JONES INDUSTRIAL AVERAGE - CHICAGO BOARD OF TRADE

37

DOW JONES INDUSTRIAL x5$

COT - DOW JONES INDUSTRIAL AVG- x $5 - CHICAGO BOARD OF TRADE

38

E-MINI S&P400

COT - E-MINI S&P 400 STOCK INDEX - CHICAGO MERCANTILE EXCHANGE

39

E-MINI S&P500

COT - E-MINI S&P500 CONCATENATE

40

S&P500 STOCK INDEX

COT - S&P500 STOCK INDEX CONCATENATE

41

S&P400 MIDCAP STOCK INDEX

COT - S&P400 MIDCAP STOCK INDEX CONCATENATE

42

NASDAQ-100

COT - NASDAQ-100 STOCK INDEX CONCATENATE

43

NASDAQ-100 MINI

COT - NASDAQ-100 INDEX (MINI) CONCATENATE

44

NIKKEY INDEX

COT - NIKKEI STOCK AVERAGE CONCATENATE

45

RUSSELL-2000 E-MINI

COT - RUSSELL 2000 CONCATENATE

долговые инструменты

46

10 ЛЕТНИЙ ПРОЦЕНТЫЙ СВОП

COT - INTEREST RATE SWAPS 10YR CONCATENATE

47

5 ЛЕТНИЙ ПРОЦЕНТЫЙ СВОП

COT - INTEREST RATE SWAPS 5YR CONCATENATE

48

КАЗНАЧЕЙСКИЕ БОНДЫ

COT - U.S. TREASURY BONDS - CHICAGO BOARD OF TRADE

49

10-ЛЕТНИЕ КАЗНАЧЕЙСКИЕ НОТЫ

COT - 10-YEAR U.S. TREASURY NOTES - CHICAGO BOARD OF TRADE

50

5-ЛЕТНИЕ КАЗНАЧЕЙСКИЕ НОТЫ

COT - 5-YEAR U.S. TREASURY NOTES - CHICAGO BOARD OF TRADE

51

2х-ЛЕТНИЕ КАЗНАЧЕЙСКИЕ НОТЫ

COT - 2-YEAR U.S. TREASURY NOTES - CHICAGO BOARD OF TRADE

52

1-МЕСЯЧНЫЕ ПРОЦЕНТЫЕ СТАВКИ ЛИБОР

COT - 1-MONTH LIBOR RATE CONCATENATE

53

30-ДНЕВНЫЕ ГОСУДАРСТВЕННЫЕ ПРОЦЕНТНЫЕ БУМАГИ

COT - 30-DAY FEDERAL FUNDS - CHICAGO BOARD OF TRADE

54

3-х МЕСЯЧНЫЕ ПРОЦЕНТЫЕ СТАВКИ ТИБОР НА ЕВРОЙЕНУ

COT - 3-MO. EUROYEN TIBOR CONCATENATE

55

3-х МЕСЯЧНЫЕ ДЕПОЗИТЫ ПО ЕВРОДОЛЛАРУ

COT - 3-MONTH EURODOLLARS CONCATENATE

энергоносители

56

СЫРАЯ ЛЕКГАЯ НЕФТЬ (МАРКА LIGHT SWEET)

COT - CRUDE OIL LIGHT SWEET - NEW YORK MERCANTILE EXCHANGE

57

НАТУРАЛЬНЫЙ ГАЗ

COT - NATURAL GAS - NEW YORK MERCANTILE EXCHANGE

58

ТОПОЧНЫЙ МАЗУТ

COT - NO. 2 HEATING OIL N.Y. HARBOR - NEW YORK MERCANTILE EXCHANGE

индексы волатильности

59

МЕСЯЧНАЯ ВОЛАТИЛЬНОСТЬ ЦЕН ФЬЮЧЕРСОВ

COT - ISO NEW ENGLAND LMP SWAP - NEW YORK MERCANTILE EXCHANGE

Таблица 4-3. Список инструментов с регулярными отчетами имеющимися длительный период времени


Как видно из таблицы, в настоящий момент комиссия собирает данные по широкому спектру сель-скохозяйственных, валютных, финансовых и прочих рынках. Все файлы, описанные в таблице будут получены после выполнения скриптов Meta COT Script Build и Meta COT Script Concatenate.


4.2 Создаем исследовательский робот

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

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

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

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

Если у медленной средней текущее значение больше чем ее же значение две недели назад, значит долгосрочная тенденция повышательная, если меньше – понижательная. Так же будем анализировать пятипериодную скользящую среднюю: если ее текущее значении больше чем два дня назад, мы предположительно в краткосрочном бычьем тренде, если меньше – мы предположительно в краткосрочном медвежьем тренде. Как только краткосрочный тренд совпадет с долгосрочным, мы откроем позицию в их сторону. В качестве фильтра будет использован один из индикаторов Meta COT. Позиция будет открыта только в том случае, если индикатор будет находится в это время в диапазоне благоприятных значений. Обратимся за более детальными разъяснениями к рисунку 4-2:



График 4-4. Сигналы технического анализа подаваемые для открытия позиции

На рисунке 4-4 представлен дневной график EURUSD. В левом верхнем углу рисунка изображен отрывок недельного графика EURUSD за этот же период. Долгосрочная простая средняя (синяя линия) имеет тот же период расчета что и индикатор Meta COT Operators Index, в данном случае 26 недель. Краткосрочная средняя (красная линия) всегда пятипериодная. Видно, что 15 октября 2006 года значение красной средней (МА1) было выше, чем два дня назад (МА2), в то же время значение долгосрочной средней было выше чем две недели назад. Тренды совпали, к тому же уровень индикатора индекса операторов составлял 100%, говоря о благоприятной возможности для покупки (строго говоря это условие совпало днем раньше, однако для графический наглядности используется эта комбинация).

Робот производит покупку с обязательным выставлением уровня Stop Loss и Take Profit (это един-ственные возможные точки выхода). Причем размер уровней зависит от периода индикатора, чем больше расчетный период – тем выше значения стоп-лоссов и тейк-профитов. На каждые 26 перио-дов индикатора приходится 100 пунктов убытков и 300 пунктов прибыли. Таким образом если для 26 периодного индекса операторов стоп-лосс будет равняться 100 пунктам, а тейк-профит 300, то для 156 недельного индикатора стоп-лосс будет равен 600 пунктам, а тейк-профит 1800 пунктов (решение получилось грубым но зато простым). Предельные уровни убытков и прибылей являются единственными точками выхода из позиции, таким образом можно считать что торговая система является полностью законченной. Размер позиций фиксированный и составляет 0.1 контракта инструмента.

Система крайне не совершена, если не сказать примитивна. В целом она является хорошим способом разорения, однако все может измениться, если ее использовать с фильтрами Meta COT.

Теперь обратимся к самому исходному коду робота. Его принцип работы крайне похож на принцип работы индикатора. По большому счету робот не что иное как индикатор умеющий выставлять ордера. В момент инициализации робот опираясь на библиотеку cotlib.mq4 загружает данные для текущего графика, затем подсчитывает значения всех индикаторов, после чего получает значение одного из них. То, какой это будет индикатор зависит от целочисленной переменной indicator_type, если скажем она равна 17, то это означает что необходимо использовать индикатор WILLCO для операторов, если 22, то это индекс рассчитанный для неподотчетной публики.

Узнать какому номеру какой индикатор соответствует весьма просто, достаточно прочитать определения предпроцессора в самом начале библиотеки cotlib.mq4. За период расчета индикатора отвечает одноименная переменная period. Перебор индикаторов и их периодов был элегантно организован с помощью оптимизатора стратегий. Обе переменные помечаются как оптимизированные. Переменная period стартует со значения 26, шагом 26 и стопом 156. Переменная indicator_tape стартует со значения 16, шагом 1 и стопом 26. Таким образом, достигается перебор всех участвующих индикаторов и различных периодов усреднения:



Рисунок 4-4. Входные параметры окна настроек эксперта


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

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


Название инструмента

Индикатор

Период расчета

Всего сделок

Прибыльность

Мат. Ожидание

Просадка %

Прибыль

$

ЕВРО

Index Operators

26

77

1.79

62.31

12.57

4798

БРИТАНСКИЙ ФУНТ

WILLCO Noncomm

26

140

1.44

18.64

7.12

2600

ЯПОНСКАЯ ЙЕНА

Index Nonrep

52

35

1.37

63.29

14.85

2200

ШВЕЦАРСКИЙ ФРАНК

Movement Index Operators

26

21

3.96

159.71

4.63

3354

АВСТРАЛИЙСКИЙ ДОЛЛАР

Index Nonrep

26

59

1.98

57.50

5.67

3392

НОВОЗЕЛАНДСКИЙ ДОЛЛАР

Index Noncomm

26

20

1.97

59.00

4.13

1180

ИНДЕКС ДОЛЛАРА

Movement Nonrep

26

144

1.20

1.50

1.98

216

ЗОЛОТО

Index Nonrep

26

81

1.84

52.09

5.70

4219

СЕРЕБРО

WILLCO Operators

26

165

1.85

26.58

4.76

4385

ПЛАТИНА

Index Nonrep

26

233

1.77

24.54

6.73

5717

ПАЛАДИЙ

Index Noncomm

26

142

1.23

8.15

10.61

1158

САХАР

WILLCO Operators

26

18

1.89

61.22

6.67

1102

КОКАО

Index Operators

26

29

1.96

56.59

6.08

1641

КОФЕ

Index Operators

52

113

1.38

19.58

7.59

2212

ОВЕС

Index Operators

26

15

2.24

83.50

8.25

1252

ПШЕНИЦА

Index OI

26

53

1.66

53.25

8.91

2822

СОЕВЫЕ БОБЫ

Index Noncomm

26

66

2.88

118.72

6.46

7965

АПЕЛЬСИНОВЫЙ СОК

Index Operators

26

29

2.75

68.83

2.73

1996

НЕФТЬ LIGHT SWEET

Index Operators

26

194

1.23

16.53

12.68

3206

E-MINI S&P

Movement Operators

26

32

2.01

75.21

6.66

2406

Таблица 4-5. Лучшие результаты тестирования фильтров COT при фиксированном лоте 0.1


Результаты перебора индикаторов достаточно интересны. Во-первых, наблюдается явное смещение в прибыльную зону у Индекса трейдеров и WILLCO. Поведение индикаторов группы Movement Index более неопределенное. Хотя на некоторых инструментах с помощью этого индикатора были достигнуты максимальные прибыли (как правило индикатор рассчитывался для операторов), на некоторых значениях этот же индикатор давал большой убыток. Примечательным оказался Movement Index рассчитанный для некоммерческих трейдеров. Его значения стабильно приносили максимальный убыток практически для всех инструментов (точка 43 на рисунке 4-6). Возможно более глубокое исследование этого феномена поможет использовать его сигналы в свою пользу. Концептуально график оптимизации можно изобразить на следующем рисунке:


Рисунок 4-6. Общая схема эффективности перебора индикаторов и их параметров

Красная линия – нулевой уровень доходности. Начиная с 43 прогона прибыль становиться менее стабильной.

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

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



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

Теперь сравним эффективность фильтров самих по себе. Для этого прогоним тест на одном и том же графике с фильтрами COT и без него. В качестве инструмента для прогона используем фьючерс евро. На графике 4-8 представлен результат торговой системы без использования фильтра COT:



График 4-8. Результаты торгового робота без использования фильтров COT

Как видно итоговая прибыль составила 1897 долларов, что приблизительно эквивалентно такому же количеству пунктов при 0.1 лоте. Максимальная просадка при этом составила 30%, что бесспорно очень много. Теперь обратимся к графику 4-9. Это та же самая стратегия, но уже отфильтрованная значениями 26-недельного индекса операторов:


Таблица 4-9. Результаты торгового робота с использованием фильтров COT.


Как видно, количество сделок резко уменьшилось, математическое ожидание выигрыша возросло. Итоговая прибыль получилась ни на много больше предыдущего теста, однако самые большие изменения произошли с уровнем максимальной просадки. Теперь она составила 8.6% что гораздо меньше предыдущего варианта. Бесспорно, фильтры COT достаточно эффективны, позволяя даже убыточные стратегии выводить в плюс.

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


4.3 Послесловие достойное продолжения

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

1. Стоит ли применять логику открытия позиции описанную в эксперте на практике?
Конечно нет. Без труда Вы сможете найти более подходящую технику для определения боле точ-ных моментов для входа в рынок. Возможно, Вы уже имеете свои собственные наработки в области технического анализа. Попробуйте внедрить фильтры CFTC в свою торговую стратегию. Снабдите исследовательского робота Meta COT своей логикой ведения позиции, только после этого проводите масштабные исследования с его помощью.

2. Позиции какой из трех групп лучше отслеживать?
Однозначного ответа нет. Выяснить какая группа наиболее эффективна на том или ином рынке, поможет Meta COT Expert. Переберите с его помощью все три группы для каждого рынка и выберите ту, которая на Ваш взгляд дает более точные прогнозы.

3. Какой из индикаторов лучше использовать?
Однозначного ответа нет. Предварительные тесты показывают, что довольно неплохим выбором мог бы стать WILLCO или индекс движения. Опять таки, необходимо выбрать такой индикатор, который бы во-первых хорошо соотносился с рынком а во-вторых, хорошо сочетался с используемой ТС. В любом случае исследовательский робот должен определить наиболее подходящий индикатор при условии программирования в нем логики ТС.

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

5. Какие уровни индикаторов считать критическими?
В своей книге, Ларри Вильямс показывает графики с разными уровнями. В том время как на одних графиках изображены уровни 25 – 75 %, на других 20 – 80%. Возможно, на одних рынках эффек-тивные уровни более широкие, а на других более узкие. В любом случае эффективность уровней будет в диапозоне 0 – 30% и 70 – 100%. Выяснить оптимальные уровни можно с помощью исследо-вательского робота. Создайте две переменные, содержащие значение нижнего и верхнего уровня. Передайте эти переменные оптимизатору. Плавно перебирайте значения двух переменных ища оптимальный результат.

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

7. Я хочу объединить несколько инструментов в один с помощью программы Meta COT Aggregation, однако не уверен, что объединение будет корректным. Как выяснить корректно ли я объединил инструменты?

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

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

9. Я не могу найти нужный отчет для рынка.
Отчеты создаются далеко не для всех рынков. Возможно по рынку, который вы выбрали, отчеты не собираются. Найдите требуемый рынок в таблице, представленной в 4 части. Если его нет в таблице, значит скорее всего отчетов для него просто не существует, либо они не полные, поэтому их нельзя использовать. Если в таблице рынок определен, посмотрите название файла-отчета, соответствующее ему. Загрузите в индикатор этот файл в ручную.

10. Индикатор (скрипт, эксперт) не работает. Что делать?
Вам стоит более внимательно прочитать третью часть. Скорее всего, Вы что-то забыли сделать или сделали неправильно. Внимательно прочтите и попытайтесь решить проблему самостоятельно.

11. Индикатор не отображается.
Основной причиной этого является отсутствие файла-отчета. Проверьте что файл-отчет был загружен. Для этого откройте окно «Терминал», Выберете вкладку «Журнал» и загрузите индикатор вновь. Если индикатор не нашел файл-отчет, то появиться предупреждающее сообщение: «Не уда-лось загрузить файл Название_Файла.scv. Дальнейшая работа невозможна». Зайдите в каталог \files Вашего терминала и проверьте существования необходимого файла. Если файла не существует, сотрите все отчеты с помощью пакетной программы erase_cot.bat, после чего создайте их вновь. Требуемый файл должен появиться.

12. Индикатор отображается, но не тот. Вместо названия индикатора надпись «ИНСТРУМЕНТ НЕ НАЙДЕН!».
Скорее всего, название текущего инструмента не соответствует ни одному из отчетов. Отройте файл settings.ini и найдите отчет, который необходимо загружать автоматически. Если отчета нет, то создайте строку настройки самостоятельно (как это сделать описывается в разделе 3.4). Впишите название инструмента в файл-перечисление. Перезагрузите индикатор, он должен заработать.

13. Эксперт не совершает ни одной сделки.
Возможная причина в том, что файлы-отчеты требуемые для работы эксперта не были скопированы в каталог \tester\files. Для тестера стратегий используется свой каталог, поэтому файлы необходимо располагать в нем. Скопируйте все файлы в т.ч. настроечные в каталог \tester\files. Эксперт должен заработать.

14. Можно ли на основе Meta COT создать свой собственный индикатор?
Конечно. Основная функция, которая Вам понадобиться это get_data(int type, int bar). Она возвращает значение индикатора вид которого определен параметром type. Более подробно исходный код и примеры описаны в третье части.

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

16. Скрипты запускаются без возможности их настройки / Скрипты каждый раз перед запуском показывают окно настроек, хотя этого не требуется.
За вызов окна настроек отвечает директива #property show_inputs расположенная в самом начале исходных файлов. Закомментируйте директиву, если окно настроек не требуется. Снимите комментарии если наоборот потребуется настройка параметров. Затем перекомпилируйте скрипт.

17. Даже после прочтения статьи у меня остались многие вопросы…
Вам необходимо несколько раз перечитать книгу Ларри Вильямса «Секреты торговли на фьючерсном рынке. Действуйте вместе с инсайдерами». Тема анализа отчетов CFTC слишком обширна, чтобы она могла быть полностью раскрыта в одной статье или даже в одной книге.

Источники

1. Уильямс Л. Секреты торговли на фьючерсном рынке: Действуйте вместе с инсайдерами. М.: Альпина Бизнес Букс, 2007. – 239с.
2. Stephen Briese. The Commitments of Traders Bible.
3. Макконнелл К.Р., Брю Экономикс С.Л. Экономикс, 13-е издание. М.: Инфра-М, 2001. – 974с.
4. Лофтон Т. Биржевые секреты: Фьючерсы. Смоленск: Смоленск-Русичи, 2008. – 368с.
5. http://www.procapital.ru/forumdisplay.php?f=267 Раздел русскоязычного форума посвященный ис-пользованию COT.
6. http://www.aup.ru/articles/finance/1.htm Понятие рисков в экономической деятельности Валерий Сергеевич Романов.
7. http://www.timingcharts.com WEB-графики, поддерживающие индикаторы COT.
8. http://www.ireallytrade.com Сайт Ларри Вильямса. Содержит регулярно обновляемую информацию по отчетам COT. На страницах сайта Ларри Вильямс регулярно дает ценные советы в виде телевизионных передач, относительно благоприятных моментов спекуляций.
9. http://commitmentsoftraders.org Сайт Стефана Бриза. В основном посвящен его же книге (см. источник 2). Содержит полезную аналитику и дополнительные индикаторы в основном в PDF-формате.

10. http://cftc.gov Сайт комиссии CFTC. Содержит регулярно обновлемые данные по позициям трейдеров. Является основным источником информации при анализе данных COT.