diff --git a/.gitignore b/.gitignore index 23140e65..a859a730 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,7 @@ Release/ # 其他文件 *.dump -*.vssettings \ No newline at end of file +*.vssettings + +# 不想同步的 +*.local \ No newline at end of file diff --git a/vn.datayes/api.py b/vn.datayes/api.py index a2f74e04..667df21f 100644 --- a/vn.datayes/api.py +++ b/vn.datayes/api.py @@ -39,8 +39,7 @@ class Config(object): toke_ = '44ebc0f058981f85382595f9f15f967' + \ '0c7eaf2695de30dd752e8f33e9022baa0' - token = '7c2e59e212dbff90ffd6b382c7afb57' + \ - 'bc987a99307d382b058af6748f591d723' + token = '575593eb7696aec7339224c0fac2313780d8645f68b77369dcb35f8bcb419a0b' body = { 'ssl': False, diff --git a/vn.datayes/tests.py b/vn.datayes/tests.py index 979dd4f6..452a8159 100644 --- a/vn.datayes/tests.py +++ b/vn.datayes/tests.py @@ -101,7 +101,7 @@ def test_mktbar_M1_get_interM(): if __name__ == '__main__': #test_config() - #test_mktbar_D1() + test_mktbar_D1() #test_bond_D1() #test_fut_D1() #test_fund_D1() @@ -116,4 +116,4 @@ if __name__ == '__main__': #test_mongod_get_all() #test_mktbar_M1_get_drudgery() #test_mktbar_M1_get_all() - test_mktbar_M1_get_interM() \ No newline at end of file + #test_mktbar_M1_get_interM() \ No newline at end of file diff --git a/vn.lts/vnltstd/test/vnltstd.pyd b/vn.lts/vnltstd/test/vnltstd.pyd index 7b548cda..3fe5e236 100644 Binary files a/vn.lts/vnltstd/test/vnltstd.pyd and b/vn.lts/vnltstd/test/vnltstd.pyd differ diff --git a/vn.lts/vnltstd/vnltstd/vnltstd.cpp b/vn.lts/vnltstd/vnltstd/vnltstd.cpp index 791d9105..ba301ea7 100644 --- a/vn.lts/vnltstd/vnltstd/vnltstd.cpp +++ b/vn.lts/vnltstd/vnltstd/vnltstd.cpp @@ -1414,7 +1414,7 @@ int TdApi::reqOrderInsert(dict req, int nRequestID) CSecurityFtdcInputOrderField myreq = CSecurityFtdcInputOrderField(); memset(&myreq, 0, sizeof(myreq)); getChar(req, "ContingentCondition", &myreq.ContingentCondition); - getChar(req, "CombOffsetFlag", myreq.CombOffsetFlag); + //getChar(req, "CombOffsetFlag", myreq.CombOffsetFlag); getChar(req, "UserID", myreq.UserID); getChar(req, "LimitPrice", myreq.LimitPrice); getInt(req, "UserForceClose", &myreq.UserForceClose); @@ -1436,6 +1436,19 @@ int TdApi::reqOrderInsert(dict req, int nRequestID) getInt(req, "RequestID", &myreq.RequestID); getChar(req, "Direction", &myreq.Direction); + //CombOffsetFlag + if (req.has_key("CombOffsetFlag")) + { + object o2 = req["CombOffsetFlag"]; + extract x2(o2); + if (x2.check()) + { + string s2 = x2(); + const char *buffer2 = s2.c_str(); + myreq.CombOffsetFlag[0] = *buffer2; + } + } + int i = this->api->ReqOrderInsert(&myreq, nRequestID); return i; }; diff --git a/vn.trader/CTA_setting.json b/vn.trader/CTA_setting.json new file mode 100644 index 00000000..3e8805eb --- /dev/null +++ b/vn.trader/CTA_setting.json @@ -0,0 +1,14 @@ +{ + "Test1": { + "strategyClassName": "TestStrategy", + "vtSymbol": "IF1511" + }, + "Test3": { + "strategyClassName": "TestStrategy", + "vtSymbol": "IF1512" + }, + "Test2": { + "strategyClassName": "TestStrategy", + "vtSymbol": "IH1511" + } +} \ No newline at end of file diff --git a/vn.trader/CTP_connect.json b/vn.trader/CTP_connect.json index 959c21d4..fe1ffded 100644 --- a/vn.trader/CTP_connect.json +++ b/vn.trader/CTP_connect.json @@ -1,7 +1,7 @@ { - "brokerID": "8070", - "tdAddress": "tcp://27.115.57.147:41205", - "password": "123456", - "mdAddress": "tcp://27.115.57.147:41213", - "userID": "750000" + "brokerID": "9999", + "tdAddress": "tcp://180.168.146.187:10000", + "password": "simnow申请", + "mdAddress": "tcp://180.168.212.228:41213", + "userID": "simnow申请" } \ No newline at end of file diff --git a/vn.trader/ContractData.vt b/vn.trader/ContractData.vt new file mode 100644 index 00000000..15d41f3d Binary files /dev/null and b/vn.trader/ContractData.vt differ diff --git a/vn.trader/LTS_connect.json b/vn.trader/LTS_connect.json new file mode 100644 index 00000000..d3b5fbda --- /dev/null +++ b/vn.trader/LTS_connect.json @@ -0,0 +1,11 @@ +{ + "brokerID": "2011", + "tdAddress": "tcp://211.144.195.163:54505", + "qryAddress": "tcp://211.144.195.163:54506", + "mdAddress": "tcp://211.144.195.163:54513", + "productInfo": "LTS-Test", + "authCode": "N3EHKP4CYHZGM9VJ", + "tdPassword": "华宝证券申请", + "mdPassword": "华宝证券申请", + "userID": "华宝证券申请" +} \ No newline at end of file diff --git a/vn.trader/ctaConstant.py b/vn.trader/ctaConstant.py new file mode 100644 index 00000000..c01c0ed8 --- /dev/null +++ b/vn.trader/ctaConstant.py @@ -0,0 +1,15 @@ +# encoding: UTF-8 + +# CTA引擎中涉及到的交易方向类型 +CTAORDER_BUY = u'买开' +CTAORDER_SELL = u'卖平' +CTAORDER_SHORT = u'卖开' +CTAORDER_COVER = u'买平' + +# 本地停止单状态 +STOPORDER_WAITING = u'等待中' +STOPORDER_CANCELLED = u'已撤销' +STOPORDER_TRIGGERED = u'已触发' + +# 本地停止单前缀 +STOPORDERPREFIX = 'CtaStopOrder.' \ No newline at end of file diff --git a/vn.trader/ctaEngine.py b/vn.trader/ctaEngine.py new file mode 100644 index 00000000..81c4e64d --- /dev/null +++ b/vn.trader/ctaEngine.py @@ -0,0 +1,472 @@ +# encoding: UTF-8 + +from datetime import datetime +import json +from collections import OrderedDict + +from eventEngine import * +from vtConstant import * +from vtGateway import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData + +from ctaConstant import * +from ctaStrategies import strategyClassDict + + +######################################################################## +class StopOrder(object): + """本地停止单""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + self.vtSymbol = EMPTY_STRING + self.orderType = EMPTY_UNICODE + self.price = EMPTY_FLOAT + self.volume = EMPTY_INT + + self.strategy = None # 下停止单的策略对象 + self.stopOrderID = EMPTY_STRING # 停止单的本地编号 + self.status = EMPTY_STRING # 停止单状态 + + +######################################################################## +class CtaBarData(object): + """K线数据""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + self.vtSymbol = EMPTY_STRING # vt系统代码 + self.symbol = EMPTY_STRING # 代码 + self.exchange = EMPTY_STRING # 交易所 + + self.open = EMPTY_FLOAT # OHLC + self.high = EMPTY_FLOAT + self.low = EMPTY_FLOAT + self.close = EMPTY_FLOAT + + self.date = EMPTY_STRING # bar开始的时间,日期 + self.time = EMPTY_STRING # 时间 + self.datetime = None # python的datetime时间对象 + + self.volume = EMPTY_INT # 成交量 + self.openInterest = EMPTY_INT # 持仓量 + + +######################################################################## +class CtaTickData(object): + """Tick数据""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + self.vtSymbol = EMPTY_STRING # vt系统代码 + self.symbol = EMPTY_STRING # 合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + + # 成交数据 + self.lastPrice = EMPTY_FLOAT # 最新成交价 + self.volume = EMPTY_INT # 最新成交量 + self.openInterest = EMPTY_INT # 持仓量 + + self.upperLimit = EMPTY_FLOAT # 涨停价 + self.lowerLimit = EMPTY_FLOAT # 跌停价 + + # tick的时间 + self.date = EMPTY_STRING # 日期 + self.time = EMPTY_STRING # 时间 + self.datetime = None # python的datetime时间对象 + + # 五档行情 + self.bidPrice1 = EMPTY_FLOAT + self.bidPrice2 = EMPTY_FLOAT + self.bidPrice3 = EMPTY_FLOAT + self.bidPrice4 = EMPTY_FLOAT + self.bidPrice5 = EMPTY_FLOAT + + self.askPrice1 = EMPTY_FLOAT + self.askPrice2 = EMPTY_FLOAT + self.askPrice3 = EMPTY_FLOAT + self.askPrice4 = EMPTY_FLOAT + self.askPrice5 = EMPTY_FLOAT + + self.bidVolume1 = EMPTY_INT + self.bidVolume2 = EMPTY_INT + self.bidVolume3 = EMPTY_INT + self.bidVolume4 = EMPTY_INT + self.bidVolume5 = EMPTY_INT + + self.askVolume1 = EMPTY_INT + self.askVolume2 = EMPTY_INT + self.askVolume3 = EMPTY_INT + self.askVolume4 = EMPTY_INT + self.askVolume5 = EMPTY_INT + + +######################################################################## +class CtaEngine(object): + """CTA策略引擎""" + settingFileName = 'CTA_setting.json' + + #---------------------------------------------------------------------- + def __init__(self, mainEngine, eventEngine, dataEngine): + """Constructor""" + self.mainEngine = mainEngine + self.eventEngine = eventEngine + self.dataEngine = dataEngine + + # 保存策略对象的字典 + # key为策略名称,value为策略对象,注意策略名称不允许重复 + self.strategyDict = {} + + # 保存vtSymbol和策略对象映射的字典(用于推送tick数据) + # 由于可能多个strategy交易同一个vtSymbol,因此key为vtSymbol + # value为包含所有相关strategy对象的list + self.tickStrategyDict = {} + + # 保存vtOrderID和strategy对象映射的字典(用于推送order和trade数据) + # key为vtOrderID,value为strategy对象 + self.orderStrategyDict = {} + + # 本地停止单编号计数 + self.stopOrderCount = 0 + # stopOrderID = STOPORDERPREFIX + str(stopOrderCount) + + # 本地停止单字典 + # key为stopOrderID,value为stopOrder对象 + self.stopOrderDict = {} # 停止单撤销后不会从本字典中删除 + self.workingStopOrderDict = {} # 停止单撤销后会从本字典中删除 + + # 注册事件监听 + self.registerEvent() + + #---------------------------------------------------------------------- + def sendOrder(self, vtSymbol, orderType, price, volume, strategy): + """发单""" + contract = self.dataEngine.getContract(vtSymbol) + + req = VtOrderReq() + req.symbol = contract.symbol + req.exchange = contract.exchange + req.price = price + req.volume = volume + + # 设计为CTA引擎发出的委托只允许使用限价单 + req.priceType = PRICETYPE_LIMITPRICE + + # CTA委托类型映射 + if orderType == CTAORDER_BUY: + req.direction = DIRECTION_LONG + req.offset = OFFSET_OPEN + elif orderType == CTAORDER_SELL: + req.direction = DIRECTION_SHORT + req.offset = OFFSET_CLOSE + elif orderType == CTAORDER_SHORT: + req.direction = DIRECTION_SHORT + req.offset = OFFSET_OPEN + elif orderType == CTAORDER_COVER: + req.direction = DIRECTION_LONG + req.offset = OFFSET_CLOSE + + vtOrderID = self.mainEngine.sendOrder(req) # 发单 + self.orderDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 + return vtOrderID + + #---------------------------------------------------------------------- + def cancelOrder(self, vtOrderID): + """撤单""" + # 查询报单对象 + order = self.dataEngine.getOrder(vtOrderID) + + # 如果查询成功 + if order: + # 检查是否报单还有效,只有有效时才发出撤单指令 + orderFinished = (order.status==STATUS_ALLTRADED or order.status==STATUS_CANCELLED) + if not orderFinished: + 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 sendStopOrder(self, vtSymbol, orderType, price, volume, strategy): + """发停止单(本地实现)""" + self.stopOrderCount += 1 + stopOrderID = STOPORDERPREFIX + str(self.stopOrderCount) + + so = StopOrder() + so.vtSymbol = vtSymbol + so.orderType = orderType + so.price = price + so.volume = volume + so.strategy = strategy + so.stopOrderID = stopOrderID + so.status = STOPORDER_WAITING + + # 保存stopOrder对象到字典中 + self.stopOrderDict[stopOrderID] = so + self.workingStopOrderDict[stopOrderID] = so + + return stopOrderID + + #---------------------------------------------------------------------- + def cancelStopOrder(self, stopOrderID): + """撤销停止单""" + # 检查停止单是否存在 + if stopOrderID in self.workingStopOrderDict: + so = self.workingStopOrderDict[stopOrderID] + so.status = STOPORDER_CANCELLED + del self.workingStopOrderDict[stopOrderID] + + #---------------------------------------------------------------------- + def processStopOrder(self, tick): + """收到行情后处理本地停止单(检查是否要立即发出)""" + vtSymbol = tick.vtSymbol + + # 首先检查是否有策略交易该合约 + if vtSymbol in self.tickStrategyDict: + # 遍历等待中的停止单,检查是否会被触发 + for so in self.workingStopOrderDict.values(): + if so.vtSymbol == vtSymbol: + longTriggered = so.direction==DIRECTION_LONG and tick.lastPrice>=so.price # 多头停止单被触发 + shortTriggered = so.direction==DIRECTION_SHORT and tick.lasatPrice<=so.price # 空头停止单被触发 + + if longTriggered or shortTriggered: + # 买入和卖出分别以涨停跌停价发单(模拟市价单) + if so.direction==DIRECTION_LONG: + price = tick.upperLimit + else: + price = tick.lowerLimit + + so.status = STOPORDER_TRIGGERED + self.sendOrder(so.vtSymbol, so.orderType, price, so.volume, so.strategy) + del self.workingStopOrderDict[so.stopOrderID] + + #---------------------------------------------------------------------- + def procecssTickEvent(self, event): + """处理行情推送""" + tick = event.dict_['data'] + # 收到tick行情后,先处理本地停止单(检查是否要立即发出) + self.processStopOrder(tick) + + # 推送tick到对应的策略对象进行处理 + if tick.vtSymbol in self.tickStrategyDict: + # 将vtTickData数据转化为ctaTickData + ctaTick = CtaTickData() + d = ctaTick.__dict__ + for key in d.keys(): + if key != 'datetime': + d[key] = tick.__getattribute__(key) + # 添加datetime字段 + ctaTick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y%m%d %H:%M:%S.%f') + + # 逐个推送到策略对象中 + l = self.tickStrategyDict[tick.vtSymbol] + for strategy in l: + strategy.onTick(tick) + + #---------------------------------------------------------------------- + def processOrderEvent(self, event): + """处理委托推送""" + order = event.dict_['data'] + + if order.vtOrderID in self.orderStrategyDict: + strategy = self.orderStrategyDict[order.vtOrderID] + strategy.onOrder(order) + + #---------------------------------------------------------------------- + def processTradeEvent(self, event): + """处理成交推送""" + trade = event.dict_['data'] + + if trade.vtOrderID in self.orderStrategyDict: + strategy = self.orderStrategyDict[order.vtOrderID] + strategy.onTrade(trade) + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + self.eventEngine.register(EVENT_TICK, self.procecssTickEvent) + self.eventEngine.register(EVENT_ORDER, self.processOrderEvent) + self.eventEngine.register(EVENT_TRADE, self.processTradeEvent) + + #---------------------------------------------------------------------- + def insertData(self, dbName, collectionName, data): + """插入数据到数据库(这里的data可以是CtaTickData或者CtaBarData)""" + self.mainEngine.dbInsert(dbName, collectionName, data.__dict__) + + #---------------------------------------------------------------------- + def loadBar(self, dbName, collectionName, startDate): + """从数据库中读取Bar数据,startDate是datetime对象""" + d = {'datetime':{'$gte':startDate}} + cursor = self.mainEngine.dbQuery(dbName, collectionName, d) + + l = [] + for d in cursor: + bar = CtaBarData() + bar.__dict__ = d + l.append(bar) + + return l + + #---------------------------------------------------------------------- + def loadTick(self, dbName, collectionName, startDate): + """从数据库中读取Tick数据,startDate是datetime对象""" + d = {'datetime':{'$gte':startDate}} + cursor = self.mainEngine.dbQuery(dbName, collectionName, d) + + l = [] + for d in cursor: + tick = CtaTickData() + tick.__dict__ = d + l.append(tick) + + return l + + #---------------------------------------------------------------------- + def getToday(self): + """获取代表今日的datetime对象""" + today = datetime.today() + today = today.replace(hour=0, minute=0, second=0, microsecond=0) + return today + + #---------------------------------------------------------------------- + def writeCtaLog(self, content): + """快速发出CTA模块日志事件""" + log = VtLogData() + log.logContent = content + event = Event(type_=EVENT_CTA_LOG) + event.dict_['data'] = log + self.eventEngine.put(event) + + #---------------------------------------------------------------------- + def initStrategy(self, name, strategyClass, paramDict=None): + """初始化策略""" + # 防止策略重名 + if name not in self.strategyDict: + # 创建策略对象 + strategy = strategyClass(self, name, paramDict) + self.strategyDict[name] = strategy + + # 保存Tick映射关系 + if strategy.vtSymbol in self.tickStrategyDict: + l = self.tickStrategyDict[strategy.vtSymbol] + else: + l = [] + self.tickStrategyDict[strategy.vtSymbol] = l + l.append(strategy) + + # 订阅合约 + contract = self.dataEngine.getContract(strategy.vtSymbol) + if contract: + req = VtSubscribeReq() + req.symbol = contract.symbol + req.exchange = contract.exchange + self.mainEngine.subscribe(req, contract.gatewayName) + else: + self.writeCtaLog(u'存在策略对象重名:' + name) + + #--------------------------------------------------------------------- + def startStrategy(self, name): + """启动策略""" + if name in self.strategyDict: + strategy = self.strategyDict[name] + + if not strategy.trading: + strategy.trading = True + strategy.start() + else: + self.writeCtaLog(u'策略对象不存在:' + name) + + #---------------------------------------------------------------------- + def stopStrategy(self, name): + """停止策略""" + if name in self.strategyDict: + strategy = self.strategyDict[name] + + if strategy.trading: + strategy.trading = False + strategy.stop() + + # 对该策略发出的所有限价单进行撤单 + for vtOrderID, s in self.orderStrategyDict.items(): + if s is strategy: + self.cancelOrder(vtOrderID) + + # 对该策略发出的所有本地停止单撤单 + for stopOrderID, so in self.workingStopOrderDict.items(): + if so.strategy is strategy: + self.cancelStopOrder(stopOrderID) + else: + self.writeCtaLog(u'策略对象不存在:' + name) + + #---------------------------------------------------------------------- + def saveStrategySetting(self): + """保存引擎中的策略配置""" + with open(self.settingFileName, 'w') as f: + d = {} + + for name, strategy in self.strategyDict.items(): + setting = {} + setting['strategyClassName'] = strategy.strategyClassName + for param in strategy.paramList: + setting[param] = strategy.__getattribute__(param) + d[name] = setting + + jsonD = json.dumps(d, indent=4) + f.write(jsonD) + + #---------------------------------------------------------------------- + def loadStrategySetting(self): + """读取引擎中的策略配置""" + with open(self.settingFileName) as f: + d = json.load(f) + + for name, setting in d.items(): + strategyClassName = setting['strategyClassName'] + + if strategyClassName in strategyClassDict: + strategyClass = strategyClassDict[strategyClassName] + self.initStrategy(name, strategyClass, setting) + else: + self.writeCtaLog(u'无法找到策略类:' + strategyClassName) + break + + #---------------------------------------------------------------------- + def getStrategyVar(self, name): + """获取策略当前的变量字典""" + if name in self.strategyDict: + strategy = self.strategyDict[name] + d = strategy.__dict__ + varDict = OrderedDict() + + for key in strategy.varList: + if key in d: + varDict[key] = d[key] + + return varDict + else: + self.writeCtaLog(u'策略对象不存在:' + name) + return None + + #---------------------------------------------------------------------- + def getStrategyParam(self, name): + """获取策略的参数字典""" + if name in self.strategyDict: + strategy = self.strategyDict[name] + d = strategy.__dict__ + paramDict = OrderedDict() + + for key in strategy.paramList: + if key in d: + paramDict[key] = d[key] + + return paramDict + else: + self.writeCtaLog(u'策略对象不存在:' + name) + return None + + diff --git a/vn.trader/ctaStrategies.py b/vn.trader/ctaStrategies.py new file mode 100644 index 00000000..ce5fa40b --- /dev/null +++ b/vn.trader/ctaStrategies.py @@ -0,0 +1,10 @@ +# encoding: UTF-8 + +''' +在本文件中引入所有希望在系统中使用的策略类 +''' + +from ctaStrategyTemplate import TestStrategy + +strategyClassDict = {} +strategyClassDict[u'TestStrategy'] = TestStrategy \ No newline at end of file diff --git a/vn.trader/ctaStrategyTemplate.py b/vn.trader/ctaStrategyTemplate.py new file mode 100644 index 00000000..5ea0a619 --- /dev/null +++ b/vn.trader/ctaStrategyTemplate.py @@ -0,0 +1,233 @@ +# encoding: UTF-8 + +from vtConstant import * +from ctaConstant import * + + +######################################################################## +class CtaStrategyTemplate(object): + """CTA策略模板""" + # 策略类的名称 + strategyClassName = 'Template' + + # 参数列表,保存了参数的名称 + paramList = ['vtSymbol'] + + # 变量列表,保存了变量的名称 + varList = ['trading'] + + #---------------------------------------------------------------------- + def __init__(self, ctaEngine, name, setting=None): + """Constructor""" + self.ctaEngine = ctaEngine + self.name = name + + self.vtSymbol = EMPTY_STRING # 交易的合约vt系统代码 + + self.tickDbName = EMPTY_STRING # tick数据库名称 + self.barDbName = EMPTY_STRING # bar数据库名称 + + self.trading = False # 控制是否启动交易 + + self.init() # 初始化策略 + + if setting: + self.setParam(setting) + + #---------------------------------------------------------------------- + def init(self): + """初始化策略(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def start(self): + """启动策略(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def stop(self): + """停止策略(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def onTick(self, tick): + """收到行情TICK推送(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def onOrder(self, order): + """收到委托变化推送(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def onTrade(self, trade): + """收到成交推送(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def onBar(self, bar): + """收到Bar推送(必须由用户继承实现)""" + raise NotImplementedError + + #---------------------------------------------------------------------- + def buy(self, price, volume, stop=False): + """买开""" + # 如果stop为True,则意味着发本地停止单 + if self.trading: + if stop: + orderID = self.ctaEngine.sendStopOrder(self.vtSymbol, CTAORDER_BUY, price, volume, self) + else: + orderID = self.ctaEngine.sendOrder(self.vtSymbol, CTAORDER_BUY, price, volume, self) + return orderID + else: + return None + + #---------------------------------------------------------------------- + def sell(self, price, volume, stop=False): + """卖平""" + # 如果stop为True,则意味着发本地停止单 + if self.trading: + if stop: + orderID = self.ctaEngine.sendStopOrder(self.vtSymbol, CTAORDER_SELL, price, volume, self) + else: + orderID = self.ctaEngine.sendOrder(self.vtSymbol, CTAORDER_SELL, price, volume, self) + return orderID + else: + return None + + #---------------------------------------------------------------------- + def short(self, price, volume, stop=False): + """卖开""" + # 如果stop为True,则意味着发本地停止单 + if self.trading: + if stop: + orderID = self.ctaEngine.sendStopOrder(self.vtSymbol, CTAORDER_SHORT, price, volume, self) + else: + orderID = self.ctaEngine.sendOrder(self.vtSymbol, CTAORDER_SHORT, price, volume, self) + return orderID + else: + return None + + #---------------------------------------------------------------------- + def cover(self, price, volume, stop=False): + """买平""" + if self.trading: + # 如果stop为True,则意味着发本地停止单 + if stop: + orderID = self.ctaEngine.sendStopOrder(self.vtSymbol, CTAORDER_COVER, price, volume, self) + else: + orderID = self.ctaEngine.sendOrder(self.vtSymbol, CTAORDER_COVER, price, volume, self) + return orderID + else: + return None + + #---------------------------------------------------------------------- + def cancelOrder(self, orderID): + """撤单""" + if STOPORDERPREFIX in orderID: + self.ctaEngine.cancelStopOrder(orderID) + else: + self.ctaEngine.cancelOrder(orderID) + + #---------------------------------------------------------------------- + def insertTick(self, tick): + """向数据库中插入tick数据""" + self.ctaEngine.insertData(self.tickDbName, self.vtSymbol, tick) + + #---------------------------------------------------------------------- + def insertBar(self, bar): + """向数据库中插入bar数据""" + self.ctaEngine.insertData(self.barDbName, self.vtSymbol, bar) + + #---------------------------------------------------------------------- + def loadTick(self, startDate): + """读取tick数据""" + return self.ctaEngine.loadTick(self.tickDbName, self.vtSymbol, startDate) + + #---------------------------------------------------------------------- + def loadBar(self, startDate): + """读取bar数据""" + return self.ctaEngine.loadBar(self.barDbName, self.vtSymbol, startDate) + + #---------------------------------------------------------------------- + def setParam(self, setting): + """设置参数""" + d = self.__dict__ + for key in self.paramList: + if key in setting: + d[key] = setting[key] + + #---------------------------------------------------------------------- + def getToday(self): + """查询当前日期""" + return self.ctaEngine.getToday() + + #---------------------------------------------------------------------- + def writeCtaLog(self, content): + """记录CTA日志""" + self.ctaEngine.writeCtaLog(content) + + + +######################################################################## +class TestStrategy(CtaStrategyTemplate): + """测试策略""" + + #---------------------------------------------------------------------- + def __init__(self, ctaEngine, name, setting=None): + """Constructor""" + super(TestStrategy, self).__init__(ctaEngine, name, setting) + + self.strategyClassName = 'TestStrategy' + + self.author = u'用Python的交易员' # 作者 + + self.pos = EMPTY_INT # 持仓 + self.lastPrice = EMPTY_FLOAT # 最新价 + + # 参数和变量列表设置 + self.paramList.append(u'author') + + self.varList.append('pos') + self.varList.append('lastPrice') + + #---------------------------------------------------------------------- + def init(self): + """初始化策略(必须由用户继承实现)""" + self.writeCtaLog(u'测试策略%s初始化' %self.name) + + #---------------------------------------------------------------------- + def start(self): + """启动策略(必须由用户继承实现)""" + self.writeCtaLog(u'测试策略%s启动' %self.name) + + #---------------------------------------------------------------------- + def stop(self): + """停止策略(必须由用户继承实现)""" + self.writeCtaLog(u'测试策略%s停止' %self.name) + + #---------------------------------------------------------------------- + def onTick(self, tick): + """收到行情TICK推送(必须由用户继承实现)""" + self.writeCtaLog(u'测试策略%s收到Tick' %self.name) + self.lastPrice = tick.lastPrice + + #---------------------------------------------------------------------- + def onOrder(self, order): + """收到委托变化推送(必须由用户继承实现)""" + self.writeCtaLog(u'onOrder不会被调用') + + #---------------------------------------------------------------------- + def onTrade(self, trade): + """收到成交推送(必须由用户继承实现)""" + self.writeCtaLog(u'onTrade不会被调用') + + #---------------------------------------------------------------------- + def onBar(self, bar): + """收到Bar推送(必须由用户继承实现)""" + self.writeCtaLog(u'测试策略%s收到Bar' %self.name) + + + + + \ No newline at end of file diff --git a/vn.trader/ctpGateway.py b/vn.trader/ctpGateway.py index b1168ec9..c2b92ef3 100644 --- a/vn.trader/ctpGateway.py +++ b/vn.trader/ctpGateway.py @@ -1,5 +1,13 @@ # encoding: UTF-8 +''' +vn.ctp的gateway接入 + +考虑到现阶段大部分CTP中的ExchangeID字段返回的都是空值 +vtSymbol直接使用symbol +''' + + import os import json @@ -8,6 +16,47 @@ from vnctptd import TdApi from ctpDataType import * from vtGateway import * +# 以下为一些VT类型和CTP类型的映射字典 +# 价格类型映射 +priceTypeMap = {} +priceTypeMap[PRICETYPE_LIMITPRICE] = defineDict["THOST_FTDC_OPT_LimitPrice"] +priceTypeMap[PRICETYPE_MARKETPRICE] = defineDict["THOST_FTDC_OPT_AnyPrice"] +priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()} + +# 方向类型映射 +directionMap = {} +directionMap[DIRECTION_LONG] = defineDict['THOST_FTDC_D_Buy'] +directionMap[DIRECTION_SHORT] = defineDict['THOST_FTDC_D_Sell'] +directionMapReverse = {v: k for k, v in directionMap.items()} + +# 开平类型映射 +offsetMap = {} +offsetMap[OFFSET_OPEN] = defineDict['THOST_FTDC_OF_Open'] +offsetMap[OFFSET_CLOSE] = defineDict['THOST_FTDC_OF_Close'] +offsetMap[OFFSET_CLOSETODAY] = defineDict['THOST_FTDC_OF_CloseToday'] +offsetMap[OFFSET_CLOSESYESTERDAY] = defineDict['THOST_FTDC_OF_CloseYesterday'] +offsetMapReverse = {v:k for k,v in offsetMap.items()} + +# 交易所类型映射 +exchangeMap = {} +#exchangeMap[EXCHANGE_CFFEX] = defineDict['THOST_FTDC_EIDT_CFFEX'] +#exchangeMap[EXCHANGE_SHFE] = defineDict['THOST_FTDC_EIDT_SHFE'] +#exchangeMap[EXCHANGE_CZCE] = defineDict['THOST_FTDC_EIDT_CZCE'] +#exchangeMap[EXCHANGE_DCE] = defineDict['THOST_FTDC_EIDT_DCE'] +exchangeMap[EXCHANGE_CFFEX] = 'CFFEX' +exchangeMap[EXCHANGE_SHFE] = 'SHFE' +exchangeMap[EXCHANGE_CZCE] = 'CZCE' +exchangeMap[EXCHANGE_DCE] = 'DCE' +exchangeMap[EXCHANGE_UNKNOWN] = '' +exchangeMapReverse = {v:k for k,v in exchangeMap.items()} + +# 持仓类型映射 +posiDirectionMap = {} +posiDirectionMap[DIRECTION_NET] = defineDict["THOST_FTDC_PD_Net"] +posiDirectionMap[DIRECTION_LONG] = defineDict["THOST_FTDC_PD_Long"] +posiDirectionMap[DIRECTION_SHORT] = defineDict["THOST_FTDC_PD_Short"] +posiDirectionMapReverse = {v:k for k,v in posiDirectionMap.items()} + ######################################################################## class CtpGateway(VtGateway): @@ -24,6 +73,8 @@ class CtpGateway(VtGateway): self.mdConnected = False # 行情API连接状态,登录完成后为True self.tdConnected = False # 交易API连接状态 + self.qryEnabled = False # 是否要启动循环查询 + #---------------------------------------------------------------------- def connect(self): """连接""" @@ -56,11 +107,14 @@ class CtpGateway(VtGateway): # 创建行情和交易接口对象 self.mdApi.connect(userID, password, brokerID, mdAddress) self.tdApi.connect(userID, password, brokerID, tdAddress) + + # 初始化并启动查询 + self.initQuery() #---------------------------------------------------------------------- def subscribe(self, subscribeReq): """订阅行情""" - self.mdApi(subscribeReq) + self.mdApi.subscribe(subscribeReq) #---------------------------------------------------------------------- def sendOrder(self, orderReq): @@ -85,8 +139,52 @@ class CtpGateway(VtGateway): #---------------------------------------------------------------------- def close(self): """关闭""" - self.mdApi.close() - self.tdApi.close() + if self.mdConnected: + self.mdApi.close() + if self.tdConnected: + self.tdApi.close() + + #---------------------------------------------------------------------- + def initQuery(self): + """初始化连续查询""" + if self.qryEnabled: + # 需要循环的查询函数列表 + self.qryFunctionList = [self.getAccount, self.getPosition] + + self.qryCount = 0 # 查询触发倒计时 + self.qryTrigger = 2 # 查询触发点 + self.qryNextFunction = 0 # 上次运行的查询函数索引 + + self.startQuery() + + #---------------------------------------------------------------------- + def query(self, event): + """注册到事件处理引擎上的查询函数""" + self.qryCount += 1 + + if self.qryCount > self.qryTrigger: + # 清空倒计时 + self.qryCount = 0 + + # 执行查询函数 + function = self.qryFunctionList[self.qryNextFunction] + function() + + # 计算下次查询函数的索引,如果超过了列表长度,则重新设为0 + self.qryNextFunction += 1 + if self.qryNextFunction == len(self.qryFunctionList): + self.qryNextFunction = 0 + + #---------------------------------------------------------------------- + def startQuery(self): + """启动连续查询""" + self.eventEngine.register(EVENT_TIMER, self.query) + + #---------------------------------------------------------------------- + def setQryEnabled(self, qryEnabled): + """设置是否要启动循环查询""" + self.qryEnabled = qryEnabled + ######################################################################## @@ -106,7 +204,6 @@ class CtpMdApi(MdApi): self.connectionStatus = False # 连接状态 self.loginStatus = False # 登录状态 - self.subscribedSymbols = set() # 已订阅合约代码 self.userID = EMPTY_STRING # 账号 @@ -123,7 +220,6 @@ class CtpMdApi(MdApi): log.gatewayName = self.gatewayName log.logContent = u'行情服务器连接成功' self.gateway.onLog(log) - self.login() #---------------------------------------------------------------------- @@ -162,6 +258,7 @@ class CtpMdApi(MdApi): self.gateway.mdConnected = True log = VtLogData() + log.gatewayName = self.gatewayName log.logContent = u'行情服务器登录完成' self.gateway.onLog(log) @@ -214,18 +311,25 @@ class CtpMdApi(MdApi): def onRtnDepthMarketData(self, data): """行情推送""" tick = VtTickData() + tick.gatewayName = self.gatewayName tick.symbol = data['InstrumentID'] - tick.vtSymbol = '.'.join([self.gatewayName, tick.symbol]) + tick.exchange = exchangeMapReverse.get(data['ExchangeID'], u'未知') + tick.vtSymbol = tick.symbol #'.'.join([tick.symbol, EXCHANGE_UNKNOWN]) tick.lastPrice = data['LastPrice'] tick.volume = data['Volume'] tick.openInterest = data['OpenInterest'] - tick.tickTime = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)]) + tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)]) + tick.date = data['TradingDay'] tick.openPrice = data['OpenPrice'] tick.highPrice = data['HighestPrice'] tick.lowPrice = data['LowestPrice'] + tick.preClosePrice = data['PreClosePrice'] + + tick.upperLimit = data['UpperLimitPrice'] + tick.lowerLimit = data['LowerLimitPrice'] # CTP只有一档行情 tick.bidPrice1 = data['BidPrice1'] @@ -280,7 +384,10 @@ class CtpMdApi(MdApi): #---------------------------------------------------------------------- def subscribe(self, subscribeReq): """订阅合约""" - self.subscribeMarketData(subscribeReq.symbol) + # 这里的设计是,如果尚未登录就调用了订阅方法 + # 则先保存订阅请求,登录完成后会自动订阅 + if self.loginStatus: + self.subscribeMarketData(str(subscribeReq.symbol)) self.subscribedSymbols.add(subscribeReq) #---------------------------------------------------------------------- @@ -305,27 +412,6 @@ class CtpMdApi(MdApi): class CtpTdApi(TdApi): """CTP交易API实现""" - # 以下为一些VT类型和CTP类型的映射字典 - # 价格类型映射 - priceTypeMap = {} - priceTypeMap[PRICETYPE_LIMITPRICE] = defineDict["THOST_FTDC_OPT_LimitPrice"] - priceTypeMap[PRICETYPE_MARKETPRICE] = defineDict["THOST_FTDC_OPT_AnyPrice"] - priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()} - - # 方向类型映射 - directionMap = {} - directionMap[DIRECTION_LONG] = defineDict['THOST_FTDC_D_Buy'] - directionMap[DIRECTION_SHORT] = defineDict['THOST_FTDC_D_Sell'] - directionMapReverse = {v: k for k, v in directionMap.items()} - - # 开平类型映射 - offsetMap = {} - offsetMap[OFFSET_OPEN] = defineDict['THOST_FTDC_OF_Open'] - offsetMap[OFFSET_CLOSE] = defineDict['THOST_FTDC_OF_Close'] - offsetMap[OFFSET_CLOSETODAY] = defineDict['THOST_FTDC_OF_CloseToday'] - offsetMap[OFFSET_CLOSESYESTERDAY] = defineDict['THOST_FTDC_OF_CloseYesterday'] - offsetMapReverse = {v:k for k,v in offsetMap.items()} - #---------------------------------------------------------------------- def __init__(self, gateway): """API对象的初始化函数""" @@ -345,6 +431,9 @@ class CtpTdApi(TdApi): self.brokerID = EMPTY_STRING # 经纪商代码 self.address = EMPTY_STRING # 服务器地址 + self.frontID = EMPTY_INT # 前置机编号 + self.sessionID = EMPTY_INT # 会话编号 + #---------------------------------------------------------------------- def onFrontConnected(self): """服务器连接""" @@ -384,6 +473,8 @@ class CtpTdApi(TdApi): """登陆回报""" # 如果登录成功,推送日志信息 if error['ErrorID'] == 0: + self.frontID = str(data['FrontID']) + self.sessionID = str(data['SessionID']) self.loginStatus = True self.gateway.mdConnected = True @@ -536,17 +627,13 @@ class CtpTdApi(TdApi): # 保存代码 pos.symbol = data['InstrumentID'] - pos.vtSymbol = '.'.join([self.gatewayName, pos.symbol]) + pos.vtSymbol = pos.symbol # 这里因为data中没有ExchangeID这个字段 # 方向和持仓冻结数量 - if data['PosiDirection'] == '1': - pos.direction = DIRECTION_NET + pos.direction = posiDirectionMapReverse.get(data['PosiDirection'], '') + if pos.direction == DIRECTION_NET or pos.direction == DIRECTION_LONG: pos.frozen = data['LongFrozen'] - if data['PosiDirection'] == '2': - pos.direction = DIRECTION_LONG - pos.frozen = data['LongFrozen'] - elif data['PosiDirection'] == '3': - pos.direction = DIRECTION_SHORT + elif pos.direction == DIRECTION_SHORT: pos.frozen = data['ShortFrozen'] # 持仓量 @@ -583,7 +670,7 @@ class CtpTdApi(TdApi): # 这里的balance和快期中的账户不确定是否一样,需要测试 account.balance = (data['PreBalance'] - data['PreCredit'] - data['PreMortgage'] + data['Mortgage'] - data['Withdraw'] + data['Deposit'] + - data['ClostProfit'] + data['PositionProfit'] + data['CashIn'] - + data['CloseProfit'] + data['PositionProfit'] + data['CashIn'] - data['Commission']) # 推送 @@ -624,10 +711,11 @@ class CtpTdApi(TdApi): """合约查询回报""" contract = VtContractData() contract.gatewayName = self.gatewayName - + contract.symbol = data['InstrumentID'] - contract.vtSymbol = '.'.join([self.gatewayName, contract.symbol]) - contract.name = data['InstrumentName'] + contract.exchange = exchangeMapReverse[data['ExchangeID']] + contract.vtSymbol = contract.symbol #'.'.join([contract.symbol, contract.exchange]) + contract.name = data['InstrumentName'].decode('GBK') # 合约数值 contract.size = data['VolumeMultiple'] @@ -637,20 +725,28 @@ class CtpTdApi(TdApi): # 合约类型 if data['ProductClass'] == '1': - contract.productClass == PRODUCT_FUTURES + contract.productClass = PRODUCT_FUTURES elif data['ProductClass'] == '2': contract.productClass = PRODUCT_OPTION elif data['ProductClass'] == '3': contract.productClass = PRODUCT_COMBINATION + else: + contract.productClass = PRODUCT_UNKNOWN # 期权类型 - if data['OptionType'] == '1': + if data['OptionsType'] == '1': contract.optionType = OPTION_CALL - elif data['OptionType'] == '2': + elif data['OptionsType'] == '2': contract.optionType = OPTION_PUT # 推送 self.gateway.onContract(contract) + + if last: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易合约信息获取完成' + self.gateway.onLog(log) #---------------------------------------------------------------------- def onRspQryDepthMarketData(self, data, error, n, last): @@ -779,10 +875,10 @@ class CtpTdApi(TdApi): # 保存代码和报单号 order.symbol = data['InstrumentID'] - order.vtSymbol = '.'.join([self.gatewayName, order.symbol]) + order.exchange = exchangeMapReverse[data['ExchangeID']] + order.vtSymbol = order.symbol #'.'.join([order.symbol, order.exchange]) order.orderID = data['OrderRef'] - order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) # 方向 if data['Direction'] == '0': @@ -821,6 +917,12 @@ class CtpTdApi(TdApi): order.frontID = data['FrontID'] order.sessionID = data['SessionID'] + # CTP的报单号一致性维护需要基于frontID, sessionID, orderID三个字段 + # 但在本接口设计中,已经考虑了CTP的OrderRef的自增性,避免重复 + # 唯一可能出现OrderRef重复的情况是多处登录并在非常接近的时间内(几乎同时发单) + # 考虑到VtTrader的应用场景,认为以上情况不会构成问题 + order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) + # 推送 self.gateway.onOrder(order) @@ -829,11 +931,12 @@ class CtpTdApi(TdApi): """成交回报""" # 创建报单数据对象 trade = VtTradeData() - order.gatewayName = self.gatewayName + trade.gatewayName = self.gatewayName # 保存代码和报单号 trade.symbol = data['InstrumentID'] - trade.vtSymbol = '.'.join([self.gatewayName, trade.symbol]) + trade.exchange = exchangeMapReverse[data['ExchangeID']] + trade.vtSymbol = trade.symbol #'.'.join([trade.symbol, trade.exchange]) trade.tradeID = data['TradeID'] trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) @@ -842,20 +945,10 @@ class CtpTdApi(TdApi): trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID]) # 方向 - if data['Direction'] == '0': - trade.direction = DIRECTION_LONG - elif data['Direction'] == '1': - trade.direction = DIRECTION_SHORT - else: - trade.direction = DIRECTION_UNKNOWN + trade.direction = directionMapReverse.get(data['Direction'], '') # 开平 - if data['OffsetFlag'] == '0': - trade.offset = OFFSET_OPEN - elif data['OffsetFlag'] == '1': - trade.offset = OFFSET_CLOSE - else: - trade.offset = OFFSET_UNKNOW + trade.offset = offsetMapReverse.get(data['OffsetFlag'], '') # 价格、报单量等数值 trade.price = data['Price'] @@ -1146,9 +1239,9 @@ class CtpTdApi(TdApi): # 下面如果由于传入的类型本接口不支持,则会返回空字符串 try: - req['OrderPriceType'] = self.priceTypeMap[orderReq.priceType] - req['Direction'] = self.directionMap[orderReq.priceType] - req['CombOffsetFlag'] = self.offsetMap[orderReq.offset] + req['OrderPriceType'] = priceTypeMap[orderReq.priceType] + req['Direction'] = directionMap[orderReq.direction] + req['CombOffsetFlag'] = offsetMap[orderReq.offset] except KeyError: return '' @@ -1168,7 +1261,8 @@ class CtpTdApi(TdApi): self.reqOrderInsert(req, self.reqID) # 返回订单号(字符串),便于某些算法进行动态管理 - return str(self.orderRef) + vtOrderID = '.'.join([self.gatewayName, str(self.orderRef)]) + return vtOrderID #---------------------------------------------------------------------- def cancelOrder(self, cancelOrderReq): @@ -1179,7 +1273,7 @@ class CtpTdApi(TdApi): req['InstrumentID'] = cancelOrderReq.symbol req['ExchangeID'] = cancelOrderReq.exchange - req['OrderRef'] = cancelOrderReq.orderRef + req['OrderRef'] = cancelOrderReq.orderID req['FrontID'] = cancelOrderReq.frontID req['SessionID'] = cancelOrderReq.sessionID @@ -1192,4 +1286,30 @@ class CtpTdApi(TdApi): #---------------------------------------------------------------------- def close(self): """关闭""" - self.exit() \ No newline at end of file + self.exit() + + +#---------------------------------------------------------------------- +def test(): + """测试""" + from PyQt4 import QtCore + import sys + + def print_log(event): + log = event.dict_['data'] + print ':'.join([log.logTime, log.logContent]) + + app = QtCore.QCoreApplication(sys.argv) + + eventEngine = EventEngine() + eventEngine.register(EVENT_LOG, print_log) + eventEngine.start() + + gateway = CtpGateway(eventEngine) + gateway.connect() + + sys.exit(app.exec_()) + + +if __name__ == '__main__': + test() \ No newline at end of file diff --git a/vn.trader/eventEngine.py b/vn.trader/eventEngine.py index 2ceada00..03f97b17 100644 --- a/vn.trader/eventEngine.py +++ b/vn.trader/eventEngine.py @@ -143,7 +143,7 @@ class EventEngine: """注销事件处理函数监听""" # 尝试获取该事件类型对应的处理函数列表,若无则忽略该次注销请求 try: - handlerList = self.handlers[type_] + handlerList = self.__handlers[type_] # 如果该函数存在于列表中,则移除 if handler in handlerList: @@ -151,7 +151,7 @@ class EventEngine: # 如果函数列表为空,则从引擎中移除该事件类型 if not handlerList: - del self.handlers[type_] + del self.__handlers[type_] except KeyError: pass diff --git a/vn.trader/eventType.py b/vn.trader/eventType.py index dd101f1a..4b52dcbc 100644 --- a/vn.trader/eventType.py +++ b/vn.trader/eventType.py @@ -24,6 +24,12 @@ EVENT_ACCOUNT = 'eAccount.' # 账户回报事件 EVENT_CONTRACT = 'eContract.' # 合约基础信息回报事件 EVENT_ERROR = 'eError.' # 错误回报事件 +# CTA模块相关 +EVENT_CTA_LOG = 'eCtaLog' # CTA相关的日志事件 + +# Wind接口相关 +EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件 + #---------------------------------------------------------------------- def test(): diff --git a/vn.trader/ltsDataType.py b/vn.trader/ltsDataType.py new file mode 100644 index 00000000..587eb8d7 --- /dev/null +++ b/vn.trader/ltsDataType.py @@ -0,0 +1,2181 @@ +# encoding: UTF-8 + +defineDict = {} +typedefDict = {} + +#////////////////////////////////////////////////////////////////////// +#@company shanghai liber information Technology Co.,Ltd +#@file SecurityFtdcUserApiDataType.h +#@brief 定义业务数据类型 +#////////////////////////////////////////////////////////////////////// + + + +#////////////////////////////////////////////////////////////////////// +#TFtdcErrorIDType是一个错误代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcErrorIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcErrorMsgType是一个错误信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcErrorMsgType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeIDType是一个交易所代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcExchangeIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeNameType是一个交易所名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcExchangeNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangePropertyType是一个交易所属性类型 +#////////////////////////////////////////////////////////////////////// +#正常 +defineDict["SECURITY_FTDC_EXP_Normal"] = '0' +#根据成交生成报单 +defineDict["SECURITY_FTDC_EXP_GenOrderByTrade"] = '1' + +typedefDict["TSecurityFtdcExchangePropertyType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeConnectStatusType是一个交易所连接状态类型 +#////////////////////////////////////////////////////////////////////// +#没有任何连接 +defineDict["SECURITY_FTDC_ECS_NoConnection"] = '1' +#已经发出合约查询请求 +defineDict["SECURITY_FTDC_ECS_QryInstrumentSent"] = '2' +#已经获取信息 +defineDict["SECURITY_FTDC_ECS_GotInformation"] = '9' + +typedefDict["TSecurityFtdcExchangeConnectStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDateType是一个日期类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcDateType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTimeType是一个时间类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTimeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentIDType是一个合约代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInstrumentIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductNameType是一个产品名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcProductNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductClassType是一个产品类型类型 +#////////////////////////////////////////////////////////////////////// +#期货 +defineDict["SECURITY_FTDC_PC_Futures"] = '1' +#期权 +defineDict["SECURITY_FTDC_PC_Options"] = '2' +#组合 +defineDict["SECURITY_FTDC_PC_Combination"] = '3' +#即期 +defineDict["SECURITY_FTDC_PC_Spot"] = '4' +#期转现 +defineDict["SECURITY_FTDC_PC_EFP"] = '5' +#证券A股 +defineDict["SECURITY_FTDC_PC_StockA"] = '6' +#证券B股 +defineDict["SECURITY_FTDC_PC_StockB"] = '7' +#ETF +defineDict["SECURITY_FTDC_PC_ETF"] = '8' +#ETF申赎 +defineDict["SECURITY_FTDC_PC_ETFPurRed"] = '9' + +typedefDict["TSecurityFtdcProductClassType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeMultipleType是一个合约数量乘数类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVolumeMultipleType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPriceType是一个价格类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcPriceType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeType是一个数量类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVolumeType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPositionTypeType是一个持仓类型类型 +#////////////////////////////////////////////////////////////////////// +#净持仓 +defineDict["SECURITY_FTDC_PT_Net"] = '1' +#综合持仓 +defineDict["SECURITY_FTDC_PT_Gross"] = '2' + +typedefDict["TSecurityFtdcPositionTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPositionDateTypeType是一个持仓日期类型类型 +#////////////////////////////////////////////////////////////////////// +#使用历史持仓 +defineDict["SECURITY_FTDC_PDT_UseHistory"] = '1' +#不使用历史持仓 +defineDict["SECURITY_FTDC_PDT_NoUseHistory"] = '2' + +typedefDict["TSecurityFtdcPositionDateTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeInstIDType是一个合约在交易所的代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcExchangeInstIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcYearType是一个年份类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcYearType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMonthType是一个月份类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMonthType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstLifePhaseType是一个合约生命周期状态类型 +#////////////////////////////////////////////////////////////////////// +#未上市 +defineDict["SECURITY_FTDC_IP_NotStart"] = '0' +#上市 +defineDict["SECURITY_FTDC_IP_Started"] = '1' +#停牌 +defineDict["SECURITY_FTDC_IP_Pause"] = '2' +#到期 +defineDict["SECURITY_FTDC_IP_Expired"] = '3' + +typedefDict["TSecurityFtdcInstLifePhaseType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBoolType是一个布尔型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBoolType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRightModelIDType是一个股票权限模版代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRightModelIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRightModelNameType是一个股票权限模版名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRightModelNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPosTradeTypeType是一个持仓交易类型类型 +#////////////////////////////////////////////////////////////////////// +#今日新增持仓能卖出 +defineDict["SECURITY_FTDC_PTT_CanSelTodayPos"] = '1' +#今日新增持仓不能卖出 +defineDict["SECURITY_FTDC_PTT_CannotSellTodayPos"] = '2' + +typedefDict["TSecurityFtdcPosTradeTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTraderIDType是一个交易所交易员代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTraderIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcParticipantIDType是一个会员代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcParticipantIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPasswordType是一个密码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcPasswordType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerIDType是一个经纪公司代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBrokerIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderLocalIDType是一个本地报单编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOrderLocalIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerAbbrType是一个经纪公司简称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBrokerAbbrType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerNameType是一个经纪公司名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBrokerNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInvestorIDType是一个投资者代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInvestorIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPartyNameType是一个参与人名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcPartyNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIdCardTypeType是一个证件类型类型 +#////////////////////////////////////////////////////////////////////// +#组织机构代码 +defineDict["SECURITY_FTDC_ICT_EID"] = '0' +#身份证 +defineDict["SECURITY_FTDC_ICT_IDCard"] = '1' +#军官证 +defineDict["SECURITY_FTDC_ICT_OfficerIDCard"] = '2' +#警官证 +defineDict["SECURITY_FTDC_ICT_PoliceIDCard"] = '3' +#士兵证 +defineDict["SECURITY_FTDC_ICT_SoldierIDCard"] = '4' +#户口簿 +defineDict["SECURITY_FTDC_ICT_HouseholdRegister"] = '5' +#护照 +defineDict["SECURITY_FTDC_ICT_Passport"] = '6' +#台胞证 +defineDict["SECURITY_FTDC_ICT_TaiwanCompatriotIDCard"] = '7' +#回乡证 +defineDict["SECURITY_FTDC_ICT_HomeComingCard"] = '8' +#营业执照号 +defineDict["SECURITY_FTDC_ICT_LicenseNo"] = '9' +#税务登记号 +defineDict["SECURITY_FTDC_ICT_TaxNo"] = 'A' +#其他证件 +defineDict["SECURITY_FTDC_ICT_OtherCard"] = 'x' + +typedefDict["TSecurityFtdcIdCardTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIdentifiedCardNoType是一个证件号码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcIdentifiedCardNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientIDType是一个交易编码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcClientIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAccountIDType是一个投资者帐号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcAccountIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientTypeType是一个交易编码类型类型 +#////////////////////////////////////////////////////////////////////// +#普通 +defineDict["SECURITY_FTDC_CLT_Normal"] = '1' +#信用交易 +defineDict["SECURITY_FTDC_CLT_Credit"] = '2' +#衍生品账户 +defineDict["SECURITY_FTDC_CLT_Derive"] = '3' +#其他类型 +defineDict["SECURITY_FTDC_CLT_Other"] = '4' + +typedefDict["TSecurityFtdcClientTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInvestorGroupNameType是一个投资者分组名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInvestorGroupNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserIDType是一个用户代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcUserIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserNameType是一个用户名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcUserNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFunctionCodeType是一个功能代码类型 +#////////////////////////////////////////////////////////////////////// +#强制用户登出 +defineDict["SECURITY_FTDC_FC_ForceUserLogout"] = '2' +#变更管理用户口令 +defineDict["SECURITY_FTDC_FC_UserPasswordUpdate"] = '3' +#变更经纪公司口令 +defineDict["SECURITY_FTDC_FC_BrokerPasswordUpdate"] = '4' +#变更投资者口令 +defineDict["SECURITY_FTDC_FC_InvestorPasswordUpdate"] = '5' +#报单插入 +defineDict["SECURITY_FTDC_FC_OrderInsert"] = '6' +#报单操作 +defineDict["SECURITY_FTDC_FC_OrderAction"] = '7' +#同步系统数据 +defineDict["SECURITY_FTDC_FC_SyncSystemData"] = '8' +#同步经纪公司数据 +defineDict["SECURITY_FTDC_FC_SyncBrokerData"] = '9' +#超级查询 +defineDict["SECURITY_FTDC_FC_SuperQuery"] = 'B' +#报单插入 +defineDict["SECURITY_FTDC_FC_ParkedOrderInsert"] = 'C' +#报单操作 +defineDict["SECURITY_FTDC_FC_ParkedOrderAction"] = 'D' +#同步动态令牌 +defineDict["SECURITY_FTDC_FC_SyncOTP"] = 'E' +#未知单操作 +defineDict["SECURITY_FTDC_FC_UnkownOrderAction"] = 'F' +#转托管 +defineDict["SECURITY_FTDC_FC_DepositoryTransfer"] = 'G' +#余券划转 +defineDict["SECURITY_FTDC_FC_ExcessStockTransfer"] = 'H' + +typedefDict["TSecurityFtdcFunctionCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserTypeType是一个用户类型类型 +#////////////////////////////////////////////////////////////////////// +#投资者 +defineDict["SECURITY_FTDC_UT_Investor"] = '0' +#操作员 +defineDict["SECURITY_FTDC_UT_Operator"] = '1' +#管理员 +defineDict["SECURITY_FTDC_UT_SuperUser"] = '2' + +typedefDict["TSecurityFtdcUserTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerFunctionCodeType是一个经纪公司功能代码类型 +#////////////////////////////////////////////////////////////////////// +#强制用户登出 +defineDict["SECURITY_FTDC_BFC_ForceUserLogout"] = '1' +#变更用户口令 +defineDict["SECURITY_FTDC_BFC_UserPasswordUpdate"] = '2' +#同步经纪公司数据 +defineDict["SECURITY_FTDC_BFC_SyncBrokerData"] = '3' +#报单插入 +defineDict["SECURITY_FTDC_BFC_OrderInsert"] = '5' +#报单操作 +defineDict["SECURITY_FTDC_BFC_OrderAction"] = '6' +#全部查询 +defineDict["SECURITY_FTDC_BFC_AllQuery"] = '7' +#未知单操作 +defineDict["SECURITY_FTDC_BFC_UnkownOrderAction"] = '8' +#转托管 +defineDict["SECURITY_FTDC_BFC_DepositoryTransfer"] = '9' +#余券划转 +defineDict["SECURITY_FTDC_BFC_ExcessStockTransfer"] = 'A' +#资金内转 +defineDict["SECURITY_FTDC_BFC_FundInterTransfer"] = 'B' +#系统功能:登入/登出/修改密码等 +defineDict["SECURITY_FTDC_BFC_log"] = 'a' +#基本查询:查询基础数据,如合约,交易所等常量 +defineDict["SECURITY_FTDC_BFC_BaseQry"] = 'b' +#交易查询:如查成交,委托 +defineDict["SECURITY_FTDC_BFC_TradeQry"] = 'c' +#交易功能:报单,撤单 +defineDict["SECURITY_FTDC_BFC_Trade"] = 'd' +#转账 +defineDict["SECURITY_FTDC_BFC_Virement"] = 'e' +#查询/管理:查询会话,踢人等 +defineDict["SECURITY_FTDC_BFC_Session"] = 'g' +#同步动态令牌 +defineDict["SECURITY_FTDC_BFC_SyncOTP"] = 'E' + +typedefDict["TSecurityFtdcBrokerFunctionCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCurrencyCodeType是一个币种类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCurrencyCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMoneyType是一个资金类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMoneyType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRatioType是一个比率类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRatioType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAccountTypeType是一个账户类型类型 +#////////////////////////////////////////////////////////////////////// +#普通账户 +defineDict["SECURITY_FTDC_AcT_Normal"] = '1' +#信用账户 +defineDict["SECURITY_FTDC_AcT_Credit"] = '2' +#衍生品账户 +defineDict["SECURITY_FTDC_AcT_Derive"] = '3' +#其他类型 +defineDict["SECURITY_FTDC_AcT_Other"] = '4' + +typedefDict["TSecurityFtdcAccountTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDepartmentRangeType是一个投资者范围类型 +#////////////////////////////////////////////////////////////////////// +#所有 +defineDict["SECURITY_FTDC_DR_All"] = '1' +#组织架构 +defineDict["SECURITY_FTDC_DR_Group"] = '2' +#单一投资者 +defineDict["SECURITY_FTDC_DR_Single"] = '3' + +typedefDict["TSecurityFtdcDepartmentRangeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserRightTypeType是一个客户权限类型类型 +#////////////////////////////////////////////////////////////////////// +#登录 +defineDict["SECURITY_FTDC_URT_Logon"] = '1' +#银期转帐 +defineDict["SECURITY_FTDC_URT_Transfer"] = '2' +#邮寄结算单 +defineDict["SECURITY_FTDC_URT_EMail"] = '3' +#传真结算单 +defineDict["SECURITY_FTDC_URT_Fax"] = '4' +#条件单 +defineDict["SECURITY_FTDC_URT_ConditionOrder"] = '5' + +typedefDict["TSecurityFtdcUserRightTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductInfoType是一个产品信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcProductInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAuthCodeType是一个客户端认证码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcAuthCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLargeVolumeType是一个大额数量类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcLargeVolumeType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMillisecType是一个时间(毫秒)类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMillisecType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcHedgeFlagType是一个投机套保标志类型 +#////////////////////////////////////////////////////////////////////// +#投机 +defineDict["SECURITY_FTDC_HF_Speculation"] = '1' +#套保 +defineDict["SECURITY_FTDC_HF_Hedge"] = '3' + +typedefDict["TSecurityFtdcHedgeFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDirectionType是一个买卖方向类型 +#////////////////////////////////////////////////////////////////////// +#买 +defineDict["SECURITY_FTDC_D_Buy"] = '0' +#卖 +defineDict["SECURITY_FTDC_D_Sell"] = '1' +#ETF申购 +defineDict["SECURITY_FTDC_D_ETFPur"] = '2' +#ETF赎回 +defineDict["SECURITY_FTDC_D_ETFRed"] = '3' +#现金替代,只用作回报 +defineDict["SECURITY_FTDC_D_CashIn"] = '4' +#债券入库 +defineDict["SECURITY_FTDC_D_PledgeBondIn"] = '5' +#债券出库 +defineDict["SECURITY_FTDC_D_PledgeBondOut"] = '6' +#配股 +defineDict["SECURITY_FTDC_D_Rationed"] = '7' +#转托管 +defineDict["SECURITY_FTDC_D_DepositoryTransfer"] = '8' +#信用账户配股 +defineDict["SECURITY_FTDC_D_CreditRationed"] = '9' +#担保品买入 +defineDict["SECURITY_FTDC_D_BuyCollateral"] = 'A' +#担保品卖出 +defineDict["SECURITY_FTDC_D_SellCollateral"] = 'B' +#担保品转入 +defineDict["SECURITY_FTDC_D_CollateralTransferIn"] = 'C' +#担保品转出 +defineDict["SECURITY_FTDC_D_CollateralTransferOut"] = 'D' +#融资买入 +defineDict["SECURITY_FTDC_D_MarginTrade"] = 'E' +#融券卖出 +defineDict["SECURITY_FTDC_D_ShortSell"] = 'F' +#卖券还款 +defineDict["SECURITY_FTDC_D_RepayMargin"] = 'G' +#买券还券 +defineDict["SECURITY_FTDC_D_RepayStock"] = 'H' +#直接还款 +defineDict["SECURITY_FTDC_D_DirectRepayMargin"] = 'I' +#直接还券 +defineDict["SECURITY_FTDC_D_DirectRepayStock"] = 'J' +#余券划转 +defineDict["SECURITY_FTDC_D_ExcessStockTransfer"] = 'K' +#OF申购 +defineDict["SECURITY_FTDC_D_OFPur"] = 'L' +#OF赎回 +defineDict["SECURITY_FTDC_D_OFRed"] = 'M' +#SF拆分 +defineDict["SECURITY_FTDC_D_SFSplit"] = 'N' +#SF合并 +defineDict["SECURITY_FTDC_D_SFMerge"] = 'O' +#备兑 +defineDict["SECURITY_FTDC_D_Covered"] = 'P' +#证券冻结(开)/解冻(平) +defineDict["SECURITY_FTDC_D_Freeze"] = 'Q' +#行权 +defineDict["SECURITY_FTDC_D_Execute"] = 'R' +#CB回售 +defineDict["SECURITY_FTDC_D_CBRed"] = 'S' +#CB转股 +defineDict["SECURITY_FTDC_D_CBConv"] = 'T' +#OF认购 +defineDict["SECURITY_FTDC_D_OFSub"] = 'U' + +typedefDict["TSecurityFtdcDirectionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeIDType是一个成交编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeTypeType是一个成交类型类型 +#////////////////////////////////////////////////////////////////////// +#普通成交 +defineDict["SECURITY_FTDC_TRDT_Common"] = '0' +#期权执行 +defineDict["SECURITY_FTDC_TRDT_OptionsExecution"] = '1' +#OTC成交 +defineDict["SECURITY_FTDC_TRDT_OTC"] = '2' +#期转现衍生成交 +defineDict["SECURITY_FTDC_TRDT_EFPDerived"] = '3' +#组合衍生成交 +defineDict["SECURITY_FTDC_TRDT_CombinationDerived"] = '4' +#ETF申购 +defineDict["SECURITY_FTDC_TRDT_EFTPurchase"] = '5' +#ETF赎回 +defineDict["SECURITY_FTDC_TRDT_EFTRedem"] = '6' + +typedefDict["TSecurityFtdcTradeTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCreationredemptionStatusType是一个基金当天申购赎回状态类型 +#////////////////////////////////////////////////////////////////////// +#不允许申购赎回 +defineDict["SECURITY_FTDC_CDS_Forbidden"] = '0' +#表示允许申购和赎回 +defineDict["SECURITY_FTDC_CDS_Allow"] = '1' +#允许申购、不允许赎回 +defineDict["SECURITY_FTDC_CDS_OnlyPurchase"] = '2' +#不允许申购、允许赎回 +defineDict["SECURITY_FTDC_CDS_OnlyRedeem"] = '3' + +typedefDict["TSecurityFtdcCreationredemptionStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcETFCurrenceReplaceStatusType是一个ETF现金替代标志类型 +#////////////////////////////////////////////////////////////////////// +#禁止现金替代 +defineDict["SECURITY_FTDC_ETFCRS_Forbidden"] = '0' +#可以现金替代 +defineDict["SECURITY_FTDC_ETFCRS_Allow"] = '1' +#必须现金替代 +defineDict["SECURITY_FTDC_ETFCRS_Force"] = '2' +#跨市场股票退补现金替代 +defineDict["SECURITY_FTDC_ETFCRS_CrossMarketComp"] = '3' +#跨市场必须现金替代 +defineDict["SECURITY_FTDC_ETFCRS_CrossMarketFroce"] = '4' + +typedefDict["TSecurityFtdcETFCurrenceReplaceStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInterestType是一个利息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInterestType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRepurchaseMaxTimesType是一个正回购放大倍数类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRepurchaseMaxTimesType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCapitalStockTypeType是一个股本类型类型 +#////////////////////////////////////////////////////////////////////// +#总通股本 +defineDict["SECURITY_FTDC_CPTSTOCK_TOTALSTOCK"] = '1' +#流通股本 +defineDict["SECURITY_FTDC_CPTSTOCK_CIRCULATION"] = '2' + +typedefDict["TSecurityFtdcCapitalStockTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMarginPriceTypeType是一个保证金价格类型类型 +#////////////////////////////////////////////////////////////////////// +#昨结算价 +defineDict["SECURITY_FTDC_MPT_PreSettlementPrice"] = '1' +#最新价 +defineDict["SECURITY_FTDC_MPT_SettlementPrice"] = '2' +#成交均价 +defineDict["SECURITY_FTDC_MPT_AveragePrice"] = '3' +#开仓价 +defineDict["SECURITY_FTDC_MPT_OpenPrice"] = '4' + +typedefDict["TSecurityFtdcMarginPriceTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAlgorithmType是一个盈亏算法类型 +#////////////////////////////////////////////////////////////////////// +#浮盈浮亏都计算 +defineDict["SECURITY_FTDC_AG_All"] = '1' +#浮盈不计,浮亏计 +defineDict["SECURITY_FTDC_AG_OnlyLost"] = '2' +#浮盈计,浮亏不计 +defineDict["SECURITY_FTDC_AG_OnlyGain"] = '3' +#浮盈浮亏都不计算 +defineDict["SECURITY_FTDC_AG_None"] = '4' + +typedefDict["TSecurityFtdcAlgorithmType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIncludeCloseProfitType是一个是否包含平仓盈利类型 +#////////////////////////////////////////////////////////////////////// +#包含平仓盈利 +defineDict["SECURITY_FTDC_ICP_Include"] = '0' +#不包含平仓盈利 +defineDict["SECURITY_FTDC_ICP_NotInclude"] = '2' + +typedefDict["TSecurityFtdcIncludeCloseProfitType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAllWithoutTradeType是一个是否受可提比例限制类型 +#////////////////////////////////////////////////////////////////////// +#不受可提比例限制 +defineDict["SECURITY_FTDC_AWT_Enable"] = '0' +#受可提比例限制 +defineDict["SECURITY_FTDC_AWT_Disable"] = '2' +#无仓不受可提比例限制 +defineDict["SECURITY_FTDC_AWT_NoHoldEnable"] = '3' + +typedefDict["TSecurityFtdcAllWithoutTradeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcHandlePositionAlgoIDType是一个持仓处理算法编号类型 +#////////////////////////////////////////////////////////////////////// +#基本 +defineDict["SECURITY_FTDC_HPA_Base"] = '1' +#非交易 +defineDict["SECURITY_FTDC_HPA_NoneTrade"] = '4' +#证券 +defineDict["SECURITY_FTDC_HPA_Stock"] = '5' + +typedefDict["TSecurityFtdcHandlePositionAlgoIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeParamIDType是一个交易系统参数代码类型 +#////////////////////////////////////////////////////////////////////// +#系统加密算法 +defineDict["SECURITY_FTDC_TPID_EncryptionStandard"] = 'E' +#用户最大会话数 +defineDict["SECURITY_FTDC_TPID_SingleUserSessionMaxNum"] = 'S' +#最大连续登录失败数 +defineDict["SECURITY_FTDC_TPID_LoginFailMaxNum"] = 'L' +#是否强制认证 +defineDict["SECURITY_FTDC_TPID_IsAuthForce"] = 'A' +#是否生成用户事件 +defineDict["SECURITY_FTDC_TPID_GenUserEvent"] = 'G' +#起始报单本地编号 +defineDict["SECURITY_FTDC_TPID_StartOrderLocalID"] = 'O' +#融资融券买券还券算法 +defineDict["SECURITY_FTDC_TPID_RepayStockAlgo"] = 'R' +#衍生品账户资金提取线 +defineDict["SECURITY_FTDC_TPID_DeriveWithdrawRatio"] = 'D' +#期权行权冻结可用起始时间 +defineDict["SECURITY_FTDC_TPID_ExecuteStartTime"] = 'T' + +typedefDict["TSecurityFtdcTradeParamIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSettlementParamValueType是一个参数代码值类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSettlementParamValueType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMemoType是一个备注类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMemoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPriorityType是一个优先级类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcPriorityType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderRefType是一个报单引用类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOrderRefType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMarketIDType是一个市场代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMarketIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMacAddressType是一个Mac地址类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcMacAddressType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcHDSerialNumberType是一个硬盘序列号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcHDSerialNumberType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentNameType是一个合约名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInstrumentNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderSysIDType是一个报单编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOrderSysIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIPAddressType是一个IP地址类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcIPAddressType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIPPortType是一个IP端口类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcIPPortType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProtocolInfoType是一个协议信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcProtocolInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDepositSeqNoType是一个出入金流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcDepositSeqNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSystemNameType是一个系统名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSystemNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInvestorRangeType是一个投资者范围类型 +#////////////////////////////////////////////////////////////////////// +#所有 +defineDict["SECURITY_FTDC_IR_All"] = '1' +#投资者组 +defineDict["SECURITY_FTDC_IR_Group"] = '2' +#单一投资者 +defineDict["SECURITY_FTDC_IR_Single"] = '3' + +typedefDict["TSecurityFtdcInvestorRangeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDataSyncStatusType是一个数据同步状态类型 +#////////////////////////////////////////////////////////////////////// +#未同步 +defineDict["SECURITY_FTDC_DS_Asynchronous"] = '1' +#同步中 +defineDict["SECURITY_FTDC_DS_Synchronizing"] = '2' +#已同步 +defineDict["SECURITY_FTDC_DS_Synchronized"] = '3' + +typedefDict["TSecurityFtdcDataSyncStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTraderConnectStatusType是一个交易所交易员连接状态类型 +#////////////////////////////////////////////////////////////////////// +#没有任何连接 +defineDict["SECURITY_FTDC_TCS_NotConnected"] = '1' +#已经连接 +defineDict["SECURITY_FTDC_TCS_Connected"] = '2' +#已经发出合约查询请求 +defineDict["SECURITY_FTDC_TCS_QryInstrumentSent"] = '3' +#订阅私有流 +defineDict["SECURITY_FTDC_TCS_SubPrivateFlow"] = '4' + +typedefDict["TSecurityFtdcTraderConnectStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderActionStatusType是一个报单操作状态类型 +#////////////////////////////////////////////////////////////////////// +#已经提交 +defineDict["SECURITY_FTDC_OAS_Submitted"] = 'a' +#已经接受 +defineDict["SECURITY_FTDC_OAS_Accepted"] = 'b' +#已经被拒绝 +defineDict["SECURITY_FTDC_OAS_Rejected"] = 'c' + +typedefDict["TSecurityFtdcOrderActionStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderStatusType是一个报单状态类型 +#////////////////////////////////////////////////////////////////////// +#全部成交 +defineDict["SECURITY_FTDC_OST_AllTraded"] = '0' +#部分成交还在队列中 +defineDict["SECURITY_FTDC_OST_PartTradedQueueing"] = '1' +#部分成交不在队列中 +defineDict["SECURITY_FTDC_OST_PartTradedNotQueueing"] = '2' +#未成交还在队列中 +defineDict["SECURITY_FTDC_OST_NoTradeQueueing"] = '3' +#未成交不在队列中 +defineDict["SECURITY_FTDC_OST_NoTradeNotQueueing"] = '4' +#撤单 +defineDict["SECURITY_FTDC_OST_Canceled"] = '5' +#未知 +defineDict["SECURITY_FTDC_OST_Unknown"] = 'a' +#尚未触发 +defineDict["SECURITY_FTDC_OST_NotTouched"] = 'b' +#已触发 +defineDict["SECURITY_FTDC_OST_Touched"] = 'c' + +typedefDict["TSecurityFtdcOrderStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderSubmitStatusType是一个报单提交状态类型 +#////////////////////////////////////////////////////////////////////// +#已经提交 +defineDict["SECURITY_FTDC_OSS_InsertSubmitted"] = '0' +#撤单已经提交 +defineDict["SECURITY_FTDC_OSS_CancelSubmitted"] = '1' +#修改已经提交 +defineDict["SECURITY_FTDC_OSS_ModifySubmitted"] = '2' +#已经接受 +defineDict["SECURITY_FTDC_OSS_Accepted"] = '3' +#报单已经被拒绝 +defineDict["SECURITY_FTDC_OSS_InsertRejected"] = '4' +#撤单已经被拒绝 +defineDict["SECURITY_FTDC_OSS_CancelRejected"] = '5' +#改单已经被拒绝 +defineDict["SECURITY_FTDC_OSS_ModifyRejected"] = '6' + +typedefDict["TSecurityFtdcOrderSubmitStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPositionDateType是一个持仓日期类型 +#////////////////////////////////////////////////////////////////////// +#今日持仓 +defineDict["SECURITY_FTDC_PSD_Today"] = '1' +#历史持仓 +defineDict["SECURITY_FTDC_PSD_History"] = '2' + +typedefDict["TSecurityFtdcPositionDateType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingRoleType是一个交易角色类型 +#////////////////////////////////////////////////////////////////////// +#代理 +defineDict["SECURITY_FTDC_ER_Broker"] = '1' +#自营 +defineDict["SECURITY_FTDC_ER_Host"] = '2' +#做市商 +defineDict["SECURITY_FTDC_ER_Maker"] = '3' + +typedefDict["TSecurityFtdcTradingRoleType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPosiDirectionType是一个持仓多空方向类型 +#////////////////////////////////////////////////////////////////////// +#净 +defineDict["SECURITY_FTDC_PD_Net"] = '1' +#多头 +defineDict["SECURITY_FTDC_PD_Long"] = '2' +#空头 +defineDict["SECURITY_FTDC_PD_Short"] = '3' +#备兑 +defineDict["SECURITY_FTDC_PD_Covered"] = '4' + +typedefDict["TSecurityFtdcPosiDirectionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderPriceTypeType是一个报单价格条件类型 +#////////////////////////////////////////////////////////////////////// +#即时成交剩余撤销市价单 +defineDict["SECURITY_FTDC_OPT_AnyPrice"] = '1' +#限价 +defineDict["SECURITY_FTDC_OPT_LimitPrice"] = '2' +#最优五档即时成交剩余撤销市价单 +defineDict["SECURITY_FTDC_OPT_BestPrice"] = '3' +#最优五档即时成交剩余转限价市价单 +defineDict["SECURITY_FTDC_OPT_BestLimitPrice"] = '4' +#全部成交或撤销市价单 +defineDict["SECURITY_FTDC_OPT_AllPrice"] = '5' +#本方最优价格市价单 +defineDict["SECURITY_FTDC_OPT_ForwardBestPrice"] = '6' +#对方最优价格市价单 +defineDict["SECURITY_FTDC_OPT_ReverseBestPrice"] = '7' +#即时成交剩余转限价市价单 +defineDict["SECURITY_FTDC_OPT_Any2LimitPrice"] = '8' +#全部成交或撤销限价单 +defineDict["SECURITY_FTDC_OPT_AllLimitPrice"] = '9' +#激活A股网络密码服务代码 +defineDict["SECURITY_FTDC_OPT_ActiveANetPassSvrCode"] = 'G' +#注销A股网络密码服务代码 +defineDict["SECURITY_FTDC_OPT_InactiveANetPassSvrCode"] = 'H' +#激活B股网络密码服务代码 +defineDict["SECURITY_FTDC_OPT_ActiveBNetPassSvrCode"] = 'I' +#注销B股网络密码服务代码 +defineDict["SECURITY_FTDC_OPT_InactiveBNetPassSvrCode"] = 'J' +#回购注销 +defineDict["SECURITY_FTDC_OPT_Repurchase"] = 'K' +#指定撤销 +defineDict["SECURITY_FTDC_OPT_DesignatedCancel"] = 'L' +#指定登记 +defineDict["SECURITY_FTDC_OPT_Designated"] = 'M' +#证券参与申购 +defineDict["SECURITY_FTDC_OPT_SubscribingShares"] = 'N' +#证券参与配股 +defineDict["SECURITY_FTDC_OPT_Split"] = 'O' +#要约收购登记 +defineDict["SECURITY_FTDC_OPT_TenderOffer"] = 'P' +#要约收购撤销 +defineDict["SECURITY_FTDC_OPT_TenderOfferCancel"] = 'Q' +#证券投票 +defineDict["SECURITY_FTDC_OPT_Ballot"] = 'R' +#可转债转换登记 +defineDict["SECURITY_FTDC_OPT_ConvertibleBondsConvet"] = 'S' +#可转债回售登记 +defineDict["SECURITY_FTDC_OPT_ConvertibleBondsRepurchase"] = 'T' +#权证行权 +defineDict["SECURITY_FTDC_OPT_Exercise"] = 'U' +#开放式基金申购 +defineDict["SECURITY_FTDC_OPT_PurchasingFunds"] = 'V' +#开放式基金赎回 +defineDict["SECURITY_FTDC_OPT_RedemingFunds"] = 'W' +#开放式基金认购 +defineDict["SECURITY_FTDC_OPT_SubscribingFunds"] = 'X' +#开放式基金转托管转出 +defineDict["SECURITY_FTDC_OPT_LOFIssue"] = 'Y' +#开放式基金设置分红方式 +defineDict["SECURITY_FTDC_OPT_LOFSetBonusType"] = 'Z' +#开放式基金转换为其他基金 +defineDict["SECURITY_FTDC_OPT_LOFConvert"] = 'a' +#债券入库 +defineDict["SECURITY_FTDC_OPT_DebentureStockIn"] = 'b' +#债券出库 +defineDict["SECURITY_FTDC_OPT_DebentureStockOut"] = 'c' +#ETF申购 +defineDict["SECURITY_FTDC_OPT_PurchasesETF"] = 'd' +#ETF赎回 +defineDict["SECURITY_FTDC_OPT_RedeemETF"] = 'e' + +typedefDict["TSecurityFtdcOrderPriceTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOffsetFlagType是一个开平标志类型 +#////////////////////////////////////////////////////////////////////// +#开仓 +defineDict["SECURITY_FTDC_OF_Open"] = '0' +#平仓 +defineDict["SECURITY_FTDC_OF_Close"] = '1' +#强平 +defineDict["SECURITY_FTDC_OF_ForceClose"] = '2' +#平今 +defineDict["SECURITY_FTDC_OF_CloseToday"] = '3' +#平昨 +defineDict["SECURITY_FTDC_OF_CloseYesterday"] = '4' +#强减 +defineDict["SECURITY_FTDC_OF_ForceOff"] = '5' +#本地强平 +defineDict["SECURITY_FTDC_OF_LocalForceClose"] = '6' + +typedefDict["TSecurityFtdcOffsetFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcForceCloseReasonType是一个强平原因类型 +#////////////////////////////////////////////////////////////////////// +#非强平 +defineDict["SECURITY_FTDC_FCC_NotForceClose"] = '0' +#资金不足 +defineDict["SECURITY_FTDC_FCC_LackDeposit"] = '1' +#客户超仓 +defineDict["SECURITY_FTDC_FCC_ClientOverPositionLimit"] = '2' +#会员超仓 +defineDict["SECURITY_FTDC_FCC_MemberOverPositionLimit"] = '3' +#持仓非整数倍 +defineDict["SECURITY_FTDC_FCC_NotMultiple"] = '4' +#违规 +defineDict["SECURITY_FTDC_FCC_Violation"] = '5' +#其它 +defineDict["SECURITY_FTDC_FCC_Other"] = '6' +#自然人临近交割 +defineDict["SECURITY_FTDC_FCC_PersonDeliv"] = '7' + +typedefDict["TSecurityFtdcForceCloseReasonType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderTypeType是一个报单类型类型 +#////////////////////////////////////////////////////////////////////// +#正常 +defineDict["SECURITY_FTDC_ORDT_Normal"] = '0' +#报价衍生 +defineDict["SECURITY_FTDC_ORDT_DeriveFromQuote"] = '1' +#组合衍生 +defineDict["SECURITY_FTDC_ORDT_DeriveFromCombination"] = '2' +#组合报单 +defineDict["SECURITY_FTDC_ORDT_Combination"] = '3' +#条件单 +defineDict["SECURITY_FTDC_ORDT_ConditionalOrder"] = '4' +#互换单 +defineDict["SECURITY_FTDC_ORDT_Swap"] = '5' + +typedefDict["TSecurityFtdcOrderTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTimeConditionType是一个有效期类型类型 +#////////////////////////////////////////////////////////////////////// +#立即完成,否则撤销 +defineDict["SECURITY_FTDC_TC_IOC"] = '1' +#本节有效 +defineDict["SECURITY_FTDC_TC_GFS"] = '2' +#当日有效 +defineDict["SECURITY_FTDC_TC_GFD"] = '3' +#指定日期前有效 +defineDict["SECURITY_FTDC_TC_GTD"] = '4' +#撤销前有效 +defineDict["SECURITY_FTDC_TC_GTC"] = '5' +#集合竞价有效 +defineDict["SECURITY_FTDC_TC_GFA"] = '6' + +typedefDict["TSecurityFtdcTimeConditionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeConditionType是一个成交量类型类型 +#////////////////////////////////////////////////////////////////////// +#任何数量 +defineDict["SECURITY_FTDC_VC_AV"] = '1' +#最小数量 +defineDict["SECURITY_FTDC_VC_MV"] = '2' +#全部数量 +defineDict["SECURITY_FTDC_VC_CV"] = '3' + +typedefDict["TSecurityFtdcVolumeConditionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcContingentConditionType是一个触发条件类型 +#////////////////////////////////////////////////////////////////////// +#立即 +defineDict["SECURITY_FTDC_CC_Immediately"] = '1' +#止损 +defineDict["SECURITY_FTDC_CC_Touch"] = '2' +#止赢 +defineDict["SECURITY_FTDC_CC_TouchProfit"] = '3' +#预埋单 +defineDict["SECURITY_FTDC_CC_ParkedOrder"] = '4' +#最新价大于条件价 +defineDict["SECURITY_FTDC_CC_LastPriceGreaterThanStopPrice"] = '5' +#最新价大于等于条件价 +defineDict["SECURITY_FTDC_CC_LastPriceGreaterEqualStopPrice"] = '6' +#最新价小于条件价 +defineDict["SECURITY_FTDC_CC_LastPriceLesserThanStopPrice"] = '7' +#最新价小于等于条件价 +defineDict["SECURITY_FTDC_CC_LastPriceLesserEqualStopPrice"] = '8' +#卖一价大于条件价 +defineDict["SECURITY_FTDC_CC_AskPriceGreaterThanStopPrice"] = '9' +#卖一价大于等于条件价 +defineDict["SECURITY_FTDC_CC_AskPriceGreaterEqualStopPrice"] = 'A' +#卖一价小于条件价 +defineDict["SECURITY_FTDC_CC_AskPriceLesserThanStopPrice"] = 'B' +#卖一价小于等于条件价 +defineDict["SECURITY_FTDC_CC_AskPriceLesserEqualStopPrice"] = 'C' +#买一价大于条件价 +defineDict["SECURITY_FTDC_CC_BidPriceGreaterThanStopPrice"] = 'D' +#买一价大于等于条件价 +defineDict["SECURITY_FTDC_CC_BidPriceGreaterEqualStopPrice"] = 'E' +#买一价小于条件价 +defineDict["SECURITY_FTDC_CC_BidPriceLesserThanStopPrice"] = 'F' +#买一价小于等于条件价 +defineDict["SECURITY_FTDC_CC_BidPriceLesserEqualStopPrice"] = 'H' + +typedefDict["TSecurityFtdcContingentConditionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcActionFlagType是一个操作标志类型 +#////////////////////////////////////////////////////////////////////// +#删除 +defineDict["SECURITY_FTDC_AF_Delete"] = '0' +#修改 +defineDict["SECURITY_FTDC_AF_Modify"] = '3' + +typedefDict["TSecurityFtdcActionFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingRightType是一个交易权限类型 +#////////////////////////////////////////////////////////////////////// +#可以交易 +defineDict["SECURITY_FTDC_TR_Allow"] = '0' +#不能交易 +defineDict["SECURITY_FTDC_TR_Forbidden"] = '2' + +typedefDict["TSecurityFtdcTradingRightType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderSourceType是一个报单来源类型 +#////////////////////////////////////////////////////////////////////// +#来自参与者 +defineDict["SECURITY_FTDC_OSRC_Participant"] = '0' +#来自管理员 +defineDict["SECURITY_FTDC_OSRC_Administrator"] = '1' + +typedefDict["TSecurityFtdcOrderSourceType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPriceSourceType是一个成交价来源类型 +#////////////////////////////////////////////////////////////////////// +#前成交价 +defineDict["SECURITY_FTDC_PSRC_LastPrice"] = '0' +#买委托价 +defineDict["SECURITY_FTDC_PSRC_Buy"] = '1' +#卖委托价 +defineDict["SECURITY_FTDC_PSRC_Sell"] = '2' + +typedefDict["TSecurityFtdcPriceSourceType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderActionRefType是一个报单操作引用类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOrderActionRefType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFrontIDType是一个前置编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFrontIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSessionIDType是一个会话编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSessionIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstallIDType是一个安装编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcInstallIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSequenceNoType是一个序号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSequenceNoType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRequestIDType是一个请求编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRequestIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCombOffsetFlagType是一个组合开平标志类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCombOffsetFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCombHedgeFlagType是一个组合投机套保标志类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCombHedgeFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSequenceSeriesType是一个序列系列号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSequenceSeriesType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCommPhaseNoType是一个通讯时段编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCommPhaseNoType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserEventTypeType是一个用户事件类型类型 +#////////////////////////////////////////////////////////////////////// +#登录 +defineDict["SECURITY_FTDC_UET_Login"] = '1' +#登出 +defineDict["SECURITY_FTDC_UET_Logout"] = '2' +#交易成功 +defineDict["SECURITY_FTDC_UET_Trading"] = '3' +#交易失败 +defineDict["SECURITY_FTDC_UET_TradingError"] = '4' +#修改密码 +defineDict["SECURITY_FTDC_UET_UpdatePassword"] = '5' +#客户端认证 +defineDict["SECURITY_FTDC_UET_Authenticate"] = '6' +#其他 +defineDict["SECURITY_FTDC_UET_Other"] = '9' + +typedefDict["TSecurityFtdcUserEventTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserEventInfoType是一个用户事件信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcUserEventInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOTPTypeType是一个动态令牌类型类型 +#////////////////////////////////////////////////////////////////////// +#无动态令牌 +defineDict["SECURITY_FTDC_OTP_NONE"] = '0' +#时间令牌 +defineDict["SECURITY_FTDC_OTP_TOTP"] = '1' + +typedefDict["TSecurityFtdcOTPTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeSourceType是一个成交来源类型 +#////////////////////////////////////////////////////////////////////// +#来自交易所普通回报 +defineDict["SECURITY_FTDC_TSRC_NORMAL"] = '0' +#来自查询 +defineDict["SECURITY_FTDC_TSRC_QUERY"] = '1' + +typedefDict["TSecurityFtdcTradeSourceType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBranchIDType是一个营业部编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBranchIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcStockPriceType是一个证券交易价格类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcStockPriceType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRightModelIDType是一个股票权限模版代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRightModelIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSerialNumberType是一个序列号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSerialNumberType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentRangeType是一个股票权限分类类型 +#////////////////////////////////////////////////////////////////////// +#所有 +defineDict["SECURITY_FTDC_INR_All"] = '1' +#产品 +defineDict["SECURITY_FTDC_INR_Product"] = '2' +#股票权限模版 +defineDict["SECURITY_FTDC_INR_Model"] = '3' +#股票 +defineDict["SECURITY_FTDC_INR_Stock"] = '4' +#市场 +defineDict["SECURITY_FTDC_INR_Market"] = '5' + +typedefDict["TSecurityFtdcInstrumentRangeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBusinessUnitType是一个业务单元类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBusinessUnitType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOTPVendorsIDType是一个动态令牌提供商类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOTPVendorsIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLastDriftType是一个上次OTP漂移值类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcLastDriftType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLastSuccessType是一个上次OTP成功值类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcLastSuccessType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAuthKeyType是一个令牌密钥类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcAuthKeyType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserSessionHashType是一个用户会话Hash值类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcUserSessionHashType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcStockTradeTypeType是一个证券交易类型类型 +#////////////////////////////////////////////////////////////////////// +#可交易证券 +defineDict["SECURITY_FTDC_STT_Stock"] = '0' +#买入网络密码服务 +defineDict["SECURITY_FTDC_STT_BuyNetService"] = '1' +#回购注销 +defineDict["SECURITY_FTDC_STT_CancelRepurchase"] = '2' +#指定撤销 +defineDict["SECURITY_FTDC_STT_CancelRegister"] = '3' +#指定登记 +defineDict["SECURITY_FTDC_STT_Register"] = '4' +#买入发行申购 +defineDict["SECURITY_FTDC_STT_PurchaseIssue"] = '5' +#卖出配股 +defineDict["SECURITY_FTDC_STT_Allotment"] = '6' +#卖出要约收购 +defineDict["SECURITY_FTDC_STT_SellTender"] = '7' +#买入要约收购 +defineDict["SECURITY_FTDC_STT_BuyTender"] = '8' +#网上投票 +defineDict["SECURITY_FTDC_STT_NetVote"] = '9' +#卖出可转债回售 +defineDict["SECURITY_FTDC_STT_SellConvertibleBonds"] = 'a' +#权证行权代码 +defineDict["SECURITY_FTDC_STT_OptionExecute"] = 'b' +#开放式基金申购 +defineDict["SECURITY_FTDC_STT_PurchaseOF"] = 'c' +#开放式基金赎回 +defineDict["SECURITY_FTDC_STT_RedeemOF"] = 'd' +#开放式基金认购 +defineDict["SECURITY_FTDC_STT_SubscribeOF"] = 'e' +#开放式基金转托管转出 +defineDict["SECURITY_FTDC_STT_OFCustodianTranfer"] = 'f' +#开放式基金分红设置 +defineDict["SECURITY_FTDC_STT_OFDividendConfig"] = 'g' +#开放式基金转成其他基金 +defineDict["SECURITY_FTDC_STT_OFTransfer"] = 'h' +#债券入库 +defineDict["SECURITY_FTDC_STT_BondsIn"] = 'i' +#债券出库 +defineDict["SECURITY_FTDC_STT_BondsOut"] = 'j' +#EFT申购 +defineDict["SECURITY_FTDC_STT_PurchaseETF"] = 'k' +#EFT赎回 +defineDict["SECURITY_FTDC_STT_RedeemETF"] = 'l' +#可转债回售登记 +defineDict["SECURITY_FTDC_STT_ConvertibleRegister"] = 'm' + +typedefDict["TSecurityFtdcStockTradeTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcHandleTradingAccountAlgoIDType是一个资金处理算法编号类型 +#////////////////////////////////////////////////////////////////////// +#基本 +defineDict["SECURITY_FTDC_HTAA_Base"] = '1' + +typedefDict["TSecurityFtdcHandleTradingAccountAlgoIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcStockWthType是一个股票使用流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcStockWthType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcStockSeqType是一个股票使用流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcStockSeqType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcWTFSType是一个委托方式类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcWTFSType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcWTLBType是一个委托类别类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcWTLBType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcWTRQType是一个委托日期类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcWTRQType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcINTEGERType是一个一般整型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcINTEGERType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcINT3Type是一个三位数整型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcINT3Type"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcINT6Type是一个六位数整型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcINT6Type"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcINT12Type是一个十二位数整型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcINT12Type"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR1Type是一个一字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR1Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR2Type是一个二字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR2Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR3Type是一个三字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR3Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR4Type是一个四字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR4Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR5Type是一个五字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR5Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR6Type是一个六字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR6Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR8Type是一个八字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR8Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR10Type是一个十字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR10Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR11Type是一个十一字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR11Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR12Type是一个十二字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR12Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR13Type是一个十三字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR13Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR14Type是一个十四字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR14Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR16Type是一个十六字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR16Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR19Type是一个十九字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR19Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR20Type是一个二十字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR20Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR21Type是一个二十一字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR21Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR23Type是一个二十三字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR23Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR30Type是一个三十字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR30Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR32Type是一个三十二字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR32Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR50Type是一个五十字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR50Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR64Type是一个六十四字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR64Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCHAR65Type是一个六十五字节CHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCHAR65Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR4Type是一个四字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR4Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR6Type是一个六字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR6Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR8Type是一个八字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR8Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR10Type是一个十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR10Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR12Type是一个十二字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR12Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR16Type是一个十六字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR16Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR20Type是一个二十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR20Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR30Type是一个三十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR30Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR50Type是一个五十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR50Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR60Type是一个六十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR60Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR65Type是一个六十五字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR65Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR80Type是一个八十字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR80Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR84Type是一个八十四字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR84Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR255Type是一个二五五字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR255Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVCHAR1024Type是一个一零二四字节VCHAR类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcVCHAR1024Type"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL8P3Type是一个八点三实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL8P3Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL9P3Type是一个九点三实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL9P3Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL9P6Type是一个九点六实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL9P6Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL10P4Type是一个十点四实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL10P4Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL16P2Type是一个十六点二实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL16P2Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL16P8Type是一个十六点八实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL16P8Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcREAL22P2Type是一个二十二点二实型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcREAL22P2Type"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCommandNoType是一个DB命令序号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCommandNoType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCommandTypeType是一个DB命令类型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCommandTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSettlementGroupIDType是一个结算组代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSettlementGroupIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFieldNameType是一个字段名类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFieldNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFieldContentType是一个字段内容类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFieldContentType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankIDType是一个银行代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankNameType是一个银行名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankBrchIDType是一个银行分中心代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankBrchIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLiberSerialType是一个Liber系统流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcLiberSerialType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRoleIDType是一个角色编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRoleIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRoleNameType是一个角色名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcRoleNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDescriptionType是一个描述类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcDescriptionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFunctionIDType是一个功能代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFunctionIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBillNoType是一个票据号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBillNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundIOTypeType是一个出入金类型类型 +#////////////////////////////////////////////////////////////////////// +#出入金 +defineDict["SECURITY_FTDC_FIOT_FundIO"] = '1' +#银期转帐 +defineDict["SECURITY_FTDC_FIOT_Transfer"] = '2' + +typedefDict["TSecurityFtdcFundIOTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundTypeType是一个资金类型类型 +#////////////////////////////////////////////////////////////////////// +#银行存款 +defineDict["SECURITY_FTDC_FT_Deposite"] = '1' +#分项资金 +defineDict["SECURITY_FTDC_FT_ItemFund"] = '2' +#公司调整 +defineDict["SECURITY_FTDC_FT_Company"] = '3' + +typedefDict["TSecurityFtdcFundTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundDirectionType是一个出入金方向类型 +#////////////////////////////////////////////////////////////////////// +#入金 +defineDict["SECURITY_FTDC_FD_In"] = '1' +#出金 +defineDict["SECURITY_FTDC_FD_Out"] = '2' + +typedefDict["TSecurityFtdcFundDirectionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankFlagType是一个银行统一标识类型类型 +#////////////////////////////////////////////////////////////////////// +#工商银行 +defineDict["SECURITY_FTDC_BF_ICBC"] = '1' +#农业银行 +defineDict["SECURITY_FTDC_BF_ABC"] = '2' +#中国银行 +defineDict["SECURITY_FTDC_BF_BC"] = '3' +#建设银行 +defineDict["SECURITY_FTDC_BF_CBC"] = '4' +#交通银行 +defineDict["SECURITY_FTDC_BF_BOC"] = '5' +#其他银行 +defineDict["SECURITY_FTDC_BF_Other"] = 'Z' + +typedefDict["TSecurityFtdcBankFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOperationMemoType是一个操作摘要类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOperationMemoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundStatusType是一个资金状态类型 +#////////////////////////////////////////////////////////////////////// +#已录入 +defineDict["SECURITY_FTDC_FS_Record"] = '1' +#已复核 +defineDict["SECURITY_FTDC_FS_Check"] = '2' +#已冲销 +defineDict["SECURITY_FTDC_FS_Charge"] = '3' + +typedefDict["TSecurityFtdcFundStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundProjectIDType是一个资金项目编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFundProjectIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOperatorIDType是一个操作员代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOperatorIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCounterIDType是一个计数器代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCounterIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFunctionNameType是一个功能名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcFunctionNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeCodeType是一个交易代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerBranchIDType是一个经纪公司分支机构代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBrokerBranchIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeDateType是一个交易日期类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeDateType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeTimeType是一个交易时间类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeTimeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankSerialType是一个银行流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankSerialType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSerialType是一个流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcSerialType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLastFragmentType是一个最后分片标志类型 +#////////////////////////////////////////////////////////////////////// +#是最后分片 +defineDict["SECURITY_FTDC_LF_Yes"] = '0' +#不是最后分片 +defineDict["SECURITY_FTDC_LF_No"] = '1' + +typedefDict["TSecurityFtdcLastFragmentType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIndividualNameType是一个个人姓名类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcIndividualNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCustTypeType是一个客户类型类型 +#////////////////////////////////////////////////////////////////////// +#自然人 +defineDict["SECURITY_FTDC_CUSTT_Person"] = '0' +#机构户 +defineDict["SECURITY_FTDC_CUSTT_Institution"] = '1' + +typedefDict["TSecurityFtdcCustTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankAccountType是一个银行账户类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankAccountType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcYesNoIndicatorType是一个是或否标识类型 +#////////////////////////////////////////////////////////////////////// +#是 +defineDict["SECURITY_FTDC_YNI_Yes"] = '0' +#否 +defineDict["SECURITY_FTDC_YNI_No"] = '1' + +typedefDict["TSecurityFtdcYesNoIndicatorType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeAmountType是一个交易金额(元)类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeAmountType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCustFeeType是一个应收客户费用(元)类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcCustFeeType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerFeeType是一个应收经纪公司费用(元)类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBrokerFeeType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFeePayFlagType是一个费用支付标志类型 +#////////////////////////////////////////////////////////////////////// +#由受益方支付费用 +defineDict["SECURITY_FTDC_FPF_BEN"] = '0' +#由发送方支付费用 +defineDict["SECURITY_FTDC_FPF_OUR"] = '1' +#由发送方支付发起的费用,受益方支付接受的费用 +defineDict["SECURITY_FTDC_FPF_SHA"] = '2' + +typedefDict["TSecurityFtdcFeePayFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAddInfoType是一个附加信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcAddInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDigestType是一个摘要类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcDigestType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankAccTypeType是一个银行帐号类型类型 +#////////////////////////////////////////////////////////////////////// +#银行存折 +defineDict["SECURITY_FTDC_BAT_BankBook"] = '1' +#储蓄卡 +defineDict["SECURITY_FTDC_BAT_SavingCard"] = '2' +#信用卡 +defineDict["SECURITY_FTDC_BAT_CreditCard"] = '3' + +typedefDict["TSecurityFtdcBankAccTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDeviceIDType是一个渠道标志类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcDeviceIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPwdFlagType是一个密码核对标志类型 +#////////////////////////////////////////////////////////////////////// +#不核对 +defineDict["SECURITY_FTDC_BPWDF_NoCheck"] = '0' +#明文核对 +defineDict["SECURITY_FTDC_BPWDF_BlankCheck"] = '1' +#密文核对 +defineDict["SECURITY_FTDC_BPWDF_EncryptCheck"] = '2' + +typedefDict["TSecurityFtdcPwdFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankCodingForBrokerType是一个银行对经纪公司的编码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcBankCodingForBrokerType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOperNoType是一个交易柜员类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOperNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTIDType是一个交易ID类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTransferStatusType是一个转账交易状态类型 +#////////////////////////////////////////////////////////////////////// +#正常 +defineDict["SECURITY_FTDC_TRFS_Normal"] = '0' +#被冲正 +defineDict["SECURITY_FTDC_TRFS_Repealed"] = '1' + +typedefDict["TSecurityFtdcTransferStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPlateSerialType是一个平台流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcPlateSerialType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAvailabilityFlagType是一个有效标志类型 +#////////////////////////////////////////////////////////////////////// +#未确认 +defineDict["SECURITY_FTDC_AVAF_Invalid"] = '0' +#有效 +defineDict["SECURITY_FTDC_AVAF_Valid"] = '1' +#冲正 +defineDict["SECURITY_FTDC_AVAF_Repeal"] = '2' + +typedefDict["TSecurityFtdcAvailabilityFlagType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOperatorCodeType是一个操作员类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcOperatorCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRepayStockAlgoType是一个买券还券算法类型 +#////////////////////////////////////////////////////////////////////// +#默认算法 +defineDict["SECURITY_FTDC_RSA_Original"] = '0' +#按还券比例计算 +defineDict["SECURITY_FTDC_RSA_Ratio"] = '1' +#Min[1,2] +defineDict["SECURITY_FTDC_RSA_Min"] = '2' + +typedefDict["TSecurityFtdcRepayStockAlgoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeSpanType是一个交易时间段类型类型 +#////////////////////////////////////////////////////////////////////// +#普通业务 +defineDict["SECURITY_FTDC_TS_Common"] = '1' +#转账 +defineDict["SECURITY_FTDC_TS_Transfer"] = '2' + +typedefDict["TSecurityFtdcTradeSpanType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSettleSystemTypeType是一个所属结算系统类型类型 +#////////////////////////////////////////////////////////////////////// +#顶点系统 +defineDict["SECURITY_FTDC_SST_Aboss"] = '1' +#恒生系统 +defineDict["SECURITY_FTDC_SST_HS"] = '2' + +typedefDict["TSecurityFtdcSettleSystemTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLogLevelType是一个日志级别类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcLogLevelType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProcessNameType是一个存储过程名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcProcessNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTemplateIDType是一个模板代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTemplateIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeIndexType是一个成交序号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TSecurityFtdcTradeIndexType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSplitMergeStatusType是一个基金当天拆分合并状态类型 +#////////////////////////////////////////////////////////////////////// +#表示允许拆分和合并 +defineDict["SECURITY_FTDC_SMS_Allow"] = '0' +#允许拆分、不允许合并 +defineDict["SECURITY_FTDC_SMS_OnlySplit"] = '1' +#不允许拆分、允许合并 +defineDict["SECURITY_FTDC_SMS_OnlyMerge"] = '2' +#不允许拆分和合并 +defineDict["SECURITY_FTDC_SMS_Forbidden"] = '3' + +typedefDict["TSecurityFtdcSplitMergeStatusType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundInterTransferTypeType是一个资金内转类型类型 +#////////////////////////////////////////////////////////////////////// +#转入 +defineDict["SECURITY_FTDC_FITT_TransferIn"] = '0' +#转出 +defineDict["SECURITY_FTDC_FITT_TransferOut"] = '1' + +typedefDict["TSecurityFtdcFundInterTransferTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentTypeType是一个合约类型类型 +#////////////////////////////////////////////////////////////////////// +#普通 +defineDict["SECURITY_FTDC_IT_Normal"] = '0' +#看涨期权 +defineDict["SECURITY_FTDC_IT_CallOptions"] = '1' +#看跌期权 +defineDict["SECURITY_FTDC_IT_PutOptions"] = '2' +#普通(STEP) +defineDict["SECURITY_FTDC_IT_Normal_STEP"] = '3' + +typedefDict["TSecurityFtdcInstrumentTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInvestorLevelType是一个投资者期权交易等级类型 +#////////////////////////////////////////////////////////////////////// +#一级 +defineDict["SECURITY_FTDC_IL_Level_1"] = '0' +#二级 +defineDict["SECURITY_FTDC_IL_Level_2"] = '1' +#三级 +defineDict["SECURITY_FTDC_IL_Level_3"] = '2' + +typedefDict["TSecurityFtdcInvestorLevelType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCloseDirectionType是一个平仓方向类型 +#////////////////////////////////////////////////////////////////////// +#买平仓 +defineDict["SECURITY_FTDC_CD_CloseBuy"] = '!' +#卖平仓 +defineDict["SECURITY_FTDC_CD_CloseSell"] = '@' +#备兑平仓 +defineDict["SECURITY_FTDC_CD_CloseCover"] = '#' + +typedefDict["TSecurityFtdcCloseDirectionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDelivTypeType是一个交割类型类型 +#////////////////////////////////////////////////////////////////////// +#看涨期权执行 +defineDict["SECURITY_FTDC_DT_ExecCallOptions"] = '0' +#看跌期权执行 +defineDict["SECURITY_FTDC_DT_ExecPutOptions"] = '1' +#在途证券 +defineDict["SECURITY_FTDC_DT_UnavailStock"] = '2' +#赎回在途资金 +defineDict["SECURITY_FTDC_DT_UnavailRedMoney"] = '2' + +typedefDict["TSecurityFtdcDelivTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExpireTypeType是一个到期类型类型 +#////////////////////////////////////////////////////////////////////// +#正回购到期 +defineDict["SECURITY_FTDC_ET_Repurchase"] = '0' +#逆回购到期 +defineDict["SECURITY_FTDC_ET_ReverseRepurch"] = '1' +#债券到期 +defineDict["SECURITY_FTDC_ET_Bond"] = '2' + +typedefDict["TSecurityFtdcExpireTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFundClassType是一个基金类别类型 +#////////////////////////////////////////////////////////////////////// +#发行期 +defineDict["SECURITY_FTDC_FC_Subscription"] = '0' +#普通型 +defineDict["SECURITY_FTDC_FC_Normal"] = '1' +#货币型 +defineDict["SECURITY_FTDC_FC_Monetary"] = '2' + +typedefDict["TSecurityFtdcFundClassType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingPhaseType是一个交易阶段类型 +#////////////////////////////////////////////////////////////////////// +#非交易时段 +defineDict["SECURITY_FTDC_TP_NonTrade"] = '0' +#集合竞价时段 +defineDict["SECURITY_FTDC_TP_Bidding"] = '1' +#连续交易时段 +defineDict["SECURITY_FTDC_TP_Continuous"] = '2' +#停牌时段 +defineDict["SECURITY_FTDC_TP_Suspension"] = '3' +#熔断时段 +defineDict["SECURITY_FTDC_TP_Fuse"] = '4' + +typedefDict["TSecurityFtdcTradingPhaseType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOpenRestrictionType是一个开仓限制类型 +#////////////////////////////////////////////////////////////////////// +#无开仓限制 +defineDict["SECURITY_FTDC_OR_None"] = '0' +#限制备兑开仓 +defineDict["SECURITY_FTDC_OR_NoCoverOpen"] = '1' +#限制卖出开仓 +defineDict["SECURITY_FTDC_OR_NoSellOpen"] = '2' +#限制卖出开仓、备兑开仓 +defineDict["SECURITY_FTDC_OR_NoSellAndCoverOpen"] = '3' +#限制买入开仓 +defineDict["SECURITY_FTDC_OR_NoBuyOpen"] = '4' +#限制买入开仓、备兑开仓 +defineDict["SECURITY_FTDC_OR_NoBuyAndCoverOpen"] = '5' +#限制买入开仓、卖出开仓 +defineDict["SECURITY_FTDC_OR_NoBuyAndSellOpen"] = '6' +#限制买入开仓、卖出开仓、备兑开仓 +defineDict["SECURITY_FTDC_OR_NoBuySellAndCoverOpen"] = '7' + +typedefDict["TSecurityFtdcOpenRestrictionType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOfferTypeType是一个报盘类型类型 +#////////////////////////////////////////////////////////////////////// +#普通报盘 +defineDict["SECURITY_FTDC_OT_Normal"] = '0' +#期权报盘 +defineDict["SECURITY_FTDC_OT_Options"] = '1' + +typedefDict["TSecurityFtdcOfferTypeType"] = "string" + diff --git a/vn.trader/ltsGateway.py b/vn.trader/ltsGateway.py new file mode 100644 index 00000000..8f4134ce --- /dev/null +++ b/vn.trader/ltsGateway.py @@ -0,0 +1,1240 @@ +# encoding: UTF-8 + +''' +vn.lts的gateway接入 +''' + +import os +import json + +from vnltsmd import MdApi +from vnltstd import TdApi +from vnltsqry import QryApi +from ltsDataType import * +from vtGateway import * + + +# 以下为一些VT类型和LTS类型的映射字典 +# 价格类型映射 +priceTypeMap= {} +priceTypeMap[PRICETYPE_LIMITPRICE] = defineDict["SECURITY_FTDC_OPT_LimitPrice"] +priceTypeMap[PRICETYPE_MARKETPRICE] = defineDict["SECURITY_FTDC_OPT_AnyPrice"] +priceTypeMap[PRICETYPE_FAK] = defineDict["SECURITY_FTDC_OPT_BestPrice"] +priceTypeMap[PRICETYPE_FOK] = defineDict["SECURITY_FTDC_OPT_AllLimitPrice"] +priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()} + +# 方向类型映射 +directionMap = {} +directionMap[DIRECTION_LONG] = defineDict["SECURITY_FTDC_D_Buy"] +directionMap[DIRECTION_SHORT] = defineDict["SECURITY_FTDC_D_Sell"] +directionMapReverse = {v: k for k, v in directionMap.items()} + +# 开平类型映射 +offsetMap = {} +offsetMap[OFFSET_OPEN] = defineDict["SECURITY_FTDC_OF_Open"] +offsetMap[OFFSET_CLOSE] = defineDict["SECURITY_FTDC_OF_Close"] +offsetMap[OFFSET_CLOSETODAY] = defineDict["SECURITY_FTDC_OF_CloseToday"] +offsetMap[OFFSET_CLOSESYESTERDAY] = defineDict["SECURITY_FTDC_OF_CloseYesterday"] +offsetMapReverse = {v:k for k,v in offsetMap.items()} + +# 交易所类型映射 +exchangeMap = {} +exchangeMap[EXCHANGE_SSE] = 'SSE' +exchangeMap[EXCHANGE_SZSE] = 'SZE' +exchangeMapReverse = {v:k for k,v in exchangeMap.items()} + +# 持仓类型映射 +posiDirectionMap = {} +posiDirectionMap[DIRECTION_NET] = defineDict["SECURITY_FTDC_PD_Net"] +posiDirectionMap[DIRECTION_LONG] = defineDict["SECURITY_FTDC_PD_Long"] +posiDirectionMap[DIRECTION_SHORT] = defineDict["SECURITY_FTDC_PD_Short"] +posiDirectionMapReverse = {v:k for k,v in posiDirectionMap.items()} + + +######################################################################################## +class LtsGateway(VtGateway): + """Lts接口""" + + #---------------------------------------------------------------------- + def __init__(self, eventEngine, gatewayName='LTS'): + """Constructor""" + super(LtsGateway, self).__init__(eventEngine, gatewayName) + + self.mdApi = LtsMdApi(self) + self.tdApi = LtsTdApi(self) + self.qryApi = LtsQryApi(self) + + self.mdConnected = False + self.tdConnected = False + self.qryConnected = False + + self.qryEnabled = False # 是否要启动循环查询 + + #---------------------------------------------------------------------- + def connect(self): + """连接""" + # 载入json 文件 + fileName = self.gatewayName + '_connect.json' + try: + f = file(fileName) + except IOError: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'读取连接配置出错,请检查' + self.onLog(log) + return + + # 解析json文件 + setting = json.load(f) + try: + userID = str(setting['userID']) + mdPassword = str(setting['mdPassword']) + tdPassword = str(setting['tdPassword']) + brokerID = str(setting['brokerID']) + tdAddress = str(setting['tdAddress']) + mdAddress = str(setting['mdAddress']) + qryAddress = str(setting['qryAddress']) + productInfo = str(setting['productInfo']) + authCode = str(setting['authCode']) + except KeyError: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'连接配置缺少字段,请检查' + self.onLog(log) + return + + # 创建行情和交易接口对象 + self.mdApi.connect(userID, mdPassword, brokerID, mdAddress) + self.tdApi.connect(userID, tdPassword, brokerID, tdAddress, productInfo, authCode) + self.qryApi.connect(userID, tdPassword, brokerID, qryAddress, productInfo, authCode) + + # 初始化并启动查询 + self.initQuery() + self.startQuery() + + #---------------------------------------------------------------------- + def subscribe(self, subscribeReq): + """订阅行情""" + self.mdApi.subscribe(subscribeReq) + + #---------------------------------------------------------------------- + def sendOrder(self, orderReq): + """发单""" + return self.tdApi.sendOrder(orderReq) + + #---------------------------------------------------------------------- + def cancelOrder(self, cancelOrderReq): + """撤单""" + self.tdApi.cancelOrder(cancelOrderReq) + + #---------------------------------------------------------------------- + def getAccount(self): + """查询账户资金""" + self.qryApi.getAccount() + + #---------------------------------------------------------------------- + def getPosition(self): + """查询持仓""" + self.qryApi.getPosition() + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + if self.mdConnected: + self.mdApi.close() + if self.tdConnected: + self.tdApi.close() + if self.qryConnected: + self.qryApi.close() + + #---------------------------------------------------------------------- + def initQuery(self): + """初始化连续查询""" + if self.qryEnabled: + # 需要循环的查询函数列表 + self.qryFunctionList = [self.getAccount, self.getPosition] + + self.qryCount = 0 # 查询触发倒计时 + self.qryTrigger = 2 # 查询触发点 + self.qryNextFunction = 0 # 上次运行的查询函数索引 + + self.startQuery() + + #---------------------------------------------------------------------- + def query(self, event): + """注册到事件处理引擎上的查询函数""" + self.qryCount += 1 + + if self.qryCount > self.qryTrigger: + # 清空倒计时 + self.qryCount = 0 + + # 执行查询函数 + function = self.qryFunctionList[self.qryNextFunction] + function() + + # 计算下次查询函数的索引,如果超过了列表长度,则重新设为0 + self.qryNextFunction += 1 + if self.qryNextFunction == len(self.qryFunctionList): + self.qryNextFunction = 0 + + #---------------------------------------------------------------------- + def startQuery(self): + """启动连续查询""" + self.eventEngine.register(EVENT_TIMER, self.query) + + #---------------------------------------------------------------------- + def setQryEnabled(self, qryEnabled): + """设置是否要启动循环查询""" + self.qryEnabled = qryEnabled + + +######################################################################## +class LtsMdApi(MdApi): + """Lts行情API实现""" + + #---------------------------------------------------------------------- + def __init__(self, gateway): + """Constructor""" + super(LtsMdApi, self).__init__() + + self.gateway = gateway #gateway对象 + self.gatewayName = gateway.gatewayName #gateway对象名称 + + self.reqID = EMPTY_INT # 操作请求编号 + + self.connectionStatus = False # 连接状态 + self.loginStatus = False # 登陆状态 + + self.subscribedSymbols = set() + + self.userID = EMPTY_STRING # 账号 + self.password = EMPTY_STRING # 密码 + self.brokerID = EMPTY_STRING # 经纪商代码 + self.address = EMPTY_STRING # 服务器地址 + + #---------------------------------------------------------------------- + def onFrontConnected(self): + """服务器连接""" + self.connectionStatus = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器连接成功' + self.gateway.onLog(log) + self.login() + + #---------------------------------------------------------------------- + def onFrontDisconnected(self,n): + """服务器断开""" + self.connectionStatus= False + self.loginStatus = False + self.gateway.mdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器连接断开' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onHeartBeatWarning(self, n): + """心跳报警""" + pass + + #---------------------------------------------------------------------- + def onRspError(self,error,n,last): + """错误回报""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogin(self, data, error, n, last): + """登陆回报""" + # 如果登录成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = True + self.gateway.mdConnected = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器登录完成' + self.gateway.onLog(log) + + # 重新订阅之前订阅的合约 + for subscribeReq in self.subscribedSymbols: + self.subscribe(subscribeReq) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogout(self, data, error, n, last): + """登出回报""" + # 如果登出成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器登出完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspSubMarketData(self, data, error, n, last): + """订阅合约回报""" + # 通常不在乎订阅错误,选择忽略 + pass + + #---------------------------------------------------------------------- + def onRspUnSubMarketData(self, data, error, n, last): + """退订合约回报""" + # 同上 + pass + + #---------------------------------------------------------------------- + def onRtnDepthMarketData(self, data): + """行情推送""" + tick = VtTickData() + tick.gatewayName = self.gatewayName + + tick.symbol = data['InstrumentID'] + tick.exchange = exchangeMapReverse.get(data['ExchangeID'], u'未知') + tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) + + tick.lastPrice = data['LastPrice'] + tick.volume = data['Volume'] + tick.openInterest = data['OpenInterest'] + tick.tickTime = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)]) + tick.date = data['TradingDay'] + + tick.openPrice = data['OpenPrice'] + tick.highPrice = data['HighestPrice'] + tick.lowPrice = data['LowestPrice'] + tick.preClosePrice = data['PreClosePrice'] + + tick.upperLimit = data['UpperLimitPrice'] + tick.lowerLimit = data['LowerLimitPrice'] + + # LTS有5档行情 + tick.bidPrice1 = data['BidPrice1'] + tick.bidVolume1 = data['BidVolume1'] + tick.askPrice1 = data['AskPrice1'] + tick.askVolume1 = data['AskVolume1'] + + tick.bidPrice2 = data['BidPrice2'] + tick.bidVolume2 = data['BidVolume2'] + tick.askPrice2 = data['AskPrice2'] + tick.askVolume2 = data['AskVolume2'] + + tick.bidPrice3 = data['BidPrice3'] + tick.bidVolume3 = data['BidVolume3'] + tick.askPrice3 = data['AskPrice3'] + tick.askVolume3 = data['AskVolume3'] + + tick.bidPrice4 = data['BidPrice4'] + tick.bidVolume4 = data['BidVolume4'] + tick.askPrice4 = data['AskPrice4'] + tick.askVolume4 = data['AskVolume4'] + + tick.bidPrice5 = data['BidPrice5'] + tick.bidVolume5 = data['BidVolume5'] + tick.askPrice5 = data['AskPrice5'] + tick.askVolume5 = data['AskVolume5'] + + self.gateway.onTick(tick) + + #---------------------------------------------------------------------- + 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 = os.getcwd() + '\\temp\\' + self.gatewayName + '\\' + if not os.path.exists(path): + os.makedirs(path) + self.createFtdcMdApi(path) + + # 注册服务器地址 + self.registerFront(self.address) + + # 初始化连接,成功会调用onFrontConnected + self.init() + + # 若已经连接但尚未登录,则进行登录 + else: + if not self.loginStatus: + self.login() + + #---------------------------------------------------------------------- + def subscribe(self, subscribeReq): + """订阅合约""" + req = {} + req['InstrumentID'] = str(subscribeReq.symbol) + req['ExchangeID'] = str(subscribeReq.exchange) + + # 这里的设计是,如果尚未登录就调用了订阅方法 + # 则先保存订阅请求,登录完成后会自动订阅 + if self.loginStatus: + self.subscribeMarketData(req) + + self.subscribedSymbols.add(subscribeReq) + + #---------------------------------------------------------------------- + def login(self): + """登录""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.password and self.brokerID: + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + self.reqID += 1 + self.reqUserLogin(req, self.reqID) + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + self.exit() + + +######################################################################## +class LtsTdApi(TdApi): + """LTS交易API实现""" + + #---------------------------------------------------------------------- + def __init__(self, gateway): + """API对象的初始化函数""" + super(LtsTdApi, self).__init__() + + self.gateway = gateway # gateway对象 + self.gatewayName = gateway.gatewayName # gateway对象名称 + + self.reqID = EMPTY_INT # 操作请求编号 + self.orderRef = EMPTY_INT # 订单编号 + + self.connectionStatus = False # 连接状态 + self.loginStatus = False # 登录状态 + + self.userID = EMPTY_STRING # 账号 + self.password = EMPTY_STRING # 密码 + self.brokerID = EMPTY_STRING # 经纪商代码 + self.address = EMPTY_STRING # 服务器地址 + self.productInfo = EMPTY_STRING # 程序产品名称 + self.authCode = EMPTY_STRING # 授权码 + self.randCode = EMPTY_STRING # 随机码 + + self.frontID = EMPTY_INT # 前置机编号 + self.sessionID = EMPTY_INT # 会话编号 + + #---------------------------------------------------------------------- + def onFrontConnected(self): + """服务器连接""" + self.connectionStatus = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器连接成功' + self.gateway.onLog(log) + + # 前置机连接后,请求随机码 + self.reqID += 1 + self.reqFetchAuthRandCode({}, self.reqID) + + #---------------------------------------------------------------------- + def onFrontDisconnected(self, n): + """服务器断开""" + self.connectionStatus = False + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器连接断开' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onHeartBeatWarning(self, n): + """""" + pass + + #---------------------------------------------------------------------- + def onRspUserLogin(self, data, error, n, last): + """登陆回报""" + # 如果登录成功,推送日志信息 + if error['ErrorID'] == 0: + self.frontID = str(data['FrontID']) + self.sessionID = str(data['SessionID']) + self.loginStatus = True + self.gateway.mdConnected = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器登录完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gateway + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogout(self, data, error, n, last): + """登出回报""" + # 如果登出成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器登出完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspFetchAuthRandCode(self, data, error, n, last): + """请求随机认证码""" + self.randCode = data['RandCode'] + self.login() + + #---------------------------------------------------------------------- + def onRspUserPasswordUpdate(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspTradingAccountPasswordUpdate(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspOrderInsert(self, data, error, n, last): + """发单错误(柜台)""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspOrderAction(self, data, error, n, last): + """撤单错误(柜台)""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspError(self, error, n, last): + """错误回报""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRtnOrder(self, data): + """报单回报""" + # 更新最大报单编号 + newref = data['OrderRef'] + self.orderRef = max(self.orderRef, int(newref)) + + # 创建报单数据对象 + order = VtOrderData() + order.gatewayName = self.gatewayName + + # 保存代码和报单号 + order.symbol = data['InstrumentID'] + order.exchange = exchangeMapReverse[data['ExchangeID']] + order.vtSymbol = '.'.join([order.symbol, order.exchange]) + + order.orderID = data['OrderRef'] + + # 方向 + if data['Direction'] == '0': + order.direction = DIRECTION_LONG + elif data['Direction'] == '1': + order.direction = DIRECTION_SHORT + else: + order.direction = DIRECTION_UNKNOWN + + # 开平 + if data['CombOffsetFlag'] == '0': + order.offset = OFFSET_OPEN + elif data['CombOffsetFlag'] == '1': + order.offset = OFFSET_CLOSE + else: + order.offset = OFFSET_UNKNOWN + + # 状态 + if data['OrderStatus'] == '0': + order.status = STATUS_ALLTRADED + elif data['OrderStatus'] == '1': + order.status = STATUS_PARTTRADED + elif data['OrderStatus'] == '3': + order.status = STATUS_NOTTRADED + elif data['OrderStatus'] == '5': + order.status = STATUS_CANCELLED + else: + order.status = STATUS_UNKNOWN + + # 价格、报单量等数值 + order.price = data['LimitPrice'] + order.totalVolume = data['VolumeTotalOriginal'] + order.tradedVolume = data['VolumeTraded'] + order.orderTime = data['InsertTime'] + order.cancelTime = data['CancelTime'] + order.frontID = data['FrontID'] + order.sessionID = data['SessionID'] + + # CTP的报单号一致性维护需要基于frontID, sessionID, orderID三个字段 + order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) + + # 推送 + self.gateway.onOrder(order) + + #---------------------------------------------------------------------- + def onRtnTrade(self, data): + """成交回报""" + # 创建报单数据对象 + trade = VtTradeData() + trade.gatewayName = self.gatewayName + + # 保存代码和报单号 + trade.symbol = data['InstrumentID'] + trade.exchange = exchangeMapReverse[data['ExchangeID']] + trade.vtSymbol = '.'.join([trade.symbol, trade.exchange]) + + trade.tradeID = data['TradeID'] + trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) + + trade.orderID = data['OrderRef'] + trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID]) + + # 方向 + trade.direction = directionMapReverse.get(data['Direction'], '') + + # 开平 + trade.offset = offsetMapReverse.get(data['OffsetFlag'], '') + + # 价格、报单量等数值 + trade.price = data['Price'] + trade.volume = data['Volume'] + trade.tradeTime = data['TradeTime'] + + # 推送 + self.gateway.onTrade(trade) + + #---------------------------------------------------------------------- + def onErrRtnOrderInsert(self, data, error): + """发单错误回报(交易所)""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onErrRtnOrderAction(self, data, error): + """撤单错误回报(交易所)""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspFundOutByLiber(self, data, error, n, last): + """LTS发起出金应答""" + pass + + #---------------------------------------------------------------------- + def onRtnFundOutByLiber(self, data): + """LTS发起出金通知""" + pass + + #---------------------------------------------------------------------- + def onErrRtnFundOutByLiber(self, data, error): + """LTS发起出金错误回报""" + pass + + #---------------------------------------------------------------------- + def onRtnFundInByBank(self, data): + """银行发起入金通知""" + pass + + #---------------------------------------------------------------------- + def onRspFundInterTransfer(self, data, error, n, last): + """资金内转应答""" + pass + + #---------------------------------------------------------------------- + def onRtnFundInterTransferSerial(self, data): + """资金内转流水通知""" + pass + + #---------------------------------------------------------------------- + def onErrRtnFundInterTransfer(self, data, error): + """资金内转错误回报""" + pass + + #---------------------------------------------------------------------- + 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 = os.getcwd() + '\\temp\\' + self.gatewayName + '\\' + if not os.path.exists(path): + os.makedirs(path) + self.createFtdcTraderApi(path) + + # 注册服务器地址 + self.registerFront(self.address) + + # 初始化连接,成功会调用onFrontConnected + self.init() + + # 若已经连接但尚未登录,则进行登录 + else: + if not self.loginStatus: + self.login() + + #---------------------------------------------------------------------- + def login(self): + """连接服务器""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.password and self.brokerID: + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + req['UserProductInfo'] = self.productInfo + req['AuthCode'] = self.authCode + req['RandCode'] = self.randCode + self.reqID += 1 + self.reqUserLogin(req, self.reqID) + + #---------------------------------------------------------------------- + def sendOrder(self, orderReq): + """发单""" + self.reqID += 1 + self.orderRef += 1 + + req = {} + + req['InstrumentID'] = orderReq.symbol + req['LimitPrice'] = str(orderReq.price) # LTS里的价格是字符串 + req['VolumeTotalOriginal'] = orderReq.volume + req['ExchangeID'] = orderReq.exchange + + # 下面如果由于传入的类型本接口不支持,则会返回空字符串 + try: + req['OrderPriceType'] = priceTypeMap[orderReq.priceType] + req['Direction'] = directionMap[orderReq.direction] + req['CombOffsetFlag'] = offsetMap[orderReq.offset] + req['ExchangeID'] = exchangeMap[orderReq.exchange] + except KeyError: + return '' + + req['OrderRef'] = str(self.orderRef) + req['InvestorID'] = self.userID + req['UserID'] = self.userID + req['BrokerID'] = self.brokerID + + req['CombHedgeFlag'] = defineDict['SECURITY_FTDC_HF_Speculation'] # 投机单 + req['ContingentCondition'] = defineDict['SECURITY_FTDC_CC_Immediately'] # 立即发单 + req['ForceCloseReason'] = defineDict['SECURITY_FTDC_FCC_NotForceClose'] # 非强平 + req['IsAutoSuspend'] = 0 # 非自动挂起 + req['TimeCondition'] = defineDict['SECURITY_FTDC_TC_GFD'] # 今日有效 + req['VolumeCondition'] = defineDict['SECURITY_FTDC_VC_AV'] # 任意成交量 + req['MinVolume'] = 1 # 最小成交量为1 + req['UserForceClose'] = 0 + + self.reqOrderInsert(req, self.reqID) + + # 返回订单号(字符串),便于某些算法进行动态管理 + vtOrderID = '.'.join([self.gatewayName, str(self.orderRef)]) + return vtOrderID + + #---------------------------------------------------------------------- + def cancelOrder(self, cancelOrderReq): + """撤单""" + self.reqID += 1 + + req = {} + + req['InstrumentID'] = cancelOrderReq.symbol + req['ExchangeID'] = cancelOrderReq.exchange + req['OrderRef'] = cancelOrderReq.orderID + req['FrontID'] = cancelOrderReq.frontID + req['SessionID'] = cancelOrderReq.sessionID + + req['ActionFlag'] = defineDict['SECURITY_FTDC_AF_Delete'] + req['BrokerID'] = self.brokerID + req['InvestorID'] = self.userID + + self.reqOrderAction(req, self.reqID) + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + self.exit() + + +######################################################################## +class LtsQryApi(QryApi): + """Lts账户查询实现""" + + #---------------------------------------------------------------------- + def __init__(self, gateway): + """API对象的初始化函数""" + super(LtsQryApi, self).__init__() + + self.gateway = gateway # gateway对象 + self.gatewayName = gateway.gatewayName # gateway对象名称 + + self.reqID = EMPTY_INT # 操作请求编号 + self.orderRef = EMPTY_INT # 订单编号 + + self.connectionStatus = False # 连接状态 + self.loginStatus = False # 登录状态 + + self.userID = EMPTY_STRING # 账号 + self.password = EMPTY_STRING # 密码 + self.brokerID = EMPTY_STRING # 经纪商代码 + self.address = EMPTY_STRING # 服务器地址 + self.productInfo = EMPTY_STRING # 程序产品名称 + self.authCode = EMPTY_STRING # 授权码 + self.randCode = EMPTY_STRING # 随机码 + + self.frontID = EMPTY_INT # 前置机编号 + self.sessionID = EMPTY_INT # 会话编号 + + #---------------------------------------------------------------------- + def onFrontConnected(self): + """服务器连接""" + self.connectionStatus = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'查询服务器连接成功' + self.gateway.onLog(log) + + # 前置机连接后,请求随机码 + self.reqID += 1 + self.reqFetchAuthRandCode({}, self.reqID) + + #---------------------------------------------------------------------- + def onFrontDisconnected(self, n): + """服务器断开""" + self.connectionStatus = False + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'查询服务器连接断开' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onHeartBeatWarning(self, n): + """""" + pass + + #---------------------------------------------------------------------- + def onRspError(self, error, n, last): + """错误回报""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogin(self, data, error, n, last): + """登陆回报""" + # 如果登录成功,推送日志信息 + if error['ErrorID'] == 0: + self.frontID = str(data['FrontID']) + self.sessionID = str(data['SessionID']) + self.loginStatus = True + self.gateway.qryConnected = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'查询服务器登录完成' + self.gateway.onLog(log) + + # 查询合约代码 + self.reqID += 1 + self.reqQryInstrument({}, self.reqID) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gateway + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogout(self, data, error, n, last): + """登出回报""" + # 如果登出成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = False + self.gateway.qryConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'查询服务器登出完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspFetchAuthRandCode(self, data, error, n, last): + """请求随机认证码""" + self.randCode = data['RandCode'] + self.login() + + #---------------------------------------------------------------------- + def onRspQryExchange(self, data, error, n, last): + pass + + #---------------------------------------------------------------------- + def onRspQryInstrument(self, data, error, n, last): + """合约查询回报""" + contract = VtContractData() + contract.gatewayName = self.gatewayName + + contract.symbol = data['InstrumentID'] + contract.exchange = exchangeMapReverse[data['ExchangeID']] + contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) + contract.name = data['InstrumentName'].decode('GBK') + + # 合约数值 + contract.size = data['VolumeMultiple'] + contract.priceTick = data['PriceTick'] + contract.strikePrice = data['ExecPrice'] + contract.underlyingSymbol = data['MarketID'] + + # 合约类型 + if data['ProductClass'] == '1': + contract.productClass = PRODUCT_FUTURES + elif data['ProductClass'] == '2': + contract.productClass = PRODUCT_OPTION + elif data['ProductClass'] == '3': + contract.productClass = PRODUCT_COMBINATION + elif data['ProductClass'] == '6': + contract.productClass = PRODUCT_EQUITY + elif data['ProductClass'] == '8': + contract.productClass = PRODUCT_EQUITY + else: + print data['ProductClass'] + + # 期权类型 + if data['InstrumentType'] == '1': + contract.optionType = OPTION_CALL + elif data['InstrumentType'] == '2': + contract.optionType = OPTION_PUT + + # 推送 + self.gateway.onContract(contract) + + if last: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易合约信息获取完成' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onRspQryInvestor(self, data, error, n, last): + """投资者查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryTradingCode(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryTradingAccount(self, data, error, n, last): + """资金账户查询回报""" + account = VtAccountData() + account.gatewayName = self.gatewayName + + # 账户代码 + account.accountID = data['AccountID'] + account.vtAccountID = '.'.join([self.gatewayName, account.accountID]) + + # 数值相关 + account.preBalance = data['PreBalance'] + account.available = data['Available'] + account.commission = data['Commission'] + account.margin = data['CurrMargin'] + #account.closeProfit = data['CloseProfit'] + #account.positionProfit = data['PositionProfit'] + + # 这里的balance和快期中的账户不确定是否一样,需要测试 + account.balance = data['Balance'] + + # 推送 + self.gateway.onAccount(account) + + #---------------------------------------------------------------------- + def onRspQryBondInterest(self, data, error, n, last): + """债券利息查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryMarketRationInfo(self, data, error, n, last): + """市值配售查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryInstrumentCommissionRate(self, data, error, n, last): + """合约手续费查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryETFInstrument(self, data, error, n, last): + """ETF基金查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryETFBasket(self, data, error, n, last): + """ETF股票篮查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryOFInstrument(self, data, error, n, last): + """OF合约查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQrySFInstrument(self, data, error, n, last): + """SF合约查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryInstrumentUnitMargin(self, data, error, n, last): + """查询单手保证金""" + pass + + #---------------------------------------------------------------------- + def onRspQryPreDelivInfo(self, data, error, n , last): + """查询预交割信息""" + pass + + #---------------------------------------------------------------------- + def onRsyQryCreditStockAssignInfo(self, data, error, n, last): + """查询可融券分配""" + pass + + #---------------------------------------------------------------------- + def onRspQryCreditCashAssignInfo(self, data, error, n , last): + """查询可融资分配""" + pass + + #---------------------------------------------------------------------- + def onRsyQryConversionRate(self, data, error, n, last): + """查询证券这算率""" + pass + + #---------------------------------------------------------------------- + def onRspQryHisCreditDebtInfo(self,data, error, n, last): + """查询历史信用负债""" + pass + + #---------------------------------------------------------------------- + def onRspQryMarketDataStaticInfo(self, data, error, n, last): + """查询行情静态信息""" + pass + + #---------------------------------------------------------------------- + def onRspQryExpireRepurchInfo(self, data, error, n, last): + """查询到期回购信息响应""" + pass + + #---------------------------------------------------------------------- + def onRspQryBondPledgeRate(self, data, error, n, last): + """查询债券质押为标准券比例""" + pass + + #---------------------------------------------------------------------- + def onRspQryPledgeBond(self, data, error, n, last): + """查询债券质押代码对照关系""" + pass + + #---------------------------------------------------------------------- + def onRspQryOrder(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryTrade(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryInvestorPosition(self, data, error, n, last): + """持仓查询回报""" + pos = VtPositionData() + pos.gatewayName = self.gatewayName + + # 保存代码 + pos.symbol = data['InstrumentID'] + pos.exchange = data['ExchangeID'] + pos.vtSymbol = '.'.join([pos.symbol, pos.exchange]) + + # 方向和持仓冻结数量 + pos.direction = posiDirectionMapReverse.get(data['PosiDirection'], '') + if pos.direction == DIRECTION_NET or pos.direction == DIRECTION_LONG: + pos.frozen = data['LongFrozen'] + elif pos.direction == DIRECTION_SHORT: + pos.frozen = data['ShortFrozen'] + + # 持仓量 + pos.position = data['Position'] + + # 持仓均价 + if pos.position: + pos.price = data['PositionCost'] / pos.position + + # VT系统持仓名 + pos.vtPositionName = '.'.join([pos.vtSymbol, pos.direction]) + + # 推送 + self.gateway.onPosition(pos) + + #---------------------------------------------------------------------- + def OnRspQryFundTransferSerial(self, data, error, n, last): + """资金转账查询""" + pass + + #---------------------------------------------------------------------- + def onRspQryFundInterTransferSerial(self, data, error,n, last): + """资金内转流水查询""" + pass + + #---------------------------------------------------------------------- + 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 = os.getcwd() + '\\temp\\' + self.gatewayName + '\\' + if not os.path.exists(path): + os.makedirs(path) + self.createFtdcQueryApi(path) + + # 注册服务器地址 + self.registerFront(self.address) + + # 初始化连接,成功会调用onFrontConnected + self.init() + + # 若已经连接但尚未登录,则进行登录 + else: + if not self.loginStatus: + self.login() + + #---------------------------------------------------------------------- + def login(self): + """连接服务器""" + # 如果填入了用户名密码等,则登录 + + if self.userID and self.password and self.brokerID: + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + req['UserProductInfo'] = self.productInfo + req['AuthCode'] = self.authCode + req['RandCode'] = self.randCode + self.reqID += 1 + + self.reqUserLogin(req, self.reqID) + + #---------------------------------------------------------------------- + def getAccount(self): + """查询账户""" + self.reqID += 1 + #是否需要INVESTERID, BROKERID? + req = {} + req['BrokerID'] = self.brokerID + req['InvestorID'] = self.userID + self.reqQryTradingAccount(req, self.reqID) + + #---------------------------------------------------------------------- + def getPosition(self): + """查询持仓""" + self.reqID += 1 + req = {} + req['BrokerID'] = self.brokerID + req['InvestorID'] = self.userID + self.reqQryInvestorPosition(req, self.reqID) + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + self.exit() + + + \ No newline at end of file diff --git a/vn.trader/securitymduserapi.dll b/vn.trader/securitymduserapi.dll new file mode 100644 index 00000000..4bb2dd5e Binary files /dev/null and b/vn.trader/securitymduserapi.dll differ diff --git a/vn.trader/securityqueryapi.dll b/vn.trader/securityqueryapi.dll new file mode 100644 index 00000000..10bfd96a Binary files /dev/null and b/vn.trader/securityqueryapi.dll differ diff --git a/vn.trader/securitytraderapi.dll b/vn.trader/securitytraderapi.dll new file mode 100644 index 00000000..6bfda3e3 Binary files /dev/null and b/vn.trader/securitytraderapi.dll differ diff --git a/vn.trader/uiBasicWidget.py b/vn.trader/uiBasicWidget.py index 93b22556..69153348 100644 --- a/vn.trader/uiBasicWidget.py +++ b/vn.trader/uiBasicWidget.py @@ -5,22 +5,152 @@ from collections import OrderedDict from PyQt4 import QtGui, QtCore from eventEngine import * - +from vtFunction import * +from vtGateway import * + + +BASIC_FONT = QtGui.QFont(u'微软雅黑', 12) + + +######################################################################## +class BasicCell(QtGui.QTableWidgetItem): + """基础的单元格""" + + #---------------------------------------------------------------------- + def __init__(self, text=None): + """Constructor""" + super(BasicCell, self).__init__() + self.data = None + if text: + self.setContent(text) + + #---------------------------------------------------------------------- + def setContent(self, text): + """设置内容""" + self.setText(text) + + +######################################################################## +class DirectionCell(QtGui.QTableWidgetItem): + """用来显示买卖方向的单元格""" + + #---------------------------------------------------------------------- + def __init__(self, text=None): + """Constructor""" + super(DirectionCell, self).__init__() + self.data = None + if text: + self.setContent(text) + + #---------------------------------------------------------------------- + def setContent(self, text): + """设置内容""" + if text == DIRECTION_LONG or text == DIRECTION_NET: + self.setForeground(QtGui.QColor('red')) + elif text == DIRECTION_SHORT: + self.setForeground(QtGui.QColor('green')) + self.setText(text) + + +######################################################################## +class NameCell(QtGui.QTableWidgetItem): + """用来显示合约中文的单元格""" + dataEngine = None + + #---------------------------------------------------------------------- + def __init__(self, text=None, dataEngine=None): + """Constructor""" + super(NameCell, self).__init__() + self.data = None + if text: + self.setContent(text) + + #---------------------------------------------------------------------- + @staticmethod + def setDataEngine(self, dataEngine): + """设置读取合约用的数据引擎对象""" + self.dataEngine = dataEngine + + #---------------------------------------------------------------------- + def setContent(self, text): + """设置内容""" + if self.dataEngine: + # 首先尝试正常获取合约对象 + contract = self.dataEngine.getContract(text) + + # 如果交易所代码为UNKNOWN,则删除交易所代码部分后再试 + if EXCHANGE_UNKNOWN in text: + i = text.index('.') + symbol = text[:i] + contract = self.dataEngine.getContract(symbol) + + # 如果能读取合约信息 + if contract: + self.setText(contract.name) + + +######################################################################## +class BidCell(QtGui.QTableWidgetItem): + """买价单元格""" + + #---------------------------------------------------------------------- + def __init__(self, text=None): + """Constructor""" + super(BidCell, self).__init__() + self.data = None + + self.setBackground(QtGui.QColor(255,174,201)) + + if text: + self.setContent(text) + + #---------------------------------------------------------------------- + def setContent(self, text): + """设置内容""" + self.setText(text) + + +######################################################################## +class AskCell(QtGui.QTableWidgetItem): + """买价单元格""" + + #---------------------------------------------------------------------- + def __init__(self, text=None): + """Constructor""" + super(AskCell, self).__init__() + self.data = None + + self.setBackground(QtGui.QColor(160,255,160)) + + if text: + self.setContent(text) + + #---------------------------------------------------------------------- + def setContent(self, text): + """设置内容""" + self.setText(text) + ######################################################################## class BasicMonitor(QtGui.QTableWidget): - """基础监控""" + """ + 基础监控 + + headerDict中的值对应的字典格式如下 + {'chinese': u'中文名', 'cellType': BasicCell} + + """ signal = QtCore.pyqtSignal(type(Event())) #---------------------------------------------------------------------- - def __init__(self, eventEngine, parent=None): + def __init__(self, eventEngine=None, parent=None): """Constructor""" super(BasicMonitor, self).__init__(parent) self.eventEngine = eventEngine # 保存表头标签用 - self.headerDict = OrderedDict() # 有序字典,key是英文名,value是对应的中文名 + self.headerDict = OrderedDict() # 有序字典,key是英文名,value是对应的配置字典 self.headerList = [] # 对应self.headerDict.keys() # 保存相关数据用 @@ -33,6 +163,9 @@ class BasicMonitor(QtGui.QTableWidget): # 字体 self.font = None + # 保存数据对象到单元格 + self.saveData = False + #---------------------------------------------------------------------- def setHeaderDict(self, headerDict): """设置表头有序字典""" @@ -53,46 +186,65 @@ class BasicMonitor(QtGui.QTableWidget): def setFont(self, font): """设置字体""" self.font = font + + #---------------------------------------------------------------------- + def setSaveData(self, saveData): + """设置是否要保存数据到单元格""" + self.saveData = saveData #---------------------------------------------------------------------- def initTable(self): """初始化表格""" # 设置表格的列数 - col = len(self.labelDict) + col = len(self.headerDict) self.setColumnCount(col) # 设置列表头 - self.setHorizontalHeaderLabels(self.labelDict.values()) + labels = [d['chinese'] for d in self.headerDict.values()] + self.setHorizontalHeaderLabels(labels) # 关闭左边的垂直表头 self.verticalHeader().setVisible(False) # 设为不可编辑 self.setEditTriggers(self.NoEditTriggers) + + # 设为行交替颜色 + self.setAlternatingRowColors(True) #---------------------------------------------------------------------- def registerEvent(self): """注册GUI更新相关的事件监听""" - self.signal.connect(self.updateData) + self.signal.connect(self.updateEvent) self.eventEngine.register(self.eventType, self.signal.emit) + + #---------------------------------------------------------------------- + def updateEvent(self, event): + """收到事件更新""" + data = event.dict_['data'] + self.updateData(data) #---------------------------------------------------------------------- - def updateData(self, event): - """更新数据""" - data = event.dict_['data'] - key = data.__getattribute__(self.dataKey) - + def updateData(self, data): + """将数据更新到表格中""" # 如果设置了dataKey,则采用存量更新模式 if self.dataKey: + key = data.__getattribute__(self.dataKey) # 如果键在数据字典中不存在,则先插入新的一行,并创建对应单元格 if key not in self.dataDict: self.insertRow(0) d = {} for n, header in enumerate(self.headerList): - content = unicode(data.__getattribute__(header)) - cell = QtGui.QTableWidgetItem(content) + content = safeUnicode(data.__getattribute__(header)) + cellType = self.headerDict[header]['cellType'] + cell = cellType(content) + if self.font: - cell.setFont(font) # 如果设置了特殊字体,则进行单元格设置 + cell.setFont(self.font) # 如果设置了特殊字体,则进行单元格设置 + + if self.saveData: # 如果设置了保存数据对象,则进行对象保存 + cell.data = data + self.setItem(0, n, cell) d[header] = cell self.dataDict[key] = d @@ -100,17 +252,26 @@ class BasicMonitor(QtGui.QTableWidget): else: d = self.dataDict[key] for header in self.headerList: - content = unicode(data.__getattribute__(header)) + content = safeUnicode(data.__getattribute__(header)) cell = d[header] - cell.setText(content) + cell.setContent(content) + + if self.saveData: # 如果设置了保存数据对象,则进行对象保存 + cell.data = data # 否则采用增量更新模式 else: self.insertRow(0) for n, header in enumerate(self.headerList): - content = unicode(data.__getattribute__(header)) - cell = QtGui.QTableWidgetItem(content) + content = safeUnicode(data.__getattribute__(header)) + cellType = self.headerDict[header]['cellType'] + cell = cellType(content) + if self.font: - cell.setFont(font) + cell.setFont(self.font) + + if self.saveData: + cell.data = data + self.setItem(0, n, cell) # 调整列宽 @@ -133,19 +294,20 @@ class MarketMonitor(BasicMonitor): # 设置表头有序字典 d = OrderedDict() - d['symbol'] = u'合约代码' - d['vtSymbol'] = u'系统代码' - d['lastPrice'] = u'最新价' - d['volume'] = u'成交量' - d['openInterest'] = u'持仓量' - d['openPrice'] = u'开盘价' - d['highPrice'] = u'最高价' - d['lowPrice'] = u'最低价' - d['bidPrice1'] = u'买一价' - d['bidVolume1'] = u'买一量' - d['askPrice1'] = u'卖一价' - d['askVolume1'] = u'卖一量' - d['tickTime'] = u'时间' + d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} + d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell} + d['lastPrice'] = {'chinese':u'最新价', 'cellType':BasicCell} + d['volume'] = {'chinese':u'成交量', 'cellType':BasicCell} + d['openInterest'] = {'chinese':u'持仓量', 'cellType':BasicCell} + d['openPrice'] = {'chinese':u'开盘价', 'cellType':BasicCell} + d['highPrice'] = {'chinese':u'最高价', 'cellType':BasicCell} + d['lowPrice'] = {'chinese':u'最低价', 'cellType':BasicCell} + d['bidPrice1'] = {'chinese':u'买一价', 'cellType':BidCell} + d['bidVolume1'] = {'chinese':u'买一量', 'cellType':BidCell} + d['askPrice1'] = {'chinese':u'卖一价', 'cellType':AskCell} + d['askVolume1'] = {'chinese':u'卖一量', 'cellType':AskCell} + d['time'] = {'chinese':u'时间', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) # 设置数据键 @@ -154,6 +316,9 @@ class MarketMonitor(BasicMonitor): # 设置监控事件类型 self.setEventType(EVENT_TICK) + # 设置字体 + self.setFont(BASIC_FONT) + # 初始化表格 self.initTable() @@ -170,13 +335,14 @@ class LogMonitor(BasicMonitor): """Constructor""" super(LogMonitor, self).__init__(eventEngine, parent) - d = OrderedDict() - d['gatewayName'] = u'接口' - d['logTime'] = u'时间' - d['logContent'] = u'内容' + d = OrderedDict() + d['logTime'] = {'chinese':u'时间', 'cellType':BasicCell} + d['logContent'] = {'chinese':u'内容', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setEventType(EVENT_LOG) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() @@ -190,13 +356,15 @@ class ErrorMonitor(BasicMonitor): """Constructor""" super(ErrorMonitor, self).__init__(eventEngine, parent) - d = OrderedDict() - d['gatewayName'] = u'接口' - d['errorID'] = u'错误代码' - d['errorMsg'] = u'错误信息' + d = OrderedDict() + d['errorID'] = {'chinese':u'错误代码', 'cellType':BasicCell} + d['errorMsg'] = {'chinese':u'错误信息', 'cellType':BasicCell} + d['additionalInfo'] = {'chinese':u'补充信息', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setEventType(EVENT_ERROR) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() @@ -211,18 +379,20 @@ class TradeMonitor(BasicMonitor): super(TradeMonitor, self).__init__(eventEngine, parent) d = OrderedDict() - d['gatewayName'] = u'接口' - d['tradeID'] = u'成交编号' - d['orderID'] = u'委托编号' - d['symbol'] = u'合约代码' - d['direction'] = u'方向' - d['offset'] = u'开平' - d['price'] = u'价格' - d['volume'] = u'数量' - d['tradeTime'] = u'成交时间' + d['tradeID'] = {'chinese':u'成交编号', 'cellType':BasicCell} + d['orderID'] = {'chinese':u'委托编号', 'cellType':BasicCell} + d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} + d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell} + d['direction'] = {'chinese':u'方向', 'cellType':DirectionCell} + d['offset'] = {'chinese':u'开平', 'cellType':BasicCell} + d['price'] = {'chinese':u'价格', 'cellType':BasicCell} + d['volume'] = {'chinese':u'数量', 'cellType':BasicCell} + d['tradeTime'] = {'chinese':u'成交时间', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setEventType(EVENT_TRADE) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() @@ -232,30 +402,57 @@ class OrderMonitor(BasicMonitor): """委托监控""" #---------------------------------------------------------------------- - def __init__(self, eventEngine, parent=None): + def __init__(self, eventEngine, mainEngine, parent=None): """Constructor""" super(OrderMonitor, self).__init__(eventEngine, parent) + + self.mainEngine = mainEngine d = OrderedDict() - d['gatewayName'] = u'接口' - d['orderID'] = u'委托编号' - d['symbol'] = u'合约代码' - d['direction'] = u'方向' - d['offset'] = u'开平' - d['price'] = u'价格' - d['totalVolume'] = u'委托数量' - d['tradedVolume'] = u'成交数量' - d['status'] = u'状态' - d['orderTime'] = u'委托时间' - d['tradeTime'] = u'撤销时间' - d['frontID'] = u'前置编号' - d['sessionID'] = u'会话编号' + d['orderID'] = {'chinese':u'委托编号', 'cellType':BasicCell} + d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} + d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell} + d['direction'] = {'chinese':u'方向', 'cellType':DirectionCell} + d['offset'] = {'chinese':u'开平', 'cellType':BasicCell} + d['price'] = {'chinese':u'价格', 'cellType':BasicCell} + d['totalVolume'] = {'chinese':u'委托数量', 'cellType':BasicCell} + d['tradedVolume'] = {'chinese':u'成交数量', 'cellType':BasicCell} + d['status'] = {'chinese':u'状态', 'cellType':BasicCell} + d['orderTime'] = {'chinese':u'委托时间', 'cellType':BasicCell} + d['cancelTime'] = {'chinese':u'撤销时间', 'cellType':BasicCell} + d['frontID'] = {'chinese':u'前置编号', 'cellType':BasicCell} + d['sessionID'] = {'chinese':u'会话编号', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setDataKey('vtOrderID') self.setEventType(EVENT_ORDER) + self.setFont(BASIC_FONT) + self.setSaveData(True) + self.initTable() self.registerEvent() + + self.connectSignal() + + #---------------------------------------------------------------------- + def connectSignal(self): + """连接信号""" + # 双击单元格撤单 + self.itemDoubleClicked.connect(self.cancelOrder) + + #---------------------------------------------------------------------- + def cancelOrder(self, cell): + """根据单元格的数据撤单""" + order = cell.data + + 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) ######################################################################## @@ -268,16 +465,18 @@ class PositionMonitor(BasicMonitor): super(PositionMonitor, self).__init__(eventEngine, parent) d = OrderedDict() - d['gatewayName'] = u'接口' - d['symbol'] = u'合约代码' - d['direction'] = u'方向' - d['position'] = u'持仓量' - d['frozen'] = u'冻结量' - d['price'] = u'价格' + d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} + d['vtSymbol'] = {'chinese':u'名称', 'cellType':NameCell} + d['direction'] = {'chinese':u'方向', 'cellType':DirectionCell} + d['position'] = {'chinese':u'持仓量', 'cellType':BasicCell} + d['frozen'] = {'chinese':u'冻结量', 'cellType':BasicCell} + d['price'] = {'chinese':u'价格', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setDataKey('vtPositionName') self.setEventType(EVENT_POSITION) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() @@ -292,20 +491,451 @@ class AccountMonitor(BasicMonitor): super(AccountMonitor, self).__init__(eventEngine, parent) d = OrderedDict() - d['gatewayName'] = u'接口' - d['accountID'] = u'账户' - d['preBalance'] = u'昨结' - d['balance'] = u'净值' - d['available'] = u'可用' - d['commission'] = u'手续费' - d['margin'] = u'保证金' - d['closeProfit'] = u'平仓盈亏' - d['positionProfit'] = u'持仓盈亏' + d['accountID'] = {'chinese':u'账户', 'cellType':BasicCell} + d['preBalance'] = {'chinese':u'昨结', 'cellType':BasicCell} + d['balance'] = {'chinese':u'净值', 'cellType':BasicCell} + d['available'] = {'chinese':u'可用', 'cellType':BasicCell} + d['commission'] = {'chinese':u'手续费', 'cellType':BasicCell} + d['margin'] = {'chinese':u'保证金', 'cellType':BasicCell} + d['closeProfit'] = {'chinese':u'平仓盈亏', 'cellType':BasicCell} + d['positionProfit'] = {'chinese':u'持仓盈亏', 'cellType':BasicCell} + d['gatewayName'] = {'chinese':u'接口', 'cellType':BasicCell} self.setHeaderDict(d) self.setDataKey('vtAccountID') self.setEventType(EVENT_ACCOUNT) + self.setFont(BASIC_FONT) self.initTable() self.registerEvent() + + +######################################################################## +class TradingWidget(QtGui.QFrame): + """简单交易组件""" + signal = QtCore.pyqtSignal(type(Event())) + + directionList = [DIRECTION_LONG, + DIRECTION_SHORT] + + offsetList = [OFFSET_OPEN, + OFFSET_CLOSE, + OFFSET_CLOSESYESTERDAY, + OFFSET_CLOSETODAY] + + priceTypeList = [PRICETYPE_LIMITPRICE, + PRICETYPE_MARKETPRICE, + PRICETYPE_FAK, + PRICETYPE_FOK] + + exchangeList = [EXCHANGE_NONE, + EXCHANGE_CFFEX, + EXCHANGE_SHFE, + EXCHANGE_DCE, + EXCHANGE_CZCE, + EXCHANGE_SSE, + EXCHANGE_SZSE] + + #---------------------------------------------------------------------- + def __init__(self, mainEngine, eventEngine, dataEngine, parent=None): + """Constructor""" + super(TradingWidget, self).__init__(parent) + self.mainEngine = mainEngine + self.eventEngine = eventEngine + self.dataEngine = dataEngine + + self.symbol = '' + + self.initUi() + self.connectSignal() + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setWindowTitle(u'交易') + self.setMaximumWidth(400) + self.setFrameShape(self.Box) # 设置边框 + self.setLineWidth(1) + + # 左边部分 + labelSymbol = QtGui.QLabel(u'代码') + labelName = QtGui.QLabel(u'名称') + labelDirection = QtGui.QLabel(u'方向类型') + labelOffset = QtGui.QLabel(u'开平') + labelPrice = QtGui.QLabel(u'价格') + labelVolume = QtGui.QLabel(u'数量') + labelPriceType = QtGui.QLabel(u'价格类型') + labelExchange = QtGui.QLabel(u'交易所') + + self.lineSymbol = QtGui.QLineEdit() + self.lineName = QtGui.QLineEdit() + + self.comboDirection = QtGui.QComboBox() + self.comboDirection.addItems(self.directionList) + + self.comboOffset = QtGui.QComboBox() + self.comboOffset.addItems(self.offsetList) + + self.spinPrice = QtGui.QDoubleSpinBox() + self.spinPrice.setDecimals(4) + self.spinPrice.setMinimum(0) + self.spinPrice.setMaximum(100000) + + self.spinVolume = QtGui.QSpinBox() + self.spinVolume.setMinimum(0) + self.spinVolume.setMaximum(1000000) + + self.comboPriceType = QtGui.QComboBox() + self.comboPriceType.addItems(self.priceTypeList) + + self.comboExchange = QtGui.QComboBox() + self.comboExchange.addItems(self.exchangeList) + + gridleft = QtGui.QGridLayout() + gridleft.addWidget(labelSymbol, 0, 0) + gridleft.addWidget(labelName, 1, 0) + gridleft.addWidget(labelDirection, 2, 0) + gridleft.addWidget(labelOffset, 3, 0) + gridleft.addWidget(labelPrice, 4, 0) + gridleft.addWidget(labelVolume, 5, 0) + gridleft.addWidget(labelPriceType, 6, 0) + gridleft.addWidget(labelExchange, 7, 0) + gridleft.addWidget(self.lineSymbol, 0, 1) + gridleft.addWidget(self.lineName, 1, 1) + gridleft.addWidget(self.comboDirection, 2, 1) + gridleft.addWidget(self.comboOffset, 3, 1) + gridleft.addWidget(self.spinPrice, 4, 1) + gridleft.addWidget(self.spinVolume, 5, 1) + gridleft.addWidget(self.comboPriceType, 6, 1) + gridleft.addWidget(self.comboExchange, 7, 1) + + # 右边部分 + labelBid1 = QtGui.QLabel(u'买一') + labelBid2 = QtGui.QLabel(u'买二') + labelBid3 = QtGui.QLabel(u'买三') + labelBid4 = QtGui.QLabel(u'买四') + labelBid5 = QtGui.QLabel(u'买五') + + labelAsk1 = QtGui.QLabel(u'卖一') + labelAsk2 = QtGui.QLabel(u'卖二') + labelAsk3 = QtGui.QLabel(u'卖三') + labelAsk4 = QtGui.QLabel(u'卖四') + labelAsk5 = QtGui.QLabel(u'卖五') + + self.labelBidPrice1 = QtGui.QLabel() + self.labelBidPrice2 = QtGui.QLabel() + self.labelBidPrice3 = QtGui.QLabel() + self.labelBidPrice4 = QtGui.QLabel() + self.labelBidPrice5 = QtGui.QLabel() + self.labelBidVolume1 = QtGui.QLabel() + self.labelBidVolume2 = QtGui.QLabel() + self.labelBidVolume3 = QtGui.QLabel() + self.labelBidVolume4 = QtGui.QLabel() + self.labelBidVolume5 = QtGui.QLabel() + + self.labelAskPrice1 = QtGui.QLabel() + self.labelAskPrice2 = QtGui.QLabel() + self.labelAskPrice3 = QtGui.QLabel() + self.labelAskPrice4 = QtGui.QLabel() + self.labelAskPrice5 = QtGui.QLabel() + self.labelAskVolume1 = QtGui.QLabel() + self.labelAskVolume2 = QtGui.QLabel() + self.labelAskVolume3 = QtGui.QLabel() + self.labelAskVolume4 = QtGui.QLabel() + self.labelAskVolume5 = QtGui.QLabel() + + labelLast = QtGui.QLabel(u'最新') + self.labelLastPrice = QtGui.QLabel() + self.labelReturn = QtGui.QLabel() + + self.labelLastPrice.setMinimumWidth(60) + self.labelReturn.setMinimumWidth(60) + + gridRight = QtGui.QGridLayout() + gridRight.addWidget(labelAsk5, 0, 0) + gridRight.addWidget(labelAsk4, 1, 0) + gridRight.addWidget(labelAsk3, 2, 0) + gridRight.addWidget(labelAsk2, 3, 0) + gridRight.addWidget(labelAsk1, 4, 0) + gridRight.addWidget(labelLast, 5, 0) + gridRight.addWidget(labelBid1, 6, 0) + gridRight.addWidget(labelBid2, 7, 0) + gridRight.addWidget(labelBid3, 8, 0) + gridRight.addWidget(labelBid4, 9, 0) + gridRight.addWidget(labelBid5, 10, 0) + + gridRight.addWidget(self.labelAskPrice5, 0, 1) + gridRight.addWidget(self.labelAskPrice4, 1, 1) + gridRight.addWidget(self.labelAskPrice3, 2, 1) + gridRight.addWidget(self.labelAskPrice2, 3, 1) + gridRight.addWidget(self.labelAskPrice1, 4, 1) + gridRight.addWidget(self.labelLastPrice, 5, 1) + gridRight.addWidget(self.labelBidPrice1, 6, 1) + gridRight.addWidget(self.labelBidPrice2, 7, 1) + gridRight.addWidget(self.labelBidPrice3, 8, 1) + gridRight.addWidget(self.labelBidPrice4, 9, 1) + gridRight.addWidget(self.labelBidPrice5, 10, 1) + + gridRight.addWidget(self.labelAskVolume5, 0, 2) + gridRight.addWidget(self.labelAskVolume4, 1, 2) + gridRight.addWidget(self.labelAskVolume3, 2, 2) + gridRight.addWidget(self.labelAskVolume2, 3, 2) + gridRight.addWidget(self.labelAskVolume1, 4, 2) + gridRight.addWidget(self.labelReturn, 5, 2) + gridRight.addWidget(self.labelBidVolume1, 6, 2) + gridRight.addWidget(self.labelBidVolume2, 7, 2) + gridRight.addWidget(self.labelBidVolume3, 8, 2) + gridRight.addWidget(self.labelBidVolume4, 9, 2) + gridRight.addWidget(self.labelBidVolume5, 10, 2) + + # 发单按钮 + buttonSendOrder = QtGui.QPushButton(u'发单') + buttonCancelAll = QtGui.QPushButton(u'全撤') + + size = buttonSendOrder.sizeHint() + buttonSendOrder.setMinimumHeight(size.height()*2) # 把按钮高度设为默认两倍 + buttonCancelAll.setMinimumHeight(size.height()*2) + + # 整合布局 + hbox = QtGui.QHBoxLayout() + hbox.addLayout(gridleft) + hbox.addLayout(gridRight) + + vbox = QtGui.QVBoxLayout() + vbox.addLayout(hbox) + vbox.addWidget(buttonSendOrder) + vbox.addWidget(buttonCancelAll) + vbox.addStretch() + + self.setLayout(vbox) + + # 关联更新 + buttonSendOrder.clicked.connect(self.sendOrder) + buttonCancelAll.clicked.connect(self.cancelAll) + self.lineSymbol.returnPressed.connect(self.updateSymbol) + + #---------------------------------------------------------------------- + def updateSymbol(self): + """合约变化""" + symbol = unicode(self.lineSymbol.text()) + exchange = unicode(self.comboExchange.currentText()) + + if exchange: + vtSymbol = '.'.join([symbol, exchange]) + contract = self.dataEngine.getContract(vtSymbol) + else: + contract = self.dataEngine.getContract(symbol) + + if contract: + exchange = contract.exchange # 保证有交易所代码 + + self.lineName.setText(contract.name)#.decode('GBK')) + + # 清空价格数量 + self.spinPrice.setValue(0) + self.spinVolume.setValue(0) + + # 清空行情显示 + self.labelBidPrice1.setText('') + self.labelBidPrice2.setText('') + self.labelBidPrice3.setText('') + self.labelBidPrice4.setText('') + self.labelBidPrice5.setText('') + self.labelBidVolume1.setText('') + self.labelBidVolume2.setText('') + self.labelBidVolume3.setText('') + self.labelBidVolume4.setText('') + self.labelBidVolume5.setText('') + self.labelAskPrice1.setText('') + self.labelAskPrice2.setText('') + self.labelAskPrice3.setText('') + self.labelAskPrice4.setText('') + self.labelAskPrice5.setText('') + self.labelAskVolume1.setText('') + self.labelAskVolume2.setText('') + self.labelAskVolume3.setText('') + self.labelAskVolume4.setText('') + self.labelAskVolume5.setText('') + self.labelLastPrice.setText('') + self.labelReturn.setText('') + + # 重新注册事件监听 + self.eventEngine.unregister(EVENT_TICK + self.symbol, self.signal.emit) + self.eventEngine.register(EVENT_TICK + contract.vtSymbol, self.signal.emit) + + # 订阅合约 + req = VtSubscribeReq() + req.symbol = symbol + req.exchange = exchange + self.mainEngine.subscribe(req, contract.gatewayName) + + # 更新组件当前交易的合约 + self.symbol = contract.vtSymbol + + #---------------------------------------------------------------------- + def updateTick(self, event): + """更新行情""" + tick = event.dict_['data'] + + if tick.vtSymbol == self.symbol: + self.labelBidPrice1.setText(str(tick.bidPrice1)) + self.labelAskPrice1.setText(str(tick.askPrice1)) + self.labelBidVolume1.setText(str(tick.bidVolume1)) + self.labelAskVolume1.setText(str(tick.askVolume1)) + + if tick.bidPrice2: + self.labelBidPrice2.setText(str(tick.bidPrice2)) + self.labelBidPrice3.setText(str(tick.bidPrice3)) + self.labelBidPrice4.setText(str(tick.bidPrice4)) + self.labelBidPrice5.setText(str(tick.bidPrice5)) + + self.labelAskPrice2.setText(str(tick.askPrice2)) + self.labelAskPrice3.setText(str(tick.askPrice3)) + self.labelAskPrice4.setText(str(tick.askPrice4)) + self.labelAskPrice5.setText(str(tick.askPrice5)) + + self.labelBidVolume2.setText(str(tick.bidVolume2)) + self.labelBidVolume3.setText(str(tick.bidVolume3)) + self.labelBidVolume4.setText(str(tick.bidVolume4)) + self.labelBidVolume5.setText(str(tick.bidVolume5)) + + self.labelAskVolume2.setText(str(tick.askVolume2)) + self.labelAskVolume3.setText(str(tick.askVolume3)) + self.labelAskVolume4.setText(str(tick.askVolume4)) + self.labelAskVolume5.setText(str(tick.askVolume5)) + + self.labelLastPrice.setText(str(tick.lastPrice)) + rt = (tick.lastPrice/tick.preClosePrice)-1 + self.labelReturn.setText(('%.2f' %(rt*100))+'%') + + #---------------------------------------------------------------------- + def connectSignal(self): + """连接Signal""" + self.signal.connect(self.updateTick) + + #---------------------------------------------------------------------- + def sendOrder(self): + """发单""" + symbol = str(self.lineSymbol.text()) + exchange = str(self.comboExchange.currentText()) + + if exchange: + vtSymbol = '.'.join([symbol, exchange]) + contract = self.dataEngine.getContract(vtSymbol) + else: + contract = self.dataEngine.getContract(symbol) + + if contract: + req = VtOrderReq() + req.symbol = symbol + req.exchange = contract.exchange + req.price = self.spinPrice.value() + req.volume = self.spinVolume.value() + req.direction = unicode(self.comboDirection.currentText()) + req.priceType = unicode(self.comboPriceType.currentText()) + req.offset = unicode(self.comboOffset.currentText()) + self.mainEngine.sendOrder(req, contract.gatewayName) + + #---------------------------------------------------------------------- + def cancelAll(self): + """一键撤销所有委托""" + l = self.dataEngine.getAllWorkingOrders() + for order in l: + 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) + + +######################################################################## +class ContractMonitor(BasicMonitor): + """合约查询""" + + #---------------------------------------------------------------------- + def __init__(self, dataEngine, parent=None): + """Constructor""" + super(ContractMonitor, self).__init__(parent=parent) + + self.dataEngine = dataEngine + + d = OrderedDict() + d['symbol'] = {'chinese':u'合约代码', 'cellType':BasicCell} + d['exchange'] = {'chinese':u'交易所', 'cellType':BasicCell} + d['vtSymbol'] = {'chinese':u'vt系统代码', 'cellType':BasicCell} + d['name'] = {'chinese':u'名称', 'cellType':BasicCell} + d['productClass'] = {'chinese':u'合约类型', 'cellType':BasicCell} + d['size'] = {'chinese':u'大小', 'cellType':BasicCell} + d['priceTick'] = {'chinese':u'最小价格变动', 'cellType':BasicCell} + #d['strikePrice'] = {'chinese':u'期权行权价', 'cellType':BasicCell} + #d['underlyingSymbol'] = {'chinese':u'期权标的物', 'cellType':BasicCell} + #d['optionType'] = {'chinese':u'期权类型', 'cellType':BasicCell} + self.setHeaderDict(d) + + self.initUi() + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setWindowTitle(u'合约查询') + self.setMinimumSize(800, 800) + self.setFont(BASIC_FONT) + self.initTable() + self.initMenu() + + #---------------------------------------------------------------------- + def showAllContracts(self): + """显示所有合约数据""" + l = self.dataEngine.getAllContracts() + d = {'.'.join([contract.exchange, contract.symbol]):contract for contract in l} + l2 = d.keys() + l2.sort(reverse=True) + + self.setRowCount(len(l2)) + row = 0 + + for key in l2: + contract = d[key] + + for n, header in enumerate(self.headerList): + content = safeUnicode(contract.__getattribute__(header)) + cellType = self.headerDict[header]['cellType'] + cell = cellType(content) + + if self.font: + cell.setFont(self.font) # 如果设置了特殊字体,则进行单元格设置 + + self.setItem(row, n, cell) + + row = row + 1 + + #---------------------------------------------------------------------- + def refresh(self): + """刷新""" + self.clearContents() + self.setRowCount(0) + self.showAllContracts() + self.menu.close() # 关闭菜单 + + #---------------------------------------------------------------------- + def initMenu(self): + """初始化右键菜单""" + refreshAction = QtGui.QAction(u'刷新', self) + refreshAction.triggered.connect(self.refresh) + + self.menu = QtGui.QMenu(self) + self.menu.addAction(refreshAction) + + #---------------------------------------------------------------------- + def contextMenuEvent(self, event): + """右键点击事件""" + self.menu.popup(QtGui.QCursor.pos()) + + #---------------------------------------------------------------------- + def show(self): + """显示""" + super(ContractMonitor, self).show() + self.refresh() \ No newline at end of file diff --git a/vn.trader/uiCtaWidget.py b/vn.trader/uiCtaWidget.py new file mode 100644 index 00000000..d37935bd --- /dev/null +++ b/vn.trader/uiCtaWidget.py @@ -0,0 +1,248 @@ +# encoding: UTF-8 + +'''CTA模块相关的GUI控制组件''' + +from uiBasicWidget import QtGui, QtCore, BasicCell +from eventEngine import * + + +######################################################################## +class ValueMonitor(QtGui.QTableWidget): + """数值监控""" + signal = QtCore.pyqtSignal() + + #---------------------------------------------------------------------- + def __init__(self, parent=None): + """Constructor""" + super(ValueMonitor , self).__init__(parent) + + self.keyCellDict = {} + self.row = 0 + self.data = None + + self.initUi() + self.signal.connect(self.updateTable) + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setColumnCount(2) + + self.verticalHeader().setVisible(False) + self.horizontalHeader().setVisible(False) + + self.setEditTriggers(self.NoEditTriggers) + self.setAlternatingRowColors(True) + + #---------------------------------------------------------------------- + def updateData(self, data): + """更新数据""" + self.data = data + self.signal.emit() + + #---------------------------------------------------------------------- + def updateTable(self): + """更新表格""" + for key, value in self.data.items(): + if key in self.keyCellDict: + cell = self.keyCellDict[key] + cell.setText(unicode(value)) + else: + # 创建并保存单元格 + keyCell = BasicCell(unicode(key)) + cell = BasicCell(unicode(value)) + self.keyCellDict[key] = cell + + # 移动到下一行 + self.insertRow(self.row) + self.setItem(self.row, 0, keyCell) + self.setItem(self.row, 1, cell) + self.row += 1 + + +######################################################################## +class CtaStrategyManager(QtGui.QGroupBox): + """策略管理组件""" + + #---------------------------------------------------------------------- + def __init__(self, ctaEngine, eventEngine, name, parent=None): + """Constructor""" + super(CtaStrategyManager, self).__init__(parent) + + self.ctaEngine = ctaEngine + self.eventEngine = eventEngine + self.name = name + + self.initUi() + self.updateMonitor() + self.registerEvent() + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setTitle(self.name) + + paramLabel = QtGui.QLabel(u'参数') + varLabel = QtGui.QLabel(u'变量') + + self.paramMonitor = ValueMonitor(self) + self.varMonitor = ValueMonitor(self) + + buttonStart = QtGui.QPushButton(u'启动') + buttonStop = QtGui.QPushButton(u'停止') + buttonStart.clicked.connect(self.start) + buttonStop.clicked.connect(self.stop) + + hbox = QtGui.QHBoxLayout() + hbox.addWidget(buttonStart) + hbox.addWidget(buttonStop) + hbox.addStretch() + + vbox = QtGui.QVBoxLayout() + vbox.addLayout(hbox) + vbox.addWidget(paramLabel) + vbox.addWidget(self.paramMonitor) + vbox.addWidget(varLabel) + vbox.addWidget(self.varMonitor) + self.setLayout(vbox) + + #---------------------------------------------------------------------- + def updateMonitor(self, event=None): + """显示策略最新状态""" + paramDict = self.ctaEngine.getStrategyParam(self.name) + if paramDict: + self.paramMonitor.updateData(paramDict) + + varDict = self.ctaEngine.getStrategyVar(self.name) + if varDict: + self.varMonitor.updateData(varDict) + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + self.eventEngine.register(EVENT_TIMER, self.updateMonitor) + + #---------------------------------------------------------------------- + def start(self): + """启动策略""" + self.ctaEngine.startStrategy(self.name) + + #---------------------------------------------------------------------- + def stop(self): + """停止策略""" + self.ctaEngine.stopStrategy(self.name) + + + +######################################################################## +class CtaEngineManager(QtGui.QWidget): + """CTA引擎管理组件""" + signal = QtCore.pyqtSignal(type(Event())) + + #---------------------------------------------------------------------- + def __init__(self, ctaEngine, eventEngine, parent=None): + """Constructor""" + super(CtaEngineManager, self).__init__(parent) + + self.ctaEngine = ctaEngine + self.eventEngine = eventEngine + + self.strategyLoaded = False + + self.initUi() + self.registerEvent() + + # 记录日志 + self.ctaEngine.writeCtaLog(u'CTA引擎启动成功') + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setWindowTitle(u'CTA策略') + + # 按钮 + loadButton = QtGui.QPushButton(u'加载策略') + startAllButton = QtGui.QPushButton(u'全部启动') + stopAllButton = QtGui.QPushButton(u'全部停止') + + loadButton.clicked.connect(self.load) + startAllButton.clicked.connect(self.startAll) + stopAllButton.clicked.connect(self.stopAll) + + # 滚动区域,放置所有的CtaStrategyManager + self.scrollArea = QtGui.QScrollArea() + + # CTA组件的日志监控 + self.ctaLogMonitor = QtGui.QTextEdit() + self.ctaLogMonitor.setReadOnly(True) + + # 设置布局 + hbox2 = QtGui.QHBoxLayout() + hbox2.addWidget(loadButton) + hbox2.addWidget(startAllButton) + hbox2.addWidget(stopAllButton) + hbox2.addStretch() + + vbox = QtGui.QVBoxLayout() + vbox.addLayout(hbox2) + vbox.addWidget(self.scrollArea) + vbox.addWidget(self.ctaLogMonitor) + self.setLayout(vbox) + + #---------------------------------------------------------------------- + def initStrategyManager(self): + """初始化策略管理组件界面""" + w = QtGui.QWidget() + hbox = QtGui.QHBoxLayout() + + for name in self.ctaEngine.strategyDict.keys(): + strategyManager = CtaStrategyManager(self.ctaEngine, self.eventEngine, name) + hbox.addWidget(strategyManager) + + w.setLayout(hbox) + self.scrollArea.setWidget(w) + + #---------------------------------------------------------------------- + def startAll(self): + """全部启动""" + for name in self.ctaEngine.strategyDict.keys(): + self.ctaEngine.startStrategy(name) + + #---------------------------------------------------------------------- + def stopAll(self): + """全部停止""" + for name in self.ctaEngine.strategyDict.keys(): + self.ctaEngine.stopStrategy(name) + + #---------------------------------------------------------------------- + def load(self): + """加载策略""" + if not self.strategyLoaded: + self.ctaEngine.loadStrategySetting() + self.initStrategyManager() + self.strategyLoaded = True + self.ctaEngine.writeCtaLog(u'策略加载成功') + + #---------------------------------------------------------------------- + def updateCtaLog(self, event): + """更新CTA相关日志""" + log = event.dict_['data'] + content = '\t'.join([log.logTime, log.logContent]) + self.ctaLogMonitor.append(content) + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + self.signal.connect(self.updateCtaLog) + self.eventEngine.register(EVENT_CTA_LOG, self.signal.emit) + + + + + + + + + + + \ No newline at end of file diff --git a/vn.trader/uiMainWindow.py b/vn.trader/uiMainWindow.py new file mode 100644 index 00000000..4ac0f868 --- /dev/null +++ b/vn.trader/uiMainWindow.py @@ -0,0 +1,289 @@ +# encoding: UTF-8 + +import psutil + +from uiBasicWidget import * +from uiCtaWidget import CtaEngineManager + +######################################################################## +class MainWindow(QtGui.QMainWindow): + """主窗口""" + + #---------------------------------------------------------------------- + def __init__(self, mainEngine, eventEngine, dataEngine): + """Constructor""" + super(MainWindow, self).__init__() + + self.mainEngine = mainEngine + self.eventEngine = eventEngine + self.dataEngine = dataEngine + + self.initUi() + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setWindowTitle('VnTrader') + self.initCentral() + self.initMenu() + self.initStatusBar() + + #---------------------------------------------------------------------- + def initCentral(self): + """初始化中心区域""" + marketM = MarketMonitor(self.eventEngine) + logM = LogMonitor(self.eventEngine) + errorM = ErrorMonitor(self.eventEngine) + tradeM = TradeMonitor(self.eventEngine) + orderM = OrderMonitor(self.eventEngine, self.mainEngine) + positionM = PositionMonitor(self.eventEngine) + accountM = AccountMonitor(self.eventEngine) + + tradingW = TradingWidget(self.mainEngine, self.mainEngine.eventEngine, self.mainEngine.dataEngine) + + leftTab = QtGui.QTabWidget() + leftTab.addTab(logM, u'日志') + leftTab.addTab(errorM, u'错误') + leftTab.addTab(accountM, u'账户') + + rightTab = QtGui.QTabWidget() + rightTab.addTab(tradeM, u'成交') + rightTab.addTab(orderM, u'委托') + rightTab.addTab(positionM, u'持仓') + + hbox = QtGui.QHBoxLayout() + hbox.addWidget(tradingW) + hbox.addWidget(marketM) + + grid = QtGui.QGridLayout() + grid.addLayout(hbox, 0, 0, 1, 2) + grid.addWidget(leftTab, 1, 0) + grid.addWidget(rightTab, 1, 1) + + central = QtGui.QWidget() + central.setLayout(grid) + self.setCentralWidget(central) + + #---------------------------------------------------------------------- + def initMenu(self): + """初始化菜单""" + # 创建操作 + connectCtpAction = QtGui.QAction(u'连接CTP', self) + connectCtpAction.triggered.connect(self.connectCtp) + + connectLtsAction = QtGui.QAction(u'连接LTS', self) + connectLtsAction.triggered.connect(self.connectLts) + + connectWindAction = QtGui.QAction(u'连接Wind', self) + connectWindAction.triggered.connect(self.connectWind) + + testAction = QtGui.QAction(u'测试', self) + testAction.triggered.connect(self.testSubscribe) + + exitAction = QtGui.QAction(u'退出', self) + exitAction.triggered.connect(self.close) + + aboutAction = QtGui.QAction(u'关于', self) + aboutAction.triggered.connect(self.openAbout) + + contractAction = QtGui.QAction(u'查询合约', self) + contractAction.triggered.connect(self.openContract) + + ctaAction = QtGui.QAction(u'CTA策略', self) + ctaAction.triggered.connect(self.openCta) + + # 创建菜单 + menubar = self.menuBar() + + sysMenu = menubar.addMenu(u'系统') + sysMenu.addAction(connectCtpAction) + sysMenu.addAction(connectLtsAction) + sysMenu.addAction(connectWindAction) + sysMenu.addAction(testAction) + sysMenu.addAction(exitAction) + + functionMenu = menubar.addMenu(u'功能') + functionMenu.addAction(contractAction) + functionMenu.addAction(ctaAction) + + helpMenu = menubar.addMenu(u'帮助') + helpMenu.addAction(aboutAction) + + #---------------------------------------------------------------------- + def initStatusBar(self): + """初始化状态栏""" + self.statusLabel = QtGui.QLabel() + self.statusLabel.setAlignment(QtCore.Qt.AlignLeft) + + self.statusBar().addPermanentWidget(self.statusLabel) + self.statusLabel.setText(self.getCpuMemory()) + + self.sbCount = 0 + self.sbTrigger = 10 # 10秒刷新一次 + self.eventEngine.register(EVENT_TIMER, self.updateStatusBar) + + #---------------------------------------------------------------------- + def updateStatusBar(self, event): + """在状态栏更新CPU和内存信息""" + self.sbCount += 1 + + if self.sbCount == self.sbTrigger: + self.sbCount = 0 + self.statusLabel.setText(self.getCpuMemory()) + + #---------------------------------------------------------------------- + def getCpuMemory(self): + """获取CPU和内存状态信息""" + cpuPercent = psutil.cpu_percent() + memoryPercent = psutil.virtual_memory().percent + return u'CPU使用率:%d%% 内存使用率:%d%%' % (cpuPercent, memoryPercent) + + #---------------------------------------------------------------------- + def connectCtp(self): + """连接CTP接口""" + self.mainEngine.connect('CTP') + + #---------------------------------------------------------------------- + def connectLts(self): + """连接LTS接口""" + self.mainEngine.connect('LTS') + + #---------------------------------------------------------------------- + def connectWind(self): + """连接Wind接口""" + self.mainEngine.connect('Wind') + + #---------------------------------------------------------------------- + def testSubscribe(self): + """测试订阅""" + req = VtSubscribeReq() + req.symbol = '600000' + req.exchange = EXCHANGE_SSE + self.mainEngine.subscribe(req, 'Wind') + + req = VtSubscribeReq() + req.symbol = '000062' + req.exchange = EXCHANGE_SZSE + self.mainEngine.subscribe(req, 'Wind') + + req = VtSubscribeReq() + req.symbol = 'IF1511' + req.exchange = EXCHANGE_CFFEX + self.mainEngine.subscribe(req, 'Wind') + + req = VtSubscribeReq() + req.symbol = 'CU1601' + req.exchange = EXCHANGE_SHFE + self.mainEngine.subscribe(req, 'Wind') + + req = VtSubscribeReq() + req.symbol = 'C1601' + req.exchange = EXCHANGE_DCE + self.mainEngine.subscribe(req, 'Wind') + + req = VtSubscribeReq() + req.symbol = 'SR1601' + req.exchange = EXCHANGE_CZCE + self.mainEngine.subscribe(req, 'Wind') + + #---------------------------------------------------------------------- + def openAbout(self): + """打开关于""" + try: + self.aboutW.show() + except AttributeError: + self.aboutW = AboutWidget(self) + self.aboutW.show() + + #---------------------------------------------------------------------- + def openContract(self): + """打开合约查询""" + try: + self.contractM.show() + except AttributeError: + self.contractM = ContractMonitor(self.mainEngine.dataEngine) + self.contractM.show() + + #---------------------------------------------------------------------- + def openCta(self): + """打开CTA组件""" + try: + self.ctaM.show() + except AttributeError: + self.ctaM = CtaEngineManager(self.mainEngine.ctaEngine, self.eventEngine) + self.ctaM.show() + + #---------------------------------------------------------------------- + def closeEvent(self, event): + """关闭事件""" + reply = QtGui.QMessageBox.question(self, u'退出', + u'确认退出?', QtGui.QMessageBox.Yes | + QtGui.QMessageBox.No, QtGui.QMessageBox.No) + + if reply == QtGui.QMessageBox.Yes: + self.mainEngine.exit() + event.accept() + else: + event.ignore() + + +######################################################################## +class AboutWidget(QtGui.QDialog): + """显示关于信息""" + + #---------------------------------------------------------------------- + def __init__(self, parent=None): + """Constructor""" + super(AboutWidget, self).__init__(parent) + + self.initUi() + + #---------------------------------------------------------------------- + def initUi(self): + """""" + self.setWindowTitle(u'关于') + + text = u""" + VnTrader + + 更新日期:2015/9/29 + + 作者:用Python的交易员 + + License:MIT + + 主页:vnpy.org + + Github:github.com/vnpy/vnpy + + QQ交流群:262656087 + + + + + 开发环境 + + 操作系统:Windows 7 专业版 64位 + + Python发行版:Python 2.7.6 (Anaconda 1.9.2 Win-32) + + CTP:vn.ctp 2015/6/1版 + + 图形库:PyQt4 4.11.3 Py2.7-x32 + + 事件驱动引擎:vn.event + + 开发环境:WingIDE 5.0.6 + + + """ + + label = QtGui.QLabel() + label.setText(text) + label.setMinimumWidth(500) + + vbox = QtGui.QVBoxLayout() + vbox.addWidget(label) + + self.setLayout(vbox) + \ No newline at end of file diff --git a/vn.trader/vnltsmd.pyd b/vn.trader/vnltsmd.pyd new file mode 100644 index 00000000..ca26f785 Binary files /dev/null and b/vn.trader/vnltsmd.pyd differ diff --git a/vn.trader/vnltsqry.pyd b/vn.trader/vnltsqry.pyd new file mode 100644 index 00000000..f701f93d Binary files /dev/null and b/vn.trader/vnltsqry.pyd differ diff --git a/vn.trader/vnltstd.pyd b/vn.trader/vnltstd.pyd new file mode 100644 index 00000000..3fe5e236 Binary files /dev/null and b/vn.trader/vnltstd.pyd differ diff --git a/vn.trader/vnpy.ico b/vn.trader/vnpy.ico new file mode 100644 index 00000000..d7013599 Binary files /dev/null and b/vn.trader/vnpy.ico differ diff --git a/vn.trader/vtConstant.py b/vn.trader/vtConstant.py new file mode 100644 index 00000000..10612119 --- /dev/null +++ b/vn.trader/vtConstant.py @@ -0,0 +1,57 @@ +# encoding: UTF-8 + +# 默认空值 +EMPTY_STRING = '' +EMPTY_UNICODE = u'' +EMPTY_INT = 0 +EMPTY_FLOAT = 0.0 + +# 方向常量 +DIRECTION_NONE = u'无方向' +DIRECTION_LONG = u'多' +DIRECTION_SHORT = u'空' +DIRECTION_UNKNOWN = u'未知' +DIRECTION_NET = u'净' + +# 开平常量 +OFFSET_NONE = u'无开平' +OFFSET_OPEN = u'开仓' +OFFSET_CLOSE = u'平仓' +OFFSET_CLOSETODAY = u'平今' +OFFSET_CLOSESYESTERDAY = u'平昨' +OFFSET_UNKNOWN = u'未知' + +# 状态常量 +STATUS_NOTTRADED = u'未成交' +STATUS_PARTTRADED = u'部分成交' +STATUS_ALLTRADED = u'全部成交' +STATUS_CANCELLED = u'已撤销' +STATUS_UNKNOWN = u'未知' + +# 合约类型常量 +PRODUCT_EQUITY = u'股票' +PRODUCT_FUTURES = u'期货' +PRODUCT_OPTION = u'期权' +PRODUCT_INDEX = u'指数' +PRODUCT_COMBINATION = u'组合' +PRODUCT_UNKNOWN = u'未知' + +# 价格类型常量 +PRICETYPE_LIMITPRICE = u'限价' +PRICETYPE_MARKETPRICE = u'市价' +PRICETYPE_FAK = u'FAK' +PRICETYPE_FOK = u'FOK' + +# 期权类型 +OPTION_CALL = u'看涨期权' +OPTION_PUT = u'看跌期权' + +# 交易所类型 +EXCHANGE_SSE = u'SSE' # 上交所 +EXCHANGE_SZSE = u'SZSE' # 深交所 +EXCHANGE_CFFEX = u'CFFEX' # 中金所 +EXCHANGE_SHFE = u'SHFE' # 上期所 +EXCHANGE_CZCE = u'CZCE' # 郑商所 +EXCHANGE_DCE = u'DCE' # 大商所 +EXCHANGE_UNKNOWN = 'UNKNOWN'# 未知交易所 +EXCHANGE_NONE = '' # 空交易所 \ No newline at end of file diff --git a/vn.trader/vtEngine.py b/vn.trader/vtEngine.py index 5e2107d9..f8a0f80e 100644 --- a/vn.trader/vtEngine.py +++ b/vn.trader/vtEngine.py @@ -1,8 +1,17 @@ # encoding: UTF-8 +import shelve + +from pymongo import MongoClient +from pymongo.errors import ConnectionFailure from eventEngine import * from ctpGateway import CtpGateway +from ltsGateway import LtsGateway +from windGateway import WindGateway +from vtGateway import * +import uiBasicWidget +from ctaEngine import CtaEngine ######################################################################## @@ -16,12 +25,28 @@ class MainEngine(object): self.eventEngine = EventEngine() self.eventEngine.start() + # 创建数据引擎 + self.dataEngine = DataEngine(self.eventEngine) + uiBasicWidget.NameCell.setDataEngine(uiBasicWidget.NameCell, self.dataEngine) # 将数据引擎对象传给NameCell + # 用来保存接口对象的字典 self.gatewayDict = {} # 创建我们想要接入的接口对象 self.addGateway(CtpGateway, 'CTP') + self.gatewayDict['CTP'].setQryEnabled(True) + self.addGateway(LtsGateway, 'LTS') + self.gatewayDict['LTS'].setQryEnabled(True) + + self.addGateway(WindGateway, 'Wind') # 没有Wind的请注释掉这一行 + + # MongoDB数据库相关 + self.dbClient = None # MongoDB客户端对象 + + # CTA引擎 + self.ctaEngine = CtaEngine(self, self.eventEngine, self.dataEngine) + #---------------------------------------------------------------------- def addGateway(self, gateway, gatewayName=None): """创建接口""" @@ -30,45 +55,203 @@ class MainEngine(object): #---------------------------------------------------------------------- def connect(self, gatewayName): """连接特定名称的接口""" - gateway = self.gatewayDict[gatewayName] - gateway.connect() + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + gateway.connect() + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def subscribe(self, subscribeReq, gatewayName): """订阅特定接口的行情""" - gateway = self.gatewayDict[gatewayName] - gateway.subscribe(subscribeReq) + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + gateway.subscribe(subscribeReq) + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def sendOrder(self, orderReq, gatewayName): """对特定接口发单""" - gateway = self.gatewayDict[gatewayName] - return gateway.sendOrder(orderReq) + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + return gateway.sendOrder(orderReq) + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def cancelOrder(self, cancelOrderReq, gatewayName): """对特定接口撤单""" - gateway = self.gatewayDict[gatewayName] - gateway.cancelOrder(cancelOrderReq) + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + gateway.cancelOrder(cancelOrderReq) + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def getAccont(self, gatewayName): """查询特定接口的账户""" - gateway = self.gatewayDict[gatewayName] - gateway.getAccount() + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + gateway.getAccount() + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def getPosition(self, gatewayName): """查询特定接口的持仓""" - gateway = self.gatewayDict[gatewayName] - gateway.getPosition() + if gatewayName in self.gatewayDict: + gateway = self.gatewayDict[gatewayName] + gateway.getPosition() + else: + self.writeLog(u'接口不存在:%s' %gatewayName) #---------------------------------------------------------------------- def exit(self): - """退出程序前调用,保证正常退出""" - # 停止事件引擎 - self.eventEngine.stop() - + """退出程序前调用,保证正常退出""" # 安全关闭所有接口 - for gateway in self.gatewayDict.values(): - gateway.close() \ No newline at end of file + for gateway in self.gatewayDict.values(): + gateway.close() + + # 停止事件引擎 + self.eventEngine.stop() + + # 保存数据引擎里的合约数据到硬盘 + self.dataEngine.saveContracts() + + #---------------------------------------------------------------------- + def writeLog(self, content): + """快速发出日志事件""" + log = VtLogData() + log.logContent = content + event = Event(type_=EVENT_LOG) + event.dict_['data'] = log + self.eventEngine.put(event) + + #---------------------------------------------------------------------- + def dbConnect(self): + """连接MongoDB数据库""" + if not self.dbClient: + try: + self.dbClient = MongoClient() + self.writeLog(u'MongoDB连接成功') + except ConnectionFailure: + self.writeLog(u'MongoDB连接失败') + + #---------------------------------------------------------------------- + def dbInsert(self, dbName, collectionName, d): + """向MongoDB中插入数据,d是具体数据""" + if self.dbClient: + db = self.dbClient[dbName] + collection = db[collectionName] + collection.insert(d) + + #---------------------------------------------------------------------- + def dbQuery(self, dbName, collectionName, d): + """从MongoDB中读取数据,d是查询要求,返回的是数据库查询的指针""" + if self.dbClient: + db = self.dbClient[dbName] + collection = db[collectionName] + cursor = collection.find(d) + return cursor + else: + return None + + +######################################################################## +class DataEngine(object): + """数据引擎""" + contractFileName = 'ContractData.vt' + + #---------------------------------------------------------------------- + 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.contractFileName) + f['data'] = self.contractDict + f.close() + + #---------------------------------------------------------------------- + def loadContracts(self): + """从硬盘读取合约对象""" + f = shelve.open(self.contractFileName) + 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 == STATUS_ALLTRADED or order.status == 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) + + + \ No newline at end of file diff --git a/vn.trader/vtFunction.py b/vn.trader/vtFunction.py new file mode 100644 index 00000000..3ccaf9b4 --- /dev/null +++ b/vn.trader/vtFunction.py @@ -0,0 +1,26 @@ +# encoding: UTF-8 + +""" +包含一些开放中常用的函数 +""" + +import decimal + +MAX_NUMBER = 1000000000 +MAX_DECIMAL = 4 + +#---------------------------------------------------------------------- +def safeUnicode(value): + """检查接口数据潜在的错误,保证转化为的字符串正确""" + # 检查是数字接近0时会出现的浮点数上限 + if type(value) is int or type(value) is float: + if value > MAX_NUMBER: + value = 0 + + # 检查防止小数点位过多 + if type(value) is float: + d = decimal.Decimal(str(value)) + if abs(d.as_tuple().exponent) > MAX_DECIMAL: + value = round(value, ndigits=MAX_DECIMAL) + + return unicode(value) \ No newline at end of file diff --git a/vn.trader/vtGateway.py b/vn.trader/vtGateway.py index 76d70c5c..1afaa8b6 100644 --- a/vn.trader/vtGateway.py +++ b/vn.trader/vtGateway.py @@ -4,48 +4,7 @@ import time from eventEngine import * -# 默认空值 -EMPTY_STRING = '' -EMPTY_UNICODE = u'' -EMPTY_INT = 0 -EMPTY_FLOAT = 0.0 - -# 方向常量 -DIRECTION_NONE = u'无方向' -DIRECTION_LONG = u'多' -DIRECTION_SHORT = u'空' -DIRECTION_UNKNOWN = u'未知' -DIRECTION_NET = u'净' - -# 开平常量 -OFFSET_NONE = u'无开平' -OFFSET_OPEN = u'开仓' -OFFSET_CLOSE = u'平仓' -OFFSET_CLOSETODAY = u'平今' -OFFSET_CLOSESYESTERDAY = u'平昨' -OFFSET_UNKNOWN = u'未知' - -# 状态常量 -STATUS_NOTTRADED = u'未成交' -STATUS_PARTTRADED = u'部分成交' -STATUS_ALLTRADED = u'全部成交' -STATUS_CANCELLED = u'已撤销' -STATUS_UNKNOWN = u'未知' - -# 合约类型常量 -PRODUCT_EQUITY = u'股票' -PRODUCT_FUTURES = u'期货' -PRODUCT_OPTION = u'期权' -PRODUCT_INDEX = u'指数' -PRODUCT_COMBINATION = u'组合' - -# 价格类型常量 -PRICETYPE_LIMITPRICE = u'限价' -PRICETYPE_MARKETPRICE = u'市价' - -# 期权类型 -OPTION_CALL = u'看涨期权' -OPTION_PUT = u'看跌期权' +from vtConstant import * ######################################################################## @@ -200,18 +159,24 @@ class VtTickData(VtBaseData): # 代码相关 self.symbol = EMPTY_STRING # 合约代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 Gateway名.合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 # 成交数据 self.lastPrice = EMPTY_FLOAT # 最新成交价 self.volume = EMPTY_INT # 最新成交量 self.openInterest = EMPTY_INT # 持仓量 - self.tickTime = EMPTY_STRING # 更新时间 + self.time = EMPTY_STRING # 时间 11:20:56.5 + self.date = EMPTY_STRING # 日期 20151009 # 常规行情 self.openPrice = EMPTY_FLOAT # 今日开盘价 self.highPrice = EMPTY_FLOAT # 今日最高价 self.lowPrice = EMPTY_FLOAT # 今日最低价 + self.preClosePrice = EMPTY_FLOAT + + self.upperLimit = EMPTY_FLOAT # 涨停价 + self.lowerLimit = EMPTY_FLOAT # 跌停价 # 五档行情 self.bidPrice1 = EMPTY_FLOAT @@ -250,7 +215,8 @@ class VtTradeData(VtBaseData): # 代码编号相关 self.symbol = EMPTY_STRING # 合约代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 Gateway名.合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 self.tradeID = EMPTY_STRING # 成交编号 self.vtTradeID = EMPTY_STRING # 成交在vt系统中的唯一编号,通常是 Gateway名.成交编号 @@ -277,7 +243,8 @@ class VtOrderData(VtBaseData): # 代码编号相关 self.symbol = EMPTY_STRING # 合约代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 Gateway名.合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 self.orderID = EMPTY_STRING # 订单编号 self.vtOrderID = EMPTY_STRING # 订单在vt系统中的唯一编号,通常是 Gateway名.订单编号 @@ -309,7 +276,8 @@ class VtPositionData(VtBaseData): # 代码编号相关 self.symbol = EMPTY_STRING # 合约代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 Gateway名.合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,合约代码.交易所代码 # 持仓相关 self.direction = EMPTY_STRING # 持仓方向 @@ -353,6 +321,7 @@ class VtErrorData(VtBaseData): self.errorID = EMPTY_STRING # 错误代码 self.errorMsg = EMPTY_UNICODE # 错误信息 + self.additionalInfo = EMPTY_UNICODE # 补充信息 ######################################################################## @@ -378,7 +347,8 @@ class VtContractData(VtBaseData): super(VtBaseData, self).__init__() self.symbol = EMPTY_STRING # 代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 Gateway名.合约代码 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 self.name = EMPTY_UNICODE # 合约中文名 self.productClass = EMPTY_UNICODE # 合约类型 @@ -409,13 +379,14 @@ class VtOrderReq: #---------------------------------------------------------------------- def __init__(self): """Constructor""" - self.symbol = EMPTY_STRING - self.price = EMPTY_FLOAT - self.volume = EMPTY_INT - - self.priceType = EMPTY_STRING - self.direction = EMPTY_STRING - self.offset = EMPTY_STRING + self.symbol = EMPTY_STRING # 代码 + self.exchange = EMPTY_STRING # 交易所 + self.price = EMPTY_FLOAT # 价格 + self.volume = EMPTY_INT # 数量 + + self.priceType = EMPTY_STRING # 价格类型 + self.direction = EMPTY_STRING # 买卖 + self.offset = EMPTY_STRING # 开平 ######################################################################## @@ -425,13 +396,13 @@ class VtCancelOrderReq: #---------------------------------------------------------------------- def __init__(self): """Constructor""" - self.symbol = EMPTY_STRING - self.exchange = EMPTY_STRING + self.symbol = EMPTY_STRING # 代码 + self.exchange = EMPTY_STRING # 交易所 # 以下字段主要和CTP、LTS类接口相关 - self.orderRef = EMPTY_STRING - self.frontID = EMPTY_STRING - self.sessionID = EMPTY_STRING + self.orderID = EMPTY_STRING # 报单号 + self.frontID = EMPTY_STRING # 前置机号 + self.sessionID = EMPTY_STRING # 会话号 diff --git a/vn.trader/vtMain.py b/vn.trader/vtMain.py new file mode 100644 index 00000000..36c8a3b5 --- /dev/null +++ b/vn.trader/vtMain.py @@ -0,0 +1,26 @@ +# encoding: UTF-8 + +import sys +import ctypes + +from vtEngine import MainEngine +from uiMainWindow import * + +#---------------------------------------------------------------------- +def main(): + """主程序入口""" + # 设置底部任务栏图标,win7以下请注释掉 + ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('vn.py demo') + + app = QtGui.QApplication(sys.argv) + app.setWindowIcon(QtGui.QIcon('vnpy.ico')) + app.setFont(BASIC_FONT) + + mainEngine = MainEngine() + mainWindow = MainWindow(mainEngine, mainEngine.eventEngine, mainEngine.dataEngine) + mainWindow.showMaximized() + + sys.exit(app.exec_()) + +if __name__ == '__main__': + main() diff --git a/vn.trader/windGateway.py b/vn.trader/windGateway.py new file mode 100644 index 00000000..dc87c607 --- /dev/null +++ b/vn.trader/windGateway.py @@ -0,0 +1,183 @@ +# encoding: UTF-8 + +''' +Wind Python API的gateway接入 +''' +from threading import Thread + +try: + from WindPy import w +except ImportError: + print u'请先安装WindPy接口' + +from vtGateway import * + +# 交易所类型映射 +exchangeMap = {} +exchangeMap[EXCHANGE_SSE] = 'SH' +exchangeMap[EXCHANGE_SZSE] = 'SZ' +exchangeMap[EXCHANGE_CFFEX] = 'CFE' +exchangeMap[EXCHANGE_SHFE] = 'SHF' +exchangeMap[EXCHANGE_DCE] = 'DCE' +exchangeMap[EXCHANGE_CZCE] = 'CZC' +exchangeMap[EXCHANGE_UNKNOWN] = '' +exchangeMapReverse = {v:k for k,v in exchangeMap.items()} + + +######################################################################## +class WindGateway(VtGateway): + """Wind接口""" + # 订阅wsq时传入的字段列表 + wsqParamMap = {} + wsqParamMap['rt_last'] = 'lastPrice' + wsqParamMap['rt_last_vol'] = 'volume' + wsqParamMap['rt_oi'] = 'openInterest' + + wsqParamMap['rt_open'] = 'openPrice' + wsqParamMap['rt_high'] = 'highPrice' + wsqParamMap['rt_low'] = 'lowPrice' + wsqParamMap['rt_pre_close'] = 'preClosePrice' + + wsqParamMap['rt_high_limit'] = 'upperLimit' + wsqParamMap['rt_low_limit'] = 'lowerLimit' + + wsqParamMap['rt_bid1'] = 'bidPrice1' + wsqParamMap['rt_bid2'] = 'bidPrice2' + wsqParamMap['rt_bid3'] = 'bidPrice3' + wsqParamMap['rt_bid4'] = 'bidPrice4' + wsqParamMap['rt_bid5'] = 'bidPrice5' + + wsqParamMap['rt_ask1'] = 'askPrice1' + wsqParamMap['rt_ask2'] = 'askPrice2' + wsqParamMap['rt_ask3'] = 'askPrice3' + wsqParamMap['rt_ask4'] = 'askPrice4' + wsqParamMap['rt_ask5'] = 'askPrice5' + + wsqParamMap['rt_bsize1'] = 'bidVolume1' + wsqParamMap['rt_bsize2'] = 'bidVolume2' + wsqParamMap['rt_bsize3'] = 'bidVolume3' + wsqParamMap['rt_bsize4'] = 'bidVolume4' + wsqParamMap['rt_bsize5'] = 'bidVolume5' + + wsqParamMap['rt_asize1'] = 'askVolume1' + wsqParamMap['rt_asize2'] = 'askVolume2' + wsqParamMap['rt_asize3'] = 'askVolume3' + wsqParamMap['rt_asize4'] = 'askVolume4' + wsqParamMap['rt_asize5'] = 'askVolume5' + + wsqParam = ','.join(wsqParamMap.keys()) + + #---------------------------------------------------------------------- + def __init__(self, eventEngine, gatewayName='Wind'): + """Constructor""" + super(WindGateway, self).__init__(eventEngine, gatewayName) + + self.w = w # Wind API对象 + self.connected = False # 连接状态 + + # Wind的wsq更新采用的是增量更新模式,每次推送只会更新发生变化的字段 + # 而vt中的tick是完整更新,因此需要本地维护一个所有字段的快照 + self.tickDict = {} + + self.registerEvent() + + #---------------------------------------------------------------------- + def connect(self): + """连接""" + # 由于w.start方法会阻塞较长时间 + # 因此设计为异步模式,交给事件处理线程去处理 + # 另外w.start和WingIDE的debug模块有冲突,会导致异常退出 + event = Event(type_=EVENT_WIND_CONNECTREQ) + self.eventEngine.put(event) + + #---------------------------------------------------------------------- + def subscribe(self, subscribeReq): + """订阅行情""" + windSymbol = '.'.join([subscribeReq.symbol, exchangeMap[subscribeReq.exchange]]) + data = self.w.wsq(windSymbol, self.wsqParam, func=self.wsqCallBack) + + #---------------------------------------------------------------------- + def sendOrder(self, orderReq): + """发单""" + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'Wind接口未实现发单功能' + self.onLog(log) + + #---------------------------------------------------------------------- + def cancelOrder(self, cancelOrderReq): + """撤单""" + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'Wind接口未实现撤单功能' + self.onLog(log) + + #---------------------------------------------------------------------- + def getAccount(self): + """查询账户资金""" + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'Wind接口未实现查询账户功能' + self.onLog(log) + + #---------------------------------------------------------------------- + def getPosition(self): + """查询持仓""" + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'Wind接口未实现查询持仓功能' + self.onLog(log) + + #---------------------------------------------------------------------- + def close(self): + self.w.stop() + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + self.eventEngine.register(EVENT_WIND_CONNECTREQ, self.wConnect) + + #---------------------------------------------------------------------- + def wsqCallBack(self, data): + """收到wsq推送""" + windSymbol = data.Codes[0] + if windSymbol in self.tickDict: + tick = self.tickDict[windSymbol] + else: + tick = VtTickData() + tick.gatewayName = self.gatewayName + symbolSplit = windSymbol.split('.') + tick.symbol = symbolSplit[0] + tick.exchange = exchangeMapReverse[symbolSplit[1]] + tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) + self.tickDict[windSymbol] = tick + + dt = data.Times[0] + tick.time = dt.strftime('%H:%M:%S') + tick.date = dt.strftime('%Y%m%d') + + # 采用遍历的形式读取数值 + fields = data.Fields + values = data.Data + d = tick.__dict__ + for n, field in enumerate(fields): + field = field.lower() + key = self.wsqParamMap[field] + value = values[n][0] + d[key] = value + + self.onTick(tick) + + #---------------------------------------------------------------------- + def wConnect(self, event): + """利用事件处理线程去异步连接Wind接口""" + result = self.w.start() + + log = VtLogData() + log.gatewayName = self.gatewayName + + if not result.ErrorCode: + log.logContent = u'Wind接口连接成功' + else: + log.logContent = u'Wind接口连接失败,错误代码%d' %result.ErrorCode + self.onLog(log) \ No newline at end of file