• 小散量化炒股记|wxPython中多线程解决方案,加速全市场选股就用它


    c4fb30517232a601830caac2993a5e89.png

    前言

    b0e4d78af722e928ad4459d1249d0641.png

    我们使用Python开发带有GUI的量化系统,有时候我们需要进行全市场选股、全市场行情数据下载等循环任务,这个时候往往需要执行很长时间。

    我们会发现在点击“开始选股” 或者“开始下载”按钮之后,耗时任务会堵塞GUI的事件循环,于是,程序卡死了!

    如何才能避免这种情况呢?我们可以利用wxPython多线程方案来完美解决!

    9cd6ef1d2db3596b0a2af971964d0467.png

    多线程方案

    5ad4b7783321ec796c46ba24631ca567.png

    我们以全市场选股为场景来介绍wxPython多线程的方案。

    首先创建一个主线程和三个子线程:

    • AppUI:GUI的主界面

    • ProgressThread:进度条指示选股执行进度

    • SelectThread:执行选股策略

    设计多线程GUI时,建议主线程进行UI相关的控件事件、显示数据绘制等任务,而子线程只进行业务逻辑处理。

    2a07cc947ae97bb63377bef5a9629a5d.png

    当我们点击“开始选股”按钮后,主线程会触发Button事件,此时会启用子线程ProgressThread和SelectThread。如下所示:

    1. def on_click_start(self, evt):
    2. self.dialog = wx.ProgressDialog("选股进度", "Time remaining", 5,
    3. style=wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
    4. self.progress = ProgressThread(self)
    5. self.progress.start()
    6. self.select = SelectThread(self)
    7.     self.select.start()

    1908c5c009339212cad16470895844a5.png

    因为GUI的操作必须发生在主线程或者应用程序住循环所处的地方中。当涉及到子线程需要调用主线程任务时,wxPython提供了“线程安全”的函数——wx.PostEvent、wx.CallAfter和wx.CallLater。

    此处,我们使用wx.CallAfter()即可,传递给wx.CallAfter()的函数对象总是在主线程中处理的。这是wxPython中子线程给主线程发送消息最简单的方法。

    wxPython中子线程调用wx.CallAfter()方法之后,会使得主线程的UI可以在当前事件结束处理后,去处理子线程发送的消息。

    1. classProgressThread(threading.Thread):
    2.     """进度条类  """
    3. def __init__(self, parent):
    4. """
    5. :param parent: 主线程UI
    6. :param timer: 计时器
    7. """
    8. super(ProgressThread, self).__init__() # 继承
    9. self.parent = parent
    10. self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。
    11. def run(self):
    12. count = 0
    13. while count < 5:
    14. count = count + 0.5
    15. time.sleep(0.5)
    16. wx.CallAfter(self.parent.update_process_bar, count) # 更新进度条进度
    17. wx.CallAfter(self.parent.close_process_bar) # destroy进度条

    例程中,我们在每次循环中调用wx.CallAfter更新进度条的刻度,当执行完成后调用wx.CallAfter去摧毁进度条,而操作进度条是在主线程中处理的。

    另外,wxPython线程间的调用还能使用发布-订阅机制。

    在wxPython 2.8.11之前,wx.lib.pubsub模块提供了发布-订阅方式实现线程间的调用。从wxPython 2.8.11开始,wx.lib.pubsub集成了新的PyPubSub。

    首先要安装下PyPubSub模块,然后导入该模块:

    from pubsub import pub

    其次订阅以下主题,接收以下主题的信息:

    1. pub.subscribe(self.update_process_bar, "update")
    2. pub.subscribe(self.close_process_bar, "close")

    当要调用的时候,发布主题并向主题发送信息:

    1. wx.CallAfter(pub.sendMessage,"update", count=count) # 更新进度条进度
    2. wx.CallAfter(pub.sendMessage, "close") # destroy进度条

    目前在QTYX量化系统中,我们已经将行情数据下载采用了多线程方式,下一步在选股分析的时候也会采用这种方式。

    说明

    wxPython是量化编程的基础知识,我们会把完整的源码上传到知识星球《Python量化场景编程技巧与方法》中,帮助小伙伴们更好地掌握这个方法。

    《Python量化场景编程技巧和方法》围绕《玩转股票量化交易》中涉及到的一些内容,分享一些偏基础的关于Python编程技巧、Pandas编程技巧、数据库技巧、可视化编程技巧等等。
    加入星球《玩转股票量化交易》的会员可以免费加入星球《Python量化场景编程技巧与方法》,微信联系我加入!!

    知识星球介绍点击:知识星球《玩转股票量化交易》精华内容概览

    4108c6add279fa444e01240b92ffba30.jpeg

  • 相关阅读:
    Java方向面试题(一)
    软件测试/测试开发丨ChatGPT:带你进入智能对话的新时代
    .Net 6.0 处理跨域的方式
    CTF-misc练习(https://buuoj.cn)之第一页
    线性回归法学习笔记
    力扣.20. 有效的括号(栈的括号匹配问题)
    Java多态
    【持续集成_06课_Jenkins高级pipeline应用】
    html表白代码
    javaEE基于springboot的小区社区文化活动报名系统jsp生活服务网站
  • 原文地址:https://blog.csdn.net/hangzhouyx/article/details/126792031