Блог им. Svaroggg

Автоматическое получение биржевых котировок в Google Spreadsheet

Приветствую вас, начинающие (и не только) портфелеводы. В прошлый раз (https://smart-lab.ru/blog/492069.php) мы значительно облегчили себе жизнь, частично автоматизировав ввод сделок. Сегодня сделаем еще один небольшой шажок в светлое будущее, научим наш Гугл документ по расписанию забирать актуальные котировки.

Шаг этот будет немного скучный (так как придется немного попрограммировать), но, надеюсь, полезный.

Итак, приступим. Без лишних слов хочу показать Гугл документ, в котором уже реализовано обновление котировок: https://docs.google.com/spreadsheets/d/1vGj_NszrlVt-1sA225RAgkOLEkdiGBmnSa3lTpsWfzI/edit?usp=sharing

Вполне возможно, что вам этого будет достаточно. Если же остались вопросы, то коротенько опишу, что он делает и как работает.

Во-первых, в этом документ есть лист «Портфель», который содержит информацию по вашим ценным бумагам. Для примера я оставил несколько бумаг (акций и облигаций), убрав все лишнее (в том числе и форматирование).

Автоматическое получение биржевых котировок в Google Spreadsheet

Для обновления котировок нужно нажать большую красную кнопку, после чего скрипт запросит у вас (вы должны быть залогинены в Гугл) определенные разрешения (их нужно дать, иначе не работает) и начнет получать данные. По результаты работы выдает такое сообщение:

Автоматическое получение биржевых котировок в Google Spreadsheet

Как же все работает?

Сначала в скрипте (сам скрипт можно скачать по ссылке: my.pcloud.com/publink/show?code=XZG0Q17ZuC1NsO3HKY8PaD2e8cAzXR5Byz47) идет «настроечная часть», где нужно прописать правильный ID листа, УРЛы до данных и т.п.:

var sheet_id = «1vGj_NszrlVt-1sA225RAgkOLEkdiGBmnSa3lTpsWfzI»;
var googleSpreadSheet = SpreadsheetApp.openById(sheet_id);

var micex_xml_stocks_url = «www.micex.ru/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=3&board_group_id=57&start=0&limit=10000&lang=ru»;

//OFZ bonds
var micex_bonds_url_ofz = «www.micex.ru/issrpc/marketdata/stock/bonds/daily/download/micex_stock_bonds.xml?collection_id=7&board_group_id=58&start=0&limit=1000&lang=ru»;

//my tickers settigns
var rangeDefPortfolio = «A8:AC120»;
var myBadTickersGlobal = ['TODO:','EXTRA']; //no real tickers which exist in my Portfolio. I want to ignore them
var myTickersDataGlobal = {}; //Some extra data about my tickers parsed from the Portolio sheet. I need to know number of lots, types, etc...
var myTickersGlobal = collectMyTickersNew();
var limitForWarningGlobal = 4;
var warningsArr = []; //if a price changes — we'll push info about changed ticker into this global array
var allErrors = [];

С помощью функции collectMyTickersNew() собираются данные о ваших ценных бумагах с листа «Портфель». Это нужно, чтобы сохранять информацию только по нужным активам.

Основная функция — stocksAndBondsRealTime(), именно ее нужно запускать, чтобы получить обновленные котировки. Сама она достаточно простая.
Сначала забирает XML данные по указанным в начале адресам, формирует массив в нужном формате, а потом записывает его на лист «XMLStocks».
Все легко и элегантно, в результате на листе XMLStocks появляются нужные нам данные:

Автоматическое получение биржевых котировок в Google Spreadsheet

Для облигаций дополнительно сохраняется информация по купону (дата и размер следующего и т.д.), экспирации, НКД.

Потом эти данные можно использовать для подсчета будущих денежных поступлений (описывал здесь: https://smart-lab.ru/blog/492305.php)

Осталось два небольших действия:

1. На листе «Портфель» в колонку «Рыночная цена» прописываем формулу, которая будет показывать актуальные данные с листа XMLStocks: VLOOKUP($A8,XMLStocks!$A$2:$P$98, 3, FALSE)

2. Добавляем в триггеры проекта регулярное выполнение функции stocksAndBondsRealTime() 

Автоматическое получение биржевых котировок в Google Spreadsheet
Я запускаю эту функцию раз в час, чаще необходимости не вижу. Да и зачем создавать лишнюю нагрузку на сервера Гугла и Биржи?

В дополнение для каждой бумаги в портфеле я добавил две колонки «Цена алерта покупать» и «Цена алерта продавать». Они нужны для оповещения по почте, когда рыночная цена оказывается меньше или больше желаемой. Скрипт, получив все котировки, проверяет целевые цены и формирует массив на отправку. Также у меня есть оповещения (код функций я здесь не привожу, там все несложно, просто сравниваю одну цену с другой), если цена какой-то бумаги изменилась больше, чем на заданную величину (limitForWarningGlobal = 4 в моем случае). Выглядит письмо примерно так:

Автоматическое получение биржевых котировок в Google Spreadsheet

Сначала я думал, что это мне будет полезно, но в реальной жизни оказалось, что я все равно никаких действий не предпринимаю, даже если цена поменялась на эти 4-5 процента. Разве что может быть полезно узнать, что облигации ваши сильно просели. Если у эмитента начались какие-то проблемы, то облигации падают не так быстро, как акции. Можно успеть слить их процентов по 90 от номинала, а не дожидаться падения до 30% и ниже (как у меня было с Татфондбанком)

 

 

 

★53
58 комментариев
Можно пойти дальше и использовать https://datastudio.google.com/gallery


avatar
Гденьги ☭, Подскажите, а что это? Не очень разобрался, как можно использовать…
avatar
=importxml? не, не слышали
=googlefinance? не, не слышали
имхо, если можно формулами, то скрипты избыточны
avatar

Grigoriy Romanenkov, мне скриптами проще, так как это обычный и знакомый JavaScript, а гугл формулы надо отдельно изучать. Можете пример привести, как с помощью importxml получить котировки для SU29011RMFS2, например?

В GoogleFinance много чего не было (облигаций, ETF). Может, изменилось? Они дают актуальные данные по купонам ОФЗ, к примеру?

avatar
Сергей Ветко, могу сходу привести пример с башнефтью преф, например. Он не вытаскивается Google Finance, поэтому на его примере зарюхал importxml.
Обратите внимание, что источник может быть любой. В этом примере — яху финансе, но там нету ОФЗ, я сейчас сходу не нашёл.
=ПОДСТАВИТЬ(ПОДСТАВИТЬ(ИНДЕКС(IMPORTXML(СЦЕПИТЬ(«finance.yahoo.com/quote/BANEP.ME»);"//*[@class='Trsdu(0.3s)']");1;1);",";"");".";",")

То есть, если надо именно ОФЗ, то надо найти сайт где есть котировки — и переписать xml-path в запросе в формуле.
С помощью ПОДСТАВИТЬ исправляем формат (точка -> запятая)
avatar
Grigoriy Romanenkov, спасибо за пример, но мне мой вариант нравится больше:). Да и к тому же зачем искать какой-то сайт (возможно, и не один), когда данные в удобном формате есть у Мосбиржи?
avatar
Сергей Ветко, вот и я о том же — можно в формулу вкорячить сайт мосбиржи, а если на мосбирже нет (очевидно) котировок других бирж — то любой другой сайт. 
avatar
Grigoriy Romanenkov, Можно, конечно и вкорячить. Вот только зачем, если можно написать один красивый(ну, почти), удобный и легко поддерживаемый скрипт:)? А для других бирж действительно можно юзать GoogleFinance, с которого я и начинал когда-то, но данных было слишком мало.
avatar
Интересно! Искал что то похожее когда себе портфель в гугл таблицах создавал. 
В итоге нашел

=GOOGLEFINANCE($A2,«price»)
Где А2 префикс биржи и тикер

И

=GOOGLEFINANCE($A2,«changepct»)
Изменение процентное цены

Этих двух значений вполне хватает для портфеля акций на американском рынке и российском
Обновление происходит автоматически (не знаю точный интервал, но около 1 минуты) 

avatar
Иван Симпл, Да, с GOOGLEFINANCE я тоже начинал, но в нем многого нет (ETF, облигаций, многих привилегированных акций). Ну или я плохо искал. На американский рынок я пока не выходил, поэтому и решил копать в сторону данных от Мосбиржи.
avatar
Сергей Ветко, аналогично, а ещё для просмотра состояния портфеля нужно открывать саму таблицу и невозможно строить график во времени, поэтому я подумал немного в другую сторону и сделал телеграм-бота, который по расписанию обновляет котировки и отправляет сообщение с результатами, может вам тоже понравится misterbuffett.ru
avatar
Артём Курбатов, Интересное решение!
avatar
технический вопрос

не могу запустить скрипт
Как понимаю красная кнопка в режиме редактирования и 
функционал свой не отрабатывает

Открывал готовый файл https://docs.google.com/spreadsheets/d/1vGj_NszrlVt-1sA225RAgkOLEkdiGBmnSa3lTpsWfzI/edit?usp=sharing

Просьба напишите как запустить 
поиском пользовался
остался бубен и форум SL))
Спасибо!
avatar
Алексей Чугреев, и правда, почему-то сломалась кнопка. Поправил, теперь должна работать. Вообще, она должна запускать скрипт «stocksAndBondsRealTime». Если вдруг опять не будет работать — пишите.
avatar
Сергей Ветко, пока нет
возможно у меня не установлены отдельные дополнения.
как можно вызвать триггеры текущего проекта?
avatar
Алексей Чугреев, Хм, да никаких особых дополнений не надо. Нужно просто быть залогиненым в Гугл и дать разрешения, когда попросят (после нажатия на кнопку обычно).
Еще можно попробовать в меню выбрать Tools->Script Editor (не знаю, как это переведно на русский) и запустить функцию stocksAndBondsRealTime
avatar
Сергей Ветко, заработало!!! Сергей спасиб!
остался вопрос, как вызвать меню с периодичностью обновления - 
“Триггеры текущего проекта”

avatar
Алексей Чугреев, Нужно опять же зайти в редактор скриптов (Tools->Script Editor). И в пункте меню Edit будет нужный про триггеры. Ну или на панели есть кнопочка в виде часов.
avatar
Сергей Ветко, Спасибо! Запустил! 
avatar
Сергей Ветко, Спасибо за помощь.
avatar

var micex_xml_stocks_url = 
«www.micex.ru/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=3&board_group_id=57&start=0&limit=10000&lang=ru»;

//OFZ bonds
var micex_bonds_url_ofz = «www.micex.ru/issrpc/marketdata/stock/bonds/daily/download/micex_stock_bonds.xml?collection_id=7&board_group_id=58&start=0&limit=1000&lang=ru»;

А как формируются эти ссылки? Есть чтото вышестоящее со ссылками? Ибо например в акциях нету ETFов, в бондах нету корпоратива, попробовал поподбирать collection_id= другие ключи подставлять типа boardid все безуспешно
avatar
Артем П., Я вот здесь смотрел нужные мне параметры ссылок: http://moex.com/ru/marketdata/#/group=4&collection=3&boardgroup=57&data_type=current&mode=groups&sort=VALTODAY&order=desc
avatar
Здравствуйте Сергей. 
Не могли бы Вы выложить образец своей Таблицы учета облигаций и акций с помощью Google Spreadsheet?
С уважением Сергей.
avatar
Сергей, добрый вечер.

А что конкретно интересует? За основу я этот брал: https://docs.google.com/spreadsheets/d/1IUxJfnRjzpqkNpuKAU83eTqxCOLyWVZmkVTI9galxZ0/edit#gid=1464404184
Но потом под свои нужды доделывал, там много всего специфического…
avatar
Здравствуйте Сергей. 
Интересует шаблон с учетом облигаций на одном листе, акций на другом, а лист портфель суммарно. 
avatar
Сергей, 
На самом деле там практически ничего интересного и нет, я просто ручками скопировал акции на один лист, а облигации — на другой. По облигациям считаю купонный доход накопленный и дату платежа. Данные по купонам подтягиваются автоматически, это видно в моем примере: https://docs.google.com/spreadsheets/d/1vGj_NszrlVt-1sA225RAgkOLEkdiGBmnSa3lTpsWfzI/edit#gid=1805699294

Л
ист «Портфель» практически не менялся.
К сожалению, образец подготовить — достаточно трудозатратное дело, так как нужно вычистить все свои реальные данные.
avatar
Здравствуйте, Сергей!
Спасибо большое за статью и файл.
А можете рассказать как поменять скрипт таким образом, чтобы в ценах разделителем между рублями и копейками была не точка, а запятая?
avatar
Илья, 
думаю, разделитель зависит от настроек конкретного документа. Пункт меню File->Spreadsheet settings...

Но точно я не проверял, так как мне привычнее с точками.

avatar
я пробовал поставить в настройках документа формат российский, для всех ячеек разделитель становится запятая.
но скрипт берёт данные из xml файла с сайта биржи, где разделитель — точки
www.micex.ru/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=3&board_group_id=57&start=0&limit=10000&lang=ru
в результате в формулах получаются ошибки.
а как вы тогда переносите сделки из quik в эксель и потом в из экселя в гугл?
у меня данные из quik в эксель тоже выгружаются с разделителем — запятая.
avatar
Илья, 
У меня в Эксель тоже разделитель — точки. Поэтому никаких проблем нет, везде точки. Очень удобно.
avatar
Илья, в гугле можно воспользоваться функцией SUBSTITUTE, чтобы заменить точки на запятые
avatar
а у меня везде запятые, что тоже было очень удобно :-)
avatar
IMPORTXML(«iss.moex.com/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=3&board_group_id=57&start=0&limit=10000&lang=ru», "//row[@SECID="«SBER»"]/@LAST")

Вставляем в google sheets. Не благодарите




Сергей Кузьмичев, 

Все равно поблагодарю, и правда работает. Хотя, такой вариант уже предлагали выше в комментариях.
А вы проверяли, как это работает на большом количестве эмитентов (пусть будет 30). Обновляется нормально и регулярно?

В любом случае, у меня на получение котировок завязано еще много чего (например, оповещение о резком изменении по какой-то акции или о достижении целевой цены)
Сергей Кузьмичев, что-то у меня не работает :/

Олег Кузьмин, 
Да вроде работает. Я вот в ячейку вставляю: =IMPORTXML(«iss.moex.com/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=3&board_group_id=57&start=0&limit=10000&lang=ru», "//row[@SECID='SBERP']/@LAST")
Надеюсь, ничего лишнего не порежется
Сергей Ветко, не, не работает :(
А вы можете вставить вашу формулу напрямую в спредшит?
docs.google.com/spreadsheets/d/1nZ7d2MNM3fC9eFhNbTT4VP7FllSNkiySn_LaZlYKB3I/edit?usp=sharing
Я посмотрю что не так :/
Олег Кузьмин, Вставил. все сработало.
Сергей Ветко, ага, всё понятно. https отрезалось из ссылки… *рукалицо*
Спасибо! :)
Шикарный пост, шикарные комментарии! Ребята, всем огромное спасибо
avatar
Все сломалось. Московская биржа поменяла ISS.
avatar
Станислав, 

Вполне возможно. Периодически происходят какие-то изменения, бумаги перемещаются из одного списка в другой. Но особых проблем нет, чтобы найти, куда они переместились. И поправить под свои нужды.
avatar
Я тупенький, я их теперь даже найти не могу. (
avatar
Станислав, кого именно не получается найти?
avatar
Да сломались акции
iss.moex.com/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?_id=3&board_group_id=57

При этом облигации работают
avatar

guldan, 

Видимо, и облигациям недолго осталось. По акциям есть такая ссылка: https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities.xml

Но там структура данных поменялась, без переработки скрипта не работает:(

avatar
Все теперь вместо iss.moex.com/issrpc/
iss.moex.com/iss/
Но еще и параметры старые не подходят. :(
avatar
Станислав, 

мда, похоже, что у них все кардинально поменялось. Надо будет править под новые формат данных…
avatar
Заработало все по старым запросам.
avatar

Отличная статья! Сергей, спасибо за готовый скрипт. =)

Чуть-чуть допили его под себя, добавив ссылку на листинг ETF-фондов:

// ETF bonds
var micex_bonds_url_etf = «iss.moex.com/issrpc/marketdata/stock/shares/daily/download/micex_stock_shares.xml?collection_id=151&board_group_id=57&start=0&limit=100000&lang=ru»;



И соответственно в stocksAndBondsRealTime():

allStocksAndBonds = allStocksAndBonds.concat(collectStocksFromXML(micex_bonds_url_etf, 'etf'));


 
Доброго дня! Подскажите, может знаете, как c moex забрать историю курсов валют? Желательно в разрезе open, low, up, close?
Максим Филенко, к сожалению, не знаю. Не интересовался данным вопросом. Найдете даннные — напишите, пожалуйста.
Сергей Ветко, в соседней ветке подсказали решение:
https://iss.moex.com/iss/history/engines/currency/markets/selt/boards/cets/securities/USD000UTSTOM?from=2020-02-15&till=2020-02-25
подскажите пожалуйста если сможете 
low52 и high52 на привелигерованные акции
через importxml полагаю нужно тянуть — найти не могу 
avatar
Дмитрий Шалай, к сожалению, не знаю, не интересовался этими значениями.
avatar
Недавно стала появляться такая ошибка «White spaces are required between publicId and systemId». С чем может быть связана?
avatar

Sergej M, К сожалению, не знаю в чем проблема. Я у себя уже поменял получение данных, теперь получаю их из JSON. Например:
iss.moex.com/iss/engines/stock/markets/bonds/securities/RU000A1008B1/securities.json?iss.meta=off

iss.moex.com/iss/engines/stock/markets/shares/securities/GAZP/securities.json?iss.meta=off

И вот еще хорошая статья: https://m.habr.com/ru/post/486716/


теги блога Сергей Ветко

....все тэги



UPDONW
Новый дизайн