Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_tinkoff-contest-python-main/src/service/config.py
5935 views
1
from typing import Optional
2
3
import tinkoff.invest
4
from tinkoff.invest import AccessLevel, AccountStatus, InstrumentIdType
5
from tinkoff.invest.async_services import AsyncServices
6
7
from src import settings
8
from src.containers.config import TraderConfig
9
from src.service.errors import ConfigError
10
11
12
async def prepare_trader_config(config: dict) -> TraderConfig:
13
ticker = config["ticker"]
14
class_code = config["class_code"]
15
16
async with tinkoff.invest.AsyncClient(
17
settings.INVEST_TOKEN, sandbox_token=settings.SANDBOX_TOKEN, app_name=settings.APP_NAME
18
) as services:
19
# get id of the user account
20
account_id = await _fetch_user_account_id(services, target_account_id=settings.ACCOUNT_ID)
21
22
# TODO: check schedule, buy, sell and api trade flags (MarketDataService.GetTradingStatus first)
23
# check that the instrument is currently available for trading
24
instrument_data = (
25
await services.instruments.get_instrument_by(
26
id_type=InstrumentIdType.INSTRUMENT_ID_TYPE_TICKER, id=ticker, class_code=class_code
27
)
28
).instrument
29
# schedule = await services.instruments.trading_schedules(
30
# from_=datetime.datetime.utcnow(),
31
# to=datetime.datetime.utcnow() + datetime.timedelta(days=5),
32
# exchange=instrument_data.exchange,
33
# )
34
35
instrument_figi = instrument_data.figi
36
37
return TraderConfig(account_id=account_id, instrument_figi=instrument_figi, config=config)
38
39
40
async def _fetch_user_account_id(services: AsyncServices, *, target_account_id: Optional[str]) -> str:
41
accounts = (await services.users.get_accounts()).accounts
42
if target_account_id is not None:
43
try:
44
account = next(acc for acc in accounts if acc.id == target_account_id)
45
except StopIteration:
46
raise ConfigError("Specified account id is not found for the given token")
47
else:
48
if len(accounts) > 1:
49
raise ConfigError(
50
"Multiple accounts found for the token. "
51
"Please, specify the concrete one with the ACCOUNT_ID env variable."
52
)
53
account = accounts[0]
54
55
# verify rights on the account
56
if account.access_level != AccessLevel.ACCOUNT_ACCESS_LEVEL_FULL_ACCESS:
57
raise ConfigError("The access token does not have full access to the account")
58
if account.status != AccountStatus.ACCOUNT_STATUS_OPEN:
59
raise ConfigError("Can not operate on the account with incorrect status")
60
61
return account.id
62
63