KonishchevDmitry / investments

Helps you with managing your investments
495 stars 58 forks source link

Пользовательские провайдеры для котировок #77

Closed dim0xff closed 1 year ago

dim0xff commented 1 year ago

Приветствую!

Столкнулся с проблемой, что finnhub отдаёт данные только по US бумагам. Поэтому возникла идея использовать собственный прокси-провайдер для предоставления данных.

Если возможности/времени на добавление провайдера нет, то просьба дать возможность задания урл для провайдера в файле настроек, чтобы заворачивать трафик на свой сервер, который будет отдавать данные в таком-же формате как и исходный провайдер.

https://github.com/KonishchevDmitry/investments/blob/135a1721ef1eb2a7d7974c1733e752c921c32203/src/quotes/finnhub.rs#L22-L26

Или в приложении уже есть решение данного вопроса?

KonishchevDmitry commented 1 year ago

Добрый день! Это вам для IB нужно? А откуда бы вы стали тянуть эти котировки? Котировки с Питерской биржи вам не подойдут? (требуется наличие аккаунта в Тинькофф)

dim0xff commented 1 year ago

Если это имеет значение, то бумаги в IB.

Для примера, https://www.justetf.com/en/etf-profile.html?isin=IE00B4L5Y983 -- в зависимости от биржи там будет разный тикер (на LSE в долларах это IWDA).

Откуда в итоге тянуть котировки -- не так важно. Важно, что в данный момент возможность получения котировок ограничена текущими провайдерами. А так, я смотрю на таблицы Google Docs (через =GOOGLEFINANCE) или Yahoo Finance. При желании можно хоть из статического файла заполненного руками (лично мне не так важна актуальность данных в "прямом эфире").

По поводу котировок из СПБ Биржи через Тинькова, я не очень понял суть вопроса... Если суть была в том, чтобы попробовать поставить токен для брокера-тинькова и должны подтянуться данные, то для примера выше (IWDA на LSE) после заполнения brokers/tinkoff/api_token фокус не удался (подтянулись только курсы валют, золота и серебра):

[23:28:20.503] [tes/mod.rs:262] D: Getting quotes from Tinkoff for the following symbols: USD/RUB...
[23:28:20.503] [tes/mod.rs:262] D: Getting quotes from Finnhub for the following symbols: IWDA...
[23:28:20.503] [/common.rs:074] T: Sending request to https://finnhub.io/api/v1/quote?symbol=IWDA&token=*******...
[23:28:20.589] [off/mod.rs:188] T: Got the following currencies from Tinkoff:
[23:28:20.589] [off/mod.rs:190] T: * Армянский драм (AMDRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Тенге (KZTRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Киргизский сом (KGSRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Узбекский сум (UZSRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Доллар США (USD000UTSTOM)
[23:28:20.589] [off/mod.rs:190] T: * Юань (CNYRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Таджикский сомони (TJSRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Белорусский рубль (BYNRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Гонконгский доллар (HKDRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Золото (GLDRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Турецкая лира (TRYRUB_TOM)
[23:28:20.589] [off/mod.rs:190] T: * Серебро (SLVRUB_TOM)
[23:28:20.589] [off/mod.rs:122] T: Getting quotes for the following symbols from Tinkoff: USD/RUB...
[23:28:21.463] [/common.rs:076] T: Got response from https://finnhub.io/api/v1/quote?symbol=IWDA&token=*******.
[23:28:21.629] [nts/mod.rs:044] E: Unable to find quotes for following symbols: IWDA.

Вообще на finnhub для IWDA с LSE тикер будет IWDA.L

    symbol_remapping:
      IWDA: IWDA.L

Но с тиньковым это ситуацию не поменяло (да и не должно по идее):

[23:37:19.631] [tes/mod.rs:262] D: Getting quotes from Finnhub for the following symbols: IWDA.L...
[23:37:19.631] [tes/mod.rs:262] D: Getting quotes from Tinkoff for the following symbols: USD/RUB...
[23:37:20.366] [/common.rs:074] T: Sending request to https://finnhub.io/api/v1/quote?symbol=IWDA.L&token=*******...
[23:37:19.726] [off/mod.rs:188] T: Got the following currencies from Tinkoff:
[23:37:19.726] [off/mod.rs:190] T: * Армянский драм (AMDRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Тенге (KZTRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Киргизский сом (KGSRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Узбекский сум (UZSRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Доллар США (USD000UTSTOM)
[23:37:19.726] [off/mod.rs:190] T: * Юань (CNYRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Таджикский сомони (TJSRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Белорусский рубль (BYNRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Гонконгский доллар (HKDRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Золото (GLDRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Турецкая лира (TRYRUB_TOM)
[23:37:19.726] [off/mod.rs:190] T: * Серебро (SLVRUB_TOM)
[23:37:19.726] [off/mod.rs:122] T: Getting quotes for the following symbols from Tinkoff: USD/RUB...
[23:37:20.493] [/common.rs:076] T: Got response from https://finnhub.io/api/v1/quote?symbol=IWDA.L&token=*******.
[23:37:20.497] [nts/mod.rs:044] E: Failed to get quotes from Finnhub: Failed to get quotes from https://finnhub.io/api/v1/quote?symbol=IWDA.L&token=*******: Server returned an error: 403 Forbidden.
KonishchevDmitry commented 1 year ago

Да - это имеет значение, т. к. в программе есть некоторое (очень упрощённое) понимание торговых площадок, и для IB'шного портфеля она просто так на Питерскую биржу не пойдет. Но вам бы это и вряд ли помогло, т. к. всяких IWDA на ней нет - разве что только если брать данные с Тиньковской внебиржи (не знаю - возможно для получения котировок нужен Премиум тариф).

Ок, я вас понял - давайте сделаю кастомный провайдер. Я их уже столько сменил, что новый добавляется без особых проблем.

KonishchevDmitry commented 1 year ago

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

dim0xff commented 1 year ago

Спасибо!

Проверил, и работает для analyse. Но (баг?) symbol_remapping для команды show не работает: пытается подтянуть котировки по исходным тикерам

    symbol_remapping:
      IWDA: IWDA.L

    assets:
       ...
      assets:
              - {name: iShares Core MSCI World UCITS ETF USD Acc, symbol: IWDA, weight: 100%}
[16:31:19.752] [tes/mod.rs:290] D: Getting quotes from custom quotes provider for the following symbols: IWDA...
[16:31:19.752] [/common.rs:074] T: Sending request to http://172.17.0.1:12345/v1/quotes?symbols=IWDA...
[16:31:19.833] [/common.rs:076] T: Got response from http://172.17.0.1:12345/v1/quotes?symbols=IWDA.
[16:31:19.833] [tes/mod.rs:290] D: Getting quotes from Finnhub for the following symbols: IWDA...
[16:31:19.833] [/common.rs:074] T: Sending request to https://finnhub.io/api/v1/quote?symbol=IWDA&token=******...

Прокси -- https://gist.github.com/dim0xff/7798ffa5d362215ab361bdd47f9f7391

dim0xff commented 1 year ago

Но вам бы это и вряд ли помогло, т. к. всяких IWDA на ней нет - разве что только если брать данные с Тиньковской внебиржи (не знаю - возможно для получения котировок нужен Премиум тариф).

Кстати, глянул на апи тинькова, и IWDA там есть) Что, конечно, не означает, что там есть все интересующие инструменты.

$ curl -X POST -v 'https://sandbox-invest-public-api.tinkoff.ru/rest/tinkoff.public.invest.api.contract.v1.InstrumentsService/EtfBy' \
   -H 'Content-Type: application/json' \
   -H 'Authorization: Bearer ******' \
   --data '{"id_type":"INSTRUMENT_ID_TYPE_TICKER","class_code":"IWDA","id":"IWDA"}'

{
  "instrument": {
    "figi": "BBG000PH9DS6",
    "ticker": "IWDA",
    "classCode": "IWDA",
    "isin": "IE00B4L5Y983",
    "lot": 1,
    "currency": "usd",
    "shortEnabledFlag": false,
    "name": "iShares Core MSCI World UCITS",
    "exchange": "lse",
    "focusType": "equity",
    "countryOfRisk": "",
    "countryOfRiskName": "",
    "sector": "",
    "rebalancingFreq": "",
    "tradingStatus": "SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING",
    "otcFlag": true,
    "buyAvailableFlag": false,
    "sellAvailableFlag": false,
    "apiTradeAvailableFlag": false,
    "uid": "a2328651-1a20-45b6-afb7-29e3ca427df8",
    "realExchange": "REAL_EXCHANGE_OTC",
    "positionUid": "dae2c819-9fb8-4132-8a8f-a395de4b1915",
    "forIisFlag": false,
    "forQualInvestorFlag": true,
    "weekendFlag": false,
    "blockedTcaFlag": false
  }
}
* Connection #0 to host sandbox-invest-public-api.tinkoff.ru left intact

$ curl -X POST -v 'https://sandbox-invest-public-api.tinkoff.ru/rest/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices' \
   -H 'Content-Type: application/json' \
   -H 'Authorization: Bearer ******' \
   --data '{"instrumentId":["a2328651-1a20-45b6-afb7-29e3ca427df8"]}'

{
  "lastPrices": [{
    "figi": "BBG000PH9DS6",
    "price": {
      "units": "79",
      "nano": 880000000
    },
    "time": "2023-04-14T15:14:03Z",
    "instrumentUid": "a2328651-1a20-45b6-afb7-29e3ca427df8"
  }]
}
* Connection #0 to host sandbox-invest-public-api.tinkoff.ru left intact
dim0xff commented 1 year ago

Но (баг?) symbol_remapping для команды show не работает: пытается подтянуть котировки по исходным тикерам

То же самое для rebalance. Вообще может лучше оформить это отдельным issue?

KonishchevDmitry commented 1 year ago

Но (баг?) symbol_remapping для команды show не работает: пытается подтянуть котировки по исходным тикерам

symbol_remapping немного про другое: он нужен в тех случаях, когда в брокерском отчете инструменты имеют странные тикеры (к примеру, устаревший ISI вместо ITOT в Firstrade, или ISIN'ы вместо тикеров для БПИФ в БКС). И тут цель - получить из брокерского отчета "правильный" (общеизвестный) тикер. Ну а в show/rebalance вы их вводите сами в конфиге, и предполагается, что вы ввели уже "правильный".

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

Кстати, глянул на апи тинькова, и IWDA там есть) Что, конечно, не означает, что там есть все интересующие инструменты.

А у вас обычный тариф или премиальный (на котором доступна внебиржа)? В целом наверное да - имеет смысл таскать данные ещё и оттуда. Не делал это потому что:

Пожалуй, да - сделаю стягивание данных с OTC, но воткну его после Finnhub-провайдера, чтобы как раз где есть котировки, стягивались честные, а за случаями вроде IWDA ходили в Тинькофф.

dim0xff commented 1 year ago

А у вас обычный тариф или премиальный (на котором доступна внебиржа)?

Я не думаю, что наличие данных по котировкам связано с тарифом (если нужно, то смогу проверить).

Про symbol_remapping, я понял, что использую его неправильно -- решил этот момент на своей стороне, как вы и описали.

У меня всё работает, и в целом, наверное, задачу можно закрывать. Спасибо за труд!

ЗЫ: если есть куда, я готов закинуть на кофе с десертом.