Как получить котировки из графика QUIK
Как я обещал в «Плане публикаций», в этой статье мы рассмотрим аспекты получения котировок из графика в QUIK. Для начала прочитаем статью на сайте «Фондовые рынки». Также как и Автор той статьи, я придерживаюсь мнения, что QUIK в чистом виде не удобен для получения котировок, и очень надеюсь, что в будущем разработчики QUIK введут в оборот функции прямого получения котировок, как в большинстве программ теханализа, например HIGH (10), которая даст значение именно хая именно 10 бара. Ну а пока таких функций нет в нашем арсенале — пользуемся своими разработками.
Код, размещенный на сайте «Фондовые рынки» я изменил. В первоначальном виде он рисовал таблицу с перечнем OHLC, и исполнял свою функцию, т.к. и был задуман для «показательного выступления». В моем варианте он получил именно рабочую функцию выдавать OHLC именно нужного нам бара по номеру (считаем с конца, начиная с первого). Теперь эти функции можно использовать в любом роботе, которые работает с котировками, получаемыми из графиков. Думаю, что это оценит любой программист, работающий с QPILE. Указав в настраиваемых данных в начале кода INTERVAL равный нужному, и одновременно доступному в QUIK, таймфрейму и CANDLETOFIND равный номеру искомого нами бара, на выходе получим все данные бара! Не забываем указывать инструмент и код класса. Утомил наверное уже описанием — переходим непосредственно к коду:
Код на QPILE доступен только зарегистрированным пользователям.
А теперь домашнее задание
попробуйте добавить в таблицу значение объема найденного бара!
если можно... делай пож. побольше комментариев
ждем новых уроков. на простых понятных примерах
Постараюсь
Совет, смотрите выложенные коды по дате, я каждый момент комментирую с момента публикации, потом похожие участки комментирую выборочно. Будет более понятно.
Классный сайт. Правда вышеописанны алгоритм у меня на QUIK 5.12 не захотел работать пока не добавил этот блок инициализации переменных:
OPEN=0
HIGH=0
LOW=0
CLOSE=0
после PROGRAM
P.S. Вообще занимаюсь программированием, если нужна помощь, давайте сотрудничать.
Может создать библиотеку полезны функций QPILE ? Например:
'Функция записи сообщений в окно сообщений и в лог-файл
FUNC LogMessage (MessageText)
Message (MessageText, 1)
DateTime=GET_DATETIME ()
tDate=SUBSTR (Get_Value (DateTime, «DateTime»), 0, 19)
WRITELN (PathToLogFile, tDate&": "&MessageText)
END FUNC
Нормально Григорий!
Инициализацию переменных нужно было добавить сразу — просмотрел, спасибо изменю код.
Насчет библиотеки функций — хорошая идея, сделаю.
Насчет логов — хотел этому посвятить отдельную статью, чтоб детально рассмотреть.
А что значат выражение &
Евгений Reply:
апреля 20, 2009 at 17:26
Эээээ... Криво вставилось... Поправил.
Всем привет
OHLC — вызывает некоторые сложности
написал функцию расчета DI+, DI-
к сожалению из за регулярного обращения к OHLC все явно начинает подтормаживать
думаю при вычислении ADX комп — сдохнет
вижу следующий выход
создается глобал таблица в которую кидаются все нужные данные по свече — в том числе и данные индикаторов и различные расчетные показатели
колекция — номер бара
вложенный мап — все данные по бару
в конечном итоге вся логика принятия решения строится на этой таблице
при реализации столкнулся с проблемой
вставки в глобальную коллекцию нулевого мапа когда в ней уже есть какой либо объем данных
Женя куда кинуть код и можем ли созвониться для обсуждения
Идея зачот! Насчет создания коллекции из данных по графику. Но насколько это «облегчит» систему пока не берусь судить.
Что касается проблем со вставкой, пишите в разделе контакты свой мыльник и код. я отвечу.
заработало
все собирается — не тормозит
в ближайшее время допишу туда dx+ dx- dx adx
также добавлю пример с индикаторами из графика и выложу
можно будет уже реально строить логику на тех анализе
да так же в этом решении будет возможность анализировать разные таймфрэймы по бумаге
Женя!
ресурс последний месяц живет как-то не активно
звучали предложения сделать его закрытым в части определенных разработок
и выкладывать какие-то базовые наработки уже для тех кто не наполняет
в принципе это хорошая идея
думаю это привлечет людей желающих его развивать а не ждать когда кто-то на него выложит готового робота
Евгений Reply:
июня 3, 2009 at 15:31
Денис, нового не публикую — не хватает рук — работаю на заказ над большим арбитражным проектом. Основная работа + этот проект занимают все время бордствования.
Насчет идеи по закрытому разделу — поддерживаю, если Вам не сложно — напишите правила раздела, и если есть желание предлагаю стать его ведущим и модератором. Напишите мне в «личку» мыльник свой — обсудим.
Евгений помогите найти ошибку.
написал робота который должен показывать стандартную табличку OHLC, но он почему то не считает значения у свечей. хотя проверка в режиме отладки показывает что текущую дату он компанует успешно.
PORTFOLIO_EX OHLC;
DESCRIPTION OHLC;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST ALL_FIRMS;
PROGRAM
YEAR=GET_VALUE (GET_DATETIME (), «YEAR»)
MONTH=GET_VALUE (GET_DATETIME (), «MONTH»)
DAY=GET_VALUE (GET_DATETIME (), «DAY»)
HOUR = GET_VALUE (GET_DATETIME (), «HOUR»)
MIN = GET_VALUE (GET_DATETIME (), «MIN»)
DATA=YEAR&MONTH&DAY+0
TIME=HOUR&MIN+0
CANDLE=GET_CANDLE («SPBFUT»,"RIZ9","«,»1","PRICE",DATA,TIME)
OPEN=GET_VALUE (CANDLE, «OPEN»)+0
HIGH=GET_VALUE (CANDLE, «HIGH»)+0
LOW=GET_VALUE (CANDLE, «LOW»)+0
CLOSE=GET_VALUE (CANDLE, «CLOSE»)+0
OUTPUT=CREATE_MAP ()
OUTPUT=SET_VALUE (OUTPUT,"OPEN",OPEN)
OUTPUT=SET_VALUE (OUTPUT,"HIGH",HIGH)
OUTPUT=SET_VALUE (OUTPUT,"LOW",LOW)
OUTPUT=SET_VALUE (OUTPUT,"CLOSE",CLOSE)
DELETE_ALL_ITEMS ()
ADD_ITEM (1,OUTPUT)
END_PROGRAM
PARAMETER OPEN;
PARAMETER_TITLE OPEN;
PARAMETER_DESCRIPTION OPEN;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER HIGH;
PARAMETER_TITLE HIGH;
PARAMETER_DESCRIPTION HIGH;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER LOW;
PARAMETER_TITLE LOW;
PARAMETER_DESCRIPTION LOW;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER CLOSE;
PARAMETER_TITLE CLOSE;
PARAMETER_DESCRIPTION CLOSE;
PARAMETER_TYPE NUMERIC (10,2);
END
END_PORTFOLIO_EX
pocemon Reply:
ноября 12, 2009 at 22:59
ура) оказывается при расчете свечных данных нахватало секунд.
добавил
SEK=00&0
DATA=YEAR&MONTH&DAY+0
TIME=HOUR&MIN&SEK+0 и все заработало.
Евгений подскажите пожалуйста а почему при переходе с одного интервального значения на другое таблица OHLC обнуляется на 5 секунд.
допустим если у меня минутки то между минутами 5 сек нет данных в таблице, если 5 минутки то между ними нет 5 сек данных в таблице есть только нолики везде.
Евгений, а можно данную функцию улучшить, как-то чтоб она не все бары пробегала, начиная с первого, а начинала с полностью сформированного бара, т.е. 2 го. Это пожелание вызвано тестами на исторических данных , там сигналы поступают от полностью сформированных баров . Спасибо.
Евгений Reply:
декабря 10, 2009 at 20:06
Достаточно поставить CANDLETOFIND=2, или если вам нужно несколько баров начиная со второго — сделайте цикл «два и более»
Мне надо именно данные всех свечек со второй. Цикл 2 и более для CANDLETOFIND тоже выход, но хотелось все изменения сделать внутри этой функции, не вынося из за нее. Возможно ли такое?
Евгений Reply:
декабря 11, 2009 at 19:25
Основа всей это функции — временной запрос к графику, т.е. указываем даты и время нужной нам свечи. Если вы хотите изменить функцию. то начинайте запрашивать данные исключая первую свечку.
Евгений я кажется нашел решение:
CURMIN = (INTERVAL*FLOOR (CURMIN/INTERVAL)) -INTERVAL
Будет ли это то, что мне надо или все-таки придется делать цикл CANDLETOFIND.
Евгений Reply:
декабря 11, 2009 at 19:29
Это будет работать только исключая первую свечку, а потом запрашивая вторую вы получите третью и т.д. По мне проще сделать цикл.
pocemon Reply:
декабря 11, 2009 at 22:47
Я сделал цикл для CANDLETOFIND — 2 и более, но сталкнулся с тем что он считает цикл не на одном прогоне т.е.1 сек (как задано в настройках портфеля)а каждый прогон прибавляет к CANDLETOFIND +1.
Пока не могу понять в чем дело. Сама функция до модификации делала проход по свечкам внутри одного прогона ( 1 сек).
Нужна подсказка: дата меняется а значения всегда 0. За графиком слежу — открыт и масштаб нужный. И еще, если число дней назад 0 то ошибка. Вообще, мне надо получить данные всех минутных свечей «сегодня» начиная по порядку с первой. Как ни мучил GET_CANDLE ничего не выходит — нули.
Может есть смысл пойти в обход этой функции?
Евгений Reply:
декабря 15, 2009 at 19:13
Это единственная функция. Если постоянно нули. значит либо временной запрос неверный, либо код инструмента или код класса неверный. Функция работает прекрасно, но надо ее правильно спросить что вам нужно.
Интересно, а GET_CANDLE_EX работает нормально...
Евгений Reply:
декабря 15, 2009 at 19:14
Это несколько расширенная функция, позволяющая получать данные массивом. Разбирайтесь с GET_CANDLE
Вот так проверяю, где ошибка? Подскажите плиз.
CANDLE = GET_CANDLE («SPBFUT», «SIH0», "", «1», «PRICE», 20091215, 160000)
HIGH = 0 + GET_VALUE (CANDLE, «HIGH»)
LOW = 0 + GET_VALUE (CANDLE, «LOW»)
Евгений Reply:
декабря 15, 2009 at 20:24
Верно.
При таком запросе нули выдает?
Инструмент в список доступных входит? График по нему минутный открыт?
Боюсь что глюк в проге — переставлял винду а квик не менял, только обновлял. Спасибо за подсказки, тяжеловатый для меня купайл.
Может кому пригодится: ошибка была тут SiH0. Поскольку i маленькое, в начале кода надо было добавить:
PORTFOLIO_EX CANDLE_1712_006;
DESCRIPTION CANDLE;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST ALL_FIRMS;
USE_CASE_SENSITIVE_CONSTANTS — вот это
PROGRAM
DELETE_ALL_ITEMS ()
CANDLE = GET_CANDLE («SPBFUT», «SiH0», "«, „1“,»PRICE", «20091216», «150000» )
HIGH = 0 + GET_VALUE (CANDLE, «HIGH»)
LOW = 0 + GET_VALUE (CANDLE, «LOW»)
Евгений, подскажите пожалуйста. Реально ли получить с помощью GET_CANDLE несколько свечей. Мне к примеру нужно 20 последних свечей, а т.к. в GET_CANDLE время указано как текущее то получаются данные последней 1 свечи, а нужно данные 20 последних. Подскажите, если не трудно, как можно поэксперементировать со временем?
Евгений Reply:
января 19, 2010 at 21:12
Привет.
Сделайте цикл от 1 до 20 и в середине цикла используйте общую функцию OHLC из этой статьи. Создайте массив и запишите в него данные по вашим 20 свечкам для последующего использования.
Добрый день, Евгений!
Столкнулся вот с такой проблемой на малоликвидных рынках: к примеру — в вечернюю сессию на фьючерсе РТССтандарт на часовом графике есть пропуски, из-за которых при расчете индикаторов получаем их крайне неточные значения. Ведь когда нет бара функция его пропусает и выдает значение уже следующего бара (а если за рассчитываемый период несколько пропусков, то получаем очень сильный сдвиг по значениям).
Подскажите, пожалуйста, какой тут может быть выход?
Евгений Reply:
апреля 2, 2010 at 20:28
Если нет бара, тонет OHLC, и наверное нет даже времени и даты этого бара... сложный вопрос...
OPEN=GET_VALUE (CANDLE, "OPEN")+0 IF OPEN>0 ' ЕСЛИ ЧТО-ТО НАШЛИ M=M+1 ' СЧИТАЕМ НАЙДЕННЫЕ ДАННЫЕ СЧЕТЧИКОМ IF M=NUMBER ' ЕСЛИ НАШЛИ ИМЕЕНО ТОТ БАР КОТОРЫЙ ИСКАЛИ DATE=TEXTDATA ' ПРИСВАИВАЕМ ПЕРЕМЕННЫМ НАЙДЕННЫЕ ДАННЫЕ TIME=TEXTTIME OPEN=GET_VALUE (CANDLE, "OPEN")+0 HIGH=GET_VALUE (CANDLE, "HIGH")+0 LOW=GET_VALUE (CANDLE, "LOW")+0 CLOSE=GET_VALUE (CANDLE, "CLOSE")+0 I=N ' ЗАКАНЧИВАЕМ ЦИКЛ ELSE т.е. если OPEN не больше нуля (равно нулю) то это потенциально может быть тот самый несуществующий "нулевой" бар в положенном месте. Надо проверить есть ли у этого "нулевого" бара верменные характеристики, для этого нам из массива данных свечи нужно получить время и дату. Для этого нужно уже использовать функцию GET_CANDLE_EX, задавать графику идентификатор и запрашивать у этой свечи ее точное время. Если оно +0 больше нуля то M=M+1 и считаем это баром но с нулевыми значениями. END IFRem Reply:
апреля 3, 2010 at 15:04
Спасибо, Евгений, за подсказку!
Пока юзал Вашу подсказку, натолкнулся на еще один вариант решения данной проблемы (может кому пригодиться):
1. Берем высоколиквидный инструмент, например фьючерс РТС, и получаем с помощью функции значения CLOSE для него.
2. Там же получаем CANDLE и OHLC нужного инструмента.
3. Преобразовываем полученные нулевые значения нашего инструмента. Например, при CLOSE=0 на каком-то баре, приравниваем его к OPEN на предыдущем баре. Если OPEN предыдущего бара равен 0, то приравниваем CLOSE к OPEN на еще раннем баре (если смотреть справа налево).
Евгений Reply:
апреля 3, 2010 at 20:24
Отличное и элегантное решение!
Rem Reply:
апреля 14, 2010 at 13:30
Спасибо, Евгений, ценю Вашу оценку!
Но проблему на малых тайм-фреймах в вечернюю сессию всё же это не решает. Наверно, правильным было бы, если бы функция использовала данные только за период с 10-30 до 18-45 и соответственно пропускала всю вечернюю сессию. Особенно, если фьючерс идет в связке с акцией. Подскажите, пожалуйста, как задать такое условие в функции.
Евгений Reply:
апреля 14, 2010 at 23:01
В графике Квик в свойствах можно настроить период, за который будет показываться график. Поппробуйте настроить только на дневную сессию и экспортнуть из него данные, должно получиться без переписывания кода.
А никого не смущает, что в каждом месяце получается 31 день?
Евгений Reply:
апреля 2, 2010 at 20:58
А почему это должно смущать?
ShvarcGarberg Reply:
апреля 2, 2010 at 23:29
Да, Евгений, щас внимательней просмотрел код, врубился. Спасибо.
ShvarcGarberg Reply:
апреля 3, 2010 at 0:21
Смущал тот момент, что для не существующих дней месяца (иногда это 31 число, а иногда и несколько дней в феврале), а также выходных, цикл проходит все интервалы. Для одного такого дня при минутном графике, мы получаем 24*60 = 1440 пустых интераций. Сопутствующая проблема — сдвиги, о которых написал Rem.
Сложность вопроса я понял.
Второй момент касается времени работы биржи, т.е. 2/3 дня мы просчитываем впустую.
Может это можно учесть так?:
...
IF CURHOUR<10
CURHOUR = 19
CURDAY=CURDAY-1
...
Я конечно могу и ошибаться.
Я не знаю особенностей среды исполнения QUIK,
но возможно так будет быстрее:
DATETIME = GET_DATETIME ()
CURYEAR = GET_VALUE (DATETIME, "YEAR")
CURMONTH = GET_VALUE (DATETIME, "MONTH")
CURDAY = GET_VALUE (DATETIME, "DAY")
CURHOUR = GET_VALUE (DATETIME, "HOUR")
CURMIN = GET_VALUE (DATETIME, "MIN")
Евгений Reply:
апреля 3, 2010 at 20:20
Это все здорово, но на ФОРТС, например, сессия заканчивается в 23.50. так что вот это:
IF CURHOUR<10
CURHOUR = 19
CURDAY=CURDAY-1
уже работать не будет.
От добра добра не ищут, код проверен годами работы на разных площадках. инструментах и т.п.
Здравствуйте Евгений!!!
Не могли бы вы подсказать?? OHLC очень удобная функция, однако у меня возникла такая проблема. Мне для робота нужно грубо говоря 4 значения. (1) Текущая цена и цена 1 интервал назад (закрытия, открытия...не важно) + (2) moving average текущее значение и moving average значение один интервал назад. с помощью OHLC мы можем получить либо 2 мувинга либо 2 цены...а как получить и то и другое в одном роботе??
Заранее спасибо!!!!!
Евгений Reply:
июня 1, 2010 at 20:05
Привет.
1. Текущая цена берется из таблтекпараметров.
2. OHLC (1)
3. moving average — найдите на сайте робота Мувинг. там описано получение его данных
4. Если мувинг простой, то можно вообще его посчитать «в ручную», т.е. задать цикл для функции OHLC, просуммировать CLOSE и поделить на нужный период мувинга.