Path: blob/master/ invest-robot-contest_invest-bot-main/invest_api/services/accounts_service.py
7833 views
import logging12from tinkoff.invest import Client, AccessLevel, AccountType, AccountStatus34from configuration.settings import AccountSettings5from invest_api.invest_error_decorators import invest_error_logging, invest_api_retry67__all__ = ("AccountService")89logger = logging.getLogger(__name__)101112class AccountService:13"""14The class encapsulate tinkoff account api15"""16def __init__(self, token: str, app_name: str) -> None:17self.__token = token18self.__app_name = app_name1920@invest_api_retry()21@invest_error_logging22def trading_account_id(self, account_settings: AccountSettings) -> str:23"""24Method returns appropriate account id for trading:25Full rights, common type (avoid IIS etc), account is open and ready,26liquid_portfolio more that configured,27green margin status (liquid > starting_margin)28Account with high liquid_portfolio will be selected if more that one found29"""30result = None31max_liquid_portfolio = -13233with Client(self.__token, app_name=self.__app_name) as client:34logger.info("List of client accounts:")3536for account in client.users.get_accounts().accounts:37logger.info(f"Account settings: {account}")3839if account.access_level == AccessLevel.ACCOUNT_ACCESS_LEVEL_FULL_ACCESS \40and account.type == AccountType.ACCOUNT_TYPE_TINKOFF \41and account.status == AccountStatus.ACCOUNT_STATUS_OPEN:4243account_margin = client.users.get_margin_attributes(account_id=account.id)44logger.info(f"Account margin attributes: {account_margin}")4546if account_margin.liquid_portfolio.units >= account_settings.min_liquid_portfolio \47and account_margin.liquid_portfolio.units > account_margin.starting_margin.units:48logger.info(f"Account is ready for trading")4950if max_liquid_portfolio < account_margin.liquid_portfolio.units:51max_liquid_portfolio = account_margin.liquid_portfolio.units52result = account.id5354return result5556@invest_api_retry()57@invest_error_logging58def __verify(self) -> bool:59"""60Verification method. Just connect and read some settings.61"""62logger.info(f"Start client verification. App name: {self.__app_name}")6364with Client(self.__token, app_name=self.__app_name) as client:65accounts = client.users.get_accounts()6667logger.info("List of client accounts:")68for account in accounts.accounts:69logger.info(account)7071tariff = client.users.get_user_tariff()7273logger.info("Current unary limits:")74for unary_limit in tariff.unary_limits:75logger.info(f"Request per minutes: {unary_limit.limit_per_minute}")76logger.info("\t" + "\n\t".join(unary_limit.methods))7778logger.info("Current stream limits:")79for stream_limit in tariff.stream_limits:80logger.info(f"Connections {stream_limit.limit}:")81logger.info("\t" + "\n\t".join(stream_limit.streams))8283logger.info("Client information:")84logger.info(client.users.get_info())8586logger.info("Verification has been passed successfully.")8788return True8990def verify_token(self) -> bool:91"""92Tinkoff API token verification93:return: True - token is good, False - Try another one.94"""95try:96return self.__verify()97except Exception as ex:98logger.error(f"Verify error - {repr(ex)}")99return False100101102