【实战】——基于GUI编程的python股票量化交易策略之双均线策略

目录

  • 前言
  • 一、概念
  • 二、tkinter的使用
    • 1、模块的导入
    • 2、窗口和文本框的创建
    • 3、处理函数的定义
    • 4、按钮的创建
    • 5、运行结果
  • 三、实战案例——根据界面输入绘制动态K线和均线图
    • 1、模块的导入
    • 2、窗口界面和文本框的创建
    • 3、处理函数的定义
      • 3.1、获取股票数据
      • 3.2、【绘制】按钮的处理函数
      • 3.3、【计算买卖点】按钮的处理函数
      • 3.4、【重置】按钮的处理函数
    • 4、按钮的创建及canvas控件
    • 5、运行结果
  • 结语及源代码
  • 1、“登录窗口”源代码
  • 2、“股票K线均线”源代码(部分)

前言

如果有对于股票数据分析或者量化交易经典策略–双均线策略不熟悉的读者,可以参考一下我之前写的文章:
python金融数据分析及可视化
Python量化交易策略及回测系统

一、概念

GUI(Graphical User Interface)意为图形用户界面,在python中,可以利用tkinter模块来开发用户操作界面,然后通过键盘和鼠标等输入设备,操作屏幕上的文本框或命令框等控件来完成一些任务。

双均线策略:构建周期不同的两根移动平均线,如5日移动平均线与30日移动平均线;然后利用两者的交叉点进行股票买卖,如当5日移动平均线从下往上穿过30日移动平均线时,买入股票并持有,当5日移动平均线从上往下穿过30日移动平均线时,卖出股票。

本文利用GUI编程开发用户操作界面,以此来绘制动态的K线及双均线,实现界面动态交互效果

二、tkinter的使用

在下面实战案例中,主要利用的GUI编程知识有:tkinter的基本用法——带标签的文本框、带标签的按钮以及弹出框的显示。在进入案例前先学习一下这些功能的实现

1、模块的导入

import tkinter
import tkinter.messagebox

首先是导入tkinter模块来实现GUI界面的开发,而tkinter.messagebox是用于弹出框的显示

2、窗口和文本框的创建

loginwin = tkinter.Tk()
loginwin.geometry('220x120')
loginwin.title('登录窗口')

其次是窗口的创建,以及窗口大小、窗口标题的定义

tkinter.Label(loginwin,text='用户名:').place(x=10,y=20)
tkinter.Label(loginwin,text='密  码:').place(x=10,y=50)

接下来是创建两个标签对象用于提示文本框输入的信息,以及这两个标签的文本、位置的设定

userval = tkinter.StringVar()
pwdval = tkinter.StringVar()
userentry = tkinter.Entry(loginwin, textvariable=userval)
userentry.place(x=65,y=20)
pwdentry = tkinter.Entry(loginwin,textvariable=pwdval,show='*')
pwdentry.place(x=65,y=50)

然后tkinter.Entry()是文本框的定义,并指定文本框输入的内容存放于tkinter.StringVal()数据类型的对象userval和pwdval中,且将密码的显示改为*

3、处理函数的定义

def check():
    username = userval.get()
    pwd = pwdval.get()
    print('用户名:' + username)
    print('密  码:' + pwd)
    if(username == 'aaa' and pwd == '123'):
        tkinter.messagebox.showinfo('提示','登录成功')
    else:
        if(username == 'aaa' and pwd != '123'):
            tkinter.messagebox.showinfo('提示','密码错误')
        else:
            tkinter.messagebox.showinfo('提示','登录失败')

随后自定义函数check()用于连接按钮,执行点击按钮后的对应操作,其中tkinter.messagebox.showinfo()是弹出窗口定义

4、按钮的创建

tkinter.Button(loginwin, text='登录',width=12,command=check).place(x=10,y=85)
tkinter.Button(loginwin, text='退出',width=12,command=loginwin.quit).place(x=120,y=85)
tkinter.mainloop()

最后tkinter.Botton()用于创建命令按钮,参数定义了按钮的文本、大小以及调用的函数,即单击该按钮后触发的函数。tkinter.mainloop()是开启主循环,用于监听键盘、鼠标等输入设备操作事件,当事件(点击)发生触发相应方法(登录/退出)。

5、运行结果

运行之后就可以得到:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第1张图片
输入正确的账号密码:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第2张图片
输入密码错误:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第3张图片
输入的账号不存在:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第4张图片

三、实战案例——根据界面输入绘制动态K线和均线图

1、模块的导入

import pandas as pd
import akshare as ak
import matplotlib.pyplot as plt
from mpl_finance import candlestick2_ochl
import tkinter
import tkinter.messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

以上的大部分模块对我们来说已经是非常熟悉了,除了最后一个FigureCanvasTkAgg,该模块用于创建canvas控件,整合matplotlib库和tkinter库,使matplotlib库的图形可以导入tkinter库的窗口界面之中。

2、窗口界面和文本框的创建

和前面一样,导入模块之后就是创建窗口界面和文本框了。

win = tkinter.Tk()
win.geometry('625x600')
win.title('股票K线均线')
tkinter.Label(win, text='股票代码:').place(x=10,y=20)
tkinter.Label(win, text='开始时间:').place(x=10,y=50)
tkinter.Label(win, text='结束时间:').place(x=10,y=80)

根据需要,设置窗口的大小;以及文本框的标签的文本、位置

stockcodeval = tkinter.StringVar()
startdateval = tkinter.StringVar()
enddateval = tkinter.StringVar()
stockcodeentry = tkinter.Entry(win, textvariable=stockcodeval)
stockcodeentry.place(x=70,y=20)
stockcodeentry.insert(0,"sh000001")
startdateentry = tkinter.Entry(win, textvariable=startdateval)
startdateentry.place(x=70,y=50)
startdateentry.insert(0,"20190101")
enddateentry = tkinter.Entry(win, textvariable=enddateval)
enddateentry.place(x=70,y=80)
enddateentry.insert(0,"20190630")

大家别看文本框创建的代码就有十几行而看不下去,其实它就只有4行,然后3个文本框重复操作而显得有点复杂而已(下面也有相类似的地方),在这里多了一个insert()函数用于设置文本框的默认值

3、处理函数的定义

以下自定义了6个函数,其中4个用于连接最后定义的4个按钮,其他两个用于辅助操作的实现。

3.1、获取股票数据

def getstockdata(stockcode, startdate, enddate):
    stock_df = ak.stock_zh_a_daily(symbol=stockcode, start_date=startdate, end_date=enddate)
    filename = 'D:\\' + stockcode + startdate + enddate + '.csv'
    stock_df.to_csv(filename)

有看过之前的文章的读者一定不陌生,这个函数中ak.stock_zh_a_daily()是用于获取新浪财经A股个股的历史行情数据的。在这里我们将获取的数据储存起来,以便后面读取数据。

3.2、【绘制】按钮的处理函数

以下两个自定义函数是可以合成一个的,但为了分析就拆成了两个

def draw():
    plt.clf()
    stockcode = stockcodeval.get()
    startdate = startdateval.get()
    enddate = enddateval.get()
    drawline(stockcode, startdate, enddate)    

第一个自定义函数是用于获取文本框输入的内容,并将信息传给下一个函数用于绘制对应的图形

def drawline(stockcode, startdate, enddate):
    filename = 'D:\\' + stockcode + startdate + enddate + '.csv'
    getstockdata(stockcode, startdate, enddate)
    df = pd.read_csv(filename, encoding='gbk')
    
    ax = figure.add_subplot(111)
    candlestick2_ochl(ax=ax, opens=df['open'].values, closes=df['close'].values,
                      highs=df['high'].values, lows=df['low'].values, width=0.75,colorup='red',colordown='green')
    df['close'].rolling(window=5).mean().plot(label='5日均线')
    df['close'].rolling(window=20).mean().plot(label='20日均线')
    plt.legend(loc='best')
    ax.grid(True)
    plt.title("股票{}的K线图".format(stockcode))
    plt.rcParams['font.sans-serif']=['SimHei']
    
    major_index = df.index[df.index%10==0]
    major_xticks = df['date'][df.index%10==0]
    plt.xticks(major_index,major_xticks)
    plt.setp(plt.gca().get_xticklabels(),rotation=30)
    canvas.draw()

在得到要绘制的图形的信息之后,自定义函数drawline()先调用第一个函数获取股票数据,然后根据数据绘制K线图和均线图(想必大家都已通读前置文章了解清楚了,我就不过多的赘述了)

最后对图形的x轴数据进行设置,并利用canvas控件展示在窗口界面中。

3.3、【计算买卖点】按钮的处理函数

下面就以【买点提示】按钮的处理函数为例讲解分析,【卖点提示】按钮的处理函数也是相类似的,只需要修改其判断条件即可

def printbuypoint():
    stockcode = stockcodeval.get()
    startdate = startdateval.get()
    enddate = enddateval.get()
    filename = 'D:\\' + stockcode + startdate + enddate + '.csv'
    getstockdata(stockcode, startdate, enddate)
    stock_df = pd.read_csv(filename, encoding='gbk')
    
    stock_df_date = stock_df['date'].values
    stock_df.index = stock_df_date
    stock_df_close = stock_df['close']
    s_short = stock_df_close.rolling(window=5, min_periods=5).mean()
    s_long = stock_df_close.rolling(window=20, min_periods=20).mean()
    stock_df_len = len(stock_df)
    
    buydate = ''
    for i in range(stock_df_len):
        if pd.isna(s_long[i]):
            continue
        elif s_short[i-1] < s_long[i-1] and s_short[i] > s_long[i]:
            buydate = buydate + stock_df_date[i] + ','
        else:
            continue
    
    tkinter.messagebox.showinfo('提示买点',buydate)
    print('提示买点'+buydate)

与【绘制】按钮第一步操作一样,先得到文本框输入的信息,利用信息获取股票数据,然后计算长短两个周期的移动平均线,利用其交叉点进行买卖的判断(前置文章中有详细介绍)

最后就是利用tkinter.messagebox.showinfo()将得到的信息在弹出窗口中显示,其中,第一个参数为弹出窗口的标题,第二个为弹出窗口中显示的内容。

3.4、【重置】按钮的处理函数

def reset():
    stockcodeentry.delete(0,tkinter.END)
    stockcodeentry.insert(0,"sh000001")
    startdateentry.delete(0,tkinter.END)
    startdateentry.insert(0,"20190101")
    enddateentry.delete(0,tkinter.END)
    enddateentry.insert(0,"20190630")
    plt.clf()
    canvas.draw()

自定义函数reset()就是在点击【重置】按钮后,删除文本框的信息同时插入自定义的股票代码、开始时间、结束时间的默认值。

4、按钮的创建及canvas控件

接下来就是按钮的创建了,根据需要创建了【绘制】、【重置】、【计算买点】和【计算卖点】四个按钮,并且调整它们的宽度、位置等参数

tkinter.Button(win,text='绘制',width=12,command=draw).place(x=200,y=50)
tkinter.Button(win,text='重置',width=12,command=reset).place(x=200,y=80)
tkinter.Button(win,text='计算买点',width=12,command=printbuypoint).place(x=300,y=50)
tkinter.Button(win,text='计算卖点',width=12,command=printsellpoint).place(x=300,y=80)

最后就是利用控件canvas整合了基于matplotlib库的figure对象和面向GUI界面的win对象,然后设置控件canvas的大小及位置;当然不要忘记开启循环!

figure = plt.figure()
canvas = FigureCanvasTkAgg(figure, win)
canvas.get_tk_widget().config(width=575,heigh=500)
canvas.get_tk_widget().place(x=0,y=100)
win.mainloop()

5、运行结果

运行之后会出现:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第5张图片
点击【绘制】按钮之后:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第6张图片
点击【计算买点】按钮之后:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第7张图片
点击【计算卖点】按钮之后:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第8张图片
修改信息之后,点击【绘制】按钮:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第9张图片
点击【重置】按钮之后:
【实战】——基于GUI编程的python股票量化交易策略之双均线策略_第10张图片

结语及源代码

分享的过程也是学习的过程,在写完这篇博客之后,我对GUI与图形库交互的技巧的掌握也更进一步,学明白了基于tkinter库的GUI交互界面的开发,包括标签、文本框、按钮和canvas等控件的用法,并结合以前所学的知识:股票数据的分析和可视化,对两者进行整合,最终体会到掌握新技能的快乐。

最后附上源代码,希望大家也可以一起学习进步

1、“登录窗口”源代码

import tkinter
import tkinter.messagebox

loginwin = tkinter.Tk()
loginwin.geometry('220x120')
loginwin.title('登录窗口')
tkinter.Label(loginwin,text='用户名:').place(x=10,y=20)
tkinter.Label(loginwin,text='密  码:').place(x=10,y=50)
userval = tkinter.StringVar()
pwdval = tkinter.StringVar()
userentry = tkinter.Entry(loginwin, textvariable=userval)
userentry.place(x=65,y=20)
pwdentry = tkinter.Entry(loginwin,textvariable=pwdval,show='*')
pwdentry.place(x=65,y=50)
def check():
    username = userval.get()
    pwd = pwdval.get()
    print('用户名:' + username)
    print('密  码:' + pwd)
    if(username == 'aaa' and pwd == '123'):
        tkinter.messagebox.showinfo('提示','登录成功')
    else:
        if(username == 'aaa' and pwd != '123'):
            tkinter.messagebox.showinfo('提示','密码错误')
        else:
            tkinter.messagebox.showinfo('提示','登录失败')
tkinter.Button(loginwin, text='登录',width=12,command=check).place(x=10,y=85)
tkinter.Button(loginwin, text='退出',width=12,command=loginwin.quit).place(x=120,y=85)
tkinter.mainloop()

2、“股票K线均线”源代码(部分)

import pandas as pd
import akshare as ak
import matplotlib.pyplot as plt
from mpl_finance import candlestick2_ochl
import tkinter
import tkinter.messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

win = tkinter.Tk()
win.geometry('625x600')
win.title('股票K线均线')
tkinter.Label(win, text='股票代码:').place(x=10,y=20)
tkinter.Label(win, text='开始时间:').place(x=10,y=50)
tkinter.Label(win, text='结束时间:').place(x=10,y=80)
......

def getstockdata(stockcode, startdate, enddate):
    stock_df = ak.stock_zh_a_daily(symbol=stockcode, start_date=startdate, end_date=enddate)
    ......
    
def draw():
    stockcode = stockcodeval.get()
    startdate = startdateval.get()
    enddate = enddateval.get()
    ......
    
def drawline(stockcode, startdate, enddate):
    filename = 'D:\\' + stockcode + startdate + enddate + '.csv'
    getstockdata(stockcode, startdate, enddate)
    df = pd.read_csv(filename, encoding='gbk')
    ......
    
def printbuypoint():
    stockcode = stockcodeval.get()
    startdate = startdateval.get()
    enddate = enddateval.get()
    ......
    
def printsellpoint():
    stockcode = stockcodeval.get()
    startdate = startdateval.get()
    enddate = enddateval.get()
    ......
    
def reset():
    stockcodeentry.delete(0,tkinter.END)
    stockcodeentry.insert(0,"sh000001")
    ......

tkinter.Button(win,text='绘制',width=12,command=draw).place(x=200,y=50)
tkinter.Button(win,text='重置',width=12,command=reset).place(x=200,y=80)
tkinter.Button(win,text='计算买点',width=12,command=printbuypoint).place(x=300,y=50)
tkinter.Button(win,text='计算卖点',width=12,command=printsellpoint).place(x=300,y=80)
......

以上完整的代码也可以在我上传的资源上下载,其中包括.py、.ipynb两种类型的文件,可以根据需要下载下来练练手,掌握tkinter模块、入门python量化交易!

最后的最后,大家如果觉得不错的话记得点赞、收藏、关注三连哦~

你可能感兴趣的:(python,量化投资分析,金融数据分析,python,数据分析,金融,策略模式,交互)