k100
k100 личный блог
04 октября 2017, 12:31

Торговая система своими руками. Часть 7. Лучший тестер – это своя голова.

     Да! Именно так! Разработка собственного тестера или покупка готового не приведёт к успеху, если нет самого главного – идеи. Можно прятаться за кучей графиков или оправдывать себя горой ненужного “профессионально написанного кода”, коллекционировать и применять кстати и не кстати различные термины, знать на зубок тервер и математику. Но нет идеи – нет и денег!

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

     Сделав свой тестер, я стал гонять простые стратегии, и постоянно перебирал кучу параметров: “а что если торговать только по вторникам с 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) компилятору для построения более оптимального плана запроса; использовать встроенные механизмы распараллеливания вычислений и т.п. Всё это, даёт возможность, даже на слабых машинах, позволяет выполнять запросы определённой сложности.

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

0 Комментариев

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн