Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_invest-bot-main/invest_api/services/accounts_service.py
7833 views
1
import logging
2
3
from tinkoff.invest import Client, AccessLevel, AccountType, AccountStatus
4
5
from configuration.settings import AccountSettings
6
from invest_api.invest_error_decorators import invest_error_logging, invest_api_retry
7
8
__all__ = ("AccountService")
9
10
logger = logging.getLogger(__name__)
11
12
13
class AccountService:
14
"""
15
The class encapsulate tinkoff account api
16
"""
17
def __init__(self, token: str, app_name: str) -> None:
18
self.__token = token
19
self.__app_name = app_name
20
21
@invest_api_retry()
22
@invest_error_logging
23
def trading_account_id(self, account_settings: AccountSettings) -> str:
24
"""
25
Method returns appropriate account id for trading:
26
Full rights, common type (avoid IIS etc), account is open and ready,
27
liquid_portfolio more that configured,
28
green margin status (liquid > starting_margin)
29
Account with high liquid_portfolio will be selected if more that one found
30
"""
31
result = None
32
max_liquid_portfolio = -1
33
34
with Client(self.__token, app_name=self.__app_name) as client:
35
logger.info("List of client accounts:")
36
37
for account in client.users.get_accounts().accounts:
38
logger.info(f"Account settings: {account}")
39
40
if account.access_level == AccessLevel.ACCOUNT_ACCESS_LEVEL_FULL_ACCESS \
41
and account.type == AccountType.ACCOUNT_TYPE_TINKOFF \
42
and account.status == AccountStatus.ACCOUNT_STATUS_OPEN:
43
44
account_margin = client.users.get_margin_attributes(account_id=account.id)
45
logger.info(f"Account margin attributes: {account_margin}")
46
47
if account_margin.liquid_portfolio.units >= account_settings.min_liquid_portfolio \
48
and account_margin.liquid_portfolio.units > account_margin.starting_margin.units:
49
logger.info(f"Account is ready for trading")
50
51
if max_liquid_portfolio < account_margin.liquid_portfolio.units:
52
max_liquid_portfolio = account_margin.liquid_portfolio.units
53
result = account.id
54
55
return result
56
57
@invest_api_retry()
58
@invest_error_logging
59
def __verify(self) -> bool:
60
"""
61
Verification method. Just connect and read some settings.
62
"""
63
logger.info(f"Start client verification. App name: {self.__app_name}")
64
65
with Client(self.__token, app_name=self.__app_name) as client:
66
accounts = client.users.get_accounts()
67
68
logger.info("List of client accounts:")
69
for account in accounts.accounts:
70
logger.info(account)
71
72
tariff = client.users.get_user_tariff()
73
74
logger.info("Current unary limits:")
75
for unary_limit in tariff.unary_limits:
76
logger.info(f"Request per minutes: {unary_limit.limit_per_minute}")
77
logger.info("\t" + "\n\t".join(unary_limit.methods))
78
79
logger.info("Current stream limits:")
80
for stream_limit in tariff.stream_limits:
81
logger.info(f"Connections {stream_limit.limit}:")
82
logger.info("\t" + "\n\t".join(stream_limit.streams))
83
84
logger.info("Client information:")
85
logger.info(client.users.get_info())
86
87
logger.info("Verification has been passed successfully.")
88
89
return True
90
91
def verify_token(self) -> bool:
92
"""
93
Tinkoff API token verification
94
:return: True - token is good, False - Try another one.
95
"""
96
try:
97
return self.__verify()
98
except Exception as ex:
99
logger.error(f"Verify error - {repr(ex)}")
100
return False
101
102