diff --git a/README.md b/README.md new file mode 100644 index 0000000..c46433a --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# Chan — 缠论分析引擎 + +把 OHLCV K 线拆成缠论结构(K 线单元 → 合并 K 线 → 分型 → 笔 → 线段 → 中枢 → 买卖点), +配一个 TradingView Charting Library 的 Web 界面,外加一套验证信号有效性的回测脚本。 + +标的不限:加密永续(ccxt)与 A 股(akshare)都走同一条分析链路。 + +``` +chanlun/ 缠论引擎,纯 pandas/numpy,无外部指标库依赖 +web/ Flask API + 图表界面 +research/ 信号有效性验证脚本(step1 ~ step30) +data/ 本地 K 线(freqtrade 的 feather 格式) +``` + +## 安装 + +需要 Python ≥ 3.11(pandas 3.x / numpy 2.x 的要求,不是本项目代码的限制)。 + +```bash +python -m venv .venv +.venv/bin/pip install -r requirements.txt # 核心运行时,8 个包 +.venv/bin/pip install -r requirements-dev.txt # 另加测试与 research/ 所需 +``` + +## 跑 Web + +```bash +cd web +../.venv/bin/python app.py # 默认 http://0.0.0.0:8128 +``` + +从仓库根跑 `.venv/bin/python web/app.py` 也可以——Python 会把脚本所在目录放进 `sys.path`。 +但**不能用 `python -m web.app`**,也不能 `import web.app`:`web/` 内部是无前缀导入 +(`import config`、`from api.analyze import bp`),`-m` 方式下 `sys.path` 里是仓库根而不是 +`web/`,会 `ModuleNotFoundError: No module named 'config'`。 + +配置全部走环境变量,见 `web/config.py`: + +| 变量 | 默认值 | 用途 | +|------|--------|------| +| `FLASK_HOST` / `FLASK_PORT` | `0.0.0.0` / `8128` | 监听地址 | +| `DATA_SERVICE_URL` | `https://provider.jackyu66.com` | 行情 REST 源 | +| `DATA_SERVICE_WS_URL` | `wss://jackyu66.com/ws` | 行情 WebSocket 源 | +| `ASHARE_DP_URL` | `http://103.179.242.166:8000` | A 股数据源 | +| `CHAN_HTTP_PROXY` | 未设置则不走代理 | ccxt / HTTP 代理 | +| `MACD_FACTOR` / `MACD_SMOOTH` | `1` / `1` | MACD 周期倍数,默认 12/26/9 | + +主要接口:`GET /api/analyze` 返回某标的某周期的完整缠论结构,`/api/klines/recent` +取最新 K 线,`/api/trend_filter` 与 `/api/trend_detail` 做多周期趋势筛选, +`/api/symbols`、`/api/search_stock`、`/api/sectors` 等负责标的检索。页面在 `/` 与 `/chan_tv`。 + +## 作为库使用 + +```python +import pandas as pd +from chanlun import TF_DF + +# 需要 date/open/high/low/close/volume 六列,date 为 datetime +df = pd.read_feather("data/binance/futures/BTC_USDT_USDT-1h-futures.feather") + +tf = TF_DF(df, interval=1, timeframe="1h") + +len(tf.klu_list) # K 线单元 +len(tf.klc_list) # 合并 K 线(处理包含关系后) +len(tf.bi_list) # 笔 +len(tf.seg_list) # 线段 +len(tf.zs_list) # 中枢 +tf.bi_list[-1].dir # Chan_BI_DIR.DOWN +tf.chanmacd # MACD 结构分析(背驰判定用) +``` + +**`interval` 的单位是分钟**,对传入的 df 做重采样;`interval=1` 是特例,表示原样使用、 +不重采样。所以拿 1h 的 feather 要传 `interval=1`,拿 1m 数据想看 1h 才传 `interval=60`: + +```python +df1m = pd.read_feather("data/binance/futures/BTC_USDT_USDT-1m-futures.feather") +TF_DF(df1m, interval=5, timeframe="5m") +TF_DF(df1m, interval=60, timeframe="1h") +``` + +传错不会报错,只会静默给出错误周期的结构——1h 数据配 `interval=4` 相当于按 4 分钟 +重采样,结果与 `interval=1` 完全相同。 + +## 分析流程 + +`TF_DF.init_TF_DF()` 按顺序做这几步,每步的实现在 `chanlun/pipeline/builders/` 下同名文件: + +1. `resample_to_interval` — 重采样(`interval != 1` 时) +2. `add_indicators` — 追加 33 列指标(MACD / BBANDS / EMA / RSI / ATR 等) +3. `cal_kl_data` → `klu_list` — K 线单元 +4. `get_klc_list` → `klc_list` — 按包含关系合并 K 线,并标记分型 +5. `cal_bi_list` → `bi_list` — 笔 +6. `cal_bi_zs_list_pure` → `bi_zs_list` — 笔中枢 +7. `get_seg_list` → `seg_list` — 线段 +8. `get_zs_list` / `get_big_zs_list` — 中枢与大级别中枢 +9. `ChanMACD(klu_list)` — MACD 段 / 柱堆结构,供背驰判定 + +## 数据 + +`data/<交易所>/futures/-<周期>-futures.feather`,即 freqtrade 的下载格式, +如 `data/binance/futures/BTC_USDT_USDT-1h-futures.feather`。 +`research/lib/data.py` 负责定位:`BTC/USDT:USDT` + `1h` 会解析到上面这个路径, +找不到本地文件则回落到远端拉取。 + +## 测试 + +```bash +.venv/bin/python -m pytest chanlun/tests web/tests -q +``` + +`chanlun/tests/test_ta_compat.py` 有个**需要注意的陷阱**:它把 `chanlun/indicators/ta.py` +的输出逐 bar 钉在 TA-Lib 上,但 **TA-Lib 不存在时会静默跳过**。也就是说改了 `ta.py` +之后在没装 TA-Lib 的环境里跑,测试会显示通过,其实一项都没验证。改动那个文件时请先装: + +```bash +sudo apt-get install -y libta-lib0 ta-lib-dev +.venv/bin/pip install TA-Lib technical +``` + +## 已知问题 + +- **`web/DEPLOY_GUIDE.md` 已失效**:它引用的 `deploy_venv.sh`、`stop_venv.sh`、 + `status_venv.sh` 等 6 个脚本都在 `7f393b9` 精简提交里删掉了,目前没有部署脚本。 + 两个 systemd unit 文件(`web/chanlun-web*.service`)仍可参考,但它们用 gunicorn + 且写死端口 8123,与 `config.py` 默认的 8128 不一致,gunicorn 也不在依赖清单里。 +- **`web/README.txt` 已过时**:它说的 `web/requirements.txt` 不存在,依赖清单在仓库根目录。 +- **四个零引用的死文件**:`chanlun/analysis/` 下的 `ChanPY.py`、`ChanLun_Classifier.py`、 + `Find_Trend.py`、`ChanHeng.py` 全项目无人引用。`ChanPY.py` 依赖未安装的外部 chan.py 库, + 另外三个需要 matplotlib / mplfinance / xgboost / scikit-learn——这些都**不在**依赖清单里, + 是有意为之。要用得自行安装。 diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..6bba2d4 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,32 @@ +# Tests and research/ — everything beyond the core runtime. +# +# .venv/bin/pip install -r requirements.txt -r requirements-dev.txt +# .venv/bin/python -m pytest chanlun/tests web/tests + +-r requirements.txt + +# --- tests ----------------------------------------------------------------- +pytest>=8.0 + +# --- research/ ------------------------------------------------------------- +# pyarrow reads the data/binance/*.feather klines (research/lib/data.py) and +# writes the parquet cache. Needed for research/, not by the web app. +pyarrow>=15.0 + +# Only research/step10_direct_return_label.py and step11_breakout_follow.py. +# Neither is installed by default; skip this pair unless running those steps. +scikit-learn>=1.4 +lightgbm>=4.3 + +# --- indicator parity check (optional) ------------------------------------- +# chanlun/indicators/ta.py replaced TA-Lib and technical, so nothing here needs +# them at runtime. chanlun/tests/test_ta_compat.py pins our output against +# TA-Lib bar for bar and SKIPS SILENTLY when they are absent — meaning a change +# to ta.py can look tested when it was not. Install these and re-run that file +# whenever ta.py changes. +# +# TA-Lib needs the C library first: +# sudo apt-get install -y libta-lib0 ta-lib-dev +# +# TA-Lib>=0.6 +# technical>=1.7 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..52a4cae --- /dev/null +++ b/requirements.txt @@ -0,0 +1,29 @@ +# Core runtime — what `web/` and `chanlun/` need to run. +# +# python -m venv .venv && .venv/bin/pip install -r requirements.txt +# +# Tests and research/ pull in more; see requirements-dev.txt. +# +# Requires Python >= 3.11 (imposed by pandas 3.x / numpy 2.x, not by our code). +# +# Lower bounds are the oldest versions believed safe. Verified set as of +# 2026-08-27 on Python 3.14.4: +# pandas 3.0.5 · numpy 2.5.2 · Flask 3.1.3 · requests 2.34.2 +# python-dateutil 2.9.0 · pytz 2026.3 · ccxt 4.5.75 · akshare 1.18.94 + +# chanlun/ — kline pipeline and indicators. +# pandas >= 2.2 for the "5min" offset alias used by chanlun/pipeline/resample.py. +pandas>=2.2 +numpy>=1.26 + +# web/ — Flask API and templates. +Flask>=3.0 +requests>=2.31 +python-dateutil>=2.9 +pytz>=2024.1 + +# Market data. ccxt drives the live websocket/REST state in +# web/services/runtime/state.py; akshare only backs the A-share endpoints in +# web/services/cn_stock.py. +ccxt>=4.4 +akshare>=1.16