Блог им. badpidgin

Исторические данные с ММВБ (мой велосипед)

По мотивам поста https://smart-lab.ru/blog/616708.php

Вот и мой велосипед на питоне для получения котировок с Мосбиржи

from urllib import request, error
from json import loads
import pprint


class GetRawDataException(Exception):
	pass

class GetPricesException(Exception):
	pass

def get_prices(start_date: str, end_date: str, ticker: str) -> dict:
	"""
		Возвращает словарь: {дата:цена закрытия}
	"""
	req = 'https://iss.moex.com/iss/history/engines/stock/markets/shares/boards/TQBR/securities/{}.json?from={}&till={}'.format(ticker, start_date, end_date)
	contents = get_raw_data(req)
	try:
		data = loads(contents)
		prices = {x[1] : x[11] for x in data['history']['data']}
		return(prices)		
	except Exception as err:
		raise GetPricesException(err)


def get_raw_data(req: str) -> str:
	"""
		Возвращает результат запроса к серверу Мосбиржи
	"""
	try:
		contents = request.urlopen(req).read()
		return(contents)
	except URLError as err:
		raise GetRawDataException(err)


try:
	prices = get_prices('2019-05-23', '2019-05-30', 'GAZP')
	pprint.pprint(prices)
except GetRawDataException as err:
	print('Error getting raw data: ', str(err))
except GetPricesException as err:
	print('Error parsing json: ', str(err))

Вывод данных происходит с помощью функции get_prices(). Механизм простой: формируется url для GET-запроса. Мосбиржа в ответ присылает json, из которого забираются нужные данные и выводятся на экран.

Есть и другие способы получения данных: yfinance, pandas-datareader и универсальный BeautifulSoup, ещё более универсальный Selenium. Но это уже совсем другая история...

★5
8 комментариев

Скажите, а зачем???

Тики ИСС не даст, а бары можно (и нужно) выкачивать с сервера своего брокера.

avatar
ch5oh, наткнулся на пост, который в начале указал, вспомнил про свой давний велосипед и решил выложить. Практическая ценность стремится к нулю, это всё ради процесса программирования. Я то вообще трейдингом не занимаюсь
avatar

Чем шире твой диапазон возможностей, чем больше всего разного приходилось пилить, тем больше зевоты вызывают такие штуки. А раньше подобные вещи приводили в восторг)), в смысле когда сам что-то такое смастеришь и оно ещё и работает)).

 

А так полезный код, бери и запускай, кому-то пригодится, наверно.

avatar
Сам писал такой же код, только на основе примера что на сайте мосбиржи выложен. Так там нюансы есть ведь. Например, 1) что за 1 запрос не выдается больше скольких-то там тысяч записей (баров в данном случае), 2) что если пункт 1 поправишь и будешь качать итерациями слишком много данных (скажем, все минутки за 10 лет), то есть таймаут когда соединение обрывается, надо запросы разбивать на несколько частей.
avatar
tranquility, засунуть всё в try...except. Если отвалилось, то пробовать заново. Разбить период на несколько более мелких
avatar
badpidgin, я просто период на три-четыре части разбивал и выкачивал так все без проблем. А высчитывать время таймаута — плохо, я думаю. Биржа так забанить может, мне кажется)) Вот мой код:
github.com/pecec/moex_iss
а вот то же самое, Михаил реализовал, с более подробными комментариями (мне правда, не нравится такой вариант потому что его устанавливать в питон свой нужно, примера использования я что-то не нашел сразу), вероятно, он больше времени потратил на доведение до ума деталей каких-то:
github.com/WLM1ke/apimoex
avatar

пара замечаний, не могу пройти мимо)

1. Зачем urllib, если есть requests?

2. from json import loads — это плохой стиль. когда где-нибудь вызывается loads, то приходится искать откуда он пришел. json.loads(...) — легче воспринимать, нет вопросов что это за функция. в данном маленьком примере в принципе пофиг, но в более массивных кусках кода так лучше не делать.

avatar

day0markets, 

1. Я знаю, что есть

2. А мне так больше нравится. Вызовы короче получаются, особенно в более массивных кусках кода. По мне так хороший стиль.

avatar

теги блога badpidgin

....все тэги



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