Блог им. WinterMute
Да! Именно так! Разработка собственного тестера или покупка готового не приведёт к успеху, если нет самого главного – идеи. Можно прятаться за кучей графиков или оправдывать себя горой ненужного “профессионально написанного кода”, коллекционировать и применять кстати и не кстати различные термины, знать на зубок тервер и математику. Но нет идеи – нет и денег!
Откуда появляются идеи? Может, это совокупность опыта, природной чувствительности, удачи? Так, или иначе, необходимо отбросить на самом раннем этапе всё несущественное, и выявить или почувствовать перспективные направления, чтобы не тратить время на просто перебор. Энтузиазм, как один из важнейших факторов успеха, может быть сведён на нет постоянными неудачами переборов. Тестер – это помощник, позволяющий отшлифовать алгоритм, а не создать его. Но, к слову сказать, найти хорошую идею можно и с помощью него – перебор тоже, совершенно случайно, может дать результат, но он, всё-таки, никогда не будет давать стабильные результаты. Грааль спрятан внутри!
Сделав свой тестер, я стал гонять простые стратегии, и постоянно перебирал кучу параметров: “а что если торговать только по вторникам с 10.30 до 12?” или “а если усредняться после просадки в 4%… а если после 4.5? а если по уровням фибо?” и так далее… Это магия “возможности перебрать кучу параметров и вариантов”. Кажется, что если есть такая возможность, то непременно что-то да найдётся. И главное – что находится же! Но, отнимают прибыль не только комисы, спред и проскальзывание, а ещё и жадная вера в свои статически неустойчивые гипотезы.
Важна именно исследовательская работа, а тестер не совсем пригоден для этого. Но, есть то, что подойдёт чуть лучше – языки манипулирования данными. На самом деле, это тот же перебор, во многом, ничуть не хуже, чем и тестер, но, извините, альтернатив не так много.
Научившись оперативно манипулировать данными, можно получить в своё распоряжение хороший инструмент, для проверки своих гипотез. Здесь сгодятся заточенные для этого языки: R, Pyton, Matlab, SQL и пр. О последнем я хотел вкратце рассказать.
SQL – это язык запросов для реляционных БД.На SQL удобно проводить анализ данных, считать динамику, корреляцию, дисперсию, в общем такой мини дата-майнинг. Не нужен никакой иной язык программирования, достаточно иметь сами данные (котировки и т.д.) и дать волю фантазии. Тут можно использовать open-source'ный PostgerSql, MySql, MSSql… Вариантов очень много. Я пишу на SQL под ORACLE, и не использую специальных библиотек, кроме встроенного в ORACLE диалекта (аналитические функции и т.п). Этого вполне хватает.
Наиболее общая конструкция запросов такова: SELECT [что мы хотим выбрать] FROM [источники данных] WHERE [условия]. Т.е. в отличии, например, от C# или Java, в SQL надо лишь сформулировать «что надо сделать», а не «как это сделать». Приведу теперь несколько простых примеров SQL запросов.
Дана последовательность из 100500 случайных чисел от 1 до 10. Найти среднее квадратичное отклонение этой последовательности:
SELECT DISTINCT SQRT (SUM (val) over ()) FROM (SELECT POWER (val - SUM (val) over () / COUNT (*) over (), 2) / COUNT (*) over () val FROM (SELECT ROUND (dbms_random.VALUE ( 0.5, 10.49999999 )) val FROM dual CONNECT BY ROWNUM < 100500 + 1))
К слову сказать, то же самое можно сделать встроенной функцией STDDEV:
SELECT STDDEV (val) FROM (SELECT ROUND (dbms_random.VALUE (0.5, 10.49999999 )) val FROM dual CONNECT BY ROWNUM < 100500 + 1)
Ещё пример: в своё время у меня на руках оказались данные об атмосферном давлении, я, недолго думая, решил попробовать найти корреляцию между давлением и, например, нашими фьючами. К слову сказать, явной зависимости я не нашёл, хотя, в некоторые периоды она была >0.7. Вот так выгляди простейший запрос (pressure – таблица с данным о давлении, quotes – таблица котировок), также, добавим дополнительные условия: период с апреля по сентябрь 17, учитывать только понедельник и пятницу и, время с 14 по 18:
SELECT DISTINCT ROUND (SUM (( hight - avg_hight ) * ( pressure - avg_pressure )) over () / SQRT (SUM (POWER (hight - avg_hight, 2)) over () * SUM ( POWER ( pressure - avg_pressure, 2)) over ()), 2) cor FROM (SELECT q.date_time, q.hight, p.pressure, AVG (q.hight) over () avg_hight, AVG (p.pressure) over () avg_pressure FROM quotes q join pressure p ON q.date_time = p.date_time WHERE TRUNC (q.date_time) BETWEEN '01.04.2017' AND '30.09.2017' AND TO_CHAR (q.date_time, 'DY') IN ( 'ПН', 'ПТ' ) AND EXTRACT (hour FROM CAST ( q.date_time AS TIMESTAMP) ) IN ( 14, 15, 16, 17, 18 ))
То же самое можно сделать с помощью встроенной функции CORR.
И, последний пример – преобразовать тиковые данные (таблица ticks) в минутные OHLC бары:
SELECT DISTINCT TRUNC (date_time, 'MI') mi_date_time, FIRST_VALUE (price) over ( PARTITION BY TRUNC (date_time, 'MI') ORDER BY id ASC) OPEN, MAX (price) over ( PARTITION BY TRUNC (date_time, 'MI')) hight, MIN (price) over ( PARTITION BY TRUNC (date_time, 'MI')) low, FIRST_VALUE (price) over ( PARTITION BY TRUNC (date_time, 'MI') ORDER BY id DESC) CLOSE, SUM (vol) over ( PARTITION BY TRUNC (date_time, 'MI')) vol FROM ticks
Сделать подобное на C# было бы труднее. SQL позволяет буквально жонглировать данными и проводить достаточно серьёзные статистические исследования. У современных СУБД есть ряд инструментов, позволяющих существенно повысить производительность. Можно проиндексировать поля, участвующие в условных выражениях; хранить промежуточные рассчитанные данные в отдельной таблице (т.н. materialized views); поделить таблицу на кластеры – архивный/оперативный; использовать встроенные подсказки (hints) компилятору для построения более оптимального плана запроса; использовать встроенные механизмы распараллеливания вычислений и т.п. Всё это, даёт возможность, даже на слабых машинах, позволяет выполнять запросы определённой сложности.
Исследовательская часть очень важна, используя языки манипулирования данными можно сэкономить массу времени и автоматизировать процессы расчетов. Зато тестер удобен при расчете динамики торговли – статистика сделок, показатели торговой системы, графическое представление и п.р.