Path: blob/master/ invest-robot-contest_invest-bot-main/trading/trade_service.py
5927 views
import asyncio1import datetime2import logging34from blog.blogger import Blogger5from configuration.settings import AccountSettings, TradingSettings, BlogSettings, StrategySettings6from invest_api.services.accounts_service import AccountService7from invest_api.services.client_service import ClientService8from invest_api.services.instruments_service import InstrumentService9from invest_api.services.market_data_service import MarketDataService10from invest_api.services.operations_service import OperationService11from invest_api.services.orders_service import OrderService12from invest_api.services.market_data_stream_service import MarketDataStreamService13from trade_system.strategies.base_strategy import IStrategy14from trading.trader import Trader1516__all__ = ("TradeService")1718logger = logging.getLogger(__name__)192021class TradeService:22"""23Represent logic keep trading going24"""25def __init__(26self,27account_service: AccountService,28client_service: ClientService,29instrument_service: InstrumentService,30operation_service: OperationService,31order_service: OrderService,32stream_service: MarketDataStreamService,33market_data_service: MarketDataService,34blogger: Blogger,35account_settings: AccountSettings,36trading_settings: TradingSettings,37strategies: list[IStrategy]38) -> None:39self.__account_service = account_service40self.__client_service = client_service41self.__instrument_service = instrument_service42self.__operation_service = operation_service43self.__order_service = order_service44self.__stream_service = stream_service45self.__market_data_service = market_data_service46self.__blogger = blogger47self.__account_settings = account_settings48self.__trading_settings = trading_settings49self.__strategies = strategies5051async def worker(self) -> None:52try:53logger.info("Finding account for trading")54account_id = self.__account_service.trading_account_id(self.__account_settings)5556if not account_id:57logger.error("Account for trading hasn't been found")58return None5960logger.info(f"Account id: {account_id}")6162except Exception as ex:63logger.error(f"Start trading error: {repr(ex)}")64return None6566await self.__working_loop(account_id)6768async def __working_loop(self, account_id: str) -> None:69logger.info("Start every day trading")7071while True:72logger.info("Check trading schedule on today")7374try:75is_trading_day, start_time, end_time = \76self.__instrument_service.moex_today_trading_schedule()77# for tests purposes78#is_trading_day, start_time, end_time = \79# True, \80# datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) + datetime.timedelta(seconds=10), \81# datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) + datetime.timedelta(minutes=12)8283if is_trading_day and datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) <= end_time:84logger.info(f"Today is trading day. Trading will start after {start_time}")8586await TradeService.__sleep_to(87start_time + datetime.timedelta(seconds=self.__trading_settings.delay_start_after_open)88)8990logger.info(f"Trading day has been started")9192await Trader(93client_service=self.__client_service,94instrument_service=self.__instrument_service,95operation_service=self.__operation_service,96order_service=self.__order_service,97stream_service=self.__stream_service,98market_data_service=self.__market_data_service,99blogger=self.__blogger100).trade_day(101account_id,102self.__trading_settings,103self.__strategies,104end_time,105self.__account_settings.min_rub_on_account106)107108logger.info("Trading day has been completed")109else:110logger.info("Today is not trading day. Sleep on next morning")111except Exception as ex:112logger.error(f"Start trading today error: {repr(ex)}")113114logger.info("Sleep to next morning")115await TradeService.__sleep_to_next_morning()116117@staticmethod118async def __sleep_to_next_morning() -> None:119future = datetime.datetime.utcnow() + datetime.timedelta(days=1)120next_time = datetime.datetime(year=future.year, month=future.month, day=future.day,121hour=6, minute=0, tzinfo=datetime.timezone.utc)122123await TradeService.__sleep_to(next_time)124125@staticmethod126async def __sleep_to(next_time: datetime) -> None:127now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)128129logger.debug(f"Sleep from {now} to {next_time}")130total_seconds = (next_time - now).total_seconds()131132if total_seconds > 0:133await asyncio.sleep(total_seconds)134135136