Как торговому роботу получить котировки из графика 2 часть
Мы уже рассматривали код торгового робота, который получает OHLC по номеру свечи из графика. Но в первоначальном варианте этого кода, таймфрейм был ограничен 1 — 60 минутами, т.е. «часовками». Сейчас я переделал код, чтоб можно было получать длительные таймфреймы, в т.ч. «дневки» и «недельки» и даже, не побоюсь этого слова, «месячные»! Отличие — в блоке анализа переменной INTERVAL, и если она отрицательная (в случаях дневок и более) или больше 60 — меняется переменная таймфрейма подстановки в функцию получения данных свечи из графика, а переменная перебора времени та же самая. Функция готовая, ее можно использовать. Т.к. функция очень востребована, выкладываю в свободном доступе.
В QUIK выводи график цены, в виде баров или свечей, выбранного и прописанного в переменной INSTRUMENT в коде робота кода бумаги (код класса определяется автоматически). Значение переменной NUMBER — это номер свечи, OHLC которой нам нужно, а в переменной INTERVAL указываем активный таймфрейм на построенном графике, в соответствии с подсказкой. Вот что получаем:
Здесь показан торговый робот, у которого была задача найти котировки второй свечи на недельном графике. что он и сделал, и вывел в таблицу. Ну и текущее серверное время, до кучи
PORTFOLIO_EX OHLC2;
DESCRIPTION OHLC2;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST ALL_FIRMS;
USE_CASE_SENSITIVE_CONSTANTS;
PROGRAM
' НАСТРОЙКИ ТОЛЬКО ЗДЕСЬ!
INSTRUMENT="RIM0"
NUMBER=2 ' НОМЕР ИСКОМОЙ СВЕЧИ. ТЕКУЩАЯ = 1
INTERVAL=-2 ' ТАЙМФРЕЙМ НА ОТКРЫТОМ ГРАФИКЕ В МИНУТАХ. ВАЖНО!
' ЗНАЧЕНИЯ ПЕРЕМЕННОЙ INTERVAL ДЛЯ ТАЙМФРЕЙМОВ:
' 1 МИНУТА=1
' 2 МИНУТЫ=2
' 3 МИНУТЫ=3
' 4 МИНУТЫ=4
' 5 МИНУТ=5
' 6 МИНУТ=6
' 10 МИНУТ=10
' 15 МИНУТ=15
' 20 МИНУТ=20
' 30 МИНУТ=30
' 60 МИНУТ=60
' 2 ЧАСА=120
' 4 ЧАСА=240
' ДНЕВНОЙ=-1
' НЕДЕЛЬНЫЙ=-2
' МЕСЯЧНЫЙ=-3
' *************
'========= ПЕРЕМЕННЫЕ
CLASSCODE=GET_VALUE(GET_SECURITY_INFO("",INSTRUMENT),"CLASS_CODE") ' АВТОМАТИЧЕСКИ ПОЛУЧАЕМ КОД КЛАССА
OPEN=0 ' ЗАВОДИМ ПЕРЕМЕННЫЕ
HIGH=0
LOW=0
CLOSE=0
'========= ДАТА И ВРЕМЯ СЕРВЕРНОЕ
SERVERTIME=GET_INFO_PARAM("SERVERTIME")
SERVERDATE=GET_INFO_PARAM("TRADEDATE")
TIMESERV=SUBSTR(SERVERTIME,0,2)&SUBSTR(SERVERTIME,3,2)&SUBSTR(SERVERTIME,6,7)
HOUR=SUBSTR(TIMESERV,0,2)+0
MIN=SUBSTR(TIMESERV,2,2)+0
SEC=SUBSTR(TIMESERV,4,2)+0
TIME=TIMESERV+0
DATE=SUBSTR(SERVERDATE,6,4)&SUBSTR(SERVERDATE,3,2)&SUBSTR(SERVERDATE,0,2)
TRID=TIME&DATE
'========= КОНТРОЛЬ СОЕДИНЕНИЯ С СЕРВЕРОМ
IF IS_CONNECTED()<>1
RETURN
END IF
'========= ПОЛУЧАЕМ ДАННЫЕ СВЕЧЕЙ
OHLC(NUMBER) ' ВЫЗОВ ФУНКЦИИ
IF OPEN=0 OR HIGH=0 OR LOW=0 OR CLOSE=0
MESSAGE("НЕПРАВИЛЬНАЯ НАСТРОЙКА РОБОТА ИЛИ ГРАФИКА!",1)
RETURN
END IF
'========= ФУНКЦИИ
' OHLC
FUNC OHLC(NUMBER)
M=0
IF INTERVAL>60 OR INTERVAL<0
INTERVAL2=INTERVAL
INTERVAL=60
ELSE
INTERVAL2=INTERVAL
END IF
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)
N=(50*24) *(FLOOR(60/INTERVAL))
FOR I FROM 1 TO N
TEXTDATA=FTEXTDATA(CURYEAR,CURMONTH,CURDAY) &""
TEXTTIME=FTEXTTIME(CURHOUR,CURMIN) & ""
CANDLE=GET_CANDLE(CLASSCODE,INSTRUMENT, "", INTERVAL2 & "", "PRICE", TEXTDATA, TEXTTIME)
OPEN=GET_VALUE (CANDLE, "OPEN")+0
IF OPEN>0
M=M+1
IF M=NUMBER
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
INTERVAL=INTERVAL2
END IF
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 ("NO DATA",1)
END IF
END IF
END IF
END IF
END IF
END FOR
END FUNC
' ФУНКЦИЯ ПЕРЕВОДА ДАТЫ В ТЕКСТОВЫЙ ФОРМАТ
FUNC FTEXTDATA(YEAR,MONTH,DAY)
IF (LEN(MONTH) < 2)
MONTH = "0" & MONTH
END IF
IF (LEN(DAY) < 2)
DAY = "0" & DAY
END IF
RESULT = YEAR & MONTH & DAY
END FUNC
' ФУНКЦИЯ ПЕРЕВОДА ВРЕМЕНИ В ТЕКСТОВЫЙ ФОРМАТ
FUNC FTEXTTIME(HOUR,MIN,SEC)
IF (LEN(HOUR) < 2)
HOUR = "0" & HOUR
END IF
IF (LEN(MIN) < 2)
MIN = "0" & MIN
END IF
RESULT = HOUR & MIN & "00"
END FUNC
'========= ТАБЛИЦА
OUTPUT=CREATE_MAP()
OUTPUT=SET_VALUE(OUTPUT,"TIME",TIME)
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 TIME;
PARAMETER_TITLE ВРЕМЯ;
PARAMETER_DESCRIPTION ВРЕМЯ;
PARAMETER_TYPE STRING(30);
END
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

Евгений спасибо я месяц с интервалом мучился
Спасибо Евгений за ваш труд! Подскажите, пожалуйста, как надо доработать этот код, чтобы можно было получить котировки из графика по нескольким свечам одновременно (например, 1-я свеча, 3 свеча, 7 свеча). Желательно, чтобы это было задано переменными (например number=1, number=3, number=7)
С уважением, заранее благодарен
Евгений Reply:
мая 2, 2010 at 22:18
Доработки минимальны, в настройках:
NUMBER1=2
NUMBER2=3
NUMBER3=5
NUMBER4=15
и далее, где вызов функции:
OHLC (NUMBER1)
HIGH1=HIGH
...
CLOSE1=CLOSE
OHLC (NUMBER2)
HIGH2=HIGH
...
CLOSE2=CLOSE
OHLC (NUMBER3)
HIGH3=HIGH
...
CLOSE3=CLOSE
OHLC (NUMBER4)
...
В итоге вы имеете (по данному примеру) 4 комплекта переменных OHLC по 4-м свечам.
У меня этот алгоритм ошибаеться. выдает неправильную свечу:
NUMBER=1 ' НОМЕР ИСКОМОЙ СВЕЧИ. ТЕКУЩАЯ = 1
INTERVAL=30 ' ТАЙМФРЕЙМ НА ОТКРЫТОМ ГРАФИКЕ В МИНУТАХ. ВАЖНО!
1 = 3й свече.
Через время стало на второй свече. (При закрытых торгах).
Евгений Reply:
мая 21, 2010 at 19:33
Напишите мне в личку почту свою, попробуем разобраться.
Евгений а можете доработать код так, чтобы можно было задать кол-во свечек которые нужно получить? например получать 200 дневных свечек.
Евгений Reply:
июня 22, 2010 at 9:43
Привет.
Полученные 200 свечей надо выводить в файл?
Hedinos Reply:
июня 22, 2010 at 22:06
Выводить в файл не нужно. Табличка будет выводиться в эксель по DDE.
Евгений Reply:
июня 22, 2010 at 22:22
Ну тогда все просто.
Нужно задать цикл в блоке получения котировок,и перенести блок формирования таблицы в этот же блок.
Затем, обычным способом, настроить экспорт в Эксель.
Если сами не справитесь с задачей — обращайтесь в личку, что-нибудь придумаем.
а объем как еще объем добавить? (((
Евгений Reply:
июля 7, 2010 at 10:26
В блоке «Переменные» объявить переменную VOLUME
В блоке получения котировок по аналогии с OHLC также получить значение объема.
В блоке формирования таблицы по аналогии добавить эту переменную.
И в блоке описания таблицы (в самом низу кода) описать новое поле для этой переменной.
Евгений , подскажи пожалуйста где меняется переменная таймфрейма ?
где и что нужно изменить чтобы данные вытаскивались из 4-х часового таймфрейма
Евгений Reply:
июля 19, 2010 at 20:07
Из кода в с\этой статье вам нужно целиком взять три функции, блок переменных. В переменной INTERVAL указываете какой период вам нужен.
Добрый день, Евгений!
Подскажите, а у Вас нет в проекте сделать точно такую же функцию как OHLC2, только работающую на основе GET_CANDLE_EX?
Эта функция замечательно работает, но у меня получается одновременно получить только значения с графика цены и быстрой скользящей средней.
А вот как с ее помощью получить еще и значение медленной скользящей средней...?
Евгений Reply:
ноября 16, 2010 at 20:21
Привет.
Просто в функцию OHLC2 вместо GET_CANDLE вставьте GET_CANDLE_EX. Основа функции OHLC2 — это правильный перебор дат и поиск нужного по номеру бара значения.
Евгений, приветствую! Благодарю за то, что ты делаешь!
Объясни, пожалуйста смысл этой строчки:
N = (50 * 24) * ( FLOOR (60 / INTERVAL))
Мои соображения следующие... N — это количество итераций (циклов), которые мы планируем пересчитать. FLOOR — это функция округления числа в меньшую сторону до ближайшего целого. FLOOR (60 / INTERVAL) — это количество итераций в течение часа (для интервалов, меньше часовых). А что за таинственные (50 * 24), откуда они взялись и чего они тут делают?
Я адаптирую код под дневные графики. Здесь ты уходишь от интервалов, больше часовых, потому как у тебя перебор баров так спроектирован, по минутам, верно? Выходит, что при определении дневных значений данные все равно вычисляются для каждого часа. Только так как TEXTDATA и TEXTTIME не совпадают с соответствующими значениями свечи, то GET_VALUE (CANDLE, «OPEN») возвращает 0 и итерация не засчитывается. Все я правильно понял? Или чего-то где-то намудрил?
Евгений Reply:
февраля 12, 2011 at 0:48
Привет.
1. В этой строке мы задаем глубину просмотра истории: 50 дней по 24 часа с поправкой на выбранный интервал.
2. Так а зачем адаптировать? В самом начале кода есть памятка по интервалам, задаете в настройках INTERVAL=-1 и получаете дневки.