Торговый робот «Индикатор ATR для QUIK»
Почему в стандартном QUIK нет встроенного индикатора ATR (Average True Range) — тайна покрытая мраком. Хотя разработчики давно обещают его сделать. Но думаю это временно и, наверное, в следующих ближайших версиях он появится. Но нам то работать надо уже сейчас, а не ждать когда он будет встроенным.
Для начала предлагаю освежить в памяти, что же такое ATR? Индикатор Average True Range — «средний истинный диапазон» был разработан Уэллсом Уайлдером, и предназначен для оценки размера предыдущих свечей — оценки волатильности. Изначально автор определил TR — True Range — Истинный диапазон, который определялся как самое большое из трех параметров:
- разница между текущими HIGH и LOW;
- модуль разницы между текущим HIGH и предыдущим CLOSE;
- модуль разницы между текущим LOW и предыдущим CLOSE.
Средний истинный диапазон — ATR- ничто иное как простое среднее из TR за определенный период. Как правило используют периоды ATR от 12 до 14, чем выше его значение тем активнее торговля и больше вероятность резких движений. Считается что это неплохой индикатор для фильтрации флэта.
С теорией разобрались — переходим к практике. Как понятно из формулы расчета ATR, нам необходимо проанализировать OHLC такого количества баров, какой период ATR нам нужен. Для этого можно использовать проверенную функцию OHLC. Перед написанием расчета я поискал в сети и нашел готовую функцию расчета ATR, которая была сделана как раз на основе нашей функции OHLC! Воистину мир круглый! Отдельное спасибо товарищу DIM_TRADER, за разрешение публикации его функции. Автор акцентирует наше внимание на том, что функция выдает результат идентичный встроенному индикатору ATR в WLD (система технического анализа), что нас вполне устраивает:
FUNC FATR_COL (PERIODATR, INTERVAL, CLASSCODELIST, INSTRUMENT)
'***************************************************************************
' DIM-MARCH-2010 (DIM_TRADER.LIVEJOURNAL.COM И TD4LIVE.LIVEJOURNAL.COM)
' ПОСЛЕДНЯЯ КОРРЕКТИРОВКА, 19.03.2010.' УБРАНО ВСЕ ЛИШНЕЕ
'***************************************************************************
' ФУНКЦИЯ ДЛЯ РАСЧЕТА ATR
'
' PERIODATR - ПЕРИОД ATR В БАРАХ
' INTERVAL - ТАЙМ ФРЕЙМ ГРАФИКА
' CLASSCODE, INSTRUMENT - НАЗВАНИЕ ГРАФИКА С КОТОРЫМ РАБОТАЕМ И КОД КЛАССА
'
'***************************************************************************'
CANDLECOUNT=0
HIGH=0
LOW=0
CLOSE=0
RES=0
AVR_RES=0
DAYTOFIND=PERIODATR*50
CANDLETOFIND=PERIODATR
' СОЗДАЕМ ПРОМЕЖУТОЧНЫЕ МАССИВЫ
COL_HIGH=CREATE_COLLECTION()
COL_LOW=CREATE_COLLECTION()
COL_CLOSE=CREATE_COLLECTION()
CURYEAR=GET_VALUE(GET_DATETIME(), "YEAR")
CURMONTH=GET_VALUE(GET_DATETIME(), "MONTH")
CURDAY=GET_VALUE(GET_DATETIME(), "DAY")
CURHOUR = GET_VALUE(GET_DATETIME(), "HOUR")
CURMIN = GET_VALUE(GET_DATETIME(), "MIN")
CURMIN = INTERVAL*FLOOR(CURMIN/INTERVAL) ' ОКРУГЛЯЕМ МИНУТЫ ДО "ИНТЕРВАЛЬНЫХ"
' *** ОТЛАДОЧНАЯ ЗАПИСЬ В ФАЙЛ
'WRITELN ("CANDLE.LOG", CURHOUR& " "&CURMIN & "------------------------------------------------")
'WRITELN ("ATR.LOG", CURHOUR& " "&CURMIN & "------------------------------------------------")
FOR I FROM 1 TO DAYTOFIND ' ПОИСК ПО ТАКОМУ КОЛИЧЕСТВУ СВЕЧЕК ГРАФИКА
' ГОТОВИМ ПЕРЕМЕННЫЕ ДЛЯ ОБРАЩЕНИЯ К СВЕЧКЕ НА ГРАФИКЕ
TEXTDATA=FTEXTDATA(CURYEAR,CURMONTH,CURDAY) &""
TEXTTIME=FTEXTTIME(CURHOUR,CURMIN) & ""
' ЧИТАЕМ СВЕЧКУ С ГРАФИКА
CANDLE=GET_CANDLE(CLASSCODELIST,INSTRUMENT, "", INTERVAL & "", "PRICE", TEXTDATA, TEXTTIME)
OPEN=GET_VALUE (CANDLE, "OPEN")+0
IF (OPEN>0) ' Т.Е. ЕСЛИ СВЕЧКА СУЩЕСТВУЕТ И МЫ НЕ ВЫЛЕЗЛИ ЗА ДИАПАЗОН ТОРГОВ
CANDLECOUNT=CANDLECOUNT+1 ' ВЕДЕМ ПОДСЧЕТ ЭЛЕМЕНТОВ В МАССИВЕ
CLOSE=GET_VALUE (CANDLE, "CLOSE")+0 ' НУЖЕН НА ЭТОМ БАРЕ
HIGH=GET_VALUE (CANDLE, "HIGH")+0 ' НУЖНЫ НА СЛЕДУЮЩЕМ БАРЕ
LOW =GET_VALUE (CANDLE, "LOW")+0 ' НУЖНЫ НА СЛЕДУЮЩЕМ БАРЕ
' СОХРАНИТЬ В 3 МАССИВА ДЛЯ ДАЛЬНЕЙШЕЙ ОБРАБОТКИ
COL_HIGH =INSERT_COLLECTION_ITEM(COL_HIGH,0,0)
COL_HIGH =SET_COLLECTION_ITEM(COL_HIGH,0,HIGH)
COL_LOW =INSERT_COLLECTION_ITEM(COL_LOW,0,0)
COL_LOW =SET_COLLECTION_ITEM(COL_LOW,0,LOW)
COL_CLOSE =INSERT_COLLECTION_ITEM(COL_CLOSE,0,0)
COL_CLOSE =SET_COLLECTION_ITEM(COL_CLOSE,0,CLOSE)
' *** ОТЛАДОЧНАЯ ЗАПИСЬ В ФАЙЛ
' ДАЛЕЕ - ВЕДЕМ ЖУРНАЛ (ДЛЯ ОТЛАДКИ)
' WRITELN ("CANDLE.LOG", "CANDLECOUNT=" & CANDLECOUNT & " COL=" & GET_COLLECTION_COUNT(COL_HIGH) & " DATA=" & TEXTDATA & " TIME=" & TEXTTIME & "H=" & HIGH & "L=" & LOW & "C=" & CLOSE)
END IF
' ОТКАТ НА "ИНТЕРВАЛ" НАЗАД
CURMIN=CURMIN-INTERVAL
IF CURMIN<0
CURMIN=60+CURMIN
CURHOUR=CURHOUR-1
IF CURHOUR<0
CURHOUR=23
CURDAY=CURDAY-1
IF CURDAY<1
CURDAY=31
CURMONTH=CURMONTH-1
IF CURMONTH<1
CURMONTH=12
CURYEAR=CURYEAR-1
IF CURYEAR<0
MESSAGE ("ОШИБКА! ФУНКЦИЯ FATR_COL. ОБНАРУЖЕН КОНЕЦ КОТИРОВОК",1)
END IF
END IF
END IF
END IF
END IF
END FOR
' НАЧИНАЕМ ИСКАТЬ TR И ДЕЛАТЬ MOVING AVERAGE
FOR I FROM 0 TO CANDLECOUNT-3 'ПОЧЕМУ 3: КОГДА ПИСАЛИ МАССИВЫ-НУМЕРОВАЛИ ОТ 1..., ТУТ C НУЛЯ (-1 ЯЧЕЙКА), ВЫКИНУЛИ ТЕКУЩУЮ (-1), ВЫКИНУЛИ ПРЕВУЮ СВЕЧКУ (У НЕЕ НЕТ CLOSE-1)
HIGH =GET_COLLECTION_ITEM (COL_HIGH , I+1) ' СЛЕДУЮЩАЯ ЗАПИСЬ
LOW =GET_COLLECTION_ITEM (COL_LOW , I+1) ' СЛЕДУЮЩАЯ ЗАПИСЬ
CLOSE =GET_COLLECTION_ITEM (COL_CLOSE, I) ' ЭТА ЗАПИСЬ
' ИЩЕМ МАКСИМУМ ИЗ 3-Х ВЕЛИЧИН
IF ABS(HIGH-LOW) > ABS(HIGH-CLOSE)
RES=ABS (HIGH-LOW)
ELSE
RES=ABS(HIGH-CLOSE)
END IF
IF ABS(LOW-CLOSE) > RES
RES=ABS(LOW-CLOSE)
END IF
' ТЕПЕРЬ ДЕЛАЕМ MOVING AVERAGE, СЧИТАЕМ ATR ИЗ TR
IF I=0
AVR_RES=RES 'ВОТ ТУТ - ВАЖНО! ПЕРВЫЙ TR ПРОСТО РАВЕН HIGH-LOW !!! (СОГЛАСНО ПЕРВОИСТОЧНИКУ)
ELSE
AVR_RES=(AVR_RES*(CANDLETOFIND-1)+RES)/CANDLETOFIND
END IF
' *** ОТЛАДОЧНАЯ ЗАПИСЬ В ФАЙЛ
' WRITELN ("ATR.LOG", "I=" & I & " RES=" & RES & " AVR_RES=" & AVR_RES &" H(I)L(I)C(I-1)="&HIGH&" "&LOW&" "&CLOSE)
END FOR
RESULT = AVR_RES
END FUNC
Итак — промежуточный итог: у нас есть функция. Нужно нарисовать ее на графике. Здесь набросаем небольшой план наступления:
- При первом старте нужно просчитать ATR на определенное кол-во баров назад, чтобы не ждать пока прорисуется весь график;
- Новое значение наносим на график только с появлением новой свечи, чтоб не загружать систему;
Как рисовать на графике мы уже знаем — наносим метки с помощью функции ADD_LABEL. Метка — это графический-bmp файлик, с каким-то изображением, который мы помещаем в определенную точку на графике: ось X — время и дата нужной свечи, ось Y — значение ATR. Мы помним, что нанесение меток на существующий график возможно только по идентификатору, поэтому делаем следующее: создаем график цены нужной нам бумаги. Правой кнопкой по нему — добавить индикатор (например Elders Force Index) в новое окно. На вкладке «Дополнительно» в свойствах этого индикатора прописываем идентификатор BASE. чтоб наш робот увидел куда наносить метки. Затем делаем цвет линий этого индикатора таким же как фон. чтоб он нам не мешал. Поле подготовили. Теперь беремся за робота.
Тут все понятно: функция готовая, главная сложность это перебор баров назад для прорисовки предыдущих значений индикатора. Но и тут все просто: делаем цикл, и внутри него вызываем функцию ATR. Единственное нам пришлось чуть ее изменить. чтоб она сама возвращала время и дату свечи для каждого значения ATR. Итак — код:
Код торгового робота на QPILE доступен только зарегистрированным пользователям.
Как мы видим, метка рисуется файликом ATR_GRAPH.BMP, который должен храниться в той же папке что и сам робот. Мой файлик можно скачать тут. А можно нарисовать самостоятельно в Паинте:)
Все готово! Настраиваем и запускаем:

Индикатор ATR для QUIK
Да, чуть не забыл: у меня на 1 мин таймфрейме значение индикатора получилось в диапазоне 110-140, чтоб выглядело все красиво — двойной клик левой кнопкой по нижнему окну графика, и на вкладке «текущее окно диаграммы» в правом поле есть настройки правой оси. Укажите верхнюю и нижнюю границу так, чтоб было удобно читать индикатор. например: я поставил нижнюю границу=100 а верхнюю=250.
Удачи и боооольших профитов!
Файл с меткой должен быть и в папке со скриптом, и в папке квика, иначе после перезапуска квик ее не найдет.
А лучше писать полный путь.
Евгений Reply:
февраля 1, 2011 at 23:11
У меня находит. Скрипт и файл с меткой лежат в одной папке. Но вы правы, от греха можно указывать полный путь.
Camill Reply:
февраля 1, 2011 at 23:44
У квиковцев на форуме на эту тему уже ругались — картинка ищется в текущей папке, которая при запуске будет папкой с quik.exe.
Может быть уже пофиксили в новой версии.
Camill Reply:
февраля 1, 2011 at 23:56
Похоже, что-то они сделали.
У меня не только путь, но и картинка запомнилась — я ее меняю, а квик ту же самую рисует.
DELETE_ALL_LABEL грохает все метки, в том числе в соседнем окне той же диаграмы. Обидно.
Евгений Reply:
февраля 1, 2011 at 23:51
Должен удалять только те, которые имеют отношение к указанному идентификатору. Но удаляет все — напишу разработчикам.
Если вы не видите метки которые рисует робот — проверьте настройки верхней и нижней границы диаграммы: метки либо выше либо ниже. Ориентируйтесь в настройке границ на текущее значение АТР из таблицы робота.
ПОДСКАЖЕТ МОЖЕТ КТО ГДЕ СКАЧАТЬ WLD С РУСИФИКАТОРОМ ?
Евгений Здравствуйте,помогите разобратся с постановкой стоп-заявки по индикатору ATR ,все публикации которые нашел в сети ну очень запутанные,вот пример инструмент RIM1
1.вход вкороткую по цене 184755
2.текущее значение ATR 1810,57
3.PERIODATR=12
в сети пишут что стоп надо устанавливать: цена входа+ATR
STOPPRICE=184755+1810=186565
Евгений Reply:
мая 6, 2011 at 19:00
Ну можно и так. А вообще подобные моменты любят тестирование на исторических данных.
Спасибо ,не понятно было сам механизм выставления стопа,а значения каждый подбирает сам где то надо 3ATR гдето 0,5,
Евгений я набросал код на выстовления адаптивного стопа на основе вашего,но немогу понять как значения ATR получать без дробей или округлять до целого,а то цена стопа не совпадает с шагом цены.
Евгений Reply:
мая 6, 2011 at 21:00
www.hirobot.ru/2009/06/to...a-quik-defender/
Каменты почитайте, там в конце описывались формулы.
Спасибо,НАШЕЛ ПРИМЕР все заработало.
Код торгового робота почему то не отображается
Евгений Reply:
мая 19, 2011 at 19:36
Авторизуйтесь.
Не подскажете, как уменьшить расстояние между метками (изображение или символ) на графике? По умолчанию они далековато друг от друга получаются.
Евгений Reply:
февраля 29, 2012 at 19:23
Привет.
Символ рисуется один на свечу, уменьшите масштаб горизонтальный и символы будут ближе. А вообще в новой версии квика появился родной индикатор АТР
max22 Reply:
февраля 29, 2012 at 20:24
Просто есть скрипт который рисует на графике символы «|» по такой схеме
FUNC VtoCHART (VALUE,VALUE1)
MSG="«
FOR X FROM 1 TO CEIL (VALUE/VALUE1)
MSG=MSG&»|"
END FOR
RESULT=MSG
END FUNC
Раньше они складывались в сплошную линию. А сейчас, то ли обновления quik повлияли, то ли что-то с windows и они теперь как пунктир идут.
max22 Reply:
февраля 29, 2012 at 20:28
на график добавляется примерно так
ChartID=PlotLabelD (i1*scale+0,cur_year, timeadd (TTIME, -mINTERVAL), VtoCHART (mUp+mDn,VolDiv), (mUp-mDn),( mDn) & «x» & ( mUp) &"=" & (mUp-mDn),MaxDelta,0)
Евгений Reply:
февраля 29, 2012 at 20:45
Я так понимаю что бары на график вы выводите через текстовое поле HINT?
max22 Reply:
февраля 29, 2012 at 20:50
видимо да
FUNC PlotLabelD (PRICE,DATE,TIME,TEXT,DELTA,HINT,MAXIDELTA,TYPE)
Евгений Reply:
февраля 29, 2012 at 21:04
Ну тут сказать ничего не могу. Встроенный язык не регламентирует вывод текста на график.
max22 Reply:
марта 1, 2012 at 14:08
Разобрался. Была старая версия шрифта в виндах, там большие отсупы между черточками.
На демо счете работает, а на реальном показывает нули
Евгений Reply:
апреля 15, 2012 at 3:07
У робота нет ограничений, проверяйте правильность указания кода бумаги.
на реальном счете заработало после того как
CLASSCODELIST=GET_VALUE (GET_SECURITY_INFO («„,INSTRUMENT),“CLASS_CODE»)&"«
заменил на
CLASSCODELIST=»SPBFUT"
Евгений Reply:
апреля 15, 2012 at 3:08
Да, кстати, у некоторых брокеров есть разночтения. Почему то функции определения кода класса по коду бумаги выдают непонятно что...