def connect(self, userID, password, brokerID, address): """初始化连接""" self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcMdApi(path) # 订阅主题 self.subscribeMarketDataTopic(100, 2) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if not self.loginStatus: self.login()
def connect(self, userID, password, brokerID, address, productInfo, authCode): """初始化连接""" self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 self.productInfo = productInfo self.authCode = authCode # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcQueryApi(path) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if not self.loginStatus: self.login()
def connect(self, userID, password, brokerID, address, authCode, userProductInfo): """初始化连接""" # print "%s.%s.%s" % (__name__, self.__class__.__name__, get_current_function_name()) self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 self.authCode = authCode # 验证码 self.userProductInfo = userProductInfo # 产品信息 # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcTraderApi(path) # 设置数据同步模式为推送从今日开始所有数据 self.subscribePrivateTopic(0) self.subscribePublicTopic(0) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if self.requireAuthentication and not self.authStatus: self.authenticate() elif not self.loginStatus: self.login()
def connect(self, userID, password, brokerID, address): """初始化连接""" self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcTraderApi(path) # 设置数据同步模式为推送从今日开始所有数据 self.subscribePrivateTopic(0) self.subscribePublicTopic(0) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if not self.loginStatus: self.login()
def connect(self, userID, password, brokerID, address, productInfo, authCode): """初始化连接""" self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 self.productInfo = productInfo self.authCode = authCode # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcTraderApi(path) # 设置数据同步模式为推送从今日开始所有数据 self.subscribePrivateTopic(0) self.subscribePublicTopic(0) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if not self.loginStatus: self.login()
def addFileHandler(self): """添加文件输出""" if not self.fileHandler: filename = 'vt.log' filepath = getTempPath(filename) self.fileHandler = logging.FileHandler(filepath) self.fileHandler.setLevel(self.level) self.fileHandler.setFormatter(self.formatter) self.logger.addHandler(self.fileHandler)
def addFileHandler(self): """添加文件输出""" if not self.fileHandler: filename = 'vt_' + datetime.now().strftime('%Y%m%d') + '.log' filepath = getTempPath(filename) self.fileHandler = logging.FileHandler(filepath) self.fileHandler.setLevel(self.level) self.fileHandler.setFormatter(self.formatter) self.logger.addHandler(self.fileHandler)
def __init__(self): super(SqliteMetricSender, self).__init__() filename = "ctaMetric.sqlite" filepath = getTempPath(filename) engine = create_engine('sqlite:///%s' % filepath) self.engine = engine self.ensure_table() Session = sessionmaker() Session.configure(bind=engine) self.session = Session()
def addFileHandler(self, filename=''): """添加文件输出""" if not self.fileHandler: if not filename: filename = 'vt_' + datetime.now().strftime('%Y%m%d') + '.log' filepath = getTempPath(filename) self.fileHandler = logging.FileHandler(filepath, mode='w', encoding='utf-8') self.fileHandler.setLevel(self.level) self.fileHandler.setFormatter(self.formatter) self.logger.addHandler(self.fileHandler)
def __init__(self): super(LogfileMetricSender, self).__init__() logger = logging.getLogger(__name__) filename = "ctaMetric.log" filepath = getTempPath(filename) self.hander = TimedRotatingFileHandler(filepath, when="d", backupCount=7) formater = logging.Formatter(fmt="%(asctime)s|%(message)s") self.hander.setFormatter(formater) logger.addHandler(self.hander) logger.setLevel(logging.INFO) logger.propagate = False self.logger = logger
def addFileHandler(self): """添加文件输出""" if not self.fileHandler: filename = 'vt_' + datetime.now().strftime('%Y%m%d') + '.log' filepath = getTempPath(filename) # self.fileHandler = logging.FileHandler(filepath) # 引擎原有的handler # 限制日志文件大小为20M,一天最多 400 MB self.fileHandler = logging.handlers.RotatingFileHandler( filepath, maxBytes=20971520, backupCount=20) self.fileHandler.setLevel(self.level) self.fileHandler.setFormatter(self.formatter) self.logger.addHandler(self.fileHandler)
def connect(self, userID, password, brokerID, address): """初始化连接""" # print "%s.%s.%s" % (__name__, self.__class__.__name__, get_current_function_name()) self.userID = userID # 账号 self.password = password # 密码 self.brokerID = brokerID # 经纪商代码 self.address = address # 服务器地址 # 如果尚未建立服务器连接,则进行连接 if not self.connectionStatus: # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 path = getTempPath(self.gatewayName + '_') self.createFtdcMdApi(path) # 注册服务器地址 self.registerFront(self.address) # 初始化连接,成功会调用onFrontConnected self.init() # 若已经连接但尚未登录,则进行登录 else: if not self.loginStatus: self.login()
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED] def __init__(self, eventEngine): """Constructor""" self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} self.accountDict = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 持仓细节相关 self.detailDict = {} # vtSymbol:PositionDetail self.tdPenaltyList = globalSetting['tdPenalty'] # 平今手续费惩罚的产品代码列表 # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() def registerEvent(self): """注册事件监听""" # print('-----------vtEngine.py registerEvent line393------------') self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) self.eventEngine.register(EVENT_POSITION, self.processPositionEvent) self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent) # # 下面是zls添加用于ib # self.eventEngine.register(EVENT_TICK, self.processContractEvent) def processAccountEvent(self, event): account = event.dict_['data'] self.accountDict[account.gatewayName] = account def processContractEvent(self, event): """处理合约事件""" # print('----------vtEngine processContractEvent line408 -----------') contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 def processOrderEvent(self, event): """处理委托事件""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in self.FINISHED_STATUS: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order # 更新到持仓细节中 detail = self.getPositionDetail(order.vtSymbol) detail.updateOrder(order) def processTradeEvent(self, event): """处理成交事件""" trade = event.dict_['data'] # 更新到持仓细节中 detail = self.getPositionDetail(trade.vtSymbol) detail.updateTrade(trade) def processPositionEvent(self, event): """处理持仓事件""" pos = event.dict_['data'] # 更新到持仓细节中 detail = self.getPositionDetail(pos.vtSymbol) detail.updatePosition(pos) def getContract(self, vtSymbol): """查询合约对象""" try: # print 'vtEngine.py line453 查询合约对象:', vtSymbol, len(self.contractDict), [contract.vtSymbol for contract in self.contractDict.values()] # 0 return self.contractDict[vtSymbol] except KeyError: return None def getAllContracts(self): """查询所有合约对象(返回列表)""" return self.contractDict.values() def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() def getOrder(self, vtOrderID): """查询委托""" try: return self.orderDict[vtOrderID] except KeyError: return None def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self.workingOrderDict.values() def getPositionDetail(self, vtSymbol): """查询持仓细节""" if vtSymbol in self.detailDict: detail = self.detailDict[vtSymbol] else: detail = PositionDetail(vtSymbol) self.detailDict[vtSymbol] = detail # 设置持仓细节的委托转换模式 contract = self.getContract(vtSymbol) if contract: detail.exchange = contract.exchange # 上期所合约 if contract.exchange == EXCHANGE_SHFE: detail.mode = detail.MODE_SHFE # 检查是否有平今惩罚 for productID in self.tdPenaltyList: if str(productID) in contract.symbol: detail.mode = detail.MODE_TDPENALTY return detail def updateOrderReq(self, req, vtOrderID): """委托请求更新""" vtSymbol = req.vtSymbol detail = self.getPositionDetail(vtSymbol) detail.updateOrderReq(req, vtOrderID) def convertOrderReq(self, req): """根据规则转换委托请求""" detail = self.detailDict.get(req.vtSymbol, None) if not detail: # print("ctaEngine 21") return [req] else: # print("ctaEngine 22") return detail.convertOrderReq(req)
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) # ---------------------------------------------------------------------- def __init__(self, mainEngine, eventEngine): """Constructor""" self.mainEngine = mainEngine self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} # 本地自定义的合约详细配置字典 self.custom_contract_setting = {} # 合约与自定义套利合约映射表 self.contract_spd_mapping = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() # 已订阅合约代码 self.subscribedSymbols = set() # ---------------------------------------------------------------------- def updateContract(self, event): """更新合约数据""" contract = event.dict_['data'] if contract.vtSymbol.endswith('99'): old_contract = self.contractDict.get(contract.vtSymbol, None) if old_contract is not None: contract.size = max(contract.size, old_contract.size) contract.longMarginRatio = max(contract.longMarginRatio, old_contract.longMarginRatio) contract.shortMarginRatio = max(contract.shortMarginRatio, old_contract.shortMarginRatio) self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 # ---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: if vtSymbol in self.contractDict.keys(): return self.contractDict[vtSymbol] return None except Exception as ex: print(str(ex), file=sys.stderr) return None # ---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return list(self.contractDict.values()) # ---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" self.mainEngine.writeLog(u'持久化合约数据') f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() # ---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" print(u'load contract data from:{}'.format(self.contractFilePath)) f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() c = Custom_Contract() self.custom_contract_setting = c.get_config() d = c.get_contracts() if len(d) > 0: print(u'更新本地定制合约') self.contractDict.update(d) # 将leg1,leg2合约对应的自定义spd合约映射 for spd_name in self.custom_contract_setting.keys(): setting = self.custom_contract_setting.get(spd_name) leg1_symbol = setting.get('leg1_symbol') leg2_symbol = setting.get('leg2_symbol') for symbol in [leg1_symbol, leg2_symbol]: spd_mapping_list = self.contract_spd_mapping.get(symbol, []) # 更新映射 if spd_name not in spd_mapping_list: spd_mapping_list.append(spd_name) self.contract_spd_mapping.update( {symbol: spd_mapping_list}) # ---------------------------------------------------------------------- def updateOrder(self, event): """更新委托数据""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in [ STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED ]: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order def check_self_trade_risk(self, vtSymbol, direction, price, gatewayName): """ 检查自成交 :param vtSymbol: :param direction: :param price: :return:True;有风险;False:无风险 """ if len(self.workingOrderDict) == 0: return False try: if direction == DIRECTION_LONG: for order in list(self.workingOrderDict.values()): if order.vtSymbol == vtSymbol and order.direction == DIRECTION_SHORT and order.gatewayName == gatewayName and order.price <= price: self.mainEngine.writeNotification( u'存在反向委托单:id:{},{},gw:{},order.price:{}<{},有自成交风险'. format(order.vtOrderID, order.direction, order.gatewayName, order.price, price)) return True elif direction == DIRECTION_SHORT: for order in list(self.workingOrderDict.values()): if order.vtSymbol == vtSymbol and order.direction == DIRECTION_LONG and order.gatewayName == gatewayName and order.price >= price: self.mainEngine.writeNotification( u'存在反向委托单:id:{},{},gw:{},order.price:{}>{},有自成交风险'. format(order.vtOrderID, order.direction, order.gatewayName, order.price, price)) return True return False except Exception as ex: self.mainEngine.writeCritical( u'DataEngine check_self_trade_risk Exception:{} /{}'.format( str(ex), traceback.format_exc())) return False # ---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托单(报单)""" try: return self.orderDict[vtOrderID] except KeyError: return None # ---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return list(self.workingOrderDict.values()) # ---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.updateContract) self.eventEngine.register(EVENT_ORDER, self.updateOrder) self.eventEngine.register(EVENT_POSITION, self.updatePosition) def clearData(self): """清空数据""" self.orderDict = {} self.workingOrderDict = {} self.subscribedSymbols.clear() def updatePosition(self, event): """更新持仓信息""" # 1、在获取更新持仓信息时,自动订阅这个symbol position = event.dict_['data'] symbol = position.symbol if symbol is None: return if len(symbol) == 0: return # 已存在,不做更新 if symbol in self.subscribedSymbols: return self.subscribedSymbols.add(symbol) gatewayName = position.gatewayName contract = self.mainEngine.getContract(symbol) if not contract: self.mainEngine.writeLog( u'vtEngine.updatePosition()找不到合约{0}信息'.format(symbol)) return # 订阅合约 req = VtSubscribeReq() req.symbol = symbol req.exchange = contract.exchange req.currency = '' req.productClass = '' self.mainEngine.subscribe(req, gatewayName) self.mainEngine.writeLog(u'自动订阅合约{0}'.format(symbol))
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) #---------------------------------------------------------------------- def __init__(self, eventEngine): """Constructor""" self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() #---------------------------------------------------------------------- def updateContract(self, event): """更新合约数据""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 #---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self.contractDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return self.contractDict.values() #---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() #---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() #---------------------------------------------------------------------- def updateOrder(self, event): """更新委托数据""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED]: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order #---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托""" try: return self.orderDict[vtOrderID] except KeyError: return None #---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self.workingOrderDict.values() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.updateContract) self.eventEngine.register(EVENT_ORDER, self.updateOrder)
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED] TIME_RECORD_ACCOUNT = time(15, 2) TIME_RECORD_ACCOUNT_END = time(15, 20) #---------------------------------------------------------------------- def __init__(self, eventEngine): """Constructor""" self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 持仓细节相关 self.detailDict = {} # vtSymbol:PositionDetail self.tdPenaltyList = globalSetting['tdPenalty'] # 平今手续费惩罚的产品代码列表 # 读取保存在硬盘的合约数据 self.loadContracts() self.orderResTime = None ##由于持仓查询有延迟,所以持仓查询必须在onorder ontrader 没有返回后的15分钟才有效 self.mysqlClient = None ##mysql引擎 self.accountIsRecord = False # 注册事件监听 self.registerEvent() def setMysqlClient(self, mysqlClient): self.mysqlClient = mysqlClient #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) self.eventEngine.register(EVENT_POSITION, self.processPositionEvent) self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent) def processAccountEvent(self, event): account = event.dict_['data'] ##下午3.05记录账号信息 nowTime = datetime.now().time() if nowTime > self.TIME_RECORD_ACCOUNT and nowTime < self.TIME_RECORD_ACCOUNT_END: if self.mysqlClient and self.accountIsRecord == False: self.accountIsRecord = True self.mysqlClient.dbInsert(SQL_TABLENAME_ACCOUNT, account) #---------------------------------------------------------------------- def processContractEvent(self, event): """处理合约事件""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 #---------------------------------------------------------------------- def processOrderEvent(self, event): """处理委托事件""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in self.FINISHED_STATUS: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order # 更新到持仓细节中 detail = self.getPositionDetail(order.vtSymbol) detail.updateOrder(order) #---------------------------------------------------------------------- def processTradeEvent(self, event): """处理成交事件""" self.orderResTime = datetime.now() trade = event.dict_['data'] # 更新到持仓细节中 detail = self.getPositionDetail(trade.vtSymbol) detail.updateTrade(trade) #---------------------------------------------------------------------- def processPositionEvent(self, event): """处理持仓事件""" if self.orderResTime: now = datetime.now() last_time = self.orderResTime + timedelta(seconds=15) if last_time > now: ##1分钟内不更新持仓, 用trader更新 return pos = event.dict_['data'] #print(pos) # 更新到持仓细节中 detail = self.getPositionDetail(pos.vtSymbol) detail.updatePosition(pos) #---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self.contractDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return self.contractDict.values() #---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() #---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() #---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托""" try: return self.orderDict[vtOrderID] except KeyError: return None #---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self.workingOrderDict.values() def getAllPositionDetail(self): return self.detailDict #---------------------------------------------------------------------- def getPositionDetail(self, vtSymbol): """查询持仓细节""" if vtSymbol in self.detailDict: detail = self.detailDict[vtSymbol] else: contract = self.getContract(vtSymbol) detail = PositionDetail(vtSymbol, contract) if not contract: ##contract为空的时候不加入detailDict return detail self.detailDict[vtSymbol] = detail # 设置持仓细节的委托转换模式 #contract = self.getContract(vtSymbol) if contract: detail.exchange = contract.exchange # 上期所合约 if contract.exchange == EXCHANGE_SHFE: detail.mode = detail.MODE_SHFE # 检查是否有平今惩罚 for productID in self.tdPenaltyList: if str(productID) in contract.symbol: detail.mode = detail.MODE_TDPENALTY return detail #---------------------------------------------------------------------- def updateOrderReq(self, req, vtOrderID): """委托请求更新""" vtSymbol = req.vtSymbol detail = self.getPositionDetail(vtSymbol) detail.updateOrderReq(req, vtOrderID) #---------------------------------------------------------------------- def convertOrderReq(self, req): """根据规则转换委托请求""" detail = self.detailDict.get(req.vtSymbol, None) if not detail: return [req] else: return detail.convertOrderReq(req)
class TcManager(QtWidgets.QWidget): """""" REQ_ADDRESS = 'tcp://localhost:2015' SUB_ADDRESS = 'tcp://localhost:2018' REP_ADDRESS = 'tcp://*:2015' PUB_ADDRESS = 'tcp://*:2018' COPY_RATIO = '1' INTERVAL = '1' settingFileName = 'TradeCopy.vt' settingFilePath = getTempPath(settingFileName) signal = QtCore.Signal(type(Event())) #---------------------------------------------------------------------- def __init__(self, tcEngine, eventEngine, parent=None): """Constructor""" super(TcManager, self).__init__(parent) self.tcEngine = tcEngine self.eventEngine = eventEngine self.initUi() self.loadSetting() self.registerEvent() self.tcEngine.writeLog(u'欢迎使用TradeCopy交易复制模块') #---------------------------------------------------------------------- def initUi(self): """""" self.setWindowTitle(u'交易复制') self.setMinimumWidth(700) self.setMinimumHeight(700) # 创建组件 self.lineReqAddress = QtWidgets.QLineEdit(self.REQ_ADDRESS) self.lineSubAddress= QtWidgets.QLineEdit(self.SUB_ADDRESS) self.lineRepAddress = QtWidgets.QLineEdit(self.REP_ADDRESS) self.linePubAddress = QtWidgets.QLineEdit(self.PUB_ADDRESS) validator = QtGui.QDoubleValidator() validator.setBottom(0) self.lineCopyRatio = QtWidgets.QLineEdit() self.lineCopyRatio.setValidator(validator) self.lineCopyRatio.setText(self.COPY_RATIO) validator2 = QtGui.QIntValidator() validator2.setBottom(1) self.lineInterval = QtWidgets.QLineEdit() self.lineInterval.setValidator(validator2) self.lineInterval.setText(self.INTERVAL) self.buttonProvider = QtWidgets.QPushButton(u'启动发布者') self.buttonProvider.clicked.connect(self.startProvider) self.buttonSubscriber = QtWidgets.QPushButton(u'启动订阅者') self.buttonSubscriber.clicked.connect(self.startSubscriber) self.buttonStopEngine = QtWidgets.QPushButton(u'停止') self.buttonStopEngine.clicked.connect(self.stopEngine) self.buttonStopEngine.setEnabled(False) self.buttonResetAddress = QtWidgets.QPushButton(u'重置地址') self.buttonResetAddress.clicked.connect(self.resetAddress) self.logMonitor = QtWidgets.QTextEdit() self.logMonitor.setReadOnly(True) self.widgetList = [ self.lineCopyRatio, self.lineInterval, self.linePubAddress, self.lineSubAddress, self.lineRepAddress, self.lineReqAddress, self.buttonProvider, self.buttonSubscriber, self.buttonResetAddress ] # 布局 QLabel = QtWidgets.QLabel grid = QtWidgets.QGridLayout() grid.addWidget(QLabel(u'响应地址'), 0, 0) grid.addWidget(self.lineRepAddress, 0, 1) grid.addWidget(QLabel(u'请求地址'), 0, 2) grid.addWidget(self.lineReqAddress, 0, 3) grid.addWidget(QLabel(u'发布地址'), 1, 0) grid.addWidget(self.linePubAddress, 1, 1) grid.addWidget(QLabel(u'订阅地址'), 1, 2) grid.addWidget(self.lineSubAddress, 1, 3) grid.addWidget(QLabel(u'发布间隔(秒)'), 2, 0) grid.addWidget(self.lineInterval, 2, 1) grid.addWidget(QLabel(u'复制比例(倍)'), 2, 2) grid.addWidget(self.lineCopyRatio, 2, 3) grid.addWidget(self.buttonProvider, 3, 0, 1, 2) grid.addWidget(self.buttonSubscriber, 3, 2, 1, 2) grid.addWidget(self.buttonStopEngine, 4, 0, 1, 2) grid.addWidget(self.buttonResetAddress, 4, 2, 1, 2) grid.addWidget(self.logMonitor, 5, 0, 1, 4) self.setLayout(grid) #---------------------------------------------------------------------- def saveSetting(self): """""" f = shelve.open(self.settingFilePath) f['repAddress'] = self.lineRepAddress.text() f['reqAddress'] = self.lineReqAddress.text() f['pubAddress'] = self.linePubAddress.text() f['subAddress'] = self.lineSubAddress.text() f['copyRatio'] = self.lineCopyRatio.text() f['interval'] = self.lineInterval.text() f.close() #---------------------------------------------------------------------- def loadSetting(self): """""" f = shelve.open(self.settingFilePath) if f: self.lineRepAddress.setText(f['repAddress']) self.lineReqAddress.setText(f['reqAddress']) self.linePubAddress.setText(f['pubAddress']) self.lineSubAddress.setText(f['subAddress']) self.lineCopyRatio.setText(f['copyRatio']) self.lineInterval.setText(f['interval']) f.close() #---------------------------------------------------------------------- def resetAddress(self): """""" self.lineReqAddress.setText(self.REQ_ADDRESS) self.lineRepAddress.setText(self.REP_ADDRESS) self.linePubAddress.setText(self.PUB_ADDRESS) self.lineSubAddress.setText(self.SUB_ADDRESS) #---------------------------------------------------------------------- def stopEngine(self): """""" self.tcEngine.stop() for widget in self.widgetList: widget.setEnabled(True) self.buttonStopEngine.setEnabled(False) #---------------------------------------------------------------------- def registerEvent(self): """""" self.signal.connect(self.processLogEvent) self.eventEngine.register(EVENT_TC_LOG, self.signal.emit) #---------------------------------------------------------------------- def processLogEvent(self, event): """""" log = event.dict_['data'] txt = '%s: %s' %(log.logTime, log.logContent) self.logMonitor.append(txt) #---------------------------------------------------------------------- def startProvider(self): """""" repAddress = str(self.lineRepAddress.text()) pubAddress = str(self.linePubAddress.text()) interval = int(self.lineInterval.text()) self.tcEngine.startProvider(repAddress, pubAddress, interval) for widget in self.widgetList: widget.setEnabled(False) self.buttonStopEngine.setEnabled(True) #---------------------------------------------------------------------- def startSubscriber(self): """""" reqAddress = str(self.lineReqAddress.text()) subAddress = str(self.lineSubAddress.text()) copyRatio = float(self.lineCopyRatio.text()) self.tcEngine.startSubscriber(reqAddress, subAddress, copyRatio) for widget in self.widgetList: widget.setEnabled(False) self.buttonStopEngine.setEnabled(True)
class OmEngine(object): """期权主引擎""" impvFileName = 'PricingImpv.vt' impvFilePath = getTempPath(impvFileName) #---------------------------------------------------------------------- def __init__(self, mainEngine, eventEngine): """Constructor""" self.mainEngine = mainEngine self.eventEngine = eventEngine # """持仓组合""" self.portfolio = None self.optionContractDict = {} # symbol:contract self.registerEvent() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) #---------------------------------------------------------------------- def processTickEvent(self, event): """行情事件""" tick = event.dict_['data'] self.portfolio.newTick(tick) #---------------------------------------------------------------------- def processTradeEvent(self, event): """成交事件""" trade = event.dict_['data'] self.portfolio.newTrade(trade) #---------------------------------------------------------------------- def processContractEvent(self, event): """合约事件""" contract = event.dict_['data'] if contract.symbol and contract.productClass == PRODUCT_OPTION: self.optionContractDict[contract.symbol] = contract #---------------------------------------------------------------------- def subscribeEvent(self, symbol): """订阅对应合约的事件""" contract = self.mainEngine.getContract(symbol) if not contract: self.writeLog(u'行情订阅失败,找不到合约:%s' % symbol) return vtSymbol = contract.vtSymbol # 订阅行情 req = VtSubscribeReq() req.symbol = contract.symbol req.exchange = contract.exchange gateway = self.mainEngine.getGateway(contract.gatewayName) if gateway.mdConnected: self.mainEngine.subscribe(req, contract.gatewayName) else: self.mainEngine.subscribe(req, 'SEC') self.mainEngine.subscribe(req, 'CSHSHLP') # 订阅事件 if req.symbol == '510050': #做这个处理是因为,中信接口没有行情接口,需要用其他的接口获取行情,但是有时候会出现vtSymbol对应不上的情况 self.eventEngine.register(EVENT_TICK + req.symbol, self.processTickEvent) vtSymbol = '510050.SSE' self.eventEngine.register(EVENT_TICK + vtSymbol, self.processTickEvent) self.eventEngine.register(EVENT_TRADE + vtSymbol, self.processTradeEvent) #---------------------------------------------------------------------- def initEngine(self, fileName): """初始化引擎""" if self.portfolio: return False f = file(fileName) setting = json.load(f) # 读取定价模型 model = MODEL_DICT.get(setting['model'], None) if not model: self.writeLog(u'找不到定价模型%s' % setting['model']) return # 创建标的对象 underlyingDict = OrderedDict() for underlyingSymbol in setting['underlying']: contract = self.mainEngine.getContract(underlyingSymbol) if not contract: self.writeLog(u'找不到标的物合约%s' % underlyingSymbol) continue detail = self.mainEngine.getPositionDetail(contract.vtSymbol) underlying = OmUnderlying(contract, detail) underlyingDict[underlyingSymbol] = underlying # 创建期权链对象并初始化 chainList = [] futureList = [] for d in setting['chain']: chainSymbol = d['chainSymbol'] futureSymbol = d['futureSymbol'] #查找对应的期货合约 futureContact = self.mainEngine.getContract(futureSymbol) if not futureContact: self.writeLog(u'找不到期货合约%s' % futureSymbol) return detail = self.mainEngine.getPositionDetail(futureContact.vtSymbol) future = OmUnderlying(futureContact, detail) futureList.append(future) # 利率 r = d['r'] # 锁定标的对象 underlying = underlyingDict.get(d['underlyingSymbol'], None) if not underlying: self.writeLog(u'%s期权链的标的合约%s尚未创建,请检查配置文件' % (chainSymbol, underlyingSymbol)) continue # 创建期权对象并初始化 callDict = {} putDict = {} for symbol, contract in self.optionContractDict.items(): if contract.underlyingSymbol == d['chainSymbol']: detail = self.mainEngine.getPositionDetail( contract.vtSymbol) option = OmOption(contract, detail, underlying, model, r) if contract.optionType is OPTION_CALL: if option.k in callDict: callDict[option.k + 0.0001] = option else: callDict[option.k] = option else: if option.k in putDict: putDict[option.k + 0.0001] = option else: putDict[option.k] = option # 期权排序 strikeList = callDict.keys() strikeList.sort() callList = [callDict[k] for k in strikeList] putList = [putDict[k] for k in strikeList] # 创建期权链 chain = OmChain(underlying, chainSymbol, callList, putList, future) chainList.append(chain) # 添加标的映射关系 underlying.addChain(chain) # 创建持仓组合对象并初始化 self.portfolio = OmPortfolio(self.mainEngine, self.eventEngine, setting['name'], model, underlyingDict.values(), chainList, futureList) # 载入波动率配置 self.loadImpvSetting() # 订阅行情和事件 for underlying in underlyingDict.values(): self.subscribeEvent(underlying.vtSymbol) for chain in chainList: self.subscribeEvent(chain.future.vtSymbol) for option in chain.optionDict.values(): self.subscribeEvent(option.vtSymbol) # 载入成功返回 return True #---------------------------------------------------------------------- def loadImpvSetting(self): """载入波动率配置""" f = shelve.open(self.impvFilePath) for chain in self.portfolio.chainDict.values(): for option in chain.optionDict.values(): option.pricingImpv = f.get(option.symbol, 0) f.close() #---------------------------------------------------------------------- def saveImpvSetting(self): """保存波动率配置""" if not self.portfolio: return f = shelve.open(self.impvFilePath) for chain in self.portfolio.chainDict.values(): for option in chain.optionDict.values(): f[option.symbol] = option.pricingImpv f.close() #---------------------------------------------------------------------- def stop(self): """关闭函数""" self.saveImpvSetting() #---------------------------------------------------------------------- def writeLog(self, content): """发出日志 """ log = VtLogData() log.logContent = content event = Event(EVENT_OM_LOG) event.dict_['data'] = log self.eventEngine.put(event)
class DataCache(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED] #---------------------------------------------------------------------- def getTick(self, vtSymbol): """查询行情对象""" try: return self._dickLatestTick[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self._dictLatestContract[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return self._dictLatestContract.values() #---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self._dictLatestContract f.close() #---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self._dictLatestContract[key] = value f.close() #---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托""" try: return self._dictLatestOrder[vtOrderID] except KeyError: return None #---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self._dictWorkingOrder.values() #---------------------------------------------------------------------- def getAllOrders(self): """获取所有委托""" return self._dictLatestOrder.values() #---------------------------------------------------------------------- def getAllTrades(self): """获取所有成交""" return self._dictTrade.values() #---------------------------------------------------------------------- def getAllPositions(self): """获取所有持仓""" return self._dictPositions.values() #---------------------------------------------------------------------- def getAllAccounts(self): """获取所有资金""" return self._dictAccounts.values() #---------------------------------------------------------------------- def getPositionDetail(self, vtSymbol): """查询持仓细节""" if vtSymbol in self._dictDetails: detail = self._dictDetails[vtSymbol] else: contract = self.getContract(vtSymbol) detail = PositionDetail(vtSymbol, contract) self._dictDetails[vtSymbol] = detail # 设置持仓细节的委托转换模式 contract = self.getContract(vtSymbol) if contract: detail.exchange = contract.exchange # 上期所合约 if contract.exchange == EXCHANGE_SHFE: detail.mode = detail.MODE_SHFE # 检查是否有平今惩罚 for productID in self._lstTdPenalty: if str(productID) in contract.symbol: detail.mode = detail.MODE_TDPENALTY return detail #---------------------------------------------------------------------- def getAllPositionDetails(self): """查询所有本地持仓缓存细节""" return self._dictDetails.values() #---------------------------------------------------------------------- def updateOrderReq(self, req, vtOrderID): """委托请求更新""" vtSymbol = req.vtSymbol detail = self.getPositionDetail(vtSymbol) detail.updateOrderReq(req, vtOrderID) #---------------------------------------------------------------------- def convertOrderReq(self, req): """根据规则转换委托请求""" detail = self._dictDetails.get(req.vtSymbol, None) if not detail: return [req] else: return detail.convertOrderReq(req) #---------------------------------------------------------------------- def getLog(self): """获取日志""" return self._lstLogs #---------------------------------------------------------------------- def getError(self): """获取错误""" return self._lstErrors
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED] #---------------------------------------------------------------------- def __init__(self, eventEngine): """Constructor""" self.eventEngine = eventEngine # 保存数据的字典和列表 self.tickDict = {} self.contractDict = {} self.orderDict = {} self.workingOrderDict = {} # 可撤销委托 self.tradeDict = {} self.accountDict = {} self.positionDict = {} self.logList = [] self.errorList = [] # 持仓细节相关 # self.detailDict = {} # vtSymbol:PositionDetail self.tdPenaltyList = globalSetting['tdPenalty'] # 平今手续费惩罚的产品代码列表 # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_TICK, self.processTickEvent) self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) self.eventEngine.register(EVENT_POSITION, self.processPositionEvent) self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent) self.eventEngine.register(EVENT_LOG, self.processLogEvent) self.eventEngine.register(EVENT_ERROR, self.processErrorEvent) #---------------------------------------------------------------------- def processTickEvent(self, event): """处理成交事件""" tick = event.dict_['data'] self.tickDict[tick.vtSymbol] = tick #---------------------------------------------------------------------- def processContractEvent(self, event): """处理合约事件""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 #---------------------------------------------------------------------- def processOrderEvent(self, event): """处理委托事件""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in self.FINISHED_STATUS: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order # 更新到持仓细节中 # detail = self.getPositionDetail(order.vtSymbol) # detail.updateOrder(order) #---------------------------------------------------------------------- def processTradeEvent(self, event): """处理成交事件""" trade = event.dict_['data'] self.tradeDict[trade.vtTradeID] = trade # 更新到持仓细节中 # detail = self.getPositionDetail(trade.vtSymbol) # detail.updateTrade(trade) #---------------------------------------------------------------------- def processPositionEvent(self, event): """处理持仓事件""" pos = event.dict_['data'] self.positionDict[pos.vtPositionName] = pos # 更新到持仓细节中 # detail = self.getPositionDetail(pos.vtSymbol) # detail.updatePosition(pos) #---------------------------------------------------------------------- def processAccountEvent(self, event): """处理账户事件""" account = event.dict_['data'] self.accountDict[account.vtAccountID] = account #---------------------------------------------------------------------- def processLogEvent(self, event): """处理日志事件""" log = event.dict_['data'] self.logList.append(log) #---------------------------------------------------------------------- def processErrorEvent(self, event): """处理错误事件""" error = event.dict_['data'] self.errorList.append(error) #---------------------------------------------------------------------- def getTick(self, vtSymbol): """查询行情对象""" try: return self.tickDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self.contractDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return self.contractDict.values() #---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() #---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() #---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托""" try: return self.orderDict[vtOrderID] except KeyError: return None #---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self.workingOrderDict.values() #---------------------------------------------------------------------- def getAllOrders(self): """获取所有委托""" return self.orderDict.values() #---------------------------------------------------------------------- def getAllTrades(self): """获取所有成交""" return self.tradeDict.values() #---------------------------------------------------------------------- def getAllPositions(self): """获取所有持仓""" return self.positionDict.values() #---------------------------------------------------------------------- def getAllAccounts(self): """获取所有资金""" return self.accountDict.values() # #---------------------------------------------------------------------- # def getPositionDetail(self, vtSymbol): # """查询持仓细节""" # if vtSymbol in self.detailDict: # detail = self.detailDict[vtSymbol] # else: # contract = self.getContract(vtSymbol) # detail = PositionDetail(vtSymbol, contract) # self.detailDict[vtSymbol] = detail # # 设置持仓细节的委托转换模式 # contract = self.getContract(vtSymbol) # if contract: # detail.exchange = contract.exchange # # 上期所合约 # if contract.exchange == EXCHANGE_SHFE: # detail.mode = detail.MODE_SHFE # # 检查是否有平今惩罚 # for productID in self.tdPenaltyList: # if str(productID) in contract.symbol: # detail.mode = detail.MODE_TDPENALTY # return detail #---------------------------------------------------------------------- # def getAllPositionDetails(self): # """查询所有本地持仓缓存细节""" # return self.detailDict.values() # #---------------------------------------------------------------------- # def updateOrderReq(self, req, vtOrderID): # """委托请求更新""" # vtSymbol = req.vtSymbol # detail = self.getPositionDetail(vtSymbol) # detail.updateOrderReq(req, vtOrderID) # #---------------------------------------------------------------------- # def convertOrderReq(self, req): # """根据规则转换委托请求""" # detail = self.detailDict.get(req.vtSymbol, None) # if not detail: # return [req] # else: # return detail.convertOrderReq(req) #---------------------------------------------------------------------- def getLog(self): """获取日志""" return self.logList #---------------------------------------------------------------------- def getError(self): """获取错误""" return self.errorList
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) # ---------------------------------------------------------------------- def __init__(self, mainEngine, eventEngine): """Constructor""" self.mainEngine = mainEngine self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() # 已订阅合约代码 self.subscribedSymbols = set() # ---------------------------------------------------------------------- def updateContract(self, event): """更新合约数据""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 # ---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self.contractDict[vtSymbol] except KeyError: return None # ---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return list(self.contractDict.values()) # ---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() # ---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" print(u'load contract data from:{}'.format(self.contractFilePath)) f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() # ---------------------------------------------------------------------- def updateOrder(self, event): """更新委托数据""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in [ STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED ]: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order # ---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托单(报单)""" try: return self.orderDict[vtOrderID] except KeyError: return None # ---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return list(self.workingOrderDict.values()) # ---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.updateContract) self.eventEngine.register(EVENT_ORDER, self.updateOrder) self.eventEngine.register(EVENT_POSITION, self.updatePosition) def clearData(self): """清空数据""" self.orderDict = {} self.workingOrderDict = {} self.subscribedSymbols.clear() def updatePosition(self, event): """更新持仓信息""" # 在获取更新持仓信息时,自动订阅这个symbol # 目的:1、 position = event.dict_['data'] symbol = position.symbol if symbol is None: return if len(symbol) == 0: return # 已存在,不做更新 if symbol in self.subscribedSymbols: return self.subscribedSymbols.add(symbol) gatewayName = position.gatewayName contract = self.mainEngine.getContract(symbol) if not contract: self.mainEngine.writeLog( u'vtEngine.updatePosition()找不到合约{0}信息'.format(symbol)) return # 订阅合约 req = VtSubscribeReq() req.symbol = symbol req.exchange = contract.exchange req.currency = '' req.productClass = '' self.mainEngine.subscribe(req, gatewayName) self.mainEngine.writeLog(u'自动订阅合约{0}'.format(symbol))
class StAlgoEngine(object): """价差算法交易引擎""" algoFileName = 'SpreadTradingAlgo.vt' algoFilePath = getTempPath(algoFileName) #---------------------------------------------------------------------- def __init__(self, dataEngine, mainEngine, eventEngine): """Constructor""" self.dataEngine = dataEngine self.mainEngine = mainEngine self.eventEngine = eventEngine self.algoDict = {} # spreadName:algo self.vtSymbolAlgoDict = {} # vtSymbol:algo self.registerEvent() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_SPREADTRADING_TICK, self.processSpreadTickEvent) self.eventEngine.register(EVENT_SPREADTRADING_POS, self.processSpreadPosEvent) self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) self.eventEngine.register(EVENT_TIMER, self.processTimerEvent) #---------------------------------------------------------------------- def processSpreadTickEvent(self, event): """处理价差行情事件""" spread = event.dict_['data'] # 若价差的买卖价均为0,则意味着尚未初始化,直接返回 if not spread.bidPrice and not spread.askPrice: return algo = self.algoDict.get(spread.name, None) if algo: algo.updateSpreadTick(spread) #---------------------------------------------------------------------- def processSpreadPosEvent(self, event): """处理价差持仓事件""" spread = event.dict_['data'] algo = self.algoDict.get(spread.name, None) if algo: algo.updateSpreadPos(spread) #---------------------------------------------------------------------- def processTradeEvent(self, event): """处理成交事件""" trade = event.dict_['data'] algo = self.vtSymbolAlgoDict.get(trade.vtSymbol, None) if algo: algo.updateTrade(trade) #---------------------------------------------------------------------- def processOrderEvent(self, event): """处理委托事件""" order = event.dict_['data'] algo = self.vtSymbolAlgoDict.get(order.vtSymbol, None) if algo: algo.updateOrder(order) #---------------------------------------------------------------------- def processTimerEvent(self, event): """""" for algo in self.algoDict.values(): algo.updateTimer() #---------------------------------------------------------------------- def sendOrder(self, vtSymbol, direction, offset, price, volume, payup=0): """发单""" contract = self.mainEngine.getContract(vtSymbol) if not contract: return '' req = VtOrderReq() req.symbol = contract.symbol req.exchange = contract.exchange req.vtSymbol = contract.vtSymbol req.direction = direction req.offset = offset req.volume = int(volume) req.priceType = PRICETYPE_LIMITPRICE if direction == DIRECTION_LONG: req.price = price + payup * contract.priceTick else: req.price = price - payup * contract.priceTick # 委托转换 reqList = self.mainEngine.convertOrderReq(req) vtOrderIDList = [] for req in reqList: vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) vtOrderIDList.append(vtOrderID) return vtOrderIDList #---------------------------------------------------------------------- def cancelOrder(self, vtOrderID): """撤单""" order = self.mainEngine.getOrder(vtOrderID) if not order: return req = VtCancelOrderReq() req.symbol = order.symbol req.exchange = order.exchange req.frontID = order.frontID req.sessionID = order.sessionID req.orderID = order.orderID self.mainEngine.cancelOrder(req, order.gatewayName) #---------------------------------------------------------------------- def buy(self, vtSymbol, price, volume, payup=0): """买入""" l = self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_OPEN, price, volume, payup) return l #---------------------------------------------------------------------- def sell(self, vtSymbol, price, volume, payup=0): """卖出""" l = self.sendOrder(vtSymbol, DIRECTION_SHORT, OFFSET_CLOSE, price, volume, payup) return l #---------------------------------------------------------------------- def short(self, vtSymbol, price, volume, payup=0): """卖空""" l = self.sendOrder(vtSymbol, DIRECTION_SHORT, OFFSET_OPEN, price, volume, payup) return l #---------------------------------------------------------------------- def cover(self, vtSymbol, price, volume, payup=0): """平空""" l = self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_CLOSE, price, volume, payup) return l #---------------------------------------------------------------------- def putAlgoEvent(self, algo): """发出算法状态更新事件""" event = Event(EVENT_SPREADTRADING_ALGO + algo.name) self.eventEngine.put(event) #---------------------------------------------------------------------- def writeLog(self, content): """输出日志""" log = VtLogData() log.logContent = content event = Event(EVENT_SPREADTRADING_ALGOLOG) event.dict_['data'] = log self.eventEngine.put(event) #---------------------------------------------------------------------- def saveSetting(self): """保存算法配置""" setting = {} for algo in self.algoDict.values(): setting[algo.spreadName] = algo.getAlgoParams() f = shelve.open(self.algoFilePath) f['setting'] = setting f.close() #---------------------------------------------------------------------- def loadSetting(self): """加载算法配置""" # 创建算法对象 l = self.dataEngine.getAllSpreads() for spread in l: algo = SniperAlgo(self, spread) self.algoDict[spread.name] = algo # 保存腿代码和算法对象的映射 for leg in spread.allLegs: self.vtSymbolAlgoDict[leg.vtSymbol] = algo # 加载配置 f = shelve.open(self.algoFilePath) setting = f.get('setting', None) f.close() if not setting: return for algo in self.algoDict.values(): if algo.spreadName in setting: d = setting[algo.spreadName] algo.setAlgoParams(d) #---------------------------------------------------------------------- def stopAll(self): """停止全部算法""" for algo in self.algoDict.values(): algo.stop() #---------------------------------------------------------------------- def startAlgo(self, spreadName): """启动算法""" algo = self.algoDict[spreadName] algoActive = algo.start() return algoActive #---------------------------------------------------------------------- def stopAlgo(self, spreadName): """停止算法""" algo = self.algoDict[spreadName] algoActive = algo.stop() return algoActive #---------------------------------------------------------------------- def getAllAlgoParams(self): """获取所有算法的参数""" return [algo.getAlgoParams() for algo in self.algoDict.values()] #---------------------------------------------------------------------- def setAlgoBuyPrice(self, spreadName, buyPrice): """设置算法买开价格""" algo = self.algoDict[spreadName] algo.setBuyPrice(buyPrice) #---------------------------------------------------------------------- def setAlgoSellPrice(self, spreadName, sellPrice): """设置算法卖平价格""" algo = self.algoDict[spreadName] algo.setSellPrice(sellPrice) #---------------------------------------------------------------------- def setAlgoShortPrice(self, spreadName, shortPrice): """设置算法卖开价格""" algo = self.algoDict[spreadName] algo.setShortPrice(shortPrice) #---------------------------------------------------------------------- def setAlgoCoverPrice(self, spreadName, coverPrice): """设置算法买平价格""" algo = self.algoDict[spreadName] algo.setCoverPrice(coverPrice) #---------------------------------------------------------------------- def setAlgoMode(self, spreadName, mode): """设置算法工作模式""" algo = self.algoDict[spreadName] algo.setMode(mode) #---------------------------------------------------------------------- def setAlgoMaxOrderSize(self, spreadName, maxOrderSize): """设置算法单笔委托限制""" algo = self.algoDict[spreadName] algo.setMaxOrderSize(maxOrderSize) #---------------------------------------------------------------------- def setAlgoMaxPosSize(self, spreadName, maxPosSize): """设置算法持仓限制""" algo = self.algoDict[spreadName] algo.setMaxPosSize(maxPosSize)
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' # 获取存放临时文件的路径 contractFilePath = getTempPath(contractFileName) # ---------------------------------------------------------------------- def __init__(self, mainEngine, eventEngine): """Constructor""" self.mainEngine = mainEngine self.eventEngine = eventEngine # 保存合约详细信息的字典 self.contractDict = {} # 保存委托数据的字典 self.orderDict = {} # 保存活动委托数据的字典(即可撤销) self.workingOrderDict = {} # 读取保存在硬盘的合约数据 self.loadContracts() # 注册事件监听 self.registerEvent() # 已订阅合约代码 self.subscribedSymbols = set() # ---------------------------------------------------------------------- def updateContract(self, event): """更新合约数据""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 # ---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: # 返回合约字典中的合约对象 return self.contractDict[vtSymbol] except KeyError: return None # ---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return list(self.contractDict.values()) # ---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" self.mainEngine.writeLog(u'持久化合约数据') f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() # ---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" print(u'load contract data from:{}'.format(self.contractFilePath)) f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() # ---------------------------------------------------------------------- def updateOrder(self, event): """更新委托数据""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in [ STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED ]: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order def check_self_trade_risk(self, vtSymbol, direction, price, gatewayName): """ 检查自成交 :param vtSymbol: :param direction: :param price: :return:True;有风险;False:无风险 """ if len(self.workingOrderDict) == 0: return False try: if direction == DIRECTION_LONG: for order in list(self.workingOrderDict.values()): if order.vtSymbol == vtSymbol and order.direction == DIRECTION_SHORT and order.gatewayName == gatewayName and order.price <= price: self.mainEngine.writeNotification( u'存在反向委托单:id:{},{},gw:{},order.price:{}<{},有自成交风险'. format(order.vtOrderID, order.direction, order.gatewayName, order.price, price)) return True elif direction == DIRECTION_SHORT: for order in list(self.workingOrderDict.values()): if order.vtSymbol == vtSymbol and order.direction == DIRECTION_LONG and order.gatewayName == gatewayName and order.price >= price: self.mainEngine.writeNotification( u'存在反向委托单:id:{},{},gw:{},order.price:{}>{},有自成交风险'. format(order.vtOrderID, order.direction, order.gatewayName, order.price, price)) return True return False except Exception as ex: self.mainEngine.writeCritical( u'DataEngine check_self_trade_risk Exception:{} /{}'.format( str(ex), traceback.format_exc())) return False # ---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托单(报单)""" try: return self.orderDict[vtOrderID] except KeyError: return None # ---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return list(self.workingOrderDict.values()) # ---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.updateContract) self.eventEngine.register(EVENT_ORDER, self.updateOrder) self.eventEngine.register(EVENT_POSITION, self.updatePosition) def clearData(self): """清空数据""" self.orderDict = {} self.workingOrderDict = {} self.subscribedSymbols.clear() def updatePosition(self, event): """更新持仓信息""" # 在获取更新持仓信息时,自动订阅这个symbol position = event.dict_['data'] symbol = position.symbol if symbol is None: return if len(symbol) == 0: return # 已存在,不做更新 if symbol in self.subscribedSymbols: return # 加入已订阅合约代码列表 self.subscribedSymbols.add(symbol) gatewayName = position.gatewayName # 查询合约对象 contract = self.mainEngine.getContract(symbol) if not contract: self.mainEngine.writeLog( u'vtEngine.updatePosition()找不到合约{0}信息'.format(symbol)) return # 订阅合约 req = VtSubscribeReq() req.symbol = symbol req.exchange = contract.exchange req.currency = '' req.productClass = '' # 订阅特定接口的行情 self.mainEngine.subscribe(req, gatewayName) self.mainEngine.writeLog(u'自动订阅合约{0}'.format(symbol))
class OmEngine(object): """期权主引擎""" impvFileName = 'PricingImpv.vt' impvFilePath = getTempPath(impvFileName) #---------------------------------------------------------------------- def __init__(self, mainEngine, eventEngine): """Constructor""" self.mainEngine = mainEngine self.eventEngine = eventEngine self.portfolio = None self.optionContractDict = {} # symbol:contract self.strategyEngine = OmStrategyEngine(self, eventEngine) self.registerEvent() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) #---------------------------------------------------------------------- def processTickEvent(self, event): """行情事件""" tick = event.dict_['data'] self.portfolio.newTick(tick) #---------------------------------------------------------------------- def processTradeEvent(self, event): """成交事件""" trade = event.dict_['data'] self.portfolio.newTrade(trade) #---------------------------------------------------------------------- def processContractEvent(self, event): """合约事件""" contract = event.dict_['data'] if contract.symbol and contract.productClass == PRODUCT_OPTION: self.optionContractDict[contract.symbol] = contract #---------------------------------------------------------------------- def subscribeEvent(self, symbol): """订阅对应合约的事件""" contract = self.mainEngine.getContract(symbol) if not contract: self.writeLog(u'行情订阅失败,找不到合约:%s' % symbol) return vtSymbol = contract.vtSymbol # 订阅行情 req = VtSubscribeReq() req.symbol = contract.symbol req.exchange = contract.exchange self.mainEngine.subscribe(req, contract.gatewayName) # 订阅事件 self.eventEngine.register(EVENT_TICK + vtSymbol, self.processTickEvent) self.eventEngine.register(EVENT_TRADE + vtSymbol, self.processTradeEvent) #---------------------------------------------------------------------- def initEngine(self, fileName): """初始化引擎""" if self.portfolio: return False f = open(fileName) setting = json.load(f) f.close() # 读取定价模型 model = MODEL_DICT.get(setting['model'], None) if not model: self.writeLog(u'找不到定价模型%s' % setting['model']) return # 创建标的对象 underlyingDict = OrderedDict() for underlyingSymbol in setting['underlying']: contract = self.mainEngine.getContract(underlyingSymbol) if not contract: self.writeLog(u'找不到标的物合约%s' % underlyingSymbol) continue detail = self.mainEngine.getPositionDetail(contract.vtSymbol) underlying = OmUnderlying(contract, detail) underlyingDict[underlyingSymbol] = underlying # 创建期权链对象并初始化 chainList = [] for d in setting['chain']: chainSymbol = d['chainSymbol'] r = d['r'] # 锁定标的对象 underlying = underlyingDict.get(d['underlyingSymbol'], None) if not underlying: self.writeLog(u'%s期权链的标的合约%s尚未创建,请检查配置文件' % (chainSymbol, underlyingSymbol)) continue # 创建期权对象并初始化 callDict = {} putDict = {} for symbol, contract in self.optionContractDict.items(): if contract.underlyingSymbol == d['chainSymbol']: detail = self.mainEngine.getPositionDetail( contract.vtSymbol) option = OmOption(contract, detail, underlying, model, r) key = str(option.k) if contract.optionType is OPTION_CALL: if key in callDict: key += 'a' callDict[key] = option else: if key in putDict: key += 'a' putDict[key] = option # 期权排序 strikeList = sorted(callDict.keys()) callList = [callDict[k] for k in strikeList] putList = [putDict[k] for k in strikeList] # 创建期权链 chain = OmChain(chainSymbol, callList, putList) chainList.append(chain) # 添加标的映射关系 underlying.addChain(chain) # 创建持仓组合对象并初始化 self.portfolio = OmPortfolio(setting['name'], model, underlyingDict.values(), chainList) # 载入波动率配置 self.loadImpvSetting() # 订阅行情和事件 for underlying in underlyingDict.values(): self.subscribeEvent(underlying.vtSymbol) for chain in chainList: for option in chain.optionDict.values(): self.subscribeEvent(option.vtSymbol) # 载入成功返回 return True #---------------------------------------------------------------------- def loadImpvSetting(self): """载入波动率配置""" f = shelve.open(self.impvFilePath) for chain in self.portfolio.chainDict.values(): for option in chain.optionDict.values(): option.pricingImpv = f.get(option.symbol, 0) f.close() #---------------------------------------------------------------------- def saveImpvSetting(self): """保存波动率配置""" if not self.portfolio: return f = shelve.open(self.impvFilePath) for chain in self.portfolio.chainDict.values(): for option in chain.optionDict.values(): f[option.symbol] = option.pricingImpv f.close() #---------------------------------------------------------------------- def stop(self): """关闭函数""" self.saveImpvSetting() #---------------------------------------------------------------------- def writeLog(self, content): """发出日志 """ log = VtLogData() log.logContent = content event = Event(EVENT_OM_LOG) event.dict_['data'] = log self.eventEngine.put(event) #---------------------------------------------------------------------- def adjustR(self): """调整折现率""" if self.portfolio: self.portfolio.adjustR() for chain in self.portfolio.chainDict.values(): self.writeLog(u'期权链%s的折现率r拟合为%.3f' % (chain.symbol, chain.r))
class DataEngine(object): """数据引擎""" contractFileName = 'ContractData.vt' contractFilePath = getTempPath(contractFileName) FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_REJECTED, STATUS_CANCELLED] #---------------------------------------------------------------------- def __init__(self, eventEngine): """Constructor""" self.eventEngine = eventEngine # 保存数据的字典和列表 self.tickDict = {} self.contractDict = {} self.orderDict = {} self.workingOrderDict = {} # 可撤销委托 self.tradeDict = {} self.accountDict = {} self.positionDict = {} self.logList = [] self.errorList = [] # 持仓细节相关 self.detailDict = {} # vtSymbol:PositionDetail self.tdPenaltyList = globalSetting['tdPenalty'] # 平今手续费惩罚的产品代码列表 # 读取保存在硬盘的合约数据 self.loadContracts() self.posBufferDict = {} #持仓缓存 # 注册事件监听 self.registerEvent() #---------------------------------------------------------------------- def registerEvent(self): """注册事件监听""" self.eventEngine.register(EVENT_TICK, self.processTickEvent) self.eventEngine.register(EVENT_CONTRACT, self.processContractEvent) self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) self.eventEngine.register(EVENT_POSITION, self.processPositionEvent) self.eventEngine.register(EVENT_ACCOUNT, self.processAccountEvent) self.eventEngine.register(EVENT_LOG, self.processLogEvent) self.eventEngine.register(EVENT_ERROR, self.processErrorEvent) #---------------------------------------------------------------------- def putMsg(self, q): """处理账户事件""" q.put(self.accountDict, block=False) def putPos(self, q): """推送持仓""" q.put(self.detailDict, block=False) #---------------------------------------------------------------------- def processTickEvent(self, event): """处理成交事件""" tick = event.dict_['data'] print "tick: ", tick.vtSymbol, tick.askPrice1 self.tickDict[tick.vtSymbol] = tick #---------------------------------------------------------------------- def processContractEvent(self, event): """处理合约事件""" contract = event.dict_['data'] self.contractDict[contract.vtSymbol] = contract self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复 #---------------------------------------------------------------------- def processOrderEvent(self, event): """处理委托事件""" order = event.dict_['data'] self.orderDict[order.vtOrderID] = order # 如果订单的状态是全部成交或者撤销,则需要从workingOrderDict中移除 if order.status in self.FINISHED_STATUS: if order.vtOrderID in self.workingOrderDict: del self.workingOrderDict[order.vtOrderID] # 否则则更新字典中的数据 else: self.workingOrderDict[order.vtOrderID] = order # 更新到持仓细节中 detail = self.getPositionDetail(order.vtSymbol) detail.updateOrder(order) #---------------------------------------------------------------------- def processTradeEvent(self, event): """处理成交事件""" trade = event.dict_['data'] self.tradeDict[trade.vtTradeID] = trade # 更新到持仓细节中 detail = self.getPositionDetail(trade.vtSymbol) detail.updateTrade(trade) ## 更新持仓缓存数据 #posBuffer = self.posBufferDict.get(trade.vtSymbol, None) #if not posBuffer: #posBuffer = PositionBuffer() #posBuffer.vtSymbol = trade.vtSymbol #self.posBufferDict[trade.vtSymbol] = posBuffer #posBuffer.updateTradeData(trade) #---------------------------------------------------------------------- def updateTradeData(self, trade): """更新成交数据""" if trade.direction == DIRECTION_LONG: # 多方开仓,则对应多头的持仓和今仓增加 if trade.offset == OFFSET_OPEN: self.longPosition += trade.volume self.longToday += trade.volume # 多方平今,对应空头的持仓和今仓减少 elif trade.offset == OFFSET_CLOSETODAY: self.shortPosition -= trade.volume self.shortToday -= trade.volume # 多方平昨,对应空头的持仓和昨仓减少 else: self.shortPosition -= trade.volume self.shortYd -= trade.volume else: # 空头和多头相同 if trade.offset == OFFSET_OPEN: self.shortPosition += trade.volume self.shortToday += trade.volume elif trade.offset == OFFSET_CLOSETODAY: self.longPosition -= trade.volume self.longToday -= trade.volume else: self.longPosition -= trade.volume self.longYd -= trade.volume #---------------------------------------------------------------------- def processPositionEvent(self, event): """处理持仓事件""" pos = event.dict_['data'] self.positionDict[pos.vtPositionName] = pos # 更新到持仓细节中 detail = self.getPositionDetail(pos.vtSymbol) detail.updatePosition(pos) # 更新持仓缓存数据 #posBuffer = self.posBufferDict.get(pos.vtSymbol, None) #if not posBuffer: #posBuffer = PositionBuffer() #posBuffer.vtSymbol = pos.vtSymbol #self.posBufferDict[pos.vtSymbol] = posBuffer #posBuffer.updatePositionData(pos) #---------------------------------------------------------------------- def updatePositionData(self, pos): """更新持仓数据""" if pos.direction == DIRECTION_LONG: self.longPosition = pos.position self.longYd = pos.ydPosition self.longToday = self.longPosition - self.longYd else: self.shortPosition = pos.position self.shortYd = pos.ydPosition self.shortToday = self.shortPosition - self.shortYd #---------------------------------------------------------------------- def processAccountEvent(self, event): """处理账户事件""" account = event.dict_['data'] self.accountDict[account.vtAccountID] = account # print account.vtAccountID , " banlance: ", account.balance #---------------------------------------------------------------------- def processLogEvent(self, event): """处理日志事件""" log = event.dict_['data'] self.logList.append(log) #---------------------------------------------------------------------- def processErrorEvent(self, event): """处理错误事件""" error = event.dict_['data'] self.errorList.append(error) #---------------------------------------------------------------------- def getTick(self, vtSymbol): """查询行情对象""" try: return self.tickDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getContract(self, vtSymbol): """查询合约对象""" try: return self.contractDict[vtSymbol] except KeyError: return None #---------------------------------------------------------------------- def getAllContracts(self): """查询所有合约对象(返回列表)""" return self.contractDict.values() #---------------------------------------------------------------------- def saveContracts(self): """保存所有合约对象到硬盘""" f = shelve.open(self.contractFilePath) f['data'] = self.contractDict f.close() #---------------------------------------------------------------------- def loadContracts(self): """从硬盘读取合约对象""" f = shelve.open(self.contractFilePath) if 'data' in f: d = f['data'] for key, value in d.items(): self.contractDict[key] = value f.close() #---------------------------------------------------------------------- def getOrder(self, vtOrderID): """查询委托""" try: return self.orderDict[vtOrderID] except KeyError: return None #---------------------------------------------------------------------- def getAllWorkingOrders(self): """查询所有活动委托(返回列表)""" return self.workingOrderDict.values() #-----------------------------------------r----------------------------- def getAllOrders(self): """获取所有委托""" return self.orderDict.values() #---------------------------------------------------------------------- def getAllTrades(self): """获取所有成交""" return self.tradeDict.values() #---------------------------------------------------------------------- def getAllPositions(self): """获取所有持仓""" return self.positionDict.values() #---------------------------------------------------------------------- def getAllAccounts(self): """获取所有资金""" return self.accountDict.values() #---------------------------------------------------------------------- def getPositionDetail(self, vtSymbol): """查询持仓细节""" if vtSymbol in self.detailDict: detail = self.detailDict[vtSymbol] else: contract = self.getContract(vtSymbol) detail = PositionDetail(vtSymbol, contract) self.detailDict[vtSymbol] = detail # 设置持仓细节的委托转换模式 contract = self.getContract(vtSymbol) if contract: detail.exchange = contract.exchange # 上期所合约 if contract.exchange == EXCHANGE_SHFE: detail.mode = detail.MODE_SHFE # 检查是否有平今惩罚 for productID in self.tdPenaltyList: if str(productID) in contract.symbol: detail.mode = detail.MODE_TDPENALTY return detail #---------------------------------------------------------------------- def getAllPositionDetails(self): """查询所有本地持仓缓存细节""" return self.detailDict.values() #---------------------------------------------------------------------- def updateOrderReq(self, req, vtOrderID): """委托请求更新""" vtSymbol = req.vtSymbol detail = self.getPositionDetail(vtSymbol) detail.updateOrderReq(req, vtOrderID) #---------------------------------------------------------------------- def convertOrderReq(self, req): """根据规则转换委托请求""" detail = self.detailDict.get(req.vtSymbol, None) if not detail: return [req] else: return detail.convertOrderReq(req) #---------------------------------------------------------------------- def getLog(self): """获取日志""" return self.logList #---------------------------------------------------------------------- def getError(self): """获取错误""" return self.errorList