invest-openapi
invest-openapi copied to clipboard
Максимальное количество данных в ответе GET /market/candles/
Добрый день.
Например, я хочу получить большой массив данных исторических свечей с высокой гранулярностью. За 1 год и интервалом в час. Получаю ответ 500 типа
HTTP response body: {"trackingId":"9984e02119807c7f","payload":{"message":"[to]: Bad candle interval: from=2019-03-06T16:00:00Z to=2020-03-05T16:00:00Z expected from 1 hour to 7 days","code":"VALIDATION_ERROR"},"status":"Error"}
Указал я интервал 1 час. В ответе говорится expected from 1 hour to 7 days. Но я и так ведь указал 1 час. В чем проблема?
Гранулярность данных слишком высокая, да, но вопрос более в другом. Как определить максимальный объем выборки, которую я могу получить за один запрос? - Чтобы я смог отмерить и получить необходимые мне данные в несколько запросов.
Спасибо.
curl -s https://tinkoffcreditsystems.github.io/invest-openapi/swagger-ui/swagger.yaml | yq -r '.components.schemas.CandleResolution.description'
Интервал свечи и допустимый промежуток запроса:
- 1min [1 minute, 1 day]
- 2min [2 minutes, 1 day]
- 3min [3 minutes, 1 day]
- 5min [5 minutes, 1 day]
- 10min [10 minutes, 1 day]
- 15min [15 minutes, 1 day]
- 30min [30 minutes, 1 day]
- hour [1 hour, 7 days]
- day [1 day, 1 year]
- week [7 days, 2 years]
- month [1 month, 10 years]
curl -s https://tinkoffcreditsystems.github.io/invest-openapi/swagger-ui/swagger.yaml | yq -r '.components.schemas.CandleResolution.description'
Интервал свечи и допустимый промежуток запроса: - 1min [1 minute, 1 day] - 2min [2 minutes, 1 day] - 3min [3 minutes, 1 day] - 5min [5 minutes, 1 day] - 10min [10 minutes, 1 day] - 15min [15 minutes, 1 day] - 30min [30 minutes, 1 day] - hour [1 hour, 7 days] - day [1 day, 1 year] - week [7 days, 2 years] - month [1 month, 10 years]
Я правильно понимаю, что не смогу загрузить минутный график глубиной больше, чем сутки? Что делать, если мне нужны минуты за несколько последних лет?
Это можно сделать слепив 365 запросов :)
Тогда еще очень в тему будет вопрос про rate-limit: 120 запросов в 60 секунд. А как это время распределено? - Значит ли это, что между запросами должно быть не менее 0.5 секунд?
К сути: как организовывать таймауты и повторы? Например, поток выполняет запрос, получает ответ 429 (Too Many Requets) - сколько ему ждать до того как попробовать снова? И инкрементирует ли счетчик запросов rate-limit тот запрос, на который был получен ответ 429?
Лимиты считаются внутри минуты, т.е. если первый запрос был в 10:01:10, то новая минута будет отсчитываться с 10:02:10. Временной промежуток между запросами не нужно соблюдать, т.е. можно все 120 запросов отправить за 1 секунду, просто потом подождать минуту чтобы сбросились лимиты
И инкрементирует ли счетчик запросов rate-limit тот запрос, на который был получен ответ 429?
Нет, но если сильно нагружать сервис, то может сработать защита и ваш IP будет заблокирован для работы с OpenApi на некоторое время
Тогда еще очень в тему будет вопрос про rate-limit: 120 запросов в 60 секунд. А как это время распределено? - Значит ли это, что между запросами должно быть не менее 0.5 секунд?
К сути: как организовывать таймауты и повторы? Например, поток выполняет запрос, получает ответ 429 (Too Many Requets) - сколько ему ждать до того как попробовать снова? И инкрементирует ли счетчик запросов rate-limit тот запрос, на который был получен ответ 429?
Про организацию таймаутов: для тех, кто (как я) пишет на NodeJS+axios есть пакет axios-rate-limit. Уверен, для вашего окружения тоже найдется неплохое готовое решение.
Это можно сделать слепив 365 запросов :)
Попробовал в цикле вызывать Optional<HistoricalCandles> candsHist = ca.createApi().getMarketContext().getMarketCandles(fig, past, now, CandleInterval.ONE_MIN).join(); за последний месяц и, похоже, получаю блок от сервера: Exception in thread "main" java.util.concurrent.CompletionException: java.net.SocketTimeoutException: Connect timed out
Отпускает только примерно через час, на дает с api работать.
@felixrap так и есть, можно упереться в жесткие лимиты, по ним происходит блокировка IP
@felixrap так и есть, можно упереться в жесткие лимиты, по ним происходит блокировка IP
Как тогда можно получить минутный график например за год? Если ли какое-то описание лимитов?
В заголовках ответа я почему-то не смог найти инфу о лимитах, хотя она должна там быть. - На заголовки ответа опираться надежно.
Можно считать число вызовов функции за минуту и если это число стало 120, след. вызов блочить, задерживать до конца минуты.
Можно при получении ответа с кодом 429 брать таймаут, с каждым ответом 429 увеличивая этот таймаут вдвое или втрое (до какого-то лимита, в 60 или 120 секунд, например), потом пробовать снова.
@felixrap запросить 120 дней, подождать минуту, запросить следующие 120 дней
https://tinkoffcreditsystems.github.io/invest-openapi/rest/
@felixrap запросить 120 дней, подождать минуту, запросить следующие 120 дней
https://tinkoffcreditsystems.github.io/invest-openapi/rest/
А если я работаю с 30 бумагами? Это полчаса только чтобы собрать данные. А если бумаг больше, то дополнять по ним данные из стриминга не получится из-за ограничения в 6 потоков - просто не будет успевать оббегать всё.
@felixrap кешируйте данные. В итоге у вас будет всего 30 запросов на 30 бумаг на текущий день
@NikitaMelnikov Возможно баг. На week указано 2 года:
- week [7 days, 2 years]
Но при dateFrom = subYears(new Date(), 2) - выдает 500 ошибку (превышен диапазон). Вероятно из-за високосного года? Если отнимать от текущей даты не годы а дни (~700+), то всё ок.
Свой вопрос переношу сюда.
По спецификации увидел ограничения на получение исторических данных:
Ограничение на временной диапазон (1 день для 1-30 минуток) Ограничение на кол-во запросов в минуту (120)
Если мне изначально нужно получить, например, 40 ликвидных тикеров ММВБ на 15-и минутках, то их получить можно только частями.
Изначально мы не знаем, с какой даты брать тикеры. Обычно, берут с начала эпохи UNIX 01.01.1970. Получается, что для каждого тикера нужно сделать 18000+ запросов. Если в минуту можно посылать не более 120 запросов, то начальное получение исторических данных на каждый тикер будет занимать более 2.5 часов.
Непонятно, как работать скринерами. На акциях США скринер может просматривать тысячи тикеров раз в период. Т.е. ему нужно, например, раз в 15 минут получить 1 новую свечку для 1000 тикеров. Также будет ошибка.
Может, как-то изменить ограничения?
@cia76 исторические данные раньше 2013 года мы не предоставляем, если я правильно помню, поэтому с 1970 смысла нет искать.
Рекомендую на своей стороне просто ставить ограничение на количество запросов и ждать минуту после 120 запросов
Как уже говорил, есть 2 ситуации, когда ограничения становятся узким местом:
- Начальное получение истории
- Массовое получение последнего бара для 120+ тикеров
Минутки Сбербанка с 2013 года. 7.25 года. В каждом годе около 200 торговых дней. Минимум, 12 минут на получение тикера. Если таких тикеров взять 30, то получим более 6-и часов, чтобы получить исходные данные.
На тех же минутках получаем только последний бар для 1000+ тикеров акций США. За минуту мы можем получить только 120 обновлений. Как насчет остальных? Для автоторговли нам нужна последняя минутка по всем тикерам.
Далее мои мысли.
Если ничего в ограничениях не менять, то смысла в разработке и поддержке получения исторических данных нет. Например, Алор в Atentis так и сделали. Берите исторические данные где хотите, но не у нас. Мы не будем заморачиваться с нагрузкой, обработкой и хранением.
Без ограничений все исторические данные подтягиваются в TRANSAQ (Финам) и Квик (все брокеры). Раз другие системы позволяют получать всю историю без ограничений и работают стабильно, то, может, и вы сможете?
Все ограничения API описал здесь: https://chechet.org/355 Провайдер автоторговли для Wealth-Lab Тинькофф Инвестиции уже выдаю трейдерам. Но, не думаю, что с такими ограничениями трейдеры будут переходить от связки с Квиком на вас. Хотя ваша разработка на голову выше того же Квика.
Поддерживаю @cia76. Если получение исторических данных еще можно (и нужно) решить локальным кешированием, то получение текущей цены по >120 тикерам - это уже проблема. Было бы хорошо иметь возможность массового получения текущего OHLCV по многим тикерам. А в идеале весь intraday по определенному набору тикеров. Помимо удобства, это разгрузит ваш апи от большого количества запросов.
@NikitaMelnikov можете ли вы подтвердить, что в качестве альтернативы ежеминутного получения последней цены >120 акций - это подписаться через ws на 100-200-300 тикеров - это нормально и не будет ограничено какими-либо лимитами?
В разработке новые инструменты для скринеров, пока что не могу назвать даты
mvkasatkin
можете ли вы подтвердить, ...
да, в стриминге можно подписываться на неограниченное число инструментов, но лучше распределить общее число по 6 соединениям
@konstunn остались ли у вас какие-то вопросы?
но лучше распределить общее число по 6 соединениям
Можете, пожалуйста, пояснить, чем лучше распределение по 6 соединениям вместо одного?
Я не разработчик API, но могу предположить, что когда ты установишь 6 Websocket соединений, то они с большой вероятностью будут подключены к разным backend серверам и так нагрузка на них будет распределяться более равномерно.
Представь, если ты через один коннект подпишешься на 1000 стоков. Потом приду я и тоже подпишусь на 1000 стоков в одном конннекте. Если оба этих коннекта попадут на один и тот же сервер, то на нём будет нагрузка в 2000 подписок, а на остальные N серверов – нулевая.
Ну и наверняка чем больше подписок в одном коннекте, тем больше может быть задержка между обновлениями. Но это не точно :)
Если оба этих коннекта попадут на один и тот же сервер, то на нём будет нагрузка в 2000 подписок, а на остальные N серверов – нулевая.
Ну наши 2 подключения никак не связаны, это как раз задача балансера раскидать подключения по остальным серверам чтобы не было нулевой нагрузки. Что серверу раскидывать 2 подключения что 12 разницы особо нет. К тому же соединение, даже без трафика, тоже не бесплатное. 12 соединений, дороже чем 2, могу предположить, что лимит в 6 соединений на токен раз из-за этого.
Ну и меня, в целом больше инетересует вопрос с точки зрения пользователя API, инфраструктура, не мое дело.
@cia76 исторические данные раньше 2013 года мы не предоставляем, если я правильно помню, поэтому с 1970 смысла нет искать.
Хотелось бы всё-таки узнать конкретную дату начала котировок. Точно не 2013-й год. Например по тикеру "Т" получил с 2001 г. совпадает с данными яхо финанса.
Через терминал выяснил, что для T дата - сентябрь 1988. В API выдаётся начиная с октября 1988.
IPO AT&T случилось 19-го июля 1984-го года.
На мой взгляд, для инструментов стоит добавить поле - дату начала исторических данных.
На мой взгляд, для инструментов стоит добавить поле - дату начала исторических данных.
Хорошее предложение, рассмотрим
Сейчас для многих бумаг торгующихся на SPB бирже (AAPL, MSFT например) история по минутным свечам ограничена до 2018-01-23. По MSK бирже последний день 2018-07-03, проверял на DSKY. Это баг или фича? Если фича, может быть стоит добавить в документацию?