IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【实战】——基于GUI编程的python股票量化交易策略之双均线策略 -> 正文阅读

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

前言

如果有对于股票数据分析或者量化交易经典策略–双均线策略不熟悉的读者,可以参考一下我之前写的文章:
[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、运行结果

运行之后就可以得到:
在这里插入图片描述
输入正确的账号密码:
在这里插入图片描述
输入密码错误:
在这里插入图片描述
输入的账号不存在:
在这里插入图片描述

三、实战案例——根据界面输入绘制动态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与图形库交互的技巧的掌握也更进一步,学明白了基于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)
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")

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)
    
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()
    
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)
    
def printsellpoint():
    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)
    
    selldate = ''
    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]:
            selldate = selldate + stock_df_date[i] + ','
        else:
            continue
    
    tkinter.messagebox.showinfo('提示卖点',selldate)
    print('提示卖点'+selldate)
    
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()

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)
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()

以上代码也可以在我上传的资源上下载.py、.ipynb两种类型的文件

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

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:30:34  更:2022-03-24 00:30:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 12:21:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计