Pull to refresh

Comments 78

Гм, даже больше, я не знал (хотя и не интересовался в общем-то), что в таблицах гугла можно так ловко использовать API. Интересный способ погонять с визуализацией.


Интересно подумать, как выгрузить статистику по стоимости инструмента на каждый день, пусть за последние 10 лет.

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

Попробуйте iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/SBER.json?iss.json=extended&from=2000-01-01
где SBER — тикер акции Сбербанк, TQBR — основной режим торгов. Цена закрытия на дату находится в поле CLOSE. Выборка ограничена 100 элементами, но можно запрашивать несколько раз, меняя from
Стоимость акций умеет импортировать встроенная функция GOOGLEFINANCE (пример: =GOOGLEFINANCE(«SBER»)). Разве что задержка может быть разной.
А вот с облигациями и правда так гораздо удобней. Спасибо за статью.
как получить последние выплаченные дивиденды на акцию

Удивительно, почему-то я не нашёл нигде информацию про запрос /dividends в API мосбиржи, где вы это узнали? У вас есть какой-то более полный справочник? Поделитесь!
Есть ли подобное для истории купонов по облигациям?
Есть ли подобное для истории амортизации облигаций?
Пишу себе инструмент для автоматического расчёта портфеля, не хватает этих данных.
PS. история дивидендов выдаётся не полная по некоторым акциям… По некоторым вообще не выдаётся… Странно. Мосбиржа не располагает информацией о том, что по акции выплачен дивиденд?

Подскажите, а инструмент для автоматического расчёта портфеля — на чем пишете?

А отчет от брокера чем парсите? Вы автоматически его обрабатываете или вручную?

автоматически… Отчёт брокера у quik сбера — это xls или html документ… не сложно парсится.

Как говорится, хочешь сделать что то хорошо — сделай это сам…
Я тоже свою систему писать начал, потому что готовые либо платные, либо не достаточно автоматизированы

Там ещё проблема в том, что даны даты закрытия реестра (registryclosedate), но реальные даты отсечки (последний день торгов до выплаты дивов) нет. В режиме торгов акций T+ это минус 2 рабочих дня, но не всегда это так как оказалось. Например, для НЛМК была выплата дивов с датой закрытия реестра 09.01.2018, а дата отсечки по факту была 04.01.2018 (это видно на графике), хотя 9-2 рабочих дня — это 5 число, и биржа 5 числа работала, но отсечка была 4 числа. И как точно узнать дату отсечки не совсем понятно. Если считать всегда -2 рабочих дня без учёта локальных праздников и без учёта календаря торговых дней биржи, то можно неверно посчитать дивидендную доходность (попасть на дату с ценой после гэпа). Это важно при расчёте портфеля и анализе дивидендов. Они могли бы добавить в API информацию именно о дате отсечки с учётом режима торгов, наверняка она у них есть.


Я тоже нигде не нашел в документации информации об этом endpoint-е в ISS. Возможно, оно экспериментальное или просто забыли добавить в доку.


Смотреть дивиденды можно на сайте www.conomy.ru, например, для НЛМК: https://www.conomy.ru/emitent/nlmk/nlmk-div
Но там тоже есть ошибки с датами отсечки и путаница с датами закрытия реестра (чего-то нет, что-то лишнее)


Там ещё много разного фундаментального анализа есть для российских эмитентов.

Спасибо за ваш комментарий!

На всякий случай выложил в gist своё решение на Python для поиска рабочих дней биржи в стиле pandas.DateOffset:
https://gist.github.com/espdev/135055b78cdad709025061b920578c5b


Работает так:


>>> '2018-01-09' - TradingDay(calendar='XMOS', days=2)
Timestamp('2018-01-04 00:00:00')

Использует этот очень полезный пакет: https://github.com/quantopian/trading_calendars

Для Python к сожалению. Здесь ведь всё на JavaScript написано.

Возможно, для JavaScript тоже есть биржевые календари подобные trading_calendars. Как-то люди же узнают время и даты торговых сессий.


trading_calendars хорош тем, что поддерживает практически все мировые биржи, но к сожалению, дальнейшая судьба проекта неизвестна, стартап quantopian прекратил своё существование.


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

Это хорошее предложение, ведь документация крайне ограничена, а возможностей много. Когда только разбирался что и как — в основном наугад шёл, но сейчас много упорядоченной информации правда не от из официальных источников.

Я так вычисляю даты выплаты купонов:
Беру дату погашения MATDATE в секундах и вычитаю из неё период выплаты купона COUPONPERIOD в секундах. Каждый вычет — это дата выплаты купона. Получается с ошибкой (например если дата на выходные выпала...), но не значительной.


    //Дата погашения
    $date = $bond['MATDATE'];
    $time = strtotime($date);
    //Период выплаты, сек.
    $period = $bond['COUPONPERIOD'] * 3600 * 24;
    //формируем список выплат по облигации от момента первой покупки
    //$coupon_list = Array();
    while ($time > $sd['time']) {
        if ($time < time()) {
            $summa = $bond['COUPONVALUE'] * $cnt * (1 - $nalog / 100);
            $bond['summa'] = ceil($summa * 100) / 100;
            $bond['date'] = date('d.m.y', $time);
        }
        $time -= $period;
    }

Нашёл хороший способ для получения дат, купонов, амортизаций по облигациям.
Пример запроса:
https://iss.moex.com/iss/statistics/engines/stock/markets/bonds/bondization?from=2020-02-01&till=2020-02-20&start=0&limit=100&iss.only=amortizations,coupons
Выдаёт все купоны по всем облигациям между указанными датами

А вот этого я не знал. Спасибо!

Возможно я непроходимо глуп, но не могу понять по moex-овской PDF-ке как посмотреть индикативный курс Доллара США, используемый при расчете долларовых значений индексов через http запрос.
Если я правильно понимаю по валюте инструменты не доступны iss.moex.com/iss/engines/stock/markets/currency
Похоже вы уже нашли ответ. Ещё можно в валютной секции посмотреть.

Или через API Сбербанка:
https://www.sberbank.ru/portalserver/proxy/?pipe=shortCachePipe&url=http://localhost/rates-web/rateService/rate/current%3FregionId%3D77%26currencyCode%3D840%26currencyCode%3D978%26rateCategory%3Dbeznal

Вот, нашел по облигациям.
https://iss.moex.com/iss/securities/RU000A0JXQ85/bondization.json?iss.json=extended&iss.meta=off&iss.only=coupons&lang=ru&limit=unlimited


Вообще в chrome достаточно открыть консоль разработчика и посмотреть откуда сайт тянет запросы. Он сам по json эти данные выкачивает.

Спасибо большое за эту ссылку, может вы знаете где можно увидеть дивиденды по гдр (FIVE например)?

В смысле по бумагам которых нет на Московской бирже?

В смысле по депозитарным распискам, торгуемым на Московской бирже. Если вот сюда http://iss.moex.com/iss/securities/TATN/dividends.json?iss.json=extended вместо татнефти(TATN) вставить пятерочку(FIVE), то ничего не покажет. Где можно посмотреть дивиденды пятёрочки?

Спасибо понятно, значит через moex API нельзя

Я вот ищу такое ПО для учета, которое бы учитывало необходимый заплатить НДФЛ.
Как это учитывать? Особенно если акции покупались в разное время по разным ценам.

Это ведь работа брокера?

Я понимаю, что брокер по итогу года рассчитает налог и возьмет его сам.
Я про другое думаю. Вот я купил акцию по 100 рублей, потом по 120, потом по 130 рублей. Купленные акции складываются в фифо. Продажа акций осуществляется так же из фифо, то есть первыми продаются акции те, что по 100 рублей.
Потом они начинают расти и опускаться, колебания курса.
Я бы хотел продать подороже, а потом откупить их назад подешевле (спекуляция). Проблема в том, что продавая на пике я потом с трудом представляю по какой цене мне разумно откупать акцию назад.
Может так оказаться, что продав на некотором пике и дождавшись снижения, откупая акцию назад я оказываюсь не в выигрыше, а в проигрыше из-за предполагаемого ндфл от первой продажи. Разве не так? Может оказаться, что продав дороже и потом купив чуть дешевле я не получаю ничего кроме проигрыша и уплаты налога. Понятно, что на самом деле расчет и уплата ведется по итогу года, а не по каждой сделке, но тем не менее… Это место у меня в голове не складывается. Опять же такое: акция сильно выросла в цене и я ее продал. Я посчитал какой получится ндфл и пытаюсь рассчитать по какой цене имеет смысл откупать с учетом тех 13% налога, но на такую большую величину акции уже не падают даже при больших колебаниях… Как быть?
Возможно, расмышляя в таком ключе, я действую не верно. Некоторые говорят, что не нужно об этом думать вообще: купил-продал — остался в выигрыше, забудь об этой сделке, думай о следующей. Но вот мне это не дает покоя — как правильно? Мне кажется нужно ПО для учета фифо сделок и расчета ндфл по каждой сделке… Сейчас я пытаюсь это сделать в экселе, но получается не очень…

Понял о чём Вы, но я как долгосрочный инвестор такими вещами не интересовался — лично у меня нет решения.

Долгосрочный инвестор — дело хорошее, но думаю его это тоже касается…
Например, вы ставите стопы на продажу?
Когда акция подросла вы же передвигаете наверное стоп на продажу повыше, так?
И если акция внезапно провалилась и по стопу была автоматически продана, чтобы зафиксировать прибыль и избежать убытков, вы потом хотите ее назад откупить или нет?

Раньше (давно) занимался трейдингом и торговыми системами, но сейчас уже много лет нет. Дело не особо благодарное — время тратится, результат не гарантирован.

Измените PREVADMITTEDQUOTE на другое:


"BOARDID": {"type": "string", "bytes": 12, "max_size": 0},
"SHORTNAME": {"type": "string", "bytes": 30, "max_size": 0},
"PREVPRICE": {"type": "double"},
"LOTSIZE": {"type": "int32"},
"FACEVALUE": {"type": "double"},
"STATUS": {"type": "string", "bytes": 3, "max_size": 0},
"BOARDNAME": {"type": "string", "bytes": 381, "max_size": 0},
"DECIMALS": {"type": "int32"},
"SECNAME": {"type": "string", "bytes": 90, "max_size": 0},
"REMARKS": {"type": "string", "bytes": 24, "max_size": 0},
"MARKETCODE": {"type": "string", "bytes": 12, "max_size": 0},
"INSTRID": {"type": "string", "bytes": 12, "max_size": 0},
"SECTORID": {"type": "string", "bytes": 12, "max_size": 0},
"MINSTEP": {"type": "double"},
"PREVWAPRICE": {"type": "double"},
"FACEUNIT": {"type": "string", "bytes": 12, "max_size": 0},
"PREVDATE": {"type": "date", "bytes": 10, "max_size": 0},
"ISSUESIZE": {"type": "int64"},
"ISIN": {"type": "string", "bytes": 36, "max_size": 0},
"LATNAME": {"type": "string", "bytes": 90, "max_size": 0},
"REGNUMBER": {"type": "string", "bytes": 90, "max_size": 0},
"PREVLEGALCLOSEPRICE": {"type": "double"},
"PREVADMITTEDQUOTE": {"type": "double"},
"CURRENCYID": {"type": "string", "bytes": 12, "max_size": 0},
"SECTYPE": {"type": "string", "bytes": 3, "max_size": 0},
"LISTLEVEL": {"type": "int32"},
"SETTLEDATE": {"type": "date", "bytes": 10, "max_size": 0}```
все доступные поля со значениями можно же увидеть по
iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities.xml?iss.meta=off&iss.only=securities
и тут нет текущей котировки (пусть с 15мин задержкой)

<row SECID="AFKS" BOARDID="TQBR" SHORTNAME="Система ао" PREVPRICE="18.7" LOTSIZE="100" FACEVALUE="0.09" STATUS="A" BOARDNAME="Т+: Акции и ДР - безадрес." DECIMALS="3" SECNAME="АФК "Система" ПАО ао" REMARKS="" MARKETCODE="FNDT" INSTRID="EQIN" SECTORID="EQ-N" MINSTEP="0.001" PREVWAPRICE="18.372" FACEUNIT="SUR" PREVDATE="2020-02-19" ISSUESIZE="9650000000" ISIN="RU000A0DQZE3" LATNAME="AFK Sistema" REGNUMBER="1-05-01669-A" PREVLEGALCLOSEPRICE="18.7" PREVADMITTEDQUOTE="18.7" CURRENCYID="SUR" SECTYPE="1" LISTLEVEL="1" SETTLEDATE="2020-02-25"/>

а только котировка на конец предыдущего торгового дня…

в другом разделе тогда посмотрите — у них достаточно запутанная структура API и текущая цена точно есть

О, спасибо тебе, добрый человек! Не хватает репутации, чтобы поставить + тебе.

Итак, для получения цены BID (лучшая котировка на покупку для оценки портфеля) для тикера, например, из ячейки C3, вместо кривой формулы:

=GOOGLEFINANCE("MCX:" & C3)

которая не работает с привелигированными акциями, ещё и округляет дробные значения (у ФСК, ТГК-1 и др.) до бесполезных значений, используем такую формулу:

=SUBSTITUTE( IMPORTxml("https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities.xml?iss.meta=off&iss.only=marketdata&marketdata.columns=SECID,BID"; "//row[@SECID='" & C3 & "']/@BID") ;".";",")

а в ваших примерах вместо CONCATENATE проще использовать &
И ещё один способ как получить цену последней сделки, напр. для AFKS

=IMPORTXML("https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/AFKS.xml?iss.meta=off&iss.only=marketdata&marketdata.columns=LAST"; "//@LAST")

это вариант для русской локали, а для американской вместо последей ";" ставим ","
тут вместо цены BID лучше использовать LAST. А то в выходные BID пустой, а цена последней сделки всегда непустая
Ещё один способ, это на отедльном листе загрузить все котировки, например, цены последних сделкок:

=IMPORTHTML("http://iss.moex.com/iss/engines/stock/markets/shares/boards/tqbr/securities.html?iss.meta=on&iss.only=marketdata&marketdata.columns=SECID,LAST"; "table";1)

А потом на другом листе с помощью VLOOKUP находить по тикеру соответствующую цену.

И можно добавить макрос, который перезаписывает формулу, чтобы принудительно обновить котировки:

function CopyPaste() {
var spreadsheet = SpreadsheetApp.getActive();
var startsheet = spreadsheet.getActiveSheet();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('TICK'), true);
spreadsheet.getRange('E1').activate();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
Utilities.sleep(1000);
spreadsheet.getCurrentCell().setFormula('=IMPORTHTML("http://iss.moex.com/iss/engines/stock/markets/shares/boards/tqbr/securities.html?iss.meta=on&iss.only=marketdata&marketdata.columns=SECID,LAST"; "table";1)');
spreadsheet.setActiveSheet(startsheet);
spreadsheet.getRange('A16').activate();
};

Не знаете как это провернуть в Excel, и почему все работают в Гугл доках...?

Для Excel надо писать VBA скрипт чтобы было подобное.

Для Excel всё же есть вариант. Например, стоимость еврооблигации RUS-28:


=ФИЛЬТР.XML(ВЕБСЛУЖБА("http://iss.moex.com/iss/engines/stock/markets/bonds/boards/TQOD/securities/XS0088543193/securities.xml");"//document//data//rows//row/@PREVPRICE")

Отсюда: https://journal.tinkoff.ru/investment-report/

Никак не могу понять — как можно например получить последнюю цену акций Сбера?
Подскажите, как можно получить капитализацию компании?
Подскажите, а вы пользуетесь мультипликатором Р/Е и другими? Если да, то как загружаете в свой файл (я так понял вы используете Google Sheets)? Я пытаюсь сейчас отдельно вытянуть из московской биржи капитализацию и чистую прибыль за последние 12 месяцев, но как-то сложно идет)
по американскому рынку прекрасно тянется из гуглдоксов и яху.финанс, а вот как для российского рынка это делать, ума не приложу. Нашел, как с биржи МОЕХ тянуть количество акций в обращении, потом просто перемножаю кол-во акций на их стоимость и получаю капитализацию. А вот с Р/Е осталось вытянуть годовую прибыль за последние 4 квартала. Пока не понял как это делается.

Ссылка из вашего спредшита для некоторых ETF не работает, к сожалению. Например, TSPX (Tinkoff S&P500). Он вроде находится, но никаких данных о ценах нет (rows пустые): https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/TSPX.xml

В тут (эндпоинт на котором основана формула в спредшите) его вообще нет - https://iss.moex.com/iss/engines/stock/markets/shares/boards/TQTF/securities.xml?iss.meta=off&iss.only=securities

В чем может быть дело?

На знаю, где спросить, вдруг здесь помогут :)

Чтобы собрать портфель из ETF, хочу знать их структуру. На каком-нибудь FinEx полно графиков с долями стран, секторов в процентах и т.п. Но как бы это все вытащить пусть не сразу в таблицу, а через несложные скрипты на python?

На MOEX такой детальной инфы по составу фондов не нашел...

Вопрос очень хороший, но Московская биржа таких данных не предоставляет. Нет ни на сайте, ни в API их.

У вас доступ к таблицам-примерам закрыт(

Тоже стукнулся в закрытый доступ - да и сделал в LO Calc в итоге, что хотел. Функции там есть готовые, например:

Название (строка):

=FILTERXML(WEBSERVICE(CONCATENATE("https://iss.moex.com/iss/engines/stock/markets/bonds/boards/";$L5;"/securities.xml?iss.meta=off&iss.only=securities"));CONCATENATE("//row[@SECID=""";$A5;"""]/@SECNAME"))

Величина купона (дробное):

=NUMBERVALUE(FILTERXML(WEBSERVICE(CONCATENATE("https://iss.moex.com/iss/engines/stock/markets/bonds/boards/";$L5;"/securities.xml?iss.meta=off&iss.only=securities"));CONCATENATE("//row[@SECID=""";$A5;"""]/@COUPONVALUE"));".")

A5 = ISIN

L5 = режим торгов (TQCB и прочие)

Sign up to leave a comment.

Articles