class DemoApp(object): # ---------------------------------------------------------------------- def __init__(self): """Constructor""" self.eventEngine = EventEngine() self.eventEngine.start() self.tianqinGateway = TianQinGateway(self.eventEngine) def start(self): self.tianqinGateway.connect() self.tianqinGateway.subscribe_quote( ["cu1803", "SR801", "c1801", "IF1708"], self.on_quote_data) self.tianqinGateway.subscribe_chart("cu1803", 5, 1000, self.on_chart_data) self.tianqinGateway.subscribe_chart("au1712", 0, 1000, self.on_chart_data) def on_quote_data(self, ins_id): quote = self.tianqinGateway.get_quote(ins_id) print("quote_update", ins_id, quote) def on_chart_data(self, ins_id, dur_seconds): if dur_seconds == 0: tick_serial = self.tianqinGateway.get_tick_serial(ins_id) print("tick_serial_update", tick_serial) else: kline_serial = self.tianqinGateway.get_kline_serial( ins_id, dur_seconds) print("kline_serial_update", kline_serial)
class Mform(): def __init__(self): self.mainCTPList = [] self.agentCTPList = [] self.getAccounts() self.ee = EventEngine() self.ee.start() self.setupCTP(self.ee) def getAccounts(self): filename = 'G:/main/accounts.ph' self.mainAccountList, self.agentAccountList = getAccounts(filename) print('账号是', self.mainAccountList) return self.mainAccountList, self.agentAccountList def setupCTP(self, eventEngine): for i in self.agentAccountList: print('i is ', i) self.agentCTPList.append(setupAgentCTP(i, eventEngine)) for i in self.mainAccountList: print('mainaccountlist_i is ', i) self.mainCTPList.append(setupMainCTP(i, eventEngine)) for i in self.mainAccountList: if len(i.childs) > 0: print('有孩子') print(i.childs) print(i.userID) mainCtp = getCTP(i, self.mainCTPList) for j in i.childs: agentCtp = getCTP(j, self.agentCTPList) mainCtp.childList.append(agentCtp) agentCtp.father = mainCtp def getCTPList(self): return self.mainCTPList, self.agentCTPList # 关联 def relevance(self): mainAccount = self.mainAccountList[0] agentAccount = self.agentAccountList[0] mainCtp = getCTP(mainAccount, self.mainCTPList) agentCtp = getCTP(agentAccount, self.agentCTPList) agentCtp.opposite = False for i in mainCtp.childList: print('main have guanlian') if agentCtp is i: print('关联信息已经存在') print(agentCtp.userID) return mainAccount.childs.append(agentAccount) agentAccount.father = mainAccount mainCtp.childList.append(agentCtp) agentCtp.father = mainCtp
def main(): event_engine = EventEngine() event_engine.register("test", handle) event_engine.start() evt = Event("test") evt.data = "df" print("recei22:" + evt.__str__()) event_engine.put(evt) sleep(1) event_engine.stop()
def main(): """客户端主程序入口""" # 重载sys模块,设置默认字符串编码方式为utf8 reload(sys) sys.setdefaultencoding('utf8') # 设置Windows底部任务栏图标 if 'Windows' in platform.uname(): ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( 'vn.trader') # 创建事件引擎 eventEngine = EventEngine() eventEngine.start(timer=False) # 创建客户端 reqAddress = 'tcp://localhost:2014' subAddress = 'tcp://localhost:0602' client = VtClient(reqAddress, subAddress, eventEngine) client.subscribeTopic('') client.start() # 初始化Qt应用对象 app = QtGui.QApplication(sys.argv) app.setWindowIcon(QtGui.QIcon(ICON_FILENAME)) app.setFont(BASIC_FONT) # 设置Qt的皮肤 try: f = file(SETTING_FILENAME) setting = json.load(f) if setting['darkStyle']: import qdarkstyle app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False)) except: pass # 初始化主引擎和主窗口对象 mainEngine = ClientEngine(client, eventEngine) mainWindow = MainWindow(mainEngine, mainEngine.eventEngine) mainWindow.showMaximized() # 在主线程中启动Qt事件循环 sys.exit(app.exec_())
class MainEngine: """ Acts as the core of VN Trader. """ def __init__(self, event_engine: EventEngine = None): """""" if event_engine: self.event_engine: EventEngine = event_engine else: self.event_engine = EventEngine() self.event_engine.start() self.gateways: Dict[str, BaseGateway] = {} self.engines: Dict[str, BaseEngine] = {} self.apps: Dict[str, BaseApp] = {} self.exchanges: List[Exchange] = [] os.chdir(TRADER_DIR) # Change working directory self.init_engines() # Initialize function engines def add_engine(self, engine_class: Any) -> "BaseEngine": """ Add function engine. """ engine = engine_class(self, self.event_engine) self.engines[engine.engine_name] = engine return engine def add_gateway(self, gateway_class: Type[BaseGateway]) -> BaseGateway: """ Add gateway. """ gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway # Add gateway supported exchanges into engine for exchange in gateway.exchanges: if exchange not in self.exchanges: self.exchanges.append(exchange) return gateway def add_app(self, app_class: Type[BaseApp]) -> "BaseEngine": """ Add app. """ app = app_class() self.apps[app.app_name] = app engine = self.add_engine(app.engine_class) return engine def init_engines(self) -> None: """ Init all engines. """ self.add_engine(LogEngine) self.add_engine(OmsEngine) self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = "") -> None: """ Put log event with specific message. """ log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) self.event_engine.put(event) def get_gateway(self, gateway_name: str) -> BaseGateway: """ Return gateway object by name. """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str) -> "BaseEngine": """ Return engine object by name. """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str) -> Optional[Dict[str, Any]]: """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self) -> List[str]: """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self) -> List[BaseApp]: """ Get all app objects. """ return list(self.apps.values()) def get_all_exchanges(self) -> List[Exchange]: """ Get all exchanges. """ return self.exchanges def connect(self, setting: dict, gateway_name: str) -> None: """ Start connection of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str) -> None: """ Subscribe tick data update of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def send_order(self, req: OrderRequest, gateway_name: str) -> str: """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str) -> None: """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str) -> List[str]: """ """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_orders(reqs) else: return ["" for req in reqs] def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str) -> None: """ """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_orders(reqs) def query_history(self, req: HistoryRequest, gateway_name: str) -> Optional[List[BarData]]: """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.query_history(req) else: return None def close(self) -> None: """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()
class MainEngine: """ Acts as the core of VN Trader. """ def __init__(self, event_engine: EventEngine = None): """""" if event_engine: self.event_engine = event_engine else: self.event_engine = EventEngine() self.event_engine.start() self.gateways = {} self.engines = {} self.apps = {} self.init_engines() def add_engine(self, engine_class: Any): """ Add function engine. """ engine = engine_class(self, self.event_engine) self.engines[engine.engine_name] = engine return engine def add_gateway(self, gateway_class: BaseGateway): """ Add gateway. """ gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway return gateway def add_app(self, app_class: BaseApp): """ Add app. """ app = app_class() self.apps[app.app_name] = app engine = self.add_engine(app.engine_class) return engine def init_engines(self): """ Init all engines. """ self.add_engine(LogEngine) self.add_engine(OmsEngine) self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = ""): """ Put log event with specific message. """ log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) self.event_engine.put(event) def get_gateway(self, gateway_name: str): """ Return gateway object by name. """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str): """ Return engine object by name. """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str): """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self): """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self): """ Get all app objects. """ return list(self.apps.values()) def connect(self, setting: dict, gateway_name: str): """ Start connection of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str): """ Subscribe tick data update of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def send_order(self, req: OrderRequest, gateway_name: str): """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str): """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def close(self): """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()
class Form(QMainWindow, ui_mainfollow.Ui_MainWindow): """docstring for Form""" def __init__(self, parent=None): super(Form, self).__init__(parent) self.setupUi(self) self.ee = EventEngine() self.ee.start() self.eventPush = EventPush(self.ee) self.dirty = False mxh_a, mxh_b = self.getAccounts() self.mainCTPList = [] self.agentCTPList = [] self.mainShowCtp = ShowCtp() self.agentShowCtp = ShowCtp() self.ee.register(u"addListWidget", self.addListWidget) self.ee.register(u"addLog", self.addLog) self.ee.register(u"addTable", self.updateTable) self.mainFreshPushButton.clicked.connect(self.qryMainPositionDetail) # self.agentFreshPushButton.clicked.connect(self.qryAgentPositionDetail) self.setupCTP(self.ee) self.newAgentCtp = None self.newMainCtp = None self.editItem = EditTreeItem() self.filemenu = self.menuBar().addMenu(u"&菜单") self.editmenu = self.menuBar().addMenu(u"账户设置") fileToolbar = self.addToolBar("file") editToolbar = self.addToolBar("edit") self.startAction = self.createAction(u"启动", self.start, icon="start", tip=u"启动连接账号") self.stopAction = self.createAction(u"停止", self.stop, icon="stop", tip=u"断开账户连接") newAction = self.createAction(u"新建", self.new, icon="add", tip=u"新建账户") self.modifyAction = self.createAction(u"账户修改", self.modify, icon="modify", tip=u"修改账户信息") self.delAction = self.createAction(u"删除账户", self.delete, icon="delete", tip=u"删除选中的账户") # self.relevanceAction = self.createAction(u"关联账户", self.relevance, # icon="relevance", tip=u"关联主账户与子账户") startAllAction = self.createAction(u"全部启动", self.startAll, tip=u"启动全部账号") stopAllAction = self.createAction(u"全部停止", self.stopAll, tip=u"断开全部账号") exitAction = self.createAction(u"退出", self.closeEvent, tip=u"退出系统") self.saveAction = self.createAction(u"保存", self.save, icon="save", tip=u"保存账号信息") fileActions = (self.startAction, self.stopAction, None, startAllAction, stopAllAction, None, exitAction) editActions = (newAction, self.modifyAction, self.saveAction, self.delAction, None) self.addActions(self.filemenu, fileActions) self.addActions(self.editmenu, editActions) self.addActions(fileToolbar, (self.startAction, self.stopAction)) self.addActions(editToolbar, editActions) self.setWindowTitle(u"期货系统") self.updateUi() self.initComboBox() self.updateTree() self.setWindowIcon(QIcon(":/logo.png")) self.statusLabelCompany = QLabel(u"杭州易期智能科技有限公司") self.statusLabelTel = QLabel(u"Tel:0571-86493200") self.statusBar().addPermanentWidget(self.statusLabelCompany) self.statusBar().addPermanentWidget(self.statusLabelTel) self.accountTreeWidget.itemClicked.connect(self.getEditItem) # 初始化时,什么也没做 self.mainAccountComboBox.currentIndexChanged.connect( self.updateMainComboBox) # self.agentAccountComboBox.currentIndexChanged.connect(self.updateAgentComboBox) # 设置输出信息 self.setupTable(self.mainAccountTable) # self.setupTable(self.agentAccountTable) # 初始化订阅列表 self.subscribeSetup() def subscribeSetup(self): for i in self.mainAccountList: for j in self.mainCTPList: if j.userID == i.userID: j.subscribeList = i.subscribes def subscribeApi(self, subscribeObj, mainuserID): for i in self.mainAccountList: if i.userID == mainuserID: print('jinru') for sub in i.subscribes: if subscribeObj.channel_id == sub.channel_id: print('have subscript') break else: pass else: print('start subscribe...') i.subscribes.append(subscribeObj) self.save() # ctp列表中订阅 for j in self.mainCTPList: if j.userID == i.userID: j.subscribeList.append(subscribeObj) else: print('没有此操盘手:%s' % mainuserID) return self.mainAccountList def unsubscribeApi(self, subscribeObj, mainuserID): for i in self.mainAccountList: if i.userID == mainuserID: print('jinru') for sub in i.subscribes: if subscribeObj.channel_id == sub.channel_id: print('delect subscribe') i.subscribes.remove(sub) self.save() # ctp列表中删除订阅 for j in self.mainCTPList: if j.userID == i.userID: for each in j.subscribeList: if each.channel_id == subscribeObj.channel_id: j.subscribeList.remove(each) break else: pass else: print('You have not subscribed ') return self.mainAccountList # 设置输出框的格式 def setupTable(self, target): target.setSortingEnabled(False) target.setColumnCount(6) headers = [u"持仓合约", u'买卖', u'手数', u'开仓价', u'开仓时间', u"持仓盈亏"] target.setHorizontalHeaderLabels(headers) target.setEditTriggers(target.NoEditTriggers) target.setAlternatingRowColors(True) def updateTable(self, event): data = event.dict_['data'] rowCount = len(data) print u'持仓信息' print '就是这里' def setItem(target, data): target.clearContents() for i, v in enumerate(data): # print i,v if i == 0: continue item = QTableWidgetItem("%s" % v['InstrumentID']) target.setItem(i - 1, 0, item) if v['Direction'] == "0": item = QTableWidgetItem(u"买") item.setForeground(QColor('red')) else: item = QTableWidgetItem(u"卖") item.setForeground(QColor('green')) target.setItem(i - 1, 1, item) item = QTableWidgetItem("%s" % safeUnicode(v['Volume'])) target.setItem(i - 1, 2, item) item = QTableWidgetItem("%s" % safeUnicode(v['OpenPrice'])) target.setItem(i - 1, 3, item) item = QTableWidgetItem("%s" % safeUnicode(v['OpenDate'])) target.setItem(i - 1, 4, item) item = QTableWidgetItem("%s" % safeUnicode(v['PositionProfitByDate'])) if v['PositionProfitByDate'] < 0: item.setBackground(QColor("green")) item.setForeground(QColor("white")) elif v['PositionProfitByDate'] > 0: item.setBackground(QColor("red")) item.setForeground(QColor("white")) target.setItem(i - 1, 5, item) if data[0] and rowCount != 0: self.mainAccountTable.setRowCount(rowCount - 1) setItem(self.mainAccountTable, data) else: pass def getEditItem(self): currentItem = self.accountTreeWidget.currentItem() parentItem = currentItem.parent() topIndex = self.accountTreeWidget.indexOfTopLevelItem(parentItem) if topIndex == 0: k, ctp, accountIndex, account = getCTPFromTree( currentItem.text(0), currentItem.text(2), self.mainCTPList, self.mainAccountList) self.editItem.index = k self.editItem.ctp = ctp self.editItem.flag = True self.editItem.isNone = False self.editItem.accountIndex = accountIndex self.editItem.account = account elif topIndex == 1: k, ctp, accountIndex, account = getCTPFromTree( currentItem.text(0), currentItem.text(2), self.agentCTPList, self.agentAccountList) self.editItem.index = k self.editItem.ctp = ctp self.editItem.flag = False self.editItem.isNone = False self.editItem.accountIndex = accountIndex self.editItem.account = account else: self.editItem = EditTreeItem() self.updateUi() def updateTree(self): self.accountTreeWidget.clear() self.accountTreeWidget.setColumnCount(3) self.accountTreeWidget.setHeaderLabels([u'账号信息', u'连接状态', u'期货公司']) self.rootMain = QTreeWidgetItem(self.accountTreeWidget) self.rootMain.setText(0, u"主账号:") # self.rootAgent = QTreeWidgetItem(self.accountTreeWidget) # self.rootAgent.setText(0, u"子账号:") self.accountTreeWidget.expandItem(self.rootMain) # self.accountTreeWidget.expandItem(self.rootAgent) for i in self.mainCTPList: mainCtp = QTreeWidgetItem(self.rootMain) mainCtp.setText(0, i.userID) if i.loginStatus: mainCtp.setText(1, u"ON") else: mainCtp.setText(1, u"OFF") mainCtp.setText(2, i.company) # print i.childList if len(i.childList) > 0: for k, j in enumerate(i.childList): childCtp = QTreeWidgetItem(mainCtp) childCtp.setText(0, u"%s:" % (k + 1) + unicode(j.userID)) if j.connectionStatus: childCtp.setText(1, u"ON") else: childCtp.setText(1, u"OFF") childCtp.setText(2, j.company) # for i in self.agentCTPList: # agentCtp = QTreeWidgetItem(self.rootAgent) # agentCtp.setText(0, i.userID) # if i.connectionStatus: # agentCtp.setText(1, u"ON") # else: # agentCtp.setText(1, u"OFF") # agentCtp.setText(2, i.company) def getAccounts(self): filename = os.getcwd() + r"\\accounts.ph" self.mainAccountList, self.agentAccountList = getAccounts(filename) return self.mainAccountList, self.agentAccountList def setupCTP(self, eventEngine): self.mainCTPList = [] self.agentCTPList = [] for i in self.agentAccountList: print('i is ', i) self.agentCTPList.append(setupAgentCTP(i, eventEngine)) for i in self.mainAccountList: print('mainaccountlist_i is ', i) self.mainCTPList.append(setupMainCTP(i, eventEngine)) for i in self.mainAccountList: if len(i.childs) > 0: mainCtp = getCTP(i, self.mainCTPList) for j in i.childs: agentCtp = getCTP(j, self.agentCTPList) mainCtp.childList.append(agentCtp) agentCtp.father = mainCtp def updateCTP(self): if self.newMainCtp is not None: self.mainCTPList.append(self.newMainCtp) if self.newAgentCtp is not None: self.agentCTPList.append(self.newAgentCtp) self.newMainCtp = None self.newAgentCtp = None # 账号启动连接 def start(self): if self.editItem.flag: self.editItem.ctp.connect() else: if self.editItem.ctp.father is not None: self.editItem.ctp.connect() else: QMessageBox.warning(self, u"账号启动", u"启动前请先关联主账号。") sleep(1) self.updateUi() self.updateTree() def stop(self): self.editItem.ctp.close() # sleep(1) now = datetime.now() if self.editItem.flag: flag = u"主帐号" else: flag = u"子帐号" msg = " ".join( (now.strftime('%Y-%m-%d %H:%M:%S'), flag, self.editItem.ctp.company, self.editItem.ctp.userID, u"已经断开连接")) self.logListWidget.insertItem(0, QListWidgetItem(msg)) self.updateUi() self.updateTree() def startAll(self): for i in self.mainCTPList: i.connect() for i in self.agentCTPList: if i.father is not None: i.connect() else: QMessageBox.warning(self, u"账号启动", u"启动前请先关联主账号。") sleep(1) self.updateTree() def stopAll(self): for i in self.mainCTPList: if i.loginStatus: i.close() for i in self.agentCTPList: if i.loginStatus: i.close() self.updateTree() now = datetime.now() msg = " ".join((now.strftime('%Y-%m-%d %H:%M:%S'), u"账号已经全部断开连接")) self.logListWidget.insertItem(0, QListWidgetItem(msg)) def save(self): if self.dirty: filename = os.getcwd() + r"\\accounts.ph" accounts = shelve.open(filename) accounts['mainAccountList'] = self.mainAccountList accounts['agentAccountList'] = self.agentAccountList accounts.close() self.dirty = False self.updateUi() def new(self): self.newDialog = NewAccountDialog(self) if self.newDialog.exec_(): newAccount = self.newDialog.newAccount if newAccount.mainFlag: self.mainAccountList.append(newAccount) self.newMainCtp = setupMainCTP(newAccount, self.ee) else: # self.agentAccountList.append(newAccount) # self.newAgentCtp = setupAgentCTP(newAccount, self.ee) pass else: return self.updateCTP() self.dirty = True self.updateUi() self.updateTree() self.initComboBox() def updateUi(self): if self.dirty: self.saveAction.setEnabled(True) else: self.saveAction.setEnabled(False) if self.editItem.isNone: self.stopAction.setEnabled(False) # self.relevanceAction.setEnabled(False) self.startAction.setEnabled(False) self.modifyAction.setEnabled(False) self.delAction.setEnabled(False) else: if self.editItem.ctp.connectionStatus: self.stopAction.setEnabled(True) self.startAction.setEnabled(False) else: self.stopAction.setEnabled(False) self.startAction.setEnabled(True) self.modifyAction.setEnabled(True) # self.relevanceAction.setEnabled(True) self.delAction.setEnabled(True) if self.editItem.isNone: self.startAction.setEnabled(False) self.stopAction.setEnabled(False) else: if self.editItem.ctp.connectionStatus: self.startAction.setEnabled(False) self.stopAction.setEnabled(True) else: self.startAction.setEnabled(True) self.stopAction.setEnabled(False) def initComboBox(self): self.mainAccountComboBox.clear() # self.agentAccountComboBox.clear() for i in self.mainAccountList: msg = u"brokerID:" + unicode(i.brokerID) + u" 账号:" + unicode( i.userID) self.mainAccountComboBox.addItem(msg) # for j in self.agentAccountList: # msg = u"brokerID:" + unicode(j.brokerID) + u" 账号:" + unicode(j.userID) # self.agentAccountComboBox.addItem(msg) self.updateMainComboBox() # self.updateAgentComboBox() def updateMainComboBox(self): try: msg = self.mainAccountComboBox.currentText() msg = msg.split(" ") brokerID = msg[0].split(":")[1] userID = msg[1].split(":")[1] k, ctp = getCTPFromBrokerID(brokerID, userID, self.mainCTPList) self.mainShowCtp.index = k self.mainShowCtp.ctp = ctp self.mainShowCtp.isNone = False self.mainCompanyLabel.setText(ctp.company) self.mainOperatorLabel.setText(ctp.operator) self.mainTdAddressLabel.setText(ctp.address) except IndexError: pass def updateAgentComboBox(self): try: msg = self.agentAccountComboBox.currentText() msg = msg.split(" ") brokerID = msg[0].split(":")[1] userID = msg[1].split(":")[1] k, ctp = getCTPFromBrokerID(brokerID, userID, self.agentCTPList) self.agentShowCtp.id = k self.agentShowCtp.ctp = ctp self.agentShowCtp.isNone = False self.agentCompanyLabel.setText(ctp.company) self.agentOperatorLabel.setText(ctp.operator) self.agentTdAddressLabel.setText(ctp.address) except IndexError: pass def qryMainPositionDetail(self, event): if not self.mainShowCtp.isNone and self.mainShowCtp.ctp.loginStatus: self.mainShowCtp.ctp.qryInvestorPositionDetail() else: # pass self.mainAccountTable.clearContents() def qryAgentPositionDetail(self, event): if not self.agentShowCtp.isNone and self.agentShowCtp.ctp.loginStatus: sleep(0.2) self.agentShowCtp.ctp.qryInvestorPositionDetail() else: pass def modify(self): if self.editItem.isNone: QMessageBox.warning(self, u"密码修改", u"请选择账号。") return self.editDialog = EditDialog(self.editItem.ctp.strike, self.editItem.ctp.multiple, self.editItem.ctp.opposite, self) self.editDialog.userIDLabel.setText(self.editItem.ctp.userID) if self.editDialog.exec_(): password = self.editDialog.password multiple = self.editDialog.multiple strike = self.editDialog.slip oppositeFlag = self.editDialog.oppositeFlag if password != "": self.editItem.ctp.password = password self.editItem.account.password = password self.editItem.ctp.strike = strike self.editItem.ctp.multiple = multiple self.editItem.ctp.opposite = oppositeFlag self.dirty = True self.updateUi() print self.editItem.ctp.opposite print '是什么?' else: return def delete(self): msg = " ".join(("确定删除", self.editItem.ctp.company, "账户:", self.editItem.ctp.userID, "?")) reply = QMessageBox.question(self, u"账户删除", msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if self.editItem.flag: self.mainAccountList.pop(self.editItem.accountIndex) self.mainCTPList.pop(self.editItem.index) for i in self.agentCTPList: if self.editItem.ctp == i.father: i.father = None for i in self.agentAccountList: if self.editItem.account == i.father: i.father = None else: if self.editItem.ctp.father is not None: for k, i in enumerate(self.editItem.ctp.father.childList): if self.editItem.ctp is i: self.editItem.ctp.father.childList.pop(k) for k, i in enumerate(self.editItem.account.father.childs): if self.editItem.account.userID == i.userID \ and self.editItem.account.brokerID == i.brokerID: self.editItem.account.father.childs.pop(k) self.agentAccountList.pop(self.editItem.accountIndex) self.agentCTPList.pop(self.editItem.index) self.editItem = EditTreeItem() self.dirty = True self.updateTree() self.updateUi() self.initComboBox() else: return def relevance(self): self.relevanceDialog = RelevanceDialog(self, self.mainAccountList, self.agentAccountList) mainAccount = None agentAccount = None strike = 3 if self.relevanceDialog.exec_(): mainAccount = self.relevanceDialog.mainAccount agentAccount = self.relevanceDialog.agentAccount strike = self.relevanceDialog.strike multiple = self.relevanceDialog.multiple oppositeFlag = self.relevanceDialog.oppositeFlag if mainAccount is not None and agentAccount is not None: mainCtp = getCTP(mainAccount, self.mainCTPList) agentCtp = getCTP(agentAccount, self.agentCTPList) agentCtp.strike = strike agentCtp.multiple = multiple agentCtp.opposite = oppositeFlag print agentCtp.opposite print 'guan lian' for i in mainCtp.childList: print('guanlianxinxihanshu:', i) if agentCtp is i: QMessageBox.warning( self, u"关联信息已存在", " ".join( (u"子账户", agentCtp.company, agentCtp.userID, u"已经关联到主账户", mainCtp.company, mainCtp.userID, u"中,请勿重复关联!"))) return mainAccount.childs.append(agentAccount) agentAccount.father = mainAccount mainCtp.childList.append(agentCtp) agentCtp.father = mainCtp self.dirty = True self.updateTree() return def closeEvent(self, event): reply = QMessageBox.question(self, u"退出", u"确认退出系统?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if self.dirty: saveReply = QMessageBox.question( self, u"保存", u"账号信息有变动,是否保存?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if saveReply == QMessageBox.Yes: self.save() self.stopAll() self.ee.stop() event.accept() else: event.ignore() def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: if signal == "triggered": action.triggered.connect(slot) if checkable: action.setCheckable(True) return action def addActions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def getPrice(self): pass def addListWidget(self, event): now = datetime.now() msg = " ".join( (now.strftime('%Y-%m-%d %H:%M:%S'), event.dict_['data'])) self.logListWidget.insertItem(0, QListWidgetItem(msg)) print('print meg is', QListWidgetItem(msg)) def addLog(self, event): print event.dict_['data'] print '数据嘛?'
class Mform(): def __init__(self): self.mainCTPList = [] self.agentCTPList = [] self.getAccountsM() self.ee = EventEngine() self.ee.start() self.setupCTP(self.ee) #初始化订阅列表 self.subscribeSetup() def subscribeSetup(self): for i in self.mainAccountList: for j in self.mainCTPList: if j.userID == i.userID: j.subscribeList = i.subscribes def getAccountsM(self): filename = os.getcwd() + r"\\accounts.ph" self.mainAccountList, self.agentAccountList = getAccounts(filename) print('账号是', self.mainAccountList) return self.mainAccountList, self.agentAccountList def setupCTP(self, eventEngine): for i in self.agentAccountList: print('i is ', i) self.agentCTPList.append(setupAgentCTP(i, eventEngine)) for i in self.mainAccountList: print('mainaccountlist_i is ', i) print(i.company, i.operator, i.userID, i.tdAddress, i.mdAddress, i.childs, i.subscribes) self.mainCTPList.append(setupMainCTP(i, eventEngine)) for i in self.mainAccountList: if len(i.childs) > 0: mainCtp = getCTP(i, self.mainCTPList) for j in i.childs: agentCtp = getCTP(j, self.agentCTPList) mainCtp.childList.append(agentCtp) agentCtp.father = mainCtp def getCTPList(self): return self.mainCTPList, self.mainAccountList def subscribeApi(self, subscribeObj, mainuserID): for i in self.mainAccountList: if i.userID == mainuserID: print('jinru') for sub in i.subscribes: if subscribeObj.channel_id == sub.channel_id: print('have subscript') break else: pass else: print('start subscribe...') i.subscribes.append(subscribeObj) self.save() #ctp列表中订阅 for j in self.mainCTPList: if j.userID == i.userID: j.subscribeList.append(subscribeObj) else: print('没有此操盘手:%s' % mainuserID) return self.mainAccountList def unsubscribeApi(self, subscribeObj, mainuserID): for i in self.mainAccountList: if i.userID == mainuserID: print('jinru') for sub in i.subscribes: if subscribeObj.channel_id == sub.channel_id: print('delect subscribe') i.subscribes.remove(sub) self.save() # ctp列表中删除订阅 for j in self.mainCTPList: if j.userID == i.userID: for each in j.subscribeList: if each.channel_id == subscribeObj.channel_id: j.subscribeList.remove(each) break else: pass else: print('You have not subscribed ') return self.mainAccountList def save(self): filename = os.getcwd() + r"\\accounts.ph" accounts = shelve.open(filename) accounts['mainAccountList'] = self.mainAccountList accounts['agentAccountList'] = self.agentAccountList accounts.close() def new(self, userID, password, brokerID, company, operator, tdAddress, mdAddress): mainuser = phAccount() mainuser.userID = userID mainuser.password = password mainuser.brokerID = brokerID mainuser.company = company mainuser.operator = operator mainuser.tdAddress = tdAddress mainuser.mdAddress = mdAddress mainuser.mainFlag = True for i in self.mainAccountList: if userID == i.userID: print('user have exist') num = input('1,确定修改,2 退出') if num == 1: print('sjsj') i.userID = userID i.password = password i.brokerID = brokerID i.company = company i.operator = operator i.tdAddress = tdAddress i.mdAddress = mdAddress # self.mainAccountList.pop() self.save() break else: print('tuichu') break else: print('else zhixing') self.mainAccountList.append(mainuser) self.save() return self.mainAccountList
class MainEngine: """ Acts as the core of VN Trader. """ def __init__(self, event_engine: EventEngine = None): """""" if event_engine: self.event_engine = event_engine else: self.event_engine = EventEngine() # 添加引擎之后,立即启动 self.event_engine.start() # 所有的gateway self.gateways = {} # 所有的引擎 self.engines = {} # 所有的App self.apps = {} # 交易所 self.exchanges = [] # 初始化引擎 self.init_engines() def add_engine(self, engine_class: Any): """ Add function engine. """ # 其他所有引擎的构建方式,要添加主引擎,和事件引擎 engine = engine_class(self, self.event_engine) # 保存所有引擎 self.engines[engine.engine_name] = engine return engine def add_gateway(self, gateway_class: BaseGateway): """ Add gateway. """ # gateway_class的构建方式,添加事件引擎 gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway # Add gateway supported exchanges into engine # 添加交易所数据 for exchange in gateway.exchanges: if exchange not in self.exchanges: self.exchanges.append(exchange) return gateway def add_app(self, app_class: BaseApp): """ Add app. """ # app的构建方式,单独的app app = app_class() self.apps[app.app_name] = app # 每个app有一个engine和主引擎相联 engine = self.add_engine(app.engine_class) return engine def init_engines(self): """ Init all engines. """ # 初始化所有引擎 # 初始化日志引擎 self.add_engine(LogEngine) # 初始化订单管理引擎 self.add_engine(OmsEngine) # 初始化邮件引擎 self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = ""): """ Put log event with specific message. """ # 写日志 log = LogData(msg=msg, gateway_name=source) # 发送事件 event = Event(EVENT_LOG, log) # 插入事件 self.event_engine.put(event) def get_gateway(self, gateway_name: str): """ Return gateway object by name. """ # 获取接口 gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str): """ Return engine object by name. """ # 获取引擎 engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str): """ Get default setting dict of a specific gateway. """ # 获取默认设置,这里也就是说,每个gateway,都有get_default_setting函数 gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self): """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self): """ Get all app objects. """ return list(self.apps.values()) def get_all_exchanges(self): """ Get all exchanges. """ return self.exchanges def connect(self, setting: dict, gateway_name: str): """ Start connection of a specific gateway. """ # 也就是说,所有的gateway都有connect方法,连接的配置,字典 gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str): """ Subscribe tick data update of a specific gateway. """ # 订阅所有的gateway_name gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def send_order(self, req: OrderRequest, gateway_name: str): """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str): """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str): """ 发一系列单 """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_orders(reqs) else: return ["" for req in reqs] def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str): """ 取消一系列单 """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_orders(reqs) def query_history(self, req: HistoryRequest, gateway_name: str): """ Send cancel order request to a specific gateway. 获取历史所有请求,由gateway提供函数query_history """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.query_history(req) else: return None def close(self): """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() # 关闭所有的engine for engine in self.engines.values(): engine.close() # 关闭所有的gateway for gateway in self.gateways.values(): gateway.close()
new_data = bars[n:] # 其它留着演示 else: history = bars # 先取得最新的n根bar作为历史 new_data = [] # 演示的为空 # 绘制历史K线主图及各个副图 widget.update_history(history) # 绘制委托单到主图 trades = make_trades() trades = [value for value in trades.values()] # widget.add_orders(orders) # 绘制成交单到主图 widget.add_trades(trades) def update_bar(): if new_data: bar = new_data.pop(0) widget.update_bar(bar) timer = QtCore.QTimer() timer.timeout.connect(update_bar) if dynamic: timer.start(100) widget.show() event_engine.start() app.exec_()
class MainEngine: """ Acts as the core of VN Trader. 做为VN Trader的内核 """ def __init__(self, event_engine: EventEngine = None): """""" if event_engine: # 传入 EventEngine, 如果不为None,则赋值 self.event_engine = event_engine else: # 如果为None,创建一个EventEngine self.event_engine = EventEngine() # 开始事件引擎,并产生定时器事件 self.event_engine.start() # 保存交易通道 self.gateways = {} # 保存注册的 引擎 self.engines = {} # 保存apps, app里 self.apps = {} # 保存交易所列表 self.exchanges = [] self.init_engines() def add_engine(self, engine_class: Any): """ Add function engine. """ engine = engine_class(self, self.event_engine) self.engines[engine.engine_name] = engine return engine def add_gateway(self, gateway_class: BaseGateway): """ Add gateway. """ gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway # Add gateway supported exchanges into engine for exchange in gateway.exchanges: if exchange not in self.exchanges: self.exchanges.append(exchange) return gateway def add_app(self, app_class: BaseApp): """ Add app. 把 app 保存在 self.apps和 self.engines """ app = app_class() self.apps[app.app_name] = app engine = self.add_engine(app.engine_class) return engine def init_engines(self): """ Init all engines. """ # 日志引擎 self.add_engine(LogEngine) # 提供订单管理系统函数给VN # Trader self.add_engine(OmsEngine) # 邮件引擎 self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = ""): """ Put log event with specific message. """ log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) self.event_engine.put(event) def get_gateway(self, gateway_name: str): """ Return gateway object by name. """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str): """ Return engine object by name. 根据名字返回引擎 """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str): """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self): """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self): """ Get all app objects. """ return list(self.apps.values()) def get_all_exchanges(self): """ Get all exchanges. """ return self.exchanges def connect(self, setting: dict, gateway_name: str): """ Start connection of a specific gateway. 开始链接指定的geteway """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str): """ Subscribe tick data update of a specific gateway. 从指定的gateway 订阅tick数据 """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def subscribe1min(self, req: SubscribeRequest1Min, gateway_name: str): """ Subscribe 1 min bar data update of a specific gateway. 从指定的gateway 订阅1 min bar数据 """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe1min(req) def send_order(self, req: OrderRequest, gateway_name: str): """ Send new order request to a specific gateway. 发送新的订单数据到指定的geteway """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str): """ Send cancel order request to a specific gateway. 发送撤单数据到指定的gateway """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str): """ """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_orders(reqs) else: return ["" for req in reqs] def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str): """ """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_orders(reqs) def query_history(self, req: HistoryRequest, gateway_name: str): """ 指定 gateway 请求历史数据 """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.query_history(req) else: return None def close(self): """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()
from vnpy.event import EventEngine from vnpy.trader.engine import LogEngine logengine = LogEngine() eventEngine = EventEngine() eventEngine.start()
# from vnpy.trader.vtFunction import getTempPath # from phFunction import getCTPPath,EventPush from vnpy.trader.gateway.ctpGateway.language import text from vnpy.trader.vtConstant import GATEWAYTYPE_FUTURES from vnpy.event import EventEngine, Event from vnpy.trader.vtEngine import MainEngine from vnpy.trader.gateway.ctpGateway.ctpGateway import * from phCTP import * userID = '118336' brokerID = '9999' accountID = "".join((userID, brokerID)) def atest(event): print event.dict_['data'] print('ddd') ee = EventEngine() # ee.register(".".join(("orderSend",accountID)),atest) # ee.start(timer=True) a = MainCtp(ee, userID, '147258369', "9999", "tcp://180.168.146.187:10001", "tcp://180.168.146.187:10001", "Z模拟", "telecom") print a a.connect() # ee.register(".".join(("orderSend",a.accountID)),atest) ee.start()
class MainEngine: """ Acts as the core of VN Trader. """ def __init__(self, event_engine: EventEngine = None): """""" if event_engine: self.event_engine = event_engine else: self.event_engine = EventEngine() self.event_engine.start() self.gateways = {} self.engines = {} self.apps = {} self.init_engines() def add_engine(self, engine_class: Any): """ Add function engine. """ engine = engine_class(self, self.event_engine) self.engines[engine.engine_name] = engine def add_gateway(self, gateway_class: BaseGateway): """ Add gateway. """ gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway def add_app(self, app_class: BaseApp): """ Add app. """ app = app_class() self.apps[app.app_name] = app self.add_engine(app.engine_class) def init_engines(self): """ Init all engines. """ self.add_engine(LogEngine) self.add_engine(OmsEngine) self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = ""): """ Put log event with specific message. """ log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) self.event_engine.put(event) def get_gateway(self, gateway_name: str): """ Return gateway object by name. """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str): """ Return engine object by name. """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str): """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self): """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self): """ Get all app objects. """ return list(self.apps.values()) def connect(self, setting: dict, gateway_name: str): """ Start connection of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str): """ Subscribe tick data update of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def send_order(self, req: OrderRequest, gateway_name: str): """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str): """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def close(self): """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()
class MainEngine: """ Acts as the core of the trading platform. """ def __init__(self, event_engine: EventEngine = None): """""" # 无论如何,保证总会有事件引擎对象 if event_engine: self.event_engine: EventEngine = event_engine else: self.event_engine = EventEngine() # 启动事件引擎,主引擎在创建的时候,事件引擎便启动了 self.event_engine.start() # 交易接口字典,无脑推断通过vntrader的UI界面里添加的交易接口都会存在这里 self.gateways: Dict[str, BaseGateway] = {} # 维护其他应用的引擎 # 注意app也会创建应用引擎,在创建的过程中也会保存到engines里 self.engines: Dict[str, BaseEngine] = {} # 存加载的应用实例, 在创建的过程中,应用类都会被实例化 self.apps: Dict[str, BaseApp] = {} # 保存接口支持的交易所 # 在add_gateway的时候自动添加交易接口支持的交易所 self.exchanges: List[Exchange] = [] os.chdir(TRADER_DIR) # Change working directory # 初始化服务引擎包括日志引擎、订单路由引擎、邮件引擎 self.init_engines() # Initialize function engines def add_engine(self, engine_class: Any) -> "BaseEngine": """ Add function engine. 这种实现机制真神奇 传入的是engine_class,就是一个类 在函数实现里创建这个类,这种设计可以使得不会出现engines字典内有同一个引擎的情况? BaseEngine的构造函数可以看出,一个引擎在创建的过程中,会传入主引擎、事件引擎、引擎名,这可真绕 这样在BaseEngine所派生的引擎里,就可以调用主引擎提供的接口 class BaseEngine(ABC): def __init__( self, main_engine: MainEngine, event_engine: EventEngine, engine_name: str, ): """ engine = engine_class(self, self.event_engine) self.engines[engine.engine_name] = engine return engine def add_gateway(self, gateway_class: Type[BaseGateway]) -> BaseGateway: """ Add gateway. """ # 引擎创建与添加,同样传入的也是一个类,在函数实现时创建 gateway = gateway_class(self.event_engine) self.gateways[gateway.gateway_name] = gateway # Add gateway supported exchanges into engine for exchange in gateway.exchanges: if exchange not in self.exchanges: self.exchanges.append(exchange) return gateway def add_app(self, app_class: Type[BaseApp]) -> "BaseEngine": """ Add app. """ # 应用app创建与添加 # app类里只是一些资源索引 app = app_class() self.apps[app.app_name] = app # 将app的引擎添加进引擎字典里 # 每个app的实现都会有引擎 engine = self.add_engine(app.engine_class) return engine def init_engines(self) -> None: """ Init all engines. """ self.add_engine(LogEngine) self.add_engine(OmsEngine) self.add_engine(EmailEngine) def write_log(self, msg: str, source: str = "") -> None: """ Put log event with specific message. """ log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) self.event_engine.put(event) def get_gateway(self, gateway_name: str) -> BaseGateway: """ Return gateway object by name. """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway def get_engine(self, engine_name: str) -> "BaseEngine": """ Return engine object by name. """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine def get_default_setting(self, gateway_name: str) -> Optional[Dict[str, Any]]: """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None def get_all_gateway_names(self) -> List[str]: """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) def get_all_apps(self) -> List[BaseApp]: """ Get all app objects. """ return list(self.apps.values()) def get_all_exchanges(self) -> List[Exchange]: """ Get all exchanges. """ return self.exchanges def connect(self, setting: dict, gateway_name: str) -> None: """ Start connection of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) def subscribe(self, req: SubscribeRequest, gateway_name: str) -> None: """ Subscribe tick data update of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) def send_order(self, req: OrderRequest, gateway_name: str) -> str: """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" def cancel_order(self, req: CancelRequest, gateway_name: str) -> None: """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) def send_quote(self, req: QuoteRequest, gateway_name: str) -> str: """ Send new quote request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_quote(req) else: return "" def cancel_quote(self, req: CancelRequest, gateway_name: str) -> None: """ Send cancel quote request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_quote(req) def query_history(self, req: HistoryRequest, gateway_name: str) -> Optional[List[BarData]]: """ Query bar history data from a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.query_history(req) else: return None def close(self) -> None: """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()
class MainEngine: """ Acts as the core of VN Trader. 一个大的类来把策略、ctp行情、事件引擎combine起来 ctaTemplate -> CtaEngine->mainEngine ->ctpgateway ->CtpT dApi, 传到C++封装的接口。返回的就是vtOrderID """ def __init__(self, event_engine: EventEngine = None): """绑定事件引擎""" if event_engine: self.event_engine = event_engine # 这个地方难道还可以绑到其他事件引擎 else: self.event_engine = EventEngine() self.event_engine.start() self.gateways = {} # 这个字典的key是借口名称,value是key对应的引擎 self.engines = {} # 传入的引擎 self.apps = {} self.exchanges = [] # 交易所 os.chdir(TRADER_DIR) # Change working directory # 用于改变当前工作的目录,from .utility import get_folder_path, TRADER_DIR,是这个地方把这个值引导过来了 # 也就是把Path.cwd转换成TRADER_DIR目录地址,此处为C:\Users\Administrator self.init_engines() # Initialize function engines # 添加引擎 def add_engine(self, engine_class: Any): """ Add function engine. """ engine = engine_class(self, self.event_engine) # 返回的是engine_class的一个实例对象,如返回EmailEngine, # 上面的self代表的是MainEngine,engine_class可以指BacktesterEngine或CtaEngine等。 self.engines[engine.engine_name] = engine # 这样子就可以把引擎的名字和对应的引擎对应起来 return engine # 添加网管,gateway就是交易场所的API对接网管,每次添加一个gateway,就添加了一个交易所名称 def add_gateway(self, gateway_class: Type[BaseGateway]): """ Add gateway:添加接口; 这个函数传入CTPGateway,将传入的CTPGateway """ gateway = gateway_class(self.event_engine) # //TODO:这个geteway_class是从外面传入的参数 # 这里得到一个gateway_class(是CTPGateway之类,不是BaseGateway)的实例,实例的参数是init MainEngine的时候传入的event_engine self.gateways[gateway.gateway_name] = gateway # 这里的gateway.gateway_name指的是ctp,调用上面的实例的gateway_name属性,并作为字典的键 # 这里得到了gateways字典,在下面的get_gateway函数要用,取出gateway。 # Add gateway supported exchanges into engine # 取出gateway的exchanges类属性(列表,非实例属性), for exchange in gateway.exchanges: if exchange not in self.exchanges: self.exchanges.append(exchange) return gateway # 主要是指增加系统界面的功能模块 def add_app(self, app_class: Type[BaseApp]): """ Add app. 添加上层应用 """ app = app_class() self.apps[app.app_name] = app engine = self.add_engine(app.engine_class) return engine # 初始化引擎 def init_engines(self): """ Init all engines. """ self.add_engine(LogEngine) # 启动日志引擎 self.add_engine(OmsEngine) # 启动订单管理系统 self.add_engine(EmailEngine) # 启动邮箱管理系统 # 写入日志 def write_log(self, msg: str, source: str = ""): """ Put log event with specific message. """ # LogData继承自BaseData,BaseData有gateway_name,所以这里可以传gateway_name,得到LogData对象。 # //TODO: 不知道这个函数在做什么 log = LogData(msg=msg, gateway_name=source) event = Event(EVENT_LOG, log) # Event传入type和data self.event_engine.put(event) # 获得网管 def get_gateway(self, gateway_name: str): """ Return gateway object by name. 作用是传入CtpGateway,从字典中取出CtpGateway实例,再返回这个实例,getway_name= """ gateway = self.gateways.get(gateway_name, None) if not gateway: self.write_log(f"找不到底层接口:{gateway_name}") return gateway # 这个返回getaway表示这个gateway已经启动了,现在可以使用了。 # 主要用于后面的send_order,subscibe # 获得引擎 def get_engine(self, engine_name: str): """ Return engine object by name. """ engine = self.engines.get(engine_name, None) if not engine: self.write_log(f"找不到引擎:{engine_name}") return engine # 获得默认设置 def get_default_setting(self, gateway_name: str): """ Get default setting dict of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.get_default_setting() return None # 获得所有引擎的名字 def get_all_gateway_names(self): """ Get all names of gatewasy added in main engine. """ return list(self.gateways.keys()) # 获得所有的APP def get_all_apps(self): """ Get all app objects. """ return list(self.apps.values()) # 获得所有的交易所 def get_all_exchanges(self): """ Get all exchanges. """ return self.exchanges # 连接到行情 def connect(self, setting: dict, gateway_name: str): """ Start connection of a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.connect(setting) # 合约订阅 def subscribe(self, req: SubscribeRequest, gateway_name: str): """ Subscribe tick data update of a specific gateway. 根据传入的CtpGateway,调用get_gateway函数取出CtpGateway实例,然后订阅行情。 """ gateway = self.get_gateway(gateway_name) if gateway: gateway.subscribe(req) # 调用CTPGateway实例的subscribe方法,而self.md_api.subscribe(req)的方法就是self.md_api.subscribe(req),即底层API,而传入的参数是SubscribeRequest(一个类),应该是{self.symbol}.{self.exchange.value}这样的形式 # 下单 def send_order(self, req: OrderRequest, gateway_name: str): """ Send new order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_order(req) else: return "" # 取消订单 def cancel_order(self, req: CancelRequest, gateway_name: str): """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_order(req) # 批量下单 def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str): """ """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.send_orders(reqs) else: return ["" for req in reqs] # 批量取消订单 def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str): """ """ gateway = self.get_gateway(gateway_name) if gateway: gateway.cancel_orders(reqs) # 历史查询 def query_history(self, req: HistoryRequest, gateway_name: str): """ Send cancel order request to a specific gateway. """ gateway = self.get_gateway(gateway_name) if gateway: return gateway.query_history(req) else: return None # 关闭 def close(self): """ Make sure every gateway and app is closed properly before programme exit. """ # Stop event engine first to prevent new timer event. self.event_engine.stop() for engine in self.engines.values(): engine.close() for gateway in self.gateways.values(): gateway.close()