一款在 Android 手机上运行的股票技术分析小工具:输入股票/指数代码,自动选择对应版本的 牛门线 指标, 绘制最近 5 个交易日 的 K 线与牛门线(NML / QRL / SMX,标的版与指数版另含 20/60 日成本线), 并给出可读性强的文字判读(结构偏多/偏空、所处阶段、关键压力与支撑位)。
技术栈:Python + Kivy + KivyMD(Material Design 界面) 打包:Buildozer 在 GitHub Actions 中自动构建 APK(本项目不在本地运行,全部构建在 GitHub 完成)
- 📱 移动端原生界面:深色主题、卡片式布局、红涨绿跌 K 线、五色指标线图例
- 🔍 任意代码输入:支持
sh000852、600519、HSTECH、hk00700、usAAPL等格式(6 位纯数字自动补前缀) - 🧭 版本自动选择:根据代码自动匹配 基础主图版 / 标的版 / 指数版
- 📊 5 个交易日窗口:包含所选日在内绘制牛门线各线 + 当日 OHLC 蜡烛
- 📅 指定日期查看:日历选择任意交易日回看当时结构
- 📰 文字判读:结构判断徽章 + 阶段描述 + 概述段落 + 关键位(压力/支撑/回踩观察位)
- 🌐 双数据源:默认腾讯财经历史 K 线接口,失败自动切换新浪财经
- 🌗 深浅主题:顶栏一键切换
牛门线本质是唐奇安通道(Donchian Channel)+ ATR 波动率的复合变形指标:
| 指标线 | 公式 | 含义 |
|---|---|---|
| NML(牛门线) | REF(HHV(H,20),1) + 0.5×ATR(14) |
前 20 日最高价 + 0.5 倍平均真实波幅,突破入场 / 压力线 |
| QRL(强阻力线) | REF(HHV(H,20),1) + 1.0×ATR(14) |
前 20 日最高价 + 1 倍 ATR,强压力 / 止盈线 |
| SMX(生命线) | MA(C,10) |
10 日均线,趋势参考 / 止损线 |
| CBX20 / CBX60 | 20/60 日加权平均成本 | 标的版:SUM(AMOUNT,N)/SUM(V,N)/100;指数版:SUM(C*V,N)/SUM(V,N) |
其中 TR1 = MAX(H-L, ABS(H-REF(C,1)), ABS(L-REF(C,1))),ATRV = MA(TR1,14)。
股价突破 NML 视为多头信号,跌破 SMX 视为趋势走弱。
| 代码 | 示例 | 版本 |
|---|---|---|
sh000xxx(上证系列指数) |
sh000001 上证指数、sh000852 中证1000 |
指数版 |
sz399xxx(深证系列指数) |
sz399001 深证成指、sz399006 创业板指 |
指数版 |
A股个股(sh60x/sz0x/sz3x/bj) |
sh600519、sz300750 |
标的版 |
| 其他(港股/美股/期货/HSTECH 等) | hk00700、usaapl、hstech |
基础主图版 |
成本线口径说明:标的版优先使用成交额口径(腾讯 K 线数据含成交额字段时); 若数据源未提供成交额,则按
收盘价×成交量加权估算并在界面标注"(估算口径)"。 指数版始终使用C×V/V口径(与通达信指数公式一致)。
-
将本项目推送到你的 GitHub 仓库:
git init git add . git commit -m "牛门线分析 v1.0" git branch -M main git remote add origin https://github.com/<你的用户名>/niu-men-line.git git push -u origin main
-
打开仓库 Actions 标签页,会看到
Build Android APK工作流自动运行:Unit tests:先跑指标/判读/解析单元测试(约 1 分钟)Build Android APK:Buildozer(Docker)打包(首次约 30~60 分钟,之后有缓存会快很多)- 也可以手动点击 Run workflow 重新构建
-
构建成功后,进入该次运行的 Summary 页面,在 Artifacts 处下载
niumen-apk,解压得到niumen-1.0.0-<arch>-debug.apk。 -
把 APK 传到手机(微信/网盘/数据线均可),点击安装,首次需允许 "安装未知来源应用"。
APK 为 debug 签名,可直接安装使用。首次构建耗时较长属正常现象(需下载 Android SDK/NDK 与依赖)。
桌面预览(需要 Python 3.8+):
pip install kivy==2.2.0 kivymd==1.1.1 requests
bash tools/fetch_fonts.sh # 下载中文字体(Windows 可用 Git Bash / WSL)
python main.py运行单元测试:
pip install pytest
python -m pytest tests -vniu-men-line/
├── main.py # 程序入口
├── buildozer.spec # Buildozer 打包配置(APK 参数、依赖)
├── app/
│ ├── config.py # 常量:版本、周期参数、配色
│ ├── api.py # 腾讯(默认)/ 新浪(备用)数据源 + 解析 + 版本识别
│ ├── indicator.py # 牛门线指标计算(纯函数)
│ ├── interpreter.py # 文字判读(纯函数)
│ ├── chart.py # Canvas K 线图 + 指标线 + 日期轴
│ ├── ui.py # KivyMD 界面
│ └── assets/ # 图标、字体(字体由 CI 下载)
├── tests/ # 单元测试(CI 中自动执行)
├── tools/
│ └── fetch_fonts.sh # 下载 Noto Sans SC 中文字体
└── .github/workflows/
└── build-apk.yml # GitHub Actions:测试 + 打包 APK + 上传产物
Q:界面中文显示为方块?
A:Kivy 默认字体不含中文。GitHub Actions 构建前会自动下载 Noto Sans SC 并打包进 APK;
若手动构建(非 CI)请先执行 tools/fetch_fonts.sh。
Q:提示"获取数据失败"?
A:请确认代码格式(如 sh000852、600519、HSTECH);部分海外代码(如新加坡指数 HSTECH)
腾讯/新浪接口可能没有收录,属数据源覆盖范围问题。也请确认手机网络正常。
Q:成本线数值与券商软件不一致?
A:腾讯 K 线接口不含历史成交额时,成本线按 收盘价×成交量 估算,与通达信 AMOUNT 口径会有细微差异;
界面会标注"(估算口径)"。成交额口径下公式为 SUM(AMOUNT,N)/SUM(V,N)/100,与原文一致。
Q:如何修改指标参数?
A:修改 app/config.py 中的 N(唐奇安周期)、M(ATR 周期)、SMA10、CBX20_N、CBX60_N 后重新打包。
Q:APK 内 Python / Kivy / KivyMD 是什么版本?
A:buildozer.spec 钉住 Python 3.11.5 + Kivy 2.2.0 + KivyMD 1.1.1 的兼容组合:
Python 必须为 3.11.5(与 p4a-recipes/ 本地覆盖的 hostpython3 版本一致;Kivy 2.2.0
只能在 ≤3.12 上构建,Python 3.13+ 移除 cgi 导致 config.pxi 生成失败);kivy/kivymd
钉住避免 pip 解析器在 kivymd 1.2.0 与 kivy 最新版之间报 "conflicting dependencies"。
代码对 Kivy 2.2+/2.3+ 与 KivyMD 1.1.1+/1.2.0 均兼容。
Q:首次构建太慢? A:首次需下载 SDK/NDK/依赖(约 30~60 分钟,NDK r27b 约 1GB);工作流已配置缓存,后续构建显著加快。
Q:Buildozer 构建步骤失败?
A:构建使用官方 kivy/buildozer Docker 镜像,容器内执行 tools/docker_build.sh 自动处理:
- hostpython3 版本不匹配(
python3 should have same version as hostpython3, x != y)的 根因:p4a 新版把 hostpython3 独立成 recipe 且版本固定,并强制与 python3 钉版一致 → 通过buildozer.spec钉住p4a.branch = v2026.05.09(2026 最新 release,SDL2 2.30.x + NDK r27 支持,兼容 Android 15+ / 16KB 内存页设备),并用p4a.local_recipes本地覆盖p4a-recipes/hostpython3的版本为 3.11.5(与构建 Python 一致;新版默认 3.14.2 与 Kivy 2.2.0 冲突),android.ndk = 27b。 - Python 3.14 与 Kivy 2.x 构建链冲突(
config.pxi/cgi):镜像 venv Python 为 3.14.x, Kivy 2.2.0 只能在 ≤3.12 构建 → 脚本固定选择 3.11.5 新建独立 venv, 并把python3钉版动态改为该 Python 的确切版本。 - pip ≥ 24 与旧版 p4a(
cannot import name 'BuildDependencyInstallError'):脚本已先降级pip<24并安装 buildozer。 - CMake 4.0 与旧 recipe(
Compatibility with CMake < 3.5 has been removed from CMake., 出在 p4a 的jpeg(libjpeg-turbo 2.1.0)等 cmake recipe):镜像基座升级(Ubuntu 25.04)后/usr/bin/cmake已是 CMake 4.x,4.0 起不再兼容cmake_minimum_required(<3.5)的项目 → 脚本在 venv 内用 pip 把 cmake 钉到 3.29.6 并置入 PATH 首位,全局绕开该问题。 - 镜像/缓存中的旧 python 构建产物:脚本在构建前清理。
docker run 使用
--entrypoint /bin/bash(跳过镜像入口脚本,以 root 运行,echo y |自动应答 buildozer 的 root 提示)。 切换 Python 版本后,工作流通过缓存 key 中的-py310-v3-标记强制重建一次~/.buildozer(后续若再切换 Python 版本,需同步升级该标记)。 若镜像中没有合适的 Python(kivy/buildozer:latest目前基于 Ubuntu 25.x,系统只有 3.13/3.14,apt 也没有老版本),脚本固定取 Python 3.11.5(与本地覆盖的 hostpython3 一致):先用容器自带的 python3 建临时 venv 装 uv,由 uv 拉取 python-build-standalone 的 CPython 3.11.5 继续构建;apt 与 uv 都失败才明确报错退出。若容器无法联网获取 python3.11.5,可将.github/workflows/build-apk.yml中的kivy/buildozer:latest改为固定版本kivy/buildozer:1.5.0后重试。也可以在本地按官方文档走非 Docker 路径 (pip install buildozer+ 系统依赖)构建。
Q:手机安装时提示"未安装应用"或"解析包错误"?
A:请确认下载的 APK 完整(解压 artifact 后安装),且手机架构为 arm64(当前仅构建
arm64-v8a:v2026.05.09 的多架构构建存在 venv/pip 混装 bug,单架构可规避;2025 年
机型均为 arm64)。若需自定义图标或应用名,修改 tools/make_icon.ps1 与 buildozer.spec
后重新构建。
本项目仅为技术指标(牛门线)的原理演示与个人学习工具,界面中的文字判读由程序按固定规则自动生成, 不构成任何投资建议。股市有风险,投资需谨慎。
数据来源:腾讯财经(web.ifzq.gtimg.cn)、新浪财经(quotes.sina.cn)。