第 10 章 · 03 ipywidgets GUI 与全书回顾 本节摘要:本节解剖 ABU 的"无编程量化"层—— (约 4716 行 ipywidgets GUI),然后做全书 10 章的系统回顾。WidgetBu 用 ipywidgets 的 Tab/Accordion/SelectMultiple/Button 把回测/选股/买卖因子/UMP/网格搜索/交叉验证全部做成 Jupyter 内的可视化交互界面。核心是 ( ):用 装七个子面板(基本/股池/买策/卖策/选股/资管/裁判),底部一个"开始回测"按钮,点击即调 。用户全程不写代码,点点鼠标就能跑回测。
本节摘要:本节解剖 ABU 的"无编程量化"层——
WidgetBu(约 4716 行 ipywidgets GUI),然后做全书 10 章的系统回顾。WidgetBu 用 ipywidgets 的 Tab/Accordion/SelectMultiple/Button 把回测/选股/买卖因子/UMP/网格搜索/交叉验证全部做成 Jupyter 内的可视化交互界面。核心是WidgetRunLoopBack(ABuWGBRun.py):用widgets.Tab()装七个子面板(基本/股池/买策/卖策/选股/资管/裁判),底部一个"开始回测"按钮,点击即调run_loop_back。用户全程不写代码,点点鼠标就能跑回测。GUI 的每个因子面板(WidgetFactorBase)都通过delegate_class委托到具体的因子类,与第 3-4 章的 dict 因子定义无缝衔接。本节后半是全书回顾——从第 1 章的 run_loop_back 入口,经过行情数据、买入因子 Mixin、卖出 ATR 三层、交易执行资金融合、度量评分交叉验证、UMP 裁判(全书灵魂)、ML 三路径、技术分析弃用 talib,直到本章的并行调度 + GUI,完整串讲 ABU 的系统架构。最后总结 ABU 的三大遗产(UMP 裁判创新/可插拔工程美学/ML 服务交易)并给出读者下一步建议。这是全书的最后一节。
内容来源:原项目源码
abupy/WidgetBu/(4716 行,22 个文件),重点ABuWGBase.py+ABuWGBRun.py;并回顾全书 10 章脉络。
⚠️ 注意:本节是全书收官。重点理解 GUI 的"委托模式"——每个因子面板通过
delegate_class属性绑定到具体因子类,用户在界面填的参数会自动组装成第 3 章讲过的 dict 因子定义({'class': XxxFactor, 'param1': val1, ...}),与编程接口完全一致。这种"GUI 和代码共用同一套因子定义"的设计,让 ABU 既能给程序员用(代码),也能给普通用户用(GUI)。本节末尾的全书回顾不用过渡段,直接给收尾。
阅读完本节,你应当能够:
WidgetRunLoopBack.__init__:构造七个子面板(TT/sc/bf/sf/ps/pos/ump)→ widgets.Tab() 装载 → 底部"开始回测"按钮 → on_click 绑定 run_loop_back。WidgetBu(4716 行,22 个文件)用 ipywidgets 在 Jupyter 内构建交互界面。三级抽象在 ABuWGBase.py:
40 class WidgetBase(object): 43 def __call__(self): 44 return self.widget 46 def display(self): 48 display(self.widget) 51 class WidgetFactorBase(six.with_metaclass(ABCMeta, WidgetBase)): 54 def __init__(self, wg_manager): 55 self.wg_manager = wg_manager 61 @abstractmethod 62 def _init_widget(self): 67 @abstractmethod 68 def delegate_class(self): 72 class WidgetFactorManagerBase(six.with_metaclass(ABCMeta, WidgetBase)): 75 def __init__(self, show_add_buy=True, add_button_style='default'): 76 self.factor_dict = {} 82 self.selected_factors = widgets.SelectMultiple(options=[], description=u'已添加策略:', ...) 89 self.selected_factors.observe(self.remove_factor, names='value')
三级:
display()(调 IPython.display.display)。__call__ 返回 self.widget,方便嵌套。_init_widget(界面长啥样)和 delegate_class(委托到哪个因子类)。selected_factors(SelectMultiple)显示"已添加策略",点击可删除。accordion_shut(L28-36)处理 ipywidgets 版本兼容——折叠面板的 selected_index 在不同版本取值不同(-1 或 None),用 try/except 兜底。
WidgetRunLoopBack(ABuWGBRun.py:39-73)是 GUI 的主入口,构造七个 Tab:
43 def __init__(self): 45 self.tt = WidgetRunTT() # 基本设置(资金/周期/大盘) 46 self.sc = WidgetSymbolChoice() # 股池(选哪些股票) 47 self.bf = BuyFactorWGManager() # 买策(买入因子管理) 49 self.sf = SellFactorWGManager() # 卖策(卖出因子管理) 51 self.sf.register(self.bf) # 卖策注册到买策(接收买入因子变化) 53 self.ps = PickStockWGManager() # 选股(选股因子管理) 55 self.ps.register(self.bf) # 选股注册到买策 57 self.pos = PosWGManager() # 资管(资金管理) 59 self.pos.register(self.bf) # 资管注册到买策 62 self.ump = WidgetUmp() # 裁判(UMP 设置) 64 sub_widget_tab = widgets.Tab() 65 sub_widget_tab.children = [self.tt.widget, self.sc.widget, self.bf.widget, self.sf.widget, self.ps.widget, 66 self.pos.widget, self.ump.widget] 67 for ind, name in enumerate([u'基本', u'股池', u'买策', u'卖策', u'选股', u'资管', u'裁判']): 68 sub_widget_tab.set_title(ind, name) 70 self.run_loop_bt = widgets.Button(description=u'开始回测', layout=widgets.Layout(width='98%'), button_style='danger') 72 self.run_loop_bt.on_click(self.run_loop_back) 73 self.widget = widgets.VBox([sub_widget_tab, self.run_loop_bt])
七个 Tab 对应回测的七个维度:
| Tab | 组件 | 对应章节 |
|---|---|---|
| 基本 | WidgetRunTT | 第 1 章(资金/周期/大盘) |
| 股池 | WidgetSymbolChoice | 第 2 章(标的池) |
| 买策 | BuyFactorWGManager | 第 3 章(买入因子 Mixin) |
| 卖策 | SellFactorWGManager | 第 4 章(卖出 ATR 三层) |
| 选股 | PickStockWGManager | 第 10 章(选股调度) |
| 资管 | PosWGManager | 第 4 章(仓位管理) |
| 裁判 | WidgetUmp | 第 7 章(UMP 主裁边裁) |
注意 L51/55/59 的 register(self.bf)——卖出/选股/资管管理器都注册到买入因子管理器。为什么?因为买入因子需要知道"配套的卖出因子是谁"(买入因子可自带卖出)、"选股因子是谁"(专属选股)、"资金管理是谁"(决定仓位)。register 建立这种联动——卖出因子变化时,通知买入因子管理器更新。
底部"开始回测"按钮(button_style='danger' 红色醒目),on_click(self.run_loop_back) 绑定点击事件。点击后,GUI 把七个 Tab 的设置收集成参数,调 run_loop_back(...)(第 1 章的入口函数),回测结果在 _metrics_out_put(L75-108)里展示——度量图、orders_pd、action_pd、capital_pd、commission_df 全部 display 出来。
GUI 的精妙在于"与代码共用同一套因子定义"。每个因子面板(WidgetFactorBase 子类)通过 delegate_class 绑定到具体因子类:
# 假设的买入因子面板(简化) class WidgetBuyCallXK(WidgetFactorBase): def delegate_class(self): return AbuFactorBuyXK # 委托到具体的突破买入因子类 def _init_widget(self): self.xd = widgets.IntText(value=21, description='周期:') # ... 其他参数控件
用户在界面填参数(xd=21 等),点"添加策略"时,管理器把这些参数组装成 dict:
{'class': AbuFactorBuyXK, 'xd': 21, ...} # 这就是第 3 章讲过的 dict 因子定义!
这个 dict 与编程接口 run_loop_back(buy_factors=[{'class': AbuFactorBuyXK, 'xd': 21}]) 完全一致。所以 GUI 和代码是同一套底座——GUI 只是帮你填 dict,本质还是调 run_loop_back。这种设计让 GUI 用户和程序员共享同一套因子库,新增因子只需写一个 Widget 面板,GUI 自动支持。
WidgetBu 的 22 个文件覆盖 ABU 的所有功能:
| 模块 | 功能 | 对应章节 |
|---|---|---|
| ABuWGBRun | 回测主界面(七 Tab) | 第 1-10 章 |
| ABuWGBuyFactor | 买入因子面板库 | 第 3 章 |
| ABuWGSellFactor | 卖出因子面板库 | 第 4 章 |
| ABuWGPickStock | 选股因子面板库 | 第 10 章 |
| ABuWGPosition | 资金/仓位面板库 | 第 4 章 |
| ABuWGUmp | UMP 裁判面板 | 第 7 章 |
| ABuWGGridSearch | 网格搜索可视化 | 第 6 章 |
| ABuWGCrossVal | 交叉验证可视化 | 第 6/8 章 |
| ABuWGSMTool | 相似度匹配工具 | 第 9 章 |
| ABuWGTLTool | 技术线分析工具 | 第 9 章 |
| ABuWGDATool | 数据分析工具 | 第 2 章 |
| ABuWGStockInfo | 股票信息查询 | 第 2 章 |
| ABuWGUpdate | 数据更新 | 第 2 章 |
| ABuWGQuantTool | 量化工具入口 | 全局 |
| ABuWGVerifyTool | 验证工具 | 度量 |
用户在 Jupyter 里 from abupy.WidgetBu import WidgetRunLoopBack; WidgetRunLoopBack().display(),七 Tab 界面弹出,全程不写代码就能跑回测、调参数、看度量、配置 UMP、做网格搜索。这就是 ABU 的"无编程量化"愿景——把量化交易从程序员专属,扩展到普通用户。
我们终于走完了 ABU 源码精读的全程。把 10 章串起来,你会看到一套清晰的回测系统架构:
从 ABu.run_loop_back 开始——这个函数是 ABU 的唯一入口,接收 buy_factors/sell_factors/stock_pickers/cash_range/benchmark 等参数,内部依次调 AbuPickStockMaster 选股 → AbuPickTimeMaster 择时 → 返回 AbuResultTuple(orders_pd/action_pd/capital/metrics)。全书的脉络从这个函数展开。
MarketBu 负责 KL 数据的获取/缓存/对齐。AbuKLManager 管理多 symbol 的 KL,支持 HDF5/CSV 存储,combine_pre_kl_pd 合并历史数据供因子预热。这是回测的"原料层"。
FactorBuyBu 用 Mixin 模式(BuyCallMixin 向上突破/BuyPutMixin 向下突破)+ dict 因子定义 + 装饰器(AbuLeastPolyWrap 大盘震荡封锁)构建买入决策。fit_day 是核心接口,每个因子实现自己的"今天是否买入"逻辑。
FactorSellBu 用 ATR 三层止盈止损(止盈线/止损线/风险线)+ 涨跌停过滤(当日涨跌停不能交易)+ 仓位管理(AbuAtrPosition 用 ATR 定仓位)。read_fit_day 是核心接口。
TradeBu 的 AbuCapital 维护资金时序,apply_action_to_capital 把 action_pd 作用到资金上生成 capital_pd。手续费由 AbuCommission 上下文管理(按市场/品种不同费率)。有限资金下买单可能因资金不足被拒。
MetricsBu 用 empyrical 算夏普/索提诺/最大回撤等指标,scoring 给策略打分,AbuCrossVal 用策略间相关度做稳健性验证。这是回测的"体检报告"。
UmpBu 是 ABU 最创新的模块——主裁(AbuUmpMainBase 用 GMM 聚类学习历史交易特征)+ 边裁(AbuUmpEdgeBase 用 KNN)+ 黄金分割(AbuUmpDegBase)。predict_proba_threshold 拦截低胜率交易。这是"ML 拦截已发订单"的范式,ABU 区别于其他回测框架的核心创新。
MLBu 提供三条 ML 接入路径:① UMP 拦截(第 7 章);② 买入信号(BtcBigWaveClf 预测大波动);③ 稳健性验证(AbuCrossVal)。cross_val_prob_accuracy_score + search_match_pos_threshold 搜最优阈值。这是 ML 与交易决策的深度衔接。
TLineBu(AbuTLine 技术线 + 阻力支撑聚类 + 黄金分割)+ IndicatorBu(弃用 talib,全自实现 ATR/MA/布林/MACD/RSI)。双引擎架构保留切换能力,但默认 E_FROM_PD 全用 pandas。
AlphaBu(选股 Master-Worker 一票否决 + 择时时间驱动自然周月)+ WidgetBu(ipywidgets 七 Tab 无编程量化)。这是回测的"调度器官"和"用户界面"。
回头看,ABU 给量化社区留下三份独特遗产:
UMP(Umpire Master Programme)是 ABU 最原创的设计——把"是否拦截已发订单"做成独立的裁判层,用 GMM/KNN 学习历史交易特征,对新订单 predict_proba_threshold 拦截。这完全区别于"ML 作为买卖信号"的传统路径——UMP 不决策买卖,只决策"这个买卖要不要拦"。这种"裁判与球员分离"的架构,让 ML 能在不破坏原策略逻辑的前提下提升胜率,是工程上的精妙创新。
ABU 的因子系统是可插拔工程的典范——买入/卖出/选股/仓位因子全部用 dict 定义({'class': XxxFactor, 'param': val}),用 Mixin 组合行为(向上/向下突破),用装饰器横切关注点(大盘震荡封锁)。新增一个因子只需写一个类继承基类,不改任何现有代码。这种"开放-封闭"的工程美学,让 ABU 能容纳几十种因子而不混乱。
ABU 把 ML 深度嵌入回测各环节:① UMP 拦截(决策拦截);② 买入信号(决策买入);③ 稳健性验证(决策策略可信度)。ML 不是孤立的预测模型,而是嵌入决策链的"服务"。这种"ML as a service for trading"的架构,让回测流水线具备"自我进化"能力——回测越多,UMP 越聪明,买入信号越准,策略评估越可靠。
读完本书,你已具备读懂 ABU 任何模块的能力。下一步深入的建议方向:
结合 abupy_lecture 实操:ABU 项目配套 32 节 ipynb 实操教程,覆盖从入门到高阶的全场景。建议挑感兴趣的章节(如 UMP 实战、ML 优化、多市场回测)动手跑一遍,把书本知识与可运行案例对照。
深入 UMP 自定义裁判:第 7 章讲了 UMP 的内置实现(GMM/KNN/deg)。建议自己写一个自定义裁判(比如用 RandomForest 或 XGBoost 替换 GMM),对照 AbuUmpMainBase 的抽象精读源码。UMP 是 ABU 最有创新性的模块,自定义裁判是检验理解深度的最好方式。
写一个完整策略闭环:挑一个品种,自己写一个买入因子(基于第 9 章的技术指标触发)+ 卖出因子(ATR 止损)+ UMP 裁判,跑回测、做网格搜索、再上 GUI 可视化。把全书知识在一个项目里串起来。
对比其他量化框架:ABU 的设计(UMP 裁判/时间驱动/GUI)是独特的,但也有局限(单标的为主/因子组合偏简单)。建议对比 vnpy(本系列另一本教程,偏向实盘 CTA)、backtrader(经典事件驱动)、zipline(美国主流),理解不同框架的取舍。
从回测走向实盘:ABU 主要是回测框架,实盘能力有限。如果你想真正交易,需要把 ABU 的策略逻辑移植到 vnpy 等实盘框架,或对接交易所 API。这是从"研究"走向"生产"的关键一步。
量化交易系统的复杂度,不在任何一行代码里,而在千百行代码如何组织成一个能自我进化的系统。ABU 给了我们一个绝佳的范本——它不是最大的量化框架,但是把"ML 嵌入交易决策"这件事做得最有想法的之一。UMP 裁判、可插拔因子、ML 三路径,这些设计思想值得你在任何量化系统里借鉴。
希望这本教程能成为你量化工程之路的一块垫脚石。
祝你代码无 bug、策略正收益、回撤可控。