小散量化炒股记|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。如下所示:

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

1908c5c009339212cad16470895844a5.png

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

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

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

classProgressThread(threading.Thread):
    """进度条类  """
    def __init__(self, parent):
        """
        :param parent:  主线程UI
        :param timer:  计时器
        """
        super(ProgressThread, self).__init__()  # 继承
        self.parent = parent
        self.setDaemon(True)  # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。


    def run(self):
        count = 0
        while count < 5:
            count = count + 0.5
            time.sleep(0.5)
            wx.CallAfter(self.parent.update_process_bar, count)  # 更新进度条进度
        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

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

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

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

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

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

说明

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

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

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

4108c6add279fa444e01240b92ffba30.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值