Joomla 3.1 Templates by FatCow Coupon

SQL и биржевой график (Получение истории котировок с сервиса РБК)

Категория: Блог Опубликовано 24.05.2017

Публикация первая
Получение истории котировок с сервиса РБК


Исходные тексты, архив

Я являюсь специалистом по российскому рынку ценных бумаг (лицензия ЦБ на осуществление дилерской и 
брокерской деятельности)
Самостоятельно занимаюсь инвестированием в российский рынок уже более 5 лет
Интервью со мной на тему инвестирования в российский рынок акций можно почитать например на сайте Николая Степенко интервью с инвестором
Меня всегда интересовало взаимодействие различных сфер знания, симбиоз разных, казалось бы трудно совместимых направлений интеллектуальной деятельности.


В связи с чем 
Я хочу опубликовать серию статей, которые касаются применения инструментов SQL и PL SQL для исследования 
рыночных закономерностей , и поиска статистических преимуществ для потенциального инвестора.
В этой серии статей будут встречаются сугубо экономические , биржевые термины , которые я постараюсь сразу пояснять.

Финансовый рынок предлагает множество инструментов для инвестора , это и долговые инструменты - облигации, это 
фьючерсные контракты с левереджем и ГО , это валюты, опционы , свопы...
чтобы не запутаться в таком многообразии остановимся на акциях российских компаний торгуемых на биржевой площадке ММВБ.

Акция - это долевой финансовый инструмент , своими словами скажу, что акция дает условное право на часть 
активов компании , и на дивидендные выплаты , а так же закрепляет за ее владельцем определённые юридические права. Чем больше у вас акций, тем больше у вас тем большей долей прав вы обладаете. 

Лучшее методическое пособие,на мой взгляд ,по данному финансовому инструменту, это книга "Незнайка на Луне" писателя Носова.


Акция как ценная бумага имеет некоторую стоимость, стоимость акций может довольно часто меняться
потенциальный инвестор может заработать за счет положительного изменения стоимости акций, или же за счет 
дивидендных выплат компании эмитента.

Пример - акция Сбербанка стоила 50 рулей , а через два месяца, после выхода положительной отчетности , она стоит 
уже 100 рублей.

Продав свои акции, за два месяца, потенциальный инвестор зарабатывает 50 рулей или 50% прибыли с каждой 
приобретенной ценной бумаги. то есть инвестор заработал за счет роста стоимости акций.

Второй пример - на акцию Сбербанка выплачивается по 3 рубля дивидендов. Держатель акции зарабатывает по 3 рубля на каждую акцию , и при этом остается держателем ценных бумаг Сбербанка. 

Ликвидность - возможность быстро продать актив без существенной потери в стоимости актива
Допустим вы являетесь владельцем квартиры , и так получилось , что вы захотели ее продать и 
назначили рыночную цену. Дали обьявление, но никто вашу квартиру не покупает, нет покупателя с соответствующей суммой. Так вот эта квартира по сути является неликвидным активом 

Согласитесь, нам как активным инвесторам не очень интересны неликвидные инструменты, по ним и статистику грамотную трудно составить ,а так же их трудно купить или продать за надлежащую цену.

На финансовом рынке ликвидность актива может оцениваться по обьему торгов по данному инструменту.
Объем торгов на финансовом рынке есть количество ценных бумаг которые были проданы в течении определенного 
периода.
Чтобы отобрать наиболее ликвидные инструменты, мы будем ориентироваться на на дневные обьемы.

При оценке обьема торгов так же необходимо учитывать стоимость акции, есть акции дорогие , а есть акции дешевые
Покупка 1000 акций за 1 рубль , не одно и то же что покупка 1000 акций за 10 000 рублей.

Поэтому, при расчете ликвидности, мы будем рукодоствоваться так же и стоимостью актива. 
То есть интерес для нас будут представлять только те акции где денежный объем торгов у которых более 230 000 000 рублей.

Итак перейдем у делу...
В качестве источника биржевой информации воспользоваться сайтом RBC, данный сайт предоставляет удобный сервис импорта данных по торгам и позволяет загружать историю котировок за любой период, а так же обьемы торгов - то что нам нужно.

Предполагается что в нашей базе уже есть пользователь со всеми необходимыми правами
важно чтобы у нашего пользователя были права на пакет utl_http для корректно работы с данными(как это делается посмотрите в разделе документации oracle или в google). У меня это пользователь STOCK.

Для начала создадим необходимые нам таблицы.

это справочник финансовых инструментов TICKERLIST
И таблица с историей цен(котировок) по инструментам из справочника OHLCV

-- Create table TICKERLIST
create table TICKERLIST
(
  ticker       VARCHAR2(5) ,
  v NUMBER,
  pricev NUMBER
);
comment on table TICKERLIST
  is 'Спpавочник инcтрументов';
comment on column TICKERLIST.ticker
  is 'Тикер инструмента';
comment on column TICKERLIST.v
  is 'Объем торгов по данному инструменту на дату загрузки';
comment on column TICKERLIST.pricev
  is 'Объем торгов в денежном выражении на дату загрузки';
-- Create/Recreate indexes 
create unique index TICKERLIST_IDX on TICKERLIST(ticker);

-- ЧТО такое OHLCV ?
-- это просто условное название ценового колебания курса инструмента за заданный день
-- О(Open) - это цена открытия , цена первой секунды торгов
-- H(Hight) - самая максимальная цена за заданный день
-- L(Low) - мимнимум ценового колебания за заднный день
-- С(Close) - закрытие ценовой , цена последней секунды торгов
-- V(Volume) - обьем торгов  

--Создаем таблицу для сохранения истории котировок
create table OHLCV
(
  ticker       VARCHAR2(5) ,
  dateprice    DATE,
  O NUMBER,
  H NUMBER,
  L NUMBER,
  C NUMBER,
  V NUMBER,
  VPRICE NUMBER,
  period VARCHAR2(1) default 'D'
);
comment on table OHLCV
  is 'История котировок';
comment on column OHLCV.ticker
  is 'Тикер инструмента';
comment on column OHLCV.dateprice
  is 'Дата за котиировок';
comment on column OHLCV.o
  is 'Цена открытия';
comment on column OHLCV.h
  is 'Максимальная цена';
comment on column OHLCV.l
  is 'Минимальная цена';
comment on column OHLCV.c
  is 'Цена закрытия';
comment on column OHLCV.v
  is 'Объем торгов по данному инструменту';
comment on column OHLCV.vprice
  is 'Объем торгов в денежном выражении';
-- Create/Recreate indexes 
create unique index OHLC_IDX on ohlcv(ticker, dateprice);


Тикер - кодовое название акции в листинге на бирже.

ЧТО такое OHLCV ?
это просто условное название ценового колебания курса инструмента за заданный период
О(Open) - это цена открытия , цена первой секунды торгов
H(Hight) - самая максимальная цена за заданный период
L(Low) - минимум ценового колебания за заданный период
С(Close) - закрытие ценовой , цена последней секунды торгов
V(Volume) - объем торгов 
создадим пакет для загрузки данных с сервиса РБК

Перед созданием пакета для загрузки данных необходимо выполнить несколько действий связанных со списком контроля доступа

begin
  dbms_network_acl_admin.create_acl('rbc1acl.xml', 'Direct grant',upper( 'STOCK'), true, 'connect');
  dbms_network_acl_admin.assign_acl('rbc1acl.xml', '*.rbc.ru');
  commit;
end;


пакет для загрузки котировок 

create or replace package loader_pkg is
 -- Author  : Члышев Максим Михайлович
  -- Created : 24.09.2014 16:24:41
  -- Purpose : загрузка данных в таблицы TICKERLIST и OHLCV
  
  -- Public constant declarations
  workdate constant date := to_date('14.03.2014','DD.MM.YYYY');
  urlrbc constant varchar2(200) := 'http://export.rbc.ru/free/micex.0/free.fcgi?period=DAILY';
 
 -- насторйки для парсинга используются в get
  n_O constant number := 3; 
  n_H constant number := 4; 
  n_L constant number := 5; 
  n_C constant number := 6; 
  n_V constant number := 7; 
  
 
  -- заполняем справочник фин инструментов данными с сервиса RBC
  --  volumeprice ограниения по обьему , фильтр на загрузку инструментов  
    procedure LoadTickerList(volumeprice number := null);
    
  -- считываем историю по инструментам из справочника , если не указаны datestart , dateend 
  -- тогда дозагружаем недостающие данные   
    procedure LoadOHLCV(datestart date:= null, dateend date:= null);

 -- tc = nO или nH  или nL ,nC, nV в зависимости от того что желаем получить константы пакета 
 -- vc - строка переданная серрвисом RBC
 function get(vc varchar2, tc number) return number;  
end loader_pkg;



тело пакета

create or replace package body loader_pkg is

 -- Function and procedure implementations
 
 -- извлекаем парсим из строки переданной нам сервисом RBC O H L C V
 -- tc = nO или nH  или nL ,nC, nV в зависимости от того что желаем получить константы пакета 
 -- vc - строка переданная серрвисом RBC
 function get(vc varchar2, tc number) return number
 is
 rn number;
 begin
   return to_number(REGEXP_SUBSTR( vc, '[^(;)]+', 1, tc),'99999999999999999999999.99999999');
 exception 
   when others then return 0;  
 end get;

 -- заполняем справочник фин инструментов данными с сервиса RBC
  -- volume , volumeprice ограниения по обьему , фильтр на загрузку инструментов  
procedure LoadTickerList(volumeprice number := null) is
  vreq    utl_http.req;
  vresp   utl_http.resp;
  vc      varchar2(32547);
  vurl    varchar2(32547);
  vv      number;
  vpricev number;
begin
  vurl := urlrbc || '&tickers=NULL' || '&d1=' || to_char(workdate, 'DD') ||
          '&m1=' || to_char(workdate, 'MM') || '&y1=' ||
          to_char(workdate, 'YYYY') || '&d2=' || to_char(workdate+1, 'DD') ||
          '&m2=' || to_char(workdate, 'MM') || '&y2=' ||
          to_char(workdate, 'YYYY') || '&separator=%3B&data_format=BROWSER';
  vreq := utl_http.begin_request(vurl);
  utl_http.set_body_charset(vreq, 'CL8MSWIN1251');
  vresp := utl_http.get_response(vreq);
  loop
    utl_http.read_line(vresp, vc);
    -- получаем v 
    vv := get(vc, n_v);
    -- вычисляем vprice
    vpricev := get(vc, n_o) * vv;
    if vpricev <> 0 then
      if vpricev > volumeprice or volumeprice is null then
        -- если запись соответсвует необходиму условиям вставлем ее в таблицу
        begin
          insert into tickerlist
            (ticker, v, pricev)
          values
            (substr(vc, 1, instr(vc,';')-1), vv, vpricev);
          exception when DUP_VAL_ON_INDEX then null;
        end;
      end if;
    end if;
  end loop;
  utl_http.end_response(vresp);
exception
  when utl_http.end_of_body then
    utl_http.end_response(vresp);
  when others then
    utl_http.end_response(vresp);
    dbms_output.put_line(vc);
    raise;
end LoadTickerList;

 -- считываем историю по инструментам из справочника , если не указаны datestart , dateend 
 -- тогда дозагружаем недостающие данные   
procedure LoadOHLCV(datestart date := null, dateend date := null) is
  vdatestart date;
  vdateend   date;
  vreq       utl_http.req;
  vresp      utl_http.resp;
  vc         varchar2(32547);
  vurl       varchar2(32547);
  vv         number;
  vpricev    number;
begin
  vdateend := dateend;
  if vdateend is null then
    vdateend := sysdate;
  end if;
  for i in (select ticker from tickerlist) loop
    vdatestart := datestart;
    if vdatestart is null then
      select max(ohlcv.dateprice)
        into vdatestart
        from ohlcv
       where ohlcv.ticker = i.ticker;
    end if;
    vurl := urlrbc || '&tickers=' || i.ticker || '&d1=' ||
            to_char(vdatestart, 'DD') || '&m1=' ||
            to_char(vdatestart, 'MM') || '&y1=' ||
            to_char(vdatestart, 'YYYY') || '&d2=' ||
            to_char(vdateend + 1, 'DD') || '&m2=' ||
            to_char(vdateend, 'MM') || '&y2=' || to_char(vdateend, 'YYYY') ||
            '&separator=%3B&data_format=BROWSER';
    vreq := utl_http.begin_request(vurl);
    utl_http.set_body_charset(vreq, 'CL8MSWIN1251');
    vresp := utl_http.get_response(vreq);
    begin
      loop
        utl_http.read_line(vresp, vc);
        -- получаем v 
        vv := get(vc, n_v);
        -- вычисляем vprice
        vpricev := get(vc, n_o) * vv;
        -- dbms_output.put_line(vc||';'||vv||';'||vpricev||';'||get(vc, n_o));
        -- если запись соответсвует необходиму условиям вставлем ее в таблицу
        begin
          insert into ohlcv
            (ticker, dateprice, o, h, l, c, v, vprice)
          values
            (i.ticker,
             to_date(substr(vc, instr(vc, ';') + 1, 10), 'YYYY-MM-DD'),
             get(vc, n_o),
             get(vc, n_h),
             get(vc, n_l),
             get(vc, n_c),
             vv,
             vpricev);
        exception
          when DUP_VAL_ON_INDEX then
            null;
          when others then
            dbms_output.put_line(vc);
        end;
        commit;
      end loop;
      utl_http.end_response(vresp);
    exception
      when utl_http.end_of_body then
        utl_http.end_response(vresp);
      when others then
        utl_http.end_response(vresp);
        raise;
    end;
  end loop;
  dbms_output.put_line(vc);
  exception 
    when others then dbms_output.put_line(SQLCODE);dbms_output.put_line(SQLERRM); 
end LoadOHLCV;

begin
  -- Initialization
  null;
end loader_pkg;



для загрузки котировок с сервиса РБК выполняем следующий скрипт

begin
  -- Call the procedure
  delete tickerlist;
  loader_pkg.loadtickerlist(volumeprice => 230000000);
  commit;
  delete ohlcv;
  loader_pkg.loadohlcv(datestart => to_date('25.04.2009','DD.MM.YYYY'),
                       dateend => null);
end;



В следующих сериях вы узнаете ...
- А зачем нам торговая система?
- Ищем статистические закономерности?
- Волатильность - что за зверь и как его приручить?
- Мани менеджмент и диверсификация
- Совершаем невозможное - создаем прибыльную торговую систему
- Тестируем ТС
- Улучшаем и показатели ТС

Просмотров: 106