资讯动态

Python股票系统源码详解:从环境搭建到量化回测实战

发布时间:2026/10/27 16:58:58 来源:尧图企业网站定制
简介面向毕业设计、课程设计及个人实践场景的Python股票交易系统源码包完整覆盖行情数据获取、清洗处理、策略回测、风险控制与可视化界面等模块。开发者可在Tkinter/PyQt图形界面基础上实现移动平均线、RSI、布林带等经典交易策略并通过supervisord、定时任务脚本完成自动化运行前端页面与图表组件可直接复用便于快速搭建可交互的交易监控面板。资源共143个文件以29个Python脚本为核心辅以JavaScript、HTML、CSS构成前端展示层另有Shell脚本、Dockerfile与Nginx配置支持一键式部署压缩包仅2.19MB轻量易用。已有524人学习下载适合具备一定Python基础、希望将编程与金融分析结合实践的学生及爱好者。包内目录结构清晰可快速梳理从数据采集、策略执行到Web展示、运维部署的完整链路源码整体可读性较好可作为二次开发与功能扩展的起点。1. 把这份 Python 股票系统源码下载下来之后先别急着解压拿到一个Python开发的股票系统源码.zip绝大多数人的第一反应都是双击解压然后双击main.py等着看曲线。我劝你先停一下因为真这么干大概率第一步就翻车——缺依赖、缺配置、Python 版本不对三连击直接劝退。这份源码本质上是一个「行情数据采集 → 技术指标计算 → 策略信号生成 → 回测验证 → 图表输出」的完整框架面向的是想做量化投研、但不想从零搭轮子的从业者和学习者。它能帮你省掉搭骨架的时间让你把精力放在策略本身。但它不是自动交易软件不会给你连接券商实盘下单更不是那种“输入代码就赚钱”的黑匣子。适合谁两类人一是刚入 Python 量化、想看看真实项目怎么组织代码的初学者二是已经写过零散脚本、想把「采集、计算、回测」串成一条流水线的进阶开发者。在动手之前你只需要一点明白这份源码的价值在框架不在“预测涨跌”。下面我按拆项目的顺序把这套代码从解压到跑通完整过一遍。2. 为什么用 Python 写股票系统技术栈选型与核心数据链路2.1 选 Python 不是情怀生态、库、迭代速度三个硬理由你可能会问股票系统用 Java、C 写也大有人在为什么这份源码选了 Python答案不复杂日线级别、分钟级别的策略研究和回测Python 的效率和开发速度是最划算的。先说生态。pandas 的 DataFrame 对时间序列处理几乎是统治级的rolling()、ewm()两行代码就能算均线和指数平滑这在 C 里要自己写几十行。numpy 做向量化计算回测时整个策略的信号生成可以用布尔数组一次性算完不用写 for 循环。再加上 matplotlib 系的数据可视化从数据到图表全程不换语言。再说迭代速度。做策略的人一天要试十几个参数组合Python 改完就能跑跑完就能看结果。用编译型语言做这个事编译等待时间会严重压缩你的试错空间。当然如果是做毫秒级高频交易Python 不适合——但那份源码的场景显然是日线或者分钟线级别的策略研究这个定位下 Python 是最务实的选择。常见的一个误区是拿 Python 股票系统和「源码建站」那一类 PHP 项目对比。网页源码是解压扔到服务器就能跑Python 项目不是它需要环境、依赖、配置三步全部就位。这不是源码有问题是运行模型本身就不同。2.2 数据链路全景从行情源到策略引擎的六个环节任何股票系统的核心都是数据流。这份源码的功能能不能发挥取决于你理不理解这条链路。我拆成六段来看数据源——免费公开行情接口或者第三方库比如 akshare 这类聚合接口负责把原始 K 线数据拉回来。采集层——网络请求、限频控制、异常重试把数据从接口安全地搬运到本地。存储层——通常是 CSV 文件或者 SQLite避免每次运行都重复请求接口。指标计算层——基于原始 OHLCV 数据计算 MA、MACD、KDJ 等技术指标。策略引擎——把指标转换成买卖信号模拟持仓过程。可视化层——把 K 线、信号、资金曲线画出来供人判断。给我的经验是拿到源码第一件事不是看策略写了什么而是先确认这条链路是否完整。链路断了策略再好也跑不出结果。2.3 源码目录结构解读运行前先摸清每个文件的职责这类源码解压后通常是一个标准的 Python 工程目录。我建议你先把目录树打印出来对照着确认每个模块是不是都在。你用下面的命令看find . -maxdepth 2 -type f -name *.py | sort # 或者 Windows 下用 dir /s /b *.py我按常见做法整理一个典型的目录结构你手上的源码大概率跟这个神似stock_system/ ├── config.yaml # 全局配置股票池、数据源、策略参数 ├── requirements.txt # 第三方依赖清单 ├── main.py # 程序入口 ├── collector/ │ ├── data_fetcher.py # 行情数据拉取网络请求 │ └── stock_api.py # 数据源接口适配 ├── storage/ │ └── cache.py # 本地缓存读写CSV/SQLite ├── indicator/ │ ├── ma.py # 均线指标 │ ├── macd.py # MACD 指标 │ └── kdj.py # KDJ 指标 ├── strategy/ │ ├── base.py # 策略基类 │ └── ma_cross.py # 双均线策略示例 ├── backtest/ │ ├── engine.py # 回测引擎 │ └── metrics.py # 收益/回撤/夏普等指标 └── visualize/ └── chart.py # K 线图与买卖点绘制看一下你解压出来的目录是不是覆盖了这些模块。如果缺了indicator/或者backtest/那说明这份源码可能不是完整版后续跑到对应环节会报ModuleNotFoundError。这个检查花不了一分钟但能帮你避免后面白折腾。另一点值得在运行前做的是确认 Python 版本要求。通常这类源码会在requirements.txt或者README里标注 Python 3.8 到 3.11。如果没标注我一般会直接用 3.10 或者 3.11这两个版本对 pandas 和 numpy 的兼容性最稳。3. 把源码跑起来环境准备、依赖安装与配置核对3.1 Python 版本选择和虚拟环境隔离先说结论不要用系统全局的 Python 直接跑隔离环境是必须的。原因很简单你的机器上可能已经装过别的版本的 pandas、numpy版本不对会让这份源码疯狂报错而且报错信息往往跟真实问题隔着一层非常难排查。如果你还没装 Python先去官网下安装包装的时候记得勾选「Add Python to PATH」——这一步很多人漏了导致后续在命令行里敲python提示找不到命令。装好之后我一般会做三件事确认版本、创建虚拟环境、激活虚拟环境。命令如下python --version # 确认输出是 Python 3.8 及以上例如 Python 3.10.11 python -m venv venv # 在当前目录创建虚拟环境 venv推荐放在源码根目录 # Windows 激活方式 venv\Scripts\activate # macOS / Linux 激活方式 source venv/bin/activate创建虚拟环境的逻辑是给这个项目单独隔离出一套 Python 解释器和第三方库目录不会污染全局环境也不会被全局环境里已有的库干扰。激活后命令行前面会多出一个(venv)前缀看到这个就说明你已经进入了虚拟环境。在这之后安装的所有库都只存在于venv目录内部。提示如果激活失败Windows 用户检查一下是不是权限问题用 PowerShell 管理员模式跑一次。macOS 用户如果用的是 zsh确认路径没有拼错。3.2 依赖清单逐个核对pandas、numpy、requests、matplotlib虚拟环境激活后下一步是安装依赖。这份源码的requirements.txt里通常会列出 pandas、numpy、requests、matplotlib、PyYAML 这几个基础库可能还会有可选的 akshare。直接把整个清单装进去是最快的pip install -r requirements.txt如果你装到一半报错或者requirements.txt里是空的那就手动逐个装。这里有一个很常见的问题——很多人卡在「python 安装 numpy 库的方法」这一步具体表现是pip install numpy之后 import 还是报错。常见原因是 pip 源太慢或者超时换国内镜像源可以解决pip install numpy pandas requests matplotlib PyYAML -i https://pypi.tuna.tsinghua.edu.cn/simple装完之后验证一下不要直接跑主程序先确认每个库能不能正常导入。这一步花不了二十秒但能在运行前过滤掉一半的翻车原因python -c import pandas as pd; import numpy as np; import matplotlib; print(ok)如果输出了ok说明核心依赖没问题。如果这里报错优先检查是不是 pip 把包装到了别的 Python 环境里——用pip --version看它指向的路径是不是当前虚拟环境。3.3 配置文件逐项拆解股票池、时间区间、参数项依赖装完之后最容易被忽略但最值得认真看的就是配置文件。这类源码一般用 YAML 格式存配置名字叫config.yaml。我在实战里见过太多人跳过配置直接运行跑出来的结果跟自己预期完全对不上最后发现是股票代码没改、时间区间不对。一个典型的配置文件长这样# 股票池与数据区间 stock_pool: - 600519 # 贵州茅台 - 000001 # 平安银行 start_date: 2022-01-01 end_date: 2024-12-31 # 数据源配置 data_source: provider: akshare # 可选 akshare / sina / tencent retry_times: 3 # 失败重试次数 timeout: 10 # 单次请求超时秒 # 技术指标参数 indicator: ma_short: 5 # 短均线周期 ma_long: 20 # 长均线周期 macd_fast: 12 macd_slow: 26 macd_signal: 9 # 回测参数 backtest: initial_capital: 100000 # 初始资金 10 万 commission: 0.0003 # 单边手续费 slippage: 0.001 # 滑点比例每个参数都不是摆设。ma_short和ma_long直接决定双均线策略的买点卖点initial_capital影响回测的仓位commission和slippage如果不设置回测结果会偏乐观仓位大的时候误差很明显。我的习惯是第一次运行只改股票池和日期区间其他参数一律不动。等基线跑通了再逐个调参这样出了问题你知道是自己改了哪一项导致的排查成本最低。3.4 首次运行与日志验证跑通基线才算数配置改好之后终于可以跑主程序了。在虚拟环境激活状态下执行python main.py第一次运行建议盯着终端输出。正常情况下你会看到几类信息数据采集的进度、指标计算的完成提示、回测的起止时间、最终的资金曲线和收益指标。如果只是闪一下就退出那多半是程序里有异常没被捕获你可以在命令后面加上-u强制不缓冲输出python -u main.py跑完之后检查一下项目目录里是不是生成了新的文件比如data/目录下的 CSV 文件、results/目录下的图表。如果这些产物都出现了说明这条链路已经通了。如果只跑了数据采集就停了问题大概率卡在指标计算或者策略引擎接下来要按模块单独调试。注意免费行情接口经常有限频限制如果日志里出现请求频率过高或者HTTP 429把data_source里的超时和重试参数调大或者把采集频率降到每秒一次以下。4. 核心模块实战行情采集、指标计算、策略信号与可视化4.1 行情数据采集接口适配与本地缓存行情采集是整条链路的第一个环节也是最容易因为外部原因挂掉的地方。以常见的 akshare 第三方库为例拉取日线数据的代码结构大致如下# collector/data_fetcher.py import akshare as ak import pandas as pd def fetch_daily_data(symbol: str, start_date: str, end_date: str) - pd.DataFrame: 拉取个股日线数据 :param symbol: 股票代码如 600519 :param start_date: 起始日期 YYYYMMDD :param end_date: 结束日期 YYYYMMDD :return: 包含 OHLCV 的 DataFrame df ak.stock_zh_a_hist( symbolsymbol, perioddaily, start_datestart_date, end_dateend_date, adjustqfq # 前复权避免除权跳空 ) # 重命名列为统一格式方便后续指标计算 df.rename( columns{ 日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume, }, inplaceTrue, ) return df[[date, open, high, low, close, volume]] if __name__ __main__: data fetch_daily_data(600519, 20220101, 20241231) print(data.head())这段代码的逻辑是调 akshare 的接口拉取指定股票在区间内的日 K然后做列名归一化。adjustqfq这个参数很重要——如果股票在区间内发生过分红送股不复权数据会出现价格跳空算出来的技术指标和回测结果全失真前复权则以最新价格为基准倒推历史价格保证连续性。我一般会在采集之后立刻做一步本地缓存把数据存成 CSV后续调试策略时不需要反复请求接口省时间也避免触发限频# 接上代码在 main 中调用时 data.to_csv(data/600519_daily.csv, indexFalse, encodingutf-8-sig)4.2 技术指标计算pandas 实现 MA 与 MACD指标计算层是策略的信号来源。双均线策略只需要两条均线逻辑简单但对初学者很友好。MA 的计算在 pandas 里是一行代码的事# indicator/ma.py import pandas as pd def add_ma(df: pd.DataFrame, short: int 5, long: int 20) - pd.DataFrame: 给 DataFrame 添加短周期和长周期均线 df df.copy() df[ma_short] df[close].rolling(windowshort).mean() df[ma_long] df[close].rolling(windowlong).mean() return dfrolling(windowshort).mean()表示对 close 列取长度为short的滑动窗口平均值。窗口越短均线越贴近价格本身信号越多但噪声也大窗口越长均线越平滑信号越少但更稳。5 和 20 是双均线策略里最常见的组合之一属于短期交易常用的参数。MACD 的计算稍微复杂一点核心是 EMA指数移动平均的差离值。pandas 里有现成的ewm方法不需要手动算权重# indicator/macd.py def add_macd(df: pd.DataFrame, fast: int 12, slow: int 26, signal: int 9) - pd.DataFrame: df df.copy() # 计算快线和慢线的 EMAspan 是平滑窗口大小 ema_fast df[close].ewm(spanfast, adjustFalse).mean() ema_slow df[close].ewm(spanslow, adjustFalse).mean() # DIF 快线 EMA - 慢线 EMA df[dif] ema_fast - ema_slow # DEA DIF 的 signal 周期 EMA即信号线 df[dea] df[dif].ewm(spansignal, adjustFalse).mean() # MACD 柱状图 2 * (DIF - DEA)国内行情软件通用算法 df[macd] (df[dif] - df[dea]) * 2 return dfewm(span..., adjustFalse)是标准 EMA 算法adjustFalse表示直接按指数加权递归计算不需要校正。DIF 和 DEA 的金叉死叉对应策略的买卖信号看盘软件里通常把 MACD 画成红绿柱子就是这个代码的最终产物。4.3 策略引擎与回测骨架向量化信号生成双均线策略的买卖规则很简单短均线上穿长均线金叉买入短均线下穿长均线死叉卖出。用向量化方式生成信号代码比循环清晰得多# strategy/ma_cross.py def generate_signals(df: pd.DataFrame) - pd.DataFrame: 基于双均线生成交易信号 signal 取值1 表示买入持有0 表示卖出空仓 df df.copy() # 前一行短均线 前一行长均线当前行短均线 当前行长均线 → 金叉 df[signal] ( (df[ma_short] df[ma_long]) (df[ma_short].shift(1) df[ma_long].shift(1)) ).astype(int) # 死叉时信号为 0 df[signal] df[signal].where( ~((df[ma_short] df[ma_long]) (df[ma_short].shift(1) df[ma_long].shift(1))), 0 ) return dfshift(1)的作用是取前一行的数据这样我们才能判断“从上一个状态变成当前状态”的穿越动作。.where(条件, 0)表示不满足条件的位置替换成 0。注意这里生成的 signal 是事件信号不是持仓状态回测引擎需要把它转成持仓# backtest/engine.py def run_backtest(df: pd.DataFrame, initial_capital: float 100000.0, commission: float 0.0003): df df.copy() # 用 forward fill 把事件信号转成持仓状态买入后一直持有直到死叉 df[position] df[signal].replace(0, pd.NA).ffill().fillna(0) # 计算每日收益率简单收益率 df[daily_return] df[close].pct_change().fillna(0) # 扣除手续费和滑点这里简化为每笔交易固定成本比例 df[strategy_return] df[position].shift(1) * df[daily_return] df[strategy_return] df[strategy_return] - \ (df[signal].diff().abs() * (commission 0.001)).fillna(0) df[equity] initial_capital * (1 df[strategy_return]).cumprod() return dfposition.shift(1)是为了避免未来函数——今天的持仓决策只能基于昨天的信号今天的收盘价不能用来决定今天的仓位这一行是回测正确与否的分水岭。signal.diff().abs()计算出买卖动作发生的位置每发生一次就扣一次手续费和滑点这样回测结果才接近真实成本。4.4 数据可视化K 线图与买卖点叠加最后是可视化。用 matplotlib 手动画 K 线需要自己画矩形和影线代码稍长但灵活度高如果你装了 mplfinance 可以直接用。手动方式的核心逻辑是用matplotlib.patches.Rectangle画实体用vlines画影线# visualize/chart.py import matplotlib.pyplot as plt import matplotlib.patches as patches def plot_kline_with_signals(df: pd.DataFrame, symbol: str): fig, ax plt.subplots(figsize(14, 7)) for i, row in df.iterrows(): color #e60000 if row[close] row[open] else #009900 # 画 K 线实体矩形x 是索引位置y 是开盘价高度是实体长度 rect patches.Rectangle( (i - 0.3, min(row[open], row[close])), 0.6, abs(row[close] - row[open]), facecolorcolor, edgecolorcolor, ) ax.add_patch(rect) # 画上下影线 ax.vlines(i, row[low], row[high], colorcolor, linewidth0.8) # 叠加两条均线和买卖点 df[ma_short].plot(axax, color#f39c12, labelMA5) df[ma_long].plot(axax, color#2980b9, labelMA20) buy_points df.index[df[signal] 1] sell_points df.index[df[signal].diff().fillna(0) -1] # 死叉事件 ax.scatter(buy_points, df.loc[buy_points, close], marker^, colorred, s100, labelBUY) ax.scatter(sell_points, df.loc[sell_points, close], markerv, colorgreen, s100, labelSELL) plt.title(f{symbol} K-Line with Signal) plt.legend() plt.show()这段代码把 K 线实体、影线、均线和买卖点画在同一张图上视觉上直接验证策略的逻辑是否正确。如果你发现买卖点的位置和市场公认的高点低点偏差很大优先检查信号生成逻辑而不是怀疑绘图代码。5. 避坑记录依赖、编码、时区、数据源和日期轴的五个常见坑5.1 依赖版本冲突pandas 2.x 与 numpy 1.x 不兼容现象运行main.py时终端报ValueError: numpy.dtype size changed, may indicate binary incompatibility或者直接崩溃退出没有任何业务日志。原因pandas 2.x 在编译时依赖特定版本的 numpy而你虚拟环境里装的 numpy 版本过低或者过高二进制接口对不上。这类问题在源码解压到新机器上时极其常见因为每个人的全局环境不一样。解决先卸载重装让 pip 自动解析依赖关系。我一般这样处理pip uninstall pandas numpy -y pip install numpy pandas --upgrade如果还不行就指定版本安装pandas 1.5.3 搭配 numpy 1.23.5 是经过大量项目验证的稳定组合。版本锁定比盲目装最新版可靠得多。5.2 中文乱码CSV 编码问题导致数据读入异常现象数据采集完成后本地 CSV 文件用记事本打开是正常的中文但pd.read_csv()读进来之后列名变成一堆乱码或者直接报UnicodeDecodeError。原因Windows 环境默认编码是 GBK而 Python 的open()和 pandas 默认用 UTF-8 解码。数据文件是 UTF-8 写入的但 Windows 的某些中间环节把它转成了 GBK 或者混合编码。解决读取时显式指定编码不再依赖默认值df pd.read_csv(data/600519_daily.csv, encodingutf-8-sig)写入时也用utf-8-sig这个编码会带 BOM 头Excel 打开不会乱码pandas 再读回来也不会出问题。从那以后我写 CSV 一律utf-8-sig没有再踩过这个坑。5.3 时区错位行情数据日期偏移一天回测结果失真现象拉下来的数据里最后一根 K 线日期是昨天或者某一天的行情被归到了第二天更隐蔽的是回测里信号的买卖日期和实际 K 线日期对不上看起来像是信号滞后了一天。原因行情接口返回的时间戳是 UTC 或者交易所时区而你本地datetime.now()取的是系统时区。如果在日期格式化时没统一时区00:00附近的 K 线会被归到错误的自然日。日线还好分钟线级别的错位会直接毁掉策略评估。解决所有时间处理统一用交易日历而不是自然时区。我在代码里要求所有日期字段都是纯字符串YYYY-MM-DD禁止混用 datetime 对象如果要转换显式指定tzAsia/Shanghai。数据落地之前对date列做一次去重和排序确认没有重复值和日期倒退。5.4 免费数据源接口失效URL 变更导致采集失败现象昨天跑得好好的今天再运行日志里出现HTTP Error 403或者超时有时候返回的是空 DataFrame程序不报错但后续指标计算全部净失败。原因免费行情接口的 URL、请求头校验或者限频策略经常调整。数据源把爬虫识别出来之后直接拒绝服务或者接口地址已经更新你的代码还指向旧地址。解决不把鸡蛋放在一个篮子里。我给这份源码做了一层数据源适配核心思路是配置文件里指定主备两个数据源主数据源失败自动切换备用。另外所有请求都加上常见浏览器请求头降低被识别为脚本的概率headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept: application/json, }并且把采集结果立刻落盘即使接口挂了你还有本地缓存可以用不至于整个流程断掉。5.5 matplotlib 日期轴标签挤成一团画图横坐标太密集现象把 K 线图画出来之后X 轴上的日期标签重重叠叠完全看不清具体日期整个横轴看起来像一团黑块。很多人卡在这一步以为是自己的显示器分辨率不够。原因matplotlib 默认对时间序列的刻度定位策略是「密集覆盖」一年两百多个交易日它恨不得全标出来。而 K 线图的 X 轴实际是整数索引如果你用日期字符串当 x 轴matplotlib 会为每一天生成一个刻度。解决手动控制刻度数量和格式。最简洁的方式是指定每隔一段时间标一个日期并且把标签旋转 45 度防止重叠import matplotlib.dates as mdates ax.xaxis.set_major_locator(mdates.MonthLocator(interval2)) # 每隔 2 个月标一个刻度 ax.xaxis.set_major_formatter(mdates.DateFormatter(%Y-%m)) plt.xticks(rotation45)MonthLocator(interval2)表示每两个月放置一个主刻度DateFormatter(%Y-%m)把日期格式化成「年-月」。这一招对任何时间序列图都适用不只是股票 K 线。6. 把回测结果做成汇报级报告收益曲线、最大回撤、夏普比率一次算清跑完回测拿到一张 K 线买卖点图还不够——你得把策略的好坏变成数字才能在多个参数组合之间做对比也才能让自己信服这套策略是否值得实盘验证。这一章的做法是把回测里输出的资产曲线加工成一份标准的绩效报告。核心绩效指标有三个年化收益率、最大回撤、夏普比率。年化收益率告诉你赚钱快不快最大回撤告诉你最惨的时候亏多少夏普比率告诉你每承担一份风险换来多少超额收益通常大于 1 才算合格。# backtest/metrics.py import numpy as np import pandas as pd def compute_metrics(df: pd.DataFrame, initial_capital: float 100000.0, risk_free_rate: float 0.02, periods_per_year: int 252): 计算回测绩效指标 :param df: 包含 equity 列的 DataFramedaily_return 为每日策略收益率 :param risk_free_rate: 无风险利率默认 2% :param periods_per_year: 每年交易日数日线数据用 252 :return: 指标字典 # 资产曲线的每日变化率 daily_returns df[equity].pct_change().dropna() # 累计收益 total_days len(df) total_return df[equity].iloc[-1] / initial_capital - 1 # 年化收益率复利换算 annual_return (1 total_return) ** (periods_per_year / total_days) - 1 # 最大回撤资产从峰值跌到谷底的最大幅度 rolling_max df[equity].cummax() drawdown df[equity] / rolling_max - 1 max_drawdown drawdown.min() # 夏普比率超额收益均值 / 标准差再年化 excess_returns daily_returns - risk_free_rate / periods_per_year sharpe_ratio np.sqrt(periods_per_year) * excess_returns.mean() / excess_returns.std() return { total_return: total_return, annual_return: annual_return, max_drawdown: max_drawdown, sharpe_ratio: sharpe_ratio, }这段代码的核心是rolling_max和drawdown。资产峰值用cummax()从始至终滚动追踪每一步的当前资产与峰值相比跌了多少就是回撤取最小值就是最大回撤。很多初写回测的人会把回撤算错常见错误是直接用资产最大值减最小值忽略了「回撤是相对前高不是相对初始资金」这个定义。拿到指标之后我习惯再画一张图把资产曲线和回撤曲线上下排列这会暴露很多数字掩盖的问题。用 matplotlib 的subplots两行代码搞定fig, (ax1, ax2) plt.subplots(2, 1, figsize(14, 8), sharexTrue) ax1.plot(df[equity], color#2980b9, labelEquity Curve) ax1.set_ylabel(Capital) ax2.fill_between(df.index, drawdown * 100, 0, color#e60000, alpha0.3) ax2.set_ylabel(Drawdown (%)) plt.show()下半张图如果出现一条长时间贴着 -20% 以下的深红色区域说明这个策略有相当长的一段时期处在深度亏损状态即使整体收益为正实盘心态也很难扛住。最后说一个我自己的习惯。早先我拿到类似的股票源码第一反应都是解压、跑通、看曲线觉得能出图就算成功了。后来被数据源失效、时区错位、回测未来函数这些问题连续坑过几次才意识到跑通只是开始做空数据比对、锁版本、写自动缓存这些看起来枯燥的步骤才是真正让一套源码能在你手里稳定复现的关键。从那以后我每次拿到新源码都强制走一遍固定流程隔离环境 → 锁定依赖版本 → 跑通数据采集 → 核对信号 → 再优化参数。这套流程让「源码我收到了但跑不出结果」这句话彻底消失在了我的工作习惯里。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑