RAPTOR v18.4: Исправлена отчетность, активированы выходные

This commit is contained in:
root
2026-04-18 23:26:45 +03:00
commit ef0958239e
312 changed files with 54247 additions and 0 deletions

View File

View File

@@ -0,0 +1,506 @@
from .clients import AsyncClient, Client
from .exceptions import AioRequestError, InvestError, RequestError
from .logging import get_current_tracking_id
from .schemas import (
AccessLevel,
Account,
AccountStatus,
AccountSubscriptionStatus,
AccountType,
AccruedInterest,
Asset,
AssetBond,
AssetClearingCertificate,
AssetCurrency,
AssetEtf,
AssetFull,
AssetInstrument,
AssetRequest,
AssetResponse,
AssetSecurity,
AssetShare,
AssetsRequest,
AssetsResponse,
AssetStructuredProduct,
AssetType,
Bond,
BondResponse,
BondsResponse,
Brand,
BrokerReportRequest,
BrokerReportResponse,
BuyLimitsView,
CancelOrderRequest,
CancelOrderResponse,
CancelStopOrderRequest,
CancelStopOrderResponse,
Candle,
CandleInstrument,
CandleInterval,
CandleSubscription,
CloseSandboxAccountRequest,
CloseSandboxAccountResponse,
CountryResponse,
Coupon,
CouponType,
CurrenciesResponse,
Currency,
CurrencyResponse,
Dividend,
DividendsForeignIssuerReport,
EditFavoritesActionType,
EditFavoritesRequest,
EditFavoritesRequestInstrument,
EditFavoritesResponse,
Etf,
EtfResponse,
EtfsResponse,
ExchangeOrderType,
ExtraBond,
ExtraFuture,
FavoriteInstrument,
FilterOptionsRequest,
FindInstrumentRequest,
FindInstrumentResponse,
Future,
FutureResponse,
FuturesResponse,
GenerateBrokerReportRequest,
GenerateDividendsForeignIssuerReportRequest,
GenerateDividendsForeignIssuerReportResponse,
GetAccountsRequest,
GetAccountsResponse,
GetAccruedInterestsRequest,
GetAccruedInterestsResponse,
GetAssetFundamentalsRequest,
GetAssetFundamentalsResponse,
GetBondCouponsRequest,
GetBondCouponsResponse,
GetBrandRequest,
GetBrandsRequest,
GetBrandsResponse,
GetBrokerReportRequest,
GetCandlesRequest,
GetCandlesResponse,
GetClosePricesRequest,
GetClosePricesResponse,
GetCountriesRequest,
GetCountriesResponse,
GetDividendsForeignIssuerReportRequest,
GetDividendsForeignIssuerReportResponse,
GetDividendsForeignIssuerRequest,
GetDividendsForeignIssuerResponse,
GetDividendsRequest,
GetDividendsResponse,
GetFavoritesRequest,
GetFavoritesResponse,
GetFuturesMarginRequest,
GetFuturesMarginResponse,
GetInfoRequest,
GetInfoResponse,
GetLastPricesRequest,
GetLastPricesResponse,
GetLastTradesRequest,
GetLastTradesResponse,
GetMarginAttributesRequest,
GetMarginAttributesResponse,
GetMaxLotsRequest,
GetMaxLotsResponse,
GetMySubscriptions,
GetOperationsByCursorRequest,
GetOperationsByCursorResponse,
GetOrderBookRequest,
GetOrderBookResponse,
GetOrderPriceRequest,
GetOrderPriceResponse,
GetOrdersRequest,
GetOrdersResponse,
GetOrderStateRequest,
GetStopOrdersRequest,
GetStopOrdersResponse,
GetTradingStatusRequest,
GetTradingStatusResponse,
GetUserTariffRequest,
GetUserTariffResponse,
HistoricCandle,
InfoInstrument,
InfoSubscription,
Instrument,
InstrumentClosePriceRequest,
InstrumentClosePriceResponse,
InstrumentIdType,
InstrumentLink,
InstrumentRequest,
InstrumentResponse,
InstrumentShort,
InstrumentsRequest,
InstrumentStatus,
InstrumentType,
LastPrice,
LastPriceInstrument,
LastPriceSubscription,
MarketDataRequest,
MarketDataResponse,
MarketDataServerSideStreamRequest,
MoneyValue,
OpenSandboxAccountRequest,
OpenSandboxAccountResponse,
Operation,
OperationItem,
OperationItemTrade,
OperationItemTrades,
OperationsRequest,
OperationsResponse,
OperationState,
OperationTrade,
OperationType,
Option,
OptionDirection,
OptionPaymentType,
OptionResponse,
OptionSettlementType,
OptionsResponse,
OptionStyle,
Order,
OrderBook,
OrderBookInstrument,
OrderBookSubscription,
OrderDirection,
OrderExecutionReportStatus,
OrderStage,
OrderState,
OrderTrade,
OrderTrades,
OrderType,
Page,
PortfolioPosition,
PortfolioRequest,
PortfolioResponse,
PortfolioStreamRequest,
PortfolioStreamResponse,
PortfolioSubscriptionResult,
PortfolioSubscriptionStatus,
PositionData,
PositionsAccountSubscriptionStatus,
PositionsMoney,
PositionsOptions,
PositionsRequest,
PositionsResponse,
PositionsSecurities,
PositionsStreamRequest,
PositionsStreamResponse,
PositionsSubscriptionResult,
PositionsSubscriptionStatus,
PostOrderRequest,
PostOrderResponse,
PostStopOrderRequest,
PostStopOrderRequestTrailingData,
PostStopOrderResponse,
PriceType,
Quotation,
RealExchange,
ReplaceOrderRequest,
SandboxPayInRequest,
SandboxPayInResponse,
SecurityTradingStatus,
SellLimitsView,
Share,
ShareResponse,
SharesResponse,
ShareType,
StatisticResponse,
StopOrder,
StopOrderDirection,
StopOrderExpirationType,
StopOrderStatusOption,
StopOrderTrailingData,
StopOrderType,
StreamLimit,
StructuredProductType,
SubscribeCandlesRequest,
SubscribeCandlesResponse,
SubscribeInfoRequest,
SubscribeInfoResponse,
SubscribeLastPriceRequest,
SubscribeLastPriceResponse,
SubscribeOrderBookRequest,
SubscribeOrderBookResponse,
SubscribeTradesRequest,
SubscribeTradesResponse,
SubscriptionAction,
SubscriptionInterval,
SubscriptionStatus,
TakeProfitType,
TimeInForceType,
Trade,
TradeDirection,
TradeInstrument,
TradesStreamRequest,
TradesStreamResponse,
TradeSubscription,
TradingDay,
TradingSchedule,
TradingSchedulesRequest,
TradingSchedulesResponse,
TradingStatus,
UnaryLimit,
WithdrawLimitsRequest,
WithdrawLimitsResponse,
)
__version__ = "0.3.5"
__all__ = (
"__version__",
"AccessLevel",
"Account",
"AccountStatus",
"AccountSubscriptionStatus",
"AccountType",
"AccruedInterest",
"AioRequestError",
"Asset",
"AssetBond",
"AssetClearingCertificate",
"AssetCurrency",
"AssetEtf",
"AssetFull",
"AssetInstrument",
"AssetRequest",
"AssetResponse",
"AssetSecurity",
"AssetShare",
"AssetsRequest",
"AssetsResponse",
"AssetStructuredProduct",
"AssetType",
"AsyncClient",
"Bond",
"BondResponse",
"BondsResponse",
"Brand",
"BrokerReportRequest",
"BrokerReportResponse",
"BuyLimitsView",
"CancelOrderRequest",
"CancelOrderResponse",
"CancelStopOrderRequest",
"CancelStopOrderResponse",
"Candle",
"CandleInstrument",
"CandleInterval",
"CandleSubscription",
"Client",
"CloseSandboxAccountRequest",
"CloseSandboxAccountResponse",
"CountryResponse",
"Coupon",
"CouponType",
"CurrenciesResponse",
"Currency",
"CurrencyResponse",
"Dividend",
"DividendsForeignIssuerReport",
"EditFavoritesActionType",
"EditFavoritesRequest",
"EditFavoritesRequestInstrument",
"EditFavoritesResponse",
"Etf",
"EtfResponse",
"EtfsResponse",
"ExchangeOrderType",
"ExtraBond",
"ExtraFuture",
"FavoriteInstrument",
"FilterOptionsRequest",
"FindInstrumentRequest",
"FindInstrumentResponse",
"Future",
"FutureResponse",
"FuturesResponse",
"GenerateBrokerReportRequest",
"GenerateDividendsForeignIssuerReportRequest",
"GenerateDividendsForeignIssuerReportResponse",
"get_current_tracking_id",
"GetAccountsRequest",
"GetAccountsResponse",
"GetAccruedInterestsRequest",
"GetAccruedInterestsResponse",
"GetAssetFundamentalsRequest",
"GetAssetFundamentalsResponse",
"GetBondCouponsRequest",
"GetBondCouponsResponse",
"GetBrandRequest",
"GetBrandsRequest",
"GetBrandsResponse",
"GetBrokerReportRequest",
"GetCandlesRequest",
"GetCandlesResponse",
"GetClosePricesRequest",
"GetClosePricesResponse",
"GetCountriesRequest",
"GetCountriesResponse",
"GetDividendsForeignIssuerReportRequest",
"GetDividendsForeignIssuerReportResponse",
"GetDividendsForeignIssuerRequest",
"GetDividendsForeignIssuerResponse",
"GetDividendsRequest",
"GetDividendsResponse",
"GetFavoritesRequest",
"GetFavoritesResponse",
"GetFuturesMarginRequest",
"GetFuturesMarginResponse",
"GetInfoRequest",
"GetInfoResponse",
"GetLastPricesRequest",
"GetLastPricesResponse",
"GetLastTradesRequest",
"GetLastTradesResponse",
"GetMarginAttributesRequest",
"GetMarginAttributesResponse",
"GetMaxLotsRequest",
"GetMaxLotsResponse",
"GetMySubscriptions",
"GetOperationsByCursorRequest",
"GetOperationsByCursorResponse",
"GetOrderBookRequest",
"GetOrderBookResponse",
"GetOrderPriceRequest",
"GetOrderPriceResponse",
"GetOrdersRequest",
"GetOrdersResponse",
"GetOrderStateRequest",
"GetStopOrdersRequest",
"GetStopOrdersResponse",
"GetTradingStatusRequest",
"GetTradingStatusResponse",
"GetUserTariffRequest",
"GetUserTariffResponse",
"HistoricCandle",
"InfoInstrument",
"InfoSubscription",
"Instrument",
"InstrumentClosePriceRequest",
"InstrumentClosePriceResponse",
"InstrumentIdType",
"InstrumentLink",
"InstrumentRequest",
"InstrumentResponse",
"InstrumentShort",
"InstrumentsRequest",
"InstrumentStatus",
"InstrumentType",
"InvestError",
"LastPrice",
"LastPriceInstrument",
"LastPriceSubscription",
"MarketDataRequest",
"MarketDataResponse",
"MarketDataServerSideStreamRequest",
"MoneyValue",
"OpenSandboxAccountRequest",
"OpenSandboxAccountResponse",
"Operation",
"OperationItem",
"OperationItemTrade",
"OperationItemTrades",
"OperationsRequest",
"OperationsResponse",
"OperationState",
"OperationTrade",
"OperationType",
"Option",
"OptionDirection",
"OptionPaymentType",
"OptionResponse",
"OptionSettlementType",
"OptionsResponse",
"OptionStyle",
"Order",
"OrderBook",
"OrderBookInstrument",
"OrderBookSubscription",
"OrderDirection",
"OrderExecutionReportStatus",
"OrderStage",
"OrderState",
"OrderTrade",
"OrderTrades",
"OrderType",
"Page",
"PortfolioPosition",
"PortfolioRequest",
"PortfolioResponse",
"PortfolioStreamRequest",
"PortfolioStreamResponse",
"PortfolioSubscriptionResult",
"PortfolioSubscriptionStatus",
"PositionData",
"PositionsAccountSubscriptionStatus",
"PositionsMoney",
"PositionsOptions",
"PositionsRequest",
"PositionsResponse",
"PositionsSecurities",
"PositionsStreamRequest",
"PositionsStreamResponse",
"PositionsSubscriptionResult",
"PositionsSubscriptionStatus",
"PostOrderRequest",
"PostOrderResponse",
"PostStopOrderRequest",
"PostStopOrderRequestTrailingData",
"PostStopOrderResponse",
"PriceType",
"PriceType",
"Quotation",
"RealExchange",
"ReplaceOrderRequest",
"RequestError",
"SandboxPayInRequest",
"SandboxPayInResponse",
"SecurityTradingStatus",
"SellLimitsView",
"Share",
"ShareResponse",
"SharesResponse",
"ShareType",
"StatisticResponse",
"StopOrder",
"StopOrderDirection",
"StopOrderExpirationType",
"StopOrderStatusOption",
"StopOrderTrailingData",
"StopOrderType",
"StreamLimit",
"StructuredProductType",
"SubscribeCandlesRequest",
"SubscribeCandlesResponse",
"SubscribeInfoRequest",
"SubscribeInfoResponse",
"SubscribeLastPriceRequest",
"SubscribeLastPriceResponse",
"SubscribeOrderBookRequest",
"SubscribeOrderBookResponse",
"SubscribeTradesRequest",
"SubscribeTradesResponse",
"SubscriptionAction",
"SubscriptionInterval",
"SubscriptionStatus",
"TakeProfitType",
"TimeInForceType",
"Trade",
"TradeDirection",
"TradeInstrument",
"TradesStreamRequest",
"TradesStreamResponse",
"TradeSubscription",
"TradingDay",
"TradingSchedule",
"TradingSchedulesRequest",
"TradingSchedulesResponse",
"TradingStatus",
"UnaryLimit",
"WithdrawLimitsRequest",
"WithdrawLimitsResponse",
)

View File

@@ -0,0 +1,122 @@
import datetime
import re
from functools import wraps
from typing import Any, Callable, Optional, cast
import sentry_sdk
from grpc import StatusCode
from sentry_sdk.integrations.excepthook import ExcepthookIntegration
from sentry_sdk.types import Event
from ._errors import TFunc
from .constants import ERROR_HUB_DSN, PACKAGE_NAME
from .exceptions import AioRequestError, RequestError
__all__ = (
"init_error_hub",
"async_init_error_hub",
"handle_error_hub_gen",
"handle_aio_error_hub_gen",
)
BEARER_PATTERN = re.compile(r"Bearer\s+[a-zA-Z0-9\-_\.]+", re.IGNORECASE)
def sanitize_bearer_tokens(event, hint) -> Optional[Event]:
def _sanitize_value(value):
if isinstance(value, str):
return BEARER_PATTERN.sub("[***Filtered***]", value)
elif isinstance(value, dict):
return {k: _sanitize_value(v) for k, v in value.items()}
elif isinstance(value, (list, tuple)):
return [_sanitize_value(item) for item in value]
else:
return value
if "exc_info" in hint:
exc_type, exc_value, traceback = hint["exc_info"]
if exc_type == RequestError or exc_type == AioRequestError:
status_code = exc_value.code
if status_code == StatusCode.UNAVAILABLE:
return _sanitize_value(event)
return None
def init_error_hub(client):
import sentry_sdk
from sentry_sdk.integrations.modules import ModulesIntegration
# noinspection PyProtectedMember
sentry_sdk.init(
dsn=ERROR_HUB_DSN,
send_default_pii=False,
integrations=[],
auto_enabling_integrations=False,
disabled_integrations=[ModulesIntegration(), ExcepthookIntegration()],
before_send=sanitize_bearer_tokens,
release=PACKAGE_NAME,
environment=client._target,
add_full_stack=False,
max_stack_frames=3,
max_breadcrumbs=3,
enable_logs=False,
)
async def async_init_error_hub(client):
init_error_hub(client)
def handle_error_hub_gen() -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
with sentry_sdk.new_scope() as scope:
stream_start = datetime.datetime.now()
scope.set_extra("stream_start", stream_start)
try:
for message in func(*args, **kwargs):
scope.set_extra("last_message", message)
yield message
except RequestError as e:
metadata = e.metadata
tracking_id = metadata.tracking_id if metadata else None
scope.set_extra("tracking_id", tracking_id)
scope.set_extra(
"stream_duration", datetime.datetime.now() - stream_start
)
sentry_sdk.capture_exception(e)
raise
return cast(TFunc, wrapper)
return decorator
def handle_aio_error_hub_gen() -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
with sentry_sdk.new_scope() as scope:
stream_start = datetime.datetime.now()
scope.set_extra("stream_start", stream_start)
try:
async for message in func(*args, **kwargs):
scope.set_extra("last_message", message)
yield message
except AioRequestError as e:
metadata = e.metadata
tracking_id = metadata.tracking_id if metadata else None
scope.set_extra("tracking_id", tracking_id)
scope.set_extra(
"stream_duration", datetime.datetime.now() - stream_start
)
sentry_sdk.capture_exception(e)
raise
return cast(TFunc, wrapper)
return decorator

View File

@@ -0,0 +1,137 @@
from functools import wraps
from typing import Any, Callable, TypeVar, cast
from grpc import Call, RpcError, StatusCode
from grpc.aio import AioRpcError
from .exceptions import (
AioRequestError,
AioUnauthenticatedError,
RequestError,
UnauthenticatedError,
)
from .logging import get_metadata_from_aio_error, get_metadata_from_call, log_error
TFunc = TypeVar("TFunc", bound=Callable[..., Any])
def handle_request_error(name: str) -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
try:
return func(*args, **kwargs)
except RpcError as e:
if issubclass(type(e), Call):
metadata = get_metadata_from_call(e)
tracking_id = metadata.tracking_id if metadata else None
log_error(
tracking_id,
name,
f"{e.code().name} {e.details()}", # type:ignore
)
status_code = e.code() # type:ignore
details = e.details() # type:ignore
if status_code == StatusCode.UNAUTHENTICATED:
raise UnauthenticatedError(
status_code, details, metadata
) from e
raise RequestError(status_code, details, metadata) from e
raise
return cast(TFunc, wrapper)
return decorator
def handle_request_error_gen(name: str) -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
try:
for message in func(*args, **kwargs):
yield message
except RpcError as e:
if issubclass(type(e), Call):
metadata = get_metadata_from_call(e)
tracking_id = metadata.tracking_id if metadata else None
log_error(
tracking_id,
name,
f"{e.code().name} {e.details()}", # type:ignore
)
status_code = e.code() # type:ignore
details = e.details() # type:ignore
if status_code == StatusCode.UNAUTHENTICATED:
raise UnauthenticatedError(
status_code, details, metadata
) from e
raise RequestError(status_code, details, metadata) from e
raise
return cast(TFunc, wrapper)
return decorator
def handle_aio_request_error(name: str) -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
try:
return await func(*args, **kwargs)
except AioRpcError as e:
metadata = get_metadata_from_aio_error(e)
tracking_id = metadata.tracking_id if metadata else None
log_error(
tracking_id,
name,
f"{e.code().name} {e.details()}", # type:ignore
)
status_code = e.code() # type:ignore
details = e.details() # type:ignore
if status_code == StatusCode.UNAUTHENTICATED:
raise AioUnauthenticatedError(status_code, details, metadata) from e
raise AioRequestError(status_code, details, metadata) from e
return cast(TFunc, wrapper)
return decorator
def handle_aio_request_error_gen(name: str) -> Callable[[TFunc], TFunc]:
def decorator(func: TFunc) -> TFunc:
# noinspection DuplicatedCode
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
try:
async for result in func(*args, **kwargs):
yield result
except AioRpcError as e:
metadata = get_metadata_from_aio_error(e)
tracking_id = metadata.tracking_id if metadata else None
log_error(
tracking_id,
name,
f"{e.code().name} {e.details()}", # type:ignore
)
status_code = e.code() # type:ignore
details = e.details() # type:ignore
if status_code == StatusCode.UNAUTHENTICATED:
raise AioUnauthenticatedError(status_code, details, metadata) from e
raise AioRequestError(status_code, details, metadata) from e
return cast(TFunc, wrapper)
return decorator

View File

@@ -0,0 +1,500 @@
# pylint:disable=no-name-in-module
import dataclasses
import enum
import logging
import os
from abc import ABC
from datetime import datetime, timedelta, timezone
from decimal import Decimal
from textwrap import dedent
from typing import (
Any,
Dict,
Optional,
Tuple,
Type,
TypeVar,
Union,
get_args,
get_origin,
get_type_hints,
)
from google.protobuf import symbol_database
from google.protobuf.message_factory import GetMessageClass
from google.protobuf.timestamp_pb2 import Timestamp
_sym_db = symbol_database.Default()
NoneType = type(None)
logger = logging.getLogger(__name__)
T = TypeVar("T")
def ts_to_datetime(value: Timestamp) -> datetime:
ts = value.seconds + (value.nanos / 1e9)
return datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=ts)
def datetime_to_ts(value: datetime) -> Tuple[int, int]:
seconds = int(value.timestamp())
nanos = int(value.microsecond * 1e3)
return seconds, nanos
# Proto 3 data types
TYPE_ENUM = "enum"
TYPE_BOOL = "bool"
TYPE_INT32 = "int32"
TYPE_INT64 = "int64"
TYPE_UINT32 = "uint32"
TYPE_UINT64 = "uint64"
TYPE_SINT32 = "sint32"
TYPE_SINT64 = "sint64"
TYPE_FLOAT = "float"
TYPE_DOUBLE = "double"
TYPE_FIXED32 = "fixed32"
TYPE_SFIXED32 = "sfixed32"
TYPE_FIXED64 = "fixed64"
TYPE_SFIXED64 = "sfixed64"
TYPE_STRING = "string"
TYPE_BYTES = "bytes"
TYPE_MESSAGE = "message"
TYPE_MAP = "map"
PLACEHOLDER: Any = object()
@dataclasses.dataclass(frozen=True)
class FieldMetadata:
"""Stores internal metadata used for parsing & serialization."""
# Protobuf field number
number: int
# Protobuf type name
proto_type: str
# Map information if the proto_type is a map
map_types: Optional[Tuple[str, str]] = None
# Groups several "one-of" fields together
group: Optional[str] = None
# Describes the wrapped type (e.g. when using google.protobuf.BoolValue)
wraps: Optional[str] = None
# Is the field optional
optional: Optional[bool] = False
@staticmethod
def get(field: dataclasses.Field) -> "FieldMetadata":
"""Return the field metadata for a dataclass field."""
return field.metadata["proto"]
def dataclass_field(
number: int,
proto_type: str,
*,
map_types: Optional[Tuple[str, str]] = None,
group: Optional[str] = None,
wraps: Optional[str] = None,
optional: bool = False,
) -> dataclasses.Field:
"""Create a dataclass field with attached protobuf metadata."""
return dataclasses.field(
default=None if optional else PLACEHOLDER, # type:ignore
metadata={
"proto": FieldMetadata(
number, proto_type, map_types, group, wraps, optional
)
},
)
def enum_field(number: int, group: Optional[str] = None, optional: bool = False) -> Any:
return dataclass_field(number, TYPE_ENUM, group=group, optional=optional)
def bool_field(number: int, group: Optional[str] = None, optional: bool = False) -> Any:
return dataclass_field(number, TYPE_BOOL, group=group, optional=optional)
def int32_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_INT32, group=group, optional=optional)
def int64_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_INT64, group=group, optional=optional)
def uint32_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_UINT32, group=group, optional=optional)
def uint64_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_UINT64, group=group, optional=optional)
def sint32_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_SINT32, group=group, optional=optional)
def sint64_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_SINT64, group=group, optional=optional)
def float_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_FLOAT, group=group, optional=optional)
def double_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_DOUBLE, group=group, optional=optional)
def fixed32_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_FIXED32, group=group, optional=optional)
def fixed64_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_FIXED64, group=group, optional=optional)
def sfixed32_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_SFIXED32, group=group, optional=optional)
def sfixed64_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_SFIXED64, group=group, optional=optional)
def string_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_STRING, group=group, optional=optional)
def bytes_field(
number: int, group: Optional[str] = None, optional: bool = False
) -> Any:
return dataclass_field(number, TYPE_BYTES, group=group, optional=optional)
def message_field(
number: int,
group: Optional[str] = None,
wraps: Optional[str] = None,
optional: bool = False,
) -> Any:
return dataclass_field(
number, TYPE_MESSAGE, group=group, wraps=wraps, optional=optional
)
def map_field(
number: int, key_type: str, value_type: str, group: Optional[str] = None
) -> Any:
return dataclass_field(
number, TYPE_MAP, map_types=(key_type, value_type), group=group
)
class Enum(enum.IntEnum):
@classmethod
def from_string(cls, name: str) -> "Enum":
try:
return cls._member_map_[name] # type: ignore # pylint:disable=no-member
except KeyError as e:
raise ValueError(f"Unknown value {name} for enum {cls.__name__}") from e
class Message:
...
class Service(ABC):
_stub_factory: Any
def __init__(self, channel, metadata):
self.stub = self._stub_factory(channel)
self.metadata = metadata
_UNKNOWN: Any = object()
PRIMITIVE_TYPES = (str, float, bool, int)
class UnknownType(TypeError):
pass
PYTHON_KEYWORDS = (
"False",
"None",
"True",
"and",
"as",
"assert",
"async",
"await",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield",
)
def to_unsafe_field_name(field_name: str) -> str:
if field_name.endswith("_"):
unsafe_field_name = field_name[:-1]
if unsafe_field_name in PYTHON_KEYWORDS:
return unsafe_field_name
return field_name
TEnum = TypeVar("TEnum", bound=Enum)
USE_DEFAULT_ENUM_IF_ERROR_ENV = "USE_DEFAULT_ENUM_IF_ERROR"
def _init_enum(enum_class: Type[TEnum], value: Any) -> TEnum:
"""Defaults when value is not yet supported.
Use USE_DEFAULT_ENUM_IF_ERROR to use default enum when value is not yet supported.
"""
use_default_enum_if_error = os.environ.get(
USE_DEFAULT_ENUM_IF_ERROR_ENV, "true"
) in (
"true",
"True",
"1",
)
# todo think about using pydantic settings to parse env vars
try:
return enum_class(value)
except ValueError as error:
if not use_default_enum_if_error:
raise ValueError(
f"Неизвестное значение '{value}' для enum '{enum_class.__name__}' "
f"доступные значения: {list(enum_class)}. "
f"Возможно сервер стал отдавать новые значения, "
f"в то время как sdk еще не обновлен. "
f"Для игнорирования ошибки установите "
f"переменную окружения {USE_DEFAULT_ENUM_IF_ERROR_ENV}=true"
) from error
default_enum = enum_class(0)
logger.warning(
dedent(
"""\
Было получено неизвестное значение '%s' для enum '%s'
Доступные значения: %s.
Возможно сервер стал отдавать новые значения,
в то время как sdk еще не обновлен.
Сообщите об этой проблеме разработчикам библиотеки.
Установлено значение по умолчанию %s, ошибка проигнорирована
Для вызова ошибки установите переменную окружения %s=false
""" # noqa: RUF001
),
value,
enum_class.__name__,
list(enum_class),
default_enum,
USE_DEFAULT_ENUM_IF_ERROR_ENV,
)
return default_enum
# pylint:disable=too-many-nested-blocks
# pylint:disable=too-many-branches
# pylint:disable=too-many-locals
# pylint:disable=too-many-nested-blocks
# pylint:disable=too-many-statements
def protobuf_to_dataclass(pb_obj: Any, dataclass_type: Type[T]) -> T: # noqa:C901
dataclass_hints = get_type_hints(dataclass_type)
dataclass_dict: Dict[str, Any] = {}
dataclass_fields = dataclass_type.__dataclass_fields__ # type:ignore
for field_name, field_type in dataclass_hints.items():
unsafe_field_name = to_unsafe_field_name(field_name)
pb_value = getattr(pb_obj, unsafe_field_name)
field_value = _UNKNOWN
oneof = dataclass_fields[field_name].metadata["proto"].group
if oneof and pb_obj.WhichOneof(oneof) != field_name:
dataclass_dict[field_name] = None
continue
origin = get_origin(field_type)
if origin is None:
if field_type in PRIMITIVE_TYPES:
field_value = pb_value
if field_type == Decimal:
field_value = Decimal(str(pb_value))
elif issubclass(field_type, datetime):
field_value = ts_to_datetime(pb_value)
elif dataclasses.is_dataclass(field_type):
field_value = protobuf_to_dataclass(
pb_value,
field_type if isinstance(field_type, type) else type(field_type),
)
elif issubclass(field_type, Enum):
field_value = _init_enum(enum_class=field_type, value=pb_value)
elif origin == list:
args = get_args(field_type)
first_arg = args[0]
if first_arg in PRIMITIVE_TYPES:
field_value = pb_value
elif dataclasses.is_dataclass(first_arg):
field_value = [
protobuf_to_dataclass(
item,
first_arg if isinstance(first_arg, type) else type(first_arg),
)
for item in pb_value
]
elif first_arg == Decimal:
field_value = [Decimal(str(item)) for item in pb_value]
elif first_arg == datetime:
field_value = [ts_to_datetime(item) for item in pb_value]
elif issubclass(field_type, Enum):
field_value = [
_init_enum(enum_class=field_type, value=item) for item in pb_value
]
if origin == Union:
args = get_args(field_type)
if len(args) > 2:
raise NotImplementedError(
"Union of more than 2 args is not supported yet."
)
first_arg, second_arg = args[0], args[1]
if second_arg == NoneType and str(pb_value) == "":
field_value = None
elif first_arg in PRIMITIVE_TYPES:
field_value = pb_value
elif first_arg == Decimal:
field_value = Decimal(str(pb_value))
elif issubclass(first_arg, datetime):
field_value = ts_to_datetime(pb_value)
elif dataclasses.is_dataclass(first_arg):
field_value = protobuf_to_dataclass(
pb_value,
first_arg if isinstance(first_arg, type) else type(first_arg),
)
elif issubclass(first_arg, Enum):
field_value = _init_enum(enum_class=first_arg, value=pb_value)
if field_value is _UNKNOWN:
raise UnknownType(f'type "{field_type}" unknown')
dataclass_dict[field_name] = field_value
return dataclass_type(**dataclass_dict)
def dataclass_to_protobuff(dataclass_obj: Any, protobuff_obj: T) -> T: # noqa:C901
dataclass_type = type(dataclass_obj)
dataclass_hints = get_type_hints(dataclass_type)
if not dataclass_hints:
protobuff_obj.SetInParent() # type:ignore
return protobuff_obj
for field_name, field_type in dataclass_hints.items():
field_value = getattr(dataclass_obj, field_name)
if field_value is PLACEHOLDER:
continue
origin = get_origin(field_type)
if origin is None:
_update_field(field_type, protobuff_obj, field_name, field_value)
elif origin == list:
args = get_args(field_type)
first_arg = args[0]
pb_value = getattr(protobuff_obj, field_name)
if first_arg in PRIMITIVE_TYPES:
pb_value.extend(item for item in field_value)
elif dataclasses.is_dataclass(first_arg):
descriptor = protobuff_obj.DESCRIPTOR # type:ignore
field_descriptor = descriptor.fields_by_name[field_name].message_type
type_ = GetMessageClass(field_descriptor)
pb_value.extend(
dataclass_to_protobuff(item, type_()) for item in field_value
)
elif issubclass(first_arg, Enum):
pb_value.extend(item.value for item in field_value)
else:
raise UnknownType(f"type {field_type} unknown")
elif origin == Union:
args = get_args(field_type)
first_arg = args[0]
second_arg = args[1]
if second_arg != NoneType:
raise UnknownType(f"type {field_type} unknown")
if field_value is None:
pass # just skip setting the field, since its set to None by default
else:
_update_field(first_arg, protobuff_obj, field_name, field_value)
else:
raise UnknownType(f"type {field_type} unknown")
return protobuff_obj
def _update_field(
field_type: Type[Any], protobuff_obj: Any, field_name: str, field_value: Any
) -> None:
if field_type in PRIMITIVE_TYPES:
setattr(protobuff_obj, field_name, field_value)
elif issubclass(field_type, datetime):
field_name_ = field_name
if field_name == "from_":
field_name_ = "from"
pb_value = getattr(protobuff_obj, field_name_)
seconds, nanos = datetime_to_ts(field_value)
pb_value.seconds = seconds
pb_value.nanos = nanos
elif dataclasses.is_dataclass(field_type):
pb_value = getattr(protobuff_obj, field_name)
dataclass_to_protobuff(field_value, pb_value)
elif issubclass(field_type, Enum):
if isinstance(field_value, int):
field_value = field_type(field_value)
setattr(protobuff_obj, field_name, field_value.value)
else:
raise UnknownType(f"type {field_type} unknown")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
import logging
from dataclasses import replace
from typing import Dict, Generic, Tuple, TypeVar, cast
from t_tech.invest import InstrumentIdType
from t_tech.invest.caching.instruments_cache.models import (
InstrumentResponse,
InstrumentsResponse,
)
logger = logging.getLogger(__name__)
TInstrumentResponse = TypeVar("TInstrumentResponse", bound=InstrumentResponse)
TInstrumentsResponse = TypeVar("TInstrumentsResponse", bound=InstrumentsResponse)
class InstrumentStorage(Generic[TInstrumentResponse, TInstrumentsResponse]):
def __init__(self, instruments_response: TInstrumentsResponse):
self._instruments_response = instruments_response
self._instrument_by_class_code_figi: Dict[
Tuple[str, str], InstrumentResponse
] = {
(instrument.class_code, instrument.figi): instrument
for instrument in self._instruments_response.instruments
}
self._instrument_by_class_code_ticker: Dict[
Tuple[str, str], InstrumentResponse
] = {
(instrument.class_code, instrument.ticker): instrument
for instrument in self._instruments_response.instruments
}
self._instrument_by_class_code_uid: Dict[
Tuple[str, str], InstrumentResponse
] = {
(instrument.class_code, instrument.uid): instrument
for instrument in self._instruments_response.instruments
}
# fmt: off
self._instrument_by_class_code_id_index = {
InstrumentIdType.INSTRUMENT_ID_UNSPECIFIED:
self._instrument_by_class_code_figi,
InstrumentIdType.INSTRUMENT_ID_TYPE_FIGI:
self._instrument_by_class_code_figi,
InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER:
self._instrument_by_class_code_ticker,
InstrumentIdType.INSTRUMENT_ID_TYPE_UID:
self._instrument_by_class_code_uid,
}
# fmt: on
def get(
self, *, id_type: InstrumentIdType, class_code: str, id: str
) -> TInstrumentResponse:
logger.debug(
"Cache request id_type=%s, class_code=%s, id=%s", id_type, class_code, id
)
instrument_by_class_code_id = self._instrument_by_class_code_id_index[id_type]
logger.debug(
"Index for %s found: \n%s", id_type, instrument_by_class_code_id.keys()
)
key = (class_code, id)
logger.debug("Cache request key=%s", key)
return cast(TInstrumentResponse, instrument_by_class_code_id[key])
def get_instruments_response(self) -> TInstrumentsResponse:
return replace(self._instruments_response, **{})

View File

@@ -0,0 +1,203 @@
import logging
from typing import cast
from t_tech.invest import (
Bond,
BondResponse,
BondsResponse,
CurrenciesResponse,
Currency,
CurrencyResponse,
Etf,
EtfResponse,
EtfsResponse,
Future,
FutureResponse,
FuturesResponse,
InstrumentIdType,
InstrumentStatus,
Share,
ShareResponse,
SharesResponse,
)
from t_tech.invest.caching.instruments_cache.instrument_storage import InstrumentStorage
from t_tech.invest.caching.instruments_cache.interface import IInstrumentsGetter
from t_tech.invest.caching.instruments_cache.models import (
InstrumentResponse,
InstrumentsResponse,
)
from t_tech.invest.caching.instruments_cache.protocol import InstrumentsResponseCallable
from t_tech.invest.caching.instruments_cache.settings import InstrumentsCacheSettings
from t_tech.invest.caching.overrides import TTLCache
from t_tech.invest.services import InstrumentsService
logger = logging.getLogger(__name__)
class InstrumentsCache(IInstrumentsGetter):
def __init__(
self,
settings: InstrumentsCacheSettings,
instruments_service: InstrumentsService,
):
self._settings = settings
self._instruments_service = instruments_service
logger.debug("Initialising instruments cache")
self._instruments_methods = [
self.shares,
self.futures,
self.etfs,
self.bonds,
self.currencies,
]
self._cache: TTLCache = TTLCache(
maxsize=len(self._instruments_methods),
ttl=self._settings.ttl.total_seconds(),
)
self._refresh_cache()
def _refresh_cache(self):
logger.debug("Refreshing instruments cache")
for instruments_method in self._instruments_methods:
instruments_method()
self._assert_cache()
def _assert_cache(self):
if self._cache.keys() != {f.__name__ for f in self._instruments_methods}:
raise KeyError(f"Cache does not have all instrument types {self._cache}")
def _get_instrument_storage(
self, get_instruments_method: InstrumentsResponseCallable
) -> InstrumentStorage[InstrumentResponse, InstrumentsResponse]:
storage_key = get_instruments_method.__name__
storage = self._cache.get(storage_key)
if storage is not None:
logger.debug("Got storage for key %s from cache", storage_key)
return storage
logger.debug(
"Storage for key %s not found, creating new storage with ttl=%s",
storage_key,
self._cache.ttl,
)
instruments_response = get_instruments_method(
instrument_status=InstrumentStatus.INSTRUMENT_STATUS_ALL
)
storage = InstrumentStorage(instruments_response=instruments_response)
self._cache[storage_key] = storage
return storage # noqa:R504
def shares(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> SharesResponse:
storage = cast(
InstrumentStorage[ShareResponse, SharesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.shares),
)
return storage.get_instruments_response()
def share_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> ShareResponse:
storage = cast(
InstrumentStorage[Share, SharesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.shares),
)
share = storage.get(id_type=id_type, class_code=class_code, id=id)
return ShareResponse(instrument=share)
def futures(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> FuturesResponse:
storage = cast(
InstrumentStorage[FutureResponse, FuturesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.futures),
)
return storage.get_instruments_response()
def future_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> FutureResponse:
storage = cast(
InstrumentStorage[Future, FuturesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.futures),
)
future = storage.get(id_type=id_type, class_code=class_code, id=id)
return FutureResponse(instrument=future)
def etfs(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> EtfsResponse:
storage = cast(
InstrumentStorage[EtfResponse, EtfsResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.etfs),
)
return storage.get_instruments_response()
def etf_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> EtfResponse:
storage = cast(
InstrumentStorage[Etf, EtfsResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.etfs),
)
etf = storage.get(id_type=id_type, class_code=class_code, id=id)
return EtfResponse(instrument=etf)
def bonds(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> BondsResponse:
storage = cast(
InstrumentStorage[BondResponse, BondsResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.bonds),
)
return storage.get_instruments_response()
def bond_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> BondResponse:
storage = cast(
InstrumentStorage[Bond, BondsResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.bonds),
)
bond = storage.get(id_type=id_type, class_code=class_code, id=id)
return BondResponse(instrument=bond)
def currencies(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> CurrenciesResponse:
storage = cast(
InstrumentStorage[CurrencyResponse, CurrenciesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.currencies),
)
return storage.get_instruments_response()
def currency_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> CurrencyResponse:
storage = cast(
InstrumentStorage[Currency, CurrenciesResponse], # type: ignore
self._get_instrument_storage(self._instruments_service.currencies),
)
currency = storage.get(id_type=id_type, class_code=class_code, id=id)
return CurrencyResponse(instrument=currency)

View File

@@ -0,0 +1,98 @@
import abc
from t_tech.invest import (
BondResponse,
BondsResponse,
CurrenciesResponse,
CurrencyResponse,
EtfResponse,
EtfsResponse,
FutureResponse,
FuturesResponse,
InstrumentIdType,
InstrumentStatus,
ShareResponse,
SharesResponse,
)
class IInstrumentsGetter(abc.ABC):
@abc.abstractmethod
def shares(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> SharesResponse:
pass
@abc.abstractmethod
def share_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> ShareResponse:
pass
@abc.abstractmethod
def futures(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> FuturesResponse:
pass
@abc.abstractmethod
def future_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> FutureResponse:
pass
@abc.abstractmethod
def etfs(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> EtfsResponse:
pass
@abc.abstractmethod
def etf_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> EtfResponse:
pass
@abc.abstractmethod
def bonds(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> BondsResponse:
pass
@abc.abstractmethod
def bond_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> BondResponse:
pass
@abc.abstractmethod
def currencies(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> CurrenciesResponse:
pass
@abc.abstractmethod
def currency_by(
self,
*,
id_type: InstrumentIdType = InstrumentIdType(0),
class_code: str = "",
id: str = "",
) -> CurrencyResponse:
pass

View File

@@ -0,0 +1,13 @@
from typing import List
class InstrumentResponse:
class_code: str
figi: str
ticker: str
uid: str
class InstrumentsResponse:
instruments: List[InstrumentResponse]

View File

@@ -0,0 +1,14 @@
from typing import Protocol
from t_tech.invest import InstrumentStatus
from t_tech.invest.caching.instruments_cache.models import InstrumentsResponse
class InstrumentsResponseCallable(Protocol):
def __call__(
self, *, instrument_status: InstrumentStatus = InstrumentStatus(0)
) -> InstrumentsResponse:
...
def __name__(self) -> str:
...

View File

@@ -0,0 +1,7 @@
import dataclasses
from datetime import timedelta
@dataclasses.dataclass()
class InstrumentsCacheSettings:
ttl: timedelta = timedelta(days=1)

View File

@@ -0,0 +1,156 @@
import logging
from datetime import datetime, timedelta
from typing import Dict, Generator, Iterable, Optional, Tuple
from t_tech.invest import CandleInterval, HistoricCandle
from t_tech.invest.caching.market_data_cache.cache_settings import (
MarketDataCacheSettings,
)
from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange
from t_tech.invest.caching.market_data_cache.instrument_date_range_market_data import (
InstrumentDateRangeData,
)
from t_tech.invest.caching.market_data_cache.instrument_market_data_storage import (
InstrumentMarketDataStorage,
)
from t_tech.invest.schemas import CandleSource
from t_tech.invest.services import Services
from t_tech.invest.utils import (
candle_interval_to_timedelta,
floor_datetime,
now,
round_datetime_range,
with_filtering_distinct_candles,
)
logger = logging.getLogger(__name__)
class MarketDataCache:
def __init__(self, settings: MarketDataCacheSettings, services: Services):
self._settings = settings
self._settings.base_cache_dir.mkdir(parents=True, exist_ok=True)
self._services = services
self._figi_cache_storages: Dict[
Tuple[str, CandleInterval], InstrumentMarketDataStorage
] = {}
def _get_candles_from_net(
self,
figi: str,
interval: CandleInterval,
from_: datetime,
to: datetime,
instrument_id: str = "",
candle_source_type: Optional[CandleSource] = None,
) -> Iterable[HistoricCandle]:
yield from self._services.get_all_candles(
figi=figi,
interval=interval,
from_=from_,
to=to,
instrument_id=instrument_id,
candle_source_type=candle_source_type,
)
def _with_saving_into_cache(
self,
storage: InstrumentMarketDataStorage,
from_net: Iterable[HistoricCandle],
) -> Iterable[HistoricCandle]:
candles = list(from_net)
if candles:
complete_candles = list(self._filter_complete_candles(candles))
complete_candle_times = [candle.time for candle in complete_candles]
complete_net_range = (
min(complete_candle_times),
max(complete_candle_times),
)
storage.update(
[
InstrumentDateRangeData(
date_range=complete_net_range,
historic_candles=complete_candles,
)
]
)
yield from candles
def _filter_complete_candles(
self, candles: Iterable[HistoricCandle]
) -> Iterable[HistoricCandle]:
return filter(lambda candle: candle.is_complete, candles)
@with_filtering_distinct_candles # type: ignore
def get_all_candles(
self,
*,
from_: datetime,
to: Optional[datetime] = None,
interval: CandleInterval = CandleInterval(0),
figi: str = "",
instrument_id: str = "",
candle_source_type: Optional[CandleSource] = None,
) -> Generator[HistoricCandle, None, None]:
interval_delta = candle_interval_to_timedelta(interval)
to = to or now()
processed_time = from_
figi_cache_storage = self._get_figi_cache_storage(figi=figi, interval=interval)
for cached in figi_cache_storage.get(
request_range=round_datetime_range(
date_range=(from_, to), interval=interval
)
):
cached_start, cached_end = cached.date_range
cached_candles = list(cached.historic_candles)
if cached_start > processed_time:
yield from self._with_saving_into_cache(
storage=figi_cache_storage,
from_net=self._get_candles_from_net(
figi=figi,
interval=interval,
from_=processed_time,
to=cached_start,
instrument_id=instrument_id,
candle_source_type=candle_source_type,
),
)
yield from cached_candles
processed_time = cached_end
if processed_time + interval_delta <= to:
yield from self._with_saving_into_cache(
storage=figi_cache_storage,
from_net=self._get_candles_from_net(
figi=figi,
interval=interval,
from_=processed_time,
to=to,
instrument_id=instrument_id,
),
)
figi_cache_storage.merge()
def _get_figi_cache_storage(
self, figi: str, interval: CandleInterval
) -> InstrumentMarketDataStorage:
figi_tuple = (figi, interval)
storage = self._figi_cache_storages.get(figi_tuple)
if storage is None:
storage = InstrumentMarketDataStorage(
figi=figi, interval=interval, settings=self._settings
)
self._figi_cache_storages[figi_tuple] = storage
return storage # noqa:R504
def _round_net_range(
self, net_range: DatetimeRange, interval_delta: timedelta
) -> DatetimeRange:
start, end = net_range
return floor_datetime(start, interval_delta), floor_datetime(
end, interval_delta
)

View File

@@ -0,0 +1,56 @@
import contextlib
import dataclasses
import enum
import logging
import os
import pickle # noqa:S403 # nosec
from pathlib import Path
from typing import Dict, Generator, Sequence
from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange
logger = logging.getLogger(__name__)
class MarketDataCacheFormat(str, enum.Enum):
CSV = "csv"
@dataclasses.dataclass()
class MarketDataCacheSettings:
base_cache_dir: Path = Path(os.getcwd()) / ".market_data_cache"
format_extension: MarketDataCacheFormat = MarketDataCacheFormat.CSV
field_names: Sequence[str] = (
"time",
"open",
"high",
"low",
"close",
"volume",
"is_complete",
"candle_source",
"volume_buy",
"volume_sell",
)
meta_extension: str = "meta"
@dataclasses.dataclass()
class FileMetaData:
cached_range_in_file: Dict[DatetimeRange, Path]
@contextlib.contextmanager
def meta_file_context(meta_file_path: Path) -> Generator[FileMetaData, None, None]:
try:
with open(meta_file_path, "rb") as f:
meta = pickle.load(f) # noqa:S301 # nosec
except FileNotFoundError:
logger.error("File %s was not found. Creating default.", meta_file_path)
meta = FileMetaData(cached_range_in_file={})
try:
yield meta
finally:
with open(meta_file_path, "wb") as f:
pickle.dump(meta, f)

View File

@@ -0,0 +1,4 @@
from datetime import datetime
from typing import Tuple
DatetimeRange = Tuple[datetime, datetime]

View File

@@ -0,0 +1,11 @@
import dataclasses
from typing import Iterable
from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange
from t_tech.invest.schemas import HistoricCandle
@dataclasses.dataclass()
class InstrumentDateRangeData:
date_range: DatetimeRange
historic_candles: Iterable[HistoricCandle]

View File

@@ -0,0 +1,291 @@
import csv
import dataclasses
import itertools
import logging
from datetime import datetime
from pathlib import Path
from typing import Dict, Generator, Iterable, Iterator, Optional, Tuple
import dateutil.parser
from t_tech.invest.caching.market_data_cache.cache_settings import (
MarketDataCacheSettings,
meta_file_context,
)
from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange
from t_tech.invest.caching.market_data_cache.instrument_date_range_market_data import (
InstrumentDateRangeData,
)
from t_tech.invest.caching.market_data_cache.interface import (
IInstrumentMarketDataStorage,
)
from t_tech.invest.caching.market_data_cache.serialization import custom_asdict_factory
from t_tech.invest.schemas import CandleInterval, HistoricCandle
from t_tech.invest.utils import dataclass_from_dict
logger = logging.getLogger(__name__)
class InstrumentMarketDataStorage(
IInstrumentMarketDataStorage[Iterable[InstrumentDateRangeData]]
):
def __init__(
self, figi: str, interval: CandleInterval, settings: MarketDataCacheSettings
):
self._figi = figi
self._interval = interval
self._settings = settings
self._settings.base_cache_dir.mkdir(parents=True, exist_ok=True)
self._meta_path = self._get_metafile(
file=self._get_base_file_path(figi=self._figi, interval=self._interval)
)
def _get_base_file_path(self, figi: str, interval: CandleInterval) -> Path:
instrument_dir = self._get_cache_dir_for_instrument(figi=figi)
instrument_dir.mkdir(parents=True, exist_ok=True)
return self._get_cache_file_for_instrument(
instrument_dir=instrument_dir, interval=interval
)
@staticmethod
def _datetime_to_safe_filename(dt: datetime) -> str:
return str(int(dt.timestamp()))
def _get_file_path(self, date_range: DatetimeRange) -> Path:
start, end = date_range
filepath = self._get_base_file_path(figi=self._figi, interval=self._interval)
start_str = self._datetime_to_safe_filename(start)
end_str = self._datetime_to_safe_filename(end)
filepath = filepath.parent / (filepath.name + f"-{start_str}-{end_str}")
return filepath.with_suffix(f".{self._settings.format_extension.value}")
def _get_metafile(self, file: Path) -> Path:
return file.with_suffix(f".{self._settings.meta_extension}")
def _get_cache_file_for_instrument(
self, instrument_dir: Path, interval: CandleInterval
) -> Path:
return instrument_dir / interval.name
def _get_cache_dir_for_instrument(self, figi: str) -> Path:
return self._settings.base_cache_dir / figi
def _get_range_from_file(
self, reader: Iterable[Dict], request_range: DatetimeRange
) -> Iterable[Dict]:
start, end = request_range
for row in reader:
row_time = dateutil.parser.parse(row["time"])
if start <= row_time <= end:
yield row
if end < row_time:
return
def _get_candles_from_cache(
self,
file: Path,
request_range: DatetimeRange,
) -> Generator[HistoricCandle, None, None]:
with open(file, "r") as infile: # pylint: disable=W1514
reader = csv.DictReader(infile, fieldnames=self._settings.field_names)
reader_iter = iter(reader)
next(reader_iter) # pylint: disable=R1708
for row in self._get_range_from_file(
reader_iter, request_range=request_range
):
yield self._candle_from_row(row)
def _order_rows(
self, dict_reader1: Iterator[Dict], dict_reader2: Iterator[Dict]
) -> Iterable[Dict]:
dict_reader_iter1 = iter(dict_reader1)
dict_reader_iter2 = iter(dict_reader2)
while True:
try:
candle_dict1 = next(dict_reader_iter1)
except StopIteration:
yield from dict_reader_iter2
break
try:
candle_dict2 = next(dict_reader_iter2)
except StopIteration:
yield from dict_reader_iter1
break
candle_dict_time1 = dateutil.parser.parse(candle_dict1["time"])
candle_dict_time2 = dateutil.parser.parse(candle_dict2["time"])
if candle_dict_time1 > candle_dict_time2:
dict_reader_iter1 = itertools.chain([candle_dict1], dict_reader_iter1)
yield candle_dict2
elif candle_dict_time1 < candle_dict_time2:
dict_reader_iter2 = itertools.chain([candle_dict2], dict_reader_iter2)
yield candle_dict1
else:
yield candle_dict1
def _order_candles(
self,
tmp_dict_reader: Iterator[Dict],
historic_candles: Iterable[HistoricCandle],
) -> Iterable[Dict]:
tmp_iter = iter(tmp_dict_reader)
candle_iter = iter(historic_candles)
while True:
try:
tmp_candle_dict = next(tmp_iter)
except StopIteration:
yield from [dataclasses.asdict(candle) for candle in candle_iter]
break
try:
candle = next(candle_iter)
except StopIteration:
yield from tmp_iter
break
tmp_candle_time = dateutil.parser.parse(tmp_candle_dict["time"])
if tmp_candle_time > candle.time:
tmp_iter = itertools.chain([tmp_candle_dict], tmp_iter)
yield dataclasses.asdict(candle)
elif tmp_candle_time < candle.time:
candle_iter = itertools.chain([candle], candle_iter)
yield tmp_candle_dict
else:
yield tmp_candle_dict
def _write_candles_file(self, data: InstrumentDateRangeData) -> Path:
file = self._get_file_path(date_range=data.date_range)
with open(file, mode="w") as csv_file: # pylint: disable=W1514
writer = csv.DictWriter(csv_file, fieldnames=self._settings.field_names)
writer.writeheader()
for candle in data.historic_candles:
writer.writerow(
dataclasses.asdict(candle, dict_factory=custom_asdict_factory)
)
return file
def _candle_from_row(self, row: Dict[str, str]) -> HistoricCandle:
return dataclass_from_dict(HistoricCandle, row)
def _get_intersection(
self,
request_range: DatetimeRange,
cached_range: DatetimeRange,
) -> Optional[DatetimeRange]:
request_start, request_end = request_range
cached_start, cached_end = cached_range
max_start = max(request_start, cached_start)
min_end = min(request_end, cached_end)
if max_start <= min_end:
return max_start, min_end
return None
def _merge_intersecting_files( # pylint: disable=R0914
self,
file1: Path,
range1: DatetimeRange,
file2: Path,
range2: DatetimeRange,
) -> Tuple[DatetimeRange, Path]:
new_range = (min(min(range1), min(range2)), max(max(range1), max(range2)))
new_file = self._get_file_path(date_range=new_range)
if new_file == file1:
file2.unlink()
return new_range, new_file
if new_file == file2:
file1.unlink()
return new_range, new_file
with open(file1, "r") as infile1: # pylint: disable=W1514
reader1 = csv.DictReader(infile1, fieldnames=self._settings.field_names)
reader_iter1 = iter(reader1)
next(reader_iter1) # skip header
with open(file2, "r") as infile2: # pylint: disable=W1514
reader2 = csv.DictReader(infile2, fieldnames=self._settings.field_names)
reader_iter2 = iter(reader2)
next(reader_iter2) # skip header
with open(new_file, mode="w") as csv_file: # pylint: disable=W1514
writer = csv.DictWriter(
csv_file, fieldnames=self._settings.field_names
)
writer.writeheader()
for candle_dict in self._order_rows(
dict_reader1=reader_iter1, dict_reader2=reader_iter2
):
writer.writerow(candle_dict)
file1.unlink()
file2.unlink()
return new_range, new_file
def _get_distinct_product(
self, cached_range_in_file: Dict[DatetimeRange, Path]
) -> Iterable[Tuple[Tuple[DatetimeRange, Path], Tuple[DatetimeRange, Path]]]:
sorted_items = self._get_cached_items_sorted_by_start(cached_range_in_file)
for i, items1 in enumerate(sorted_items): # pylint: disable=R1702
for j, items2 in enumerate(sorted_items):
if i < j:
yield items1, items2
def _try_merge_files(
self, cached_range_in_file: Dict[DatetimeRange, Path]
) -> Dict[DatetimeRange, Path]:
new_cached_range_in_file = cached_range_in_file.copy()
file_pairs = self._get_distinct_product(new_cached_range_in_file)
for (cached_range, cached_file), (cached_range2, cached_file2) in file_pairs:
intersection_range = self._get_intersection(
request_range=cached_range2, cached_range=cached_range
)
if intersection_range is not None:
merged_range, merged_file = self._merge_intersecting_files(
file1=cached_file,
range1=cached_range,
file2=cached_file2,
range2=cached_range2,
)
del new_cached_range_in_file[cached_range]
del new_cached_range_in_file[cached_range2]
new_cached_range_in_file[merged_range] = merged_file
return self._try_merge_files(new_cached_range_in_file)
return new_cached_range_in_file
def get(self, request_range: DatetimeRange) -> Iterable[InstrumentDateRangeData]:
with meta_file_context(meta_file_path=self._meta_path) as meta_file:
cached_range_in_file = meta_file.cached_range_in_file
for cached_range, cached_file in self._get_cached_items_sorted_by_start(
cached_range_in_file
):
intersection = self._get_intersection(
request_range=request_range, cached_range=cached_range
)
if intersection is not None:
candles = self._get_candles_from_cache(
cached_file, request_range=request_range
)
yield InstrumentDateRangeData(
date_range=intersection, historic_candles=candles
)
def update(self, data_list: Iterable[InstrumentDateRangeData]):
with meta_file_context(meta_file_path=self._meta_path) as meta_file:
for data in data_list:
new_file = self._write_candles_file(data)
meta_file.cached_range_in_file[data.date_range] = new_file
def merge(self):
with meta_file_context(meta_file_path=self._meta_path) as meta_file:
new_cached_range_in_file = self._try_merge_files(
meta_file.cached_range_in_file
)
meta_file.cached_range_in_file = new_cached_range_in_file
def _get_cached_items_sorted_by_start(
self, cached_range_in_file: Dict[DatetimeRange, Path]
) -> Iterable[Tuple[DatetimeRange, Path]]:
return sorted(cached_range_in_file.items(), key=lambda pair: pair[0][0])

View File

@@ -0,0 +1,13 @@
from typing import Protocol, TypeVar
from t_tech.invest.caching.market_data_cache.datetime_range import DatetimeRange
TInstrumentData = TypeVar("TInstrumentData")
class IInstrumentMarketDataStorage(Protocol[TInstrumentData]):
def get(self, request_range: DatetimeRange) -> TInstrumentData:
pass
def update(self, data_list: TInstrumentData):
pass

View File

@@ -0,0 +1,10 @@
from enum import Enum
def custom_asdict_factory(data):
def convert_value(obj):
if isinstance(obj, Enum):
return obj.value
return obj
return {k: convert_value(v) for k, v in data}

View File

@@ -0,0 +1,10 @@
import time
from cachetools import TTLCache as TTLCacheBase
class TTLCache(TTLCacheBase):
def __init__(self, maxsize, ttl, timer=None, getsizeof=None):
if timer is None:
timer = time.monotonic
super().__init__(maxsize=maxsize, ttl=ttl, timer=timer, getsizeof=getsizeof)

View File

@@ -0,0 +1,16 @@
from datetime import datetime
from typing import Generator, Optional, Protocol
from t_tech.invest import CandleInterval, HistoricCandle
class CandleGetter(Protocol):
def get_all_candles( # pragma: no cover
self,
*,
from_: datetime,
to: Optional[datetime],
interval: CandleInterval,
figi: str,
) -> Generator[HistoricCandle, None, None]:
pass

View File

@@ -0,0 +1,66 @@
import itertools
from typing import Any, Optional, Sequence
import grpc
from grpc.aio import ClientInterceptor
from .constants import (
INVEST_GRPC_API,
KEEPALIVE_MAX_PINGS,
KEEPALIVE_TIME_MS,
KEEPALIVE_TIMEOUT_MS,
MAX_RECEIVE_MESSAGE_LENGTH,
)
from .typedefs import ChannelArgumentType
__all__ = ("create_channel",)
_required_options: ChannelArgumentType = [
("grpc.max_receive_message_length", MAX_RECEIVE_MESSAGE_LENGTH),
("grpc.keepalive_time_ms", KEEPALIVE_TIME_MS),
("grpc.keepalive_timeout_ms", KEEPALIVE_TIMEOUT_MS),
("grpc.http2.max_pings_without_data", KEEPALIVE_MAX_PINGS),
]
def create_channel(
*,
target: Optional[str] = None,
options: Optional[ChannelArgumentType] = None,
force_async: bool = False,
compression: Optional[grpc.Compression] = None,
interceptors: Optional[Sequence[ClientInterceptor]] = None,
) -> Any:
creds = grpc.ssl_channel_credentials()
target = target or INVEST_GRPC_API
if options is None:
options = []
options = _with_options(options, _required_options)
args = (target, creds, options, compression)
if force_async:
return grpc.aio.secure_channel(*args, interceptors=interceptors)
return grpc.secure_channel(*args)
def _with_options(options: ChannelArgumentType, _required_options: ChannelArgumentType):
for option in _required_options:
options = _with_option(options, option[0], option[1])
return options
def _with_option(
options: ChannelArgumentType, key: str, value: Any
) -> ChannelArgumentType:
if not _contains_option(options, key):
option = (key, value)
return list(itertools.chain(options, [option]))
return options
def _contains_option(options: ChannelArgumentType, expected_option_name: str) -> bool:
for option_name, _ in options:
if option_name == expected_option_name:
return True
return False

View File

@@ -0,0 +1,121 @@
from typing import List, Optional
import grpc
from grpc.aio import ClientInterceptor
from ._error_hub import async_init_error_hub, init_error_hub
from .async_services import AsyncServices
from .channels import create_channel
from .constants import INVEST_GRPC_API
from .services import Services
from .typedefs import ChannelArgumentType
__all__ = ("Client", "AsyncClient")
class Client:
"""Sync client.
```python
import os
from tinkoff.invest import Client
TOKEN = os.environ["INVEST_TOKEN"]
def main():
with Client(TOKEN) as client:
print(client.users.get_accounts())
```
"""
def __init__(
self,
token: str,
*,
target: Optional[str] = None,
sandbox_token: Optional[str] = None,
options: Optional[ChannelArgumentType] = None,
app_name: Optional[str] = None,
interceptors: Optional[List[ClientInterceptor]] = None,
):
self._token = token
self._sandbox_token = sandbox_token
self._options = options
self._app_name = app_name
self._target = target or INVEST_GRPC_API
self._channel = create_channel(target=target, options=options)
if interceptors is None:
interceptors = []
for interceptor in interceptors:
self._channel = grpc.intercept_channel(self._channel, interceptor)
def __enter__(self) -> Services:
init_error_hub(self)
channel = self._channel.__enter__()
return Services(
channel,
token=self._token,
sandbox_token=self._sandbox_token,
app_name=self._app_name,
)
def __exit__(self, exc_type, exc_val, exc_tb):
self._channel.__exit__(exc_type, exc_val, exc_tb)
return False
class AsyncClient:
"""Async client.
```python
import asyncio
import os
from tinkoff.invest import AsyncClient
TOKEN = os.environ["INVEST_TOKEN"]
async def main():
async with AsyncClient(TOKEN) as client:
print(await client.users.get_accounts())
if __name__ == "__main__":
asyncio.run(main())
```
"""
def __init__(
self,
token: str,
*,
target: Optional[str] = None,
sandbox_token: Optional[str] = None,
options: Optional[ChannelArgumentType] = None,
app_name: Optional[str] = None,
interceptors: Optional[List[ClientInterceptor]] = None,
):
self._token = token
self._sandbox_token = sandbox_token
self._options = options
self._app_name = app_name
self._target = target or INVEST_GRPC_API
self._channel = create_channel(
target=target, force_async=True, options=options, interceptors=interceptors
)
async def __aenter__(self) -> AsyncServices:
await async_init_error_hub(self)
channel = await self._channel.__aenter__()
return AsyncServices(
channel,
token=self._token,
sandbox_token=self._sandbox_token,
app_name=self._app_name,
)
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self._channel.__aexit__(exc_type, exc_val, exc_tb)
return False

View File

@@ -0,0 +1,16 @@
INVEST_GRPC_API = "invest-public-api.tinkoff.ru"
INVEST_GRPC_API_SANDBOX = "sandbox-invest-public-api.tinkoff.ru"
APP_VERSION = "0.3.5"
APP_NAME = f"t-tech.invest-python-{APP_VERSION}"
PACKAGE_NAME = f"t-tech.invest@{APP_VERSION.replace('-beta', '+')}"
X_TRACKING_ID = "x-tracking-id"
X_RATELIMIT_LIMIT = "x-ratelimit-limit"
X_RATELIMIT_REMAINING = "x-ratelimit-remaining"
X_RATELIMIT_RESET = "x-ratelimit-reset"
MESSAGE = "message"
MEGABYTE = 1024 * 1024
MAX_RECEIVE_MESSAGE_LENGTH = 10 * MEGABYTE
ERROR_HUB_DSN = "https://invest-piapi-errorhub@error-hub.tbank.ru/00000000"
KEEPALIVE_TIME_MS = 1000
KEEPALIVE_TIMEOUT_MS = 20000
KEEPALIVE_MAX_PINGS = 120

View File

@@ -0,0 +1,49 @@
from typing import Any
from grpc import StatusCode
__all__ = (
"InvestError",
"RequestError",
"AioRequestError",
"UnauthenticatedError",
"AioUnauthenticatedError",
)
class InvestError(Exception):
pass
class RequestError(InvestError):
def __init__( # pylint:disable=super-init-not-called
self, code: StatusCode, details: str, metadata: Any
) -> None:
self.code = code
self.details = details
self.metadata = metadata
class UnauthenticatedError(RequestError):
pass
class AioRequestError(InvestError):
def __init__( # pylint:disable=super-init-not-called
self, code: StatusCode, details: str, metadata: Any
) -> None:
self.code = code
self.details = details
self.metadata = metadata
class AioUnauthenticatedError(AioRequestError):
pass
class MarketDataStreamError(InvestError):
pass
class IsNotSubscribedError(MarketDataStreamError):
pass

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: t_tech/invest/grpc/common.proto
# Protobuf Python Version: 4.25.1
"""Generated protocol buffer code."""
from google.protobuf import (
descriptor as _descriptor,
descriptor_pool as _descriptor_pool,
symbol_database as _symbol_database,
)
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ft_tech/invest/grpc/common.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1fgoogle/protobuf/timestamp.proto\";\n\nMoneyValue\x12\x10\n\x08\x63urrency\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\x0c\n\x04nano\x18\x03 \x01(\x05\"(\n\tQuotation\x12\r\n\x05units\x18\x01 \x01(\x03\x12\x0c\n\x04nano\x18\x02 \x01(\x05\"E\n\x0bPingRequest\x12-\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x42\x07\n\x05_time\"A\n\x11PingDelaySettings\x12\x1a\n\rping_delay_ms\x18\x0f \x01(\x05H\x00\x88\x01\x01\x42\x10\n\x0e_ping_delay_ms\"\x95\x01\n\x04Ping\x12(\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\tstream_id\x18\x02 \x01(\t\x12:\n\x11ping_request_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x88\x01\x01\x42\x14\n\x12_ping_request_time\"*\n\x04Page\x12\r\n\x05limit\x18\x01 \x01(\x05\x12\x13\n\x0bpage_number\x18\x02 \x01(\x05\"G\n\x0cPageResponse\x12\r\n\x05limit\x18\x01 \x01(\x05\x12\x13\n\x0bpage_number\x18\x02 \x01(\x05\x12\x13\n\x0btotal_count\x18\x03 \x01(\x05\"X\n\x10ResponseMetadata\x12\x13\n\x0btracking_id\x18* \x01(\t\x12/\n\x0bserver_time\x18+ \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"K\n\tBrandData\x12\x11\n\tlogo_name\x18\x01 \x01(\t\x12\x17\n\x0flogo_base_color\x18\x02 \x01(\t\x12\x12\n\ntext_color\x18\x03 \x01(\t\",\n\x0b\x45rrorDetail\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x03 \x01(\t*\xeb\x02\n\x0eInstrumentType\x12\x1f\n\x1bINSTRUMENT_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14INSTRUMENT_TYPE_BOND\x10\x01\x12\x19\n\x15INSTRUMENT_TYPE_SHARE\x10\x02\x12\x1c\n\x18INSTRUMENT_TYPE_CURRENCY\x10\x03\x12\x17\n\x13INSTRUMENT_TYPE_ETF\x10\x04\x12\x1b\n\x17INSTRUMENT_TYPE_FUTURES\x10\x05\x12\x16\n\x12INSTRUMENT_TYPE_SP\x10\x06\x12\x1a\n\x16INSTRUMENT_TYPE_OPTION\x10\x07\x12(\n$INSTRUMENT_TYPE_CLEARING_CERTIFICATE\x10\x08\x12\x19\n\x15INSTRUMENT_TYPE_INDEX\x10\t\x12\x1d\n\x19INSTRUMENT_TYPE_COMMODITY\x10\n\x12\x17\n\x13INSTRUMENT_TYPE_DFA\x10\x0b*l\n\x10InstrumentStatus\x12!\n\x1dINSTRUMENT_STATUS_UNSPECIFIED\x10\x00\x12\x1a\n\x16INSTRUMENT_STATUS_BASE\x10\x01\x12\x19\n\x15INSTRUMENT_STATUS_ALL\x10\x02*\x81\x07\n\x15SecurityTradingStatus\x12\'\n#SECURITY_TRADING_STATUS_UNSPECIFIED\x10\x00\x12\x35\n1SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING\x10\x01\x12*\n&SECURITY_TRADING_STATUS_OPENING_PERIOD\x10\x02\x12*\n&SECURITY_TRADING_STATUS_CLOSING_PERIOD\x10\x03\x12,\n(SECURITY_TRADING_STATUS_BREAK_IN_TRADING\x10\x04\x12*\n&SECURITY_TRADING_STATUS_NORMAL_TRADING\x10\x05\x12+\n\'SECURITY_TRADING_STATUS_CLOSING_AUCTION\x10\x06\x12-\n)SECURITY_TRADING_STATUS_DARK_POOL_AUCTION\x10\x07\x12,\n(SECURITY_TRADING_STATUS_DISCRETE_AUCTION\x10\x08\x12\x32\n.SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD\x10\t\x12<\n8SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE\x10\n\x12,\n(SECURITY_TRADING_STATUS_SESSION_ASSIGNED\x10\x0b\x12)\n%SECURITY_TRADING_STATUS_SESSION_CLOSE\x10\x0c\x12(\n$SECURITY_TRADING_STATUS_SESSION_OPEN\x10\r\x12\x31\n-SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING\x10\x0e\x12\x33\n/SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING\x10\x0f\x12<\n8SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING\x10\x10\x12\x31\n-SECURITY_TRADING_STATUS_STABILIZATION_AUCTION\x10\x11*V\n\tPriceType\x12\x1a\n\x16PRICE_TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10PRICE_TYPE_POINT\x10\x01\x12\x17\n\x13PRICE_TYPE_CURRENCY\x10\x02*\x8f\x01\n\x18ResultSubscriptionStatus\x12*\n&RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED\x10\x00\x12!\n\x1dRESULT_SUBSCRIPTION_STATUS_OK\x10\x01\x12$\n RESULT_SUBSCRIPTION_STATUS_ERROR\x10\r*\x8d\x01\n\x0cRealExchange\x12\x1d\n\x19REAL_EXCHANGE_UNSPECIFIED\x10\x00\x12\x16\n\x12REAL_EXCHANGE_MOEX\x10\x01\x12\x15\n\x11REAL_EXCHANGE_RTS\x10\x02\x12\x15\n\x11REAL_EXCHANGE_OTC\x10\x03\x12\x18\n\x14REAL_EXCHANGE_DEALER\x10\x04\x42\x61\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.common_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
_globals['DESCRIPTOR']._options = None
_globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1'
_globals['_INSTRUMENTTYPE']._serialized_start=831
_globals['_INSTRUMENTTYPE']._serialized_end=1194
_globals['_INSTRUMENTSTATUS']._serialized_start=1196
_globals['_INSTRUMENTSTATUS']._serialized_end=1304
_globals['_SECURITYTRADINGSTATUS']._serialized_start=1307
_globals['_SECURITYTRADINGSTATUS']._serialized_end=2204
_globals['_PRICETYPE']._serialized_start=2206
_globals['_PRICETYPE']._serialized_end=2292
_globals['_RESULTSUBSCRIPTIONSTATUS']._serialized_start=2295
_globals['_RESULTSUBSCRIPTIONSTATUS']._serialized_end=2438
_globals['_REALEXCHANGE']._serialized_start=2441
_globals['_REALEXCHANGE']._serialized_end=2582
_globals['_MONEYVALUE']._serialized_start=107
_globals['_MONEYVALUE']._serialized_end=166
_globals['_QUOTATION']._serialized_start=168
_globals['_QUOTATION']._serialized_end=208
_globals['_PINGREQUEST']._serialized_start=210
_globals['_PINGREQUEST']._serialized_end=279
_globals['_PINGDELAYSETTINGS']._serialized_start=281
_globals['_PINGDELAYSETTINGS']._serialized_end=346
_globals['_PING']._serialized_start=349
_globals['_PING']._serialized_end=498
_globals['_PAGE']._serialized_start=500
_globals['_PAGE']._serialized_end=542
_globals['_PAGERESPONSE']._serialized_start=544
_globals['_PAGERESPONSE']._serialized_end=615
_globals['_RESPONSEMETADATA']._serialized_start=617
_globals['_RESPONSEMETADATA']._serialized_end=705
_globals['_BRANDDATA']._serialized_start=707
_globals['_BRANDDATA']._serialized_end=782
_globals['_ERRORDETAIL']._serialized_start=784
_globals['_ERRORDETAIL']._serialized_end=828
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,493 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import google.protobuf.timestamp_pb2
import sys
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _InstrumentType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _InstrumentTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
INSTRUMENT_TYPE_UNSPECIFIED: _InstrumentType.ValueType # 0
INSTRUMENT_TYPE_BOND: _InstrumentType.ValueType # 1
"""Облигация."""
INSTRUMENT_TYPE_SHARE: _InstrumentType.ValueType # 2
"""Акция."""
INSTRUMENT_TYPE_CURRENCY: _InstrumentType.ValueType # 3
"""Валюта."""
INSTRUMENT_TYPE_ETF: _InstrumentType.ValueType # 4
"""Exchange-traded fund. Фонд."""
INSTRUMENT_TYPE_FUTURES: _InstrumentType.ValueType # 5
"""Фьючерс."""
INSTRUMENT_TYPE_SP: _InstrumentType.ValueType # 6
"""Структурная нота."""
INSTRUMENT_TYPE_OPTION: _InstrumentType.ValueType # 7
"""Опцион."""
INSTRUMENT_TYPE_CLEARING_CERTIFICATE: _InstrumentType.ValueType # 8
"""Clearing certificate."""
INSTRUMENT_TYPE_INDEX: _InstrumentType.ValueType # 9
"""Индекс."""
INSTRUMENT_TYPE_COMMODITY: _InstrumentType.ValueType # 10
"""Товар."""
INSTRUMENT_TYPE_DFA: _InstrumentType.ValueType # 11
"""Цифровой актив."""
class InstrumentType(_InstrumentType, metaclass=_InstrumentTypeEnumTypeWrapper):
"""Тип инструмента."""
INSTRUMENT_TYPE_UNSPECIFIED: InstrumentType.ValueType # 0
INSTRUMENT_TYPE_BOND: InstrumentType.ValueType # 1
"""Облигация."""
INSTRUMENT_TYPE_SHARE: InstrumentType.ValueType # 2
"""Акция."""
INSTRUMENT_TYPE_CURRENCY: InstrumentType.ValueType # 3
"""Валюта."""
INSTRUMENT_TYPE_ETF: InstrumentType.ValueType # 4
"""Exchange-traded fund. Фонд."""
INSTRUMENT_TYPE_FUTURES: InstrumentType.ValueType # 5
"""Фьючерс."""
INSTRUMENT_TYPE_SP: InstrumentType.ValueType # 6
"""Структурная нота."""
INSTRUMENT_TYPE_OPTION: InstrumentType.ValueType # 7
"""Опцион."""
INSTRUMENT_TYPE_CLEARING_CERTIFICATE: InstrumentType.ValueType # 8
"""Clearing certificate."""
INSTRUMENT_TYPE_INDEX: InstrumentType.ValueType # 9
"""Индекс."""
INSTRUMENT_TYPE_COMMODITY: InstrumentType.ValueType # 10
"""Товар."""
INSTRUMENT_TYPE_DFA: InstrumentType.ValueType # 11
"""Цифровой актив."""
global___InstrumentType = InstrumentType
class _InstrumentStatus:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _InstrumentStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InstrumentStatus.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
INSTRUMENT_STATUS_UNSPECIFIED: _InstrumentStatus.ValueType # 0
"""Значение не определено."""
INSTRUMENT_STATUS_BASE: _InstrumentStatus.ValueType # 1
"""По умолчанию — базовый список инструментов, которыми можно торговать через T-Invest API. Сейчас списки доступных бумаг в API и других интерфейсах совпадают — кроме внебиржевых бумаг, но в будущем списки могут различаться."""
INSTRUMENT_STATUS_ALL: _InstrumentStatus.ValueType # 2
"""Список всех инструментов."""
class InstrumentStatus(_InstrumentStatus, metaclass=_InstrumentStatusEnumTypeWrapper):
"""Статус запрашиваемых инструментов."""
INSTRUMENT_STATUS_UNSPECIFIED: InstrumentStatus.ValueType # 0
"""Значение не определено."""
INSTRUMENT_STATUS_BASE: InstrumentStatus.ValueType # 1
"""По умолчанию — базовый список инструментов, которыми можно торговать через T-Invest API. Сейчас списки доступных бумаг в API и других интерфейсах совпадают — кроме внебиржевых бумаг, но в будущем списки могут различаться."""
INSTRUMENT_STATUS_ALL: InstrumentStatus.ValueType # 2
"""Список всех инструментов."""
global___InstrumentStatus = InstrumentStatus
class _SecurityTradingStatus:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _SecurityTradingStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SecurityTradingStatus.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
SECURITY_TRADING_STATUS_UNSPECIFIED: _SecurityTradingStatus.ValueType # 0
"""Торговый статус не определен."""
SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING: _SecurityTradingStatus.ValueType # 1
"""Недоступен для торгов."""
SECURITY_TRADING_STATUS_OPENING_PERIOD: _SecurityTradingStatus.ValueType # 2
"""Период открытия торгов."""
SECURITY_TRADING_STATUS_CLOSING_PERIOD: _SecurityTradingStatus.ValueType # 3
"""Период закрытия торгов."""
SECURITY_TRADING_STATUS_BREAK_IN_TRADING: _SecurityTradingStatus.ValueType # 4
"""Перерыв в торговле."""
SECURITY_TRADING_STATUS_NORMAL_TRADING: _SecurityTradingStatus.ValueType # 5
"""Нормальная торговля."""
SECURITY_TRADING_STATUS_CLOSING_AUCTION: _SecurityTradingStatus.ValueType # 6
"""Аукцион закрытия."""
SECURITY_TRADING_STATUS_DARK_POOL_AUCTION: _SecurityTradingStatus.ValueType # 7
"""Аукцион крупных пакетов."""
SECURITY_TRADING_STATUS_DISCRETE_AUCTION: _SecurityTradingStatus.ValueType # 8
"""Дискретный аукцион."""
SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD: _SecurityTradingStatus.ValueType # 9
"""Аукцион открытия."""
SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE: _SecurityTradingStatus.ValueType # 10
"""Период торгов по цене аукциона закрытия."""
SECURITY_TRADING_STATUS_SESSION_ASSIGNED: _SecurityTradingStatus.ValueType # 11
"""Сессия назначена."""
SECURITY_TRADING_STATUS_SESSION_CLOSE: _SecurityTradingStatus.ValueType # 12
"""Сессия закрыта."""
SECURITY_TRADING_STATUS_SESSION_OPEN: _SecurityTradingStatus.ValueType # 13
"""Сессия открыта."""
SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING: _SecurityTradingStatus.ValueType # 14
"""Доступна торговля в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING: _SecurityTradingStatus.ValueType # 15
"""Перерыв торговли в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING: _SecurityTradingStatus.ValueType # 16
"""Недоступна торговля в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_STABILIZATION_AUCTION: _SecurityTradingStatus.ValueType # 17
"""Аукцион обновления цен."""
class SecurityTradingStatus(_SecurityTradingStatus, metaclass=_SecurityTradingStatusEnumTypeWrapper):
"""Режим торгов инструмента"""
SECURITY_TRADING_STATUS_UNSPECIFIED: SecurityTradingStatus.ValueType # 0
"""Торговый статус не определен."""
SECURITY_TRADING_STATUS_NOT_AVAILABLE_FOR_TRADING: SecurityTradingStatus.ValueType # 1
"""Недоступен для торгов."""
SECURITY_TRADING_STATUS_OPENING_PERIOD: SecurityTradingStatus.ValueType # 2
"""Период открытия торгов."""
SECURITY_TRADING_STATUS_CLOSING_PERIOD: SecurityTradingStatus.ValueType # 3
"""Период закрытия торгов."""
SECURITY_TRADING_STATUS_BREAK_IN_TRADING: SecurityTradingStatus.ValueType # 4
"""Перерыв в торговле."""
SECURITY_TRADING_STATUS_NORMAL_TRADING: SecurityTradingStatus.ValueType # 5
"""Нормальная торговля."""
SECURITY_TRADING_STATUS_CLOSING_AUCTION: SecurityTradingStatus.ValueType # 6
"""Аукцион закрытия."""
SECURITY_TRADING_STATUS_DARK_POOL_AUCTION: SecurityTradingStatus.ValueType # 7
"""Аукцион крупных пакетов."""
SECURITY_TRADING_STATUS_DISCRETE_AUCTION: SecurityTradingStatus.ValueType # 8
"""Дискретный аукцион."""
SECURITY_TRADING_STATUS_OPENING_AUCTION_PERIOD: SecurityTradingStatus.ValueType # 9
"""Аукцион открытия."""
SECURITY_TRADING_STATUS_TRADING_AT_CLOSING_AUCTION_PRICE: SecurityTradingStatus.ValueType # 10
"""Период торгов по цене аукциона закрытия."""
SECURITY_TRADING_STATUS_SESSION_ASSIGNED: SecurityTradingStatus.ValueType # 11
"""Сессия назначена."""
SECURITY_TRADING_STATUS_SESSION_CLOSE: SecurityTradingStatus.ValueType # 12
"""Сессия закрыта."""
SECURITY_TRADING_STATUS_SESSION_OPEN: SecurityTradingStatus.ValueType # 13
"""Сессия открыта."""
SECURITY_TRADING_STATUS_DEALER_NORMAL_TRADING: SecurityTradingStatus.ValueType # 14
"""Доступна торговля в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_DEALER_BREAK_IN_TRADING: SecurityTradingStatus.ValueType # 15
"""Перерыв торговли в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_DEALER_NOT_AVAILABLE_FOR_TRADING: SecurityTradingStatus.ValueType # 16
"""Недоступна торговля в режиме внутренней ликвидности брокера."""
SECURITY_TRADING_STATUS_STABILIZATION_AUCTION: SecurityTradingStatus.ValueType # 17
"""Аукцион обновления цен."""
global___SecurityTradingStatus = SecurityTradingStatus
class _PriceType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _PriceTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PriceType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
PRICE_TYPE_UNSPECIFIED: _PriceType.ValueType # 0
"""Значение не определено."""
PRICE_TYPE_POINT: _PriceType.ValueType # 1
"""Цена в пунктах (только для фьючерсов и облигаций)."""
PRICE_TYPE_CURRENCY: _PriceType.ValueType # 2
"""Цена в валюте расчетов по инструменту."""
class PriceType(_PriceType, metaclass=_PriceTypeEnumTypeWrapper):
"""Тип цены."""
PRICE_TYPE_UNSPECIFIED: PriceType.ValueType # 0
"""Значение не определено."""
PRICE_TYPE_POINT: PriceType.ValueType # 1
"""Цена в пунктах (только для фьючерсов и облигаций)."""
PRICE_TYPE_CURRENCY: PriceType.ValueType # 2
"""Цена в валюте расчетов по инструменту."""
global___PriceType = PriceType
class _ResultSubscriptionStatus:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _ResultSubscriptionStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ResultSubscriptionStatus.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED: _ResultSubscriptionStatus.ValueType # 0
"""Статус подписки не определен."""
RESULT_SUBSCRIPTION_STATUS_OK: _ResultSubscriptionStatus.ValueType # 1
"""Подписка успешно установлена."""
RESULT_SUBSCRIPTION_STATUS_ERROR: _ResultSubscriptionStatus.ValueType # 13
"""Ошибка подписки"""
class ResultSubscriptionStatus(_ResultSubscriptionStatus, metaclass=_ResultSubscriptionStatusEnumTypeWrapper): ...
RESULT_SUBSCRIPTION_STATUS_UNSPECIFIED: ResultSubscriptionStatus.ValueType # 0
"""Статус подписки не определен."""
RESULT_SUBSCRIPTION_STATUS_OK: ResultSubscriptionStatus.ValueType # 1
"""Подписка успешно установлена."""
RESULT_SUBSCRIPTION_STATUS_ERROR: ResultSubscriptionStatus.ValueType # 13
"""Ошибка подписки"""
global___ResultSubscriptionStatus = ResultSubscriptionStatus
class _RealExchange:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _RealExchangeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_RealExchange.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
REAL_EXCHANGE_UNSPECIFIED: _RealExchange.ValueType # 0
"""Тип не определен."""
REAL_EXCHANGE_MOEX: _RealExchange.ValueType # 1
"""Московская биржа."""
REAL_EXCHANGE_RTS: _RealExchange.ValueType # 2
"""Санкт-Петербургская биржа."""
REAL_EXCHANGE_OTC: _RealExchange.ValueType # 3
"""Внебиржевой инструмент."""
REAL_EXCHANGE_DEALER: _RealExchange.ValueType # 4
"""Инструмент, торгуемый на площадке брокера."""
class RealExchange(_RealExchange, metaclass=_RealExchangeEnumTypeWrapper):
"""Реальная площадка исполнения расчетов."""
REAL_EXCHANGE_UNSPECIFIED: RealExchange.ValueType # 0
"""Тип не определен."""
REAL_EXCHANGE_MOEX: RealExchange.ValueType # 1
"""Московская биржа."""
REAL_EXCHANGE_RTS: RealExchange.ValueType # 2
"""Санкт-Петербургская биржа."""
REAL_EXCHANGE_OTC: RealExchange.ValueType # 3
"""Внебиржевой инструмент."""
REAL_EXCHANGE_DEALER: RealExchange.ValueType # 4
"""Инструмент, торгуемый на площадке брокера."""
global___RealExchange = RealExchange
@typing.final
class MoneyValue(google.protobuf.message.Message):
"""Денежная сумма в определенной валюте."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
CURRENCY_FIELD_NUMBER: builtins.int
UNITS_FIELD_NUMBER: builtins.int
NANO_FIELD_NUMBER: builtins.int
currency: builtins.str
"""Строковый ISO-код валюты."""
units: builtins.int
"""Целая часть суммы, может быть отрицательным числом."""
nano: builtins.int
"""Дробная часть суммы, может быть отрицательным числом."""
def __init__(
self,
*,
currency: builtins.str = ...,
units: builtins.int = ...,
nano: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["currency", b"currency", "nano", b"nano", "units", b"units"]) -> None: ...
global___MoneyValue = MoneyValue
@typing.final
class Quotation(google.protobuf.message.Message):
"""Котировка — денежная сумма без указания валюты."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
UNITS_FIELD_NUMBER: builtins.int
NANO_FIELD_NUMBER: builtins.int
units: builtins.int
"""Целая часть суммы, может быть отрицательным числом."""
nano: builtins.int
"""Дробная часть суммы, может быть отрицательным числом."""
def __init__(
self,
*,
units: builtins.int = ...,
nano: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["nano", b"nano", "units", b"units"]) -> None: ...
global___Quotation = Quotation
@typing.final
class PingRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TIME_FIELD_NUMBER: builtins.int
@property
def time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Время формирования запроса."""
def __init__(
self,
*,
time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_time", b"_time", "time", b"time"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_time", b"_time", "time", b"time"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_time", b"_time"]) -> typing.Literal["time"] | None: ...
global___PingRequest = PingRequest
@typing.final
class PingDelaySettings(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
PING_DELAY_MS_FIELD_NUMBER: builtins.int
ping_delay_ms: builtins.int
"""Задержка (пинг) сообщений: 5000180 000 миллисекунд. Значение по умолчанию — 120 000."""
def __init__(
self,
*,
ping_delay_ms: builtins.int | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "ping_delay_ms", b"ping_delay_ms"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_ping_delay_ms", b"_ping_delay_ms", "ping_delay_ms", b"ping_delay_ms"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_ping_delay_ms", b"_ping_delay_ms"]) -> typing.Literal["ping_delay_ms"] | None: ...
global___PingDelaySettings = PingDelaySettings
@typing.final
class Ping(google.protobuf.message.Message):
"""Проверка активности стрима."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TIME_FIELD_NUMBER: builtins.int
STREAM_ID_FIELD_NUMBER: builtins.int
PING_REQUEST_TIME_FIELD_NUMBER: builtins.int
stream_id: builtins.str
"""Идентификатор соединения."""
@property
def time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Время проверки."""
@property
def ping_request_time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Время формирования запроса."""
def __init__(
self,
*,
time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
stream_id: builtins.str = ...,
ping_request_time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_ping_request_time", b"_ping_request_time", "ping_request_time", b"ping_request_time", "time", b"time"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_ping_request_time", b"_ping_request_time", "ping_request_time", b"ping_request_time", "stream_id", b"stream_id", "time", b"time"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_ping_request_time", b"_ping_request_time"]) -> typing.Literal["ping_request_time"] | None: ...
global___Ping = Ping
@typing.final
class Page(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LIMIT_FIELD_NUMBER: builtins.int
PAGE_NUMBER_FIELD_NUMBER: builtins.int
limit: builtins.int
"""Максимальное число возвращаемых записей."""
page_number: builtins.int
"""Порядковый номер страницы, начиная с 0."""
def __init__(
self,
*,
limit: builtins.int = ...,
page_number: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["limit", b"limit", "page_number", b"page_number"]) -> None: ...
global___Page = Page
@typing.final
class PageResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LIMIT_FIELD_NUMBER: builtins.int
PAGE_NUMBER_FIELD_NUMBER: builtins.int
TOTAL_COUNT_FIELD_NUMBER: builtins.int
limit: builtins.int
"""Максимальное число возвращаемых записей."""
page_number: builtins.int
"""Порядковый номер страницы, начиная с 0."""
total_count: builtins.int
"""Общее количество записей."""
def __init__(
self,
*,
limit: builtins.int = ...,
page_number: builtins.int = ...,
total_count: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["limit", b"limit", "page_number", b"page_number", "total_count", b"total_count"]) -> None: ...
global___PageResponse = PageResponse
@typing.final
class ResponseMetadata(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TRACKING_ID_FIELD_NUMBER: builtins.int
SERVER_TIME_FIELD_NUMBER: builtins.int
tracking_id: builtins.str
"""Идентификатор трекинга."""
@property
def server_time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Серверное время."""
def __init__(
self,
*,
tracking_id: builtins.str = ...,
server_time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["server_time", b"server_time"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["server_time", b"server_time", "tracking_id", b"tracking_id"]) -> None: ...
global___ResponseMetadata = ResponseMetadata
@typing.final
class BrandData(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LOGO_NAME_FIELD_NUMBER: builtins.int
LOGO_BASE_COLOR_FIELD_NUMBER: builtins.int
TEXT_COLOR_FIELD_NUMBER: builtins.int
logo_name: builtins.str
"""Логотип инструмента. Имя файла для получения логотипа."""
logo_base_color: builtins.str
""" Цвет бренда."""
text_color: builtins.str
"""Цвет текста для цвета логотипа бренда."""
def __init__(
self,
*,
logo_name: builtins.str = ...,
logo_base_color: builtins.str = ...,
text_color: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["logo_base_color", b"logo_base_color", "logo_name", b"logo_name", "text_color", b"text_color"]) -> None: ...
global___BrandData = BrandData
@typing.final
class ErrorDetail(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
CODE_FIELD_NUMBER: builtins.int
MESSAGE_FIELD_NUMBER: builtins.int
code: builtins.str
"""Код ошибки."""
message: builtins.str
"""Описание ошибки."""
def __init__(
self,
*,
code: builtins.str = ...,
message: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["code", b"code", "message", b"message"]) -> None: ...
global___ErrorDetail = ErrorDetail

View File

@@ -0,0 +1,4 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: t_tech/invest/grpc/google/api/field_behavior.proto
# Protobuf Python Version: 4.25.1
"""Generated protocol buffer code."""
from google.protobuf import (
descriptor as _descriptor,
descriptor_pool as _descriptor_pool,
symbol_database as _symbol_database,
)
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2t_tech/invest/grpc/google/api/field_behavior.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto*\xa6\x01\n\rFieldBehavior\x12\x1e\n\x1a\x46IELD_BEHAVIOR_UNSPECIFIED\x10\x00\x12\x0c\n\x08OPTIONAL\x10\x01\x12\x0c\n\x08REQUIRED\x10\x02\x12\x0f\n\x0bOUTPUT_ONLY\x10\x03\x12\x0e\n\nINPUT_ONLY\x10\x04\x12\r\n\tIMMUTABLE\x10\x05\x12\x12\n\x0eUNORDERED_LIST\x10\x06\x12\x15\n\x11NON_EMPTY_DEFAULT\x10\x07:Q\n\x0e\x66ield_behavior\x12\x1d.google.protobuf.FieldOptions\x18\x9c\x08 \x03(\x0e\x32\x19.google.api.FieldBehaviorBp\n\x0e\x63om.google.apiB\x12\x46ieldBehaviorProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.google.api.field_behavior_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
_globals['DESCRIPTOR']._options = None
_globals['DESCRIPTOR']._serialized_options = b'\n\016com.google.apiB\022FieldBehaviorProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI'
_globals['_FIELDBEHAVIOR']._serialized_start=101
_globals['_FIELDBEHAVIOR']._serialized_end=267
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,147 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.descriptor_pb2
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.internal.extension_dict
import sys
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _FieldBehavior:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _FieldBehaviorEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FieldBehavior.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
FIELD_BEHAVIOR_UNSPECIFIED: _FieldBehavior.ValueType # 0
"""Conventional default for enums. Do not use this."""
OPTIONAL: _FieldBehavior.ValueType # 1
"""Specifically denotes a field as optional.
While all fields in protocol buffers are optional, this may be specified
for emphasis if appropriate.
"""
REQUIRED: _FieldBehavior.ValueType # 2
"""Denotes a field as required.
This indicates that the field **must** be provided as part of the request,
and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
"""
OUTPUT_ONLY: _FieldBehavior.ValueType # 3
"""Denotes a field as output only.
This indicates that the field is provided in responses, but including the
field in a request does nothing (the server *must* ignore it and
*must not* throw an error as a result of the field's presence).
"""
INPUT_ONLY: _FieldBehavior.ValueType # 4
"""Denotes a field as input only.
This indicates that the field is provided in requests, and the
corresponding field is not included in output.
"""
IMMUTABLE: _FieldBehavior.ValueType # 5
"""Denotes a field as immutable.
This indicates that the field may be set once in a request to create a
resource, but may not be changed thereafter.
"""
UNORDERED_LIST: _FieldBehavior.ValueType # 6
"""Denotes that a (repeated) field is an unordered list.
This indicates that the service may provide the elements of the list
in any arbitrary order, rather than the order the user originally
provided. Additionally, the list's order may or may not be stable.
"""
NON_EMPTY_DEFAULT: _FieldBehavior.ValueType # 7
"""Denotes that this field returns a non-empty default value if not set.
This indicates that if the user provides the empty value in a request,
a non-empty value will be returned. The user will not be aware of what
non-empty value to expect.
"""
class FieldBehavior(_FieldBehavior, metaclass=_FieldBehaviorEnumTypeWrapper):
"""An indicator of the behavior of a given field (for example, that a field
is required in requests, or given as output but ignored as input).
This **does not** change the behavior in protocol buffers itself; it only
denotes the behavior and may affect how API tooling handles the field.
Note: This enum **may** receive new values in the future.
"""
FIELD_BEHAVIOR_UNSPECIFIED: FieldBehavior.ValueType # 0
"""Conventional default for enums. Do not use this."""
OPTIONAL: FieldBehavior.ValueType # 1
"""Specifically denotes a field as optional.
While all fields in protocol buffers are optional, this may be specified
for emphasis if appropriate.
"""
REQUIRED: FieldBehavior.ValueType # 2
"""Denotes a field as required.
This indicates that the field **must** be provided as part of the request,
and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
"""
OUTPUT_ONLY: FieldBehavior.ValueType # 3
"""Denotes a field as output only.
This indicates that the field is provided in responses, but including the
field in a request does nothing (the server *must* ignore it and
*must not* throw an error as a result of the field's presence).
"""
INPUT_ONLY: FieldBehavior.ValueType # 4
"""Denotes a field as input only.
This indicates that the field is provided in requests, and the
corresponding field is not included in output.
"""
IMMUTABLE: FieldBehavior.ValueType # 5
"""Denotes a field as immutable.
This indicates that the field may be set once in a request to create a
resource, but may not be changed thereafter.
"""
UNORDERED_LIST: FieldBehavior.ValueType # 6
"""Denotes that a (repeated) field is an unordered list.
This indicates that the service may provide the elements of the list
in any arbitrary order, rather than the order the user originally
provided. Additionally, the list's order may or may not be stable.
"""
NON_EMPTY_DEFAULT: FieldBehavior.ValueType # 7
"""Denotes that this field returns a non-empty default value if not set.
This indicates that if the user provides the empty value in a request,
a non-empty value will be returned. The user will not be aware of what
non-empty value to expect.
"""
global___FieldBehavior = FieldBehavior
FIELD_BEHAVIOR_FIELD_NUMBER: builtins.int
field_behavior: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___FieldBehavior.ValueType]]
"""A designation of a specific field behavior (required, output only, etc.)
in protobuf messages.
Examples:
string name = 1 [(google.api.field_behavior) = REQUIRED];
State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
google.protobuf.Duration ttl = 1
[(google.api.field_behavior) = INPUT_ONLY];
google.protobuf.Timestamp expire_time = 1
[(google.api.field_behavior) = OUTPUT_ONLY,
(google.api.field_behavior) = IMMUTABLE];
"""

View File

@@ -0,0 +1,4 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,441 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import (
marketdata_pb2 as t__tech_dot_invest_dot_grpc_dot_marketdata__pb2,
)
class MarketDataServiceStub(object):
"""Сервис для получения биржевой информации:<br/> 1. Свечи.<br/> 2. Стаканы.<br/> 3. Торговые статусы.<br/> 4. Лента сделок.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetCandles = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.FromString,
)
self.GetLastPrices = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.FromString,
)
self.GetOrderBook = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetOrderBook',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.FromString,
)
self.GetTradingStatus = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatus',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.FromString,
)
self.GetTradingStatuses = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatuses',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.FromString,
)
self.GetLastTrades = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastTrades',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.FromString,
)
self.GetClosePrices = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetClosePrices',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.FromString,
)
self.GetTechAnalysis = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTechAnalysis',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.FromString,
)
self.GetMarketValues = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.MarketDataService/GetMarketValues',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.FromString,
)
class MarketDataServiceServicer(object):
"""Сервис для получения биржевой информации:<br/> 1. Свечи.<br/> 2. Стаканы.<br/> 3. Торговые статусы.<br/> 4. Лента сделок.
"""
def GetCandles(self, request, context):
"""GetCandles — исторические свечи по инструменту
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetLastPrices(self, request, context):
"""GetLastPrices — цены последних сделок по инструментам
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetOrderBook(self, request, context):
"""GetOrderBook — стакан по инструменту
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetTradingStatus(self, request, context):
"""GetTradingStatus — статус торгов по инструменту
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetTradingStatuses(self, request, context):
"""GetTradingStatuses — статус торгов по инструментам
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetLastTrades(self, request, context):
"""GetLastTrades — обезличенные сделки
Обезличенные сделки по инструменту. Метод гарантирует получение информации за последний час.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetClosePrices(self, request, context):
"""GetClosePrices — цены закрытия торговой сессии по инструментам
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetTechAnalysis(self, request, context):
"""GetTechAnalysis — технические индикаторы по инструменту
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMarketValues(self, request, context):
"""GetMarketValues — рыночные данные по инструментам
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MarketDataServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetCandles': grpc.unary_unary_rpc_method_handler(
servicer.GetCandles,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.SerializeToString,
),
'GetLastPrices': grpc.unary_unary_rpc_method_handler(
servicer.GetLastPrices,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.SerializeToString,
),
'GetOrderBook': grpc.unary_unary_rpc_method_handler(
servicer.GetOrderBook,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.SerializeToString,
),
'GetTradingStatus': grpc.unary_unary_rpc_method_handler(
servicer.GetTradingStatus,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.SerializeToString,
),
'GetTradingStatuses': grpc.unary_unary_rpc_method_handler(
servicer.GetTradingStatuses,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.SerializeToString,
),
'GetLastTrades': grpc.unary_unary_rpc_method_handler(
servicer.GetLastTrades,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.SerializeToString,
),
'GetClosePrices': grpc.unary_unary_rpc_method_handler(
servicer.GetClosePrices,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.SerializeToString,
),
'GetTechAnalysis': grpc.unary_unary_rpc_method_handler(
servicer.GetTechAnalysis,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.SerializeToString,
),
'GetMarketValues': grpc.unary_unary_rpc_method_handler(
servicer.GetMarketValues,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.MarketDataService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class MarketDataService(object):
"""Сервис для получения биржевой информации:<br/> 1. Свечи.<br/> 2. Стаканы.<br/> 3. Торговые статусы.<br/> 4. Лента сделок.
"""
@staticmethod
def GetCandles(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetCandlesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetLastPrices(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastPricesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetOrderBook(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetOrderBook',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetOrderBookResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetTradingStatus(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatus',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetTradingStatuses(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTradingStatuses',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTradingStatusesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetLastTrades(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastTrades',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetLastTradesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetClosePrices(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetClosePrices',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetClosePricesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetTechAnalysis(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetTechAnalysis',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetTechAnalysisResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetMarketValues(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataService/GetMarketValues',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.GetMarketValuesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
class MarketDataStreamServiceStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.MarketDataStream = channel.stream_stream(
'/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString,
)
self.MarketDataServerSideStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataServerSideStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString,
)
class MarketDataStreamServiceServicer(object):
"""Missing associated documentation comment in .proto file."""
def MarketDataStream(self, request_iterator, context):
"""MarketDataStream — bidirectional стрим предоставления биржевой информации
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def MarketDataServerSideStream(self, request, context):
"""MarketDataServerSideStream — server-side стрим предоставления биржевой информации
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MarketDataStreamServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'MarketDataStream': grpc.stream_stream_rpc_method_handler(
servicer.MarketDataStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.SerializeToString,
),
'MarketDataServerSideStream': grpc.unary_stream_rpc_method_handler(
servicer.MarketDataServerSideStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.MarketDataStreamService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class MarketDataStreamService(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def MarketDataStream(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(request_iterator, target, '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataStream',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def MarketDataServerSideStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataServerSideStream',
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataServerSideStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_marketdata__pb2.MarketDataResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,414 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import (
operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2,
)
class OperationsServiceStub(object):
"""С помощью методов сервиса можно получить:<br/><br/> **1**. Список операций по счету.<br/> **2**.
Портфель по счету.<br/> **3**. Позиции ценных бумаг на счете.<br/> **4**.
Доступный остаток для вывода средств.<br/> **5**. Различные отчеты.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetOperations = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperations',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString,
)
self.GetPortfolio = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetPortfolio',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString,
)
self.GetPositions = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetPositions',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString,
)
self.GetWithdrawLimits = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetWithdrawLimits',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString,
)
self.GetBrokerReport = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetBrokerReport',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.FromString,
)
self.GetDividendsForeignIssuer = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetDividendsForeignIssuer',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.FromString,
)
self.GetOperationsByCursor = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperationsByCursor',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString,
)
class OperationsServiceServicer(object):
"""С помощью методов сервиса можно получить:<br/><br/> **1**. Список операций по счету.<br/> **2**.
Портфель по счету.<br/> **3**. Позиции ценных бумаг на счете.<br/> **4**.
Доступный остаток для вывода средств.<br/> **5**. Различные отчеты.
"""
def GetOperations(self, request, context):
"""GetOperations — список операций по счету
При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetPortfolio(self, request, context):
"""GetPortfolio — портфель по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetPositions(self, request, context):
"""GetPositions — список позиций по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetWithdrawLimits(self, request, context):
"""GetWithdrawLimits — доступный остаток для вывода средств
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetBrokerReport(self, request, context):
"""GetBrokerReport — брокерский отчет.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetDividendsForeignIssuer(self, request, context):
"""GetDividendsForeignIssuer — отчет «Справка о доходах за пределами РФ»
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetOperationsByCursor(self, request, context):
"""GetOperationsByCursor — список операций по счету с пагинацией
При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_OperationsServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetOperations': grpc.unary_unary_rpc_method_handler(
servicer.GetOperations,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.SerializeToString,
),
'GetPortfolio': grpc.unary_unary_rpc_method_handler(
servicer.GetPortfolio,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.SerializeToString,
),
'GetPositions': grpc.unary_unary_rpc_method_handler(
servicer.GetPositions,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.SerializeToString,
),
'GetWithdrawLimits': grpc.unary_unary_rpc_method_handler(
servicer.GetWithdrawLimits,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.SerializeToString,
),
'GetBrokerReport': grpc.unary_unary_rpc_method_handler(
servicer.GetBrokerReport,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.SerializeToString,
),
'GetDividendsForeignIssuer': grpc.unary_unary_rpc_method_handler(
servicer.GetDividendsForeignIssuer,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.SerializeToString,
),
'GetOperationsByCursor': grpc.unary_unary_rpc_method_handler(
servicer.GetOperationsByCursor,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.OperationsService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class OperationsService(object):
"""С помощью методов сервиса можно получить:<br/><br/> **1**. Список операций по счету.<br/> **2**.
Портфель по счету.<br/> **3**. Позиции ценных бумаг на счете.<br/> **4**.
Доступный остаток для вывода средств.<br/> **5**. Различные отчеты.
"""
@staticmethod
def GetOperations(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperations',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetPortfolio(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPortfolio',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetPositions(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetPositions',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetWithdrawLimits(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetWithdrawLimits',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetBrokerReport(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetBrokerReport',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.BrokerReportResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetDividendsForeignIssuer(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetDividendsForeignIssuer',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetDividendsForeignIssuerResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetOperationsByCursor(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsService/GetOperationsByCursor',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
class OperationsStreamServiceStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.PortfolioStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PortfolioStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.FromString,
)
self.PositionsStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PositionsStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.FromString,
)
self.OperationsStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.OperationsStreamService/OperationsStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.FromString,
)
class OperationsStreamServiceServicer(object):
"""Missing associated documentation comment in .proto file."""
def PortfolioStream(self, request, context):
"""PortfolioStream — стрим обновлений портфеля
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PositionsStream(self, request, context):
"""PositionsStream — стрим обновлений информации по изменению позиций портфеля
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def OperationsStream(self, request, context):
"""OperationsStream — стрим обновлений операций
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_OperationsStreamServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'PortfolioStream': grpc.unary_stream_rpc_method_handler(
servicer.PortfolioStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.SerializeToString,
),
'PositionsStream': grpc.unary_stream_rpc_method_handler(
servicer.PositionsStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.SerializeToString,
),
'OperationsStream': grpc.unary_stream_rpc_method_handler(
servicer.OperationsStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.OperationsStreamService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class OperationsStreamService(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def PortfolioStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PortfolioStream',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PositionsStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/PositionsStream',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def OperationsStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OperationsStreamService/OperationsStream',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,412 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2
class OrdersStreamServiceStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.TradesStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.OrdersStreamService/TradesStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.FromString,
)
self.OrderStateStream = channel.unary_stream(
'/tinkoff.public.invest.api.contract.v1.OrdersStreamService/OrderStateStream',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.FromString,
)
class OrdersStreamServiceServicer(object):
"""Missing associated documentation comment in .proto file."""
def TradesStream(self, request, context):
"""TradesStream — стрим сделок пользователя
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def OrderStateStream(self, request, context):
"""OrderStateStream — стрим поручений пользователя
Перед работой прочитайте [статью](/invest/services/orders/orders_state_stream).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_OrdersStreamServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'TradesStream': grpc.unary_stream_rpc_method_handler(
servicer.TradesStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.SerializeToString,
),
'OrderStateStream': grpc.unary_stream_rpc_method_handler(
servicer.OrderStateStream,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.OrdersStreamService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class OrdersStreamService(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def TradesStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/TradesStream',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.TradesStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def OrderStateStream(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersStreamService/OrderStateStream',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderStateStreamResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
class OrdersServiceStub(object):
"""Сервис предназначен для работы с торговыми поручениями:<br/> **1**.
выставление;<br/> **2**. отмена;<br/> **3**. получение статуса;<br/> **4**.
расчет полной стоимости;<br/> **5**. получение списка заявок.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.PostOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
)
self.PostOrderAsync = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrderAsync',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString,
)
self.CancelOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/CancelOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString,
)
self.GetOrderState = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderState',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString,
)
self.GetOrders = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrders',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString,
)
self.ReplaceOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/ReplaceOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
)
self.GetMaxLots = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/GetMaxLots',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString,
)
self.GetOrderPrice = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderPrice',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString,
)
class OrdersServiceServicer(object):
"""Сервис предназначен для работы с торговыми поручениями:<br/> **1**.
выставление;<br/> **2**. отмена;<br/> **3**. получение статуса;<br/> **4**.
расчет полной стоимости;<br/> **5**. получение списка заявок.
"""
def PostOrder(self, request, context):
"""PostOrder — выставить заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PostOrderAsync(self, request, context):
"""PostOrderAsync — выставить заявку асинхронным методом
Особенности работы приведены в [статье](/invest/services/orders/async).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CancelOrder(self, request, context):
"""CancelOrder — отменить заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetOrderState(self, request, context):
"""GetOrderState — получить статус торгового поручения
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetOrders(self, request, context):
"""GetOrders — получить список активных заявок по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ReplaceOrder(self, request, context):
"""ReplaceOrder — изменить выставленную заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMaxLots(self, request, context):
"""GetMaxLots — расчет количества доступных для покупки/продажи лотов
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetOrderPrice(self, request, context):
"""GetOrderPrice — получить предварительную стоимость для лимитной заявки
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_OrdersServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'PostOrder': grpc.unary_unary_rpc_method_handler(
servicer.PostOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString,
),
'PostOrderAsync': grpc.unary_unary_rpc_method_handler(
servicer.PostOrderAsync,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.SerializeToString,
),
'CancelOrder': grpc.unary_unary_rpc_method_handler(
servicer.CancelOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.SerializeToString,
),
'GetOrderState': grpc.unary_unary_rpc_method_handler(
servicer.GetOrderState,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.SerializeToString,
),
'GetOrders': grpc.unary_unary_rpc_method_handler(
servicer.GetOrders,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.SerializeToString,
),
'ReplaceOrder': grpc.unary_unary_rpc_method_handler(
servicer.ReplaceOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString,
),
'GetMaxLots': grpc.unary_unary_rpc_method_handler(
servicer.GetMaxLots,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.SerializeToString,
),
'GetOrderPrice': grpc.unary_unary_rpc_method_handler(
servicer.GetOrderPrice,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.OrdersService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class OrdersService(object):
"""Сервис предназначен для работы с торговыми поручениями:<br/> **1**.
выставление;<br/> **2**. отмена;<br/> **3**. получение статуса;<br/> **4**.
расчет полной стоимости;<br/> **5**. получение списка заявок.
"""
@staticmethod
def PostOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PostOrderAsync(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrderAsync',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CancelOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/CancelOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetOrderState(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderState',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetOrders(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrders',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def ReplaceOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/ReplaceOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetMaxLots(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetMaxLots',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetOrderPrice(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.OrdersService/GetOrderPrice',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

View File

@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: t_tech/invest/grpc/sandbox.proto
# Protobuf Python Version: 4.25.1
"""Generated protocol buffer code."""
from google.protobuf import (
descriptor as _descriptor,
descriptor_pool as _descriptor_pool,
symbol_database as _symbol_database,
)
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from t_tech.invest.grpc import (
common_pb2 as t__tech_dot_invest_dot_grpc_dot_common__pb2,
operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2,
orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2,
stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2,
users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2,
)
from t_tech.invest.grpc.google.api import (
field_behavior_pb2 as t__tech_dot_invest_dot_grpc_dot_google_dot_api_dot_field__behavior__pb2,
)
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n t_tech/invest/grpc/sandbox.proto\x12%tinkoff.public.invest.api.contract.v1\x1a\x1ft_tech/invest/grpc/common.proto\x1a\x1ft_tech/invest/grpc/orders.proto\x1a#t_tech/invest/grpc/operations.proto\x1a#t_tech/invest/grpc/stoporders.proto\x1a\x1et_tech/invest/grpc/users.proto\x1a\x32t_tech/invest/grpc/google/api/field_behavior.proto\"7\n\x19OpenSandboxAccountRequest\x12\x11\n\x04name\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x07\n\x05_name\"0\n\x1aOpenSandboxAccountResponse\x12\x12\n\naccount_id\x18\x01 \x01(\t\"6\n\x1a\x43loseSandboxAccountRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\"\x1d\n\x1b\x43loseSandboxAccountResponse\"x\n\x13SandboxPayInRequest\x12\x18\n\naccount_id\x18\x01 \x01(\tB\x04\xe2\x41\x01\x02\x12G\n\x06\x61mount\x18\x02 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValueB\x04\xe2\x41\x01\x02\"Z\n\x14SandboxPayInResponse\x12\x42\n\x07\x62\x61lance\x18\x01 \x01(\x0b\x32\x31.tinkoff.public.invest.api.contract.v1.MoneyValue2\xfa\x16\n\x0eSandboxService\x12\x99\x01\n\x12OpenSandboxAccount\x12@.tinkoff.public.invest.api.contract.v1.OpenSandboxAccountRequest\x1a\x41.tinkoff.public.invest.api.contract.v1.OpenSandboxAccountResponse\x12\x8b\x01\n\x12GetSandboxAccounts\x12\x39.tinkoff.public.invest.api.contract.v1.GetAccountsRequest\x1a:.tinkoff.public.invest.api.contract.v1.GetAccountsResponse\x12\x9c\x01\n\x13\x43loseSandboxAccount\x12\x41.tinkoff.public.invest.api.contract.v1.CloseSandboxAccountRequest\x1a\x42.tinkoff.public.invest.api.contract.v1.CloseSandboxAccountResponse\x12\x85\x01\n\x10PostSandboxOrder\x12\x37.tinkoff.public.invest.api.contract.v1.PostOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x94\x01\n\x15PostSandboxOrderAsync\x12<.tinkoff.public.invest.api.contract.v1.PostOrderAsyncRequest\x1a=.tinkoff.public.invest.api.contract.v1.PostOrderAsyncResponse\x12\x8b\x01\n\x13ReplaceSandboxOrder\x12:.tinkoff.public.invest.api.contract.v1.ReplaceOrderRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PostOrderResponse\x12\x85\x01\n\x10GetSandboxOrders\x12\x37.tinkoff.public.invest.api.contract.v1.GetOrdersRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.GetOrdersResponse\x12\x8b\x01\n\x12\x43\x61ncelSandboxOrder\x12\x39.tinkoff.public.invest.api.contract.v1.CancelOrderRequest\x1a:.tinkoff.public.invest.api.contract.v1.CancelOrderResponse\x12\x86\x01\n\x14GetSandboxOrderState\x12;.tinkoff.public.invest.api.contract.v1.GetOrderStateRequest\x1a\x31.tinkoff.public.invest.api.contract.v1.OrderState\x12\x91\x01\n\x14GetSandboxOrderPrice\x12;.tinkoff.public.invest.api.contract.v1.GetOrderPriceRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetOrderPriceResponse\x12\x88\x01\n\x13GetSandboxPositions\x12\x37.tinkoff.public.invest.api.contract.v1.PositionsRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PositionsResponse\x12\x8b\x01\n\x14GetSandboxOperations\x12\x38.tinkoff.public.invest.api.contract.v1.OperationsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.OperationsResponse\x12\xa9\x01\n\x1cGetSandboxOperationsByCursor\x12\x43.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorRequest\x1a\x44.tinkoff.public.invest.api.contract.v1.GetOperationsByCursorResponse\x12\x88\x01\n\x13GetSandboxPortfolio\x12\x37.tinkoff.public.invest.api.contract.v1.PortfolioRequest\x1a\x38.tinkoff.public.invest.api.contract.v1.PortfolioResponse\x12\x87\x01\n\x0cSandboxPayIn\x12:.tinkoff.public.invest.api.contract.v1.SandboxPayInRequest\x1a;.tinkoff.public.invest.api.contract.v1.SandboxPayInResponse\x12\x97\x01\n\x18GetSandboxWithdrawLimits\x12<.tinkoff.public.invest.api.contract.v1.WithdrawLimitsRequest\x1a=.tinkoff.public.invest.api.contract.v1.WithdrawLimitsResponse\x12\x88\x01\n\x11GetSandboxMaxLots\x12\x38.tinkoff.public.invest.api.contract.v1.GetMaxLotsRequest\x1a\x39.tinkoff.public.invest.api.contract.v1.GetMaxLotsResponse\x12\x91\x01\n\x14PostSandboxStopOrder\x12;.tinkoff.public.invest.api.contract.v1.PostStopOrderRequest\x1a<.tinkoff.public.invest.api.contract.v1.PostStopOrderResponse\x12\x91\x01\n\x14GetSandboxStopOrders\x12;.tinkoff.public.invest.api.contract.v1.GetStopOrdersRequest\x1a<.tinkoff.public.invest.api.contract.v1.GetStopOrdersResponse\x12\x97\x01\n\x16\x43\x61ncelSandboxStopOrder\x12=.tinkoff.public.invest.api.contract.v1.CancelStopOrderRequest\x1a>.tinkoff.public.invest.api.contract.v1.CancelStopOrderResponseBa\n\x1cru.tinkoff.piapi.contract.v1P\x01Z\x0c./;investapi\xa2\x02\x05TIAPI\xaa\x02\x14Tinkoff.InvestApi.V1\xca\x02\x11Tinkoff\\Invest\\V1b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 't_tech.invest.grpc.sandbox_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
_globals['DESCRIPTOR']._options = None
_globals['DESCRIPTOR']._serialized_options = b'\n\034ru.tinkoff.piapi.contract.v1P\001Z\014./;investapi\242\002\005TIAPI\252\002\024Tinkoff.InvestApi.V1\312\002\021Tinkoff\\Invest\\V1'
_globals['_CLOSESANDBOXACCOUNTREQUEST'].fields_by_name['account_id']._options = None
_globals['_CLOSESANDBOXACCOUNTREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002'
_globals['_SANDBOXPAYINREQUEST'].fields_by_name['account_id']._options = None
_globals['_SANDBOXPAYINREQUEST'].fields_by_name['account_id']._serialized_options = b'\342A\001\002'
_globals['_SANDBOXPAYINREQUEST'].fields_by_name['amount']._options = None
_globals['_SANDBOXPAYINREQUEST'].fields_by_name['amount']._serialized_options = b'\342A\001\002'
_globals['_OPENSANDBOXACCOUNTREQUEST']._serialized_start=299
_globals['_OPENSANDBOXACCOUNTREQUEST']._serialized_end=354
_globals['_OPENSANDBOXACCOUNTRESPONSE']._serialized_start=356
_globals['_OPENSANDBOXACCOUNTRESPONSE']._serialized_end=404
_globals['_CLOSESANDBOXACCOUNTREQUEST']._serialized_start=406
_globals['_CLOSESANDBOXACCOUNTREQUEST']._serialized_end=460
_globals['_CLOSESANDBOXACCOUNTRESPONSE']._serialized_start=462
_globals['_CLOSESANDBOXACCOUNTRESPONSE']._serialized_end=491
_globals['_SANDBOXPAYINREQUEST']._serialized_start=493
_globals['_SANDBOXPAYINREQUEST']._serialized_end=613
_globals['_SANDBOXPAYINRESPONSE']._serialized_start=615
_globals['_SANDBOXPAYINRESPONSE']._serialized_end=705
_globals['_SANDBOXSERVICE']._serialized_start=708
_globals['_SANDBOXSERVICE']._serialized_end=3646
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,128 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.message
import t_tech.invest.grpc.common_pb2
import typing
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
@typing.final
class OpenSandboxAccountRequest(google.protobuf.message.Message):
"""Запрос открытия счета в песочнице."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NAME_FIELD_NUMBER: builtins.int
name: builtins.str
"""Название счета"""
def __init__(
self,
*,
name: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_name", b"_name", "name", b"name"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_name", b"_name", "name", b"name"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_name", b"_name"]) -> typing.Literal["name"] | None: ...
global___OpenSandboxAccountRequest = OpenSandboxAccountRequest
@typing.final
class OpenSandboxAccountResponse(google.protobuf.message.Message):
"""Номер открытого счета в песочнице."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Номер счета"""
def __init__(
self,
*,
account_id: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ...
global___OpenSandboxAccountResponse = OpenSandboxAccountResponse
@typing.final
class CloseSandboxAccountRequest(google.protobuf.message.Message):
"""Запрос закрытия счета в песочнице."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Номер счета"""
def __init__(
self,
*,
account_id: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ...
global___CloseSandboxAccountRequest = CloseSandboxAccountRequest
@typing.final
class CloseSandboxAccountResponse(google.protobuf.message.Message):
"""Результат закрытия счета в песочнице.
пустой ответ
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___CloseSandboxAccountResponse = CloseSandboxAccountResponse
@typing.final
class SandboxPayInRequest(google.protobuf.message.Message):
"""Запрос пополнения счета в песочнице."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
AMOUNT_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Номер счета"""
@property
def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Сумма пополнения счета в рублях"""
def __init__(
self,
*,
account_id: builtins.str = ...,
amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "amount", b"amount"]) -> None: ...
global___SandboxPayInRequest = SandboxPayInRequest
@typing.final
class SandboxPayInResponse(google.protobuf.message.Message):
"""Результат пополнения счета, текущий баланс."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
BALANCE_FIELD_NUMBER: builtins.int
@property
def balance(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Текущий баланс счета"""
def __init__(
self,
*,
balance: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["balance", b"balance"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["balance", b"balance"]) -> None: ...
global___SandboxPayInResponse = SandboxPayInResponse

View File

@@ -0,0 +1,725 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import (
operations_pb2 as t__tech_dot_invest_dot_grpc_dot_operations__pb2,
orders_pb2 as t__tech_dot_invest_dot_grpc_dot_orders__pb2,
sandbox_pb2 as t__tech_dot_invest_dot_grpc_dot_sandbox__pb2,
stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2,
users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2,
)
class SandboxServiceStub(object):
"""Методы для работы с песочницей T-Invest API
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.OpenSandboxAccount = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/OpenSandboxAccount',
request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.FromString,
)
self.GetSandboxAccounts = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxAccounts',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString,
)
self.CloseSandboxAccount = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/CloseSandboxAccount',
request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.FromString,
)
self.PostSandboxOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
)
self.PostSandboxOrderAsync = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrderAsync',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString,
)
self.ReplaceSandboxOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/ReplaceSandboxOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
)
self.GetSandboxOrders = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrders',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString,
)
self.CancelSandboxOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString,
)
self.GetSandboxOrderState = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderState',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString,
)
self.GetSandboxOrderPrice = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderPrice',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString,
)
self.GetSandboxPositions = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPositions',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString,
)
self.GetSandboxOperations = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperations',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString,
)
self.GetSandboxOperationsByCursor = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperationsByCursor',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString,
)
self.GetSandboxPortfolio = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPortfolio',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString,
)
self.SandboxPayIn = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/SandboxPayIn',
request_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.FromString,
)
self.GetSandboxWithdrawLimits = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxWithdrawLimits',
request_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString,
)
self.GetSandboxMaxLots = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxMaxLots',
request_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString,
)
self.PostSandboxStopOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxStopOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString,
)
self.GetSandboxStopOrders = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxStopOrders',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString,
)
self.CancelSandboxStopOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxStopOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString,
)
class SandboxServiceServicer(object):
"""Методы для работы с песочницей T-Invest API
"""
def OpenSandboxAccount(self, request, context):
"""OpenSandboxAccount — зарегистрировать счет
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxAccounts(self, request, context):
"""GetSandboxAccounts — счета пользователя
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CloseSandboxAccount(self, request, context):
"""CloseSandboxAccount — закрыть счет
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PostSandboxOrder(self, request, context):
"""PostSandboxOrder — выставить заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PostSandboxOrderAsync(self, request, context):
"""PostSandboxOrderAsync — выставить заявку асинхронным методом
Особенности работы приведены в [статье](/invest/services/orders/async).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ReplaceSandboxOrder(self, request, context):
"""ReplaceSandboxOrder — изменить выставленную заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxOrders(self, request, context):
"""GetSandboxOrders — получить список активных заявок по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CancelSandboxOrder(self, request, context):
"""CancelSandboxOrder — отменить заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxOrderState(self, request, context):
"""GetSandboxOrderState — получить статус торгового поручения
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxOrderPrice(self, request, context):
"""GetSandboxOrderPrice — получить предварительную стоимость для лимитной заявки
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxPositions(self, request, context):
"""GetSandboxPositions — список позиций по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxOperations(self, request, context):
"""GetSandboxOperations — список операций по счету
При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxOperationsByCursor(self, request, context):
"""GetSandboxOperationsByCursor — список операций по счету с пагинацией
При работе с методом учитывайте [особенности взаимодействия](/invest/services/operations/operations_problems).
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxPortfolio(self, request, context):
"""GetSandboxPortfolio — портфель по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SandboxPayIn(self, request, context):
"""SandboxPayIn — пополнить счет.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxWithdrawLimits(self, request, context):
"""GetSandboxWithdrawLimits — доступный остаток для вывода средств
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxMaxLots(self, request, context):
"""GetSandboxMaxLots — расчет количества доступных для покупки/продажи лотов
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PostSandboxStopOrder(self, request, context):
"""PostSandboxStopOrder — выставить стоп-заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSandboxStopOrders(self, request, context):
"""GetSandboxStopOrders — получить список активных стоп-заявок по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CancelSandboxStopOrder(self, request, context):
"""CancelSandboxStopOrder — отменить стоп-заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_SandboxServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'OpenSandboxAccount': grpc.unary_unary_rpc_method_handler(
servicer.OpenSandboxAccount,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.SerializeToString,
),
'GetSandboxAccounts': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxAccounts,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.SerializeToString,
),
'CloseSandboxAccount': grpc.unary_unary_rpc_method_handler(
servicer.CloseSandboxAccount,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.SerializeToString,
),
'PostSandboxOrder': grpc.unary_unary_rpc_method_handler(
servicer.PostSandboxOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString,
),
'PostSandboxOrderAsync': grpc.unary_unary_rpc_method_handler(
servicer.PostSandboxOrderAsync,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.SerializeToString,
),
'ReplaceSandboxOrder': grpc.unary_unary_rpc_method_handler(
servicer.ReplaceSandboxOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.SerializeToString,
),
'GetSandboxOrders': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxOrders,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.SerializeToString,
),
'CancelSandboxOrder': grpc.unary_unary_rpc_method_handler(
servicer.CancelSandboxOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.SerializeToString,
),
'GetSandboxOrderState': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxOrderState,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.SerializeToString,
),
'GetSandboxOrderPrice': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxOrderPrice,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.SerializeToString,
),
'GetSandboxPositions': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxPositions,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.SerializeToString,
),
'GetSandboxOperations': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxOperations,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.SerializeToString,
),
'GetSandboxOperationsByCursor': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxOperationsByCursor,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.SerializeToString,
),
'GetSandboxPortfolio': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxPortfolio,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.SerializeToString,
),
'SandboxPayIn': grpc.unary_unary_rpc_method_handler(
servicer.SandboxPayIn,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.SerializeToString,
),
'GetSandboxWithdrawLimits': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxWithdrawLimits,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.SerializeToString,
),
'GetSandboxMaxLots': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxMaxLots,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.SerializeToString,
),
'PostSandboxStopOrder': grpc.unary_unary_rpc_method_handler(
servicer.PostSandboxStopOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.SerializeToString,
),
'GetSandboxStopOrders': grpc.unary_unary_rpc_method_handler(
servicer.GetSandboxStopOrders,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.SerializeToString,
),
'CancelSandboxStopOrder': grpc.unary_unary_rpc_method_handler(
servicer.CancelSandboxStopOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.SandboxService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class SandboxService(object):
"""Методы для работы с песочницей T-Invest API
"""
@staticmethod
def OpenSandboxAccount(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/OpenSandboxAccount',
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.OpenSandboxAccountResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxAccounts(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxAccounts',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CloseSandboxAccount(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CloseSandboxAccount',
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.CloseSandboxAccountResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PostSandboxOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PostSandboxOrderAsync(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxOrderAsync',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderAsyncResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def ReplaceSandboxOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/ReplaceSandboxOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.ReplaceOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.PostOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxOrders(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrders',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrdersResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CancelSandboxOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxOrder',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.CancelOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxOrderState(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderState',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderStateRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.OrderState.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxOrderPrice(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOrderPrice',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetOrderPriceResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxPositions(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPositions',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PositionsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxOperations(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperations',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.OperationsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxOperationsByCursor(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxOperationsByCursor',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.GetOperationsByCursorResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxPortfolio(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxPortfolio',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.PortfolioResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def SandboxPayIn(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/SandboxPayIn',
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_sandbox__pb2.SandboxPayInResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxWithdrawLimits(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxWithdrawLimits',
t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_operations__pb2.WithdrawLimitsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxMaxLots(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxMaxLots',
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_orders__pb2.GetMaxLotsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PostSandboxStopOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/PostSandboxStopOrder',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSandboxStopOrders(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/GetSandboxStopOrders',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CancelSandboxStopOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SandboxService/CancelSandboxStopOrder',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,402 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import google.protobuf.timestamp_pb2
import sys
import t_tech.invest.grpc.common_pb2
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _StrategyType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _StrategyTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StrategyType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
STRATEGY_TYPE_UNSPECIFIED: _StrategyType.ValueType # 0
"""Не определен."""
STRATEGY_TYPE_TECHNICAL: _StrategyType.ValueType # 1
"""Техническая стратегия."""
STRATEGY_TYPE_FUNDAMENTAL: _StrategyType.ValueType # 2
"""Фундаментальная стратегия."""
class StrategyType(_StrategyType, metaclass=_StrategyTypeEnumTypeWrapper):
"""Тип стратегии."""
STRATEGY_TYPE_UNSPECIFIED: StrategyType.ValueType # 0
"""Не определен."""
STRATEGY_TYPE_TECHNICAL: StrategyType.ValueType # 1
"""Техническая стратегия."""
STRATEGY_TYPE_FUNDAMENTAL: StrategyType.ValueType # 2
"""Фундаментальная стратегия."""
global___StrategyType = StrategyType
class _SignalDirection:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _SignalDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SignalDirection.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
SIGNAL_DIRECTION_UNSPECIFIED: _SignalDirection.ValueType # 0
"""Не определен."""
SIGNAL_DIRECTION_BUY: _SignalDirection.ValueType # 1
"""Покупка."""
SIGNAL_DIRECTION_SELL: _SignalDirection.ValueType # 2
"""Продажа."""
class SignalDirection(_SignalDirection, metaclass=_SignalDirectionEnumTypeWrapper):
"""Направление сигнала."""
SIGNAL_DIRECTION_UNSPECIFIED: SignalDirection.ValueType # 0
"""Не определен."""
SIGNAL_DIRECTION_BUY: SignalDirection.ValueType # 1
"""Покупка."""
SIGNAL_DIRECTION_SELL: SignalDirection.ValueType # 2
"""Продажа."""
global___SignalDirection = SignalDirection
class _SignalState:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _SignalStateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SignalState.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
SIGNAL_STATE_UNSPECIFIED: _SignalState.ValueType # 0
"""Не определен."""
SIGNAL_STATE_ACTIVE: _SignalState.ValueType # 1
"""Активный сигнал."""
SIGNAL_STATE_CLOSED: _SignalState.ValueType # 2
"""Закрытый сигнал."""
SIGNAL_STATE_ALL: _SignalState.ValueType # 3
"""Все состояния."""
class SignalState(_SignalState, metaclass=_SignalStateEnumTypeWrapper):
"""Статус сигнала."""
SIGNAL_STATE_UNSPECIFIED: SignalState.ValueType # 0
"""Не определен."""
SIGNAL_STATE_ACTIVE: SignalState.ValueType # 1
"""Активный сигнал."""
SIGNAL_STATE_CLOSED: SignalState.ValueType # 2
"""Закрытый сигнал."""
SIGNAL_STATE_ALL: SignalState.ValueType # 3
"""Все состояния."""
global___SignalState = SignalState
@typing.final
class GetStrategiesRequest(google.protobuf.message.Message):
"""Запрос стратегий."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STRATEGY_ID_FIELD_NUMBER: builtins.int
strategy_id: builtins.str
"""Идентификатор стратегии."""
def __init__(
self,
*,
strategy_id: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_strategy_id", b"_strategy_id", "strategy_id", b"strategy_id"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_strategy_id", b"_strategy_id", "strategy_id", b"strategy_id"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_strategy_id", b"_strategy_id"]) -> typing.Literal["strategy_id"] | None: ...
global___GetStrategiesRequest = GetStrategiesRequest
@typing.final
class GetStrategiesResponse(google.protobuf.message.Message):
"""Стратегии"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STRATEGIES_FIELD_NUMBER: builtins.int
@property
def strategies(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Strategy]: ...
def __init__(
self,
*,
strategies: collections.abc.Iterable[global___Strategy] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["strategies", b"strategies"]) -> None: ...
global___GetStrategiesResponse = GetStrategiesResponse
@typing.final
class Strategy(google.protobuf.message.Message):
"""Стратегия"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STRATEGY_ID_FIELD_NUMBER: builtins.int
STRATEGY_NAME_FIELD_NUMBER: builtins.int
STRATEGY_DESCRIPTION_FIELD_NUMBER: builtins.int
STRATEGY_URL_FIELD_NUMBER: builtins.int
STRATEGY_TYPE_FIELD_NUMBER: builtins.int
ACTIVE_SIGNALS_FIELD_NUMBER: builtins.int
TOTAL_SIGNALS_FIELD_NUMBER: builtins.int
TIME_IN_POSITION_FIELD_NUMBER: builtins.int
AVERAGE_SIGNAL_YIELD_FIELD_NUMBER: builtins.int
AVERAGE_SIGNAL_YIELD_YEAR_FIELD_NUMBER: builtins.int
YIELD_FIELD_NUMBER: builtins.int
YIELD_YEAR_FIELD_NUMBER: builtins.int
strategy_id: builtins.str
"""Идентификатор стратегии."""
strategy_name: builtins.str
"""Название стратегии."""
strategy_description: builtins.str
"""Описание стратегии."""
strategy_url: builtins.str
"""Ссылка на страницу с описанием стратегии."""
strategy_type: global___StrategyType.ValueType
"""Тип стратегии."""
active_signals: builtins.int
"""Количество активных сигналов."""
total_signals: builtins.int
"""Общее количество сигналов."""
time_in_position: builtins.int
"""Среднее время нахождения сигнала в позиции."""
@property
def average_signal_yield(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Средняя доходность сигнала в стратегии."""
@property
def average_signal_yield_year(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Средняя доходность сигналов в стратегии за последний год."""
@property
def yield_year(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Доходность стратегии за последний год."""
def __init__(
self,
*,
strategy_id: builtins.str = ...,
strategy_name: builtins.str = ...,
strategy_description: builtins.str | None = ...,
strategy_url: builtins.str | None = ...,
strategy_type: global___StrategyType.ValueType = ...,
active_signals: builtins.int = ...,
total_signals: builtins.int = ...,
time_in_position: builtins.int = ...,
average_signal_yield: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
average_signal_yield_year: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
yield_year: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_strategy_description", b"_strategy_description", "_strategy_url", b"_strategy_url", "average_signal_yield", b"average_signal_yield", "average_signal_yield_year", b"average_signal_yield_year", "strategy_description", b"strategy_description", "strategy_url", b"strategy_url", "yield", b"yield", "yield_year", b"yield_year"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_strategy_description", b"_strategy_description", "_strategy_url", b"_strategy_url", "active_signals", b"active_signals", "average_signal_yield", b"average_signal_yield", "average_signal_yield_year", b"average_signal_yield_year", "strategy_description", b"strategy_description", "strategy_id", b"strategy_id", "strategy_name", b"strategy_name", "strategy_type", b"strategy_type", "strategy_url", b"strategy_url", "time_in_position", b"time_in_position", "total_signals", b"total_signals", "yield", b"yield", "yield_year", b"yield_year"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_strategy_description", b"_strategy_description"]) -> typing.Literal["strategy_description"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_strategy_url", b"_strategy_url"]) -> typing.Literal["strategy_url"] | None: ...
global___Strategy = Strategy
@typing.final
class GetSignalsRequest(google.protobuf.message.Message):
"""Запрос сигналов."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
SIGNAL_ID_FIELD_NUMBER: builtins.int
STRATEGY_ID_FIELD_NUMBER: builtins.int
STRATEGY_TYPE_FIELD_NUMBER: builtins.int
INSTRUMENT_UID_FIELD_NUMBER: builtins.int
FROM_FIELD_NUMBER: builtins.int
TO_FIELD_NUMBER: builtins.int
DIRECTION_FIELD_NUMBER: builtins.int
ACTIVE_FIELD_NUMBER: builtins.int
PAGING_FIELD_NUMBER: builtins.int
signal_id: builtins.str
"""Идентификатор сигнала."""
strategy_id: builtins.str
"""Идентификатор стратегии."""
strategy_type: global___StrategyType.ValueType
"""Тип стратегии."""
instrument_uid: builtins.str
""" Идентификатор бумаги."""
direction: global___SignalDirection.ValueType
""" Направление сигнала."""
active: global___SignalState.ValueType
"""Состояние сигнала."""
@property
def to(self) -> google.protobuf.timestamp_pb2.Timestamp:
""" Дата конца запрашиваемого интервала по UTC."""
@property
def paging(self) -> t_tech.invest.grpc.common_pb2.Page:
"""Настройки пагинации."""
def __init__(
self,
*,
signal_id: builtins.str | None = ...,
strategy_id: builtins.str | None = ...,
strategy_type: global___StrategyType.ValueType | None = ...,
instrument_uid: builtins.str | None = ...,
to: google.protobuf.timestamp_pb2.Timestamp | None = ...,
direction: global___SignalDirection.ValueType | None = ...,
active: global___SignalState.ValueType | None = ...,
paging: t_tech.invest.grpc.common_pb2.Page | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_active", b"_active", "_direction", b"_direction", "_from", b"_from", "_instrument_uid", b"_instrument_uid", "_paging", b"_paging", "_signal_id", b"_signal_id", "_strategy_id", b"_strategy_id", "_strategy_type", b"_strategy_type", "_to", b"_to", "active", b"active", "direction", b"direction", "from", b"from", "instrument_uid", b"instrument_uid", "paging", b"paging", "signal_id", b"signal_id", "strategy_id", b"strategy_id", "strategy_type", b"strategy_type", "to", b"to"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_active", b"_active", "_direction", b"_direction", "_from", b"_from", "_instrument_uid", b"_instrument_uid", "_paging", b"_paging", "_signal_id", b"_signal_id", "_strategy_id", b"_strategy_id", "_strategy_type", b"_strategy_type", "_to", b"_to", "active", b"active", "direction", b"direction", "from", b"from", "instrument_uid", b"instrument_uid", "paging", b"paging", "signal_id", b"signal_id", "strategy_id", b"strategy_id", "strategy_type", b"strategy_type", "to", b"to"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_active", b"_active"]) -> typing.Literal["active"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_direction", b"_direction"]) -> typing.Literal["direction"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_from", b"_from"]) -> typing.Literal["from"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_instrument_uid", b"_instrument_uid"]) -> typing.Literal["instrument_uid"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_paging", b"_paging"]) -> typing.Literal["paging"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_signal_id", b"_signal_id"]) -> typing.Literal["signal_id"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_strategy_id", b"_strategy_id"]) -> typing.Literal["strategy_id"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_strategy_type", b"_strategy_type"]) -> typing.Literal["strategy_type"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ...
global___GetSignalsRequest = GetSignalsRequest
@typing.final
class GetSignalsResponse(google.protobuf.message.Message):
"""Сигналы."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
SIGNALS_FIELD_NUMBER: builtins.int
PAGING_FIELD_NUMBER: builtins.int
@property
def signals(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Signal]:
"""Массив сигналов."""
@property
def paging(self) -> t_tech.invest.grpc.common_pb2.PageResponse:
"""Данные по пагинации."""
def __init__(
self,
*,
signals: collections.abc.Iterable[global___Signal] | None = ...,
paging: t_tech.invest.grpc.common_pb2.PageResponse | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["paging", b"paging"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["paging", b"paging", "signals", b"signals"]) -> None: ...
global___GetSignalsResponse = GetSignalsResponse
@typing.final
class Signal(google.protobuf.message.Message):
"""Сигнал."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
SIGNAL_ID_FIELD_NUMBER: builtins.int
STRATEGY_ID_FIELD_NUMBER: builtins.int
STRATEGY_NAME_FIELD_NUMBER: builtins.int
INSTRUMENT_UID_FIELD_NUMBER: builtins.int
CREATE_DT_FIELD_NUMBER: builtins.int
DIRECTION_FIELD_NUMBER: builtins.int
INITIAL_PRICE_FIELD_NUMBER: builtins.int
INFO_FIELD_NUMBER: builtins.int
NAME_FIELD_NUMBER: builtins.int
TARGET_PRICE_FIELD_NUMBER: builtins.int
END_DT_FIELD_NUMBER: builtins.int
PROBABILITY_FIELD_NUMBER: builtins.int
STOPLOSS_FIELD_NUMBER: builtins.int
CLOSE_PRICE_FIELD_NUMBER: builtins.int
CLOSE_DT_FIELD_NUMBER: builtins.int
signal_id: builtins.str
"""Идентификатор сигнала."""
strategy_id: builtins.str
"""Идентификатор стратегии."""
strategy_name: builtins.str
"""Название стратегии."""
instrument_uid: builtins.str
"""Идентификатор бумаги."""
direction: global___SignalDirection.ValueType
"""Направление сигнала."""
info: builtins.str
"""Дополнительная информация о сигнале."""
name: builtins.str
"""Название сигнала."""
probability: builtins.int
"""Вероятность сигнала."""
@property
def create_dt(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время создания сигнала по UTC."""
@property
def initial_price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Цена бумаги на момент формирования сигнала."""
@property
def target_price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Целевая цена."""
@property
def end_dt(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время дедлайна сигнала по UTC."""
@property
def stoploss(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Порог закрытия сигнала по стоплосс."""
@property
def close_price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Цена закрытия сигнала."""
@property
def close_dt(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время закрытия сигнала по UTC."""
def __init__(
self,
*,
signal_id: builtins.str = ...,
strategy_id: builtins.str = ...,
strategy_name: builtins.str = ...,
instrument_uid: builtins.str = ...,
create_dt: google.protobuf.timestamp_pb2.Timestamp | None = ...,
direction: global___SignalDirection.ValueType = ...,
initial_price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
info: builtins.str | None = ...,
name: builtins.str = ...,
target_price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
end_dt: google.protobuf.timestamp_pb2.Timestamp | None = ...,
probability: builtins.int | None = ...,
stoploss: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
close_price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
close_dt: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_close_dt", b"_close_dt", "_close_price", b"_close_price", "_info", b"_info", "_probability", b"_probability", "_stoploss", b"_stoploss", "close_dt", b"close_dt", "close_price", b"close_price", "create_dt", b"create_dt", "end_dt", b"end_dt", "info", b"info", "initial_price", b"initial_price", "probability", b"probability", "stoploss", b"stoploss", "target_price", b"target_price"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_close_dt", b"_close_dt", "_close_price", b"_close_price", "_info", b"_info", "_probability", b"_probability", "_stoploss", b"_stoploss", "close_dt", b"close_dt", "close_price", b"close_price", "create_dt", b"create_dt", "direction", b"direction", "end_dt", b"end_dt", "info", b"info", "initial_price", b"initial_price", "instrument_uid", b"instrument_uid", "name", b"name", "probability", b"probability", "signal_id", b"signal_id", "stoploss", b"stoploss", "strategy_id", b"strategy_id", "strategy_name", b"strategy_name", "target_price", b"target_price"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_close_dt", b"_close_dt"]) -> typing.Literal["close_dt"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_close_price", b"_close_price"]) -> typing.Literal["close_price"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_info", b"_info"]) -> typing.Literal["info"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_probability", b"_probability"]) -> typing.Literal["probability"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_stoploss", b"_stoploss"]) -> typing.Literal["stoploss"] | None: ...
global___Signal = Signal

View File

@@ -0,0 +1,106 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import (
signals_pb2 as t__tech_dot_invest_dot_grpc_dot_signals__pb2,
)
class SignalServiceStub(object):
"""Сервис для получения технических сигналов и мнений аналитиков по инструментам.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetStrategies = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SignalService/GetStrategies',
request_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.FromString,
)
self.GetSignals = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.SignalService/GetSignals',
request_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.FromString,
)
class SignalServiceServicer(object):
"""Сервис для получения технических сигналов и мнений аналитиков по инструментам.
"""
def GetStrategies(self, request, context):
"""GetStrategies — стратегии
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetSignals(self, request, context):
"""GetSignals — сигналы
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_SignalServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetStrategies': grpc.unary_unary_rpc_method_handler(
servicer.GetStrategies,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.SerializeToString,
),
'GetSignals': grpc.unary_unary_rpc_method_handler(
servicer.GetSignals,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.SignalService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class SignalService(object):
"""Сервис для получения технических сигналов и мнений аналитиков по инструментам.
"""
@staticmethod
def GetStrategies(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SignalService/GetStrategies',
t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetStrategiesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetSignals(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.SignalService/GetSignals',
t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_signals__pb2.GetSignalsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,639 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import google.protobuf.timestamp_pb2
import sys
import t_tech.invest.grpc.common_pb2
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _StopOrderDirection:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _StopOrderDirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderDirection.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
STOP_ORDER_DIRECTION_UNSPECIFIED: _StopOrderDirection.ValueType # 0
"""Значение не указано."""
STOP_ORDER_DIRECTION_BUY: _StopOrderDirection.ValueType # 1
"""Покупка."""
STOP_ORDER_DIRECTION_SELL: _StopOrderDirection.ValueType # 2
"""Продажа."""
class StopOrderDirection(_StopOrderDirection, metaclass=_StopOrderDirectionEnumTypeWrapper):
"""Направление сделки стоп-заявки."""
STOP_ORDER_DIRECTION_UNSPECIFIED: StopOrderDirection.ValueType # 0
"""Значение не указано."""
STOP_ORDER_DIRECTION_BUY: StopOrderDirection.ValueType # 1
"""Покупка."""
STOP_ORDER_DIRECTION_SELL: StopOrderDirection.ValueType # 2
"""Продажа."""
global___StopOrderDirection = StopOrderDirection
class _StopOrderExpirationType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _StopOrderExpirationTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderExpirationType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED: _StopOrderExpirationType.ValueType # 0
"""Значение не указано."""
STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL: _StopOrderExpirationType.ValueType # 1
"""Действительно до отмены."""
STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE: _StopOrderExpirationType.ValueType # 2
"""Действительно до даты снятия."""
class StopOrderExpirationType(_StopOrderExpirationType, metaclass=_StopOrderExpirationTypeEnumTypeWrapper):
"""Тип экспирации стоп-заявке."""
STOP_ORDER_EXPIRATION_TYPE_UNSPECIFIED: StopOrderExpirationType.ValueType # 0
"""Значение не указано."""
STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_CANCEL: StopOrderExpirationType.ValueType # 1
"""Действительно до отмены."""
STOP_ORDER_EXPIRATION_TYPE_GOOD_TILL_DATE: StopOrderExpirationType.ValueType # 2
"""Действительно до даты снятия."""
global___StopOrderExpirationType = StopOrderExpirationType
class _StopOrderType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _StopOrderTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
STOP_ORDER_TYPE_UNSPECIFIED: _StopOrderType.ValueType # 0
"""Значение не указано."""
STOP_ORDER_TYPE_TAKE_PROFIT: _StopOrderType.ValueType # 1
"""`Take-profit`-заявка."""
STOP_ORDER_TYPE_STOP_LOSS: _StopOrderType.ValueType # 2
"""`Stop-loss`-заявка."""
STOP_ORDER_TYPE_STOP_LIMIT: _StopOrderType.ValueType # 3
"""`Stop-limit`-заявка."""
class StopOrderType(_StopOrderType, metaclass=_StopOrderTypeEnumTypeWrapper):
"""Тип стоп-заявки."""
STOP_ORDER_TYPE_UNSPECIFIED: StopOrderType.ValueType # 0
"""Значение не указано."""
STOP_ORDER_TYPE_TAKE_PROFIT: StopOrderType.ValueType # 1
"""`Take-profit`-заявка."""
STOP_ORDER_TYPE_STOP_LOSS: StopOrderType.ValueType # 2
"""`Stop-loss`-заявка."""
STOP_ORDER_TYPE_STOP_LIMIT: StopOrderType.ValueType # 3
"""`Stop-limit`-заявка."""
global___StopOrderType = StopOrderType
class _StopOrderStatusOption:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _StopOrderStatusOptionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_StopOrderStatusOption.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
STOP_ORDER_STATUS_UNSPECIFIED: _StopOrderStatusOption.ValueType # 0
"""Значение не указано."""
STOP_ORDER_STATUS_ALL: _StopOrderStatusOption.ValueType # 1
"""Все заявки."""
STOP_ORDER_STATUS_ACTIVE: _StopOrderStatusOption.ValueType # 2
"""Активные заявки."""
STOP_ORDER_STATUS_EXECUTED: _StopOrderStatusOption.ValueType # 3
"""Исполненные заявки."""
STOP_ORDER_STATUS_CANCELED: _StopOrderStatusOption.ValueType # 4
"""Отмененные заявки."""
STOP_ORDER_STATUS_EXPIRED: _StopOrderStatusOption.ValueType # 5
"""Истекшие заявки."""
class StopOrderStatusOption(_StopOrderStatusOption, metaclass=_StopOrderStatusOptionEnumTypeWrapper):
"""Статус стоп-заяки."""
STOP_ORDER_STATUS_UNSPECIFIED: StopOrderStatusOption.ValueType # 0
"""Значение не указано."""
STOP_ORDER_STATUS_ALL: StopOrderStatusOption.ValueType # 1
"""Все заявки."""
STOP_ORDER_STATUS_ACTIVE: StopOrderStatusOption.ValueType # 2
"""Активные заявки."""
STOP_ORDER_STATUS_EXECUTED: StopOrderStatusOption.ValueType # 3
"""Исполненные заявки."""
STOP_ORDER_STATUS_CANCELED: StopOrderStatusOption.ValueType # 4
"""Отмененные заявки."""
STOP_ORDER_STATUS_EXPIRED: StopOrderStatusOption.ValueType # 5
"""Истекшие заявки."""
global___StopOrderStatusOption = StopOrderStatusOption
class _ExchangeOrderType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _ExchangeOrderTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_ExchangeOrderType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
EXCHANGE_ORDER_TYPE_UNSPECIFIED: _ExchangeOrderType.ValueType # 0
"""Значение не указано."""
EXCHANGE_ORDER_TYPE_MARKET: _ExchangeOrderType.ValueType # 1
"""Заявка по рыночной цене."""
EXCHANGE_ORDER_TYPE_LIMIT: _ExchangeOrderType.ValueType # 2
"""Лимитная заявка."""
class ExchangeOrderType(_ExchangeOrderType, metaclass=_ExchangeOrderTypeEnumTypeWrapper):
"""Тип выставляемой заявки."""
EXCHANGE_ORDER_TYPE_UNSPECIFIED: ExchangeOrderType.ValueType # 0
"""Значение не указано."""
EXCHANGE_ORDER_TYPE_MARKET: ExchangeOrderType.ValueType # 1
"""Заявка по рыночной цене."""
EXCHANGE_ORDER_TYPE_LIMIT: ExchangeOrderType.ValueType # 2
"""Лимитная заявка."""
global___ExchangeOrderType = ExchangeOrderType
class _TakeProfitType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _TakeProfitTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TakeProfitType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
TAKE_PROFIT_TYPE_UNSPECIFIED: _TakeProfitType.ValueType # 0
"""Значение не указано."""
TAKE_PROFIT_TYPE_REGULAR: _TakeProfitType.ValueType # 1
"""Обычная заявка, значение по умолчанию."""
TAKE_PROFIT_TYPE_TRAILING: _TakeProfitType.ValueType # 2
"""Трейлинг-стоп."""
class TakeProfitType(_TakeProfitType, metaclass=_TakeProfitTypeEnumTypeWrapper):
"""Тип TakeProfit-заявки."""
TAKE_PROFIT_TYPE_UNSPECIFIED: TakeProfitType.ValueType # 0
"""Значение не указано."""
TAKE_PROFIT_TYPE_REGULAR: TakeProfitType.ValueType # 1
"""Обычная заявка, значение по умолчанию."""
TAKE_PROFIT_TYPE_TRAILING: TakeProfitType.ValueType # 2
"""Трейлинг-стоп."""
global___TakeProfitType = TakeProfitType
class _TrailingValueType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _TrailingValueTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TrailingValueType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
TRAILING_VALUE_UNSPECIFIED: _TrailingValueType.ValueType # 0
"""Значение не указано."""
TRAILING_VALUE_ABSOLUTE: _TrailingValueType.ValueType # 1
"""Абсолютное значение в единицах цены."""
TRAILING_VALUE_RELATIVE: _TrailingValueType.ValueType # 2
"""Относительное значение в процентах."""
class TrailingValueType(_TrailingValueType, metaclass=_TrailingValueTypeEnumTypeWrapper):
"""Тип параметров значений трейлинг-стопа."""
TRAILING_VALUE_UNSPECIFIED: TrailingValueType.ValueType # 0
"""Значение не указано."""
TRAILING_VALUE_ABSOLUTE: TrailingValueType.ValueType # 1
"""Абсолютное значение в единицах цены."""
TRAILING_VALUE_RELATIVE: TrailingValueType.ValueType # 2
"""Относительное значение в процентах."""
global___TrailingValueType = TrailingValueType
class _TrailingStopStatus:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _TrailingStopStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TrailingStopStatus.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
TRAILING_STOP_UNSPECIFIED: _TrailingStopStatus.ValueType # 0
"""Значение не указано."""
TRAILING_STOP_ACTIVE: _TrailingStopStatus.ValueType # 1
"""Активный."""
TRAILING_STOP_ACTIVATED: _TrailingStopStatus.ValueType # 2
"""Активированный."""
class TrailingStopStatus(_TrailingStopStatus, metaclass=_TrailingStopStatusEnumTypeWrapper):
"""Статус трейлинг-стопа."""
TRAILING_STOP_UNSPECIFIED: TrailingStopStatus.ValueType # 0
"""Значение не указано."""
TRAILING_STOP_ACTIVE: TrailingStopStatus.ValueType # 1
"""Активный."""
TRAILING_STOP_ACTIVATED: TrailingStopStatus.ValueType # 2
"""Активированный."""
global___TrailingStopStatus = TrailingStopStatus
@typing.final
class PostStopOrderRequest(google.protobuf.message.Message):
"""Запрос выставления стоп-заявки."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@typing.final
class TrailingData(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
INDENT_FIELD_NUMBER: builtins.int
INDENT_TYPE_FIELD_NUMBER: builtins.int
SPREAD_FIELD_NUMBER: builtins.int
SPREAD_TYPE_FIELD_NUMBER: builtins.int
indent_type: global___TrailingValueType.ValueType
"""Тип величины отступа."""
spread_type: global___TrailingValueType.ValueType
"""Тип величины защитного спреда."""
@property
def indent(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Отступ."""
@property
def spread(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Размер защитного спреда."""
def __init__(
self,
*,
indent: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
indent_type: global___TrailingValueType.ValueType = ...,
spread: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
spread_type: global___TrailingValueType.ValueType = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["indent", b"indent", "spread", b"spread"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["indent", b"indent", "indent_type", b"indent_type", "spread", b"spread", "spread_type", b"spread_type"]) -> None: ...
FIGI_FIELD_NUMBER: builtins.int
QUANTITY_FIELD_NUMBER: builtins.int
PRICE_FIELD_NUMBER: builtins.int
STOP_PRICE_FIELD_NUMBER: builtins.int
DIRECTION_FIELD_NUMBER: builtins.int
ACCOUNT_ID_FIELD_NUMBER: builtins.int
EXPIRATION_TYPE_FIELD_NUMBER: builtins.int
STOP_ORDER_TYPE_FIELD_NUMBER: builtins.int
EXPIRE_DATE_FIELD_NUMBER: builtins.int
INSTRUMENT_ID_FIELD_NUMBER: builtins.int
EXCHANGE_ORDER_TYPE_FIELD_NUMBER: builtins.int
TAKE_PROFIT_TYPE_FIELD_NUMBER: builtins.int
TRAILING_DATA_FIELD_NUMBER: builtins.int
PRICE_TYPE_FIELD_NUMBER: builtins.int
ORDER_ID_FIELD_NUMBER: builtins.int
CONFIRM_MARGIN_TRADE_FIELD_NUMBER: builtins.int
INSTANT_EXECUTION_FIELD_NUMBER: builtins.int
figi: builtins.str
"""Deprecated FIGI-идентификатор инструмента. Используйте `instrument_id`."""
quantity: builtins.int
"""Количество лотов."""
direction: global___StopOrderDirection.ValueType
"""Направление операции."""
account_id: builtins.str
"""Номер счета."""
expiration_type: global___StopOrderExpirationType.ValueType
"""Тип экспирации заявки."""
stop_order_type: global___StopOrderType.ValueType
"""Тип заявки."""
instrument_id: builtins.str
"""Идентификатор инструмента. Принимает значение `figi`, `instrument_uid` или `ticker + '_' + class_code`."""
exchange_order_type: global___ExchangeOrderType.ValueType
"""Тип дочерней биржевой заявки."""
take_profit_type: global___TakeProfitType.ValueType
"""Подтип стоп-заявки — `TakeProfit`."""
price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType
"""Тип цены."""
order_id: builtins.str
"""Идентификатор запроса выставления поручения для целей идемпотентности в формате `UID`. Максимальная длина — 36 символов."""
confirm_margin_trade: builtins.bool
"""Согласие на выставление заявки, которая может привести к непокрытой позиции, по умолчанию false."""
instant_execution: builtins.bool
"""Признак необходимости моментальной активации, используется только для трейлинг-стопа."""
@property
def price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Цена за 1 инструмент биржевой заявки, которая будет выставлена при срабатывании по достижению `stop_price`. Чтобы получить стоимость лота, нужно умножить на лотность инструмента."""
@property
def stop_price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Стоп-цена заявки за 1 инструмент. При достижении стоп-цены происходит активация стоп-заявки, в результате чего выставляется биржевая заявка. Чтобы получить стоимость лота, нужно умножить на лотность инструмента."""
@property
def expire_date(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время окончания действия стоп-заявки по UTC. Для `ExpirationType = GoodTillDate` заполнение обязательно, для `GoodTillCancel` игнорируется."""
@property
def trailing_data(self) -> global___PostStopOrderRequest.TrailingData:
"""Массив с параметрами трейлинг-стопа."""
def __init__(
self,
*,
figi: builtins.str | None = ...,
quantity: builtins.int = ...,
price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
stop_price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
direction: global___StopOrderDirection.ValueType = ...,
account_id: builtins.str = ...,
expiration_type: global___StopOrderExpirationType.ValueType = ...,
stop_order_type: global___StopOrderType.ValueType = ...,
expire_date: google.protobuf.timestamp_pb2.Timestamp | None = ...,
instrument_id: builtins.str = ...,
exchange_order_type: global___ExchangeOrderType.ValueType = ...,
take_profit_type: global___TakeProfitType.ValueType = ...,
trailing_data: global___PostStopOrderRequest.TrailingData | None = ...,
price_type: t_tech.invest.grpc.common_pb2.PriceType.ValueType = ...,
order_id: builtins.str = ...,
confirm_margin_trade: builtins.bool = ...,
instant_execution: builtins.bool | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_expire_date", b"_expire_date", "_figi", b"_figi", "_instant_execution", b"_instant_execution", "_price", b"_price", "_stop_price", b"_stop_price", "expire_date", b"expire_date", "figi", b"figi", "instant_execution", b"instant_execution", "price", b"price", "stop_price", b"stop_price", "trailing_data", b"trailing_data"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_expire_date", b"_expire_date", "_figi", b"_figi", "_instant_execution", b"_instant_execution", "_price", b"_price", "_stop_price", b"_stop_price", "account_id", b"account_id", "confirm_margin_trade", b"confirm_margin_trade", "direction", b"direction", "exchange_order_type", b"exchange_order_type", "expiration_type", b"expiration_type", "expire_date", b"expire_date", "figi", b"figi", "instant_execution", b"instant_execution", "instrument_id", b"instrument_id", "order_id", b"order_id", "price", b"price", "price_type", b"price_type", "quantity", b"quantity", "stop_order_type", b"stop_order_type", "stop_price", b"stop_price", "take_profit_type", b"take_profit_type", "trailing_data", b"trailing_data"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_expire_date", b"_expire_date"]) -> typing.Literal["expire_date"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_figi", b"_figi"]) -> typing.Literal["figi"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_instant_execution", b"_instant_execution"]) -> typing.Literal["instant_execution"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_price", b"_price"]) -> typing.Literal["price"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_stop_price", b"_stop_price"]) -> typing.Literal["stop_price"] | None: ...
global___PostStopOrderRequest = PostStopOrderRequest
@typing.final
class PostStopOrderResponse(google.protobuf.message.Message):
"""Результат выставления стоп-заявки."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STOP_ORDER_ID_FIELD_NUMBER: builtins.int
ORDER_REQUEST_ID_FIELD_NUMBER: builtins.int
RESPONSE_METADATA_FIELD_NUMBER: builtins.int
stop_order_id: builtins.str
"""Уникальный идентификатор стоп-заявки."""
order_request_id: builtins.str
"""Идентификатор ключа идемпотентности, переданный клиентом, в формате `UID`. Максимальная длина 36 — символов."""
@property
def response_metadata(self) -> t_tech.invest.grpc.common_pb2.ResponseMetadata:
"""Метадата."""
def __init__(
self,
*,
stop_order_id: builtins.str = ...,
order_request_id: builtins.str = ...,
response_metadata: t_tech.invest.grpc.common_pb2.ResponseMetadata | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["response_metadata", b"response_metadata"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["order_request_id", b"order_request_id", "response_metadata", b"response_metadata", "stop_order_id", b"stop_order_id"]) -> None: ...
global___PostStopOrderResponse = PostStopOrderResponse
@typing.final
class GetStopOrdersRequest(google.protobuf.message.Message):
"""Запрос получения списка активных стоп-заявок."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
STATUS_FIELD_NUMBER: builtins.int
FROM_FIELD_NUMBER: builtins.int
TO_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Идентификатор счета клиента."""
status: global___StopOrderStatusOption.ValueType
"""Статус заявок."""
@property
def to(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Правая граница."""
def __init__(
self,
*,
account_id: builtins.str = ...,
status: global___StopOrderStatusOption.ValueType = ...,
to: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["from", b"from", "to", b"to"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "from", b"from", "status", b"status", "to", b"to"]) -> None: ...
global___GetStopOrdersRequest = GetStopOrdersRequest
@typing.final
class GetStopOrdersResponse(google.protobuf.message.Message):
"""Список активных стоп-заявок."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STOP_ORDERS_FIELD_NUMBER: builtins.int
@property
def stop_orders(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StopOrder]:
"""Массив стоп-заявок по счету."""
def __init__(
self,
*,
stop_orders: collections.abc.Iterable[global___StopOrder] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["stop_orders", b"stop_orders"]) -> None: ...
global___GetStopOrdersResponse = GetStopOrdersResponse
@typing.final
class CancelStopOrderRequest(google.protobuf.message.Message):
"""Запрос отмены выставленной стоп-заявки."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
STOP_ORDER_ID_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Идентификатор счета клиента."""
stop_order_id: builtins.str
"""Уникальный идентификатор стоп-заявки."""
def __init__(
self,
*,
account_id: builtins.str = ...,
stop_order_id: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "stop_order_id", b"stop_order_id"]) -> None: ...
global___CancelStopOrderRequest = CancelStopOrderRequest
@typing.final
class CancelStopOrderResponse(google.protobuf.message.Message):
"""Результат отмены выставленной стоп-заявки."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TIME_FIELD_NUMBER: builtins.int
@property
def time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Время отмены заявки по UTC."""
def __init__(
self,
*,
time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["time", b"time"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["time", b"time"]) -> None: ...
global___CancelStopOrderResponse = CancelStopOrderResponse
@typing.final
class StopOrder(google.protobuf.message.Message):
"""Информация о стоп-заявке."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@typing.final
class TrailingData(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
INDENT_FIELD_NUMBER: builtins.int
INDENT_TYPE_FIELD_NUMBER: builtins.int
SPREAD_FIELD_NUMBER: builtins.int
SPREAD_TYPE_FIELD_NUMBER: builtins.int
STATUS_FIELD_NUMBER: builtins.int
PRICE_FIELD_NUMBER: builtins.int
EXTR_FIELD_NUMBER: builtins.int
indent_type: global___TrailingValueType.ValueType
"""Тип величины отступа."""
spread_type: global___TrailingValueType.ValueType
"""Тип величины защитного спреда."""
status: global___TrailingStopStatus.ValueType
"""Статус трейлинг-стопа."""
@property
def indent(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Отступ."""
@property
def spread(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Размер защитного спреда."""
@property
def price(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Цена исполнения."""
@property
def extr(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Локальный экстремум."""
def __init__(
self,
*,
indent: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
indent_type: global___TrailingValueType.ValueType = ...,
spread: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
spread_type: global___TrailingValueType.ValueType = ...,
status: global___TrailingStopStatus.ValueType = ...,
price: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
extr: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["extr", b"extr", "indent", b"indent", "price", b"price", "spread", b"spread"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["extr", b"extr", "indent", b"indent", "indent_type", b"indent_type", "price", b"price", "spread", b"spread", "spread_type", b"spread_type", "status", b"status"]) -> None: ...
STOP_ORDER_ID_FIELD_NUMBER: builtins.int
LOTS_REQUESTED_FIELD_NUMBER: builtins.int
FIGI_FIELD_NUMBER: builtins.int
DIRECTION_FIELD_NUMBER: builtins.int
CURRENCY_FIELD_NUMBER: builtins.int
ORDER_TYPE_FIELD_NUMBER: builtins.int
CREATE_DATE_FIELD_NUMBER: builtins.int
ACTIVATION_DATE_TIME_FIELD_NUMBER: builtins.int
EXPIRATION_TIME_FIELD_NUMBER: builtins.int
PRICE_FIELD_NUMBER: builtins.int
STOP_PRICE_FIELD_NUMBER: builtins.int
INSTRUMENT_UID_FIELD_NUMBER: builtins.int
TAKE_PROFIT_TYPE_FIELD_NUMBER: builtins.int
TRAILING_DATA_FIELD_NUMBER: builtins.int
STATUS_FIELD_NUMBER: builtins.int
EXCHANGE_ORDER_TYPE_FIELD_NUMBER: builtins.int
EXCHANGE_ORDER_ID_FIELD_NUMBER: builtins.int
TICKER_FIELD_NUMBER: builtins.int
CLASS_CODE_FIELD_NUMBER: builtins.int
INSTANT_EXECUTION_FIELD_NUMBER: builtins.int
stop_order_id: builtins.str
"""Уникальный идентификатор стоп-заявки."""
lots_requested: builtins.int
"""Запрошено лотов."""
figi: builtins.str
"""FIGI-идентификатор инструмента."""
direction: global___StopOrderDirection.ValueType
"""Направление операции."""
currency: builtins.str
"""Валюта стоп-заявки."""
order_type: global___StopOrderType.ValueType
"""Тип стоп-заявки."""
instrument_uid: builtins.str
"""`instrument_uid`-идентификатор инструмента."""
take_profit_type: global___TakeProfitType.ValueType
"""Подтип стоп-заявки — `TakeProfit`."""
status: global___StopOrderStatusOption.ValueType
"""Статус заявки."""
exchange_order_type: global___ExchangeOrderType.ValueType
"""Тип дочерней биржевой заявки для тейкпрофита."""
exchange_order_id: builtins.str
"""Идентификатор биржевой заявки."""
ticker: builtins.str
"""Тикер инструмента."""
class_code: builtins.str
"""Класс-код (секция торгов)."""
instant_execution: builtins.bool
"""Признак необходимости моментальной активации, используется только для трейлинг-стопа."""
@property
def create_date(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время выставления заявки по UTC."""
@property
def activation_date_time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время конвертации стоп-заявки в биржевую по UTC."""
@property
def expiration_time(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата и время снятия заявки по UTC."""
@property
def price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Цена заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента."""
@property
def stop_price(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Цена активации стоп-заявки за 1 инструмент. Чтобы получить стоимость лота, нужно умножить на лотность инструмента."""
@property
def trailing_data(self) -> global___StopOrder.TrailingData:
"""Параметры трейлинг-стопа."""
def __init__(
self,
*,
stop_order_id: builtins.str = ...,
lots_requested: builtins.int = ...,
figi: builtins.str = ...,
direction: global___StopOrderDirection.ValueType = ...,
currency: builtins.str = ...,
order_type: global___StopOrderType.ValueType = ...,
create_date: google.protobuf.timestamp_pb2.Timestamp | None = ...,
activation_date_time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
expiration_time: google.protobuf.timestamp_pb2.Timestamp | None = ...,
price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
stop_price: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
instrument_uid: builtins.str = ...,
take_profit_type: global___TakeProfitType.ValueType = ...,
trailing_data: global___StopOrder.TrailingData | None = ...,
status: global___StopOrderStatusOption.ValueType = ...,
exchange_order_type: global___ExchangeOrderType.ValueType = ...,
exchange_order_id: builtins.str | None = ...,
ticker: builtins.str = ...,
class_code: builtins.str = ...,
instant_execution: builtins.bool = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_exchange_order_id", b"_exchange_order_id", "activation_date_time", b"activation_date_time", "create_date", b"create_date", "exchange_order_id", b"exchange_order_id", "expiration_time", b"expiration_time", "price", b"price", "stop_price", b"stop_price", "trailing_data", b"trailing_data"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_exchange_order_id", b"_exchange_order_id", "activation_date_time", b"activation_date_time", "class_code", b"class_code", "create_date", b"create_date", "currency", b"currency", "direction", b"direction", "exchange_order_id", b"exchange_order_id", "exchange_order_type", b"exchange_order_type", "expiration_time", b"expiration_time", "figi", b"figi", "instant_execution", b"instant_execution", "instrument_uid", b"instrument_uid", "lots_requested", b"lots_requested", "order_type", b"order_type", "price", b"price", "status", b"status", "stop_order_id", b"stop_order_id", "stop_price", b"stop_price", "take_profit_type", b"take_profit_type", "ticker", b"ticker", "trailing_data", b"trailing_data"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_exchange_order_id", b"_exchange_order_id"]) -> typing.Literal["exchange_order_id"] | None: ...
global___StopOrder = StopOrder

View File

@@ -0,0 +1,140 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import (
stoporders_pb2 as t__tech_dot_invest_dot_grpc_dot_stoporders__pb2,
)
class StopOrdersServiceStub(object):
"""Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.PostStopOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.StopOrdersService/PostStopOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString,
)
self.GetStopOrders = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.StopOrdersService/GetStopOrders',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString,
)
self.CancelStopOrder = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.StopOrdersService/CancelStopOrder',
request_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString,
)
class StopOrdersServiceServicer(object):
"""Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок.
"""
def PostStopOrder(self, request, context):
"""PostStopOrder — выставить стоп-заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetStopOrders(self, request, context):
"""GetStopOrders — получить список активных стоп-заявок по счету
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CancelStopOrder(self, request, context):
"""CancelStopOrder — отменить стоп-заявку
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_StopOrdersServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'PostStopOrder': grpc.unary_unary_rpc_method_handler(
servicer.PostStopOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.SerializeToString,
),
'GetStopOrders': grpc.unary_unary_rpc_method_handler(
servicer.GetStopOrders,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.SerializeToString,
),
'CancelStopOrder': grpc.unary_unary_rpc_method_handler(
servicer.CancelStopOrder,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.StopOrdersService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class StopOrdersService(object):
"""Сервис для работы со стоп-заявками: выставление, отмена, получение списка стоп-заявок.
"""
@staticmethod
def PostStopOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/PostStopOrder',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.PostStopOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetStopOrders(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/GetStopOrders',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.GetStopOrdersResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CancelStopOrder(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.StopOrdersService/CancelStopOrder',
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_stoporders__pb2.CancelStopOrderResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,695 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import google.protobuf.timestamp_pb2
import sys
import t_tech.invest.grpc.common_pb2
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _AccountType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _AccountTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ACCOUNT_TYPE_UNSPECIFIED: _AccountType.ValueType # 0
"""Тип аккаунта не определeн."""
ACCOUNT_TYPE_TINKOFF: _AccountType.ValueType # 1
"""Брокерский счeт Т-Инвестиций."""
ACCOUNT_TYPE_TINKOFF_IIS: _AccountType.ValueType # 2
"""ИИС."""
ACCOUNT_TYPE_INVEST_BOX: _AccountType.ValueType # 3
"""Инвесткопилка."""
ACCOUNT_TYPE_INVEST_FUND: _AccountType.ValueType # 4
"""Фонд денежного рынка."""
ACCOUNT_TYPE_DEBIT: _AccountType.ValueType # 5
"""Дебетовый карточный счeт."""
ACCOUNT_TYPE_SAVING: _AccountType.ValueType # 6
"""Накопительный счeт."""
ACCOUNT_TYPE_DFA: _AccountType.ValueType # 7
"""Смарт-счет."""
class AccountType(_AccountType, metaclass=_AccountTypeEnumTypeWrapper):
"""Тип счeта."""
ACCOUNT_TYPE_UNSPECIFIED: AccountType.ValueType # 0
"""Тип аккаунта не определeн."""
ACCOUNT_TYPE_TINKOFF: AccountType.ValueType # 1
"""Брокерский счeт Т-Инвестиций."""
ACCOUNT_TYPE_TINKOFF_IIS: AccountType.ValueType # 2
"""ИИС."""
ACCOUNT_TYPE_INVEST_BOX: AccountType.ValueType # 3
"""Инвесткопилка."""
ACCOUNT_TYPE_INVEST_FUND: AccountType.ValueType # 4
"""Фонд денежного рынка."""
ACCOUNT_TYPE_DEBIT: AccountType.ValueType # 5
"""Дебетовый карточный счeт."""
ACCOUNT_TYPE_SAVING: AccountType.ValueType # 6
"""Накопительный счeт."""
ACCOUNT_TYPE_DFA: AccountType.ValueType # 7
"""Смарт-счет."""
global___AccountType = AccountType
class _AccountStatus:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _AccountStatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountStatus.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ACCOUNT_STATUS_UNSPECIFIED: _AccountStatus.ValueType # 0
"""Статус счeта не определeн."""
ACCOUNT_STATUS_NEW: _AccountStatus.ValueType # 1
"""Новый, в процессе открытия."""
ACCOUNT_STATUS_OPEN: _AccountStatus.ValueType # 2
"""Открытый и активный счeт."""
ACCOUNT_STATUS_CLOSED: _AccountStatus.ValueType # 3
"""Закрытый счeт."""
ACCOUNT_STATUS_ALL: _AccountStatus.ValueType # 4
"""Все счета."""
class AccountStatus(_AccountStatus, metaclass=_AccountStatusEnumTypeWrapper):
"""Статус счeта."""
ACCOUNT_STATUS_UNSPECIFIED: AccountStatus.ValueType # 0
"""Статус счeта не определeн."""
ACCOUNT_STATUS_NEW: AccountStatus.ValueType # 1
"""Новый, в процессе открытия."""
ACCOUNT_STATUS_OPEN: AccountStatus.ValueType # 2
"""Открытый и активный счeт."""
ACCOUNT_STATUS_CLOSED: AccountStatus.ValueType # 3
"""Закрытый счeт."""
ACCOUNT_STATUS_ALL: AccountStatus.ValueType # 4
"""Все счета."""
global___AccountStatus = AccountStatus
class _AccessLevel:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _AccessLevelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccessLevel.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ACCOUNT_ACCESS_LEVEL_UNSPECIFIED: _AccessLevel.ValueType # 0
"""Уровень доступа не определeн."""
ACCOUNT_ACCESS_LEVEL_FULL_ACCESS: _AccessLevel.ValueType # 1
"""Полный доступ к счeту."""
ACCOUNT_ACCESS_LEVEL_READ_ONLY: _AccessLevel.ValueType # 2
"""Доступ с уровнем прав «только чтение»."""
ACCOUNT_ACCESS_LEVEL_NO_ACCESS: _AccessLevel.ValueType # 3
"""Доступа нет."""
class AccessLevel(_AccessLevel, metaclass=_AccessLevelEnumTypeWrapper):
"""Уровень доступа к счeту."""
ACCOUNT_ACCESS_LEVEL_UNSPECIFIED: AccessLevel.ValueType # 0
"""Уровень доступа не определeн."""
ACCOUNT_ACCESS_LEVEL_FULL_ACCESS: AccessLevel.ValueType # 1
"""Полный доступ к счeту."""
ACCOUNT_ACCESS_LEVEL_READ_ONLY: AccessLevel.ValueType # 2
"""Доступ с уровнем прав «только чтение»."""
ACCOUNT_ACCESS_LEVEL_NO_ACCESS: AccessLevel.ValueType # 3
"""Доступа нет."""
global___AccessLevel = AccessLevel
class _AccountValue:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _AccountValueEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AccountValue.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ACCOUNT_VALUE_UNSPECIFIED: _AccountValue.ValueType # 0
"""Не определён."""
ACCOUNT_VALUE_MARGIN_FEE: _AccountValue.ValueType # 1
"""Размер комиссии за маржинальное кредитование."""
ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE: _AccountValue.ValueType # 2
"""Остаток доступного лимита с текущей комиссией."""
class AccountValue(_AccountValue, metaclass=_AccountValueEnumTypeWrapper): ...
ACCOUNT_VALUE_UNSPECIFIED: AccountValue.ValueType # 0
"""Не определён."""
ACCOUNT_VALUE_MARGIN_FEE: AccountValue.ValueType # 1
"""Размер комиссии за маржинальное кредитование."""
ACCOUNT_VALUE_AMOUNT_WITHOUT_EXTRA_FEE: AccountValue.ValueType # 2
"""Остаток доступного лимита с текущей комиссией."""
global___AccountValue = AccountValue
@typing.final
class GetAccountsRequest(google.protobuf.message.Message):
"""Запрос получения счетов пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
STATUS_FIELD_NUMBER: builtins.int
status: global___AccountStatus.ValueType
"""Статус счета."""
def __init__(
self,
*,
status: global___AccountStatus.ValueType | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_status", b"_status", "status", b"status"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_status", b"_status", "status", b"status"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_status", b"_status"]) -> typing.Literal["status"] | None: ...
global___GetAccountsRequest = GetAccountsRequest
@typing.final
class GetAccountsResponse(google.protobuf.message.Message):
"""Список счетов пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNTS_FIELD_NUMBER: builtins.int
@property
def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Account]:
"""Массив счетов клиента."""
def __init__(
self,
*,
accounts: collections.abc.Iterable[global___Account] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["accounts", b"accounts"]) -> None: ...
global___GetAccountsResponse = GetAccountsResponse
@typing.final
class Account(google.protobuf.message.Message):
"""Информация о счeте."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ID_FIELD_NUMBER: builtins.int
TYPE_FIELD_NUMBER: builtins.int
NAME_FIELD_NUMBER: builtins.int
STATUS_FIELD_NUMBER: builtins.int
OPENED_DATE_FIELD_NUMBER: builtins.int
CLOSED_DATE_FIELD_NUMBER: builtins.int
ACCESS_LEVEL_FIELD_NUMBER: builtins.int
id: builtins.str
"""Идентификатор счeта."""
type: global___AccountType.ValueType
"""Тип счeта."""
name: builtins.str
"""Название счeта."""
status: global___AccountStatus.ValueType
"""Статус счeта."""
access_level: global___AccessLevel.ValueType
"""Уровень доступа к текущему счeту (определяется токеном)."""
@property
def opened_date(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата открытия счeта в часовом поясе UTC."""
@property
def closed_date(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата закрытия счeта в часовом поясе UTC."""
def __init__(
self,
*,
id: builtins.str = ...,
type: global___AccountType.ValueType = ...,
name: builtins.str = ...,
status: global___AccountStatus.ValueType = ...,
opened_date: google.protobuf.timestamp_pb2.Timestamp | None = ...,
closed_date: google.protobuf.timestamp_pb2.Timestamp | None = ...,
access_level: global___AccessLevel.ValueType = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["closed_date", b"closed_date", "opened_date", b"opened_date"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["access_level", b"access_level", "closed_date", b"closed_date", "id", b"id", "name", b"name", "opened_date", b"opened_date", "status", b"status", "type", b"type"]) -> None: ...
global___Account = Account
@typing.final
class GetMarginAttributesRequest(google.protobuf.message.Message):
"""Запрос маржинальных показателей по счeту."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Идентификатор счeта пользователя."""
def __init__(
self,
*,
account_id: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id"]) -> None: ...
global___GetMarginAttributesRequest = GetMarginAttributesRequest
@typing.final
class GetMarginAttributesResponse(google.protobuf.message.Message):
"""Маржинальные показатели по счeту."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LIQUID_PORTFOLIO_FIELD_NUMBER: builtins.int
STARTING_MARGIN_FIELD_NUMBER: builtins.int
MINIMAL_MARGIN_FIELD_NUMBER: builtins.int
FUNDS_SUFFICIENCY_LEVEL_FIELD_NUMBER: builtins.int
AMOUNT_OF_MISSING_FUNDS_FIELD_NUMBER: builtins.int
CORRECTED_MARGIN_FIELD_NUMBER: builtins.int
GUARANTEE_FOR_FUTURES_FIELD_NUMBER: builtins.int
@property
def liquid_portfolio(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Ликвидная стоимость портфеля. [Подробнее про ликвидный портфель](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q4)."""
@property
def starting_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Начальная маржа — начальное обеспечение для совершения новой сделки. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6)."""
@property
def minimal_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Минимальная маржа — это минимальное обеспечение для поддержания позиции, которую вы уже открыли. [Подробнее про начальную и минимальную маржу](https://www.tbank.ru/invest/help/brokerage/account/margin/about/#q6)."""
@property
def funds_sufficiency_level(self) -> t_tech.invest.grpc.common_pb2.Quotation:
"""Уровень достаточности средств. Соотношение стоимости ликвидного портфеля к начальной марже."""
@property
def amount_of_missing_funds(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Объем недостающих средств. Разница между стартовой маржой и ликвидной стоимости портфеля."""
@property
def corrected_margin(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Скорректированная маржа. Начальная маржа, в которой плановые позиции рассчитываются с учeтом активных заявок на покупку позиций лонг или продажу позиций шорт."""
@property
def guarantee_for_futures(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Размер гарантийного обеспечения, заблокированного под фьючерсы."""
def __init__(
self,
*,
liquid_portfolio: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
starting_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
minimal_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
funds_sufficiency_level: t_tech.invest.grpc.common_pb2.Quotation | None = ...,
amount_of_missing_funds: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
corrected_margin: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
guarantee_for_futures: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["amount_of_missing_funds", b"amount_of_missing_funds", "corrected_margin", b"corrected_margin", "funds_sufficiency_level", b"funds_sufficiency_level", "guarantee_for_futures", b"guarantee_for_futures", "liquid_portfolio", b"liquid_portfolio", "minimal_margin", b"minimal_margin", "starting_margin", b"starting_margin"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["amount_of_missing_funds", b"amount_of_missing_funds", "corrected_margin", b"corrected_margin", "funds_sufficiency_level", b"funds_sufficiency_level", "guarantee_for_futures", b"guarantee_for_futures", "liquid_portfolio", b"liquid_portfolio", "minimal_margin", b"minimal_margin", "starting_margin", b"starting_margin"]) -> None: ...
global___GetMarginAttributesResponse = GetMarginAttributesResponse
@typing.final
class GetUserTariffRequest(google.protobuf.message.Message):
"""Запрос текущих лимитов пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___GetUserTariffRequest = GetUserTariffRequest
@typing.final
class GetUserTariffResponse(google.protobuf.message.Message):
"""Текущие лимиты пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
UNARY_LIMITS_FIELD_NUMBER: builtins.int
STREAM_LIMITS_FIELD_NUMBER: builtins.int
@property
def unary_limits(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___UnaryLimit]:
"""Массив лимитов пользователя по unary-запросам."""
@property
def stream_limits(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StreamLimit]:
"""Массив лимитов пользователей для stream-соединений."""
def __init__(
self,
*,
unary_limits: collections.abc.Iterable[global___UnaryLimit] | None = ...,
stream_limits: collections.abc.Iterable[global___StreamLimit] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["stream_limits", b"stream_limits", "unary_limits", b"unary_limits"]) -> None: ...
global___GetUserTariffResponse = GetUserTariffResponse
@typing.final
class UnaryLimit(google.protobuf.message.Message):
"""Лимит unary-методов."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LIMIT_PER_MINUTE_FIELD_NUMBER: builtins.int
METHODS_FIELD_NUMBER: builtins.int
LIMIT_PER_SECOND_FIELD_NUMBER: builtins.int
limit_per_minute: builtins.int
"""Количество unary-запросов в минуту."""
limit_per_second: builtins.int
"""Количество unary-запросов в секунду."""
@property
def methods(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Названия методов."""
def __init__(
self,
*,
limit_per_minute: builtins.int = ...,
methods: collections.abc.Iterable[builtins.str] | None = ...,
limit_per_second: builtins.int | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_limit_per_second", b"_limit_per_second", "limit_per_second", b"limit_per_second"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_limit_per_second", b"_limit_per_second", "limit_per_minute", b"limit_per_minute", "limit_per_second", b"limit_per_second", "methods", b"methods"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_limit_per_second", b"_limit_per_second"]) -> typing.Literal["limit_per_second"] | None: ...
global___UnaryLimit = UnaryLimit
@typing.final
class StreamLimit(google.protobuf.message.Message):
"""Лимит stream-соединений."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
LIMIT_FIELD_NUMBER: builtins.int
STREAMS_FIELD_NUMBER: builtins.int
OPEN_FIELD_NUMBER: builtins.int
limit: builtins.int
"""Максимальное количество stream-соединений."""
open: builtins.int
"""Текущее количество открытых stream-соединений."""
@property
def streams(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Названия stream-методов."""
def __init__(
self,
*,
limit: builtins.int = ...,
streams: collections.abc.Iterable[builtins.str] | None = ...,
open: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["limit", b"limit", "open", b"open", "streams", b"streams"]) -> None: ...
global___StreamLimit = StreamLimit
@typing.final
class GetInfoRequest(google.protobuf.message.Message):
"""Запрос информации о пользователе."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___GetInfoRequest = GetInfoRequest
@typing.final
class GetInfoResponse(google.protobuf.message.Message):
"""Информация о пользователе."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
PREM_STATUS_FIELD_NUMBER: builtins.int
QUAL_STATUS_FIELD_NUMBER: builtins.int
QUALIFIED_FOR_WORK_WITH_FIELD_NUMBER: builtins.int
TARIFF_FIELD_NUMBER: builtins.int
USER_ID_FIELD_NUMBER: builtins.int
RISK_LEVEL_CODE_FIELD_NUMBER: builtins.int
prem_status: builtins.bool
"""Признак премиум клиента."""
qual_status: builtins.bool
"""Признак квалифицированного инвестора."""
tariff: builtins.str
"""Наименование тарифа пользователя."""
user_id: builtins.str
"""Идентификатор пользователя."""
risk_level_code: builtins.str
"""Категория риска."""
@property
def qualified_for_work_with(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Набор требующих тестирования инструментов и возможностей, с которыми может работать пользователь. [Подробнее](/invest/services/accounts/faq_users)."""
def __init__(
self,
*,
prem_status: builtins.bool = ...,
qual_status: builtins.bool = ...,
qualified_for_work_with: collections.abc.Iterable[builtins.str] | None = ...,
tariff: builtins.str = ...,
user_id: builtins.str = ...,
risk_level_code: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["prem_status", b"prem_status", "qual_status", b"qual_status", "qualified_for_work_with", b"qualified_for_work_with", "risk_level_code", b"risk_level_code", "tariff", b"tariff", "user_id", b"user_id"]) -> None: ...
global___GetInfoResponse = GetInfoResponse
@typing.final
class GetBankAccountsRequest(google.protobuf.message.Message):
"""Запрос списка банковских счетов пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___GetBankAccountsRequest = GetBankAccountsRequest
@typing.final
class GetBankAccountsResponse(google.protobuf.message.Message):
"""Список банковских счетов пользователя."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
BANK_ACCOUNTS_FIELD_NUMBER: builtins.int
@property
def bank_accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BankAccount]:
"""Массив банковских счетов."""
def __init__(
self,
*,
bank_accounts: collections.abc.Iterable[global___BankAccount] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["bank_accounts", b"bank_accounts"]) -> None: ...
global___GetBankAccountsResponse = GetBankAccountsResponse
@typing.final
class BankAccount(google.protobuf.message.Message):
"""Банковский счeт."""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ID_FIELD_NUMBER: builtins.int
NAME_FIELD_NUMBER: builtins.int
MONEY_FIELD_NUMBER: builtins.int
OPENED_DATE_FIELD_NUMBER: builtins.int
TYPE_FIELD_NUMBER: builtins.int
id: builtins.str
"""Идентификатор счeта."""
name: builtins.str
"""Название счeта."""
type: global___AccountType.ValueType
"""Тип счeта."""
@property
def money(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[t_tech.invest.grpc.common_pb2.MoneyValue]:
"""Список валютных позиций на счeте."""
@property
def opened_date(self) -> google.protobuf.timestamp_pb2.Timestamp:
"""Дата открытия счeта в часовом поясе UTC."""
def __init__(
self,
*,
id: builtins.str = ...,
name: builtins.str = ...,
money: collections.abc.Iterable[t_tech.invest.grpc.common_pb2.MoneyValue] | None = ...,
opened_date: google.protobuf.timestamp_pb2.Timestamp | None = ...,
type: global___AccountType.ValueType = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["opened_date", b"opened_date"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["id", b"id", "money", b"money", "name", b"name", "opened_date", b"opened_date", "type", b"type"]) -> None: ...
global___BankAccount = BankAccount
@typing.final
class CurrencyTransferRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
FROM_ACCOUNT_ID_FIELD_NUMBER: builtins.int
TO_ACCOUNT_ID_FIELD_NUMBER: builtins.int
AMOUNT_FIELD_NUMBER: builtins.int
TRANSACTION_ID_FIELD_NUMBER: builtins.int
from_account_id: builtins.str
"""Номер счета списания."""
to_account_id: builtins.str
"""Номер счета зачисления."""
transaction_id: builtins.str
"""Идентификатор запроса выставления поручения для целей идемпотентности в формате UUID."""
@property
def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Сумма перевода с указанием валюты."""
def __init__(
self,
*,
from_account_id: builtins.str = ...,
to_account_id: builtins.str = ...,
amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
transaction_id: builtins.str = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["amount", b"amount", "from_account_id", b"from_account_id", "to_account_id", b"to_account_id", "transaction_id", b"transaction_id"]) -> None: ...
global___CurrencyTransferRequest = CurrencyTransferRequest
@typing.final
class CurrencyTransferResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___CurrencyTransferResponse = CurrencyTransferResponse
@typing.final
class PayInRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
FROM_ACCOUNT_ID_FIELD_NUMBER: builtins.int
TO_ACCOUNT_ID_FIELD_NUMBER: builtins.int
AMOUNT_FIELD_NUMBER: builtins.int
from_account_id: builtins.str
"""Номер счета списания."""
to_account_id: builtins.str
"""Номер брокерского счета зачисления."""
@property
def amount(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Сумма перевода с указанием валюты."""
def __init__(
self,
*,
from_account_id: builtins.str = ...,
to_account_id: builtins.str = ...,
amount: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["amount", b"amount"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["amount", b"amount", "from_account_id", b"from_account_id", "to_account_id", b"to_account_id"]) -> None: ...
global___PayInRequest = PayInRequest
@typing.final
class PayInResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___PayInResponse = PayInResponse
@typing.final
class GetAccountValuesRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNTS_FIELD_NUMBER: builtins.int
VALUES_FIELD_NUMBER: builtins.int
@property
def accounts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Массив счетов пользователя."""
@property
def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___AccountValue.ValueType]:
"""Массив запрашиваемых параметров."""
def __init__(
self,
*,
accounts: collections.abc.Iterable[builtins.str] | None = ...,
values: collections.abc.Iterable[global___AccountValue.ValueType] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["accounts", b"accounts", "values", b"values"]) -> None: ...
global___GetAccountValuesRequest = GetAccountValuesRequest
@typing.final
class GetAccountValuesResponse(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNTS_FIELD_NUMBER: builtins.int
@property
def accounts(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AccountValuesWithParameters]:
"""Массив счетов с параметрами."""
def __init__(
self,
*,
accounts: collections.abc.Iterable[global___AccountValuesWithParameters] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["accounts", b"accounts"]) -> None: ...
global___GetAccountValuesResponse = GetAccountValuesResponse
@typing.final
class AccountValuesWithParameters(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ACCOUNT_ID_FIELD_NUMBER: builtins.int
VALUES_FIELD_NUMBER: builtins.int
account_id: builtins.str
"""Номер счета."""
@property
def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___InstrumentParameter]:
"""Массив параметров инструмента."""
def __init__(
self,
*,
account_id: builtins.str = ...,
values: collections.abc.Iterable[global___InstrumentParameter] | None = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["account_id", b"account_id", "values", b"values"]) -> None: ...
global___AccountValuesWithParameters = AccountValuesWithParameters
@typing.final
class InstrumentParameter(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NAME_FIELD_NUMBER: builtins.int
VALUE_FIELD_NUMBER: builtins.int
name: global___AccountValue.ValueType
"""Тип запрашиваемого параметра."""
@property
def value(self) -> t_tech.invest.grpc.common_pb2.MoneyValue:
"""Значение запрашиваемого параметра."""
def __init__(
self,
*,
name: global___AccountValue.ValueType = ...,
value: t_tech.invest.grpc.common_pb2.MoneyValue | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["value", b"value"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["name", b"name", "value", b"value"]) -> None: ...
global___InstrumentParameter = InstrumentParameter

View File

@@ -0,0 +1,319 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from t_tech.invest.grpc import users_pb2 as t__tech_dot_invest_dot_grpc_dot_users__pb2
class UsersServiceStub(object):
"""С помощью сервиса можно получить: <br/> 1.
список счетов пользователя; <br/> 2. маржинальные показатели по счeту.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetAccounts = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetAccounts',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString,
)
self.GetMarginAttributes = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetMarginAttributes',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.FromString,
)
self.GetUserTariff = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetUserTariff',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.FromString,
)
self.GetInfo = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetInfo',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.FromString,
)
self.GetBankAccounts = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetBankAccounts',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.FromString,
)
self.CurrencyTransfer = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/CurrencyTransfer',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.FromString,
)
self.PayIn = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/PayIn',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.FromString,
)
self.GetAccountValues = channel.unary_unary(
'/tinkoff.public.invest.api.contract.v1.UsersService/GetAccountValues',
request_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.SerializeToString,
response_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.FromString,
)
class UsersServiceServicer(object):
"""С помощью сервиса можно получить: <br/> 1.
список счетов пользователя; <br/> 2. маржинальные показатели по счeту.
"""
def GetAccounts(self, request, context):
"""GetAccounts — счета пользователя
Получить список счетов.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMarginAttributes(self, request, context):
"""GetMarginAttributes — маржинальные показатели по счeту
Метод позволяет получить маржинальные показатели и ликвидность по заданному счeту.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetUserTariff(self, request, context):
"""GetUserTariff — тариф пользователя
Получить информацию о текущих лимитах на подклчение, согласно текущему тарифу пользователя.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetInfo(self, request, context):
"""GetInfo — информация о пользователе
Получить информацию о пользователе: тариф, признак квалификации, пройденные тесты и др.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetBankAccounts(self, request, context):
"""GetBankAccounts — банковские счета пользователя
Получить список счетов пользователя, в том числе и банковских.
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def CurrencyTransfer(self, request, context):
"""CurrencyTransfer — перевод денежных средств между счетами
Перевести денежные средства между брокерскими счетами
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def PayIn(self, request, context):
"""PayIn — пополнение брокерского счета
Пополнить брокерский счёт с банковского
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetAccountValues(self, request, context):
"""GetAccountValues — дополнительные показатели счетов
Метод предназначен для получения дополнительных показателей счетов
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_UsersServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetAccounts': grpc.unary_unary_rpc_method_handler(
servicer.GetAccounts,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.SerializeToString,
),
'GetMarginAttributes': grpc.unary_unary_rpc_method_handler(
servicer.GetMarginAttributes,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.SerializeToString,
),
'GetUserTariff': grpc.unary_unary_rpc_method_handler(
servicer.GetUserTariff,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.SerializeToString,
),
'GetInfo': grpc.unary_unary_rpc_method_handler(
servicer.GetInfo,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.SerializeToString,
),
'GetBankAccounts': grpc.unary_unary_rpc_method_handler(
servicer.GetBankAccounts,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.SerializeToString,
),
'CurrencyTransfer': grpc.unary_unary_rpc_method_handler(
servicer.CurrencyTransfer,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.SerializeToString,
),
'PayIn': grpc.unary_unary_rpc_method_handler(
servicer.PayIn,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.SerializeToString,
),
'GetAccountValues': grpc.unary_unary_rpc_method_handler(
servicer.GetAccountValues,
request_deserializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.FromString,
response_serializer=t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'tinkoff.public.invest.api.contract.v1.UsersService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class UsersService(object):
"""С помощью сервиса можно получить: <br/> 1.
список счетов пользователя; <br/> 2. маржинальные показатели по счeту.
"""
@staticmethod
def GetAccounts(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccounts',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetMarginAttributes(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetMarginAttributes',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetMarginAttributesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetUserTariff(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetUserTariff',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetUserTariffResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetInfo(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetInfo',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetInfoResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetBankAccounts(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetBankAccounts',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetBankAccountsResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def CurrencyTransfer(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/CurrencyTransfer',
t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.CurrencyTransferResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def PayIn(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/PayIn',
t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.PayInResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def GetAccountValues(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/tinkoff.public.invest.api.contract.v1.UsersService/GetAccountValues',
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesRequest.SerializeToString,
t__tech_dot_invest_dot_grpc_dot_users__pb2.GetAccountValuesResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

View File

@@ -0,0 +1,120 @@
import logging
from collections import namedtuple
from contextvars import ContextVar
from typing import Any, Optional
from .constants import (
MESSAGE,
X_RATELIMIT_LIMIT,
X_RATELIMIT_REMAINING,
X_RATELIMIT_RESET,
X_TRACKING_ID,
)
__all__ = (
"get_current_tracking_id",
"get_tracking_id_from_call",
"get_tracking_id_from_coro",
"get_metadata_from_call",
"get_metadata_from_aio_error",
"log_request",
"log_error",
)
logger = logging.getLogger(__name__)
_TRACKING_ID: ContextVar[Optional[str]] = ContextVar("tracking_id", default=None)
Metadata = namedtuple(
"Metadata",
(
"tracking_id",
"ratelimit_limit",
"ratelimit_remaining",
"ratelimit_reset",
"message",
),
)
def get_current_tracking_id() -> Optional[str]:
return _TRACKING_ID.get() or None
def log_request(tracking_id: Optional[str], name: str) -> None:
_TRACKING_ID.set(tracking_id)
logger.info("%s %s", tracking_id, name)
def log_error(tracking_id: Optional[str], name: str, text: str) -> None:
_TRACKING_ID.set(tracking_id)
logger.error("%s %s %s", tracking_id, name, text)
def get_tracking_id_from_call(call: Any) -> Optional[str]:
metadata = call.initial_metadata() or call.trailing_metadata()
for item in metadata:
if item.key == X_TRACKING_ID:
return item.value
return None
async def get_tracking_id_from_coro(coro: Any) -> Optional[str]:
metadata = await coro.initial_metadata() or await coro.trailing_metadata()
for key, value in metadata:
if key == X_TRACKING_ID:
return value
return None
def get_metadata_from_call(call: Any) -> Optional[Metadata]:
metadata = call.initial_metadata() or call.trailing_metadata()
tracking_id = None
ratelimit_limit = None
ratelimit_remaining = None
ratelimit_reset = None
message = None
for item in metadata:
if item.key == X_TRACKING_ID:
tracking_id = item.value
elif item.key == X_RATELIMIT_LIMIT:
ratelimit_limit = item.value
elif item.key == X_RATELIMIT_REMAINING:
ratelimit_remaining = int(item.value)
elif item.key == X_RATELIMIT_RESET:
ratelimit_reset = int(item.value)
elif item.key == MESSAGE:
message = item.value
if not any(
(tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message)
):
return None
return Metadata(
tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message
)
def get_metadata_from_aio_error(err: Any) -> Optional[Metadata]:
metadata = err.initial_metadata() or err.trailing_metadata()
tracking_id = None
ratelimit_limit = None
ratelimit_remaining = None
ratelimit_reset = None
message = None
for key, value in metadata:
if key == X_TRACKING_ID:
tracking_id = value
elif key == X_RATELIMIT_LIMIT:
ratelimit_limit = value
elif key == X_RATELIMIT_REMAINING:
ratelimit_remaining = int(value)
elif key == X_RATELIMIT_RESET:
ratelimit_reset = int(value)
elif key == MESSAGE:
message = value
if not any(
(tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message)
):
return None
return Metadata(
tracking_id, ratelimit_limit, ratelimit_remaining, ratelimit_reset, message
)

View File

@@ -0,0 +1,77 @@
import asyncio
import threading
from asyncio import Queue
from typing import AsyncIterable, AsyncIterator, Awaitable
from t_tech.invest.market_data_stream.market_data_stream_interface import (
IMarketDataStreamManager,
)
from t_tech.invest.market_data_stream.stream_managers import (
CandlesStreamManager,
InfoStreamManager,
LastPriceStreamManager,
OrderBookStreamManager,
TradesStreamManager,
)
from t_tech.invest.schemas import MarketDataRequest, MarketDataResponse
class AsyncMarketDataStreamManager(IMarketDataStreamManager):
def __init__(
self,
market_data_stream: "MarketDataStreamService", # type: ignore # noqa: F821
):
self._market_data_stream_service = market_data_stream
self._market_data_stream: AsyncIterator[MarketDataResponse]
self._requests: Queue[MarketDataRequest] = Queue()
self._unsubscribe_event = threading.Event()
async def _get_request_generator(self) -> AsyncIterable[MarketDataRequest]:
while not self._unsubscribe_event.is_set() or not self._requests.empty():
try:
request = await asyncio.wait_for(self._requests.get(), timeout=1.0)
except asyncio.exceptions.TimeoutError:
pass
else:
yield request
self._requests.task_done()
@property
def candles(self) -> "CandlesStreamManager[AsyncMarketDataStreamManager]":
return CandlesStreamManager[AsyncMarketDataStreamManager](parent_manager=self)
@property
def order_book(self) -> "OrderBookStreamManager[AsyncMarketDataStreamManager]":
return OrderBookStreamManager[AsyncMarketDataStreamManager](parent_manager=self)
@property
def trades(self) -> "TradesStreamManager[AsyncMarketDataStreamManager]":
return TradesStreamManager[AsyncMarketDataStreamManager](parent_manager=self)
@property
def info(self) -> "InfoStreamManager[AsyncMarketDataStreamManager]":
return InfoStreamManager[AsyncMarketDataStreamManager](parent_manager=self)
@property
def last_price(self) -> "LastPriceStreamManager[AsyncMarketDataStreamManager]":
return LastPriceStreamManager[AsyncMarketDataStreamManager](parent_manager=self)
def subscribe(self, market_data_request: MarketDataRequest) -> None:
self._requests.put_nowait(market_data_request)
def unsubscribe(self, market_data_request: MarketDataRequest) -> None:
self._requests.put_nowait(market_data_request)
def stop(self) -> None:
self._unsubscribe_event.set()
def __aiter__(self) -> "AsyncMarketDataStreamManager":
self._unsubscribe_event.clear()
self._market_data_stream = self._market_data_stream_service.market_data_stream(
self._get_request_generator()
).__aiter__()
return self
def __anext__(self) -> Awaitable[MarketDataResponse]:
return self._market_data_stream.__anext__()

View File

@@ -0,0 +1,51 @@
import abc
from typing import Generic
from t_tech.invest.market_data_stream.stream_managers import (
CandlesStreamManager,
InfoStreamManager,
LastPriceStreamManager,
OrderBookStreamManager,
TradesStreamManager,
)
from t_tech.invest.market_data_stream.typevars import TMarketDataStreamManager
from t_tech.invest.schemas import MarketDataRequest
class IMarketDataStreamManager(abc.ABC, Generic[TMarketDataStreamManager]):
@property
@abc.abstractmethod
def candles(self) -> CandlesStreamManager[TMarketDataStreamManager]:
pass
@property
@abc.abstractmethod
def order_book(self) -> OrderBookStreamManager[TMarketDataStreamManager]:
pass
@property
@abc.abstractmethod
def trades(self) -> TradesStreamManager[TMarketDataStreamManager]:
pass
@property
@abc.abstractmethod
def info(self) -> InfoStreamManager[TMarketDataStreamManager]:
pass
@property
@abc.abstractmethod
def last_price(self) -> LastPriceStreamManager[TMarketDataStreamManager]:
pass
@abc.abstractmethod
def subscribe(self, market_data_request: MarketDataRequest) -> None:
pass
@abc.abstractmethod
def unsubscribe(self, market_data_request: MarketDataRequest) -> None:
pass
@abc.abstractmethod
def stop(self) -> None:
pass

View File

@@ -0,0 +1,78 @@
import queue
import threading
from typing import Iterable, Iterator
from t_tech.invest.market_data_stream.market_data_stream_interface import (
IMarketDataStreamManager,
)
from t_tech.invest.market_data_stream.stream_managers import (
CandlesStreamManager,
InfoStreamManager,
LastPriceStreamManager,
OrderBookStreamManager,
TradesStreamManager,
)
from t_tech.invest.schemas import MarketDataRequest, MarketDataResponse
class MarketDataStreamManager(IMarketDataStreamManager):
def __init__(
self,
market_data_stream_service: ( # type: ignore
"MarketDataStreamService" # noqa: F821
),
):
self._market_data_stream_service = market_data_stream_service
self._market_data_stream: Iterator[MarketDataResponse]
self._requests: queue.Queue[MarketDataRequest] = queue.Queue()
self._unsubscribe_event = threading.Event()
def _get_request_generator(self) -> Iterable[MarketDataRequest]:
while not self._unsubscribe_event.is_set() or not self._requests.empty():
try:
request = self._requests.get(timeout=1.0)
except queue.Empty:
pass
else:
yield request
@property
def candles(self) -> "CandlesStreamManager[MarketDataStreamManager]":
return CandlesStreamManager[MarketDataStreamManager](parent_manager=self)
@property
def order_book(self) -> "OrderBookStreamManager[MarketDataStreamManager]":
return OrderBookStreamManager[MarketDataStreamManager](parent_manager=self)
@property
def trades(self) -> "TradesStreamManager[MarketDataStreamManager]":
return TradesStreamManager[MarketDataStreamManager](parent_manager=self)
@property
def info(self) -> "InfoStreamManager[MarketDataStreamManager]":
return InfoStreamManager[MarketDataStreamManager](parent_manager=self)
@property
def last_price(self) -> "LastPriceStreamManager[MarketDataStreamManager]":
return LastPriceStreamManager[MarketDataStreamManager](parent_manager=self)
def subscribe(self, market_data_request: MarketDataRequest) -> None:
self._requests.put(market_data_request)
def unsubscribe(self, market_data_request: MarketDataRequest) -> None:
self._requests.put(market_data_request)
def stop(self) -> None:
self._unsubscribe_event.set()
def __iter__(self) -> "MarketDataStreamManager":
self._unsubscribe_event.clear()
self._market_data_stream = iter(
self._market_data_stream_service.market_data_stream(
self._get_request_generator()
)
)
return self
def __next__(self) -> MarketDataResponse:
return next(self._market_data_stream)

View File

@@ -0,0 +1,157 @@
import abc
from typing import Generic, List, TypeVar
from t_tech.invest.schemas import (
CandleInstrument,
InfoInstrument,
LastPriceInstrument,
MarketDataRequest,
OrderBookInstrument,
SubscribeCandlesRequest,
SubscribeInfoRequest,
SubscribeLastPriceRequest,
SubscribeOrderBookRequest,
SubscribeTradesRequest,
SubscriptionAction,
TradeInstrument,
)
TMarketDataStreamManager = TypeVar("TMarketDataStreamManager")
TInstrument = TypeVar("TInstrument")
class BaseStreamManager(abc.ABC, Generic[TInstrument, TMarketDataStreamManager]):
def __init__(self, parent_manager: TMarketDataStreamManager):
self._parent_manager = parent_manager
@abc.abstractmethod
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[TInstrument],
):
pass
def subscribe(self, instruments: List[TInstrument]) -> TMarketDataStreamManager:
self._parent_manager.subscribe( # type: ignore
self._get_request(
SubscriptionAction.SUBSCRIPTION_ACTION_SUBSCRIBE, instruments
)
)
return self._parent_manager
def unsubscribe(self, instruments: List[TInstrument]) -> TMarketDataStreamManager:
self._parent_manager.unsubscribe( # type: ignore
self._get_request(
SubscriptionAction.SUBSCRIPTION_ACTION_UNSUBSCRIBE, instruments
)
)
return self._parent_manager
class CandlesStreamManager(
BaseStreamManager[CandleInstrument, TMarketDataStreamManager]
):
def __init__(
self, parent_manager: TMarketDataStreamManager, waiting_close: bool = False
):
super().__init__(parent_manager)
self._parent_manager = parent_manager
self._waiting_close = waiting_close
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[CandleInstrument],
) -> MarketDataRequest:
return MarketDataRequest(
subscribe_candles_request=SubscribeCandlesRequest(
subscription_action=subscription_action,
instruments=instruments,
waiting_close=self._waiting_close,
)
)
def waiting_close(self, enabled: bool = True) -> "CandlesStreamManager":
"""Добавить флаг ожидания завершения интервала минутной свечи."""
return CandlesStreamManager(
parent_manager=self._parent_manager, waiting_close=enabled
)
class OrderBookStreamManager(
BaseStreamManager[OrderBookInstrument, TMarketDataStreamManager]
):
def __init__(self, parent_manager: TMarketDataStreamManager):
super().__init__(parent_manager)
self._parent_manager = parent_manager
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[OrderBookInstrument],
) -> MarketDataRequest:
return MarketDataRequest(
subscribe_order_book_request=SubscribeOrderBookRequest(
subscription_action=subscription_action,
instruments=instruments,
)
)
class TradesStreamManager(BaseStreamManager[TradeInstrument, TMarketDataStreamManager]):
def __init__(self, parent_manager: TMarketDataStreamManager):
super().__init__(parent_manager)
self._parent_manager = parent_manager
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[TradeInstrument],
) -> MarketDataRequest:
return MarketDataRequest(
subscribe_trades_request=SubscribeTradesRequest(
subscription_action=subscription_action,
instruments=instruments,
)
)
class InfoStreamManager(BaseStreamManager[InfoInstrument, TMarketDataStreamManager]):
def __init__(self, parent_manager: TMarketDataStreamManager):
super().__init__(parent_manager)
self._parent_manager = parent_manager
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[InfoInstrument],
) -> MarketDataRequest:
return MarketDataRequest(
subscribe_info_request=SubscribeInfoRequest(
subscription_action=subscription_action,
instruments=instruments,
)
)
class LastPriceStreamManager(
BaseStreamManager[LastPriceInstrument, TMarketDataStreamManager]
):
def __init__(self, parent_manager: TMarketDataStreamManager):
super().__init__(parent_manager)
self._parent_manager = parent_manager
def _get_request(
self,
subscription_action: SubscriptionAction,
instruments: List[LastPriceInstrument],
) -> MarketDataRequest:
return MarketDataRequest(
subscribe_last_price_request=SubscribeLastPriceRequest(
subscription_action=subscription_action,
instruments=instruments,
)
)

View File

@@ -0,0 +1,4 @@
from typing import TypeVar
TMarketDataStreamManager = TypeVar("TMarketDataStreamManager")
TInstrument = TypeVar("TInstrument")

View File

@@ -0,0 +1,10 @@
from typing import List, Optional, Tuple
from .constants import APP_NAME
def get_metadata(token: str, app_name: Optional[str] = None) -> List[Tuple[str, str]]:
if not app_name:
app_name = APP_NAME
return [("authorization", f"Bearer {token}"), ("x-app-name", app_name)]

View File

@@ -0,0 +1,332 @@
import logging
from contextlib import contextmanager
from datetime import datetime, timedelta
from decimal import Decimal
from functools import cached_property
from typing import Any, Callable, Dict, Generator, List, Optional
from grpc import Channel
from pytest_freezegun import freeze_time
from t_tech.invest import (
Candle,
GetCandlesResponse,
GetMarginAttributesResponse,
HistoricCandle,
MarketDataResponse,
MoneyValue,
OrderDirection,
OrderType,
PortfolioPosition,
PortfolioResponse,
PostOrderResponse,
Quotation,
)
from t_tech.invest.channels import create_channel
from t_tech.invest.services import Services
from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings
from t_tech.invest.typedefs import AccountId, ChannelArgumentType
from t_tech.invest.utils import (
candle_interval_to_subscription_interval,
decimal_to_quotation,
now,
quotation_to_decimal,
)
logger = logging.getLogger(__name__)
@contextmanager
def MockedClient(
token: str,
*,
settings: StrategySettings,
real_market_data_test_from: datetime,
real_market_data_test_start: datetime,
real_market_data_test_end: datetime,
balance: MoneyValue,
options: Optional[ChannelArgumentType] = None,
) -> Generator[Services, None, None]:
with create_channel(options=options) as channel:
with freeze_time(real_market_data_test_start) as frozen_datetime:
yield MockedServices(
channel=channel,
token=token,
settings=settings,
frozen_datetime=frozen_datetime,
real_market_data_test_from=real_market_data_test_from,
real_market_data_test_start=real_market_data_test_start,
real_market_data_test_end=real_market_data_test_end,
balance=balance,
)
@contextmanager
def MockedSandboxClient(
token: str,
*,
balance: MoneyValue,
options: Optional[ChannelArgumentType] = None,
) -> Generator[Services, None, None]:
with create_channel(options=options) as channel:
services = MockedSandboxServices(
channel=channel,
token=token,
balance=balance,
)
try:
yield services
except Exception:
del services
raise
class MockedServices(Services):
def __init__(
self,
channel: Channel,
token: str,
settings: StrategySettings,
frozen_datetime,
real_market_data_test_from: datetime,
real_market_data_test_start: datetime,
real_market_data_test_end: datetime,
balance: MoneyValue,
):
super().__init__(channel, token)
self._settings = settings
self._figi = settings.share_id
self._current_market_data: List[Candle] = []
self._portfolio_positions: Dict[str, PortfolioPosition] = {}
self._real_market_data_test_from = real_market_data_test_from
self._real_market_data_test_start = real_market_data_test_start
self._real_market_data_test_end = real_market_data_test_end
self._balance = balance
self._frozen_datetime = frozen_datetime
_ = self._real_market_data
self.market_data.get_candles = self._mocked_market_data_get_candles()
self.orders.post_order = self._mocked_orders_post_order()
self.operations.get_portfolio = self._mocked_operations_get_portfolio()
self.market_data_stream.market_data_stream = self._mocked_market_data_stream()
self.users.get_margin_attributes = self._mocked_users_get_margin_attributes()
def _mocked_orders_post_order(self) -> Callable[[Any], Any]:
def _post_order( # pylint: disable=too-many-locals
*,
figi: str = "",
quantity: int = 0,
price: Optional[Quotation] = None, # pylint: disable=unused-argument
direction: OrderDirection = OrderDirection(0),
account_id: str = "", # pylint: disable=unused-argument
order_type: OrderType = OrderType(0), # pylint: disable=unused-argument
order_id: str = "", # pylint: disable=unused-argument
):
last_candle = self._current_market_data[-1]
last_market_price = quotation_to_decimal(last_candle.close)
position = self._portfolio_positions.get(figi)
if position is None:
position = PortfolioPosition(
figi=figi,
quantity=decimal_to_quotation(Decimal(0)),
)
if direction == OrderDirection.ORDER_DIRECTION_SELL:
quantity_delta = -quantity
balance_delta = last_market_price * quantity
elif direction == OrderDirection.ORDER_DIRECTION_BUY:
quantity_delta = +quantity
balance_delta = -(last_market_price * quantity)
else:
raise AssertionError("Incorrect direction")
logger.warning("Operation: %s, %s", direction, balance_delta)
old_quantity = quotation_to_decimal(position.quantity)
new_quantity = decimal_to_quotation(old_quantity + quantity_delta)
position.quantity.units = new_quantity.units
position.quantity.nano = new_quantity.nano
old_balance = quotation_to_decimal(
Quotation(units=self._balance.units, nano=self._balance.nano)
)
new_balance = decimal_to_quotation(old_balance + balance_delta)
self._balance.units = new_balance.units
self._balance.nano = new_balance.nano
self._portfolio_positions[figi] = position
return _post_order # type: ignore
@cached_property
def _portfolio_response(self) -> PortfolioResponse:
return PortfolioResponse(
total_amount_shares=MoneyValue(currency="rub", units=28691, nano=300000000),
total_amount_bonds=MoneyValue(currency="rub", units=0, nano=0),
total_amount_etf=MoneyValue(currency="rub", units=0, nano=0),
total_amount_currencies=self._balance,
total_amount_futures=MoneyValue(currency="rub", units=0, nano=0),
expected_yield=Quotation(units=0, nano=-350000000),
positions=list(self._portfolio_positions.values()),
)
def _mocked_operations_get_portfolio(self) -> Callable[[Any], Any]:
def _get_portfolio(*args, **kwars): # pylint: disable=unused-argument
return self._portfolio_response
return _get_portfolio
def _mocked_market_data_stream(self) -> Callable[[Any], Any]:
self._frozen_datetime.move_to(self._real_market_data_test_start)
def _market_data_stream(*args, **kwargs): # pylint: disable=unused-argument
yield MarketDataResponse(candle=None) # type: ignore
interval = candle_interval_to_subscription_interval(
self._settings.candle_interval
)
for historic_candle in self._after_start_candles:
candle = Candle(
figi=self._figi,
interval=interval,
open=historic_candle.open,
high=historic_candle.high,
low=historic_candle.low,
close=historic_candle.close,
volume=historic_candle.volume,
time=historic_candle.time,
)
self._current_market_data.append(candle)
yield MarketDataResponse(candle=candle)
self._frozen_datetime.move_to(now() + timedelta(minutes=1))
return _market_data_stream
@cached_property
def _real_market_data(self) -> List[HistoricCandle]:
real_market_data = []
for candle in self.get_all_candles(
figi=self._figi,
from_=self._real_market_data_test_from,
to=self._real_market_data_test_end,
interval=self._settings.candle_interval,
):
real_market_data.append(candle)
return real_market_data
@cached_property
def _initial_candles(self) -> List[HistoricCandle]:
return [
candle
for candle in self._real_market_data
if candle.time < self._real_market_data_test_start
]
@cached_property
def _after_start_candles(self) -> List[HistoricCandle]:
return [
candle
for candle in self._real_market_data
if candle.time >= self._real_market_data_test_start
]
def _mocked_market_data_get_candles(self):
def _get_candles(*args, **kwargs): # pylint: disable=unused-argument
return GetCandlesResponse(candles=self._initial_candles)
return _get_candles
def _mocked_users_get_margin_attributes(self):
def _get_margin_attributes(*agrs, **kwargs): # pylint: disable=unused-argument
return GetMarginAttributesResponse(
liquid_portfolio=MoneyValue(currency="", units=0, nano=0),
starting_margin=MoneyValue(currency="", units=0, nano=0),
minimal_margin=MoneyValue(currency="", units=0, nano=0),
funds_sufficiency_level=Quotation(units=322, nano=0),
amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0),
)
return _get_margin_attributes
class MockedSandboxServices(Services):
def __init__(
self,
channel: Channel,
token: str,
balance: MoneyValue,
):
super().__init__(channel, token)
self.orders.post_order = self._mocked_orders_post_order()
self.operations.get_portfolio = self._mocked_operations_get_portfolio()
self.users.get_margin_attributes = self._mocked_users_get_margin_attributes()
self._account_id = self._open_account()
self._pay_in(balance)
def _pay_in(self, amount: MoneyValue):
logger.info("Pay in %s for %s", amount, self._account_id)
self.sandbox.sandbox_pay_in(account_id=self._account_id, amount=amount)
def _open_account(self) -> AccountId:
response = self.sandbox.open_sandbox_account()
self._account_id = response.account_id
logger.info("Opened sandbox account %s", self._account_id)
return self._account_id
def __del__(self):
self._close_account()
def _close_account(self) -> None:
logger.info("Closing sandbox account %s", self._account_id)
self.sandbox.close_sandbox_account(account_id=self._account_id)
def _mocked_orders_post_order(
self,
) -> Callable[[Any], PostOrderResponse]:
def _post_order(
*,
figi: str = "",
quantity: int = 0,
price: Optional[Quotation] = None,
direction: OrderDirection = OrderDirection(0),
_: str = "",
order_type: OrderType = OrderType(0),
order_id: str = "",
) -> PostOrderResponse:
return self.sandbox.post_sandbox_order(
figi=figi,
quantity=quantity,
price=price,
direction=direction,
account_id=self._account_id,
order_type=order_type,
order_id=order_id,
)
return _post_order # type: ignore
def _mocked_operations_get_portfolio(self) -> Callable[[Any], Any]:
def _get_sandbox_portfolio(
*, account_id: str = "" # pylint: disable=unused-argument
) -> PortfolioResponse:
return self.sandbox.get_sandbox_portfolio(account_id=self._account_id)
return _get_sandbox_portfolio # type: ignore
def _mocked_users_get_margin_attributes(self) -> Callable[[Any], PortfolioResponse]:
def _get_margin_attributes(*agrs, **kwargs): # pylint: disable=unused-argument
return GetMarginAttributesResponse(
liquid_portfolio=MoneyValue(currency="", units=0, nano=0),
starting_margin=MoneyValue(currency="", units=0, nano=0),
minimal_margin=MoneyValue(currency="", units=0, nano=0),
funds_sufficiency_level=Quotation(units=322, nano=0),
amount_of_missing_funds=MoneyValue(currency="", units=0, nano=0),
)
return _get_margin_attributes

View File

@@ -0,0 +1,21 @@
from t_tech.invest import AsyncClient
from t_tech.invest.retrying.aio.grpc_interceptor import AsyncRetryClientInterceptor
from t_tech.invest.retrying.aio.retry_manager import AsyncRetryManager
from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol
class AsyncRetryingClient(AsyncClient):
def __init__(
self,
token: str,
settings: RetryClientSettingsProtocol,
**kwargs,
):
self._retry_manager = AsyncRetryManager(settings=settings)
self._retry_interceptor = AsyncRetryClientInterceptor(
retry_manager=self._retry_manager
)
interceptors = kwargs.get("interceptors", [])
interceptors.append(self._retry_interceptor)
kwargs["interceptors"] = interceptors
super().__init__(token, **kwargs)

View File

@@ -0,0 +1,21 @@
import grpc
from t_tech.invest.retrying.aio.retry_manager import AsyncRetryManager
class AsyncRetryClientInterceptor(grpc.aio.UnaryUnaryClientInterceptor):
def __init__(
self, retry_manager: AsyncRetryManager
): # pylint: disable=super-init-not-called
self._retry_manager = retry_manager
async def _intercept_with_retry(self, continuation, client_call_details, request):
async def call():
return await continuation(client_call_details, request)
return await self._retry_manager.call_with_retries(call=call)
async def intercept_unary_unary(self, continuation, client_call_details, request):
return await self._intercept_with_retry(
continuation, client_call_details, request
)

View File

@@ -0,0 +1,35 @@
import asyncio
import logging
from typing import Any
from grpc.aio import AioRpcError
from t_tech.invest.logging import get_metadata_from_aio_error
from t_tech.invest.retrying.base_retry_manager import BaseRetryManager
logger = logging.getLogger(__name__)
class AsyncRetryManager(BaseRetryManager):
async def call_with_retries(self, call: Any):
retries_left = self.get_initial_retries()
while retries_left > 0:
logger.debug("Trying to call")
response = await call()
try:
await response
logger.debug("Call succeeded")
return response
except AioRpcError as exception:
retries_left -= 1
logger.debug("Retries left = %s", retries_left)
metadata = get_metadata_from_aio_error(exception)
seconds_to_sleep = self.extract_seconds_to_sleep(metadata)
await self._sleep(seconds_to_sleep)
logger.debug("RetryManager exhausted, no retries left")
return response
async def _sleep(self, seconds_to_sleep):
await asyncio.sleep(seconds_to_sleep)

View File

@@ -0,0 +1,25 @@
import logging
from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol
logger = logging.getLogger(__name__)
class BaseRetryManager:
def __init__(self, settings: RetryClientSettingsProtocol):
self._settings = settings
def get_initial_retries(self):
retries_left = self._settings.max_retry_attempt
if not self._settings.use_retry:
retries_left = 0
logger.debug("Retrying disabled")
retries_left += 1
return retries_left
@staticmethod
def extract_seconds_to_sleep(metadata) -> int:
logger.debug("Received metadata %s", metadata)
seconds_to_sleep = metadata.ratelimit_reset
logger.debug("Sleeping for %s seconds", seconds_to_sleep)
return seconds_to_sleep

View File

@@ -0,0 +1,9 @@
import dataclasses
from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol
@dataclasses.dataclass()
class RetryClientSettings(RetryClientSettingsProtocol):
use_retry: bool = True
max_retry_attempt: int = 3

View File

@@ -0,0 +1,6 @@
from typing import Protocol
class RetryClientSettingsProtocol(Protocol):
use_retry: bool
max_retry_attempt: int

View File

@@ -0,0 +1,21 @@
from t_tech.invest import Client
from t_tech.invest.retrying.settings_protocol import RetryClientSettingsProtocol
from t_tech.invest.retrying.sync.grpc_interceptor import RetryClientInterceptor
from t_tech.invest.retrying.sync.retry_manager import RetryManager
class RetryingClient(Client):
def __init__(
self,
token: str,
settings: RetryClientSettingsProtocol,
**kwargs,
):
self._retry_manager = RetryManager(settings=settings)
self._retry_interceptor = RetryClientInterceptor(
retry_manager=self._retry_manager
)
interceptors = kwargs.get("interceptors", [])
interceptors.append(self._retry_interceptor)
kwargs["interceptors"] = interceptors
super().__init__(token, **kwargs)

View File

@@ -0,0 +1,19 @@
import grpc
from t_tech.invest.retrying.sync.retry_manager import RetryManager
class RetryClientInterceptor(grpc.UnaryUnaryClientInterceptor):
def __init__(
self, retry_manager: RetryManager
): # pylint: disable=super-init-not-called
self._retry_manager = retry_manager
def _intercept_with_retry(self, continuation, client_call_details, request):
def call():
return continuation(client_call_details, request)
return self._retry_manager.call_with_retries(call=call)
def intercept_unary_unary(self, continuation, client_call_details, request):
return self._intercept_with_retry(continuation, client_call_details, request)

View File

@@ -0,0 +1,31 @@
import logging
import time
from typing import Any
from t_tech.invest.logging import get_metadata_from_call
from t_tech.invest.retrying.base_retry_manager import BaseRetryManager
logger = logging.getLogger(__name__)
class RetryManager(BaseRetryManager):
def call_with_retries(self, call: Any):
retries_left = self.get_initial_retries()
while retries_left > 0:
logger.debug("Trying to call")
result = call()
logger.debug("Call succeeded")
exception = result.exception()
if not exception:
return result
retries_left -= 1
logger.debug("Retries left = %s", retries_left)
metadata = get_metadata_from_call(exception)
seconds_to_sleep = self.extract_seconds_to_sleep(metadata)
self._sleep(seconds_to_sleep)
logger.debug("RetryManager exhausted, no retries left")
return result
def _sleep(self, seconds_to_sleep):
time.sleep(seconds_to_sleep)

View File

@@ -0,0 +1,12 @@
from t_tech.invest import AsyncClient
from t_tech.invest.constants import INVEST_GRPC_API_SANDBOX
class AsyncSandboxClient(AsyncClient):
def __init__(
self,
token: str,
**kwargs,
):
kwargs["target"] = INVEST_GRPC_API_SANDBOX
super().__init__(token, **kwargs)

View File

@@ -0,0 +1,12 @@
from t_tech.invest import Client
from t_tech.invest.constants import INVEST_GRPC_API_SANDBOX
class SandboxClient(Client):
def __init__(
self,
token: str,
**kwargs,
):
kwargs["target"] = INVEST_GRPC_API_SANDBOX
super().__init__(token, **kwargs)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
import logging
from decimal import Decimal
from t_tech.invest import Quotation
from t_tech.invest.services import Services
from t_tech.invest.strategies.base.errors import (
InsufficientMarginalTradeFunds,
MarginalTradeIsNotActive,
)
from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings
from t_tech.invest.utils import quotation_to_decimal
logger = logging.getLogger(__name__)
class AccountManager:
def __init__(self, services: Services, strategy_settings: StrategySettings):
self._services = services
self._strategy_settings = strategy_settings
def get_current_balance(self) -> Decimal:
account_id = self._strategy_settings.account_id
portfolio_response = self._services.operations.get_portfolio(
account_id=account_id
)
balance = portfolio_response.total_amount_currencies
return quotation_to_decimal(Quotation(units=balance.units, nano=balance.nano))
def ensure_marginal_trade(self) -> None:
account_id = self._strategy_settings.account_id
try:
response = self._services.users.get_margin_attributes(account_id=account_id)
except Exception as e:
raise MarginalTradeIsNotActive() from e
value = quotation_to_decimal(response.funds_sufficiency_level)
if value <= 1:
raise InsufficientMarginalTradeFunds()
logger.info("Marginal trade is active")

View File

@@ -0,0 +1,38 @@
class StrategyError(Exception):
pass
class NotEnoughData(StrategyError):
pass
class MarginalTradeIsNotActive(StrategyError):
pass
class InsufficientMarginalTradeFunds(StrategyError):
pass
class CandleEventForDateNotFound(StrategyError):
pass
class UnknownSignal(StrategyError):
pass
class OldCandleObservingError(StrategyError):
pass
class MarketDataNotAvailableError(StrategyError):
pass
class StrategySupervisorError(Exception):
pass
class EventsWereNotSupervised(StrategySupervisorError):
pass

View File

@@ -0,0 +1,21 @@
from dataclasses import dataclass
from datetime import datetime
from t_tech.invest.strategies.base.models import CandleEvent
from t_tech.invest.strategies.base.signal import Signal
@dataclass
class StrategyEvent:
time: datetime
@dataclass
class DataEvent(StrategyEvent):
candle_event: CandleEvent
@dataclass
class SignalEvent(StrategyEvent):
signal: Signal
was_executed: bool

View File

@@ -0,0 +1,19 @@
from dataclasses import dataclass
from datetime import datetime
from decimal import Decimal
@dataclass(eq=False, repr=True)
class Candle:
open: Decimal
high: Decimal
low: Decimal
close: Decimal
@dataclass(eq=False, repr=True)
class CandleEvent:
candle: Candle
volume: int
time: datetime
is_complete: bool

View File

@@ -0,0 +1,48 @@
import enum
from dataclasses import dataclass, field
class SignalDirection(enum.Enum):
LONG = "LONG"
SHORT = "SHORT"
@dataclass
class Signal:
pass
@dataclass
class OrderSignal(Signal):
lots: int
direction: SignalDirection
@dataclass
class CloseSignal(OrderSignal):
pass
@dataclass
class OpenSignal(OrderSignal):
pass
@dataclass
class OpenLongMarketOrder(OpenSignal):
direction: SignalDirection = field(default=SignalDirection.LONG)
@dataclass
class CloseLongMarketOrder(CloseSignal):
direction: SignalDirection = field(default=SignalDirection.LONG)
@dataclass
class OpenShortMarketOrder(OpenSignal):
direction: SignalDirection = field(default=SignalDirection.SHORT)
@dataclass
class CloseShortMarketOrder(CloseSignal):
direction: SignalDirection = field(default=SignalDirection.SHORT)

View File

@@ -0,0 +1,55 @@
from t_tech.invest import OrderDirection, OrderType
from t_tech.invest.services import Services
from t_tech.invest.strategies.base.signal import (
CloseLongMarketOrder,
CloseShortMarketOrder,
OpenLongMarketOrder,
OpenShortMarketOrder,
)
from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings
class SignalExecutor:
def __init__(
self,
services: Services,
settings: StrategySettings,
):
self._services = services
self._settings = settings
def execute_open_long_market_order(self, signal: OpenLongMarketOrder) -> None:
self._services.orders.post_order(
figi=self._settings.share_id,
quantity=signal.lots,
direction=OrderDirection.ORDER_DIRECTION_BUY,
account_id=self._settings.account_id,
order_type=OrderType.ORDER_TYPE_MARKET,
)
def execute_close_long_market_order(self, signal: CloseLongMarketOrder) -> None:
self._services.orders.post_order(
figi=self._settings.share_id,
quantity=signal.lots,
direction=OrderDirection.ORDER_DIRECTION_SELL,
account_id=self._settings.account_id,
order_type=OrderType.ORDER_TYPE_MARKET,
)
def execute_open_short_market_order(self, signal: OpenShortMarketOrder) -> None:
self._services.orders.post_order(
figi=self._settings.share_id,
quantity=signal.lots,
direction=OrderDirection.ORDER_DIRECTION_SELL,
account_id=self._settings.account_id,
order_type=OrderType.ORDER_TYPE_MARKET,
)
def execute_close_short_market_order(self, signal: CloseShortMarketOrder) -> None:
self._services.orders.post_order(
figi=self._settings.share_id,
quantity=signal.lots,
direction=OrderDirection.ORDER_DIRECTION_BUY,
account_id=self._settings.account_id,
order_type=OrderType.ORDER_TYPE_MARKET,
)

View File

@@ -0,0 +1,15 @@
from typing import Iterable, Protocol
from t_tech.invest.strategies.base.models import CandleEvent
from t_tech.invest.strategies.base.signal import Signal
class InvestStrategy(Protocol):
def fit(self, candles: Iterable[CandleEvent]) -> None:
pass
def observe(self, candle: CandleEvent) -> None:
pass
def predict(self) -> Iterable[Signal]:
pass

View File

@@ -0,0 +1,19 @@
import dataclasses
from datetime import timedelta
from decimal import Decimal
from t_tech.invest import CandleInterval
from t_tech.invest.typedefs import AccountId, ShareId
from t_tech.invest.utils import candle_interval_to_timedelta
@dataclasses.dataclass
class StrategySettings:
share_id: ShareId
account_id: AccountId
max_transaction_price: Decimal
candle_interval: CandleInterval
@property
def candle_interval_timedelta(self) -> timedelta:
return candle_interval_to_timedelta(self.candle_interval)

View File

@@ -0,0 +1,29 @@
import abc
from typing import Iterable, Protocol, Type
from t_tech.invest.strategies.base.event import StrategyEvent
class IStrategySupervisor(Protocol):
def notify(self, event: StrategyEvent) -> None:
pass
def get_events(self) -> Iterable[StrategyEvent]:
pass
def get_events_of_type(self, cls: Type[StrategyEvent]) -> Iterable[StrategyEvent]:
pass
class StrategySupervisor(abc.ABC, IStrategySupervisor):
@abc.abstractmethod
def notify(self, event: StrategyEvent) -> None:
pass
@abc.abstractmethod
def get_events(self) -> Iterable[StrategyEvent]:
pass
@abc.abstractmethod
def get_events_of_type(self, cls: Type[StrategyEvent]) -> Iterable[StrategyEvent]:
pass

View File

@@ -0,0 +1,69 @@
import abc
import logging
from datetime import timedelta
from typing import Iterable
import t_tech
from t_tech.invest import HistoricCandle
from t_tech.invest.services import Services
from t_tech.invest.strategies.base.models import Candle, CandleEvent
from t_tech.invest.strategies.base.strategy_interface import InvestStrategy
from t_tech.invest.strategies.base.strategy_settings_base import StrategySettings
from t_tech.invest.strategies.base.trader_interface import ITrader
from t_tech.invest.utils import now, quotation_to_decimal
logger = logging.getLogger(__name__)
class Trader(ITrader, abc.ABC):
def __init__(
self,
strategy: InvestStrategy,
services: Services,
settings: StrategySettings,
):
self._strategy = strategy
self._services = services
self._settings = settings
@staticmethod
def _convert_historic_candles_into_candle_events(
historic_candles: Iterable[HistoricCandle],
) -> Iterable[CandleEvent]:
for candle in historic_candles:
yield CandleEvent(
candle=Candle(
open=quotation_to_decimal(candle.open),
close=quotation_to_decimal(candle.close),
high=quotation_to_decimal(candle.high),
low=quotation_to_decimal(candle.low),
),
volume=candle.volume,
time=candle.time,
is_complete=candle.is_complete,
)
def _load_candles(self, period: timedelta) -> Iterable[CandleEvent]:
logger.info("Loading candles for period %s from %s", period, now())
yield from self._convert_historic_candles_into_candle_events(
self._services.get_all_candles(
figi=self._settings.share_id,
from_=now() - period,
interval=self._settings.candle_interval,
)
)
@staticmethod
def _convert_candle(candle: t_tech.invest.schemas.Candle) -> CandleEvent:
return CandleEvent(
candle=Candle(
open=quotation_to_decimal(candle.open),
close=quotation_to_decimal(candle.close),
high=quotation_to_decimal(candle.high),
low=quotation_to_decimal(candle.low),
),
volume=candle.volume,
time=candle.time,
is_complete=False,
)

View File

@@ -0,0 +1,6 @@
from typing import Protocol
class ITrader(Protocol):
def trade(self):
pass

Some files were not shown because too many files have changed in this diff Show More