Amibroker: архитектура языка

Язык Amibroker AFL – векторный, именно с этого момента у многих начинается недопонимание. Именно отсюда заявления, что тестер глючит, или стратегия не так как надо считает.

Самое главное, что нужно понять, что все переменные Amibroker – это массивы. Amibroker использует числа float (single precision) в своих расчетах, поэтому результаты расчетов некоторых индикаторов могут отличаться от других программ.

Для примера возьмем встроенные переменные AFL для работы с OHLC, ничего не нужно объявлять дополнительно, чтобы получить данные об инструменте. Список встроенных переменных данных: Open, High, Low, Close, Volume, OI, Aux1, Aux2. Или короткие эквиваленты: O, H, L, C, V. Aux1, Aux2 – это вспомогательные поля в которые можно загрузить разную доп информацию, например из текстовиков.

Простой пример выражения:

MidPx = (H + L) / 2;

Переменные H и L – это массив данные об High и Low текущего инструмента, который выбран на графике или по которому идет бэктест.
Длина всех массивов (переменных) равна числу баров и переменной BarCount.

Теперь разберемся в том, как работает выражение (H + L) / 2, допустим у нас 6 баров, с индексами от 0 до 5. В Amibroker индексация массивов тоже начинается с 0, как в C/C++. Алгоритм проходит все бары, и на каждом баре проводит простейшую математическую операцию.

Простой пример в Excel:

1

Мы можем переписать ту же операцию только через циклы, и она будет работать в Amibroker:

MidPx = 0; //Инициализируем массив, и забиваем его нулями
for( i = 0; i < BarCount; i++ )
{
   MidPx[i] = (H[i] + L[i]) / 2;
}

В точно таком же виде мы бы написали это на C#. Можно для интереса посчитать сколько символов заняло написание этого кода. Код C#-like занял у нас 67 символов, включая “{}[]();\tab\space”, код на векторном диалекте AFL – 20 символов. Эффективность кода с т.з. написания в 3 раза выше (!), и это на простейшей операции, что уж говорить о более сложных. Когда нам нужно будет инициализировать несколько сот таких переменных, в сложном коде – это не редкость, нам придется напечатать несколько сот/тысяч лишних знаков!

Как вы поняли язык Amibroker может работать в 2х режимах: в векторном и “цикловом”. C т.з. циклов и ключевых слов синтаксис Amibroker ничем не отличается от C-like языков. For, while, do-while, switch, if – все это есть.

Логические переменные и условия
В Amibroker все просто 1 – true, 0 – false. Логические переменные – это такие же массивы 0 и 1, длиной BarCount, как и все массивы Amibroker.

Простой пример, логического выражения:

MidPxGt96 = MidPx > 96;

Посмотрим какой результат даст выражение из примера Excel выше и напишем эквивалентную функцию через Excel:

2

Аналогичный код в C-like style:

MidPx = 0; //Инициализируем массив, и забиваем его нулями
MidPxGt96 = 0;
for( i = 0; i < BarCount; i++ )
{
   MidPx[i] = (H[i] + L[i]) / 2;
   if(MidPx[i] > 96)
        MidPxGt96[i] = 1;
    else
        MidPxGt96[i] = 0;
}

Попробуем сделать простейшее условие. Допустим для какого индикатора нам нужно взять Low в случае MidPx <= 96, и High во всех остальных. В Amibroker это делается с помощью функции IIF.

CondHL = IIF(MidPxGt96, H, L);

То же само через Excel:

3

Аналогичный код в C-like style:

MidPx = 0; //Инициализируем массив, и забиваем его нулями
MidPxGt96 = 0;
CondHL = 0;
for( i = 0; i < BarCount; i++ )
{
   MidPx[i] = (H[i] + L[i]) / 2;
   if(MidPx[i] > 96)
        MidPxGt96[i] = 1;
    else
        MidPxGt96[i] = 0;
    
    if(MidPxGt96[i])
        CondHL[i] = H[i];
    else
        CondHL[i] = L[i];
}

Самой распространенной ошибкой новичка является, то что он питается использовать if с массивами, вместо IIF. if – используется в циклах, или для сравнения строковых переменных, или в структурах кода вида if(Action() == actionExploration).

if(MidPxGt96[i]) - OK!
if(MidPxGt96) - FAIL! MidPxGt96 - это массив

Итоговый код
AFL: 3 строчки, 75 знаков

MidPx = (H + L) / 2;
MidPxGt96 = MidPx > 96;
CondHL = IIF(MidPxGt96, H, L);

C-like: 13 строк, 275 знаков

MidPx = 0;
MidPxGt96 = 0;
CondHL = 0;
for( i = 0; i < BarCount; i++ )
{
   MidPx[i] = (H[i] + L[i]) / 2;
   if(MidPx[i] > 96)
        MidPxGt96[i] = 1;
    else
        MidPxGt96[i] = 0;
    
    if(MidPxGt96[i])
        CondHL[i] = H[i];
    else
        CondHL[i] = L[i];
}

Если вам стало интересно и хотите попробовать Amibroker. Обязательно прочтите и проработайтеUnderstanding how AFL works Проработайте с карандашиком, калькулятором и excel! Как только поймете суть векторных вычислений, все пойдет как по маслу.

Оригинал моего поста

Leave a comment