tinkoff-invest-sdk (empty) → 0.1.0.0
raw patch · 24 files changed
+3244/−0 lines, 24 filesdep +asyncdep +basedep +bytestringbuild-type:Customsetup-changed
Dependencies added: async, base, bytestring, concurrent-extra, errors, http2-client, http2-client-grpc, http2-grpc-proto-lens, lens, mtl, proto-lens, proto-lens-runtime, text, unordered-containers
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- proto/google/protobuf/timestamp.proto +147/−0
- proto/invest/common.proto +56/−0
- proto/invest/instruments.proto +908/−0
- proto/invest/marketdata.proto +370/−0
- proto/invest/operations.proto +439/−0
- proto/invest/orders.proto +190/−0
- proto/invest/sandbox.proto +75/−0
- proto/invest/stoporders.proto +95/−0
- proto/invest/users.proto +140/−0
- src/Invest/Client.hs +56/−0
- src/Invest/Client/Errors.hs +13/−0
- src/Invest/Client/Helpers.hs +47/−0
- src/Invest/Service/Instruments.hs +105/−0
- src/Invest/Service/Internal/MarketDataStream.hs +99/−0
- src/Invest/Service/MarketData.hs +29/−0
- src/Invest/Service/MarketDataStream.hs +160/−0
- src/Invest/Service/Operations.hs +37/−0
- src/Invest/Service/Orders.hs +31/−0
- src/Invest/Service/Sandbox.hs +66/−0
- src/Invest/Service/StopOrders.hs +26/−0
- src/Invest/Service/Users.hs +30/−0
- tinkoff-invest-sdk.cabal +103/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2022 Nick Miller++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Data.ProtoLens.Setup+main = defaultMainGeneratingProtos "proto"
+ proto/google/protobuf/timestamp.proto view
@@ -0,0 +1,147 @@+// Protocol Buffers - Google's data interchange format+// Copyright 2008 Google Inc. All rights reserved.+// https://developers.google.com/protocol-buffers/+//+// Redistribution and use in source and binary forms, with or without+// modification, are permitted provided that the following conditions are+// met:+//+// * Redistributions of source code must retain the above copyright+// notice, this list of conditions and the following disclaimer.+// * Redistributions in binary form must reproduce the above+// copyright notice, this list of conditions and the following disclaimer+// in the documentation and/or other materials provided with the+// distribution.+// * Neither the name of Google Inc. nor the names of its+// contributors may be used to endorse or promote products derived from+// this software without specific prior written permission.+//+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++syntax = "proto3";++package google.protobuf;++option csharp_namespace = "Google.Protobuf.WellKnownTypes";+option cc_enable_arenas = true;+option go_package = "google.golang.org/protobuf/types/known/timestamppb";+option java_package = "com.google.protobuf";+option java_outer_classname = "TimestampProto";+option java_multiple_files = true;+option objc_class_prefix = "GPB";++// A Timestamp represents a point in time independent of any time zone or local+// calendar, encoded as a count of seconds and fractions of seconds at+// nanosecond resolution. The count is relative to an epoch at UTC midnight on+// January 1, 1970, in the proleptic Gregorian calendar which extends the+// Gregorian calendar backwards to year one.+//+// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap+// second table is needed for interpretation, using a [24-hour linear+// smear](https://developers.google.com/time/smear).+//+// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By+// restricting to that range, we ensure that we can convert to and from [RFC+// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.+//+// # Examples+//+// Example 1: Compute Timestamp from POSIX `time()`.+//+// Timestamp timestamp;+// timestamp.set_seconds(time(NULL));+// timestamp.set_nanos(0);+//+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.+//+// struct timeval tv;+// gettimeofday(&tv, NULL);+//+// Timestamp timestamp;+// timestamp.set_seconds(tv.tv_sec);+// timestamp.set_nanos(tv.tv_usec * 1000);+//+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.+//+// FILETIME ft;+// GetSystemTimeAsFileTime(&ft);+// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;+//+// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z+// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.+// Timestamp timestamp;+// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));+// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));+//+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.+//+// long millis = System.currentTimeMillis();+//+// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)+// .setNanos((int) ((millis % 1000) * 1000000)).build();+//+//+// Example 5: Compute Timestamp from Java `Instant.now()`.+//+// Instant now = Instant.now();+//+// Timestamp timestamp =+// Timestamp.newBuilder().setSeconds(now.getEpochSecond())+// .setNanos(now.getNano()).build();+//+//+// Example 6: Compute Timestamp from current time in Python.+//+// timestamp = Timestamp()+// timestamp.GetCurrentTime()+//+// # JSON Mapping+//+// In JSON format, the Timestamp type is encoded as a string in the+// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the+// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"+// where {year} is always expressed using four digits while {month}, {day},+// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional+// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),+// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone+// is required. A proto3 JSON serializer should always use UTC (as indicated by+// "Z") when printing the Timestamp type and a proto3 JSON parser should be+// able to accept both UTC and other timezones (as indicated by an offset).+//+// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past+// 01:30 UTC on January 15, 2017.+//+// In JavaScript, one can convert a Date object to this format using the+// standard+// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)+// method. In Python, a standard `datetime.datetime` object can be converted+// to this format using+// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with+// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use+// the Joda Time's [`ISODateTimeFormat.dateTime()`](+// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D+// ) to obtain a formatter capable of generating timestamps in this format.+//+//+message Timestamp {+ // Represents seconds of UTC time since Unix epoch+ // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to+ // 9999-12-31T23:59:59Z inclusive.+ int64 seconds = 1;++ // Non-negative fractions of a second at nanosecond resolution. Negative+ // second values with fractions must still have non-negative nanos values+ // that count forward in time. Must be from 0 to 999,999,999+ // inclusive.+ int32 nanos = 2;+}
+ proto/invest/common.proto view
@@ -0,0 +1,56 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";++//Денежная сумма в определенной валюте+message MoneyValue {++ // строковый ISO-код валюты+ string currency = 1;++ // целая часть суммы, может быть отрицательным числом+ int64 units = 2;++ // дробная часть суммы, может быть отрицательным числом+ int32 nano = 3;+}++//Котировка - денежная сумма без указания валюты+message Quotation {++ // целая часть суммы, может быть отрицательным числом+ int64 units = 1;++ // дробная часть суммы, может быть отрицательным числом+ int32 nano = 2;+}++//Режим торгов инструмента+enum SecurityTradingStatus {+ SECURITY_TRADING_STATUS_UNSPECIFIED = 0; //Торговый статус не определён+ SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING = 1; //Недоступен для торгов+ SECURITY_TRADING_STATUS_OPENING_PERIOD = 2; //Период открытия торгов+ SECURITY_TRADING_STATUS_CLOSING_PERIOD = 3; //Период закрытия торгов+ SECURITY_TRADING_STATUS_BREAK_IN_TRADING = 4; //Перерыв в торговле+ SECURITY_TRADING_STATUS_NORMAL_TRADING = 5; //Нормальная торговля+ SECURITY_TRADING_STATUS_CLOSING_AUCTION = 6; //Аукцион закрытия+ SECURITY_TRADING_STATUS_DARK_POOL_AUCTION = 7; //Аукцион крупных пакетов+ SECURITY_TRADING_STATUS_DISCRETE_AUCTION = 8; //Дискретный аукцион+ SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD = 9; //Аукцион открытия+ SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE = 10; //Период торгов по цене аукциона закрытия+ SECURITY_TRADING_STATUS_SESSION_ASSIGNED = 11; //Сессия назначена+ SECURITY_TRADING_STATUS_SESSION_CLOSE = 12; //Сессия закрыта+ SECURITY_TRADING_STATUS_SESSION_OPEN = 13; //Сессия открыта+ SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING = 14; //Доступна торговля в режиме внутренней ликвидности брокера+ SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING = 15; //Перерыв торговли в режиме внутренней ликвидности брокера+ SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING = 16; //Недоступна торговля в режиме внутренней ликвидности брокера+}++//Проверка активности стрима.+message Ping {++ //Время проверки.+ google.protobuf.Timestamp time = 1;+}
+ proto/invest/instruments.proto view
@@ -0,0 +1,908 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";+import "invest/common.proto";+++service InstrumentsService {/*Сервис предназначен для получения:</br>**1**. информации об инструментах;</br>**2**.+ расписания торговых сессий;</br>**3**. календаря выплат купонов по облигациям;</br>**4**.+ размера гарантийного обеспечения по фьючерсам;</br>**5**. дивидендов по ценной бумаге.*/++ //Метод получения расписания торгов торговых площадок.+ rpc TradingSchedules (TradingSchedulesRequest) returns (TradingSchedulesResponse);++ //Метод получения облигации по её идентификатору.+ rpc BondBy (InstrumentRequest) returns (BondResponse);++ //Метод получения списка облигаций.+ rpc Bonds (InstrumentsRequest) returns (BondsResponse);++ //Метод получения графика выплат купонов по облигации.+ rpc GetBondCoupons (GetBondCouponsRequest) returns (GetBondCouponsResponse);++ //Метод получения валюты по её идентификатору.+ rpc CurrencyBy (InstrumentRequest) returns (CurrencyResponse);++ //Метод получения списка валют.+ rpc Currencies (InstrumentsRequest) returns (CurrenciesResponse);++ //Метод получения инвестиционного фонда по его идентификатору.+ rpc EtfBy (InstrumentRequest) returns (EtfResponse);++ //Метод получения списка инвестиционных фондов.+ rpc Etfs (InstrumentsRequest) returns (EtfsResponse);++ //Метод получения фьючерса по его идентификатору.+ rpc FutureBy (InstrumentRequest) returns (FutureResponse);++ //Метод получения списка фьючерсов.+ rpc Futures (InstrumentsRequest) returns (FuturesResponse);++ //Метод получения акции по её идентификатору.+ rpc ShareBy (InstrumentRequest) returns (ShareResponse);++ //Метод получения списка акций.+ rpc Shares (InstrumentsRequest) returns (SharesResponse);++ //Метод получения накопленного купонного дохода по облигации.+ rpc GetAccruedInterests (GetAccruedInterestsRequest) returns (GetAccruedInterestsResponse);++ //Метод получения размера гарантийного обеспечения по фьючерсам.+ rpc GetFuturesMargin (GetFuturesMarginRequest) returns (GetFuturesMarginResponse);++ //Метод получения основной информации об инструменте.+ rpc GetInstrumentBy (InstrumentRequest) returns (InstrumentResponse);++ //Метод для получения событий выплаты дивидендов по инструменту.+ rpc GetDividends (GetDividendsRequest) returns (GetDividendsResponse);++ //Метод получения актива по его идентификатору.+ rpc GetAssetBy (AssetRequest) returns (AssetResponse);++ //Метод получения списка активов.+ rpc GetAssets (AssetsRequest) returns (AssetsResponse);++ //Метод получения списка избранных инструментов.+ rpc GetFavorites (GetFavoritesRequest) returns (GetFavoritesResponse);++ //Метод редактирования списка избранных инструментов.+ rpc EditFavorites (EditFavoritesRequest) returns (EditFavoritesResponse);++ //Метод получения списка стран.+ rpc GetCountries (GetCountriesRequest) returns (GetCountriesResponse);++ //Метод поиска инструмента.+ rpc FindInstrument (FindInstrumentRequest) returns (FindInstrumentResponse);++ //Метод получения списка брендов.+ rpc GetBrands(GetBrandsRequest) returns (GetBrandsResponse);++ //Метод получения бренда по его идентификатору.+ rpc GetBrandBy(GetBrandRequest) returns (Brand);+}++//Запрос расписания торгов.+message TradingSchedulesRequest {+ string exchange = 1; //Наименование биржи или расчетного календаря. </br>Если не передаётся, возвращается информация по всем доступным торговым площадкам.+ google.protobuf.Timestamp from = 2; //Начало периода по часовому поясу UTC.+ google.protobuf.Timestamp to = 3; //Окончание периода по часовому поясу UTC.+}++//Список торговых площадок.+message TradingSchedulesResponse {+ repeated TradingSchedule exchanges = 1; // Список торговых площадок и режимов торгов.+}++//Данные по торговой площадке.+message TradingSchedule {+ string exchange = 1; // Наименование торговой площадки.+ repeated TradingDay days = 2; // Массив с торговыми и неторговыми днями.+}++//Информация о времени торгов.+message TradingDay {+ reserved 5, 6;+ google.protobuf.Timestamp date = 1; // Дата.+ bool is_trading_day = 2; // Признак торгового дня на бирже.+ google.protobuf.Timestamp start_time = 3; // Время начала торгов по часовому поясу UTC.+ google.protobuf.Timestamp end_time = 4; // Время окончания торгов по часовому поясу UTC.+ google.protobuf.Timestamp opening_auction_start_time = 7; // Время начала аукциона открытия в часовом поясе UTC.+ google.protobuf.Timestamp closing_auction_end_time = 8; // Время окончания аукциона закрытия в часовом поясе UTC.+ google.protobuf.Timestamp evening_opening_auction_start_time = 9; // Время начала аукциона открытия вечерней сессии в часовом поясе UTC.+ google.protobuf.Timestamp evening_start_time = 10; // Время начала вечерней сессии в часовом поясе UTC.+ google.protobuf.Timestamp evening_end_time = 11; // Время окончания вечерней сессии в часовом поясе UTC.+ google.protobuf.Timestamp clearing_start_time = 12; // Время начала основного клиринга в часовом поясе UTC.+ google.protobuf.Timestamp clearing_end_time = 13; // Время окончания основного клиринга в часовом поясе UTC.+ google.protobuf.Timestamp premarket_start_time = 14; // Время начала премаркета в часовом поясе UTC.+ google.protobuf.Timestamp premarket_end_time = 15; // Время окончания премаркета в часовом поясе UTC.+}++//Запрос получения инструмента по идентификатору.+message InstrumentRequest {+ InstrumentIdType id_type = 1; // Тип идентификатора инструмента. Возможные значения: figi, ticker. Подробнее об идентификации инструментов: [Идентификация инструментов](https://tinkoff.github.io/investAPI/faq_identification/)+ string class_code = 2; // Идентификатор class_code. Обязателен при id_type = ticker.+ string id = 3; // Идентификатор запрашиваемого инструмента.+}++//Запрос получения инструментов.+message InstrumentsRequest {+ InstrumentStatus instrument_status = 1; //Статус запрашиваемых инструментов. Возможные значения: [InstrumentStatus](#instrumentstatus)+}++//Информация об облигации.+message BondResponse {+ Bond instrument = 1; // Информация об облигации.+}++//Список облигаций.+message BondsResponse {+ repeated Bond instruments = 1; //Массив облигаций.+}++//Запрос купонов по облигации.+message GetBondCouponsRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода в часовом поясе UTC. Фильтрация по coupon_date (дата выплаты купона)+ google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода в часовом поясе UTC. Фильтрация по coupon_date (дата выплаты купона)+}++//Купоны по облигации.+message GetBondCouponsResponse {+ repeated Coupon events = 1;+}++//Объект передачи информации о купоне облигации.+message Coupon {+ string figi = 1; //Figi-идентификатор инструмента.+ google.protobuf.Timestamp coupon_date = 2; //Дата выплаты купона.+ int64 coupon_number = 3; //Номер купона.+ google.protobuf.Timestamp fix_date = 4; //(Опционально) Дата фиксации реестра для выплаты купона.+ MoneyValue pay_one_bond = 5; //Выплата на одну облигацию.+ CouponType coupon_type = 6; //Тип купона.+ google.protobuf.Timestamp coupon_start_date = 7; //Начало купонного периода.+ google.protobuf.Timestamp coupon_end_date = 8; //Окончание купонного периода.+ int32 coupon_period = 9; //Купонный период в днях.+}++//Тип купонов.+enum CouponType {+ COUPON_TYPE_UNSPECIFIED = 0; //Неопределенное значение+ COUPON_TYPE_CONSTANT = 1; //Постоянный+ COUPON_TYPE_FLOATING = 2; //Плавающий+ COUPON_TYPE_DISCOUNT = 3; //Дисконт+ COUPON_TYPE_MORTGAGE = 4; //Ипотечный+ COUPON_TYPE_FIX = 5; //Фиксированный+ COUPON_TYPE_VARIABLE = 6; //Переменный+ COUPON_TYPE_OTHER = 7; //Прочее+}++//Данные по валюте.+message CurrencyResponse {+ Currency instrument = 1; // Информация о валюте.+}++//Данные по валютам.+message CurrenciesResponse {+ repeated Currency instruments = 1; //Массив валют.+}++//Данные по фонду.+message EtfResponse {+ Etf instrument = 1; // Информация о фонде.+}++//Данные по фондам.+message EtfsResponse {+ repeated Etf instruments = 1; //Массив фондов.+}++//Данные по фьючерсу.+message FutureResponse {+ Future instrument = 1; // Информация о фьючерсу.+}++//Данные по фьючерсам.+message FuturesResponse {+ repeated Future instruments = 1; //Массив фьючерсов.+}++//Данные по акции.+message ShareResponse {+ Share instrument = 1; // Информация об акции.+}++//Данные по акциям.+message SharesResponse {+ repeated Share instruments = 1; //Массив акций.+}++//Объект передачи информации об облигации.+message Bond {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код (секция торгов).+ string isin = 4; //Isin-идентификатор инструмента.+ int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 6; //Валюта расчётов.++ Quotation klong = 7; //Коэффициент ставки риска длинной позиции по инструменту.+ Quotation kshort = 8; //Коэффициент ставки риска короткой позиции по инструменту.+ Quotation dlong = 9; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 10; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 11; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 12; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 13; //Признак доступности для операций в шорт.+ string name = 15; //Название инструмента.+ string exchange = 16; //Торговая площадка.++ int32 coupon_quantity_per_year = 17; //Количество выплат по купонам в год.+ google.protobuf.Timestamp maturity_date = 18; //Дата погашения облигации в часовом поясе UTC.+ MoneyValue nominal = 19; //Номинал облигации.+ google.protobuf.Timestamp state_reg_date = 21; //Дата выпуска облигации в часовом поясе UTC.+ google.protobuf.Timestamp placement_date = 22; //Дата размещения в часовом поясе UTC.+ MoneyValue placement_price = 23; //Цена размещения.+ MoneyValue aci_value = 24; //Значение НКД (накопленного купонного дохода) на дату.++ string country_of_risk = 25; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 26; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string sector = 27; //Сектор экономики.+ string issue_kind = 28; //Форма выпуска. Возможные значения: </br>**documentary** — документарная; </br>**non_documentary** — бездокументарная.+ int64 issue_size = 29; //Размер выпуска.+ int64 issue_size_plan = 30; //Плановый размер выпуска.++ SecurityTradingStatus trading_status = 31; //Текущий режим торгов инструмента.+ bool otc_flag = 32; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 33; //Признак доступности для покупки.+ bool sell_available_flag = 34; //Признак доступности для продажи.+ bool floating_coupon_flag = 35; //Признак облигации с плавающим купоном.+ bool perpetual_flag = 36; //Признак бессрочной облигации.+ bool amortization_flag = 37; //Признак облигации с амортизацией долга.+ Quotation min_price_increment = 38; //Шаг цены.+ bool api_trade_available_flag = 39; //Признак доступности торгов через API.++ string uid = 40; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 41; //Реальная площадка исполнения расчётов.+ string position_uid = 42; //Уникальный идентификатор позиции инструмента.++ bool for_iis_flag = 51; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 61; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 62; //Дата первой дневной свечи.+}++//Объект передачи информации о валюте.+message Currency {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код (секция торгов).+ string isin = 4; //Isin-идентификатор инструмента.+ int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 6; //Валюта расчётов.++ Quotation klong = 7; //Коэффициент ставки риска длинной позиции по инструменту.+ Quotation kshort = 8; //Коэффициент ставки риска короткой позиции по инструменту.+ Quotation dlong = 9; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 10; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 11; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 12; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 13; //Признак доступности для операций в шорт.+ string name = 15; //Название инструмента.+ string exchange = 16; //Торговая площадка.++ MoneyValue nominal = 17; //Номинал.++ string country_of_risk = 18; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 19; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.++ SecurityTradingStatus trading_status = 20; //Текущий режим торгов инструмента.+ bool otc_flag = 21; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 22; //Признак доступности для покупки.+ bool sell_available_flag = 23; //Признак доступности для продажи.+ string iso_currency_name = 24; //Строковый ISO-код валюты.+ Quotation min_price_increment = 25; //Шаг цены.+ bool api_trade_available_flag = 26; //Признак доступности торгов через API.++ string uid = 27; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 28; //Реальная площадка исполнения расчётов.+ string position_uid = 29; //Уникальный идентификатор позиции инструмента.++ bool for_iis_flag = 41; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи.+}++//Объект передачи информации об инвестиционном фонде.+message Etf {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код (секция торгов).+ string isin = 4; //Isin-идентификатор инструмента.+ int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 6; //Валюта расчётов.++ Quotation klong = 7; //Коэффициент ставки риска длинной позиции по инструменту.+ Quotation kshort = 8; //Коэффициент ставки риска короткой позиции по инструменту.+ Quotation dlong = 9; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 10; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 11; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 12; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 13; //Признак доступности для операций в шорт.+ string name = 15; //Название инструмента.+ string exchange = 16; //Торговая площадка.++ Quotation fixed_commission = 17; //Размер фиксированной комиссии фонда.+ string focus_type = 18; //Возможные значения: </br>**equity** — акции;</br>**fixed_income** — облигации;</br>**mixed_allocation** — смешанный;</br>**money_market** — денежный рынок;</br>**real_estate** — недвижимость;</br>**commodity** — товары;</br>**specialty** — специальный;</br>**private_equity** — private equity;</br>**alternative_investment** — альтернативные инвестиции.+ google.protobuf.Timestamp released_date = 19; //Дата выпуска в часовом поясе UTC.+ Quotation num_shares = 20; //Количество акций фонда в обращении.++ string country_of_risk = 21; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 22; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string sector = 23; //Сектор экономики.+ string rebalancing_freq = 24; //Частота ребалансировки.++ SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента.+ bool otc_flag = 26; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 27; //Признак доступности для покупки.+ bool sell_available_flag = 28; //Признак доступности для продажи.+ Quotation min_price_increment = 29; //Шаг цены.+ bool api_trade_available_flag = 30; //Признак доступности торгов через API.++ string uid = 31; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 32; //Реальная площадка исполнения расчётов.+ string position_uid = 33; //Уникальный идентификатор позиции инструмента.++ bool for_iis_flag = 41; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи.+}++//Объект передачи информации о фьючерсе.+message Future {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код (секция торгов).+ int32 lot = 4; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 5; //Валюта расчётов.++ Quotation klong = 6; //Коэффициент ставки риска длинной позиции по клиенту.+ Quotation kshort = 7; //Коэффициент ставки риска короткой позиции по клиенту.+ Quotation dlong = 8; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 9; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 10; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 11; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 12; //Признак доступности для операций шорт.+ string name = 13; //Название инструмента.+ string exchange = 14; //Торговая площадка.++ google.protobuf.Timestamp first_trade_date = 15; //Дата начала обращения контракта в часовом поясе UTC.+ google.protobuf.Timestamp last_trade_date = 16; //Дата в часовом поясе UTC, до которой возможно проведение операций с фьючерсом.+ string futures_type = 17; //Тип фьючерса. Возможные значения: </br>**physical_delivery** — физические поставки; </br>**cash_settlement** — денежный эквивалент.+ string asset_type = 18; //Тип актива. Возможные значения: </br>**commodity** — товар; </br>**currency** — валюта; </br>**security** — ценная бумага; </br>**index** — индекс.+ string basic_asset = 19; //Основной актив.+ Quotation basic_asset_size = 20; //Размер основного актива.++ string country_of_risk = 21; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 22; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string sector = 23; //Сектор экономики.+ google.protobuf.Timestamp expiration_date = 24; //Дата истечения срока в часов поясе UTC.++ SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента.+ bool otc_flag = 26; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 27; //Признак доступности для покупки.+ bool sell_available_flag = 28; //Признак доступности для продажи.+ Quotation min_price_increment = 29; //Шаг цены.+ bool api_trade_available_flag = 30; //Признак доступности торгов через API.++ string uid = 31; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 32; //Реальная площадка исполнения расчётов.+ string position_uid = 33; //Уникальный идентификатор позиции инструмента.+ string basic_asset_position_uid = 34; //Уникальный идентификатор позиции основного инструмента.++ bool for_iis_flag = 41; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи.+}++//Объект передачи информации об акции.+message Share {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код (секция торгов).+ string isin = 4; //Isin-идентификатор инструмента.+ int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 6; //Валюта расчётов.++ Quotation klong = 7; //Коэффициент ставки риска длинной позиции по инструменту.+ Quotation kshort = 8; //Коэффициент ставки риска короткой позиции по инструменту.+ Quotation dlong = 9; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 10; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 11; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 12; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 13; //Признак доступности для операций в шорт.+ string name = 15; //Название инструмента.+ string exchange = 16; //Торговая площадка.++ google.protobuf.Timestamp ipo_date = 17; //Дата IPO акции в часовом поясе UTC.+ int64 issue_size = 18; //Размер выпуска.++ string country_of_risk = 19; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 20; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string sector = 21; //Сектор экономики.+ int64 issue_size_plan = 22; //Плановый размер выпуска.+ MoneyValue nominal = 23; //Номинал.++ SecurityTradingStatus trading_status = 25; //Текущий режим торгов инструмента.+ bool otc_flag = 26; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 27; //Признак доступности для покупки.+ bool sell_available_flag = 28; //Признак доступности для продажи.+ bool div_yield_flag = 29; //Признак наличия дивидендной доходности.+ ShareType share_type = 30; //Тип акции. Возможные значения: [ShareType](https://tinkoff.github.io/investAPI/instruments#sharetype)+ Quotation min_price_increment = 31; //Шаг цены.+ bool api_trade_available_flag = 32; //Признак доступности торгов через API.++ string uid = 33; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 34; //Реальная площадка исполнения расчётов.+ string position_uid = 35; //Уникальный идентификатор позиции инструмента.++ bool for_iis_flag = 46; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи.+}++//Запрос НКД по облигации+message GetAccruedInterestsRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода в часовом поясе UTC.+ google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода в часовом поясе UTC.+}++//НКД облигации+message GetAccruedInterestsResponse {+ repeated AccruedInterest accrued_interests = 1; //Массив операций начисления купонов.+}++//Операция начисления купонов.+message AccruedInterest {+ google.protobuf.Timestamp date = 1; //Дата и время выплаты в часовом поясе UTC.+ Quotation value = 2; //Величина выплаты.+ Quotation value_percent = 3; //Величина выплаты в процентах от номинала.+ Quotation nominal = 4; //Номинал облигации.+}++//Запрос информации о фьючерсе+message GetFuturesMarginRequest {+ string figi = 1; // Идентификатор инструмента.+}++//Данные по фьючерсу+message GetFuturesMarginResponse {+ MoneyValue initial_margin_on_buy = 1; //Гарантийное обеспечение при покупке.+ MoneyValue initial_margin_on_sell = 2; //Гарантийное обеспечение при продаже.+ Quotation min_price_increment = 3; //Шаг цены.+ Quotation min_price_increment_amount = 4; //Стоимость шага цены.+}++//Тип идентификатора инструмента. Подробнее об идентификации инструментов: [Идентификация инструментов](https://tinkoff.github.io/investAPI/faq_identification/)+enum InstrumentIdType {+ INSTRUMENT_ID_UNSPECIFIED = 0; //Значение не определено.+ INSTRUMENT_ID_TYPE_FIGI = 1; //Figi.+ INSTRUMENT_ID_TYPE_TICKER = 2; //Ticker.+ INSTRUMENT_ID_TYPE_UID = 3; //Уникальный идентификатор.+}++//Статус запрашиваемых инструментов.+enum InstrumentStatus {+ INSTRUMENT_STATUS_UNSPECIFIED = 0; //Значение не определено.+ INSTRUMENT_STATUS_BASE = 1; //Базовый список инструментов (по умолчанию). Инструменты доступные для торговли через TINKOFF INVEST API.+ INSTRUMENT_STATUS_ALL = 2; //Список всех инструментов.+}++//Данные по инструменту.+message InstrumentResponse {+ Instrument instrument = 1; // Основная информация об инструменте.+}++//Объект передачи основной информации об инструменте.+message Instrument {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код инструмента.+ string isin = 4; //Isin-идентификатор инструмента.+ int32 lot = 5; //Лотность инструмента. Возможно совершение операций только на количества ценной бумаги, кратные параметру *lot*. Подробнее: [лот](https://tinkoff.github.io/investAPI/glossary#lot)+ string currency = 6; //Валюта расчётов.++ Quotation klong = 7; //Коэффициент ставки риска длинной позиции по инструменту.+ Quotation kshort = 8; //Коэффициент ставки риска короткой позиции по инструменту.+ Quotation dlong = 9; //Ставка риска минимальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort = 10; //Ставка риска минимальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ Quotation dlong_min = 11; //Ставка риска начальной маржи в лонг. Подробнее: [ставка риска в лонг](https://help.tinkoff.ru/margin-trade/long/risk-rate/)+ Quotation dshort_min = 12; //Ставка риска начальной маржи в шорт. Подробнее: [ставка риска в шорт](https://help.tinkoff.ru/margin-trade/short/risk-rate/)+ bool short_enabled_flag = 13; //Признак доступности для операций в шорт.+ string name = 14; //Название инструмента.+ string exchange = 15; //Торговая площадка.++ string country_of_risk = 16; //Код страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string country_of_risk_name = 17; //Наименование страны риска, т.е. страны, в которой компания ведёт основной бизнес.+ string instrument_type = 18; //Тип инструмента.++ SecurityTradingStatus trading_status = 19; //Текущий режим торгов инструмента.+ bool otc_flag = 20; //Признак внебиржевой ценной бумаги.+ bool buy_available_flag = 21; //Признак доступности для покупки.+ bool sell_available_flag = 22; //Признак доступности для продажи.+ Quotation min_price_increment = 23; //Шаг цены.+ bool api_trade_available_flag = 24; //Признак доступности торгов через API.++ string uid = 25; //Уникальный идентификатор инструмента.+ RealExchange real_exchange = 26; //Реальная площадка исполнения расчётов.+ string position_uid = 27; //Уникальный идентификатор позиции инструмента.++ bool for_iis_flag = 36; //Признак доступности для ИИС.++ google.protobuf.Timestamp first_1min_candle_date = 56; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 57; //Дата первой дневной свечи.+}++//Запрос дивидендов.+message GetDividendsRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода в часовом поясе UTC. Фильтрация происходит по параметру *record_date* (дата фиксации реестра).+ google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода в часовом поясе UTC. Фильтрация происходит по параметру *record_date* (дата фиксации реестра).+}++//Дивиденды.+message GetDividendsResponse {+ repeated Dividend dividends = 1;+}++//Информация о выплате.+message Dividend {+ MoneyValue dividend_net = 1; //Величина дивиденда на 1 ценную бумагу (включая валюту).+ google.protobuf.Timestamp payment_date = 2; //Дата фактических выплат в часовом поясе UTC.+ google.protobuf.Timestamp declared_date = 3; //Дата объявления дивидендов в часовом поясе UTC.+ google.protobuf.Timestamp last_buy_date = 4; //Последний день (включительно) покупки для получения выплаты в часовом поясе UTC.+ string dividend_type = 5; //Тип выплаты. Возможные значения: Regular Cash – регулярные выплаты, Cancelled – выплата отменена, Daily Accrual – ежедневное начисление, Return of Capital – возврат капитала, прочие типы выплат.+ google.protobuf.Timestamp record_date = 6; //Дата фиксации реестра в часовом поясе UTC.+ string regularity = 7; //Регулярность выплаты. Возможные значения: Annual – ежегодная, Semi-Anl – каждые полгода, прочие типы выплат.+ MoneyValue close_price = 8; //Цена закрытия инструмента на момент ex_dividend_date.+ Quotation yield_value = 9; //Величина доходности.+ google.protobuf.Timestamp created_at = 10; //Дата и время создания записи в часовом поясе UTC.+}++//Тип акций.+enum ShareType {+ SHARE_TYPE_UNSPECIFIED = 0; //Значение не определено.+ SHARE_TYPE_COMMON = 1; //Обыкновенная+ SHARE_TYPE_PREFERRED = 2; //Привилегированная+ SHARE_TYPE_ADR = 3; //Американские депозитарные расписки+ SHARE_TYPE_GDR = 4; //Глобальные депозитарные расписки+ SHARE_TYPE_MLP = 5; //Товарищество с ограниченной ответственностью+ SHARE_TYPE_NY_REG_SHRS = 6; //Акции из реестра Нью-Йорка+ SHARE_TYPE_CLOSED_END_FUND = 7; //Закрытый инвестиционный фонд+ SHARE_TYPE_REIT = 8; //Траст недвижимости+}++//Запрос актива по идентификатору.+message AssetRequest {+ string id = 1; //uid-идентификатор актива.+}++//Данные по активу.+message AssetResponse {+ AssetFull asset = 1; //Актив.+}++//Запрос списка активов.+message AssetsRequest {+}++//Список активов.+message AssetsResponse {+ repeated Asset assets = 1; //Активы.+}++message AssetFull {+ string uid = 1; //Уникальный идентификатор актива.+ AssetType type = 2; //Тип актива.+ string name = 3; //Наименование актива.+ string name_brief = 4; //Короткое наименование актива.+ string description = 5; //Описание актива.+ google.protobuf.Timestamp deleted_at = 6; //Дата и время удаления актива.+ repeated string required_tests = 7; //Тестирование клиентов.+ oneof ext {+ AssetCurrency currency = 8; //Валюта. Обязательно и заполняется только для type = "ASSET_TYPE_CURRENCY".+ AssetSecurity security = 9; //Ценная бумага. Обязательно и заполняется только для type = "ASSET_TYPE_SECURITY".+ }+ string gos_reg_code = 10; //Номер государственной регистрации.+ string cfi = 11; //Код CFI.+ string code_nsd = 12; //Код НРД инструмента.+ string status = 13; //Статус актива.+ Brand brand = 14; //Бренд.+ google.protobuf.Timestamp updated_at = 15; //Дата и время последнего обновления записи.+ string br_code = 16; //Код типа ц.б. по классификации Банка России.+ string br_code_name = 17; //Наименование кода типа ц.б. по классификации Банка России.+ repeated AssetInstrument instruments = 18; //Массив идентификаторов инструментов.+}++//Информация об активе.+message Asset {+ string uid = 1; //Уникальный идентификатор актива.+ AssetType type = 2; //Тип актива.+ string name = 3; //Наименование актива.+ repeated AssetInstrument instruments = 4; //Массив идентификаторов инструментов.+}++//Тип актива.+enum AssetType {+ ASSET_TYPE_UNSPECIFIED = 0; //Тип не определён.+ ASSET_TYPE_CURRENCY = 1; //Валюта.+ ASSET_TYPE_COMMODITY = 2; //Товар.+ ASSET_TYPE_INDEX = 3; //Индекс.+ ASSET_TYPE_SECURITY = 4; //Ценная бумага.+}++//Валюта.+message AssetCurrency {+ string base_currency = 1; //ISO-код валюты.+}++//Ценная бумага.+message AssetSecurity {+ string isin = 1; //ISIN-идентификатор ценной бумаги.+ string type = 2; //Тип ценной бумаги.+ oneof ext {+ AssetShare share = 3; //Акция. Заполняется только для акций (тип актива asset.type = "ASSET_TYPE_SECURITY" и security.type = share).+ AssetBond bond = 4; //Облигация. Заполняется только для облигаций (тип актива asset.type = "ASSET_TYPE_SECURITY" и security.type = bond).+ AssetStructuredProduct sp = 5; //Структурная нота. Заполняется только для структурных продуктов (тип актива asset.type = "ASSET_TYPE_SECURITY" и security.type = sp).+ AssetEtf etf = 6; // Фонд. Заполняется только для фондов (тип актива asset.type = "ASSET_TYPE_SECURITY" и security.type = etf).+ AssetClearingCertificate clearing_certificate = 7; // Клиринговый сертификат участия. Заполняется только для клиринговых сертификатов (тип актива asset.type = "ASSET_TYPE_SECURITY" и security.type = clearing_certificate).+ }+}++//Акция.+message AssetShare {+ ShareType type = 1; //Тип акции.+ Quotation issue_size = 2; //Объем выпуска (шт.).+ Quotation nominal = 3; //Номинал.+ string nominal_currency = 4; //Валюта номинала.+ string primary_index = 5; //Индекс (Bloomberg).+ Quotation dividend_rate = 6; //Ставка дивиденда (для привилегированных акций).+ string preferred_share_type = 7; //Тип привилегированных акций.+ google.protobuf.Timestamp ipo_date = 8; //Дата IPO.+ google.protobuf.Timestamp registry_date = 9; //Дата регистрации.+ bool div_yield_flag = 10; //Признак наличия дивидендной доходности.+ string issue_kind = 11; //Форма выпуска ФИ.+ google.protobuf.Timestamp placement_date = 12; //Дата размещения акции.+ string repres_isin = 13; //ISIN базового актива.+ Quotation issue_size_plan = 14; //Объявленное количество шт.+ Quotation total_float = 15; //Количество акций в свободном обращении.+}++//Облигация.+message AssetBond {+ Quotation current_nominal = 1; //Текущий номинал.+ string borrow_name = 2; //Наименование заемщика.+ Quotation issue_size = 3; //Объем эмиссии облигации (стоимость).+ Quotation nominal = 4 ; //Номинал облигации.+ string nominal_currency = 5; //Валюта номинала.+ string issue_kind = 6; //Форма выпуска облигации.+ string interest_kind = 7; //Форма дохода облигации.+ int32 coupon_quantity_per_year = 8; //Количество выплат в год.+ bool indexed_nominal_flag = 9; //Признак облигации с индексируемым номиналом.+ bool subordinated_flag = 10; //Признак субординированной облигации.+ bool collateral_flag = 11; //Признак обеспеченной облигации.+ bool tax_free_flag = 12; //Признак показывает, что купоны облигации не облагаются налогом (для mass market).+ bool amortization_flag = 13; //Признак облигации с амортизацией долга.+ bool floating_coupon_flag = 14; //Признак облигации с плавающим купоном.+ bool perpetual_flag = 15; //Признак бессрочной облигации.+ google.protobuf.Timestamp maturity_date = 16; //Дата погашения облигации.+ string return_condition = 17; //Описание и условия получения дополнительного дохода.+ google.protobuf.Timestamp state_reg_date = 18; //Дата выпуска облигации.+ google.protobuf.Timestamp placement_date = 19; //Дата размещения облигации.+ Quotation placement_price = 20; //Цена размещения облигации.+ Quotation issue_size_plan = 21; //Объявленное количество шт.+}++//Структурная нота.+message AssetStructuredProduct {+ string borrow_name = 1; //Наименование заемщика.+ Quotation nominal = 2; //Номинал.+ string nominal_currency = 3; //Валюта номинала.+ StructuredProductType type = 4; //Тип структурной ноты.+ string logic_portfolio = 5; //Стратегия портфеля.+ AssetType asset_type = 6; //Тип базового актива.+ string basic_asset = 7; //Вид базового актива в зависимости от типа базового актива.+ Quotation safety_barrier = 8; //Барьер сохранности (в процентах).+ google.protobuf.Timestamp maturity_date = 9; //Дата погашения.+ Quotation issue_size_plan = 10; //Объявленное количество шт.+ Quotation issue_size = 11; //Объем размещения.+ google.protobuf.Timestamp placement_date = 12; //Дата размещения ноты.+ string issue_kind = 13; //Форма выпуска.+}++//Тип структурной ноты.+enum StructuredProductType {+ SP_TYPE_UNSPECIFIED = 0; //Тип не определён.+ SP_TYPE_DELIVERABLE = 1; //Поставочный.+ SP_TYPE_NON_DELIVERABLE = 2; //Беспоставочный.+}++//Фонд.+message AssetEtf {+ Quotation total_expense = 1; //Суммарные расходы фонда (в %).+ Quotation hurdle_rate = 2; //Барьерная ставка доходности после которой фонд имеет право на perfomance fee (в процентах).+ Quotation performance_fee = 3; //Комиссия за успешные результаты фонда (в процентах).+ Quotation fixed_commission = 4; //Фиксированная комиссия за управление (в процентах).+ string payment_type = 5; //Тип распределения доходов от выплат по бумагам.+ bool watermark_flag = 6; //Признак необходимости выхода фонда в плюс для получения комиссии.+ Quotation buy_premium = 7; //Премия (надбавка к цене) при покупке доли в фонде (в процентах).+ Quotation sell_discount = 8; //Ставка дисконта (вычет из цены) при продаже доли в фонде (в процентах).+ bool rebalancing_flag = 9; //Признак ребалансируемости портфеля фонда.+ string rebalancing_freq = 10; //Периодичность ребалансировки.+ string management_type = 11; //Тип управления.+ string primary_index = 12; //Индекс, который реплицирует (старается копировать) фонд.+ string focus_type = 13; //База ETF.+ bool leveraged_flag = 14; //Признак использования заемных активов (плечо).+ Quotation num_share = 15; //Количество акций в обращении.+ bool ucits_flag = 16; //Признак обязательства по отчетности перед регулятором.+ google.protobuf.Timestamp released_date = 17; //Дата выпуска.+ string description = 18; //Описание фонда.+ string primary_index_description = 19; //Описание индекса, за которым следует фонд.+ string primary_index_company = 20; //Основные компании, в которые вкладывается фонд.+ Quotation index_recovery_period = 21; //Срок восстановления индекса (после просадки).+ string inav_code = 22; //IVAV-код.+ bool div_yield_flag = 23; //Признак наличия дивидендной доходности.+ Quotation expense_commission = 24; //Комиссия на покрытие расходов фонда (в процентах).+ Quotation primary_index_tracking_error = 25; //Ошибка следования за индексом (в процентах).+ string rebalancing_plan = 26; //Плановая ребалансировка портфеля.+ string tax_rate = 27; //Ставки налогообложения дивидендов и купонов.+ repeated google.protobuf.Timestamp rebalancing_dates = 28; //Даты ребалансировок.+ string issue_kind = 29; //Форма выпуска.+ Quotation nominal = 30; //Номинал.+ string nominal_currency = 31; //Валюта номинала.+}++//Клиринговый сертификат участия.+message AssetClearingCertificate {+ Quotation nominal = 1; //Номинал.+ string nominal_currency = 2; //Валюта номинала.+}++//Бренд.+message Brand {+ string uid = 1; //uid идентификатор бренда.+ string name = 2; //Наименование бренда.+ string description = 3; //Описание.+ string info = 4; //Информация о бренде.+ string company = 5; //Компания.+ string sector = 6; //Сектор.+ string country_of_risk = 7; //Код страны риска.+ string country_of_risk_name = 8; //Наименование страны риска.+}++//Идентификаторы инструмента.+message AssetInstrument {+ string uid = 1; //uid идентификатор инструмента.+ string figi = 2; //figi идентификатор инструмента.+ string instrument_type = 3; //Тип инструмента.+ string ticker = 4; //Тикер инструмента.+ string class_code = 5; //Класс-код (секция торгов).+ repeated InstrumentLink links = 6; //Массив связанных инструментов.+}++//Связь с другим инструментом.+message InstrumentLink {+ string type = 1; //Тип связи.+ string instrument_uid = 2; //uid идентификатор связанного инструмента.+}++//Запрос списка избранных инструментов, входные параметры не требуются.+message GetFavoritesRequest {+}++//В ответ передаётся список избранных инструментов в качестве массива.+message GetFavoritesResponse {+ repeated FavoriteInstrument favorite_instruments = 1; //Массив инструментов+}++//Массив избранных инструментов.+message FavoriteInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+ string ticker = 2; //Тикер инструмента.+ string class_code = 3; //Класс-код инструмента.+ string isin = 4; //Isin-идентификатор инструмента.+ string instrument_type = 11; //Тип инструмента.+ bool otc_flag = 16; //Признак внебиржевой ценной бумаги.+ bool api_trade_available_flag = 17; //Признак доступности торгов через API.+}++//Запрос редактирования списка избранных инструментов.+message EditFavoritesRequest {+ repeated EditFavoritesRequestInstrument instruments = 1; //Массив инструментов.+ EditFavoritesActionType action_type = 6; //Тип действия со списком.+}++//Массив инструментов для редактирования списка избранных инструментов.+message EditFavoritesRequestInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+}++//Тип действия со списком избранных инструментов.+enum EditFavoritesActionType {+ EDIT_FAVORITES_ACTION_TYPE_UNSPECIFIED = 0; //Тип не определён.+ EDIT_FAVORITES_ACTION_TYPE_ADD = 1; //Добавить в список.+ EDIT_FAVORITES_ACTION_TYPE_DEL = 2; //Удалить из списка.+}++//Результат редактирования списка избранных инструментов.+message EditFavoritesResponse {+ repeated FavoriteInstrument favorite_instruments = 1; //Массив инструментов+}++//Реальная площадка исполнения расчётов.+enum RealExchange {+ REAL_EXCHANGE_UNSPECIFIED = 0; //Тип не определён.+ REAL_EXCHANGE_MOEX = 1; //Московская биржа.+ REAL_EXCHANGE_RTS = 2; //Санкт-Петербургская биржа.+ REAL_EXCHANGE_OTC = 3; //Внебиржевой инструмент.+}++//Запрос справочника стран.+message GetCountriesRequest { }++//Справочник стран.+message GetCountriesResponse {+ repeated CountryResponse countries = 1; //Массив стран.+}++//Данные о стране.+message CountryResponse {+ string alfa_two = 1; //Двухбуквенный код страны.+ string alfa_three = 2; //Трёхбуквенный код страны.+ string name = 3; //Наименование страны.+ string name_brief = 4; //Краткое наименование страны.+}++//Запрос на поиск инструментов.+message FindInstrumentRequest {+ string query = 1; //Строка поиска.+}++//Результат поиска инструментов.+message FindInstrumentResponse {+ repeated InstrumentShort instruments = 1; //Массив инструментов, удовлетворяющих условиям поиска.+}++//Краткая информация об инструменте.+message InstrumentShort {+ string isin = 1; //Isin инструмента.+ string figi = 2; //Figi инструмента.+ string ticker = 3; //Ticker инструмента.+ string class_code = 4; //ClassCode инструмента.+ string instrument_type = 5; //Тип инструмента.+ string name = 6; //Название инструмента.+ string uid = 7; //Уникальный идентификатор инструмента.+ string position_uid = 8; //Уникальный идентификатор позиции инструмента.+ bool api_trade_available_flag = 11; //Признак доступности торгов через API.+ bool for_iis_flag = 12; //Признак доступности для ИИС.+ google.protobuf.Timestamp first_1min_candle_date = 26; //Дата первой минутной свечи.+ google.protobuf.Timestamp first_1day_candle_date = 27; //Дата первой дневной свечи.+}++//Запрос списка брендов.+message GetBrandsRequest { }++//Запрос бренда.+message GetBrandRequest {+ string id = 1; //Uid-идентификатор бренда.+}++//Список брендов.+message GetBrandsResponse {+ repeated Brand brands = 1; //Массив брендов.+}
+ proto/invest/marketdata.proto view
@@ -0,0 +1,370 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";+import "invest/common.proto";++service MarketDataService { //Сервис получения биржевой информации:</br> **1**. свечи;</br> **2**. стаканы;</br> **3**. торговые статусы;</br> **4**. лента сделок.++ //Метод запроса исторических свечей по инструменту.+ rpc GetCandles(GetCandlesRequest) returns (GetCandlesResponse);++ //Метод запроса последних цен по инструментам.+ rpc GetLastPrices(GetLastPricesRequest) returns (GetLastPricesResponse);++ //Метод получения стакана по инструменту.+ rpc GetOrderBook(GetOrderBookRequest) returns (GetOrderBookResponse);++ //Метод запроса статуса торгов по инструментам.+ rpc GetTradingStatus(GetTradingStatusRequest) returns (GetTradingStatusResponse);++ //Метод запроса обезличенных сделок за последний час.+ rpc GetLastTrades(GetLastTradesRequest) returns (GetLastTradesResponse);+}++service MarketDataStreamService {+ //Bi-directional стрим предоставления биржевой информации.+ rpc MarketDataStream(stream MarketDataRequest) returns (stream MarketDataResponse);++ //Server-side стрим предоставления биржевой информации.+ rpc MarketDataServerSideStream(MarketDataServerSideStreamRequest) returns (stream MarketDataResponse);+}++//Запрос подписки или отписки на определённые биржевые данные.+message MarketDataRequest {+ oneof payload {+ SubscribeCandlesRequest subscribe_candles_request = 1; //Запрос подписки на свечи.+ SubscribeOrderBookRequest subscribe_order_book_request = 2; //Запрос подписки на стаканы.+ SubscribeTradesRequest subscribe_trades_request = 3; //Запрос подписки на ленту обезличенных сделок.+ SubscribeInfoRequest subscribe_info_request = 4; //Запрос подписки на торговые статусы инструментов.+ SubscribeLastPriceRequest subscribe_last_price_request = 5; //Запрос подписки на последние цены.+ GetMySubscriptions get_my_subscriptions = 6; //Запрос своих подписок.+ }+}++message MarketDataServerSideStreamRequest {+ SubscribeCandlesRequest subscribe_candles_request = 1; //Запрос подписки на свечи.+ SubscribeOrderBookRequest subscribe_order_book_request = 2; //Запрос подписки на стаканы.+ SubscribeTradesRequest subscribe_trades_request = 3; //Запрос подписки на ленту обезличенных сделок.+ SubscribeInfoRequest subscribe_info_request = 4; //Запрос подписки на торговые статусы инструментов.+ SubscribeLastPriceRequest subscribe_last_price_request = 5; //Запрос подписки на последние цены.+}++//Пакет биржевой информации по подписке.+message MarketDataResponse {+ oneof payload {+ SubscribeCandlesResponse subscribe_candles_response = 1; //Результат подписки на свечи.+ SubscribeOrderBookResponse subscribe_order_book_response = 2; //Результат подписки на стаканы.+ SubscribeTradesResponse subscribe_trades_response = 3; //Результат подписки на поток обезличенных сделок.+ SubscribeInfoResponse subscribe_info_response = 4; //Результат подписки на торговые статусы инструментов.+ Candle candle = 5; //Свеча.+ Trade trade = 6; //Сделки.+ OrderBook orderbook = 7; //Стакан.+ TradingStatus trading_status = 8; //Торговый статус.+ Ping ping = 9; //Проверка активности стрима.+ SubscribeLastPriceResponse subscribe_last_price_response = 10; //Результат подписки на последние цены инструментов.+ LastPrice last_price = 11; //Последняя цена.+ }+}++// subscribeCandles | Изменения статуса подписки на свечи.+message SubscribeCandlesRequest {+ SubscriptionAction subscription_action = 1; //Изменение статуса подписки.+ repeated CandleInstrument instruments = 2; //Массив инструментов для подписки на свечи.+ bool waiting_close = 3; //Флаг ожидания закрытия временного интервала для отправки свечи, применяется только для минутных свечей.+}++//Тип операции со списком подписок.+enum SubscriptionAction {+ SUBSCRIPTION_ACTION_UNSPECIFIED = 0; //Статус подписки не определён.+ SUBSCRIPTION_ACTION_SUBSCRIBE = 1; //Подписаться.+ SUBSCRIPTION_ACTION_UNSUBSCRIBE = 2; //Отписаться.+}++//Интервал свечи.+enum SubscriptionInterval {+ SUBSCRIPTION_INTERVAL_UNSPECIFIED = 0; //Интервал свечи не определён.+ SUBSCRIPTION_INTERVAL_ONE_MINUTE = 1; //Минутные свечи.+ SUBSCRIPTION_INTERVAL_FIVE_MINUTES = 2; //Пятиминутные свечи.+}++//Запрос изменения статус подписки на свечи.+message CandleInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionInterval interval = 2; //Интервал свечей.+}++//Результат изменения статус подписки на свечи.+message SubscribeCandlesResponse {+ string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](https://tinkoff.github.io/investAPI/grpc#tracking-id).+ repeated CandleSubscription candles_subscriptions = 2; //Массив статусов подписки на свечи.+}++//Статус подписки на свечи.+message CandleSubscription {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionInterval interval = 2; //Интервал свечей.+ SubscriptionStatus subscription_status = 3; //Статус подписки.+}++//Результат подписки.+enum SubscriptionStatus {+ SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Статус подписки не определён.+ SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно.+ SUBSCRIPTION_STATUS_INSTRUMENT_NOT_FOUND = 2; //Инструмент не найден.+ SUBSCRIPTION_STATUS_SUBSCRIPTION_ACTION_IS_INVALID = 3; //Некорректный статус подписки, список возможных значений: [SubscriptionAction](https://tinkoff.github.io/investAPI/marketdata#subscriptionaction).+ SUBSCRIPTION_STATUS_DEPTH_IS_INVALID = 4; //Некорректная глубина стакана, доступные значения: 1, 10, 20, 30, 40, 50.+ SUBSCRIPTION_STATUS_INTERVAL_IS_INVALID = 5; //Некорректный интервал свечей, список возможных значений: [SubscriptionInterval](https://tinkoff.github.io/investAPI/marketdata#subscriptioninterval).+ SUBSCRIPTION_STATUS_LIMIT_IS_EXCEEDED = 6; //Превышен лимит на общее количество подписок в рамках стрима, подробнее: [Лимитная политика](https://tinkoff.github.io/investAPI/limits/).+ SUBSCRIPTION_STATUS_INTERNAL_ERROR = 7; //Внутренняя ошибка сервиса.+ SUBSCRIPTION_STATUS_TOO_MANY_REQUESTS = 8; //Превышен лимит на количество запросов на подписки в течение установленного отрезка времени+}++//Запрос на изменение статуса подписки на стаканы.+message SubscribeOrderBookRequest {+ SubscriptionAction subscription_action = 1; //Изменение статуса подписки.+ repeated OrderBookInstrument instruments = 2; //Массив инструментов для подписки на стаканы.+}++//Запрос подписки на стаканы.+message OrderBookInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+ int32 depth = 2; //Глубина стакана.+}++//Результат изменения статуса подписки на стаканы.+message SubscribeOrderBookResponse {+ string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](https://tinkoff.github.io/investAPI/grpc#tracking-id).+ repeated OrderBookSubscription order_book_subscriptions = 2; //Массив статусов подписки на стаканы.+}++//Статус подписки.+message OrderBookSubscription {+ string figi = 1; //Figi-идентификатор инструмента.+ int32 depth = 2; //Глубина стакана.+ SubscriptionStatus subscription_status = 3; //Статус подписки.+}++//Изменение статуса подписки на поток обезличенных сделок.+message SubscribeTradesRequest {+ SubscriptionAction subscription_action = 1; //Изменение статуса подписки.+ repeated TradeInstrument instruments = 2; //Массив инструментов для подписки на поток обезличенных сделок.+}++//Запрос подписки на поток обезличенных сделок.+message TradeInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+}++//Результат изменения статуса подписки на поток обезличенных сделок.+message SubscribeTradesResponse {+ string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](https://tinkoff.github.io/investAPI/grpc#tracking-id).+ repeated TradeSubscription trade_subscriptions = 2; //Массив статусов подписки на поток сделок.+}++//Статус подписки.+message TradeSubscription {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionStatus subscription_status = 2; //Статус подписки.+}++//Изменение статуса подписки на торговый статус инструмента.+message SubscribeInfoRequest {+ SubscriptionAction subscription_action = 1; //Изменение статуса подписки.+ repeated InfoInstrument instruments = 2; //Массив инструментов для подписки на торговый статус.+}++//Запрос подписки на торговый статус.+message InfoInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+}++//Результат изменения статуса подписки на торговый статус.+message SubscribeInfoResponse {+ string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](https://tinkoff.github.io/investAPI/grpc#tracking-id).+ repeated InfoSubscription info_subscriptions = 2; //Массив статусов подписки на торговый статус.+}++//Статус подписки.+message InfoSubscription {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionStatus subscription_status = 2; //Статус подписки.+}++//Изменение статуса подписки на последнюю цену инструмента.+message SubscribeLastPriceRequest {+ SubscriptionAction subscription_action = 1; //Изменение статуса подписки.+ repeated LastPriceInstrument instruments = 2; //Массив инструментов для подписки на последнюю цену.+}++//Запрос подписки на последнюю цену.+message LastPriceInstrument {+ string figi = 1; //Figi-идентификатор инструмента.+}++//Результат изменения статуса подписки на последнюю цену.+message SubscribeLastPriceResponse {+ string tracking_id = 1; //Уникальный идентификатор запроса, подробнее: [tracking_id](https://tinkoff.github.io/investAPI/grpc#tracking-id).+ repeated LastPriceSubscription last_price_subscriptions = 2; //Массив статусов подписки на последнюю цену.+}++//Статус подписки на последнюю цену.+message LastPriceSubscription {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionStatus subscription_status = 2; //Статус подписки.+}++//Пакет свечей в рамках стрима.+message Candle {+ string figi = 1; //Figi-идентификатор инструмента.+ SubscriptionInterval interval = 2; //Интервал свечи.+ Quotation open = 3; //Цена открытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation high = 4; //Максимальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation low = 5; //Минимальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation close = 6; //Цена закрытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ int64 volume = 7; //Объём сделок в лотах.+ google.protobuf.Timestamp time = 8; //Время начала интервала свечи в часовом поясе UTC.+ google.protobuf.Timestamp last_trade_ts = 9; //Время последней сделки, вошедшей в свечу в часовом поясе UTC.+}++//Пакет стаканов в рамках стрима.+message OrderBook {+ string figi = 1; //Figi-идентификатор инструмента.+ int32 depth = 2; //Глубина стакана.+ bool is_consistent = 3; //Флаг консистентности стакана. **false** значит не все заявки попали в стакан по причинам сетевых задержек или нарушения порядка доставки.+ repeated Order bids = 4; //Массив предложений.+ repeated Order asks = 5; //Массив спроса.+ google.protobuf.Timestamp time = 6; //Время формирования стакана в часовом поясе UTC по времени биржи.+ Quotation limit_up = 7; //Верхний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation limit_down = 8; //Нижний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+}++//Массив предложений/спроса.+message Order {+ Quotation price = 1; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ int64 quantity = 2; //Количество в лотах.+}++//Информация о сделке.+message Trade {+ string figi = 1; //Figi-идентификатор инструмента.+ TradeDirection direction = 2; //Направление сделки.+ Quotation price = 3; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ int64 quantity = 4; //Количество лотов.+ google.protobuf.Timestamp time = 5; //Время сделки в часовом поясе UTC по времени биржи.+}++//Направление сделки.+enum TradeDirection {+ TRADE_DIRECTION_UNSPECIFIED = 0; //Направление сделки не определено.+ TRADE_DIRECTION_BUY = 1; //Покупка.+ TRADE_DIRECTION_SELL = 2; //Продажа.+}++//Пакет изменения торгового статуса.+message TradingStatus {+ string figi = 1; //Figi-идентификатор инструмента.+ SecurityTradingStatus trading_status = 2; //Статус торговли инструментом.+ google.protobuf.Timestamp time = 3; //Время изменения торгового статуса в часовом поясе UTC.+ bool limit_order_available_flag = 4; //Признак доступности выставления лимитной заявки по инструменту.+ bool market_order_available_flag = 5; //Признак доступности выставления рыночной заявки по инструменту.+}++//Запрос исторических свечей.+message GetCandlesRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода в часовом поясе UTC.+ google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода в часовом поясе UTC.+ CandleInterval interval = 4; //Интервал запрошенных свечей.+}++//Интервал свечей.+enum CandleInterval {+ CANDLE_INTERVAL_UNSPECIFIED = 0; //Интервал не определён.+ CANDLE_INTERVAL_1_MIN = 1; //1 минута.+ CANDLE_INTERVAL_5_MIN = 2; //5 минут.+ CANDLE_INTERVAL_15_MIN = 3; //15 минут.+ CANDLE_INTERVAL_HOUR = 4; //1 час.+ CANDLE_INTERVAL_DAY = 5; //1 день.+}++//Список свечей.+message GetCandlesResponse {+ repeated HistoricCandle candles = 1; //Массив свечей.+}++//Информация о свече.+message HistoricCandle {+ Quotation open = 1; //Цена открытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation high = 2; //Максимальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation low = 3; //Минимальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation close = 4; //Цена закрытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ int64 volume = 5; //Объём торгов в лотах.+ google.protobuf.Timestamp time = 6; //Время свечи в часовом поясе UTC.+ bool is_complete = 7; //Признак завершённости свечи. **false** значит, свеча за текущие интервал ещё сформирована не полностью.+}++//Запрос получения последних цен.+message GetLastPricesRequest {+ repeated string figi = 1; //Массив figi-идентификаторов инструментов.+}++//Список последних цен.+message GetLastPricesResponse {+ repeated LastPrice last_prices = 1; //Массив последних цен.+}++//Информация о цене.+message LastPrice {+ string figi = 1; //Идентификатор инструмента.+ Quotation price = 2; //Последняя цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ google.protobuf.Timestamp time = 3; //Время получения последней цены в часовом поясе UTC по времени биржи.+}++//Запрос стакана.+message GetOrderBookRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ int32 depth = 2; //Глубина стакана.+}++//Информация о стакане.+message GetOrderBookResponse {+ string figi = 1; //Figi-идентификатор инструмента.+ int32 depth = 2; //Глубина стакана.+ repeated Order bids = 3; //Множество пар значений на покупку.+ repeated Order asks = 4; //Множество пар значений на продажу.+ Quotation last_price = 5; //Цена последней сделки за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation close_price = 6; //Цена закрытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation limit_up = 7; //Верхний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation limit_down = 8; //Нижний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+}++//Запрос получения торгового статуса.+message GetTradingStatusRequest {+ string figi = 1; //Идентификатор инструмента.+}++//Информация о торговом статусе.+message GetTradingStatusResponse {+ string figi = 1; //Figi-идентификатор инструмента.+ SecurityTradingStatus trading_status = 2; //Статус торговли инструментом.+ bool limit_order_available_flag = 3; //Признак доступности выставления лимитной заявки по инструменту.+ bool market_order_available_flag = 4; //Признак доступности выставления рыночной заявки по инструменту.+ bool api_trade_available_flag = 5; //Признак доступности торгов через API.+}++//Запрос обезличенных сделок за последний час.+message GetLastTradesRequest {+ string figi = 1; //Figi-идентификатор инструмента+ google.protobuf.Timestamp from = 2; //Начало запрашиваемого периода в часовом поясе UTC.+ google.protobuf.Timestamp to = 3; //Окончание запрашиваемого периода в часовом поясе UTC.+}++//Обезличенных сделок за последний час.+message GetLastTradesResponse {+ repeated Trade trades = 1; //Массив сделок+}++//Запрос активных подписок.+message GetMySubscriptions { }
+ proto/invest/operations.proto view
@@ -0,0 +1,439 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";+import "invest/common.proto";++service OperationsService {/*Сервис предназначен для получения:</br> **1**. списка операций по счёту;</br> **2**.+ портфеля по счёту;</br> **3**. позиций ценных бумаг на счёте;</br> **4**.+ доступного остатка для вывода средств;</br> **5**. получения различных отчётов.*/+ //Метод получения списка операций по счёту.+ rpc GetOperations(OperationsRequest) returns (OperationsResponse);++ //Метод получения портфеля по счёту.+ rpc GetPortfolio(PortfolioRequest) returns (PortfolioResponse);++ //Метод получения списка позиций по счёту.+ rpc GetPositions(PositionsRequest) returns (PositionsResponse);++ //Метод получения доступного остатка для вывода средств.+ rpc GetWithdrawLimits(WithdrawLimitsRequest) returns (WithdrawLimitsResponse);++ //Метод получения брокерского отчёта.+ rpc GetBrokerReport(BrokerReportRequest) returns (BrokerReportResponse);++ //Метод получения отчёта "Справка о доходах за пределами РФ".+ rpc GetDividendsForeignIssuer(GetDividendsForeignIssuerRequest) returns (GetDividendsForeignIssuerResponse);++ //Метод получения списка операций по счёту с пагинацией.+ rpc GetOperationsByCursor(GetOperationsByCursorRequest) returns (GetOperationsByCursorResponse);+}++service OperationsStreamService {+ //Server-side stream обновлений портфеля+ rpc PortfolioStream(PortfolioStreamRequest) returns (stream PortfolioStreamResponse);+}++//Запрос получения списка операций по счёту.+message OperationsRequest {+ string account_id = 1; //Идентификатор счёта клиента.+ google.protobuf.Timestamp from = 2; //Начало периода (по UTC).+ google.protobuf.Timestamp to = 3; //Окончание периода (по UTC).+ OperationState state = 4; //Статус запрашиваемых операций.+ string figi = 5; //Figi-идентификатор инструмента для фильтрации.+}++//Список операций.+message OperationsResponse {+ repeated Operation operations = 1; //Массив операций.+}++//Данные по операции.+message Operation {+ string id = 1; //Идентификатор операции.+ string parent_operation_id = 2; //Идентификатор родительской операции.+ string currency = 3; //Валюта операции.+ MoneyValue payment = 4; //Сумма операции.+ MoneyValue price = 5; //Цена операции за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ OperationState state = 6; //Статус операции.+ int64 quantity = 7; //Количество единиц инструмента.+ int64 quantity_rest = 8; //Неисполненный остаток по сделке.+ string figi = 9; //Figi-идентификатор инструмента, связанного с операцией.+ string instrument_type = 10; //Тип инструмента. Возможные значения: </br>**bond** — облигация; </br>**share** — акция; </br>**currency** — валюта; </br>**etf** — фонд; </br>**futures** — фьючерс.+ google.protobuf.Timestamp date = 11; //Дата и время операции в формате часовом поясе UTC.+ string type = 12; //Текстовое описание типа операции.+ OperationType operation_type = 13; //Тип операции.+ repeated OperationTrade trades = 14; //Массив сделок.+}++//Сделка по операции.+message OperationTrade {+ string trade_id = 1; //Идентификатор сделки.+ google.protobuf.Timestamp date_time = 2; //Дата и время сделки в часовом поясе UTC.+ int64 quantity = 3; //Количество инструментов.+ MoneyValue price = 4; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+}++//Запрос получения текущего портфеля по счёту.+message PortfolioRequest {+ string account_id = 1; //Идентификатор счёта пользователя.+}++//Текущий портфель по счёту.+message PortfolioResponse {+ MoneyValue total_amount_shares = 1; //Общая стоимость акций в портфеле в рублях.+ MoneyValue total_amount_bonds = 2; //Общая стоимость облигаций в портфеле в рублях.+ MoneyValue total_amount_etf = 3; //Общая стоимость фондов в портфеле в рублях.+ MoneyValue total_amount_currencies = 4; //Общая стоимость валют в портфеле в рублях.+ MoneyValue total_amount_futures = 5; //Общая стоимость фьючерсов в портфеле в рублях.+ Quotation expected_yield = 6; //Текущая относительная доходность портфеля, в %.+ repeated PortfolioPosition positions = 7; //Список позиций портфеля.+}++//Запрос позиций портфеля по счёту.+message PositionsRequest {+ string account_id = 1; //Идентификатор счёта пользователя.+}++//Список позиций по счёту.+message PositionsResponse {+ repeated MoneyValue money = 1; //Массив валютных позиций портфеля.+ repeated MoneyValue blocked = 2; //Массив заблокированных валютных позиций портфеля.+ repeated PositionsSecurities securities = 3; //Список ценно-бумажных позиций портфеля.+ bool limits_loading_in_progress = 4; //Признак идущей в данный момент выгрузки лимитов.+ repeated PositionsFutures futures = 5; //Список фьючерсов портфеля.+}++//Запрос доступного для вывода остатка.+message WithdrawLimitsRequest {+ string account_id = 1; //Идентификатор счёта пользователя.+}++//Доступный для вывода остаток.+message WithdrawLimitsResponse {+ repeated MoneyValue money = 1; //Массив валютных позиций портфеля.+ repeated MoneyValue blocked = 2; //Массив заблокированных валютных позиций портфеля.+ repeated MoneyValue blocked_guarantee = 3; //Заблокировано под гарантийное обеспечение фьючерсов.+}++//Позиции портфеля.+message PortfolioPosition {+ string figi = 1; //Figi-идентификатора инструмента.+ string instrument_type = 2; //Тип инструмента.+ Quotation quantity = 3; //Количество инструмента в портфеле в штуках.+ MoneyValue average_position_price = 4; //Средневзвешенная цена позиции. **Возможна задержка до секунды для пересчёта**.+ Quotation expected_yield = 5; //Текущая рассчитанная доходность позиции.+ MoneyValue current_nkd = 6; // Текущий НКД.+ Quotation average_position_price_pt = 7; //Средняя цена лота в позиции в пунктах (для фьючерсов). **Возможна задержка до секунды для пересчёта**.+ MoneyValue current_price = 8; //Текущая цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента..+ MoneyValue average_position_price_fifo = 9; //Средняя цена лота в позиции по методу FIFO. **Возможна задержка до секунды для пересчёта**.+ Quotation quantity_lots = 10; //Количество лотов в портфеле.+ bool blocked = 21; //Заблокировано.+}++//Баланс позиции ценной бумаги.+message PositionsSecurities {+ string figi = 1; //Figi-идентификатор бумаги.+ int64 blocked = 2; //Заблокировано.+ int64 balance = 3; //Текущий незаблокированный баланс.+ bool exchange_blocked = 11; //Заблокировано на бирже.+ string instrument_type = 16; //Тип инструмента.+}++//Баланс фьючерса.+message PositionsFutures {+ string figi = 1; //Figi-идентификатор фьючерса.+ int64 blocked = 2; //Заблокировано.+ int64 balance = 3; //Текущий незаблокированный баланс.+}++message BrokerReportRequest {+ oneof payload {+ GenerateBrokerReportRequest generate_broker_report_request = 1;+ GetBrokerReportRequest get_broker_report_request = 2;+ }+}++message BrokerReportResponse {+ oneof payload {+ GenerateBrokerReportResponse generate_broker_report_response = 1;+ GetBrokerReportResponse get_broker_report_response = 2;+ }+}++message GenerateBrokerReportRequest {+ string account_id = 1; //Идентификатор счёта клиента.+ google.protobuf.Timestamp from = 2; //Начало периода в часовом поясе UTC.+ google.protobuf.Timestamp to = 3; //Окончание периода в часовом поясе UTC.+}++message GenerateBrokerReportResponse {+ string task_id = 1; //Идентификатор задачи формирования брокерского отчёта.+}++message GetBrokerReportRequest {+ string task_id = 1; //Идентификатор задачи формирования брокерского отчёта.+ int32 page = 2; //Номер страницы отчета (начинается с 1), значение по умолчанию: 0.+}++message GetBrokerReportResponse {+ repeated BrokerReport broker_report = 1;+ int32 itemsCount = 2; //Количество записей в отчете.+ int32 pagesCount = 3; //Количество страниц с данными отчета (начинается с 0).+ int32 page = 4; //Текущая страница (начинается с 0).+}++message BrokerReport {+ string trade_id = 1;//Номер сделки.+ string order_id = 2; //Номер поручения.+ string figi = 3; //Figi-идентификатор инструмента.+ string execute_sign = 4; //Признак исполнения.+ google.protobuf.Timestamp trade_datetime = 5; //Дата и время заключения в часовом поясе UTC.+ string exchange = 6; //Торговая площадка.+ string class_code = 7; //Режим торгов.+ string direction = 8; //Вид сделки.+ string name = 9; //Сокращённое наименование актива.+ string ticker = 10; //Код актива.+ MoneyValue price = 11; //Цена за единицу.+ int64 quantity = 12; //Количество.+ MoneyValue order_amount = 13; //Сумма (без НКД).+ Quotation aci_value = 14; //НКД.+ MoneyValue total_order_amount = 15; //Сумма сделки.+ MoneyValue broker_commission = 16; //Комиссия брокера.+ MoneyValue exchange_commission = 17; //Комиссия биржи.+ MoneyValue exchange_clearing_commission = 18; //Комиссия клир. центра.+ Quotation repo_rate = 19; //Ставка РЕПО (%).+ string party = 20; //Контрагент/Брокер.+ google.protobuf.Timestamp clear_value_date = 21; //Дата расчётов в часовом поясе UTC.+ google.protobuf.Timestamp sec_value_date = 22; //Дата поставки в часовом поясе UTC.+ string broker_status = 23; //Статус брокера.+ string separate_agreement_type = 24; //Тип дог.+ string separate_agreement_number = 25; //Номер дог.+ string separate_agreement_date = 26; //Дата дог.+ string delivery_type = 27; //Тип расчёта по сделке.+}++//Статус запрашиваемых операций.+enum OperationState {+ OPERATION_STATE_UNSPECIFIED = 0; //Статус операции не определён+ OPERATION_STATE_EXECUTED = 1; //Исполнена.+ OPERATION_STATE_CANCELED = 2; //Отменена.+ OPERATION_STATE_PROGRESS = 3; //Исполняется.+}++//Тип операции.+enum OperationType {+ OPERATION_TYPE_UNSPECIFIED = 0; //Тип операции не определён.+ OPERATION_TYPE_INPUT = 1; //Пополнение брокерского счёта.+ OPERATION_TYPE_BOND_TAX = 2; //Удержание НДФЛ по купонам.+ OPERATION_TYPE_OUTPUT_SECURITIES = 3; //Вывод ЦБ.+ OPERATION_TYPE_OVERNIGHT = 4; //Доход по сделке РЕПО овернайт.+ OPERATION_TYPE_TAX = 5; //Удержание налога.+ OPERATION_TYPE_BOND_REPAYMENT_FULL = 6; //Полное погашение облигаций.+ OPERATION_TYPE_SELL_CARD = 7; //Продажа ЦБ с карты.+ OPERATION_TYPE_DIVIDEND_TAX = 8; //Удержание налога по дивидендам.+ OPERATION_TYPE_OUTPUT = 9; //Вывод денежных средств.+ OPERATION_TYPE_BOND_REPAYMENT = 10; //Частичное погашение облигаций.+ OPERATION_TYPE_TAX_CORRECTION = 11; //Корректировка налога.+ OPERATION_TYPE_SERVICE_FEE = 12; //Удержание комиссии за обслуживание брокерского счёта.+ OPERATION_TYPE_BENEFIT_TAX = 13; //Удержание налога за материальную выгоду.+ OPERATION_TYPE_MARGIN_FEE = 14; //Удержание комиссии за непокрытую позицию.+ OPERATION_TYPE_BUY = 15; //Покупка ЦБ.+ OPERATION_TYPE_BUY_CARD = 16; //Покупка ЦБ с карты.+ OPERATION_TYPE_INPUT_SECURITIES = 17; //Перевод ценных бумаг из другого депозитария.+ OPERATION_TYPE_SELL_MARGIN = 18; //Продажа в результате Margin-call.+ OPERATION_TYPE_BROKER_FEE = 19; //Удержание комиссии за операцию.+ OPERATION_TYPE_BUY_MARGIN = 20; //Покупка в результате Margin-call.+ OPERATION_TYPE_DIVIDEND = 21; //Выплата дивидендов.+ OPERATION_TYPE_SELL = 22; //Продажа ЦБ.+ OPERATION_TYPE_COUPON = 23; //Выплата купонов.+ OPERATION_TYPE_SUCCESS_FEE = 24; //Удержание комиссии SuccessFee.+ OPERATION_TYPE_DIVIDEND_TRANSFER = 25; //Передача дивидендного дохода.+ OPERATION_TYPE_ACCRUING_VARMARGIN = 26; //Зачисление вариационной маржи.+ OPERATION_TYPE_WRITING_OFF_VARMARGIN = 27; //Списание вариационной маржи.+ OPERATION_TYPE_DELIVERY_BUY = 28; //Покупка в рамках экспирации фьючерсного контракта.+ OPERATION_TYPE_DELIVERY_SELL = 29; //Продажа в рамках экспирации фьючерсного контракта.+ OPERATION_TYPE_TRACK_MFEE = 30; //Комиссия за управление по счёту автоследования.+ OPERATION_TYPE_TRACK_PFEE = 31; //Комиссия за результат по счёту автоследования.+ OPERATION_TYPE_TAX_PROGRESSIVE = 32; //Удержание налога по ставке 15%.+ OPERATION_TYPE_BOND_TAX_PROGRESSIVE = 33; //Удержание налога по купонам по ставке 15%.+ OPERATION_TYPE_DIVIDEND_TAX_PROGRESSIVE = 34; //Удержание налога по дивидендам по ставке 15%.+ OPERATION_TYPE_BENEFIT_TAX_PROGRESSIVE = 35; //Удержание налога за материальную выгоду по ставке 15%.+ OPERATION_TYPE_TAX_CORRECTION_PROGRESSIVE = 36; //Корректировка налога по ставке 15%.+ OPERATION_TYPE_TAX_REPO_PROGRESSIVE = 37; //Удержание налога за возмещение по сделкам РЕПО по ставке 15%.+ OPERATION_TYPE_TAX_REPO = 38; //Удержание налога за возмещение по сделкам РЕПО.+ OPERATION_TYPE_TAX_REPO_HOLD = 39; //Удержание налога по сделкам РЕПО.+ OPERATION_TYPE_TAX_REPO_REFUND = 40; //Возврат налога по сделкам РЕПО.+ OPERATION_TYPE_TAX_REPO_HOLD_PROGRESSIVE = 41; //Удержание налога по сделкам РЕПО по ставке 15%.+ OPERATION_TYPE_TAX_REPO_REFUND_PROGRESSIVE = 42; //Возврат налога по сделкам РЕПО по ставке 15%.+ OPERATION_TYPE_DIV_EXT = 43; //Выплата дивидендов на карту.+ OPERATION_TYPE_TAX_CORRECTION_COUPON = 44; //Корректировка налога по купонам.+}++message GetDividendsForeignIssuerRequest {+ oneof payload {+ GenerateDividendsForeignIssuerReportRequest generate_div_foreign_issuer_report = 1; //Объект запроса формирования отчёта.+ GetDividendsForeignIssuerReportRequest get_div_foreign_issuer_report = 2; //Объект запроса сформированного отчёта.+ }+}++message GetDividendsForeignIssuerResponse {+ oneof payload {+ GenerateDividendsForeignIssuerReportResponse generate_div_foreign_issuer_report_response = 1; //Объект результата задачи запуска формирования отчёта.+ GetDividendsForeignIssuerReportResponse div_foreign_issuer_report = 2; //Отчёт "Справка о доходах за пределами РФ".+ }+}++//Объект запроса формирования отчёта "Справка о доходах за пределами РФ".+message GenerateDividendsForeignIssuerReportRequest {+ string account_id = 1; //Идентификатор счёта клиента.+ google.protobuf.Timestamp from = 2; //Начало периода (по UTC).+ google.protobuf.Timestamp to = 3; //Окончание периода (по UTC).+}++// Объект запроса сформированного отчёта "Справка о доходах за пределами РФ".+message GetDividendsForeignIssuerReportRequest {+ string task_id = 1; //Идентификатор задачи формирования отчёта.+ int32 page = 2; //Номер страницы отчета (начинается с 0), значение по умолчанию: 0.+}++// Объект результата задачи запуска формирования отчёта "Справка о доходах за пределами РФ".+message GenerateDividendsForeignIssuerReportResponse {+ string task_id = 1; //Идентификатор задачи формирования отчёта.+}++message GetDividendsForeignIssuerReportResponse {+ repeated DividendsForeignIssuerReport dividends_foreign_issuer_report = 1;+ int32 itemsCount = 2; //Количество записей в отчете.+ int32 pagesCount = 3; //Количество страниц с данными отчета (начинается с 0).+ int32 page = 4; //Текущая страница (начинается с 0).+}++// Отчёт "Справка о доходах за пределами РФ".+message DividendsForeignIssuerReport {+ google.protobuf.Timestamp record_date = 1; //Дата фиксации реестра.+ google.protobuf.Timestamp payment_date = 2; //Дата выплаты.+ string security_name = 3; //Наименование ценной бумаги.+ string isin = 4; //ISIN-идентификатор ценной бумаги.+ string issuer_country = 5; //Страна эмитента. Для депозитарных расписок указывается страна эмитента базового актива.+ int64 quantity = 6; //Количество ценных бумаг.+ Quotation dividend = 7; //Выплаты на одну бумагу+ Quotation external_commission = 8; //Комиссия внешних платёжных агентов.+ Quotation dividend_gross = 9; //Сумма до удержания налога.+ Quotation tax = 10; //Сумма налога, удержанного агентом.+ Quotation dividend_amount = 11; //Итоговая сумма выплаты.+ string currency = 12; //Валюта.+}++//Запрос установки stream-соединения.+message PortfolioStreamRequest {+ repeated string accounts = 1; //Массив идентификаторов счётов пользователя+}++//Информация по позициям и доходностям портфелей.+message PortfolioStreamResponse {+ oneof payload {+ PortfolioSubscriptionResult subscriptions = 1; //Объект результата подписки.+ PortfolioResponse portfolio = 2; //Объект стриминга портфеля.+ Ping ping = 3; //Проверка активности стрима.+ }+}++//Объект результата подписки.+message PortfolioSubscriptionResult {+ repeated AccountSubscriptionStatus accounts = 1; //Массив счетов клиента.+}++//Счет клиента.+message AccountSubscriptionStatus {+ string account_id = 1; //Идентификатор счёта+ PortfolioSubscriptionStatus subscription_status = 6; //Результат подписки.+}++//Результат подписки.+enum PortfolioSubscriptionStatus {+ PORTFOLIO_SUBSCRIPTION_STATUS_UNSPECIFIED = 0; //Тип не определён.+ PORTFOLIO_SUBSCRIPTION_STATUS_SUCCESS = 1; //Успешно.+ PORTFOLIO_SUBSCRIPTION_STATUS_ACCOUNT_NOT_FOUND = 2; //Счёт не найден или недостаточно прав.+ PORTFOLIO_SUBSCRIPTION_STATUS_INTERNAL_ERROR = 3; //Произошла ошибка.+}++//Запрос списка операций по счёту с пагинацией.+message GetOperationsByCursorRequest {+ string account_id = 1; //Идентификатор счёта клиента.+ string instrument_id = 2; //Идентификатор инструмента (Figi инструмента или uid инструмента)+ google.protobuf.Timestamp from = 6; //Начало периода (по UTC).+ google.protobuf.Timestamp to = 7; //Окончание периода (по UTC).+ string cursor = 11; //Идентификатор элемента, с которого начать формировать ответ.+ int32 limit = 12; //Лимит количества операций.+ repeated OperationType operation_types = 13; //Тип операции. Принимает значение из списка OperationType.+ OperationState state = 14; //Статус запрашиваемых операций, возможные значения указаны в OperationState.+ bool without_commissions = 15; //Флаг возвращать ли комиссии, по умолчанию false+ bool without_trades = 16; //Флаг ответ без сделок.+ bool without_overnights = 17; //Флаг не показывать overnight операций.+}++//Список операций по счёту с пагинацией.+message GetOperationsByCursorResponse {+ bool has_next = 1; //Признак, есть ли следующий элемент.+ string next_cursor = 2; //Следующий курсор.+ repeated OperationItem items = 6; //Список операций.+}++//Данные об операции.+message OperationItem {+ string cursor = 1; //Курсор.+ string broker_account_id = 6; //Номер счета клиента.+ string id = 16; //Номер поручения.+ string parent_operation_id = 17; //Номер родительского поручения.+ string name = 18; //Название операции.+ google.protobuf.Timestamp date = 21; //Дата поручения.+ OperationType type = 22; //Тип операции.+ string description = 23; //Описание операции.+ OperationState state = 24; //Статус поручения.+ string instrument_uid = 31; //Уникальный идентификатор инструмента.+ string figi = 32; //Figi.+ string instrument_type = 33; //Тип инструмента.+ InstrumentType instrument_kind = 34; //Тип инструмента.+ MoneyValue payment = 41; //Сумма операции.+ MoneyValue price = 42; //Цена операции за 1 инструмент.+ MoneyValue commission = 43; //Комиссия.+ MoneyValue yield = 44; //Доходность.+ Quotation yield_relative = 45; //Относительная доходность.+ MoneyValue accrued_int = 46; //Накопленный купонный доход.+ int64 quantity = 51; //Количество единиц инструмента.+ int64 quantity_rest = 52; //Неисполненный остаток по сделке.+ int64 quantity_done = 53; //Исполненный остаток.+ google.protobuf.Timestamp cancel_date_time = 56; //Дата и время снятия заявки.+ string cancel_reason = 57; //Причина отмены операции.+ OperationItemTrades trades_info = 61; //Массив сделок.+}++//Массив с информацией о сделках.+message OperationItemTrades {+ int32 trades_size = 1;+ repeated OperationItemTrade trades = 6;+}++//Сделка по операции.+message OperationItemTrade {+ string num = 1; //Номер сделки+ google.protobuf.Timestamp date = 6; //Дата сделки+ int64 quantity = 11; //Количество в единицах.+ MoneyValue price = 16; //Цена.+ MoneyValue yield = 21; //Доходность.+ Quotation yield_relative = 22; //Относительная доходность.+}++//Тип инструмента.+enum InstrumentType {+ INSTRUMENT_TYPE_UNSPECIFIED = 0;+ INSTRUMENT_TYPE_BOND = 1; //Облигация.+ INSTRUMENT_TYPE_SHARE = 2; //Акция.+ INSTRUMENT_TYPE_CURRENCY = 3; //Валюта.+ INSTRUMENT_TYPE_ETF = 4; //Exchange-traded fund. Фонд.+ INSTRUMENT_TYPE_FUTURES = 5; //Фьючерс.+ INSTRUMENT_TYPE_SP = 6; //Структурная нота.+ INSTRUMENT_TYPE_OPTION = 7; //Опцион.+}
+ proto/invest/orders.proto view
@@ -0,0 +1,190 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "invest/common.proto";+import "google/protobuf/timestamp.proto";++service OrdersStreamService {+ //Stream сделок пользователя+ rpc TradesStream(TradesStreamRequest) returns (stream TradesStreamResponse);+}++service OrdersService {/* Сервис предназначен для работы с торговыми поручениями:</br> **1**.+ выставление;</br> **2**. отмена;</br> **3**. получение статуса;</br> **4**.+ расчёт полной стоимости;</br> **5**. получение списка заявок.*/+ //Метод выставления заявки.+ rpc PostOrder(PostOrderRequest) returns (PostOrderResponse);++ //Метод отмены биржевой заявки.+ rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);++ //Метод получения статуса торгового поручения.+ rpc GetOrderState(GetOrderStateRequest) returns (OrderState);++ //Метод получения списка активных заявок по счёту.+ rpc GetOrders(GetOrdersRequest) returns (GetOrdersResponse);++ //Метод изменения выставленной заявки.+ rpc ReplaceOrder(ReplaceOrderRequest) returns (PostOrderResponse);+}++//Запрос установки соединения.+message TradesStreamRequest {+ repeated string accounts = 1; //Идентификаторы счетов.+}++//Информация о торговых поручениях.+message TradesStreamResponse {+ oneof payload {+ OrderTrades order_trades = 1; //Информация об исполнении торгового поручения.+ Ping ping = 2; //Проверка активности стрима.+ }+}++//Информация об исполнении торгового поручения.+message OrderTrades {+ string order_id = 1; //Идентификатор торгового поручения.+ google.protobuf.Timestamp created_at = 2; //Дата и время создания сообщения в часовом поясе UTC.+ OrderDirection direction = 3; //Направление сделки.+ string figi = 4; //Figi-идентификатор инструмента.+ repeated OrderTrade trades = 5; //Массив сделок.+ string account_id = 6; //Идентификатор счёта.+}++//Информация о сделке.+message OrderTrade {+ google.protobuf.Timestamp date_time = 1; //Дата и время совершения сделки в часовом поясе UTC.+ Quotation price = 2; //Цена одного инструмента, по которой совершена сделка.+ int64 quantity = 3; //Количество лотов в сделке.+}++//Запрос выставления торгового поручения.+message PostOrderRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ int64 quantity = 2; //Количество лотов.+ Quotation price = 3; //Цена одного инструмента. Для получения стоимости лота требуется умножить на лотность инструмента. Игнорируется для рыночных поручений.+ OrderDirection direction = 4; //Направление операции.+ string account_id = 5; //Номер счёта.+ OrderType order_type = 6; //Тип заявки.+ string order_id = 7; //Идентификатор запроса выставления поручения для целей идемпотентности. Максимальная длина 36 символов.+}++//Информация о выставлении поручения.+message PostOrderResponse {+ string order_id = 1; //Идентификатор заявки.+ OrderExecutionReportStatus execution_report_status = 2; //Текущий статус заявки.+ int64 lots_requested = 3; //Запрошено лотов.+ int64 lots_executed = 4; //Исполнено лотов.++ MoneyValue initial_order_price = 5; //Начальная цена заявки. Произведение количества запрошенных лотов на цену.+ MoneyValue executed_order_price = 6; //Исполненная цена заявки. Произведение средней цены покупки на количество лотов.+ MoneyValue total_order_amount = 7; //Итоговая стоимость заявки, включающая все комиссии.+ MoneyValue initial_commission = 8; //Начальная комиссия. Комиссия рассчитанная при выставлении заявки.+ MoneyValue executed_commission = 9; //Фактическая комиссия по итогам исполнения заявки.+ MoneyValue aci_value = 10; //Значение НКД (накопленного купонного дохода) на дату. Подробнее: [НКД при выставлении торговых поручений](https://tinkoff.github.io/investAPI/head-orders#coupon)++ string figi = 11; // Figi-идентификатор инструмента.+ OrderDirection direction = 12; //Направление сделки.+ MoneyValue initial_security_price = 13; //Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ OrderType order_type = 14; //Тип заявки.+ string message = 15; //Дополнительные данные об исполнении заявки.+ Quotation initial_order_price_pt = 16; //Начальная цена заявки в пунктах (для фьючерсов).+}++//Запрос отмены торгового поручения.+message CancelOrderRequest {+ string account_id = 1; //Номер счёта.+ string order_id = 2; //Идентификатор заявки.+}++//Результат отмены торгового поручения.+message CancelOrderResponse {+ google.protobuf.Timestamp time = 1; //Дата и время отмены заявки в часовом поясе UTC.+}++//Запрос получения статуса торгового поручения.+message GetOrderStateRequest {+ string account_id = 1; //Номер счёта.+ string order_id = 2; //Идентификатор заявки.+}++//Запрос получения списка активных торговых поручений.+message GetOrdersRequest {+ string account_id = 1; //Номер счёта.+}++//Список активных торговых поручений.+message GetOrdersResponse {+ repeated OrderState orders = 1; //Массив активных заявок.+}++//Информация о торговом поручении.+message OrderState {+ string order_id = 1; //Идентификатор заявки.+ OrderExecutionReportStatus execution_report_status = 2; //Текущий статус заявки.+ int64 lots_requested = 3; //Запрошено лотов.+ int64 lots_executed = 4; //Исполнено лотов.+ MoneyValue initial_order_price = 5; //Начальная цена заявки. Произведение количества запрошенных лотов на цену.+ MoneyValue executed_order_price = 6; //Исполненная цена заявки. Произведение средней цены покупки на количество лотов.+ MoneyValue total_order_amount = 7; //Итоговая стоимость заявки, включающая все комиссии.+ MoneyValue average_position_price = 8; //Средняя цена позиции по сделке.+ MoneyValue initial_commission = 9; //Начальная комиссия. Комиссия, рассчитанная на момент подачи заявки.+ MoneyValue executed_commission = 10; //Фактическая комиссия по итогам исполнения заявки.+ string figi = 11; //Figi-идентификатор инструмента.+ OrderDirection direction = 12; //Направление заявки.+ MoneyValue initial_security_price = 13; //Начальная цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ repeated OrderStage stages = 14; //Стадии выполнения заявки.+ MoneyValue service_commission = 15; //Сервисная комиссия.+ string currency = 16; //Валюта заявки.+ OrderType order_type = 17; //Тип заявки.+ google.protobuf.Timestamp order_date = 18; //Дата и время выставления заявки в часовом поясе UTC.+}++//Сделки в рамках торгового поручения.+message OrderStage {+ MoneyValue price = 1; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента..+ int64 quantity = 2; //Количество лотов.+ string trade_id = 3; //Идентификатор торговой операции.+}++//Запрос изменения выставленной заявки.+message ReplaceOrderRequest {+ string account_id = 1; //Номер счета.+ string order_id = 6; //Идентификатор заявки на бирже.+ string idempotency_key = 7; //Новый идентификатор запроса выставления поручения для целей идемпотентности. Максимальная длина 36 символов. Перезатирает старый ключ.+ int64 quantity = 11; //Количество лотов.+ Quotation price = 12; //Цена за 1 инструмент.+ PriceType price_type = 13; //Тип цены.+}++//Направление операции.+enum OrderDirection {+ ORDER_DIRECTION_UNSPECIFIED = 0; //Значение не указано+ ORDER_DIRECTION_BUY = 1; //Покупка+ ORDER_DIRECTION_SELL = 2; //Продажа+}++//Тип заявки.+enum OrderType {+ ORDER_TYPE_UNSPECIFIED = 0; //Значение не указано+ ORDER_TYPE_LIMIT = 1; //Лимитная+ ORDER_TYPE_MARKET = 2; //Рыночная+}++//Текущий статус заявки (поручения)+enum OrderExecutionReportStatus {+ EXECUTION_REPORT_STATUS_UNSPECIFIED = 0;+ EXECUTION_REPORT_STATUS_FILL = 1; //Исполнена+ EXECUTION_REPORT_STATUS_REJECTED = 2; //Отклонена+ EXECUTION_REPORT_STATUS_CANCELLED = 3; //Отменена пользователем+ EXECUTION_REPORT_STATUS_NEW = 4; //Новая+ EXECUTION_REPORT_STATUS_PARTIALLYFILL = 5; //Частично исполнена+}++//Тип цены.+enum PriceType {+ PRICE_TYPE_UNSPECIFIED = 0; //Значение не определено.+ PRICE_TYPE_POINT = 1; //Цена в пунктах (только для фьючерсов и облигаций).+ PRICE_TYPE_CURRENCY = 2; //Цена в валюте расчётов по инструменту.+}
+ proto/invest/sandbox.proto view
@@ -0,0 +1,75 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "invest/common.proto";+import "invest/orders.proto";+import "invest/operations.proto";+import "invest/users.proto";++service SandboxService { //Сервис для работы с песочницей TINKOFF INVEST API++ //Метод регистрации счёта в песочнице.+ rpc OpenSandboxAccount(OpenSandboxAccountRequest) returns (OpenSandboxAccountResponse);++ //Метод получения счетов в песочнице.+ rpc GetSandboxAccounts(GetAccountsRequest) returns (GetAccountsResponse);++ //Метод закрытия счёта в песочнице.+ rpc CloseSandboxAccount(CloseSandboxAccountRequest) returns (CloseSandboxAccountResponse);++ //Метод выставления торгового поручения в песочнице.+ rpc PostSandboxOrder(PostOrderRequest) returns (PostOrderResponse);++ //Метод получения списка активных заявок по счёту в песочнице.+ rpc GetSandboxOrders(GetOrdersRequest) returns (GetOrdersResponse);++ //Метод отмены торгового поручения в песочнице.+ rpc CancelSandboxOrder(CancelOrderRequest) returns (CancelOrderResponse);++ //Метод получения статуса заявки в песочнице.+ rpc GetSandboxOrderState(GetOrderStateRequest) returns (OrderState);++ //Метод получения позиций по виртуальному счёту песочницы.+ rpc GetSandboxPositions(PositionsRequest) returns (PositionsResponse);++ //Метод получения операций в песочнице по номеру счёта.+ rpc GetSandboxOperations(OperationsRequest) returns (OperationsResponse);++ //Метод получения портфолио в песочнице.+ rpc GetSandboxPortfolio(PortfolioRequest) returns (PortfolioResponse);++ //Метод пополнения счёта в песочнице.+ rpc SandboxPayIn(SandboxPayInRequest) returns (SandboxPayInResponse);+}++//Запрос открытия счёта в песочнице.+message OpenSandboxAccountRequest {+ //пустой запрос+}++//Номер открытого счёта в песочнице.+message OpenSandboxAccountResponse {+ string account_id = 1; //Номер счёта+}++//Запрос закрытия счёта в песочнице.+message CloseSandboxAccountRequest {+ string account_id = 1; //Номер счёта+}++//Результат закрытия счёта в песочнице.+message CloseSandboxAccountResponse {+ //пустой ответ+}++//Запрос пополнения счёта в песочнице.+message SandboxPayInRequest {+ string account_id = 1; //Номер счёта+ MoneyValue amount = 2; //Сумма пополнения счёта в рублях+}++//Результат пополнения счёта, текущий баланс.+message SandboxPayInResponse {+ MoneyValue balance = 1; //Текущий баланс счёта+}
+ proto/invest/stoporders.proto view
@@ -0,0 +1,95 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";+import "invest/common.proto";++service StopOrdersService { /* Сервис предназначен для работы со стоп-заявками:</br> **1**.+ выставление;</br> **2**. отмена;</br> **3**. получение списка стоп-заявок.*/++ //Метод выставления стоп-заявки.+ rpc PostStopOrder(PostStopOrderRequest) returns (PostStopOrderResponse);++ //Метод получения списка активных стоп заявок по счёту.+ rpc GetStopOrders(GetStopOrdersRequest) returns (GetStopOrdersResponse);++ //Метод отмены стоп-заявки.+ rpc CancelStopOrder(CancelStopOrderRequest) returns (CancelStopOrderResponse);+}++//Запрос выставления стоп-заявки.+message PostStopOrderRequest {+ string figi = 1; //Figi-идентификатор инструмента.+ int64 quantity = 2; //Количество лотов.+ Quotation price = 3; //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ Quotation stop_price = 4; //Стоп-цена заявки за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ StopOrderDirection direction = 5; //Направление операции.+ string account_id = 6; //Номер счёта.+ StopOrderExpirationType expiration_type = 7; //Тип экспирации заявки.+ StopOrderType stop_order_type = 8; //Тип заявки.+ google.protobuf.Timestamp expire_date = 9; //Дата и время окончания действия стоп-заявки в часовом поясе UTC. **Для ExpirationType = GoodTillDate заполнение обязательно**.+}++//Результат выставления стоп-заявки.+message PostStopOrderResponse {+ string stop_order_id = 1; //Уникальный идентификатор стоп-заявки.+}++//Запрос получения списка активных стоп-заявок.+message GetStopOrdersRequest {+ string account_id = 1; //Идентификатор счёта клиента.+}++//Список активных стоп-заявок.+message GetStopOrdersResponse {+ repeated StopOrder stop_orders = 1; //Массив стоп-заявок по счёту.+}++//Запрос отмены выставленной стоп-заявки.+message CancelStopOrderRequest {+ string account_id = 1; //Идентификатор счёта клиента.+ string stop_order_id = 2; //Уникальный идентификатор стоп-заявки.+}++//Результат отмены выставленной стоп-заявки.+message CancelStopOrderResponse {+ google.protobuf.Timestamp time = 1; //Время отмены заявки в часовом поясе UTC.+}++//Информация о стоп-заявке.+message StopOrder {+ string stop_order_id = 1; //Идентификатор-идентификатор стоп-заявки.+ int64 lots_requested = 2; //Запрошено лотов.+ string figi = 3; //Figi-идентификатор инструмента.+ StopOrderDirection direction = 4; //Направление операции.+ string currency = 5; //Валюта стоп-заявки.+ StopOrderType order_type = 6; //Тип стоп-заявки.+ google.protobuf.Timestamp create_date = 7; //Дата и время выставления заявки в часовом поясе UTC.+ google.protobuf.Timestamp activation_date_time = 8; //Дата и время конвертации стоп-заявки в биржевую в часовом поясе UTC.+ google.protobuf.Timestamp expiration_time = 9; //Дата и время снятия заявки в часовом поясе UTC.+ MoneyValue price = 10; //Цена заявки за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+ MoneyValue stop_price = 11; //Цена активации стоп-заявки за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.+}++//Направление сделки стоп-заявки.+enum StopOrderDirection {+ STOP_ORDER_DIRECTION_UNSPECIFIED = 0; //Значение не указано.+ STOP_ORDER_DIRECTION_BUY = 1; //Покупка.+ STOP_ORDER_DIRECTION_SELL = 2; //Продажа.+}++//Тип экспирации стоп-заявке.+enum StopOrderExpirationType {+ STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED = 0; //Значение не указано.+ STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL = 1; //Действительно до отмены.+ STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE = 2; //Действительно до даты снятия.+}++//Тип стоп-заявки.+enum StopOrderType {+ STOP_ORDER_TYPE_UNSPECIFIED = 0; //Значение не указано.+ STOP_ORDER_TYPE_TAKE_PROFIT = 1; //Take-profit заявка.+ STOP_ORDER_TYPE_STOP_LOSS = 2; //Stop-loss заявка.+ STOP_ORDER_TYPE_STOP_LIMIT = 3; //Stop-limit заявка.+}
+ proto/invest/users.proto view
@@ -0,0 +1,140 @@+syntax = "proto3";++package tinkoff.public.invest.api.contract.v1;++import "google/protobuf/timestamp.proto";+import "invest/common.proto";++service UsersService { /*Сервис предназначен для получения: </br> **1**.+ списка счетов пользователя; </br> **2**. маржинальных показателей по счёту.*/++ //Метод получения счетов пользователя.+ rpc GetAccounts (GetAccountsRequest) returns (GetAccountsResponse);++ //Расчёт маржинальных показателей по счёту.+ rpc GetMarginAttributes (GetMarginAttributesRequest) returns (GetMarginAttributesResponse);++ //Запрос тарифа пользователя.+ rpc GetUserTariff (GetUserTariffRequest) returns (GetUserTariffResponse);++ //Метод получения информации о пользователе.+ rpc GetInfo (GetInfoRequest) returns (GetInfoResponse);+}++//Запрос получения счетов пользователя.+message GetAccountsRequest {}++//Список счетов пользователя.+message GetAccountsResponse {+ // Массив счетов клиента.+ repeated Account accounts = 1;+}++//Информация о счёте.+message Account {++ // Идентификатор счёта.+ string id = 1;++ // Тип счёта.+ AccountType type = 2;++ // Название счёта.+ string name = 3;++ // Статус счёта.+ AccountStatus status = 4;++ // Дата открытия счёта в часовом поясе UTC.+ google.protobuf.Timestamp opened_date = 5;++ // Дата закрытия счёта в часовом поясе UTC.+ google.protobuf.Timestamp closed_date = 6;++ // Уровень доступа к текущему счёту (определяется токеном).+ AccessLevel access_level = 7;+}++//Тип счёта.+enum AccountType {+ ACCOUNT_TYPE_UNSPECIFIED = 0; //Тип аккаунта не определён.+ ACCOUNT_TYPE_TINKOFF = 1; //Брокерский счёт Тинькофф.+ ACCOUNT_TYPE_TINKOFF_IIS = 2; //ИИС счёт.+ ACCOUNT_TYPE_INVEST_BOX = 3; //Инвесткопилка.+}++//Статус счёта.+enum AccountStatus {+ ACCOUNT_STATUS_UNSPECIFIED = 0; //Статус счёта не определён.+ ACCOUNT_STATUS_NEW = 1; //Новый, в процессе открытия.+ ACCOUNT_STATUS_OPEN = 2; //Открытый и активный счёт.+ ACCOUNT_STATUS_CLOSED = 3; //Закрытый счёт.+}++//Запрос маржинальных показателей по счёту+message GetMarginAttributesRequest {++ // Идентификатор счёта пользователя.+ string account_id = 1;+}++//Маржинальные показатели по счёту.+message GetMarginAttributesResponse {++ // Ликвидная стоимость портфеля. Подробнее: [что такое ликвидный портфель?](https://help.tinkoff.ru/margin-trade/short/liquid-portfolio/).+ MoneyValue liquid_portfolio = 1;++ // Начальная маржа — начальное обеспечение для совершения новой сделки. Подробнее: [начальная и минимальная маржа](https://help.tinkoff.ru/margin-trade/short/initial-and-maintenance-margin/).+ MoneyValue starting_margin = 2;++ // Минимальная маржа — это минимальное обеспечение для поддержания позиции, которую вы уже открыли. Подробнее: [начальная и минимальная маржа](https://help.tinkoff.ru/margin-trade/short/initial-and-maintenance-margin/).+ MoneyValue minimal_margin = 3;++ // Уровень достаточности средств. Соотношение стоимости ликвидного портфеля к начальной марже.+ Quotation funds_sufficiency_level = 4;++ // Объем недостающих средств. Разница между стартовой маржой и ликвидной стоимости портфеля.+ MoneyValue amount_of_missing_funds = 5;+}++//Запрос текущих лимитов пользователя.+message GetUserTariffRequest {+}++//Текущие лимиты пользователя.+message GetUserTariffResponse {+ repeated UnaryLimit unary_limits = 1; //Массив лимитов пользователя по unary-запросам+ repeated StreamLimit stream_limits = 2; //Массив лимитов пользователей для stream-соединений+}++//Лимит unary-методов.+message UnaryLimit {+ int32 limit_per_minute = 1; //Количество unary-запросов в минуту+ repeated string methods = 2; //Названия методов+}++//Лимит stream-соединений.+message StreamLimit {+ int32 limit = 1; //Максимальное количество stream-соединений+ repeated string streams = 2; //Названия stream-методов+}++//Запрос информации о пользователе.+message GetInfoRequest {+}++//Информация о пользователе.+message GetInfoResponse {+ bool prem_status = 1; //Признак премиум клиента.+ bool qual_status = 2; //Признак квалифицированного инвестора.+ repeated string qualified_for_work_with = 3; //Набор требующих тестирования инструментов и возможностей, с которыми может работать пользователь. [Подробнее](https://tinkoff.github.io/investAPI/faq_users/).+ string tariff = 4; //Наименование тарифа пользователя.+}++//Уровень доступа к счёту.+enum AccessLevel {+ ACCOUNT_ACCESS_LEVEL_UNSPECIFIED = 0; //Уровень доступа не определён.+ ACCOUNT_ACCESS_LEVEL_FULL_ACCESS = 1; //Полный доступ к счёту.+ ACCOUNT_ACCESS_LEVEL_READ_ONLY = 2; //Доступ с уровнем прав "только чтение".+ ACCOUNT_ACCESS_LEVEL_NO_ACCESS = 3; //Доступ отсутствует.+}
+ src/Invest/Client.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE TupleSections #-}+module Invest.Client(+ ClientConfig(..)+ , simpleClientConfig+ , initGrpcClient+ , (&), (.~), (^.)+ , defMessage+ , runGrpc+ , (<#>), (#>>), (#>)+ , runExceptT+ , GrpcIO+ , GrpcClient+ , liftIO+) where++import Control.Exception (throwIO)+import Control.Lens ((&), (.~), (^.))+import Control.Monad.Except (ExceptT, MonadIO (liftIO), lift,+ runExceptT, throwError)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as BC (pack)+import Data.Maybe (maybeToList)+import Data.ProtoLens.Message (defMessage)+import Data.Text as T (pack)+import Invest.Client.Errors (SDKError (..))+import Invest.Client.Helpers+import Network.GRPC.Client (uncompressed)+import Network.GRPC.Client.Helpers (GrpcClient,+ GrpcClientConfig (_grpcClientConfigCompression, _grpcClientConfigHeaders),+ grpcClientConfigSimple,+ setupGrpcClient)+import Network.HTTP2.Client (ClientIO, runClientIO)++data ClientConfig = ClientConfig { token :: String, appName :: Maybe String }++simpleClientConfig :: String -> ClientConfig+simpleClientConfig token = ClientConfig { token = token, appName = Nothing }++initGrpcClient :: ClientConfig -> GrpcIO GrpcClient+initGrpcClient cf = lift $ runClientIO (setupGrpcClient . prepareGrpcConfig $ cf) >>= \case+ Right client -> pure client+ Left err -> throwError . userError . show $ err++prepareGrpcConfig :: ClientConfig -> GrpcClientConfig+prepareGrpcConfig config = (grpcClientConfigSimple "invest-public-api.tinkoff.ru" 443 True) {+ _grpcClientConfigHeaders = apiHeaders config,+ _grpcClientConfigCompression = uncompressed+}++apiHeaders :: ClientConfig -> [(ByteString, ByteString)]+apiHeaders config =+ maybeToList appNameH ++ [tokenH]+ where+ tokenH = (BC.pack "Authorization", BC.pack ("Bearer " ++ token config))+ appNameH = (BC.pack "x-app-name",) . BC.pack <$> appName config+
+ src/Invest/Client/Errors.hs view
@@ -0,0 +1,13 @@+module Invest.Client.Errors (+ SDKError(..)+) where++import Control.Exception (Exception)+import Data.Text (Text)++data SDKError =+ ClientSetupError Text+ | GrpcError Text+ deriving Show++instance Exception SDKError
+ src/Invest/Client/Helpers.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE TupleSections #-}+module Invest.Client.Helpers (+ runGrpc+ , runUnary+ , runUnary_+ , GrpcIO+ , GrpcClient+ , (<#>), (#>>), (#>)+ , ChanFlow(..)+) where++import Control.Exception (Exception, IOException,+ SomeException (SomeException))+import Control.Monad.Except (ExceptT, lift, runExceptT,+ throwError)+import Data.Text as T (Text, pack)+import Network.GRPC.Client (RawReply)+import Network.GRPC.Client.Helpers (GrpcClient, rawUnary)+import Network.HTTP2.Client (ClientIO, TooMuchConcurrency,+ runClientIO)++type GrpcIO a = ExceptT IOException IO a++type GrpcContext a = (GrpcClient, a)++data ChanFlow = Next | Break++runGrpc :: ClientIO (Either TooMuchConcurrency (RawReply a)) -> GrpcIO a+runGrpc f = lift $ runExceptT f >>= \case+ Right (Right (Right (_, _, Right res))) -> pure res+ Right (Right (Right (_, _, Left err))) -> throwError $ userError err+ Right (Right (Left err)) -> throwError . userError . show $ err+ Right (Left err) -> throwError . userError . show $ err+ Left err -> throwError . userError . show $ err++runUnary rpc client req = runGrpc $ rawUnary rpc client req++runUnary_ m rpc gc req = fmap m (runUnary rpc gc req)++(<#>) :: GrpcIO GrpcClient -> (GrpcClient -> GrpcIO a) -> GrpcIO (GrpcContext a)+(<#>) clIO f = clIO >>= \client -> (client,) <$> f client++(#>>) :: GrpcIO (GrpcContext a) -> (GrpcClient -> a -> GrpcIO b) -> GrpcIO (GrpcContext b)+(#>>) ctx f = ctx >>= \(cl, a) -> (cl,) <$> f cl a++(#>) :: GrpcIO (GrpcContext a) -> (a -> GrpcIO b) -> GrpcIO b+(#>) ctx f = ctx >>= \(_, val) -> f val
+ src/Invest/Service/Instruments.hs view
@@ -0,0 +1,105 @@+module Invest.Service.Instruments(+ tradingSchedules,+ bondBy,+ bonds,+ getBondCoupons,+ currencyBy,+ currencies,+ etfBy,+ etfs,+ futureBy,+ futures,+ shareBy,+ shares,+ getAccruedInterests,+ getFuturesMargin,+ getInstrumentBy,+ getDividends,+ getAssetBy,+ getAssets,+ getFavorites,+ editFavorites,+ getCountries,+ findInstrument,+ getBrands,+ getBrandBy+) where++import Control.Lens ((^.))+import Data.ProtoLens.Message (defMessage)+import Invest.Client.Helpers (GrpcIO, runUnary, runUnary_, GrpcClient)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Invest.Instruments+import qualified Proto.Invest.Instruments_Fields as I++tradingSchedules :: GrpcClient -> TradingSchedulesRequest -> GrpcIO [TradingSchedule]+tradingSchedules = runUnary_ (^. I.exchanges) (RPC :: RPC InstrumentsService "tradingSchedules")++bondBy :: GrpcClient -> InstrumentRequest -> GrpcIO Bond+bondBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "bondBy")++bonds :: GrpcClient -> InstrumentsRequest -> GrpcIO [Bond]+bonds = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "bonds")++getBondCoupons :: GrpcClient -> GetBondCouponsRequest -> GrpcIO [Coupon]+getBondCoupons = runUnary_ (^. I.events) (RPC :: RPC InstrumentsService "getBondCoupons")++currencyBy :: GrpcClient -> InstrumentRequest -> GrpcIO Currency+currencyBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "currencyBy")++currencies :: GrpcClient -> InstrumentsRequest -> GrpcIO [Currency]+currencies = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "currencies")++etfBy :: GrpcClient -> InstrumentRequest -> GrpcIO Etf+etfBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "etfBy")++etfs :: GrpcClient -> InstrumentsRequest -> GrpcIO [Etf]+etfs = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "etfs")++futureBy :: GrpcClient -> InstrumentRequest -> GrpcIO Future+futureBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "futureBy")++futures :: GrpcClient -> InstrumentsRequest -> GrpcIO [Future]+futures = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "futures")++shareBy :: GrpcClient -> InstrumentRequest -> GrpcIO Share+shareBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "shareBy")++shares :: GrpcClient -> InstrumentsRequest -> GrpcIO [Share]+shares = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "shares")++getAccruedInterests :: GrpcClient -> GetAccruedInterestsRequest -> GrpcIO [AccruedInterest]+getAccruedInterests = runUnary_ (^. I.accruedInterests) (RPC :: RPC InstrumentsService "getAccruedInterests")++getFuturesMargin :: GrpcClient -> GetFuturesMarginRequest -> GrpcIO GetFuturesMarginResponse+getFuturesMargin = runUnary (RPC :: RPC InstrumentsService "getFuturesMargin")++getInstrumentBy :: GrpcClient -> InstrumentRequest -> GrpcIO Instrument+getInstrumentBy = runUnary_ (^. I.instrument) (RPC :: RPC InstrumentsService "getInstrumentBy")++getDividends :: GrpcClient -> GetDividendsRequest -> GrpcIO [Dividend]+getDividends = runUnary_ (^. I.dividends) (RPC :: RPC InstrumentsService "getDividends")++getAssetBy :: GrpcClient -> AssetRequest -> GrpcIO AssetFull+getAssetBy = runUnary_ (^. I.asset) (RPC :: RPC InstrumentsService "getAssetBy")++getAssets :: GrpcClient -> GrpcIO [Asset]+getAssets gc = runUnary_ (^. I.assets) (RPC :: RPC InstrumentsService "getAssets") gc defMessage++getFavorites :: GrpcClient -> GrpcIO[FavoriteInstrument]+getFavorites gc = runUnary_ (^. I.favoriteInstruments) (RPC :: RPC InstrumentsService "getFavorites") gc defMessage++editFavorites :: GrpcClient -> EditFavoritesRequest -> GrpcIO [FavoriteInstrument]+editFavorites = runUnary_ (^. I.favoriteInstruments) (RPC :: RPC InstrumentsService "editFavorites")++getCountries :: GrpcClient -> GrpcIO [CountryResponse]+getCountries gc = runUnary_ (^. I.countries) (RPC :: RPC InstrumentsService "getCountries") gc defMessage++findInstrument :: GrpcClient -> FindInstrumentRequest -> GrpcIO [InstrumentShort]+findInstrument = runUnary_ (^. I.instruments) (RPC :: RPC InstrumentsService "findInstrument")++getBrands :: GrpcClient -> GrpcIO [Brand]+getBrands gc = runUnary_ (^. I.brands) (RPC :: RPC InstrumentsService "getBrands") gc defMessage++getBrandBy :: GrpcClient -> GetBrandRequest -> GrpcIO Brand+getBrandBy = runUnary (RPC :: RPC InstrumentsService "getBrandBy")
+ src/Invest/Service/Internal/MarketDataStream.hs view
@@ -0,0 +1,99 @@+module Invest.Service.Internal.MarketDataStream(+ requestId,+ responseId,+ producedBy,+ (<@), (@>),+ MDStream,+ MDStreamMonad,+ STRequest(..),+ STResponse(..)+) where++import Control.Concurrent (MVar, forkIO)+import Control.Concurrent as GHC.Conc.Sync (ThreadId)+import Control.Concurrent.Chan (Chan, readChan, writeChan)+import Control.Exception (SomeException)+import Control.Lens ((&), (.~), (^.))+import Control.Monad (void)+import Control.Monad.Cont (liftIO)+import Control.Monad.Except (forever, throwError)+import Data.Int (Int32)+import Data.Text as T (Text)+import Invest.Client+import Invest.Client.Helpers (ChanFlow (..))+import Proto.Invest.Marketdata+import Proto.Invest.Marketdata_Fields++data STRequest = PostRequest MarketDataRequest | Shutdown+data STResponse = Message MarketDataResponse | StreamStopped | StreamError SomeException++type Closed = MVar ()++type MDStream = (Closed, Chan STRequest, Chan STResponse)++type MDStreamMonad = IO MDStream++data AppFault = BadFault SomeException | SomeOtherAppProblem deriving Show++data SubId =+ Candles { candlesInsts :: [(Text, SubscriptionInterval)] } -- (figi, interval)+ | OrderBook { orderInsts :: [(Text, Int32)] } -- (figi, depth)+ | Trades { figis :: [Text] }+ | Info { figis :: [Text] }+ | LastPrice { figis :: [Text] }+ | Unknown+ deriving (Eq, Show)++(<@) :: MDStream -> STRequest -> IO ()+(<@) (_, requests, _) = writeChan requests++(@>) :: MDStream -> (MarketDataResponse -> IO ChanFlow) -> IO ThreadId+(@>) (_, _, responses) callback = forkIO . void $ pollChan responses callback++pollChan :: Chan STResponse -> (MarketDataResponse -> IO ChanFlow) -> IO ()+pollChan chan callback = runExceptT (forever $ (liftIO . readChan $ chan) >>= \case+ Message response -> do+ res <- runExceptT $ liftIO (callback response) >>= \case+ Next -> return ()+ Break -> throwError SomeOtherAppProblem+ case res of+ Left err -> throwError err+ Right x0 -> return ()+ StreamStopped -> throwError SomeOtherAppProblem+ StreamError err -> throwError (BadFault err)+ ) >>= either handleFault pure++handleFault :: AppFault -> IO ()+handleFault _ = return () -- ignore interruption message++requestId :: MarketDataRequest -> SubId+requestId request = case request ^. maybe'payload of+ Just (MarketDataRequest'SubscribeInfoRequest r) -> Info { figis = map (^. figi) $ r ^. instruments }+ Just (MarketDataRequest'SubscribeTradesRequest r) -> Trades { figis = map (^. figi) $ r ^. instruments }+ Just (MarketDataRequest'SubscribeLastPriceRequest r) -> LastPrice { figis = map (^. figi) $ r ^. instruments }+ Just (MarketDataRequest'SubscribeOrderBookRequest r) ->+ OrderBook { orderInsts = map (\i -> (i ^. figi, i ^. depth)) $ r ^. instruments }+ Just (MarketDataRequest'SubscribeCandlesRequest r) ->+ Candles { candlesInsts = map (\i -> (i ^. figi, i ^. interval)) $ r ^. instruments }+ Just (MarketDataRequest'GetMySubscriptions r) -> Unknown -- What is the response?+ Nothing -> Unknown++responseId :: MarketDataResponse -> SubId+responseId response = case response ^.maybe'payload of+ Just (MarketDataResponse'SubscribeCandlesResponse r) ->+ Candles { candlesInsts = map (\i -> (i ^. figi, i ^. interval)) $ r ^. candlesSubscriptions }+ Just (MarketDataResponse'SubscribeOrderBookResponse r) ->+ OrderBook { orderInsts = map (\i -> (i ^. figi, i ^. depth)) $ r ^. orderBookSubscriptions }+ Just (MarketDataResponse'SubscribeTradesResponse r) -> Trades { figis = map (^. figi) $ r ^. tradeSubscriptions }+ Just (MarketDataResponse'SubscribeInfoResponse r) -> Info { figis = map (^. figi) $ r ^. infoSubscriptions }+ Just (MarketDataResponse'SubscribeLastPriceResponse r) -> LastPrice { figis = map (^. figi) $ r ^. lastPriceSubscriptions }+ Just (MarketDataResponse'Candle r) -> Candles { candlesInsts = [(r ^. figi, r ^. interval)] }+ Just (MarketDataResponse'Trade r) -> Trades { figis = [r ^. figi] }+ Just (MarketDataResponse'Orderbook r) -> OrderBook { orderInsts = [(r ^. figi, r ^. depth)] }+ Just (MarketDataResponse'TradingStatus r) -> Info { figis = [r ^. figi] }+ Just (MarketDataResponse'LastPrice r) -> LastPrice { figis = [r ^. figi] }+ Just (MarketDataResponse'Ping r) -> Unknown+ Nothing -> Unknown++producedBy :: MarketDataResponse -> MarketDataRequest -> Bool+producedBy resp req = responseId resp == requestId req
+ src/Invest/Service/MarketData.hs view
@@ -0,0 +1,29 @@+module Invest.Service.MarketData(+ getCandles,+ getLastPrices,+ getOrderBook,+ getTradingStatus,+ getLastTrades+) where++import Control.Lens ((^.))+import Invest.Client.Helpers (GrpcClient, GrpcIO, runUnary,+ runUnary_)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Invest.Marketdata+import qualified Proto.Invest.Marketdata_Fields as MD++getCandles :: GrpcClient -> GetCandlesRequest -> GrpcIO [HistoricCandle]+getCandles = runUnary_ (^. MD.candles) (RPC :: RPC MarketDataService "getCandles")++getLastPrices :: GrpcClient -> GetLastPricesRequest -> GrpcIO [LastPrice]+getLastPrices = runUnary_ (^. MD.lastPrices) (RPC :: RPC MarketDataService "getLastPrices")++getOrderBook :: GrpcClient -> GetOrderBookRequest -> GrpcIO GetOrderBookResponse+getOrderBook = runUnary (RPC :: RPC MarketDataService "getOrderBook")++getTradingStatus :: GrpcClient -> GetTradingStatusRequest -> GrpcIO GetTradingStatusResponse+getTradingStatus = runUnary (RPC :: RPC MarketDataService "getTradingStatus")++getLastTrades :: GrpcClient -> GetLastTradesRequest -> GrpcIO [Trade]+getLastTrades = runUnary_ (^. MD.trades) (RPC :: RPC MarketDataService "getLastTrades")
+ src/Invest/Service/MarketDataStream.hs view
@@ -0,0 +1,160 @@+{-# OPTIONS_GHC -Wno-incomplete-patterns #-}+module Invest.Service.MarketDataStream(+ marketDataStream,+ subscribeOrderBook,+ unsubscribeOrderBook,+ close,+ wait+) where++import Control.Concurrent (forkIO, newChan,+ newEmptyMVar,+ putMVar, readChan,+ takeMVar, writeChan)+import Control.Concurrent.Async (async, link)+import Control.Concurrent.Chan (newChan, readChan,+ writeChan)+import Control.Error+import Control.Exception ()+import Control.Exception.Base (IOException)+import Control.Lens ((&), (.~), (^.))+import Control.Monad+import Control.Monad.Cont (MonadIO (..))+import Control.Monad.Except (MonadIO (..))+import Control.Monad.IO.Class (MonadIO (..))+import Control.Monad.Trans (MonadIO (..))+import Data.Int (Int32)+import Data.ProtoLens.Message (defMessage)+import Data.ProtoLens.Service.Types ()+import Data.Text as T (pack)+import Invest.Client.Helpers (ChanFlow (Next),+ GrpcClient)+import Invest.Service.Internal.MarketDataStream (MDStream,+ MDStreamMonad,+ STRequest (..),+ STResponse (..),+ producedBy, (<@),+ (@>))+import Network.GRPC.Client (CompressMode (Compressed),+ IncomingEvent (Headers, Invalid, RecvMessage, Trailers),+ OutgoingEvent (Finalize, SendMessage))+import Network.GRPC.Client.Helpers (GrpcClient,+ rawGeneralStream)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Network.HTTP2.Client (runClientIO)+import Proto.Invest.Marketdata+import qualified Proto.Invest.Marketdata_Fields as MD++printIO :: (MonadIO m, Show a) => a -> m ()+printIO = liftIO . print++runAsync :: IO a -> IO ()+runAsync f = async f >>= link++marketDataStream :: GrpcClient -> MDStreamMonad+marketDataStream gc = liftIO $ do+ closed <- newEmptyMVar+ let close = liftIO . putMVar closed $ ()+ let genLoopInput chan = \case+ Headers hdrs -> printIO hdrs >> pure chan+ Trailers trls -> (liftIO . writeChan chan $ StreamStopped) >> close >> pure chan+ Invalid err -> (liftIO . writeChan chan $ StreamError err) >> close >> pure chan+ RecvMessage msg -> (liftIO . runAsync . writeChan chan $ Message msg) >> pure chan+ let genLoopOutput chan = (liftIO . readChan $ chan) >>= \case+ PostRequest msg -> pure (chan, SendMessage Compressed msg)+ Shutdown -> pure (chan, Finalize)++ inputChannel <- newChan+ outputChannel <- newChan++ void . forkIO . void . runClientIO $+ rawGeneralStream (RPC :: RPC MarketDataStreamService "marketDataStream") gc inputChannel genLoopInput outputChannel genLoopOutput+ return (closed, outputChannel, inputChannel)++close :: MDStream -> IO ()+close stream = stream <@ Shutdown++wait :: MDStream -> IO ()+wait (closed, _, _) = takeMVar closed++subscribeMarketData :: MDStream -> MarketDataRequest -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeMarketData stream request callback = do+ stream @> \response -> if response `producedBy` request+ then callback response+ else pure Next+ stream <@ PostRequest request++-- OrderBook --+subscribeOrderBook :: MDStream -> String -> Int32 -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeOrderBook stream figi depth =+ subscribeMarketData stream (orderBookRequest [(figi, depth)] SUBSCRIPTION_ACTION_SUBSCRIBE)++unsubscribeOrderBook :: MDStream -> String -> Int32 -> IO ()+unsubscribeOrderBook stream figi depth =+ stream <@ PostRequest (orderBookRequest [(figi, depth)] SUBSCRIPTION_ACTION_UNSUBSCRIBE)++orderBookRequest :: [(String, Int32)] -> SubscriptionAction -> MarketDataRequest+orderBookRequest insts action = defMessage &+ MD.subscribeOrderBookRequest .~ (defMessage &+ MD.subscriptionAction .~ action &+ MD.instruments .~ map (\(figi, depth) -> defMessage & MD.figi .~ T.pack figi & MD.depth .~ depth) insts+ )++-- Candles --+subscribeCandles :: MDStream -> String -> SubscriptionInterval -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeCandles stream figi interval =+ subscribeMarketData stream (candlesRequest [(figi, interval)] SUBSCRIPTION_ACTION_SUBSCRIBE)++unsubscribeCandles :: MDStream -> String -> SubscriptionInterval -> IO ()+unsubscribeCandles stream figi interval =+ stream <@ PostRequest (candlesRequest [(figi, interval)] SUBSCRIPTION_ACTION_UNSUBSCRIBE)++candlesRequest :: [(String, SubscriptionInterval)] -> SubscriptionAction -> MarketDataRequest+candlesRequest insts action = defMessage &+ MD.subscribeCandlesRequest .~ (defMessage &+ MD.subscriptionAction .~ action &+ MD.instruments .~ map (\(figi, interval) -> defMessage & MD.figi .~ T.pack figi & MD.interval .~ interval) insts+ )++-- Trades --+subscribeTrades :: MDStream -> String -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeTrades stream figi =+ subscribeMarketData stream (tradesRequest [figi] SUBSCRIPTION_ACTION_SUBSCRIBE)++unsubscribeTrades :: MDStream -> String -> IO ()+unsubscribeTrades stream figi = stream <@ PostRequest (tradesRequest [figi] SUBSCRIPTION_ACTION_UNSUBSCRIBE)++tradesRequest :: [String] -> SubscriptionAction -> MarketDataRequest+tradesRequest figis action = defMessage &+ MD.subscribeTradesRequest .~ (defMessage &+ MD.subscriptionAction .~ action &+ MD.instruments .~ map (\figi -> defMessage & MD.figi .~ T.pack figi) figis+ )++-- Info --+subscribeInfo :: MDStream -> String -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeInfo stream figi = subscribeMarketData stream (infoRequest [figi] SUBSCRIPTION_ACTION_SUBSCRIBE)++unsubscribeInfo :: MDStream -> String -> IO ()+unsubscribeInfo stream figi = stream <@ PostRequest (infoRequest [figi] SUBSCRIPTION_ACTION_UNSUBSCRIBE)++infoRequest :: [String] -> SubscriptionAction -> MarketDataRequest+infoRequest figis action = defMessage &+ MD.subscribeInfoRequest .~ (defMessage &+ MD.subscriptionAction .~ action &+ MD.instruments .~ map (\figi -> defMessage & MD.figi .~ T.pack figi) figis+ )++-- Last Price --+subscribeLastPrice :: MDStream -> String -> (MarketDataResponse -> IO ChanFlow) -> IO ()+subscribeLastPrice stream figi = subscribeMarketData stream (lastPriceRequest [figi] SUBSCRIPTION_ACTION_SUBSCRIBE)++unsubscribeLastPrice :: MDStream -> String -> IO ()+unsubscribeLastPrice stream figi = stream <@ PostRequest (lastPriceRequest [figi] SUBSCRIPTION_ACTION_UNSUBSCRIBE)++lastPriceRequest :: [String] -> SubscriptionAction -> MarketDataRequest+lastPriceRequest figis action = defMessage &+ MD.subscribeLastPriceRequest .~ (defMessage &+ MD.subscriptionAction .~ action &+ MD.instruments .~ map (\figi -> defMessage & MD.figi .~ T.pack figi) figis+ )
+ src/Invest/Service/Operations.hs view
@@ -0,0 +1,37 @@+module Invest.Service.Operations(+ getOperations,+ getPortfolio,+ getPositions,+ getWithdrawLimits,+ getBrokerReport,+ getDividendsForeignIssuer+) where++import Control.Lens ((^.))+import Data.ProtoLens.Message (defMessage)+import Invest.Client.Helpers (GrpcClient, GrpcIO, runUnary,+ runUnary_)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Invest.Operations+import qualified Proto.Invest.Operations_Fields as O++getOperations :: GrpcClient -> OperationsRequest -> GrpcIO [Operation]+getOperations = runUnary_ (^. O.operations) (RPC :: RPC OperationsService "getOperations")++getPortfolio :: GrpcClient -> PortfolioRequest -> GrpcIO PortfolioResponse+getPortfolio = runUnary (RPC :: RPC OperationsService "getPortfolio")++getPositions :: GrpcClient -> PositionsRequest -> GrpcIO PositionsResponse+getPositions = runUnary (RPC :: RPC OperationsService "getPositions")++getWithdrawLimits :: GrpcClient -> WithdrawLimitsRequest -> GrpcIO WithdrawLimitsResponse+getWithdrawLimits = runUnary (RPC :: RPC OperationsService "getWithdrawLimits")++getBrokerReport :: GrpcClient -> BrokerReportRequest -> GrpcIO BrokerReportResponse+getBrokerReport = runUnary (RPC :: RPC OperationsService "getBrokerReport")++getDividendsForeignIssuer :: GrpcClient -> GetDividendsForeignIssuerRequest -> GrpcIO GetDividendsForeignIssuerResponse+getDividendsForeignIssuer = runUnary (RPC :: RPC OperationsService "getDividendsForeignIssuer")++getOperationsByCursor :: GrpcClient -> GetOperationsByCursorRequest -> GrpcIO GetOperationsByCursorResponse+getOperationsByCursor = runUnary (RPC :: RPC OperationsService "getOperationsByCursor")
+ src/Invest/Service/Orders.hs view
@@ -0,0 +1,31 @@+module Invest.Service.Orders(+ postOrder,+ cancelOrder,+ getOrderState,+ getOrders+) where++import Control.Lens ((^.))+import Data.ProtoLens.Message (defMessage)+import Invest.Client.Helpers (GrpcClient, GrpcIO, runUnary,+ runUnary_)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Google.Protobuf.Timestamp+import qualified Proto.Invest.Common_Fields as C+import Proto.Invest.Orders+import qualified Proto.Invest.Orders_Fields as O++postOrder :: GrpcClient -> PostOrderRequest -> GrpcIO PostOrderResponse+postOrder = runUnary (RPC :: RPC OrdersService "postOrder")++cancelOrder :: GrpcClient -> CancelOrderRequest -> GrpcIO Timestamp+cancelOrder = runUnary_ (^. C.time) (RPC :: RPC OrdersService "cancelOrder")++getOrderState :: GrpcClient -> GetOrderStateRequest -> GrpcIO OrderState+getOrderState = runUnary (RPC :: RPC OrdersService "getOrderState")++getOrders :: GrpcClient -> GetOrdersRequest -> GrpcIO [OrderState]+getOrders = runUnary_ (^. O.orders) (RPC :: RPC OrdersService "getOrders")++replaceOrder :: GrpcClient -> ReplaceOrderRequest -> GrpcIO PostOrderResponse+replaceOrder = runUnary (RPC :: RPC OrdersService "replaceOrder")
+ src/Invest/Service/Sandbox.hs view
@@ -0,0 +1,66 @@+module Invest.Service.Sandbox(+ openSandboxAccount,+ getSandboxAccounts,+ closeSandboxAccount,+ postSandboxOrder,+ getSandboxOrders,+ cancelSandboxOrder,+ getSandboxOrderState,+ getSandboxPositions,+ getSandboxOperations,+ getSandboxPortfolio,+ sandboxPayIn+) where++import Control.Lens ((&), (.~), (^.))+import Data.ProtoLens.Message (defMessage)+import Data.Text+import Invest.Client.Helpers (GrpcClient, GrpcIO, runUnary,+ runUnary_)+import Network.GRPC.Client (RawReply)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Google.Protobuf.Timestamp+import qualified Proto.Invest.Common_Fields as C+import Proto.Invest.Operations+import qualified Proto.Invest.Operations_Fields as OP+import Proto.Invest.Orders+import qualified Proto.Invest.Orders_Fields as O+import Proto.Invest.Sandbox+import qualified Proto.Invest.Sandbox_Fields as S+import Proto.Invest.Users+import qualified Proto.Invest.Users_Fields as U+import Proto.Invest.Common++openSandboxAccount :: GrpcClient -> GrpcIO Text+openSandboxAccount gc = runUnary_ (^. S.accountId) (RPC :: RPC SandboxService "openSandboxAccount") gc defMessage++getSandboxAccounts :: GrpcClient -> GrpcIO [Account]+getSandboxAccounts gc = runUnary_ (^. U.accounts) (RPC :: RPC SandboxService "getSandboxAccounts") gc defMessage++closeSandboxAccount :: GrpcClient -> CloseSandboxAccountRequest -> GrpcIO CloseSandboxAccountResponse+closeSandboxAccount = runUnary (RPC :: RPC SandboxService "closeSandboxAccount")++postSandboxOrder :: GrpcClient -> PostOrderRequest -> GrpcIO PostOrderResponse+postSandboxOrder = runUnary (RPC :: RPC SandboxService "postSandboxOrder")++getSandboxOrders :: GrpcClient -> Text -> GrpcIO [OrderState]+getSandboxOrders gc accountId = runUnary_ (^. O.orders) (RPC :: RPC SandboxService "getSandboxOrders") gc message+ where message = defMessage & O.accountId .~ accountId++cancelSandboxOrder :: GrpcClient -> CancelOrderRequest -> GrpcIO Timestamp+cancelSandboxOrder = runUnary_ (^. C.time) (RPC :: RPC SandboxService "cancelSandboxOrder")++getSandboxOrderState :: GrpcClient -> GetOrderStateRequest -> GrpcIO OrderState+getSandboxOrderState = runUnary (RPC :: RPC SandboxService "getSandboxOrderState")++getSandboxPositions :: GrpcClient -> PositionsRequest -> GrpcIO PositionsResponse+getSandboxPositions = runUnary (RPC :: RPC SandboxService "getSandboxPositions")++getSandboxOperations :: GrpcClient -> OperationsRequest -> GrpcIO [Operation]+getSandboxOperations = runUnary_ (^. OP.operations) (RPC :: RPC SandboxService "getSandboxOperations")++getSandboxPortfolio :: GrpcClient -> PortfolioRequest -> GrpcIO PortfolioResponse+getSandboxPortfolio = runUnary (RPC :: RPC SandboxService "getSandboxPortfolio")++sandboxPayIn :: GrpcClient -> SandboxPayInRequest -> GrpcIO MoneyValue+sandboxPayIn = runUnary_ (^. S.balance) (RPC :: RPC SandboxService "sandboxPayIn")
+ src/Invest/Service/StopOrders.hs view
@@ -0,0 +1,26 @@+module Invest.Service.StopOrders(+ postStopOrder,+ getStopOrders,+ cancelStopOrder+) where++import Control.Lens ((&), (.~), (^.))+import Data.ProtoLens.Message (defMessage)+import Data.Text as T+import Invest.Client.Helpers (GrpcClient, GrpcIO, runUnary,+ runUnary_)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Proto.Google.Protobuf.Timestamp+import qualified Proto.Invest.Common_Fields as C+import Proto.Invest.Stoporders+import qualified Proto.Invest.Stoporders_Fields as SO++postStopOrder :: GrpcClient -> PostStopOrderRequest -> GrpcIO Text+postStopOrder = runUnary_ (^. SO.stopOrderId) (RPC :: RPC StopOrdersService "postStopOrder")++getStopOrders :: GrpcClient -> Text -> GrpcIO [StopOrder]+getStopOrders gc accountId = runUnary_ (^. SO.stopOrders) (RPC :: RPC StopOrdersService "getStopOrders") gc message+ where message = defMessage & SO.accountId .~ accountId++cancelStopOrder :: GrpcClient -> CancelStopOrderRequest -> GrpcIO Timestamp+cancelStopOrder = runUnary_ (^. C.time) (RPC :: RPC StopOrdersService "cancelStopOrder")
+ src/Invest/Service/Users.hs view
@@ -0,0 +1,30 @@+module Invest.Service.Users(+ getAccounts,+ getMarginAttributes,+ getUserTariff,+ getInfo+) where++import Control.Lens ((&), (.~), (^.))+import Data.ProtoLens.Message (defMessage)+import Data.Text as T+import Invest.Client.Helpers (GrpcIO, runUnary, runUnary_)+import Network.GRPC.Client (RawReply)+import Network.GRPC.Client.Helpers (GrpcClient)+import Network.GRPC.HTTP2.ProtoLens (RPC (..))+import Network.HTTP2.Client (ClientIO, TooMuchConcurrency)+import Proto.Invest.Users+import qualified Proto.Invest.Users_Fields as U++getAccounts :: GrpcClient -> GrpcIO [Account]+getAccounts gc = runUnary_ (^. U.accounts) (RPC :: RPC UsersService "getAccounts") gc defMessage++getMarginAttributes :: GrpcClient -> String -> GrpcIO GetMarginAttributesResponse+getMarginAttributes gc accountId = runUnary (RPC :: RPC UsersService "getMarginAttributes") gc message+ where message = defMessage & U.accountId .~ T.pack accountId++getUserTariff :: GrpcClient -> GrpcIO GetUserTariffResponse+getUserTariff gc = runUnary (RPC :: RPC UsersService "getUserTariff") gc defMessage++getInfo :: GrpcClient -> GrpcIO GetInfoResponse+getInfo gc = runUnary (RPC :: RPC UsersService "getInfo") gc defMessage
+ tinkoff-invest-sdk.cabal view
@@ -0,0 +1,103 @@+cabal-version: 2.0+name: tinkoff-invest-sdk+version: 0.1.0.0+license: MIT+license-file: LICENSE+copyright: Copyright (c) 2022 Nick Miller+maintainer: nickmiller.on@gmail.com+author: Nick Miller+homepage: https://github.com/nickmi11er/tinkoff-invest-haskell#readme+synopsis: gRPC based SDK for Tinkoff Invest API V2+description: Simple gRPC based SDK for Tinkoff Invest API V2+category: Finance+build-type: Custom+extra-source-files:+ proto/google/protobuf/timestamp.proto+ proto/invest/common.proto+ proto/invest/instruments.proto+ proto/invest/marketdata.proto+ proto/invest/operations.proto+ proto/invest/orders.proto+ proto/invest/sandbox.proto+ proto/invest/stoporders.proto+ proto/invest/users.proto++custom-setup+ setup-depends:+ Cabal >=3.4.1.0 && <3.5,+ base >=4.15.1.0 && <4.16,+ proto-lens-setup >=0.4.0.6 && <0.5++library+ exposed-modules:+ Invest.Client+ Invest.Client.Helpers+ Invest.Service.Instruments+ Invest.Service.MarketData+ Invest.Service.MarketDataStream+ Invest.Service.Operations+ Invest.Service.Orders+ Invest.Service.Sandbox+ Invest.Service.StopOrders+ Invest.Service.Users+ Paths_tinkoff_invest_sdk+ Proto.Google.Protobuf.Timestamp+ Proto.Invest.Common+ Proto.Invest.Common_Fields+ Proto.Invest.Instruments+ Proto.Invest.Instruments_Fields+ Proto.Invest.Marketdata+ Proto.Invest.Marketdata_Fields+ Proto.Invest.Operations+ Proto.Invest.Operations_Fields+ Proto.Invest.Orders+ Proto.Invest.Orders_Fields+ Proto.Invest.Sandbox+ Proto.Invest.Sandbox_Fields+ Proto.Invest.Stoporders+ Proto.Invest.Stoporders_Fields+ Proto.Invest.Users+ Proto.Invest.Users_Fields++ hs-source-dirs: src+ other-modules:+ Invest.Client.Errors+ Invest.Service.Internal.MarketDataStream++ autogen-modules:+ Paths_tinkoff_invest_sdk+ Proto.Google.Protobuf.Timestamp+ Proto.Invest.Common+ Proto.Invest.Common_Fields+ Proto.Invest.Instruments+ Proto.Invest.Instruments_Fields+ Proto.Invest.Marketdata+ Proto.Invest.Marketdata_Fields+ Proto.Invest.Operations+ Proto.Invest.Operations_Fields+ Proto.Invest.Orders+ Proto.Invest.Orders_Fields+ Proto.Invest.Sandbox+ Proto.Invest.Sandbox_Fields+ Proto.Invest.Stoporders+ Proto.Invest.Stoporders_Fields+ Proto.Invest.Users+ Proto.Invest.Users_Fields++ default-language: Haskell2010+ default-extensions: LambdaCase DataKinds+ build-depends:+ async >=2.2.4 && <2.3,+ base >=4.15.1.0 && <5.0,+ bytestring >=0.10.12.1 && <0.11,+ concurrent-extra ==0.7.*,+ errors >=2.3.0 && <2.4,+ http2-client >=0.10.0.1 && <0.11,+ http2-client-grpc >=0.8.0.0 && <0.9,+ http2-grpc-proto-lens >=0.1.0.0 && <0.2,+ lens >=5.0.1 && <5.1,+ mtl >=2.2.2 && <2.3,+ proto-lens >=0.7.1.1 && <0.8,+ proto-lens-runtime >=0.7.0.2 && <0.8,+ text >=1.2.5.0 && <1.3,+ unordered-containers >=0.2.17.0 && <0.3