Программирование симулятора

   Вне зависимости от устройства (интегрированный или основанный на компонентах симулятор) в него должна быть введена логика системы, используемой пользователем. Язык программирования может быть или многоцелевым языком программирования, как С++ или FORTRAN, или собственным языком скриптов программы. Без содействия формального языка невозможно выразить торговые правила системы с достаточной для симуляции точностью. Необходимость в программировании того или иного вида не следует рассматривать как неизбежное зло – пользователь может приобрести много опыта, поскольку программирование заставляет выражать свои идеи упорядоченно и целенаправленно.
   В качестве примера программирования логики торговой системы рассмотрим TradeStation, популярный интегрированный пакет от Omega Research, содержащий интерпретатор для собственного языка программирования, называемого Easy Language, обеспечивающий проведение тестов на исторических данных. Easy Language – собственный язык фирмы, основанный на Pascal (многоцелевом языке программирования). Как выглядит простая торговая система, запрограммированная на Easy Language? В качестве примера предлагаем код для системы простого пересечения скользящей средней:
   Эта система открывает длинную позицию (один контракт) при открытии на следующий день, когда цена закрытия пересекает скользящую среднюю вверх, и короткую позицию (один контракт), когда цена закрытия пересекает скользящую среднюю вниз. Каждому приказу присваивается имя или идентификатор: А – на покупку, В – на продажу. Длина скользящей средней (Len) может задаваться пользователем или оптимизироваться программой.
   Ниже та же система, запрограммированная на языке С++ с помощью набора инструментов C-Trader от Scientific Consultant Services, в состав которого входит торговый симулятор C++:
   За исключением синтаксиса и обозначений, различия в применении С++ и Easy Language невелики. Наиболее важны сноски на текущий бар (cb) и на данный симулируемый торговый счет или ссылку на класс симулятора (ts) в версии на С++. Так, на C++ можно использовать любое количество симулируемых счетов; это важно при работе с портфелями и метасистемами (системами, управляющими счетами другой системы) и при разработке моделей, включающих скрытую адаптацию с движением вперед.

Выходные данные симулятора

   Все хорошие торговые симуляторы создают выходные данные, содержащие разнообразную информацию о поведении моделируемого счета. Можно ожидать получения данных по чистой прибыли, количеству прибыльных и убыточных сделок, максимальным падениям капитала и прочим характеристикам системы даже при использовании самых простых симуляторов. Более продвинутые программы предлагают отчеты по максимальному росту капитала, среднему благоприятному и неблагоприятному движению рынка, статистическим оценкам и т. д. и т. п., не говоря уже о детальном анализе индивидуальных сделок. Высокоуровневые симуляторы могут также включать какие-либо показатели соотношения прибыли и риска, например годовое соотношение риска/прибыли (ARRR) или отношение Шарпа – важный показатель, широко используемый для сравнения эффективности различных портфелей, систем или фондов (Sharpe, 1994).
   Выходные данные торгового симулятора обычно представляются пользователю в виде одного или нескольких отчетов. Два основных вида отчетов представляют собой обзор эффективности и детальный отчет по каждой сделке. Информация, содержащаяся в этих отчетах, может помочь трейдеру оценить «торговый стиль» системы и определить, годится ли она для реальной торговли.
   Возможно формирование и других видов отчетов, которые могут включать разнообразную информацию, генерируемую программами, как правило, в виде электронных таблиц. Почти все таблицы и графики в этой книге были построены именно так: выходные данные симулятора переносились в Excel, где обрабатывались и форматировались для представления в законченном виде.
 
   Отчеты об эффективности системы
   В качестве примера итогового отчета об эффективности системы, мы приготовили два отчета, полученные при тестировании уже упоминавшейся системы пересечения скользящей средней. Табл. 2–1 представляет собой отчет о системе, написанной и проработанной на TradeStation, а табл. 2–2 – отчет о системе, созданной с помощью С-Trader. В обоих случаях параметр длины скользящей средней был установлен равным 4.
   Большинство отчетов разбивают данные на показатели для длинных позиций, коротких позиций и всех позиций вместе. Кроме того, указываются прибыль, риск и стиль торговли. Факторы прибыли включают прибыль от всех прибыльных сделок, максимальную прибыль в одной сделке и среднюю прибыль в одной сделке. Факторы риска включают убыток от всех убыточных сделок, максимальный убыток в одной сделке, средний убыток в одной сделке и максимальное падение капитала, находящегося на моделируемом счете. Факторы риска и прибыли отражаются на показателях общей прибыли (или общего убытка) системы во всех сделках, средней прибыли (убытка) в одной сделке, соотношения средней прибыльной и убыточной сделок, фактора прибыльности (общей прибыли, деленной на общий убыток) и общего дохода (за год или без определения времени) моделируемого счета.
   К таким факторам также относятся общее количество сделок, количество прибыльных сделок, количество убыточных сделок, максимальное количество последовательных прибылей и убытков и среднее количество баров в прибыльных и убыточных сделках. В отчетах также приводятся критические для оценки системы показатели прибыли, риска и стиля торговли.
   Хотя все отчеты обеспечивают анализ системных показателей прибыли, риска и стиля торговли, между ними существуют принципиальные различия. В некоторых отчетах, пытаясь объединить максимальное количество информации в минимальном объеме, умножают значения на 10, чтобы не ставить десятичные точки, и располагают цифры в виде таблицы. В других используются менее сокращенные наименования, не округляются и не масштабируются значения и форматируются выходные данные в виде более или менее классических отчетов.
   Различия в формате менее важны, чем в собственно заключениях. Эти различия возникают из-за разнообразия подходов и определений, заложенных в системах. Например, количество прибыльных сделок может по-разному определяться на одних и тех же данных различными системами ввиду разного определения прибыльности. Некоторые симуляторы считают выгодной сделку, в которой прибыль/убыток равны нулю; другие считают выгодными только сделки с положительным балансом. Это различие и влияет на подсчет сделок, и на значение средней прибыльной сделки, и на соотношение прибыльных/убыточных сделок. Подобным же образом среднее количество дней в сделке может меняться в зависимости от метода подсчета дней. Некоторые симуляторы включают в подсчеты входной день, другие – нет. Данные по доходности счета также могут различаться – например, они могут приводиться к процентам годовых или даваться в абсолютном виде.
   Разница в содержании отчетов может быть и более значительной. Некоторые программы просто разбивают данные на результаты коротких позиций, длинных позиций и общие. Другие ведут анализ отдельно по сделкам в пределах выборки данных и вне ее. Дополнительное разделение проясняет картину; становится видно, как система, оптимизированная на одной выборке данных, будет себя вести за ее пределами. Проверка на данных, взятых из другого периода, обязательна для оптимизированных на некотором периоде систем. В некоторых отчетах присутствуют и другие важные показатели, такие как общее количество баров, максимальный подъем (показатель, противоположный максимальному падению капитала), максимальные благоприятное и неблагоприятное движения, максимальное и минимальное значения капитала на счете, прибыль в долларах за год, изменчивость торговли (в виде стандартного отклонения) и годовое соотношение риска/прибыли (вариант отношения Шарпа). Расчет статистических показателей, например т-критерия и его ассоциируемой вероятности, для отдельных тестов либо для множественных тестов и оптимизаций также является желательной чертой симулятора. Статистические функции, такие как т-тест и вероятности, важны потому, что помогают определить, действительно ли система отражает деятельность реального рынка или успех обусловлен случаем либо излишней подгонкой параметров системы под прошлые данные. Могут применяться многие дополнительные и, возможно, полезные методики анализа на основе информации, содержащейся в отчетах. Среди этих методов (Stendahl, 1999) – общие позитивные аутсайдеры, общие негативные аутсайдеры, селективная общая прибыль (за исключением выбросов), отношение убытков (максимальный убыток, деленный на общую прибыль), соотношение подъем/падение капитала, максимальный период простоя системы и прибыль стратегии «купи и держи» для сравнения с результатами торговой системы. Кроме того, в некоторых отчетах создается график состояния счета в зависимости от времени.
   Если считать, что история повторяется, то хорошее понимание прошлого должно помочь аналитику при построении прогнозов на будущее. Хороший отчет об эффективности дает широкий обзор исторического поведения торговой стратегии. Показатели прибыли и риска показывают, насколько хорошо система работала на данных рассматриваемого исторического периода. Отношение Шарпа, или годовое соотношение прибыли/риска, измеряет прибыль с учетом риска. Т-тесты и подобные статистические методы могут отличить реально эффективную на рынке стратегию от случайности или неправильной оптимизации. Результаты, достигнутые за счет действительно эффективных правил, будут повторяться снова и снова; случайные результаты вряд ли повторятся в будущем. В общем, хороший отчет помогает обнаружить явления, которые могут повторяться. Поиск устойчивых явлений, приносящих прибыль, – основа любого длительного успеха в трейдинге.
   На этом заканчивается обсуждение отчетов об эффективности, доступных с использованием большинства симуляторов. Сейчас мы рассмотрим другой тип отчетов, предлагаемых симуляторами: отчет для каждой сделки.
 
   Отчеты для каждой сделки
   Примеры отчетов для каждой сделки были созданы с использованием симуляторов TradeStation (табл. 2–3) и C-Trader toolkit (табл. 2–4). Оба отчета описывают упоминавшуюся ранее систему пересечения скользящей средней. Так как рассматривался период с сотнями сделок и полный отчет слишком длинный, из таблиц удалены большие объемы текста, помеченные многоточиями. Поскольку данные отчеты представлены только как иллюстрации, такие пропуски вполне допустимы.
   В отличие от отчета об эффективности, дающего общий обзор поведения торговой системы, детальный отчет, или отчет для каждой сделки, рассматривает в подробностях каждую из сделок, проведенную с моделируемым счетом. Минимальный отчет сопровождает каждую из сделок, включая даты входа и выхода (и время, если используются внутридневные данные), цены входа и выхода, позиции (длинные или короткие, количество контрактов) и прибыль или убыток от каждой сделки. Более обширный отчет для каждой сделки также будет включать информацию по виду использованного приказа (стоп-приказ, лимитный или рыночный приказ), по какой цене торгового дня приказ был исполнен (в начале, при закрытии или посередине), количество дней в каждой сделке, состояние счета на начало каждой сделки, максимальные благоприятные и неблагоприятные движения за каждую сделку и состояние счета при выходе из каждой сделки.
   Как и отчеты об эффективности, отчеты для каждой сделки могут быть представлены по-разному и могут основываться на различных определениях вычисляемых показателей.
   Если отчет об эффективности обеспечивает обзор всего «леса», то отчет о каждой сделке заостряет внимание на отдельных «деревьях»: в хорошем отчете каждая сделка рассматривается детально. Каковы были максимальные отрицательные переоценки открытой позиции, какова была бы прибыль при идеальном выходе и какова была «настоящая» прибыль (или убыток) моделируемой сделки, была ли торговля достаточно последовательной, были ли новые сделки лучше или хуже более старых, как можно использовать опыт худших сделок для улучшения системы – вот вопросы, на которые нельзя ответить при обзоре только общей эффективности системы. Кроме того, отчет по каждой сделке может быть дополнительно обработан в виде таблицы, например для построения гистограмм (Sweeney, 1993). Гистограммы могут показать, какая часть потенциальных прибылей фиксируется при использовании данной стратегии выхода, и полезны при определении целей прибыли. Кроме того, тщательное изучение лучших и худших сделок может дать результаты, полезные для улучшения системы.

Эффективность симулятора

   Торговые симуляторы могут сильно различаться по таким показателям, как мощность, емкость и скорость. Скорость важна при выполнении многих тестов или проведении сложных оптимизаций, например генетических. Скорость также важна при разработке систем для портфельной торговли или при использовании длинных внутридневных серий данных с тысячами сделок и сотнями тысяч числовых данных. В некоторых случаях от скорости симулятора зависит сама возможность проведения анализа: ряд задач требует поистине огромного объема расчетов, недоступного для «медленных» программ. Емкость симуляторов определяет ограничения объема задач (количество баров данных, которое может загружаться или объем кода самой системы). Мощность симулятора – показатель, определяющий, как сложные тесты и задания могут выполняться на базах данных цен товаров или на целых портфелях, что важно для серьезной профессиональной торговли. Достаточно мощный симулятор требуется, например, для использования многих торговых моделей, приведенных в этой книге.
 
   Скорость
   Наиболее важный фактор, влияющий на скорость работы системы, – природа используемого языка: скриптовый или программный, т. е. определение, является ли программа скриптом или используется в интерпретаторе. Современные компиляторы языков общего назначения, таких как С++, FORTRAN и Pascal/Delphi, переводят написанную пользователем программу в высокоэффективный машинный код, пригодный для прямого исполнения процессором; это делает пакеты с использованием таких языков и компиляторов весьма быстрыми. С другой стороны, собственные интерпретируемые языки, такие как Visual Basic for Applications и Easy Language, должны переводиться и подаваться в процессор построчно при исполнении сложного, насыщенного циклами исходного кода. Каков же возможный выигрыш в скорости для компилируемого языка по сравнению с интерпретируемым? Мы слышали о системах, которые после перевода с собственного языка на С++ стали работать в 50 раз быстрее!
 
   Емкость
   Если скорость в основном зависит от работы с языком (интерпретируемым или компилируемым), то емкость главным образом от используемого 16– или 32-битного программного обеспечения. Старые 16-битные программы часто зависят от предела в 64 кбайт, т. е. практически для тестирования системы может быть загружено не более 15 000 баров данных (около 4 дней тиковых или 7 недель 5-минутных данных S&P 500). Кроме того, если у системы код большого объема, будьте готовы получить сообщение, что программа с ней не может справиться. Современные продукты, написанные на FORTRAN или С++, работают с соответствующими компиляторами, что позволяет, например, загрузить для тестирования всю историю тиков S&P 500 c появления индекса в 1983 г., если, конечно, у компьютера достаточно памяти. Кроме того, практически нет ограничений на количество сделок, принимаемых системой, или на сложность и размер самой системы. Все современные компиляторы для FORTRAN, С++, Pascal/Delphi – полностью 32-битные программы, работающие под 32-битными операционными системами, такими как Windows 95, Windows NT или LINUX/UNIX. Любой симулятор, работающий на основе таких компиляторов, способен работать с огромными объемами данных без труда. Поскольку большинство программных пакетов постоянно совершенствуется, проблема емкости становится все менее и менее принципиальной.
 
   Мощность
   Различия в мощности симуляторов главным образом зависят от языка программирования. Для начала рассмотрим язык, но не в аспекте скорости компилируемых и интерпретируемых языков, а в аспекте его возможностей. Можно ли изящно и обстоятельно запрограммировать самую сложную торговую идею? Как правило, примитивные языки не дают всех возможностей, необходимых для кодирования наиболее сложных торговых стратегий. К сожалению, наиболее мощные языки сложнее всего изучать. Но если человеку удалось овладеть таким языком, как С++, возможным становится практически все. Ваш текстовый процессор, программа работы с таблицами, броузер и сама операционная система, скорее всего, были исходно написаны на С++ или его предшественнике – Си. Такие языки, как С++ и Object Pascal (основа Borland Delphi), расширяемы и могут легко быть приведены в соответствие с требованиями разработки торговых систем с помощью использования библиотек и дополнительных компонентов. Языки Visual Basic и Easy Language, хотя и не обладают мощностью многоцелевых объектно-ориентированных языков вроде С++ и Object Pascal, более легки в изучении и имеют большинство необходимых возможностей. Гораздо слабее и не вполне достаточны для разработчика продвинутых систем макроязыки, встроенные в ряд популярных программ построения графиков, например MetaStock. Как правило, чем мощнее используемый язык, тем мощнее симулятор.
   Вопросы оформления также влияют на мощность симулятора, особенно важна модульность и расширяемость. Симуляторы, использующие С++ или Delphi (Object Pascal) как основной язык, чрезвычайно расширяемы и модульны, поскольку таковы сами языки, спроектированные «снизу вверх». Библиотеки классов позволяют определять новые типы данных и операторов. Компоненты могут обеспечивать функции в готовых блоках, например управление базами данных или построение графиков. Даже «старинные» библиотеки, такие как Numerical Algorithms Group Library, International Mathematics and Statistics Library и Numerical Recipes Library, могут обеспечить самые разнообразные потребности. Модули, называемые User Functions могут быть написаны на Easy Language, а функции, написанные на других языках (включая C++), могут быть вызваны, если они записаны в виде DLL (динамической библиотеки ссылок). Макроязыки, с другой стороны, не столь гибки, что сильно лимитирует их эффективность для разработки продвинутых систем. С нашей точки зрения, возможность использования модулей, написанных на другом языке, абсолютно необходима: у разных языков разные «акценты», и даже при использовании мощного языка вроде С++ имеет порой смысл обратиться к модулям, созданным на другом языке, например таком, как Prolog (язык, разработанный для написания экспертных систем).
   Еще одно важное свойство симуляторов, не связанное с языками программирования, – способность симулятора работать не только с индивидуальными финансовыми инструментами, но и с портфелями. Многие продукты не имеют возможности выполнять оптимизацию целых портфелей, хотя порой это достижимо при помощи дополнительных модулей. С другой стороны, хорошо организованный симулятор, как правило, позволяет моделировать торговлю портфелем различных финансовых инструментов.

Надежность симуляторов

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

Выбор правильного симулятора

   Если вы серьезно хотите заниматься разработкой продвинутых торговых систем, торговать сильно диверсифицированными портфелями, проводить тестирование индивидуальных контрактов или опционов, вам нужно собраться с силами для изучения программирования – вам нужен симулятор, созданный с помощью языков программирования общего назначения, таких как С++ или Object Pascal. Такие симуляторы имеют открытую архитектуру, позволяющую использовать множество дополнений и библиотек: библиотеки по техническому анализу, например от FM Labs (609-261-7357) и Scientific Consultant Services (516-696-3333); библиотеки общих числовых алгоритмов, например от Numerical Recipes (800-872-7423), Numerical Algorithms Group (NAG) (44-1865-511-245) и International Mathematics and Statistics Library (IMSL), в которых хорошо освещена статистика, линейная алгебра, спектральный анализ, дифференциальные уравнения и другие математические приложения. Продвинутые симуляторы с использованием общих языков программирования также доступны целому миру компонентов и графических средств управления, покрывающих все аспекты от сложного построения графиков и представления данных до продвинутого управления базами данных, и при этом совместимы с C++ Builder и Delphi, а также с Visual Basic и Visual C++.
   Если же вам нужно нечто менее трудоемкое, выбирайте полные интегрированные решения. Убедитесь, что язык симулятора позволяет использовать процедуры, вызываемые по необходимости из DLL. Остерегайтесь продуктов, нацеленных в основном на построение графиков и с ограниченными возможностями программирования, если вы собираетесь разрабатывать, тестировать на исторических данных и использовать в торговле механические торговые системы, значительно отличающиеся от традиционных индикаторов.

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

   Мы предпочитаем использовать симуляторы, основанные на практике современного объектно-ориентированного программирования. Одна из причин такого выбора состоит в том, что объектное ориентирование упрощает создание нужного количества моделируемых счетов, каким бы оно ни было. Это в особенности полезно при моделировании торговой системы, управляющей целым портфелем товаров или акций, как это сделано в большинстве тестов в данной книге. Объектно-ориентированные симуляторы также хороши для построения адаптивных самооптимизирующихся систем, в которых иногда требуется использовать внутреннее моделирование. Кроме того, такие программы позволяют достаточно просто создавать метасистемы (системы, принимающие решения на основе графиков изменения капитала других систем). Например, метасистемами можно считать модели распределения активов, поскольку они динамически меняют распределение средств между отдельными торговыми системами или счетами. Хороший объектно-ориентированный симулятор может генерировать графики изменения капитала портфелей и другую информацию для создания и тестирования на исторических данных систем распределения активов, работающих на основе множественных торговых систем. Из этих соображений, а также в силу привычки большинство тестов в этой книге проведены с использованием C-Trader tookit. Для того чтобы почерпнуть полезные знания из этой книги, не требуются познания в С++ и программировании. Логика любой системы или элемента системы будет подробно рассматриваться в тексте.

Глава 3. Оптимизаторы и оптимизация

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