用python开发了一个绘制股票k线图的工具,还可以预测股票涨跌!【文末附源码和教学视频】

聊一聊这个工具

起初,我并不在意echarts,这不过是一个偶然、一次选择、一条简单的代码、一个图表的诞生,直到我完成了K线图的绘制。

股票,一个神奇的发明,他看不见摸不着,无法预测,却时刻让你的神经紧绷。他的出现,是对打工人的福音?还是一场灾难?是命运的转折点,还是一夜回到解放前。他都可以帮你实现。

K线图,他让你的投资有了参考,花哨的图表下面隐藏着财富的密码。接下来就让我们一起揭开这神秘的面纱。

效果展示

在这里插入图片描述
输入你喜欢的股票代码,就可以生成近一年的K线图。如此方便简洁,难免不让人心动。

更加令人兴奋的是,根据算法,可以预测出明天股票的涨跌情况。当然准不准我也不知道,仅供参考。

股票数据

该工具使用的股票数据来自于Tushare,只需要注册获取一个token就可以免费得到股票数据。

Tushare官网地址:https://tushare.pro/document/2?doc_id=14

运行项目

第一步: 从文末的源码地址,下载项目并解压到本地电脑

第二步: 配置运行环境,使用pycharm导入项目,在【terminal】下运行下面命令:

pip install -r requirements.txt

如果下载第三方库比较慢,可以考虑换一下pip的下载源:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

阿里云 http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) http://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/

第三步: 更改app.py中的ts_token,使用自己在tushare网站注册获取的token。右击运行app.py在浏览器中就可以看到图表。

前端界面

前端的技术主要用到echarts、element、vue等技术,官方文档上多有详细的案例,只需要参照官方文档案例代码,根据自己需求修改调试好代码即可。

绘制K线图

echarts图表案例:Examples - Apache ECharts

elements组件案例:组件 | Element

源码展示:

<html>
	<head>
		<meta charset="UTF-8" />
		<!-- import CSS -->
		<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
		<title>股票小工具</title>
	</head>
	<body>
		<div id="app">
			<!-- 普通字符串加密取 -->
			<el-row :gutter="10" style="margin-top: 20px;">
				<el-card class="box-card">
					<div slot="header" class="clearfix">
						<span>K线图</span>
					</div>
					<el-row>
						<el-col>
							<el-form label-width="80px" :inline="true" :model="stockForm">
								<el-form-item label="股票代码:">
									<el-input v-model="stockForm.code" placeholder="例如:000001.SZ" clearable />
								</el-form-item>
								<el-form-item>
									<el-button type="primary" v-if="stockForm.code"
										@click="stockFormSubmit('stockForm')">确定</el-button>
									<el-tooltip class="item" v-else effect="dark" content="请填写股票代码!">
										<el-button type="danger">确定</el-button>
									</el-tooltip>
								</el-form-item>
								<el-form-item>
									<el-tag v-if=forcastMsg.includes('涨') type="danger" effect="dark">
										[{stockName+forcastMsg}]
									</el-tag>
									<el-tag v-else type="success" effect="dark">
										[{stockName+forcastMsg}]
									</el-tag>
								</el-form-item>
							</el-form>
						</el-col>
					</el-row>
					<el-row>
						<div id="main" style="width:1000px;height:500px;"></div>
					</el-row>
				</el-card>
			</el-row>
		</div>
	</body>
	<!-- 导入下载的 echarts.min.js -->
	<script src="../static/js/echarts.min.js"></script>
	<!-- import Vue before Element -->
	<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
	<!--<script src="https://unpkg.com/vue/dist/vue.js"></script>-->
	<!-- import JavaScript -->
	<script src="https://unpkg.com/element-ui/lib/index.js"></script>
	<!--导入 axios 获取数据-->
	<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
	<script>
		const upColor = "#ec0000"
		const upBorderColor = "#8A0000"
		const downColor = "#00da3c"
		const downBorderColor = "#008F28"

		var nv = new Vue({
			el: '#app',
			delimiters: ['[{', '}]'],
			data: function() {
				return {
					// 表单数据
					stockForm: {
						code: '000001.SZ',
					},
					// 图表数据
					kChartdata: null,
					// 预测信息
					forcastMsg: "预测信息",
					// 股票名
					stockName: "",
				}
			},
			created:function(){
				this.stockFormSubmit()
			},
			methods: {
				// 获取输入的股票代码数据
				async stockFormSubmit(stockForm) {
					const {
						data: res
					} = await this.$http.post("http://127.0.0.1:12345/stock", this.stockForm)
					if (res.status != 200) {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'error'
						})
					} else {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'success'
						})
						// 重新赋值新的股票数据
						var myChart = echarts.init(document.getElementById('main'))
						this.kChartdata = res.stock_data
						this.forcastMsg = this.kChartdata.forcast
						this.stockName = this.kChartdata.name
						var option = {
							// 图表标题配置
							title: {
								text: this.stockName + '近一年K线图'
							},
							// 提示框配置
							tooltip: {
								// 是否显示提示框
								show: true,
								// 触发类型,axis 移动到坐标轴就触发
								trigger: "axis",
								// 坐标轴上提示点设置
								axisPointer: {
									type: "cross"
								}
							},
							// 图例配置
							legend: {
								data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']
							},
							// X 轴配置项
							xAxis: {
								type: "category",
								data: this.kChartdata.stock_trade_days,
								boundaryGap: false,
								axisLine: {
									onZero: false
								},
								splitLine: {
									show: true
								},
								min: "dataMin",
								max: "dataMax"
							},
							// y 轴配置项
							yAxis: {
								scale: true,
								splitArea: {
									show: true
								}
							},
							dataZoom: [{
									type: "inside",
									start: 50,
									end: 100
								},
								{
									show: true,
									type: "slider",
									top: "90%",
									start: 50,
									end: 100
								}
							],
							// 系列配置,根据不同图表有不同的配置
							series: [{
									name: "日K",
									// 图表类型
									type: 'candlestick',
									// 数据内容
									data: this.kChartdata.stock_trade_data,
									// K 线图的图形样式
									itemStyle: {
										// 阳线 图形的颜色
										color: upColor,
										// 阴线 图形的颜色。
										color0: downColor,
										// 阳线 图形的描边颜色
										borderColor: upBorderColor,
										// 阴线 图形的描边颜色
										borderVolor0: downBorderColor
									},
									// 标记点配置
									markPoint: {
										// 标注的文本
										label: {
											// 标签内容格式器,支持字符串模板和回调函数两种形式,字符串模板与回调函数返回的字符串均支持用 \n 换行。
											// 参数 params 是 formatter 需要的单个数据集, value是传入的数据值。
											formatter: function(param) {
												return param != null ? Math.round(param.value) + "" :
													"";
											}
										},
										// 标注的数据数组。每个数组项是一个对象
										data: [
											// 特殊的标注类型,用于标注最大值最小值等
											{
												name: "highest value",
												type: "max",
												// 在使用 type 时有效,用于指定在哪个维度上指定最大值最小值。
												valueDim: "highest",
											},
											{
												name: 'lowest value',
												type: 'min',
												valueDim: 'lowest'
											},
											{
												name: 'average value on close',
												type: 'average',
												valueDim: 'close'
											}
										],
										// 提示框浮层内容格式器,支持字符串模板和回调函数两种形式。
										tooltip: {
											// params 是 formatter 需要的数据集
											formatter: function(param) {
												// name数据名,类目名,data传入的原始数据项
												return param.name + "<br>" + (param.data.coord || "")
											}
										}
									},
									markLine: {
										// 标线两端的标记类型,可以是一个数组分别指定两端,也可以是单个统一指定
										symbol: ['none', 'none'],
										// 标线的数据数组。每个数组项可以是一个两个值的数组,分别表示线的起点和终点,每一项是一个对象
										data: [
											[
												// 定义从最小值到最大值的线
												{
													name: "from lowest to highest",
													type: "min",
													valueDim: "lowest",
													symbol: "circle",
													symbolSize: 10,
													label: {
														show: false
													},
													emphasis: {
														label: {
															show: false
														}
													}
												},
												{
													type: "max",
													valueDim: "highest",
													symbol: "circle",
													symbolSize: 10,
													label: {
														show: false
													},
													emphasis: {
														label: {
															show: false
														}
													}
												},
											],
											// 最小值水平线
											{
												name: "min line on close",
												type: "min",
												valueDim: "close"
											},
											// 最大值水平线
											{
												name: "max line on close",
												type: "max",
												valueDim: "close"
											},
										],
									}
								},
								{
									name: "MA5",
									type: "line",
									data: this.kChartdata.MA5,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA10",
									type: "line",
									data: this.kChartdata.MA10,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA20",
									type: "line",
									data: this.kChartdata.MA20,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA30",
									type: "line",
									data: this.kChartdata.MA30,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
							]
						}
						//使用刚指定的配置项和数据显示图像
						myChart.setOption(option)
					}
				},
			}
		});
	</script>
</html>

后端接口

使用flask搭建的微应用,接口介绍:

  • stock:获取输入的股票数据,返回交易数据、MA数据以及预测数据
  • index:获取主界面
import pandas as pd
from flask import Flask, render_template, request
from flask import jsonify
from flask_cors import CORS
import webbrowser
from datetime import datetime, timedelta
import tushare as ts

ts_token = "填写在tushare获取的token"
ts.set_token(ts_token)
pro = ts.pro_api()

app = Flask(__name__)
CORS(app, supports_credentials=True)


def get_stock(code):
    # 获取股票数据
    end_date = datetime.now().strftime("%Y%m%d")
    start_date = datetime.strftime(datetime.now() - timedelta(365), "%Y%m%d")
    df = pro.daily(ts_code=code, start_date=start_date, end_date=end_date).sort_values(by="trade_date")
    try:
        data = pro.query('stock_basic', exchange='', list_status='L', fields='ts_code,name')
        data.to_excel("./static/excel/stock_basic_info.xlsx", index=False)
        name = data[data["ts_code"] == code]["name"].values[0]
    except Exception as e:
        data = pd.read_excel("./static/excel/stock_basic_info.xlsx")
        name = data[data["ts_code"] == code]["name"].values[0]
    if df.empty:
        return None
    df["MA5"] = df["close"].rolling(4).mean().map(lambda x: round(x, 3))
    df["f1"] = df["MA5"] - df["close"]
    forcast_msg = f"预测 {end_date} 会跌!"
    if sum(df.tail(7)["f1"] > 0) > 4:
        forcast_msg = f"预测 {end_date} 会涨!"
    result = {
        "stock_trade_days": df["trade_date"].values.tolist(),
        "stock_trade_data": df[["open", "close", "low", "high"]].values.tolist(),
        "MA5": df["close"].rolling(4).mean().map(lambda x: round(x, 3)).fillna("-").tolist(),
        "MA10": df["close"].rolling(9).mean().map(lambda x: round(x, 3)).fillna("-").tolist(),
        "MA20": df["close"].rolling(19).mean().map(lambda x: round(x, 3)).fillna("-").tolist(),
        "MA30": df["close"].rolling(29).mean().map(lambda x: round(x, 3)).fillna("-").tolist(),
        "forcast": forcast_msg,
        "name": name
    }
    return result


@app.route("/")
def index():
    return render_template('index.html')


@app.route("/stock", methods=["GET", "POST"])
def stock():
    # 获取提交的股票代码
    rq_json = request.json
    stock_code = rq_json["code"]
    # 获取股票数据,数据解释:时间,开盘价,收盘价,最低价,最高价
    get_stock_result = get_stock(stock_code)
    if get_stock_result:
        result = {
            "status": 200,
            "stock_data": get_stock_result,
            "msg": f"获取{stock_code}股票数据成功!"
        }
        return jsonify(result)
    else:
        result = {
            "status": 400,
            "stock_data": None,
            "msg": f"获取{stock_code}股票数据失败!"
        }
        return jsonify(result)


if __name__ == '__main__':
    webbrowser.open("http://127.0.0.1:12345/")
    app.run(debug=False, port=12345)

运行后就可以在浏览器中看到,感兴趣的朋友可以试试!

源码地址

链接:https://pan.baidu.com/s/1pkAZDi3jLQoh8vifHaj0nA?pwd=vd3s

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 当然可以!您可以使用一些Python库来实现这一目的,例如:Matplotlib,Pandas等。 以下是一个简单的示例代码,使用Matplotlib绘制股票K线图: ``` import matplotlib.pyplot as plt import pandas as pd # 读取数据 data = pd.read_csv("stock_data.csv") # 绘制K线图 fig, ax = plt.subplots() candlestick_ohlc(ax, zip(data["date"], data["open"], data["high"], data["low"], data["close"]), width=0.6) # 添加x轴标签 plt.xticks(data["date"], data["date"], rotation=90) # 添加标题 plt.title("Stock K Line") # 显示图形 plt.show() ``` 请注意,您需要先准备一份股票数据的CSV文件,并将其命名为“stock_data.csv”,才能运行这段代码。 ### 回答2: 当然可以!Python作为一种流行的编程语言,拥有很多强大的库和工具,非常适合用于数据可视化任务,包括股票K线图绘制。 在Python中,有一些流行的库可以帮助我们绘制股票K线图,例如matplotlib、plotly和seaborn等。以下是一个简单的示例,展示了如何使用matplotlib库绘制一个基本的股票K线图: ```python import matplotlib.pyplot as plt import matplotlib.dates as mdates # 输入数据 dates = ['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04'] # 时间序列 opening_prices = [100, 105, 98, 102] # 开盘价 closing_prices = [102, 107, 99, 105] # 收盘价 highest_prices = [110, 112, 100, 108] # 最高价 lowest_prices = [97, 103, 95, 100] # 最低价 # 转换时间格式 dates = [mdates.datestr2num(date) for date in dates] # 创建图表 fig, ax = plt.subplots() # 绘制K线图 kwargs = dict(width=0.2, colorup='r', colordown='g', alpha=1.0) ax.xaxis_date() ax.bar(dates, highest_prices, **kwargs) ax.bar(dates, lowest_prices, **kwargs) ax.vlines(dates, opening_prices, closing_prices, colors=['r' if close_open_diff >= 0 else 'g' for close_open_diff in [close_open_diff := closing_price - opening_price for closing_price, opening_price in zip(closing_prices, opening_prices)]], linewidths=0.5) # 配置图表 ax.xaxis.set_major_locator(mdates.DayLocator()) # 按天显示x轴刻度 ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) # 设置日期格式 # 显示图表 plt.show() ``` 以上代码使用matplotlib库创建了一个基本的K线图,并通过传入开盘价、收盘价、最高价和最低价的数据来绘制K线。代码中的日期格式转换和图表配置可根据具体需求进行调整和扩展。 希望这可以帮到你!如果有其他问题,请随时提问。 ### 回答3: 当然可以帮你写一个基于Python语言股票K线图Python具有丰富的数据处理和可视化库,非常适合进行股票数据分析和可视化展示。 首先,你需要获取股票数据。你可以使用第三方库如`tushare`来获取实时的股票数据。例如,可以通过`tushare`库的`get_k_data`函数获取某只股票的K线数据。你可以指定股票代码、时间范围、K线类型等参数来获取数据。 然后,你需要使用数据处理库如`pandas`对获取的股票数据进行清洗和处理。你可以使用`pandas`的`DataFrame`结构来存储和处理数据。对于K线图,你可以使用OHLC(开盘价、最高价、最低价和收盘价)数据来绘制。 接下来,你可以使用数据可视化库如`matplotlib`或`Plotly`来绘制K线图。这些库提供了丰富的绘图函数和设置选项,你可以根据需要进行定制。例如,你可以使用`matplotlib`的`candlestick_ohlc`函数来绘制K线图。 最后,你可以添加一些额外的功能,如网格线、均线、交易量柱状图等,以便更好地分析股票走势。 在完成绘图后,你可以将结果保存为图片或在线展示。这样,你就成功地利用Python语言编写了一个简单的股票K线图。 总之,Python语言非常适合进行股票数据分析和可视化,你可以使用第三方库来获取数据、处理数据并绘制K线图。希望这个简要的回答可以对你有所帮助!如果需要更详细的代码示例或者其他帮助,请随时告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅帅的Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值