Маленькое эссе: котировки с сайта ЦБ
Нет предела фантазии трейдера . Оказалось, что даже официальные курсы Центрального банка тоже могут служить источником данных для торговых решений. В одном из заказов мне пришлось их получать.
Как взять эти данные? Не все (совсем не все) брокеры позволяют увидеть их на экране терминала. Котировки общедоступны, мест, где их можно брать, в сети множество. Обновлять данные нужно нечасто, раз в сутки - нагрузка невелика. Идеальным, очевидно, является сайт самого Центрального банка.
Знакомство с ним оставило приятное впечатление. Сайт предоставляет средства для получения в разрезе дат всех котируемых Центробанком курсов, в том числе и курсов валют. Нам требовался основной официальный курс - доллара США.
Поскольку сам робот писался в Амиброкере, получение котировок с сайта (как его маленькую часть) имело смысл написать на его встроенном языке AFL. На других языках все выглядело бы аналогично.
Последовательность действий:
- Посылаем запрос на сайт, содержащий в требуемом формате код валюты, дату начала и конца выборки
- В ответ получаем XML структуру, содержащую нужные нам данные
- Разбираем структуру при помощи XML.DOM или REGEXP
- Размазываем данные в массив
- Рисуем
- Далее рассчитываем на основании полученного массива требуемую логику
Привожу упрощенный вариант на языке AFL:
function Get_CBRF_Rates(Code,Date_From,Date_To)
{ local xmldoc,k;
local result; result = 0;
xmldoc = CreateObject("Msxml.DOMDocument");
xmldoc.async = False;
if (xmldoc.Load("http://www.cbr.ru/scripts/XML_dynamic.asp?date_req1=" + Date_From + "\&date_req2=" + Date_To + "\&VAL_NM_RQ=" + Code) != True)
{ RegExp = CreateObject("VBScript.RegExp");
RegExp.IgnoreCase = False;
RegExp.Global = True;
RegExp.MultiLine = True;
RegExp.Pattern = "<Record Date=\"([0-3]\\d).([0-1]\\d).([1-2]\\d{3})\" Id=\""+Code+"\"><Nominal>([0-9]*)</Nominal><Value>([0-9,]*)</Value></Record>"; Matches = RegExp.Execute(xmldoc.xml);
Count = Matches.Count; for (k = 0 ; k < Count ; k++)
{ Match = Matches.Item(k);
SubMatches = Match.SubMatches;
SubCount = SubMatches.Count; Date_Str = SubMatches.Item(0)+ "." + SubMatches.Item(1) + "." + SubMatches.Item(2);
_Nominal = StrToNum(SubMatches.Item(3));
_Value = StrToNum(StrReplace(SubMatches.Item(4),",",".")); indx = Lookup(BarIndex(),_DT(Date_Str),-1);
if (indx > -1)
result[indx] = _Value / _Nominal;
}
} return(result);
}
Попробуем получить курс доллара с 01 февраля 2001 по 07 мая 2013:
Close = Get_CBRF_Rates("R01235","01\/02\/2001","07\/05\/2013");
Plot(Close,"ЦБ",colorRed,styleHistogram|styleThick);
Что имеем в результате? График официальных курсов , как и планировалось.
Понятно, что запрос к сайту ЦБ есть относительно долгий процесс, который может занимать вплоть до секунды. На каждом тике его вызывать не стоит. Тем более что и никакой необходимости в этом нет - получим те же данные. Вариантов - 2. Или сохранить курсы в статическую переменную и запрашивать обновление курсов на первой итерации скрипта, или сохранить данные в базе амиброкера. Во втором случае на каждой итерации проверяем, есть ли базе нужные котировки и обращаемся к сайту только если их нет или они неполны.
В общем и целом, таким образом можно получать любые регулярные данные, предоставляемые в сети, в том числе и в реальном времени.
См. также