Встроенный в торговый терминал QUIK интерпретатор языка QPILE имеет одно несомненное преимущество – прямой и простой доступ ко всей торговой информации.

В остальном же, язык программирования QPILE имеет множество ограничений.

Это и один уровень видимости переменных и ограниченное число функций  и число переменных. При этом в суммарное число переменных входят и мена функций.

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

Указанные ограничения  создают определенную специфику написания программ на QPILE.

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

Язык QPILE , среди современных языков программирования  —  это нечто  подобное ненормативной лексики в русском языке.

Если Вы,  на ненормативной лексике,  будете рассказывать о новом балете в Большом,  то получится не очень литературно.

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

Я расскажу лишь некоторые приемы программирования на QPILE. По мере освоения языка, вы сами сможете развить их множество.

И так , начнем .

Все начинают с функций обработки даты и времени.

При этом рекомендую считать, что в любом месяце 31 день.

Это допущение существенно  упрощает функции  расчета даты, так как если полученной даты не существует, то нет и торгов:

Т е программы получаются проще и никаких проблем не возникает.

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

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

Для справки:

     ОГРАНИЧЕНИЯ QPILE
————————
Ограничение по количеству переменных составляет 1000.Каждый параметр функции задает переменную, которая занимает память в течение одной итерации, данные переменные не отображаются в окне отладчика, количество функций не ограничено.
Если функция не используется — переменные места не занимают и не создаются. Ограничение действует в рамках одного портфеля. Ограничений на размер подключаемых файлов нет.
1. Максимальное количество функций 150.
2. Максимальная глубина рекурсии 25, максимальное количество переменных 1000. Размер кода портфеля не ограничен.
3. Максимальное количество аргументов 8.
4. Максимальная длина строки 2000 символов.
Ограничение длины строковой переменной составляет 600 кбайт, данное ограничение распространяется на коллекции и ассоциативные массивы. Ограничение 2000 символов — это ограничение на длину строки в коде портфеля QPILE, которую считывает интерпретатор.
5. Длина названия переменной ограничена только максимальной длиной строки.

~~~~~~~~~~~~~~~~~~~~~~~~~

Следующий прием программирование роботов на QPILE направлен на ускорение вычислений путем  блокирование расчетов портфеля в периоды формирования очередной свечи.

Работа интерпретатора QPILE организована таким образом, что программа робота циклически исполняется через заданный в параметре “время расчета “  интервал.

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

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

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

Если время расчета робота составляет 10 секунд, то  для тайма 1 час, мы уменьшим загрузку процессора исполнением нашего робота в 360 раз (3600/10), так как расчет будет исполняться лишь в начале новой свечи.

Теперь посмотрим, как это сделать.

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

Для этого, определим переменную , которая будет хранить время последней прочитанной свечи и используем функцию чтения свечи с графика, которому присвоим идентификатор “GRAF”.

Алгоритм наших действий сведется к следующему.

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

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

NEW_GLOBAL(T_LAST,0)  ‘время последней свечи на графике

~~~~~~~~~~~~~~

x=GET_TRADE_DATE ()                                                                ‘дата торговой сессии

D= SUBSTR (x,6,4) + SUBSTR (x,3,2) + SUBSTR (x,0,2)     ‘дата в формате YYYYMMDD‘

~~~~~~~~~~~~~~

_4=»TIME»                                        ‘время последней сделки для акции

IF FIND(CLASSCODE,0,»FUT»)  >=0

_4=»CHANGETIME»                       ‘время последней сделки для фьючерса

END IF

T=GET_VALUE(GET_PARAM_EX(CLASSCODE,SECCODE,_4),»param_value»)         ‘время последней сделки

cnd=GET_CANDLE_EX(“GRAF”,D,T)   ‘читаем график с идентификатором  “GRAF”

T=Get_Value (cnd,»TIME»)              ‘читаем время свечи на графике

if cnd !=»» AND T-T_Last!=0

T_Last=T

…..

‘ здесь размещаем операторы программы, которые надо исполнять при появлении новой свечи

…..

END IF

Результаты тестирования робота за период 2007-2011 гг.

График

Синия линия — стратегия «купил и держи»

Таблица
All trades                 Long trades            Short trades
Net Profit %              559.13 %                  326.26 %                  232.87 %
Exposure %              40.65 %                22.09 %                 18.56 %


All trades      1543                  772 (50.03 %)          771 (49.97 %)
Avg. Profit/Loss %        0.36 %              0.42 %                    0.30 %


Winners          605 (39.21 %)       310 (20.09 %)        295 (19.12 %)
Avg. Profit %             2.82 %                  2.89 %                  2.74 %
Max. Consecutive           7                       6                       9
# bars in largest win         13                     13                    83


Losers      938 (60.79 %)        462 (29.94 %)      476 (30.85 %)
Avg. Loss %            -1.22 %              -1.23 %             -1.21 %
Max. Consecutive            11                 10                    17
# bars in largest loss       172               172                   148


Max. trade % drawdown        -38.25 %            -38.25 %                -24.23 %
Max. system % drawdown        -27.82 %       -26.16 %                   -22.13 %
Recovery Factor            9.64               7.22                           3.80
Profit Factor               1.49              1.57                           1.41
Payoff Ratio                2.31              2.34                           2.27
Risk-Reward Ratio           1.95            2.17                           1.17
Ulcer Performance Index      7.11            6.28                           1.98
Sharpe Ratio of trades       1.69             1.73                           1.64

В работе робота не устраивает большая величина просадки внутри тренда до 7% и в целом по году до 10%.
Поэтому дальнейшие исследования и совершенствование алгоритма были направлены на понижение величины просадки.

Введением стоп-лосса на уровне 2.5% для коротких позиций удалось улучшить показатели робота на истории.
Величина просадки уменьшилась до 6% как внутри дня, так и по году.

График

Таблица результатов со стопом:

………………….    All trades            Long trades            Short trades
Net Profit %                 254.55 %                  128.39 %                  126.16 %
Exposure %                   54.55 %                    28.89 %                    25.66 %
Risk Adjusted Return %      311.75 %                  315.75 %                  349.80 %


All trades      386                  193 (50.00 %)          193 (50.00 %)
Avg. Profit/Loss %              0.66 %                    0.67 %                       0.65 %


Winners         187 (48.45 %)         99 (25.65 %)            88 (22.80 %)
Avg. Profit %                    2.18 %             2.08 %                      2.30 %
Max. Consecutive                 13                    13                           6
# bars in largest win            216                   145                          216


Losers          199 (51.55 %)          94 (24.35 %)            105 (27.20 %)
Avg. Loss %                     -0.77 %                 -0.82 %                    -0.73 %
Max. Consecutive                  11                      8                           8
# bars in largest loss           329                     329                         10


Max. trade % drawdown            -6.03 %                  -6.03 %                  -3.87 %
Max. system % drawdown           -6.09 %                   -6.05 %                -5.43 %
Recovery Factor                  26.14                     13.24                    12.33
Profit Factor                     2.66                     2.66                     2.65
Payoff Ratio                      2.83                     2.53                     3.16
Risk-Reward Ratio                13.05                     10.86                     10.83
Ulcer Index                       1.60                     2.18                      2.02
Sharpe Ratio of trades            4.89                     5.35                       4.56