
一直想自己动手把股票走势图画出来又觉得K线图这玩意儿高不可攀别急这期内容就是来帮你把这块硬骨头啃下来的。咱们不聊那些虚头巴脑的理论直接奔着“用代码把股票走势图变成一张张K线图”这个目标去。你看完这篇文章至少能搞清楚K线图背后的数据逻辑并且亲手用Python画出第一张像模像样的图。这个系列我计划写成一个完整的实操流程今天这第一篇先做整体概述把我们接下来要走的路线图给捋清楚重点解决“为什么要这么画”和“代码大概长什么样”这两个核心问题。不管你是刚接触Python的萌新还是有点基础但一直没碰过金融数据可视化的同学这篇都能帮你把底子打好。我保证整个系列不会出现一堆看不懂的术语堆砌每一步都能照着抄、照着改。1. 内容整体设计与思路拆解1.1 K线图到底在表达什么先说点实在的。很多人打开炒股软件看到满屏红红绿绿的柱子第一反应是“这玩意儿到底想说啥”。其实K线图本质上就是一张“价格在单位时间内的四维快照”这四维分别是开盘价、收盘价、最高价和最低价。我们常说的“开高低收”四个价格就是画K线的全部数据基础。用代码画K线图说白了就是把这四个价格转换成图形元素的过程。你看一根K线它其实包含两部分中间那个粗粗的“实体”以及上下两头细长的“影线”。实体部分告诉你开盘和收盘之间的博弈结果影线则记录了这个时间段内价格冲到多高、又砸到多低。我习惯把实体比作“双方交战的战场”影线则是“侦查兵跑出去留下的足迹”这样理解起来会特别形象。为什么要用代码来画而不是直接用现成的图表软件因为当你想批量分析几十只股票或者想把自己的交易策略做成自动化盯盘工具时手工截图和鼠标点击显然不现实。代码能让你从“看一张图”升级到“管一批图”这才是程序员思维去看盘的正确姿势。1.2 为什么用Python而不是其他工具可能有人会问Excel也能画K线图为什么偏要用Python我给的答案是你要的是“流程化”和“可复现”而不是“画一次图”。Excel处理一两百个数据点还行一旦你把某只股票五年、十年的日线数据全拉下来那就是上千根K线Excel光是渲染就够你等半天的。更重要的是用Python处理后你能把“数据获取”“数据处理”“图表绘制”变成一个自动化流水线。今天想分析茅台明天想换宁德时代只需要改一个股票代码变量剩下的交给代码去跑。这种批处理和自动化的能力是任何手动操作的工具都替代不了的。而且Python在金融领域有天然的生态优势。处理表格数据有Pandas画图有Matplotlib和专门为金融设计的mplfinance库获取数据有Tushare、AkShare这些现成的接口。你要做的不是从零造轮子而是把这些成熟的轮子组装成一台能跑的车。这就是我选择Python和mplfinance作为整个系列核心工具的原因。2. 核心细节解析与实操要点2.1 环境准备这几个库一个都不能少既然要动手写代码先把环境搭好。你需要Python 3.8以上版本然后安装下面这几个核心库Pandas金融数据分析的基石专门处理表格型数据。我们用到的OHLC数据开盘价、最高价、最低价、收盘价就是典型的表格数据。MatplotlibPython最老牌的可视化库所有图表绘制的底层引擎。mplfinance基于Matplotlib开发的专业K线图库专为金融数据设计一行代码就能画出漂亮的K线图。安装命令也不复杂直接在终端里敲pip install pandas matplotlib mplfinance如果你的网络环境不太稳定可以加一个国内镜像源速度会快很多。装好之后你可以在Python交互环境里验证一下import mplfinance as mpf print(mpf.__version__)能打印出版本号说明环境就绪了。这里特别叮嘱一句Pandas和mplfinance之间是存在版本兼容问题的如果你后面遇到奇怪的报错优先检查一下这两个库的版本是不是太老了。2.2 数据从哪来公开接口与本地文件两手准备画K线图的第一步是拿到数据。市面上的数据源很多我推荐新手用Tushare或者AkShare。这两个都是国内比较主流的Python金融数据接口能直接获取A股的历史行情数据而且是免费使用的。Tushare的使用方式是注册一个Token然后通过接口调用数据这种方式适合有长期数据需求、并且希望数据格式稳定的用户。AkShare则不需要注册直接调用函数就能拿到数据说实话作为教学工具更友好一点。我用AkShare举个例子获取一只股票的日线数据大概长这样import akshare as ak # 获取贵州茅台的历史行情数据 df ak.stock_zh_a_hist(symbol600519, perioddaily, adjustqfq) print(df.head())这里面有一个细节需要特别注意获取到的数据列名通常是中文日期、开盘、收盘、最高、最低、成交量而mplfinance要求数据列是英文Open、High、Low、Close、Volume且索引必须是日期格式。这个转换过程其实就是几行代码的事但很多新手就卡在这里。我给你一个标准的清洗模板import pandas as pd # 假设df是从akshare获取的数据 df[日期] pd.to_datetime(df[日期]) # 转日期格式 df df.rename(columns{ 日期: Date, 开盘: Open, 最高: High, 最低: Low, 收盘: Close, 成交量: Volume }) df df.set_index(Date) # 将日期设置为索引 df df[[Open, High, Low, Close, Volume]]这五列是画K线图的最低要求缺一不可。之前有粉丝跑来跟我说为什么我画图总是报错就是因为他只拿了开高低收没管成交量结果mplfinance直接罢工。如果你不想用网络接口也可以自己手搓一份测试数据。我在系列文章里会经常用一组随机生成的数据做演示这样读者不需要依赖外部接口复制代码就能直接跑通import numpy as np import pandas as pd # 生成200个交易日的模拟数据 np.random.seed(42) dates pd.date_range(start2023-01-01, periods200, freqB) # B代表工作日 price 100 np.cumsum(np.random.randn(200) * 2) df pd.DataFrame({ Open: price, High: price np.random.rand(200) * 3, Low: price - np.random.rand(200) * 3, Close: price np.random.randn(200), Volume: np.random.randint(10000, 50000, 200) }, indexdates)这套模拟数据特别适合学习和测试你先跑通了流程后面再换成真实行情就只是换数据源的问题。3. 实操过程与核心环节实现3.1 第一张K线图五步画出雏形好了到了最激动人心的环节我们来画第一张图。核心代码其实简单到超乎你的想象下面就是完整的示例import mplfinance as mpf import pandas as pd import numpy as np # 1. 准备模拟数据 np.random.seed(42) dates pd.date_range(start2023-01-01, periods200, freqB) price 100 np.cumsum(np.random.randn(200) * 2) df pd.DataFrame({ Open: price, High: price np.random.rand(200) * 3, Low: price - np.random.rand(200) * 3, Close: price np.random.randn(200), Volume: np.random.randint(10000, 50000, 200) }, indexdates) # 2. 调用mplfinance绘图 mpf.plot(df, typecandle, styleyahoo, titleMy First K-Line Chart, ylabelPrice)这个代码跑完你会看到一个有红有绿的K线图弹出来。虽然代码很短但里面藏着几个关键参数值得记住typecandle指定我们画的是蜡烛图也就是K线图styleyahoo是内置配色方案这个方案里红涨绿跌符合国际惯例title和ylabel只是给图表加上标题和纵轴标签。这是不是和你想象的完全不一样你可能会觉得就这么几行代码就画完了对mplfinance的存在价值就是让你不必关心Matplotlib底层的那些坐标轴和线段绘制细节把这些都抽象成了几行声明式的参数。但如果你只看这张图就觉得自己学会了那还早得很。这张图太素了既没有成交量也没有均线还不能跟其他股票作对比实用性很低。我们接着往深处挖。3.2 样式与配色把图调成A股习惯的红涨绿跌国内股民看习惯了红涨绿跌而mplfinance默认的yahoo风格是绿涨红跌。如果你想把颜色换成我们熟悉的红涨绿跌可以用make_marketcolors()函数来定制from mplfinance import make_marketcolors from mplfinance import make_mpf_style # 定制红涨绿跌的颜色 mc make_marketcolors( upred, # 上涨用红色 downgreen, # 下跌用绿色 edgeinherit, # 边框颜色继承 wickinherit, # 影线颜色继承 volumeinherit # 成交量颜色继承 ) custom_style make_mpf_style(marketcolorsmc) mpf.plot(df, typecandle, stylecustom_style, titleA-share Style K-Line, ylabelPrice)这里的upred和downgreen就是核心把上涨和下跌对应的颜色一指派整个图的气质就变了。除了颜色你还可以通过style参数调整背景色、网格线样式等外观细节这些都是让图表变得更专业的手段。我个人的经验是在代码里建立一个统一的风格配置模块把所有定制都放在一起这样后续画几十只股票的图时能保证宏观风格完全一致看起来非常整齐。这种细节往往决定一个数据项目成品的高级感。3.3 叠加成交量与均线让信息量翻倍单看裸K线信息量实在太少。在真正的行情软件里K线图下面通常还会跟着一个成交量柱状图图上还会叠加几条移动平均线。mplfinance对这两种场景的支持是内置的不需要你额外去写Matplotlib绘图代码。先看最直观的用法只需要给plot函数加上两个参数mpf.plot( df, typecandle, stylecustom_style, titleK-Line with Volume and MA, ylabelPrice, ylabel_lowerVolume, volumeTrue, # 是否显示成交量 mav(5, 10, 20), # 是否显示均线以及显示哪些周期 figratio(16, 8), # 画布比例 figscale1.2 # 画布缩放 )volumeTrue会在K线图下方自动增加一个子图用来显示每天成交量对应的柱状图。mav(5, 10, 20)则是一次性画出5日、10日、20日三条移动平均线这也是短线交易里比较常用的三个周期。看到没真正干活只需要几行代码但每一行背后都有很深的讲究。比如mav这个参数如果你是做中长线的把周期改成(20, 60, 120)会更适合你的策略。参数的选择从来不是死的它应该服务于你的分析目标。这一节跑完之后你手里的K线图已经从“毛坯房”变成“精装修”了。4. 常见问题与排查技巧实录4.1 图表报错每根柱子都是上吊线索引和列名的坑很多新手跑通基础代码后会遇到一个现象画出来的K线图每根K线都变成一条竖线实体非常小几乎看不到红绿方块。这种情况几乎都是因为数据格式不对常见的是日期没有被正确设置为索引。mplfinance有个硬性要求传入的数据框必须是DatetimeIndex索引而且列名必须是Open、High、Low、Close、Volume这种英文格式。如果你的列名是开盘、收盘这种中文或者索引还是从0开始的数字画出来的图就是一根根“上吊线”。排查思路很简单在调用mpf.plot之前先打印一下你的数据框看一下print(df.head()) print(df.index) print(df.columns)确认索引是日期格式确认列名是英文那五个单词。如果用的是我上面的清洗模板大概率能一次通过。遇到问题时别急着怀疑代码先用print把数据和mplfinance的预期“对齐”一下往往问题一下子就清楚了。4.2 换用真实数据后日期断档周末和节假日的坑用模拟数据画图很顺滑但一换成真实数据有些人就会发现图表上K线之间有很宽的间隙像是中间少了一段似的。这个现象在日线数据上特别常见原因是真实市场里周末和法定节假日是不交易的数据中的日期是断续的。当Pandas把这些稀疏的日期作为索引时mplfinance默认会按照日期序号隔开K线之间的距离。比如你从周一到周五的数据是连续的但下次开盘是下周一中间会凭空多出两天空白反映到图上就是一根根K线之间的距离不均等。这个问题怎么解决方法很简单在plot函数里加上一个show_nontradingFalse参数mpf.plot( df, typecandle, stylecustom_style, show_nontradingFalse, # 忽略非交易日压缩日期间隙 volumeTrue, mav(5, 10, 20) )show_nontradingFalse的作用就是忽略那些非交易日让K线一根贴着一根排列图面会变得紧凑很多。这个参数特别适合日线数据如果你是画小时线或分钟线则不需要关心这个因为交易时段内本来就是连续的。4.3 均线没出现数据量不足的隐形边界还有一个很隐蔽的问题有些人在mav参数里填写了(5, 10, 20)但图上一根均线都看不到或者只看到一部分均线。这个通常不是代码问题而是数据量不足造成的。均线本质上是移动平均计算周期至少需要N个数据点。比如20日均线你至少要累积20个有效交易日才能算出一个值而且就算有了20个点你图上也只能看到最新那一天对应的均线点。如果你的样本数据不足20个那20日均线压根画不出来。我当时自己做这个功能的时候拿一批只有15天的数据去测试结果5日均线出现了10日和20日均线消失得无影无踪。折腾了半天才发现是数据量问题。所以建议你在数据预处理阶段就对长度做个判断如果不到60个点后面的60日均线就不用考虑了省得画出来一张缺胳膊少腿的图。4.4 中文字体显示成方框Matplotlib的老大难画图的时候你会发现标题或者坐标轴上的中文注释全变成了一个个小方框这在Matplotlib里是著名的历史难题——中文字体缺失。如果你不想让图表里的信息大打折扣这一步必须处理。通用的解决办法是手动指定中文字体。你可以先找到你系统上已有的中文字体名称然后通过matplotlib.rcParams来全局设置import matplotlib.pyplot as plt # 以Windows系统为例 plt.rcParams[font.sans-serif] [Microsoft YaHei] # 解决负号显示异常 plt.rcParams[axes.unicode_minus] False如果你用的是macOS把Microsoft YaHei换成PingFang HK或者Arial Unicode MS。在Linux服务器上则要提前安装中文字体包然后指定字体路径。这个问题虽然说起来很简单但在实际项目中耽误的时间不少提前处理好后面就不会被这种小问题反复打断思路。5. 进阶方向预告与操作建议5.1 多股对比一次画出几只能源股的走势图当你把单只股票的K线图跑通后自然会想能不能把好几只股票放在一张大图里对比比如我想同时看中国石油、中国石化和中海油这三只股票的近三个月走势如果一个个打开保存效率实在太低了。这就是我们代码化看图的核心优势所在——批量处理。思路其实很朴素一个循环遍历股票列表每只股票的数据都读取出来然后逐一绘图并保存到本地目录。这个流程在后续文章中我会写一个超详细的版本。这里先给你一个预览让你知道下一步长什么样stock_list [600028, 601857, 600938] for code in stock_list: df get_data_by_code(code) # 伪代码具体实现后面文章展开 mpf.plot( df, typecandle, stylecustom_style, titlef{code} K-Line, savefigf./chart/{code}.png )savefig参数直接指定图片保存路径不用每次都弹出一个窗口这样就能实现无人值守的批量出图。你自己看盘的时候只需打开文件夹所有目标股票的K线图一览无余。5.2 K线图上做标注让关键信号一目了然K线图画出来之后你是不是还想在上面画一些标记比如标出金叉位置、标出重要压力位mplfinance提供了addplot接口让你能在K线图之上继续叠加自定义元素。我举个最简单的例子在收盘价序列上叠加一条折线显著标记出均线突破的关键点import mplfinance as mpf import pandas as pd # 用当前数据的收盘价做个示例 ap mpf.make_addplot(df[Close], colorblue, width1.5) mpf.plot( df, typecandle, stylecustom_style, addplotap, titleK-Line with Close Price Line )这段代码的作用是在K线图上面画出一条收盘价折线方便你观察整体走势的连贯性。如果你理解了addplot的用法后面想标注任何东西比如“放量突破买入点”“MACD金叉点”都可以通过往addplot列表里加元素来实现。这一块是深入自定义K线图的重要入口我会在后面专门写一篇来讲各种花式标注。5.3 给新手的三个建议最后掏心窝子总结几句。第一不要一开始就追求复杂的花活。先把我这篇里的模拟数据流程跑通把K线图的原理和数据格式搞扎实这是最省时间的捷径。第二尽量早点换成真实行情数据实战。只有面对真实的涨跌停、除权除息、停牌复牌你才会真正理解数据处理的细节有多重要。第三把代码封装成函数不要总是复制粘贴。写一个类似plot_kline(stock_code, start_date, end_date)的函数后续所有分析都基于这个函数调用能帮你省下大量重复劳动。我现在写这个系列文章时其实也在不断回头看自己最早期的代码。如果当时有人能明确告诉我“K线图的本质是OHLC数据到图形元素的映射先跑通一个最小例子再追求丰富功能”我应该能少走很多弯路。希望这一篇文章能把方向给大家指清楚接下来的系列我们会一步步深入下一期讲怎么用真实行情数据画出第一张有成交量、有均线的完整K线图再下一期讲怎么把单张图变成批量出图的自动化脚本。咱们到时候接着聊。