Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_invest-bot-main/trading/trade_service.py
5927 views
1
import asyncio
2
import datetime
3
import logging
4
5
from blog.blogger import Blogger
6
from configuration.settings import AccountSettings, TradingSettings, BlogSettings, StrategySettings
7
from invest_api.services.accounts_service import AccountService
8
from invest_api.services.client_service import ClientService
9
from invest_api.services.instruments_service import InstrumentService
10
from invest_api.services.market_data_service import MarketDataService
11
from invest_api.services.operations_service import OperationService
12
from invest_api.services.orders_service import OrderService
13
from invest_api.services.market_data_stream_service import MarketDataStreamService
14
from trade_system.strategies.base_strategy import IStrategy
15
from trading.trader import Trader
16
17
__all__ = ("TradeService")
18
19
logger = logging.getLogger(__name__)
20
21
22
class TradeService:
23
"""
24
Represent logic keep trading going
25
"""
26
def __init__(
27
self,
28
account_service: AccountService,
29
client_service: ClientService,
30
instrument_service: InstrumentService,
31
operation_service: OperationService,
32
order_service: OrderService,
33
stream_service: MarketDataStreamService,
34
market_data_service: MarketDataService,
35
blogger: Blogger,
36
account_settings: AccountSettings,
37
trading_settings: TradingSettings,
38
strategies: list[IStrategy]
39
) -> None:
40
self.__account_service = account_service
41
self.__client_service = client_service
42
self.__instrument_service = instrument_service
43
self.__operation_service = operation_service
44
self.__order_service = order_service
45
self.__stream_service = stream_service
46
self.__market_data_service = market_data_service
47
self.__blogger = blogger
48
self.__account_settings = account_settings
49
self.__trading_settings = trading_settings
50
self.__strategies = strategies
51
52
async def worker(self) -> None:
53
try:
54
logger.info("Finding account for trading")
55
account_id = self.__account_service.trading_account_id(self.__account_settings)
56
57
if not account_id:
58
logger.error("Account for trading hasn't been found")
59
return None
60
61
logger.info(f"Account id: {account_id}")
62
63
except Exception as ex:
64
logger.error(f"Start trading error: {repr(ex)}")
65
return None
66
67
await self.__working_loop(account_id)
68
69
async def __working_loop(self, account_id: str) -> None:
70
logger.info("Start every day trading")
71
72
while True:
73
logger.info("Check trading schedule on today")
74
75
try:
76
is_trading_day, start_time, end_time = \
77
self.__instrument_service.moex_today_trading_schedule()
78
# for tests purposes
79
#is_trading_day, start_time, end_time = \
80
# True, \
81
# datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) + datetime.timedelta(seconds=10), \
82
# datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) + datetime.timedelta(minutes=12)
83
84
if is_trading_day and datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) <= end_time:
85
logger.info(f"Today is trading day. Trading will start after {start_time}")
86
87
await TradeService.__sleep_to(
88
start_time + datetime.timedelta(seconds=self.__trading_settings.delay_start_after_open)
89
)
90
91
logger.info(f"Trading day has been started")
92
93
await Trader(
94
client_service=self.__client_service,
95
instrument_service=self.__instrument_service,
96
operation_service=self.__operation_service,
97
order_service=self.__order_service,
98
stream_service=self.__stream_service,
99
market_data_service=self.__market_data_service,
100
blogger=self.__blogger
101
).trade_day(
102
account_id,
103
self.__trading_settings,
104
self.__strategies,
105
end_time,
106
self.__account_settings.min_rub_on_account
107
)
108
109
logger.info("Trading day has been completed")
110
else:
111
logger.info("Today is not trading day. Sleep on next morning")
112
except Exception as ex:
113
logger.error(f"Start trading today error: {repr(ex)}")
114
115
logger.info("Sleep to next morning")
116
await TradeService.__sleep_to_next_morning()
117
118
@staticmethod
119
async def __sleep_to_next_morning() -> None:
120
future = datetime.datetime.utcnow() + datetime.timedelta(days=1)
121
next_time = datetime.datetime(year=future.year, month=future.month, day=future.day,
122
hour=6, minute=0, tzinfo=datetime.timezone.utc)
123
124
await TradeService.__sleep_to(next_time)
125
126
@staticmethod
127
async def __sleep_to(next_time: datetime) -> None:
128
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
129
130
logger.debug(f"Sleep from {now} to {next_time}")
131
total_seconds = (next_time - now).total_seconds()
132
133
if total_seconds > 0:
134
await asyncio.sleep(total_seconds)
135
136