python CTP 更换前置机重连

刚接触CTP开发,博主用的是VNPY的接口和simnow的仿真账户,用的是python开发。

有时会出现simnow的前置机中途宕机的情况,然后程序就崩溃了。一直在找更换前置机重连的方法,现在找到了,就是在一开始init()之前,同时注册很多个前置机,这样,init()之后,ctp会自己找一个最快的,宕机重连后,ctp会在我们之前注册的一系列前置机中逐个尝试重连。

以下是博主自己再封装的ctp类的登录方法,因为登录后起始要确认结算单,才可以下单,所以我也封在里面了。其中那段循环就是同时注册很多个前置机。

    def Login(self):
        i = 0
        stat = 1
        self.reqid = 0
        # 在C++环境中创建MdApi对象,传入参数是希望用来保存.con文件的地址,测试通过
        self.api.createFtdcTraderApi("")
        # 设置数据流重传方式,测试通过,私有通讯方式
        self.api.subscribePrivateTopic(2)
        self.api.subscribePublicTopic(2)
        # 注册前置机地址,测试通过
        for i in range(len(self.registFront)):
            self.api.registerFront(self.registFront[i])
        # 初始化api,连接前置机,测试通过
        self.api.init()
        sleep(1)
        # # 登陆,测试通过,如果如果心跳超时就不会是0而是8193,8193下会自动登录
        if self.api.onFrontDisconnectedCode == 0:
            loginReq = {}  # 创建一个空字典
            # loginReq['UserID'] = ''  # 参数作为字典键值的方式传入
            loginReq['UserID'] = self.userid
            # loginReq['Password'] = ''  # 键名和C++中的结构体成员名对应
            loginReq['Password'] = self.password
            # loginReq['BrokerID'] = '9999'
            loginReq['BrokerID'] = self.brokerid
            self.reqid = self.reqid + 1  # 请求数必须保持唯一性
            self.api.reqUserLogin(loginReq, self.reqid)
            sleep(1)
            if hasattr(self.api,'loginErrorID'):
                if self.api.loginErrorID == 0:
                    self.SettlementInfoConfirm()
        return stat

接下来的博主还不肯定,但是问过其他开发人员,基本是这样操作的:

断连后再登录新的前置机后,应该要重新登录才可以,也就是说,在回调函数onFrontConnected里面加入断连后重新登录的判断,是否断连可以从onFrontDistconnected函数里面返回的n判断。

以下是博主自己在回调函数里写的方法,大家可以拿来参考:

    def onFrontDisconnected(self,n):
        print(n)
        # n = 8193
        # 登出状态
        if self.logoutCode == 1:
            self.onFrontDisconnectedCode = 0
        else:
            self.onFrontDisconnectedCode = n

        # 如果不是手动退出,那么就先登出
        if self.onFrontDisconnectedCode != 0:
            self.errorLogOut()
        
    def errorLogOut(self):
        logoutReq = {}
        logoutReq['BrokerID'] = self.brokerID
        logoutReq['UserID'] = self.userID
        self.reqid = self.reqid + 1
        self.reqUserLogout(logoutReq,self.reqid)
        sleep(1)
    def onFrontConnected(self):
        """服务器连接"""

        if self.onFrontDisconnectedCode != 0:
            # 重新登录
            self.auotoLogin()
            print('relogin')
      
    def auotoLogin(self):
        loginReq = {}
        loginReq['UserID'] = self.userID
        loginReq['Password'] = self.password
        loginReq['BrokerID'] = self.brokerID
        self.reqid = self.reqid + 1
        self.reqUserLogin(loginReq,self.reqid)
        sleep(1)

其中的self.onFrontDisconnectedCode 是我自己封装的logout函数中赋值的,也就是自己主动登出的时候,不会再次重连。

    def logOut(self,userID,borkerID):
        logoutReq = {}
        logoutReq['BrokerID'] = borkerID
        logoutReq["UserID"] = userID
        self.reqid = self.reqid + 1
        # 传递登出状态
        self.api.logoutCode = 1
        #
        self.api.reqUserLogout(logoutReq, self.reqid)
        sleep(1)

我是从这个帖子里获得启发的:

http://www.oceantribe.org/xf/index.php?threads/28431/

不过还有一个宕机问题,就是8193错误,据说是心跳超时?反正这个方法无法解决8193的错误,只能解决4097的断连,有没有人知道CTP出现8193怎么办?

猜你喜欢

转载自blog.csdn.net/mooncrystal123/article/details/83269296
今日推荐