回到OptionMaster

根据我们对APP调用的代码阅读,我们基本上知道了一个APP是如何被调用,那么我们回到OptionMaster学习下这个APP的实现。

看看结构

class OptionManager(QtWidgets.QWidget):
""""""
signal_new_portfolio = QtCore.pyqtSignal(Event) def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
pass def init_ui(self):
pass def register_event(self):
pass def process_new_portfolio_event(self, event: Event):
pass def update_portfolio_combo(self):
pass def open_portfolio_dialog(self):
pass def init_widgets(self):
pass def calculate_underlying_adjustment(self):
pass

通过结构和注释,我们基本上知道这是一个期权方面的APP。我们来对代码进行仔细学习

__init__

    def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
""""""
super().__init__() self.main_engine = main_engine
self.event_engine = event_engine
self.option_engine = main_engine.get_engine(APP_NAME) self.portfolio_name: str = "" self.market_monitor: OptionMarketMonitor = None
self.greeks_monitor: OptionGreeksMonitor = None self.docks: List[QtWidgets.QDockWidget] = [] self.init_ui()
self.register_event()

在init中我们看到和MainWindow不一样的地方出了main_engine和event_engin还加入了一个他自己的引擎,这个引擎是在app注册时候配置在engine_class中的。然后有两个报表:market_monitor和greeks_monitor

init_ui

    def init_ui(self):
#具体实现
self.portfolio_button = QtWidgets.QPushButton("配置")
self.portfolio_button.clicked.connect(self.open_portfolio_dialog)

简单的界面配置我们通过运行程序看到实现的大概如下



我们只看到portfolio_button点击以后调用了self.open_portfolio_dialog

open_portfolio_dialog

    def open_portfolio_dialog(self):
""""""
portfolio_name = self.portfolio_combo.currentText()
if not portfolio_name:
return self.portfolio_name = portfolio_name dialog = PortfolioDialog(self.option_engine, portfolio_name)
result = dialog.exec_() if result == dialog.Accepted:
self.portfolio_combo.setEnabled(False)
self.portfolio_button.setEnabled(False) self.init_widgets()

我们看到点击配置以后,如果有选择期权产品,则弹出 PortfolioDialog对话框。根据对话框的执行结果,如果点击了接受,则下拉框和配置按钮不可用,然后执行init_widgets

init_widgets

    def init_widgets(self):
""""""
self.market_monitor = OptionMarketMonitor(self.option_engine, self.portfolio_name)
self.greeks_monitor = OptionGreeksMonitor(self.option_engine, self.portfolio_name)
self.manual_trader = OptionManualTrader(self.option_engine, self.portfolio_name) self.market_monitor.itemDoubleClicked.connect(self.manual_trader.update_symbol) self.market_button.clicked.connect(self.market_monitor.showMaximized)
self.greeks_button.clicked.connect(self.greeks_monitor.showMaximized)
self.manual_button.clicked.connect(self.manual_trader.show)
self.chain_button.clicked.connect(self.calculate_underlying_adjustment) for button in [
self.market_button,
self.greeks_button,
self.chain_button,
self.manual_button
]:
button.setEnabled(True)

我们看到则是对market_monitor,greeks_monitor,manual_trader进行实例化,并且绑定了事件的信号插槽。同时对一些按钮进行了绑定,基本上都是窗体的显示。主要是以下按钮和窗体的显示的对应

        self.market_button = QtWidgets.QPushButton("T型报价")
self.greeks_button = QtWidgets.QPushButton("持仓希腊值")
self.chain_button = QtWidgets.QPushButton("拟合升贴水")
self.manual_button = QtWidgets.QPushButton("快速交易")

而且每一个窗体都传入了该APP定义的engine

register_event

我们在__init__方法中同时看到了此方法的调用。

    def register_event(self):
""""""
self.signal_new_portfolio.connect(self.process_new_portfolio_event) self.event_engine.register(EVENT_OPTION_NEW_PORTFOLIO, self.signal_new_portfolio.emit)

我们看到该方法把 process_new_portfolio_event的Handler和register到了MainEngine中去。

process_new_portfolio_event

    def process_new_portfolio_event(self, event: Event):
""""""
self.update_portfolio_combo() def update_portfolio_combo(self):
""""""
if not self.portfolio_combo.isEnabled():
return self.portfolio_combo.clear()
portfolio_names = self.option_engine.get_portfolio_names()
self.portfolio_combo.addItems(portfolio_names)

根据handler的调用来更新期权产品的列表

calculate_underlying_adjustment


self.chain_button.clicked.connect(self.calculate_underlying_adjustment)
    def calculate_underlying_adjustment(self):
""""""
portfolio = self.option_engine.get_portfolio(self.portfolio_name) for chain in portfolio.chains.values():
chain.calculate_underlying_adjustment()

我们看到 快速交易点击以后,会执行从引擎中获得期权产品的数据,然后执行calculate_underlying_adjustment()方法,要继续深入下去,我们有几个方向:

  1. market_monitor
  2. greeks_monitor
  3. manual_trader
  4. option_engine
  5. calculate_underlying_adjustment

我们还是从周围向心脏的方式学习,先看看几个窗体,然后随后深入引擎的代码学习

market_monitor

class OptionMarketMonitor(MonitorTable):

    def __init__(self, option_engine: OptionEngine, portfolio_name: str):

    def init_ui(self):

    def register_event(self):

    def process_tick_event(self, event: Event):

    def process_trade_event(self, event: Event):

    def process_position_event(self, event: Event):

    def update_pos(self, vt_symbol: str):

    def update_price(self, vt_symbol: str):

    def update_impv(self, vt_symbol: str):

    def update_greeks(self, vt_symbol: str):

    def scroll_to_middle(self):

    def resizeEvent(self, event: QtGui.QResizeEvent):

我们看到 OptionMarketMonitor继承了MonitorTable,而MonitorTable基本上和框架里面的MonitorBase如出一辙。其实大量代码几乎可以重用。

我们先来看看这个类的具体代码,最值得琢磨的其实是这个

    def register_event(self):
""""""
self.signal_tick.connect(self.process_tick_event)
self.signal_trade.connect(self.process_trade_event)
self.signal_position.connect(self.process_position_event) self.event_engine.register(EVENT_TICK, self.signal_tick.emit)
self.event_engine.register(EVENT_TRADE, self.signal_trade.emit)
self.event_engine.register(EVENT_POSITION, self.signal_position.emit)
def __init__(self, option_engine: OptionEngine, portfolio_name: str):
""""""
super().__init__() self.option_engine = option_engine
self.event_engine = option_engine.event_engine
self.portfolio_name = portfolio_name

把处理tick事件,交易事件,仓位事件都和OptionEngine连接起来。

而这些处理的Handler无非根据信息改变界面,就不一一研究。

其他窗体

class OptionManualTrader(QtWidgets.QWidget):
def __init__(self, option_engine: OptionEngine, portfolio_name: str):
""""""
super().__init__() self.option_engine = option_engine
self.main_engine: MainEngine = option_engine.main_engine
self.event_engine: EventEngine = option_engine.event_engine

我们可以看到窗体不但对自己的引擎OptionEngine,而且也对mainEngin和EventEngine有所调用。

 def send_order(self):
""""""
symbol = self.symbol_line.text()
contract = self.contracts.get(symbol, None)
if not contract:
return price_text = self.price_line.text()
volume_text = self.volume_line.text() if not price_text or not volume_text:
return price = float(price_text)
volume = int(volume_text)
direction = Direction(self.direction_combo.currentText())
offset = Offset(self.offset_combo.currentText()) req = OrderRequest(
symbol=contract.symbol,
exchange=contract.exchange,
direction=direction,
type=OrderType.LIMIT,
offset=offset,
volume=volume,
price=price
)
self.main_engine.send_order(req, contract.gateway_name)

整个是通过main_engin来下单的。而在分析主引擎的时候我们知道send_order正是通过gateway_name来下单的。

而gateway_name来自contract合约

而合约来自main_engin

    def init_contracts(self):
""""""
contracts = self.main_engine.get_all_contracts()
for contract in contracts:
self.contracts[contract.symbol] = contract

我们可以想象得到。而main_engine中合约的信息又来自OmsEngine 指定管理系统 (Order Manage System)

接下来我们要继续深入就必须深入到引擎的内容了。

最新文章

  1. jQuery.extend 函数详解
  2. linux的一些常用命令
  3. iOS开发之组件化架构漫谈
  4. JAVA字符串的GZIP压缩解压缩
  5. C#中怎么在EXCEL中的单元格中画斜线啊 ??
  6. android 38 Abdroid客户端和服务端交互
  7. 用它解决大问题啦,STRACE应用
  8. jquery 定时器
  9. linux文件名乱码解决办法
  10. None是什么?
  11. VisualStudio2010配置OpenCV的一种一劳永逸的方法
  12. C#之流程控制语句
  13. scala的多种集合的使用(5)之数组Array(ArrayBuffer)的操作
  14. 面向对象:MATLAB的自定义类 [MATLAB]
  15. sock5协议转换http协议工具polipo使用笔记(Centos7)
  16. redis内部数据结构深入浅出
  17. 2018.07.20 atcoder Largest Smallest Cyclic Shift(贪心)
  18. [C#] Delegate, Multicase delegate, Event
  19. HDU 1596 最短路变形
  20. css_input[checked]复选框去掉默认样式并添加新样式

热门文章

  1. 安装arcgis server时提示“应用程序无法启动,因为应用程序......或使用命令行sxstrace.exe”
  2. coding++:Arrays.asList() - java.lang.UnsupportedOperationException异常处理
  3. CSS盒子模型(boeder)+浮动(float)+定位(position)
  4. java数据库 DBHelper
  5. vulnhub~sunset:dusk1
  6. Q - Marriage Match IV (非重复最短路 + Spfa + 网络最大流Isap)
  7. Scala学习系列(一)——Scala为什么是大数据第一高薪语言
  8. 我去,还在这样读写 excel 这也太低效了吧!
  9. web自动化浏览器chrome和驱动chromedriver
  10. Scratch 全套学习资料