AmiSite.ruЭтот ресурс посвящен замечательной программе технического анализа - AmiBroker. Советы начинающим пользователям. Индикаторы, Системы, Сканеры и другие коды AFL которые показались мне интересными как написанные мной, так и найденные в сети.
|
Одним из самых важных аспектов языка AFL является то, что он является языком обработки и вычислений массивов (array processing language). Он оперирует с массивами (векторами) данных. Этот способ вычислений очень похож на то, как работают популярные пакеты электронных таблиц (типа Microsoft Excel). Каждый, кто знаком с MS Excel, не должен испытать трудностей с пониманием AFL. Фактически все примеры в этой статье были подготовлены с использованием MS Excel.
Массив это просто список (или строка) значений. В некоторых книжках он может называться вектором. Каждая пронумерованная строка в последующих примерах представляет собой отдельный массив. Для каждого символа Амиброкер сохраняет в своей базе данных 6 массивов. Один для цены открытия, один для цены лоу, один для цены хай, один для цены закрытия и один для объёма (см. строки с номерами 1-5 в таблицах далее по тексту) и один для открытого интереса. К ним можно обратиться в AFL по именам: open, low, high, close, volume, openint или O, L, H, C, V, OI.
Bar | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1 | Open | 1.23 | 1.24 | 1.21 | 1.26 | 1.24 | 1.29 | 1.33 | 1.32 | 1.35 | 1.31 |
Любые другие массивы вычисляются из этих шести массивов с использованием встроенных функций AFL. Эти массивы не хранятся в базе данных, а вычисляются, когда они необходимы.
Каждое индивидуальное значение в массиве имеет ассоциированную с ним дату. Если у вас включена опция показывать подсказки (Preferences -> Miscellaneous Tab - > Price data tool tips), то когда вы перемещаете курсор над свечками дневного графика, появляется небольшой жёлтенький прямоугольник. AFL берёт значения open, low, high, close, volume из соответствующих массивов и показывает их в подсказке.
Давайте рассмотрим, как производится обработка следующего выражения:
Когда AFL вычисляет такой оператор как ( High + Low )/2 он не повторяет этот код для каждого бара. Вместо этого он берёт МАССИВ High и МАССИВ Low и суммирует соответственные элементы массивов за один этап. Другими словами оператор «+» (и другие операторы тоже) выполняется над целыми массивами сразу и производится на скорости исполнения полностью откомпилированного кода, затем результирующий массив (каждый его элемент) делится на 2 также за один раз.
Посмотрим всё это в деталях. Когда движок AFL разбирает выражение ( High + Low )/2 он сначала берёт массивы High (1) и Low (2) и производит (за один откомпилированный шаг) временный массив (3). Затем он создаёт финальный массив (4) деля значение каждого элемента временного массива (3) на два. Этот результат присваивается переменной myVariable
Bar | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1 | High (исходный массив) | 1.24 | 1.27 | 1.25 | 1.29 | 1.25 | 1.29 | 1.35 | 1.35 | 1.37 | 1.29 |
2 | Low (исходный массив) | 1.20 | 1.21 | 1.19 | 1.20 | 1.21 | 1.24 | 1.30 | 1.28 | 1.31 | 1.27 |
3 | High+Low (временный массив создаваемый в процессе вычислений) |
2.44 | 2.48 | 2.44 | 2.49 | 2.46 | 2.53 | 2.65 | 2.63 | 2.68 | 2.46 |
4 | ( High+Low ) /2 (назначается в MyVariable) |
1.22 | 1.24 | 1.22 | 1.245 | 1.23 | 1.265 | 1.325 | 1.315 | 1.34 | 1.23 |
Теперь рассмотрим следующий код:
Этот код генерирует сигнал на покупку когда сегодняшние закрытие происходит выше чем 3-х дневное скользящее среднее и сегодняшний объём превосходит вчерашний. Он также генерирует сигнал на продажу, когда цена хай дня пробьёт 1.30.
Когда в своём коде вам скажем нужно посмотреть не превзошла ли цена закрытия например 3-х дневную простую скользящую среднюю, AFL сначала пробегает по массиву close создавая новый массив который можно условно назвать как MA(close,3) для того символа который анализируется. Каждая ячейка нового массива затем может быть сравнена одна к одной с соответственной ячейкой массива close. В нашем примере таким образом создаётся массив называемый Cond1. Для каждой ячейки, где цена закрытия выше чем значение в соответствующей ячейке MA(close,3), значение элемента в новом массиве 'Cond1' устанавливается в '1'. В противном случае значение в 'Cond1' устанавливается в '0'.
AFL также может заглядывать на заданное число ячеек массива вперёд или назад используя функцию Ref (см. строчку 6 в таблице далее по тексту в которой показан созданный временный массив содержащий значения объёма за предыдущий день)
В строке 9 показан массив Cond2 созданный как результат сравнения значения каждого элемента массива volume с предыдущим ему элементом массива, которое устанавливает в ячейку массива Cond2 значение '1' (истина) или '0' (ложь).
Строка 10 показывает массив 'Buy' создающийся как результат сравнения значений ячеек Cond1 с ячейками массива Cond2. Если элемент массива Cond1 равен '1' и соответствующий ему элемент из массива Cond2 также равен '1', то в ячейку массива 'Buy' устанавливается значение '1'.
Строка 11 показывает массив 'Sell' создаваемый во всех случаях когда значение в ячейке массива close превосходит $1.30.
День | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1 | Open | 1.23 | 1.24 | 1.21 | 1.26 | 1.24 | 1.29 | 1.33 | 1.32 | 1.35 | 1.37 |
2 | High | 1.24 | 1.27 | 1.25 | 1.29 | 1.25 | 1.29 | 1.35 | 1.35 | 1.37 | 1.29 |
3 | Low | 2.44 | 2.48 | 2.44 | 2.49 | 2.46 | 2.53 | 2.65 | 2.63 | 2.68 | 2.46 |
4 | Close | 1.23 | 1.26 | 1.24 | 1.28 | 1.25 | 1.25 | 1.31 | 1.30 | 1.32 | 1.28 |
5 | Volume | 8310 | 3021 | 5325 | 2834 | 1432 | 5666 | 7847 | 555 | 6749 | 3456 |
6 | Ref( Volume, -1 ) (временный массив создаваемый в процессе вычислений) |
Null | 8310 | 3021 | 5325 | 2834 | 1432 | 5666 | 7847 | 555 | 6749 |
7 | MA( Close, 3 ) (временный массив создаваемый в процессе вычислений) |
Null | Null | 1.243 | 1.260 | 1.357 | 1.260 | 1.270 | 1.287 | 1.310 | 1.300 |
8 | Cond1 = Close < MA(close, 3) ( 1 (или True) если выражение выполняется в противном случае ноль ) |
Null | Null | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
9 | Cond2 = Volume > Ref(volume, -1) | Null | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
10 | Buy = Cond1 AND Cond2 | Null | Null | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
11 | Sell = High > 1.30 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
Buy и Sell являются специальными массивами чьи результирующие значения могут быть отображены в окне Analyser или в виде красных или зелёных отметок на экране при необходимости.
Приведённые выше примеры очень простые. Здесь будет дано объяснение следующим трём вещам которые по-видимому порождают некоторую путаницу у пользователей:
Как описано в обучающем руководстве по базовым графическим средствам (Tutorial: Basic charting guide), вы можете выбрать и отметить любую котировку на графике и выделить временной интервал графика (From-To range). Бар, отмеченный вертикальной линией, называется “выбранным” баром ("selected" bar), также первый и последний бары интервала называются “начальным” и ”конечным” барами ("begin" and "end" bars). В AFL есть специальные функции, которые позволяют обращаться к значениям массива на выбранном, начальном и конечном баре соответственно. Это функции SelectedValue, BeginValue и EndValue. Также есть ещё одна функция – LastValue, которая позволяет получить значение массива на самом последнем баре графика. Эти четыре функции берут из массива элемент на заданном баре и возвращают ЕДИНСТВЕННОЕ ЧИСЛО представляющее собой значение массива в данной точке. Это позволяет вычислять различную статистику относительно выбранных точек графика. Например:
Когда число, полученное с помощью одной из этих функций, сравнивается с массивом или выполняется какая-либо другая арифметическая операция, в которой участвует число и массив, она осуществляется так, как если бы число распространялось на все элементы массива. Это иллюстрируется в приведённой ниже таблице (строки 2, 6, 7). Зелёным цветом отмечен “начальный” бар, а красным цветом - “конечный” бар. “Выбранный” бар закрашен синим.
День | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1 | Open | 1.23 | 1.24 | 1.21 | 1.26 | 1.24 | 1.29 | 1.33 | 1.32 | 1.35 | 1.37 |
2 | BeginValue( Open ) | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 | 1.24 |
3 | EndValue( Open ) | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 | 1.32 |
4 | SelectedValue( Open ) | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 | 1.21 |
5 | LastValue( Open ) | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 | 1,37 |
6 | Close | 1,22 | 1,26 | 1,23 | 1,28 | 1,25 | 1,25 | 1,31 | 1,30 | 1,32 | 1,28 |
7 | Close <= BeginValue( Open ) | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | result = IIF( Close <= BeginValue( Open ), Close, Open ); | 1,22 | 1,24 | 1,23 | 1,26 | 1,24 | 1,29 | 1,33 | 1,32 | 1,35 | 1,37 |
9 | Period | 2 | 3 | 4 | 2 | 3 | 5 | 2 | 3 | 4 | 2 |
10 | Factor = 2/(Period+1) | 0,667 | 0,500 | 0,400 | 0,667 | 0,500 | 0,333 | 0,667 | 0,500 | 0,600 | 0,667 |
11 | 1 – Factor | 0,333 | 0,500 | 0,600 | 0,333 | 0,500 | 0,667 | 0,333 | 0,500 | 0,600 | 0,333 |
12 | AMA( Close, Factor ) | 0,8125 | 1,0363 | 1,1138 | 1,2234 | 1,2367 | 1,2399 | 1,2853 | 1,2927 | 1,3036 | 1,2866 |
Теперь по функции
Функция
Если вы посмотрите строку 12 этой таблицы, вы можете отметить, что эти значения выглядят как скользящее среднее массива close. Это так и есть. Фактически мы описали, как вычисляется функция AMA экспоненциального скользящего среднего с переменным периодом.
С версией Амиброкера 4.40 появилась возможность организовывать циклы для итерации массивов с помощью операторов for и while и добавлен оператор ветвления if-else. Эти усовершенствования дали возможность работать обоими способами: как с использованием вычислений над массивами (описанными выше) для быстрых и простых расчётов, так и используя циклы для того чтобы делать сложную обработку. Следующий код приведён в качестве примера, как реализовать экспоненциальное скользящее усреднение с переменным периодом (описанное выше) с использованием циклов:
Как вы можете видеть, код получается длиннее, но с другой стороны он очень похож на код любого другого языка программирования как C/Pascal/Basic. Так что пользователи с некоторым опытом в программировании могут легко суметь его понять.
Если вы новичок, я советую изучить сначала программирование вычислений над массивами, прежде чем углубляться в более сложные материи организации циклов.
Если вы испытываете затруднения с программированием на AFL, то сначала можно создать массивы в виде примера в таблице Excel. Если это представляет проблему, обратитесь за помощью к друзьям, особенно если они бухгалтеры. (Только прежде спросите их, не заняты ли они сдачей фондов или квартальной отчетности.)
Когда вы освоитесь и набьёте руку, вы сможете запрограммировать любую систему из книжек по трейдингу или написать свою.
--- Special thanks to Geoff Mulhall for original article in the newsletter that was the basis of this tutorial ---
--- Перевод michaelus ---