def load_pre_reqs(self) -> None: # Initialize log feeds. self.logfeed_data = LogFeed(LogCategory.DATA) self.logfeed_data.log(LogLevel.ERROR, '. ...PROGRAM RESTARTED...') self.logfeed_trading = LogFeed(LogCategory.LIVE_TRADING) self.logfeed_trading.log(LogLevel.ERROR, '. ...PROGRAM RESTARTED...') self.logfeed_optimization = LogFeed(LogCategory.OPTIMIZATION) self.logfeed_optimization.log(LogLevel.ERROR, ' ...PROGRAM RESTARTED...') self.logfeed_visuals = LogFeed(LogCategory.VISUALS) self.logfeed_visuals.log(LogLevel.ERROR, '. ...PROGRAM RESTARTED...') self.logfeed_api = LogFeed(LogCategory.API) self.logfeed_api.log(LogLevel.ERROR, '. ...PROGRAM RESTARTED...') # Create time environment for live data collection and trading. live_time_env = TimeEnv(datetime.now()) # Create database managers but don't initialize connections. live_redis = RedisManager(self.logfeed_program, EnvType.LIVE) live_mongo = MongoManager(self.logfeed_program, EnvType.LIVE) # Initialize collector manager to access polygon.io. live_data_collector = PolygonDataCollector( logfeed_program=self.logfeed_program, logfeed_process=self.logfeed_data, time_env=live_time_env) # Initialize the live execution environment with program logs. self.live_env = ExecEnv(logfeed_program=self.logfeed_program, logfeed_process=self.logfeed_program) # Setup the live execution environment with live time & data variables. self.live_env.setup_first_time(env_type=EnvType.LIVE, time=live_time_env, data_collector=live_data_collector, mongo=live_mongo, redis=live_redis) # Set Alpaca credentials as environment variables so we don't have to pass them around. live_trading = True if Settings.get_endpoint( self.live_env) == BrokerEndpoint.LIVE else False os.environ['APCA_API_BASE_URL'] = 'https://api.alpaca.markets' \ if live_trading else 'https://paper-api.alpaca.markets' os.environ['APCA_API_KEY_ID'] = self.live_env.get_setting('alpaca.live_key_id') \ if live_trading else self.live_env.get_setting('alpaca.paper_key_id') os.environ['APCA_API_SECRET_KEY'] = self.live_env.get_setting('alpaca.live_secret_key') \ if live_trading else self.live_env.get_setting('alpaca.paper_secret_key') os.environ['POLYGON_KEY_ID'] = self.live_env.get_setting( 'alpaca.live_key_id')
def ready(self): """ Called when the Django backend starts. Starts a TC2Program. """ # Create a new TC2Program object. from tc2.TC2Program import TC2Program from tc2.log.LogFeed import LogFeed from tc2.log.LogFeed import LogCategory if shared.program is not None: print('DJANGO RE-BOOTED BUT PROGRAM IS ALREADY RUNNING') return shared.program = TC2Program(LogFeed(LogCategory.PROGRAM)) shared.program_starting.value = True # Start the program in a separate process. def start_logic(): # Set environment's timezone to New York so logs are consistent. os.environ['TZ'] = 'America/New_York' pytime.tzset() # Start the program. shared.program.start_program() shared.program_starting.value = False print('Started program with pid {}'.format(os.getpid())) # STARTUP TASKS (single-run): Run each task once in another thread. try: print('Running startup debug task(s) in another thread') shared.program.info_main( 'Running startup debug task(s) in another thread') task = DumpAIDataTask(shared.program) debug_thread_2 = Thread(target=task.run) debug_thread_2.start() except Exception: shared.program.error_main('Error running startup debug tasks:') shared.program.warn_main(traceback.format_exc()) program_process = Thread(target=start_logic) program_process.start()
def update(request): """Stops the program, pulls latest code from GitHub, and restarts.""" try: # Ignore the request if the program is already being updated if shared.program_starting.value: return Response('Program already starting/stopping/updating') else: shared.program_starting.value = True # Stop TC2Program if shared.program is not None: shared.program.shutdown() print('Program shutdown from endpoint: /api/update') time.sleep(0.2) # Remove old code files\ import shutil try: shutil.rmtree('/tc2', ignore_errors=True) shutil.rmtree('/tmp_update_cache', ignore_errors=True) os.remove('/config.properties') except OSError: pass # Fetch new code files from GitHub os.mkdir('/tmp_update_cache') os.system('git clone https://maxilie:[email protected]/maxilie/TC2 ' '/tmp_update_cache') # Copy over new code files copytree('/tmp_update_cache/backend/tc2', '/tc2') shutil.move('/tmp_update_cache/backend/config.properties', '/config.properties') # Reload the python modules import tc2 reload_package(tc2) # Create a new TC2Program object from tc2.TC2Program import TC2Program from tc2.log.LogFeed import LogFeed from tc2.log.LogFeed import LogCategory program: TC2Program = TC2Program(LogFeed(LogCategory.PROGRAM)) # Save the new program in the django app apps.program = program # Start the program in a separate thread so as not to block the django view def start_logic(): # Set environment's timezone to New York so logs are consistent os.environ['TZ'] = 'America/New_York' pytime.tzset() # Start the program program.start_program() shared.program_starting.value = False print('Started program with pid {}'.format(os.getpid())) init_thread = Thread(target=start_logic) init_thread.start() except Exception: api_util.log_stacktrace('updating the program', traceback.format_exc()) shared.program_starting.value = False return Response('Error updating the program!') return Response('Successfully updated and restarted the program')