diff --git a/examples/QuantosDataService/config.json b/examples/QuantosDataService/config.json index c046ab3f..dc5b3e25 100644 --- a/examples/QuantosDataService/config.json +++ b/examples/QuantosDataService/config.json @@ -3,8 +3,8 @@ "MONGO_PORT": 27017, "DATA_SERVER": "tcp://data.tushare.org:8910", - "USERNAME": "", - "TOKEN": "", + "USERNAME": "18616966847", + "TOKEN": "eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGVfdGltZSI6IjE1MTI2NDAzNzAxNjIiLCJpc3MiOiJhdXRoMCIsImlkIjoiMTg2MTY5NjY4NDcifQ.xp1nDYfFgEeHtNoVFVKqXcmSQHR1-kdm99fzXqnowoo", - "SYMBOLS": ["510050.SSE", "510300.SSE"] + "SYMBOLS": ["IF1712.CFFEX", "510050.SSE", "510300.SSE"] } \ No newline at end of file diff --git a/vnpy/trader/app/rtdService/RTD_setting.json b/vnpy/trader/app/rtdService/RTD_setting.json new file mode 100644 index 00000000..0388abb3 --- /dev/null +++ b/vnpy/trader/app/rtdService/RTD_setting.json @@ -0,0 +1,7 @@ +{ + "repAddress": "tcp://*:88888", + "pubAddress": "tcp://*:66666", + "eventType": { + "eTick.": "symbol" + } +} \ No newline at end of file diff --git a/vnpy/trader/app/rtdService/__init__.py b/vnpy/trader/app/rtdService/__init__.py new file mode 100644 index 00000000..6048bb5a --- /dev/null +++ b/vnpy/trader/app/rtdService/__init__.py @@ -0,0 +1,10 @@ +# encoding: UTF-8 + +from .rtdEngine import RtdEngine +from .uiRtdWidget import RtdManager + +appName = 'RtdService' +appDisplayName = u'RTD服务' +appEngine = RtdEngine +appWidget = RtdManager +appIco = 'rtd.ico' diff --git a/vnpy/trader/app/rtdService/demo.xlsx b/vnpy/trader/app/rtdService/demo.xlsx new file mode 100644 index 00000000..a37db56b Binary files /dev/null and b/vnpy/trader/app/rtdService/demo.xlsx differ diff --git a/vnpy/trader/app/rtdService/rtd.ico b/vnpy/trader/app/rtdService/rtd.ico new file mode 100644 index 00000000..f6c9cbfd Binary files /dev/null and b/vnpy/trader/app/rtdService/rtd.ico differ diff --git a/vnpy/trader/app/rtdService/rtdClient.py b/vnpy/trader/app/rtdService/rtdClient.py new file mode 100644 index 00000000..b20dfb31 --- /dev/null +++ b/vnpy/trader/app/rtdService/rtdClient.py @@ -0,0 +1,90 @@ +# encoding: UTF-8 + +from pyxll import RTD, xl_func, xl_app + +from vnpy.rpc import RpcClient + + +# key为topic.key +DATA_DICT = {} +RTD_DICT = {} + + +######################################################################## +class RtdClient(RpcClient): + """RTD客户端""" + + #---------------------------------------------------------------------- + def __init__(self, reqAddress, subAddress): + """Constructor""" + super(RtdClient, self).__init__(reqAddress, subAddress) + + self.useJson() + + #---------------------------------------------------------------------- + def callback(self, topic, data): + """回调函数实现""" + name = '_'.join([topic, data["key"]]) + DATA_DICT[name] = data + + # 检查存在的RTD对象 + rtdList = RTD_DICT.get(name, None) + if rtdList: + for rtd in rtdList: + rtd.update() + + +######################################################################## +class RtdData(RTD): + """RTD数据""" + + #---------------------------------------------------------------------- + def __init__(self, name, field): + """Constructor""" + super(RtdData, self).__init__(value=0) + + self.name = name + self.field = field + + #---------------------------------------------------------------------- + def connect(self): + """连接成功""" + l = RTD_DICT.setdefault(self.name, []) + l.append(self) + + #---------------------------------------------------------------------- + def disconnect(self): + """连接断开""" + l = RTD_DICT.get(self.name, None) + if not l: + return + + if self in l: + l.remove(self) + + #---------------------------------------------------------------------- + def update(self): + """更新数据""" + data = DATA_DICT.get(self.name, None) + if not data: + return + + newValue = data[self.field] + if newValue != self.value: + self.value = newValue + + +@xl_func("string name, string field: rtd") +#---------------------------------------------------------------------- +def rtdData(name, field): + """获取RTD数据""" + return RtdData(name, field) + + +# 连接客户端 +reqAddress = 'tcp://localhost:88888' +subAddress = 'tcp://localhost:66666' + +c = RtdClient(reqAddress, subAddress) +c.subscribeTopic('') +c.start() diff --git a/vnpy/trader/app/rtdService/rtdEngine.py b/vnpy/trader/app/rtdService/rtdEngine.py new file mode 100644 index 00000000..3d4463e9 --- /dev/null +++ b/vnpy/trader/app/rtdService/rtdEngine.py @@ -0,0 +1,98 @@ +# encoding: UTF-8 + +import json + +from vnpy.event import Event +from vnpy.rpc import RpcServer +from vnpy.trader.vtFunction import getJsonPath +from vnpy.trader.vtObject import VtLogData + + +EVENT_RTDSERVICE_LOG = 'eRtdServiceLog' + + +######################################################################## +class RtdServer(RpcServer): + """RTD服务器,直接继承RPC服务""" + + #---------------------------------------------------------------------- + def __init__(self, repAddress, pubAddress): + """Constructor""" + super(RtdServer, self).__init__(repAddress, pubAddress) + + self.useJson() + + +#################################################5####################### +class RtdEngine(object): + """RTD引擎""" + ENGINE_NAME = 'RTD' + + settingFileName = 'RTD_setting.json' + settingfilePath = getJsonPath(settingFileName, __file__) + + #---------------------------------------------------------------------- + def __init__(self, mainEngine, eventEngine): + """Constructor""" + self.mainEngine = mainEngine + self.eventEngine = eventEngine + + self.server = None + self.eventTypeDict = {} # key:事件类型,value:键 + + self.loadSetting() + self.registerEvent() + + #---------------------------------------------------------------------- + def loadSetting(self): + """读取配置""" + with open(self.settingfilePath) as f: + d = json.load(f) + + repAddress = d['repAddress'] + pubAddress = d['pubAddress'] + + self.server = RtdServer(repAddress, pubAddress) + + self.eventTypeDict = d['eventType'] + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + for eventType in self.eventTypeDict.keys(): + self.eventEngine.register(eventType, self.processDataEvent) + + #---------------------------------------------------------------------- + def processDataEvent(self, event): + """处理数据事件""" + if not self.server: + return + + data = event.dict_['data'] + d = data.__dict__ + keyname = self.eventTypeDict[event.type_] # 获取数据标识用的名称 + d["key"] = d[keyname] + + self.server.publish(event.type_, d) + + self.writeLog(u'发布数据,类型%s,内容%s' %(event.type_, str(d))) + + #---------------------------------------------------------------------- + def writeLog(self, content): + """记录日志""" + log = VtLogData() + log.logContent = content + log.gatewayName = self.ENGINE_NAME + + event = Event(EVENT_RTDSERVICE_LOG) + event.dict_['data'] = log + self.eventEngine.put(event) + + #---------------------------------------------------------------------- + def stop(self): + """停止""" + pass + + + + \ No newline at end of file diff --git a/vnpy/trader/app/rtdService/uiRtdWidget.py b/vnpy/trader/app/rtdService/uiRtdWidget.py new file mode 100644 index 00000000..59a8269a --- /dev/null +++ b/vnpy/trader/app/rtdService/uiRtdWidget.py @@ -0,0 +1,57 @@ +# encoding: UTF-8 + +from datetime import datetime + +from vnpy.event import Event +from vnpy.trader.uiQt import QtCore, QtWidgets + +from .rtdEngine import EVENT_RTDSERVICE_LOG + + +######################################################################## +class RtdManager(QtWidgets.QWidget): + """RTD管理工具""" + + signal = QtCore.Signal(type(Event())) + + #---------------------------------------------------------------------- + def __init__(self, rsEngine, eventEngine, parent=None): + """Constructor""" + super(RtdManager, self).__init__(parent) + + self.rsEngine = rsEngine + self.eventEngine = eventEngine + + self.initUi() + self.registerEvent() + + #---------------------------------------------------------------------- + def registerEvent(self): + """注册事件监听""" + self.signal.connect(self.updateLog) + + self.eventEngine.register(EVENT_RTDSERVICE_LOG, self.signal.emit) + + #---------------------------------------------------------------------- + def initUi(self): + """初始化界面""" + self.setWindowTitle(u'RTD服务') + + self.logMonitor = QtWidgets.QTextBrowser() + + vbox = QtWidgets.QVBoxLayout() + vbox.addWidget(self.logMonitor) + + self.setLayout(vbox) + + #---------------------------------------------------------------------- + def updateLog(self, event): + """输出日志""" + log = event.dict_['data'] + content = log.logTime + "\t" + log.logContent + '\n' + self.logMonitor.append(content) + + + + + \ No newline at end of file