def error(self, id, errCode, errString): global clientid global tws global connection_state global pacing global last_time global cooldowntime s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.debug(s) if errCode == ErrorCode.clientid_in_use: logging.info( "Client ID {} in use, reconnecting ...".format(clientid)) clientid += 1 tws = EPosixClientSocket(self) tws.eConnect("", 7496, clientid) elif errCode == ErrorCode.md_connection_ok: logging.info("IB[{}]: {}".format(errCode, errString)) api_started.set() # TODO: use a better string here! elif errCode == ErrorCode.historical_data_error and "Historical data request pacing violation" in errString: logging.info( "Historical data pacing violation: retrying last batch and start using pacing between data requests..." ) logging.info(errString) if not pacing: pacing = 10 dt = prev_last_time.strftime("%Y%m%d %H:%M:%S") logging.info("Cooling down for {} seconds...".format(cooldowntime)) sleep(cooldowntime) cooldowntime += 15 # sometimes we just need to cool down for a longer time tws.reqHistoricalData(0, contract, dt, duration, barsize, datatype, rth_only, 1) elif errCode == ErrorCode.historical_data_error and "invalid step" in errString: logging.info("IB[{}]: {}".format(errCode, errString)) historical_data_received.set() elif errCode == ErrorCode.historical_data_error and "HMDS query returned no data" in errString: logging.info("IB[{}]: {}".format(errCode, errString)) historical_data_received.set() elif (errCode == ErrorCode.historical_data_error and "Trader Workstation exited" in errString) or \ errCode == ErrorCode.cannot_connect_to_tws: logging.info("IB[{}]: {}".format(errCode, errString)) tws.exited = True historical_data_received.set() # requesting historical data from period too long time ago elif errCode == ErrorCode.error_validating_request and "Historical data queries on this contract requesting any data earlier than" in errString: dt = prev_last_time.strftime(dt_format) logging.info( "IB cannot provide data from period ending {}, it's too far back in the history." .format(dt)) historical_data_received.set() elif errCode == ErrorCode.error_validating_request: s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.fatal(s) historical_data_received.set() elif errCode == ErrorCode.connection_lost: # TODO: some logic to retry after connection has been momentarily lost, and eventually give up... logging.info("Connection lost, saving data end aborting...") if not output_file: sys.exit(ExitCode.error_can_continue) historical_data_received.set() elif errCode == ErrorCode.no_security_def_found: logging.info("IB[{}]: {}".format(errCode, errString)) if not output_file: sys.exit(ExitCode.error_can_continue) historical_data_received.set() else: s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.info(s)
def error(self, id, errCode, errString): global clientid global tws global connection_state global pacing global last_time global cooldowntime s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.debug(s) if errCode == ErrorCode.clientid_in_use: logging.info("Client ID {} in use, reconnecting ...".format(clientid)) clientid += 1 tws = EPosixClientSocket(self) tws.eConnect("", 7496, clientid) elif errCode == ErrorCode.md_connection_ok: logging.info("IB[{}]: {}".format(errCode, errString)) api_started.set() # TODO: use a better string here! elif errCode == ErrorCode.historical_data_error and "Historical data request pacing violation" in errString: logging.info("Historical data pacing violation: retrying last batch and start using pacing between data requests...") logging.info(errString) if not pacing: pacing = 10 dt = prev_last_time.strftime("%Y%m%d %H:%M:%S") logging.info("Cooling down for {} seconds...".format(cooldowntime)) sleep(cooldowntime) cooldowntime += 15 # sometimes we just need to cool down for a longer time tws.reqHistoricalData(0, contract, dt, duration, barsize, datatype, rth_only, 1) elif errCode == ErrorCode.historical_data_error and "invalid step" in errString: logging.info("IB[{}]: {}".format(errCode, errString)) historical_data_received.set() elif errCode == ErrorCode.historical_data_error and "HMDS query returned no data" in errString: logging.info("IB[{}]: {}".format(errCode, errString)) historical_data_received.set() elif (errCode == ErrorCode.historical_data_error and "Trader Workstation exited" in errString) or \ errCode == ErrorCode.cannot_connect_to_tws: logging.info("IB[{}]: {}".format(errCode, errString)) tws.exited = True historical_data_received.set() # requesting historical data from period too long time ago elif errCode == ErrorCode.error_validating_request and "Historical data queries on this contract requesting any data earlier than" in errString: dt = prev_last_time.strftime(dt_format) logging.info("IB cannot provide data from period ending {}, it's too far back in the history.".format(dt)) historical_data_received.set() elif errCode == ErrorCode.error_validating_request: s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.fatal(s) historical_data_received.set() elif errCode == ErrorCode.connection_lost: # TODO: some logic to retry after connection has been momentarily lost, and eventually give up... logging.info("Connection lost, saving data end aborting...") if not output_file: sys.exit(ExitCode.error_can_continue) historical_data_received.set() elif errCode == ErrorCode.no_security_def_found: logging.info("IB[{}]: {}".format(errCode, errString)) if not output_file: sys.exit(ExitCode.error_can_continue) historical_data_received.set() else: s = "IB[{}]: {}".format(errCode, errString) if id > -1: s += " (ID: {})".format(id) logging.info(s)
'1 day': '1 Y', '1W': '1 Y', '1M': '1 Y' } if args.d: duration = args.d else: duration = max_duration[barsize] # need to get extra info from tws in order to proceed callbacks = MyCallbacks() tws = EPosixClientSocket(callbacks) tws.exited = False # used to show whether TWS has suddenly exited # generate clientid based on time of day so that we won't likely get duplicate clientids timenow = datetime.utcnow().time() clientid = timenow.hour * 60 * 60 + timenow.minute * 60 + timenow.second tws.eConnect("", 7496, clientid) api_started.wait(10) if tws.exited: sys.exit(2) logging.info("API functional, getting started...") logging.info("Requesting contract details...")