当前位置: 首页 > news >正文

《中文Python穿云箭量化平台二次开发技术10》基于Tkinter的可视化股票池量化平台开发技术

《中文Python穿云箭量化平台二次开发技术10》基于Tkinter的可视化股票池量化平台开发技术
在上一篇【《中文Python穿云箭量化平台二次开发技术09》设计一个可视化股票池量化平台项目用于实现选股和自动交易】,我们介绍了可视化量化平台的开发技术。我们利用穿云箭模块,花费了4天就完成了全部代码的设计,这篇我们给出部分关键代码的实现方法。
声明:本文中代码是【小白量化股票池】的部分代码,仅供个人学习参考,不得直接商用或销售。
在整个软件中,我们充分利用了穿云箭量化的现成金融模块,以及Python自带的GUI模块Tkinter很快能搭建出任何量化工具。
在股票池菜单设计中,我们要实现这些功能。【‘打开自选股文件’,‘增加自选股’,‘保存自选股文件’,‘板块股票’,‘问财选股’,‘清空股票池’】
实现的完整代码如下。

class gpc(tk.LabelFrame):   #股票池def __init__(self, root=None,x=0,y=0,width=140, height=80,text='股票池',bg='#AA8888',bd=0,font='Helvetic 12',tag='kaishi',**options):global xm,xm2,xmi,xmm,gx,gy,gx2,gy2,mroot,top,gxb,gyb,gx2b,gy2b,statusglobal happ,hbegin,xma,xmbself.root=rootself.i=1        self.x=xself.y=yself.width=widthself.height=heightself.x2=self.x+widthself.y2=self.y+height        self.name=textself.cd='200'  #数据长度self.zq=4   #数据周期        self.bg=bgself.bd=bdself.font=fontself.bk=[]self.bk2=[]self.gs=''self.ty='gpc'tk.LabelFrame.__init__(self, root,text=text,bg=bg,bd=bd,font=font,**options)         self.scrollbar=tk.Scrollbar(self)self.scrollbar.pack(side=tk.RIGHT,fill=tk.Y)self.lb=tk.Listbox(self,selectmode=tk.BROWSE,yscrollcommand=self.scrollbar.set,font =font)  #height=5,self.lb.pack(expand=tk.YES,fill=tk.BOTH)self.scrollbar.config(command=self.lb.yview)self.place(x=self.x, y=self.y, width=self.width, height=self.height)self.init()def init(self):global xm,xm2,xmi,xmm,gx,gy,gx2,gy2,mroot,top,gxb,gyb,gx2b,gy2b,statusglobal happ,hbegin,xma,xmb        def ldzxg(event=None):  #打开自选股文件'filename = askopenfilename(defaultextension ='.blk',filetypes=[("板块文件","*.blk"),("txt文件","*.txt"),("板块文件","*.ebk")])if len(filename)==0:return(filepath,tempfilename) = os.path.split(filename)(filename2,extension) = os.path.splitext(tempfilename)extension=extension.lower()            self.bk=[]if extension=='.blk':bk2=htdx.getzxgfile(filename)elif extension=='.txt':bk2=htdx.gettxtfile(filename)self.lb.delete(0,tk.END)l=len(bk2)self['text']="股票池(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)os.chdir(hg.mainpath)self.bk2=self.bkdef ldzxg2(event=None): #增加自选股filename = askopenfilename(defaultextension ='.blk',filetypes=[("板块文件","*.blk"),("txt文件","*.txt"),("板块文件","*.ebk")])if len(filename)==0:return(filepath,tempfilename) = os.path.split(filename)(filename2,extension) = os.path.splitext(tempfilename)extension=extension.lower()          if extension=='.blk':bk3=htdx.getzxgfile(filename)elif extension=='.txt':bk3=htdx.gettxtfile(filename)bk4=set(bk3)-set(self.bk)bk2=list(bk4)#self.lb.delete(0,tk.END)l=len(bk2)+len(self.bk)self['text']="股票池(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)os.chdir(hg.mainpath)self.bk2=self.bkdef savezxg(event=None):  #保存自选股文件filename = asksaveasfilename(defaultextension ='.blk',filetypes=[("板块文件","*.blk")])if len(filename)==0:return#print(filename)htdx.putzxgfile(self.bk,filename)os.chdir(hg.mainpath)self.bk2=self.bkdef getbk(event=None):  #获取通达信板块中股票ss=simpledialog.askstring ("", "请输入通达信板块名",initialvalue='近期强势')try:if len(ss)>1:hq=htdx.TdxInit()  ##初始化通达信bk2=htdx.getblockx(bk=ss)self.lb.delete(0,tk.END)self.bk=[]l=len(bk2)self['text']="股票池(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)                    except:passself.bk2=self.bkdef getwc(event=None): #清空股票池import wencaiglobal wctj,mroot#wctj=simpledialog.askstring ('问财选挂',"问财条件",initialvalue=wctj,parent=mroot)wctj=show_dialog()try:if len(wctj)>1:self.bk=[]data = wencai.get_wc(query=wctj)bk2=[]cc=data.股票代码.to_list()for c in cc:if c[7:9]=='SZ':m=0        elif c[7:9]=='SH':       m=1else:m=0bk2.append((m,c[0:6]))  self.lb.delete(0,tk.END)l=len(bk2)self['text']="股票池(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)                    except:print('问财出错!')passself.bk2=self.bkdef scgp(event=None):self.lb.delete(0,tk.END)self.bk=[]self.bk2=self.bkself['text']=self.name# 创建弹出菜单self.menubar=tk.Menu(self.lb)toolbarName2 = ('打开自选股文件','增加自选股','保存自选股文件','板块股票','问财选股','清空股票池')toolbarCommand2 = (ldzxg,ldzxg2,savezxg,getbk,getwc,scgp)        def addPopButton(name,command):for (toolname ,toolcom) in zip(name,command):self.menubar.add_command(label=toolname,command=toolcom)def pop(event=None):# Menu 类里面有一个 post 方法,它接收两个参数,即 x 和y 坐标,它会在相应的位置弹出菜单。self.menubar.post(event.x_root,event.y_root)addPopButton(toolbarName2,toolbarCommand2) #创建弹出菜单self.lb.bind("<Button-3>",pop)

在这里插入图片描述

在策略处理模块中,我们实现的菜单很简单,【‘设置策略’,‘增加自选股’,‘保存自选股文件’,‘清空股票池’】,实现方法可以参考上面代码。
主要介绍设置【设置策略】的实现代码。
在这里插入图片描述
计算周期可以选:‘5分钟’,‘15分钟’, ‘30分钟’,‘1小时’,‘日线’,‘周线’,‘月线’,‘1分钟’,‘日线A’,‘季线’,'年线’等。
计算周期是获取的K线数量。
这个代码实现如下:

    def szcl(self): #设置策略global xm,xm2,xmi,xmm,gx,gy,gx2,gy2,mroot,top,gxb,gyb,gx2b,gy2b,statusglobal happ,hbegin,xma,xmb,ico      self.f2=f2=tk.Toplevel(mroot)  #可视化子窗f2.iconbitmap(ico)f2.title('设置'+self.name)  #Tkinter中设置窗口标题方法f2.attributes('-topmost',1)  #参数1,设置顶层窗口,覆盖其它窗口。width=560height=480f2.geometry('{}x{}+{}+{}'.format(width,height, 320+610, 500))  #改变窗口位置和大小htk.setCenter(f2, width,height)v2=tk.LabelFrame(f2, text="策略参数")v2.pack(side=tk.TOP, fill=tk.X)label1=tk.Label(v2,text='计算周期:')label1.grid(row=0,column=0,padx=1,pady=1,sticky=tk.NSEW)self.zqvar = tk.StringVar()self.zqChosen = ttk.Combobox(v2, width=10, textvariable=self.zqvar)self.hczqa=('5分钟','15分钟', '30分钟','1小时','日线','周线','月线','1分钟','1分钟A','日线A','季线','年线')self.zqChosen['values'] = self.hczqaself.zqChosen.grid(row=0, column=1,padx=1, pady=1,sticky=tk.NSEW)self.zqChosen.current(self.zq)  #设置初始显示值,值为元组['values']的下标self.zqChosen.config(state='readonly')  #设为只读模式    label3=tk.Label(v2,text='周期数量:')label3.grid(row=1,column=0,padx=1,pady=1,sticky=tk.NSEW)self.cd2= tk.StringVar('')self.cd2.set(self.cd)self.entry2 = tk.Entry(v2,width=20, textvariable=self.cd2)self.entry2.grid(row=1,column=1,padx=1, pady=1,sticky=tk.NSEW)v3=tk.LabelFrame(f2, text="策略指标公式")v3.pack(side=tk.TOP, fill=tk.X)self.text=tk.Text(v3,height=16)self.text.pack(expand=1, fill=tk.BOTH)self.text.delete(1.0,tk.END)self.text.insert(1.0,self.gs)def qd():  #确定self.zq=self.zqChosen.current()self.cd=self.cd2.get()self.gs=self.text.get(1.0,tk.END+"-1c")xma[self.i]['cd']=self.cdxma[self.i]['zq']=self.zqxma[self.i]['gs']=self.gs            print('确认操作')self.f2.destroy()            def qx():  #取消print('取消操作')self.f2.destroy()            v4=tk.Frame(f2)v4.pack(side=tk.TOP, fill=tk.X)bt1=tk.Button(v4,width=6,text='取消', command=qx,cursor='hand2')bt1.pack(side=tk.LEFT)lb2=tk.Label(v4,width=2,text=' ')lb2.pack(side=tk.LEFT)bt2=tk.Button(v4,width=6,text='确认', command=qd,cursor='hand2')bt2.pack(side=tk.RIGHT)

在输出模块中,要实现的菜单【‘读取上级计算结果’,‘保存自选股文件’,‘发邮件’,‘发微信’,‘发QQ’,‘发钉钉’,‘同花顺下单’,‘清空股票池’,‘设置’】
实现代码如下:

class sc(tk.LabelFrame):   #输出方案def __init__(self, root=None,i=0,x=0,y=0,width=140, height=80,text='策略1',bg='#8888FF',bd=0,font='Helvetic 12',tag='kaishi',**options):self.root=rootself.i=iself.x=xself.y=yself.width=widthself.height=heightself.x2=self.x+widthself.y2=self.y+heightself.name=textself.bg=bgself.bd=bdself.font=fontself.cd='200'  #数据长度self.zq=3   #数据周期        self.ty='sc'self.gs=''        self.bk=[]self.bk2=[]        self.CheckVar1 = tk.IntVar()self.CheckVar2 = tk.IntVar()self.CheckVar3 = tk.IntVar()self.CheckVar4 = tk.IntVar()self.CheckVar5 = tk.IntVar()self.CheckVar6 = tk.IntVar()           tk.LabelFrame.__init__(self, root,text=text,bg=bg,bd=bd,font=font,**options)         self.scrollbar=tk.Scrollbar(self)self.scrollbar.pack(side=tk.RIGHT,fill=tk.Y)self.lb=tk.Listbox(self,selectmode=tk.BROWSE,yscrollcommand=self.scrollbar.set,font =font)  #height=5,self.lb.pack(expand=tk.YES,fill=tk.BOTH)self.scrollbar.config(command=self.lb.yview)self.place(x=self.x, y=self.y, width=self.width, height=self.height)self.init()        self.update()def init(self):def ldzxg2(event=None): #获取自选股文件filename = askopenfilename(defaultextension ='.blk',filetypes=[("板块文件","*.blk"),("txt文件","*.txt"),("板块文件","*.ebk")])if len(filename)==0:return(filepath,tempfilename) = os.path.split(filename)(filename2,extension) = os.path.splitext(tempfilename)extension=extension.lower()          if extension=='.blk':bk3=htdx.getzxgfile(filename)elif extension=='.txt':bk3=htdx.gettxtfile(filename)bk4=set(bk3)-set(self.bk)bk2=list(bk4)#self.lb.delete(0,tk.END)l=len(bk2)+len(self.bk)self['text']=self.name+"(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)os.chdir(hg.mainpath)self.bk2=self.bkdef savezxg(event=None):  #保存自选股文件filename = asksaveasfilename(defaultextension ='.blk',filetypes=[("板块文件","*.blk")])if len(filename)==0:return#print(filename)htdx.putzxgfile(self.bk,filename)os.chdir(hg.mainpath)self.bk2=self.bkdef scgp(event=None):   #清空股票池self.lb.delete(0,tk.END)self.bk=[]self.bk2=self.bkself['text']=self.namedef jg2(event=None):   #获取上级模块计算出的股票池if self.i>1:x=xm2[self.i-1]bk2=x.bk2l=len(bk2)self['text']=self.name+"(%d)"%lfor m,c in bk2:self.bk.append((m,c))line='('+str(m)+','+str(c)+')'self.lb.insert(tk.END,line)os.chdir(hg.mainpath)self.bk2=self.bk #代码设计独狼,微信18578755056def thswt(bk,num=200):  #同花顺委托global xm,xm2,xmi,xmm,gx,gy,gx2,gy2,mroot,top,gxb,gyb,gx2b,gy2b,statusglobal happ,hbegin,xma,xmb      global ip,porthtdx.TdxInit(ip=ip,port=port) ##初始化同花顺软件ths.connect( "C:\\同花顺软件\\同花顺\\xiadan.exe")ths.enable_type_keys_for_editor()资金状况=ths.balancezjye=资金状况['资金余额']for m,c in bk:pk=htdx.get_security_quotes2(m,c)ask1=pk[0]['ask1']je=ask1*num*1.001if zjye>je:ths.buy(c, price=ask1, amount=num) status.text(2,'同花顺委托完成!')       def thsxd2(event=None):    #同花顺下单bk=self.bknum=int(self.cd)thswt(bk,num)def to_qq(event=None):   #发QQ信息bk=self.bknum=int(self.cd)txl=self.gstxl2=txl.split('\n')for who in txl2:who=who.strip()#print(who)if len(who)>1:for m,c in bk:hts.send_qq(who,'发出信号:'+c)def to_wx(event=None):  #发微信bk=self.bknum=int(self.cd)txl=self.gstxl2=txl.split('\n')for who in txl2:who=who.strip()print(who)if len(who)>1:for m,c in bk:hts.send_wx(who,'发出信号:'+c)# 创建弹出菜单self.menubar=tk.Menu(self.lb)toolbarName2 = ('读取上级计算结果','保存自选股文件','发邮件','发微信','发QQ','发钉钉','同花顺下单','清空股票池','设置')toolbarCommand2 = (jg2,savezxg,None,None,to_qq,None,thsxd2,scgp,self.szsc)        def addPopButton(name,command):for (toolname ,toolcom) in zip(name,command):self.menubar.add_command(label=toolname,command=toolcom)def pop(event=None):# Menu 类里面有一个 post 方法,它接收两个参数,即 x 和y 坐标,它会在相应的位置弹出菜单。self.menubar.post(event.x_root,event.y_root)addPopButton(toolbarName2,toolbarCommand2) #创建弹出菜单self.lb.bind("<Button-3>",pop)

输出设置如下:
在这里插入图片描述
实现方法类似处理模块的设置,这里省略。
要注意一点,在使用Tkinter中一定要使用多线程来处理。
在这里插入图片描述
不然在执行策略时,应用窗口会卡住。我们这里把【执行策略】的代码,在一个新线程中运行。因此在策略执行过程中,可以任意移动模块位置,以及修改模块的大小。

在这里插入图片描述

正在执行的策略,变为红色。我们仍然可以移动或设置模块位置和大小。

本文介绍的知识,均可以在穿云箭量化中策略或执行代码中。
前面几篇博客,我们介绍了利用《中文Python穿云箭量化平台》的Python模块,打造自己新一代的量化工具。这些工具包括行情软件,量化框架平台,中文Python代码集成开发工具,以及任意Tkinter可视化操作的应用程序。
好了,欢迎继续关注我的博客。后面我们介绍更多的二次开发技术。

超越自己是我的每一步!我的进步就是你的进步!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Kubernetes知识点问答题】资源配额 / 访问控制
  • 摩托车加装车载手机充电usb方案/雅马哈USB充电方案开发
  • OpenCV结构分析与形状描述符(19)查找二维点集的最小面积外接旋转矩形函数minAreaRect()的使用
  • 数据库系统概论笔记(持续更新)
  • 控价中数据清洗有什么创新方法
  • 10款企业图纸加密软件大盘点|2024企业图纸加密软件推荐
  • adb的安装和使用 以及安装Frida 16.0.10+雷电模拟器
  • 亚马逊、沃尔玛、敦煌网、Target塔吉特、Temu环境搭建测评技术!
  • ctfshow-PHP反序列化
  • 【PCB工艺】如何实现PCB板层间的互连
  • Redis面试题整理
  • spring 框架过滤器和拦截器的差别
  • 基于STM32单片机的太阳能自动跟踪控制系统
  • springBoot 集成https
  • 服装|基于Java+vue的服装定制系统(源码+数据库+文档)
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • gulp 教程
  • IP路由与转发
  • learning koa2.x
  • Python socket服务器端、客户端传送信息
  • Python_网络编程
  • Spring框架之我见(三)——IOC、AOP
  • storm drpc实例
  • TCP拥塞控制
  • text-decoration与color属性
  • TypeScript迭代器
  • Vue--数据传输
  • Xmanager 远程桌面 CentOS 7
  • 工作中总结前端开发流程--vue项目
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • Mac 上flink的安装与启动
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​用户画像从0到100的构建思路
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • ###STL(标准模板库)
  • #define,static,const,三种常量的区别
  • (1)bark-ml
  • (7)svelte 教程: Props(属性)
  • (BFS)hdoj2377-Bus Pass
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (算法)求1到1亿间的质数或素数
  • (算法)区间调度问题
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .NET BackgroundWorker
  • .NET Framework 3.5安装教程