def __init__(self,frontAddress,brokerID,userID,password,timeout=10): """ 1.创建ctp转换器进程 2.创建和ctp通讯进程的通讯管道 3.测试ctp连接是否正常 参数: frontAddress ctp服务器地址 brokerID 代理商Id userID 用户Id password 密码 """ # 设置等待超时时间 self.timeoutMillisecond = 1000 * timeout # 创建md转换器 self.__mdConverter = MdConverter( frontAddress,brokerID,userID,password ) # 创建回调链管理器 self.__callbackManager = CallbackManager() # 创建工作线程 self.__mdWorker = MdWorker(self.__mdConverter,self.__callbackManager) if self.__mdWorker.echo('ready') != 'ready': self.__clean__() raise Exception(u'监听线程无法正常启动...') # 接口可用性测试如果失败阻止对象创建成功 if not self.__testChannel(): self.__clean__() raise Exception(u'无法建立ctp连接,请查看ctp转换器的日志')
class Md: """ Md通讯管道类,该类通过和CTPConverter的Md(行情)进程通讯,实线行情数据的传送 """ def __testChannel(self): """ 检查和ctp md 进程是否连通 这里假设了在没有订阅的情况下调用取消订阅也能成功 """ flag = [] def OnRspUnSubMarketData(**kwargs): flag.append(1) def getDefaultInstrumentID(months=1): return datetime.strftime(datetime.now() + relativedelta(months=months),"IF%y%m") bindId = self.bind(callback.OnRspUnSubMarketData,OnRspUnSubMarketData) try: data = [getDefaultInstrumentID()] error = 0 while True: result = self.UnSubscribeMarketData(data) if result[0] != 0: return False i = 0 while len(flag) == 0: sleep(0.01) i += 1 if i > 100: break if len(flag) > 0: return True error += 1 if error > 3: return False finally: self.unbind(bindId) def __init__(self,frontAddress,brokerID,userID,password,timeout=10): """ 1.创建ctp转换器进程 2.创建和ctp通讯进程的通讯管道 3.测试ctp连接是否正常 参数: frontAddress ctp服务器地址 brokerID 代理商Id userID 用户Id password 密码 """ # 设置等待超时时间 self.timeoutMillisecond = 1000 * timeout # 创建md转换器 self.__mdConverter = MdConverter( frontAddress,brokerID,userID,password ) # 创建回调链管理器 self.__callbackManager = CallbackManager() # 创建工作线程 self.__mdWorker = MdWorker(self.__mdConverter,self.__callbackManager) if self.__mdWorker.echo('ready') != 'ready': self.__clean__() raise Exception(u'监听线程无法正常启动...') # 接口可用性测试如果失败阻止对象创建成功 if not self.__testChannel(): self.__clean__() raise Exception(u'无法建立ctp连接,请查看ctp转换器的日志') def __clean__(self): """ 资源释放处理 """ attrName = '_%s__%s' % (self.__class__.__name__, 'mdWorker') if attrName in self.__dict__.keys(): self.__mdWorker.exit() del self.__mdWorker def __enter__(self): """ 让Md可以使用with语句 """ return self def __exit__(self, type, value, tb): """ 让Md可以使用with语句 """ pass def __del__(self): """ 对象移除过程,结束md转换器进程 """ self.__clean__() def bind(self,callbackName,funcToCall): """转调回调链管理器""" return self.__callbackManager.bind(callbackName,funcToCall) def unbind(self,bindId): """转调回调管理器""" return self.__callbackManager.unbind(bindId) def getConverterPid(self): """ 获取转换器的进程标识 """ return self.__mdConverter.getPid() def requestMethod(self,requestApiName,instrumentIDList): """ 通用请求方法,提供给SubscribeMarketData和UnSubscribeMarketData调用 """ timeout = self.timeoutMillisecond request = self.__mdConverter.request # 准备调用参数 reqInfo = packageReqInfo(requestApiName,instrumentIDList) # 发送消息 requestMessage = MdRequestMessage() requestMessage.header = 'REQUEST' requestMessage.apiName = requestApiName requestMessage.reqInfo = json.dumps(reqInfo) requestMessage.send(request) # 等待转换器响应 poller = zmq.Poller() poller.register(request, zmq.POLLIN) sockets = dict(poller.poll(timeout)) if not request in sockets: return ResponseTimeOut[:-1] # 读取转换器响应,并返回处理结果 responseMessage = MdResponseMessage() responseMessage.recv(request) errorInfo = json.loads(responseMessage.errorInfo) return errorInfo['ErrorID'], errorInfo['ErrorMsg'] def SubscribeMarketData(self,instrumentIDList): """ 订阅行情 """ requestApiName = 'SubscribeMarketData' return self.requestMethod(requestApiName,instrumentIDList) def UnSubscribeMarketData(self,instrumentIDList): """ 取消行情订阅 """ requestApiName = 'UnSubscribeMarketData' return self.requestMethod(requestApiName,instrumentIDList)