packages feed

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 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