乐于分享
好东西不私藏

从零搭建 A 股量化分析助手:OpenCLAW + DeepSeek-V4-Pro 实战指南

从零搭建 A 股量化分析助手:OpenCLAW + DeepSeek-V4-Pro 实战指南

关于如何使用这篇指南?(本文仅做技术探究,股市有风险,入市须谨慎下载Trae,在solo模式下通过对话框将此文链接给他,告诉它按此文进行搭建即可

web端效果

飞书端效果

为什么选择 OpenCLAW

OpenCLAW 是开源 AI Agent 框架,内置 exec(执行本地脚本)、web_search(搜索实时资讯)、memorySearch(RAG 检索)等工具。通过 Gateway 本地运行,支持计划任务后台部署。

为什么选择 DeepSeek-V4-Pro

DeepSeek-V4-Pro 在国产大模型中能力与 GLM-5.1 同档,但 API 调用成本远低于后者,原生支持 tool calls,适合 Agent 工作流。

实现功能

  • 个股实时行情:输入股票代码,返回现价、涨跌幅、最高最低、PE、成交额
  • 个股买卖建议:结合实时数据 + 投资策略库,输出参考买入区间、止损位、目标位
  • 多股估值对比:同时拉取多只股票数据,横向对比 PE/涨跌幅,给出优选结论
  • 量化选股:五大因子评分(技术面/基本面/筹码峰/集中度/成交量震荡),TOP 推荐
  • 盘中消息分析:搜索实时资讯,判断消息面对股价的影响
  • 策略合规检查:检索用户自定的仓位/止损规则,检查持仓是否超标
  • 盘前晨报/收盘复盘:自动生成外围市场、板块、自选股的结构化报告

技术栈

组件
说明
OpenCLAW
Agent 框架,Gateway 本地运行,提供 exec / web_search / memorySearch 工具调度
DeepSeek-V4-Pro
主力分析模型,1M 上下文,支持 tool calls
DeepSeek-V4-Flash
备用模型,V4-Pro 不可用时自动切换
阿里百炼 text-embedding-v3
embedding 模型,将投资策略文档向量化供 RAG 检索
东方财富 push2 API
实时行情主数据源,返回价格/PE/成交额
同花顺 time API
实时行情备数据源,东方财富不可用时自动接管
AKShare
Python 量化接口库,提供历史K线和财务指标
mootdx(通达信)
TCP 直连通达信行情服务器,零鉴权不封 IP,K 线备数据源
腾讯财经 HTTP API
零鉴权实时行情,返回 PE(TTM)/PB,作为估值数据的补充
同花顺财报 API
通过 AKShare 获取 ROE、营收增速、利润增速等基本面真实数据
multi-search-engine
搜索引擎技能,web_search 工具使用16个引擎交叉验证资讯
SearXNG
自部署隐私搜索引擎(Docker),作为 web_search 的实际搜索后端,聚合 Google/Bing/DuckDuckGo 等结果
RAG 投资策略库
memorySearch

 检索三份核心策略文档(选股/风控/行业偏好)

一、环境准备

组件
版本要求/使用说明
Node.js
v22.x+
Python
3.14+
npm
全局可用
Trae IDE
搜索引擎搜索下载

安装 openclaw:

npm install -g openclaw@2026.5.20

安装 Python 依赖:

pip install requests beautifulsoup4 akshare pandas numpy mootdx

项目目录结构(后续章节会逐步创建)。


二、投资策略知识库

在 d:\workspace\openclaw\rag-docs\ 下创建以下三个文件。memorySearch 启动时会将它们向量化,之后每次股票分析都会自动检索这些策略。

选股标准

文件:rag-docs/投资策略-选股标准.md

# A股选股标准## 核心选股条件### 基本面筛选1. 市盈率(PE)30倍(金融股可放宽至15倍以内)2.ROE(净资产收益率)> 15%3. 流通市值 50亿 - 500亿4. 近三年营收复合增长 > 10%5. 资产负债率 60%(金融股除外)6. 经营现金流为正### 技术面筛选1. 股价位于20日均线之上2. 近20日处于上升趋势3. 成交量温和放大(非暴涨暴跌)4.MACD 处于金叉状态或即将金叉### 排除条件1.ST 股票、*ST 股票2. 上市不满 60 天的新股3. 近一月有重大负面新闻4. 股东近期有大额减持公告5. 地产、教培行业(政策风险高)## 评分体系(满分10分)| 维度 | 权重 | 标准 ||------|------|------|| 基本面 | 4分 | PE<204分, PE20-302分 || 技术面 | 3分 | 上升趋势+放量得3分 || 行业前景 | 2分 | 政策支持+景气周期得2分 || 资金面 | 1分 | 北向资金增持+融资余额增加得1分 |## 推荐等级-8-10分:强烈推荐-6-7分:推荐关注-4-5分:观望-1-3分:不推荐

风险控制

文件:rag-docs/投资策略-风险控制.md

# 风险控制规则## 仓位管理1. 单只股票仓位不超过总资金的 20%2. 同一行业持仓不超过总资金的 30%3. 总持仓不超过账户资金的 80%(保留20%现金)4. 单日新开仓不超过总资金的 10%## 止损规则1. 买入后亏损超过 -8%,无条件止损2. 从最高点回落超过 -10%,止盈离场3. 连续3天跑输大盘,减仓一半4. 单月亏损超过 -15%,当月停止交易## 交易纪律1. 不在开盘前30分钟和收盘前30分钟下单2. 不追涨停板(封板前已启动除外)3. 不在下跌趋势中加仓4. 不因利好消息冲动买入(等市场反应后再判断)5. 不持有一只股票超过3个月(除非明确长期投资逻辑)## 风控检查清单每次交易前确认:[ ] 是否在止损线以内?[ ] 单只股票仓位是否超标?[ ] 该行业仓位是否集中?[ ] 是否有明确的买入/卖出逻辑?[ ] 是否情绪化操作?## 推荐风格偏好:稳健价值投资,追求年化 15-20% 收益持股周期:中线为主(2周-3个月)换手率:每月不超过5次交易止损纪律:严格执行,不存侥幸心理

行业偏好

文件:rag-docs/投资策略-行业偏好.md

# 行业偏好与关注方向## 重点关注行业### 1. 消费(白酒、食品饮料、家电)代表标的:贵州茅台、五粮液、美的集团### 2. 医药(创新药、医疗器械、中药)代表标的:恒瑞医药、迈瑞医疗、片仔癀### 3. 新能源(光伏、储能、电动车)代表标的:宁德时代、比亚迪、阳光电源### 4. 半导体(芯片设计、设备、材料)代表标的:中芯国际、北方华创### 5. 金融(银行、保险)代表标的:招商银行、中国平安## 不关注/排除行业1. 房地产及其产业链2. 教育培训(K12相关)3. 高污染/高能耗行业4. 商业模式不清晰的公司5. 过度依赖政府补贴的公司

三、配置 openclaw.json

编辑 C:\Users\admin\.openclaw\openclaw.json。以下为完整配置文件,关键位置已添加注释。复制后替换 apiKey 和 token 即可使用。

{"models": {"providers": {// ========== DeepSeek API (主力模型 + 备用模型) =========="deepseek-api": {"baseUrl""https://api.deepseek.com/v1","apiKey""sk-你的DeepSeek_API密钥","api""openai-completions","models": [          { "id""deepseek-v4-pro",   "name""DeepSeek-V4-Pro" },          { "id""deepseek-v4-flash""name""DeepSeek-V4-Flash" }        ]      },// ========== 阿里百炼 (embedding 模型,用于 RAG 检索) =========="dashscope": {"baseUrl""https://dashscope.aliyuncs.com/compatible-mode/v1","apiKey""sk-你的百炼API密钥","api""openai-completions","models": [          { "id""text-embedding-v3""name""text-embedding-v3" }        ]      }    }  },"agents": {"defaults": {// ========== 默认模型 =========="model": { "primary""deepseek-api/deepseek-v4-pro" },// ========== Agent 工作目录 =========="workspace""C:\\Users\\admin\\.openclaw\\workspace",// ========== RAG 知识库 (检索投资策略文档) =========="memorySearch": {"enabled"true,"sources": ["memory""sessions"],"extraPaths": ["d:\\workspace\\openclaw\\rag-docs"],"provider""dashscope","model""text-embedding-v3","query": {"hybrid": {"enabled"true,"vectorWeight"0.7,"textWeight"0.3          }        }      }    },"list": [{"id""ollama-local","model": {"primary""deepseek-api/deepseek-v4-pro","fallbacks": ["deepseek-api/deepseek-v4-flash"]      },// ========== 工具权限(exec 为必开项) =========="tools": {"alsoAllow": ["memory_search","memory_get","browser","canvas","agents_list","exec","web_search","web_fetch"        ],"deny": []      }    }]  },// ========== Gateway 服务 =========="gateway": {"port"18789,"mode""local","auth": {"mode""token","token""你的网关令牌(自定义字符串)"    }  }}

配置要点:

配置项
作用
deepseek-api
DeepSeek 主力模型,需注册 platform.deepseek.com 获取 key
dashscope
阿里百炼 embedding,用于 RAG 检索,需注册 dashscope.aliyun.com
memorySearch.enabled
必须为 true,否则不检索策略库
memorySearch.extraPaths
指向 rag-docs 目录的绝对路径
tools.alsoAllow

 含 exec
模型才能调用 Python 脚本获取实时行情
tools.alsoAllow

 含 web_search
模型才能搜索实时资讯
gateway.port
UI 访问端口
gateway.auth.token
打开 UI 时输入的令牌

四、部署量化脚本

4.1 安装基础技能

量化选股脚本依赖 clawhub 上的两个基础技能:

  • stock-watcher:自选股管理技能,提供自选股的增删查改脚本(add/remove/list),以及自选股文件初始化。安装后 skills/stock-watcher/scripts/ 下的四个 Python 脚本可直接使用。
  • quant-stock-selector:量化选股技能,提供六大因子计算引擎(factor_calculator.py)、筹码分布计算(chip_distribution.py)和成交量震荡检测(volume_spike_oscillation.py)。这三个模块是后续 stock_scanner.py 批量选股的底层依赖,安装后自动就位。

在终端执行安装:

openclaw skill install stock-watcheropenclaw skill install quant-stock-selector

4.2 部署 SearXNG 搜索引擎(web_search 后端)

web_search 工具需要一个搜索引擎后端来执行实际的搜索请求。推荐自部署 SearXNG——隐私安全、无配额限制、聚合 Google/Bing/DuckDuckGo 等多引擎结果。

在远程服务器上用 Docker 部署:

# 1. 拉取镜像并启动(单 worker,适合个人使用)docker run -d --name searxng \  -p 18080:8080 \  -e SEARXNG_WORKERS=1 \  searxng/searxng:latest# 2. 查看日志,确认启动成功docker logs searxng --tail 20# 看到 "running at http://0.0.0.0:8080" 即成功# 3. 开放防火墙端口(如使用云服务器)# 阿里云/腾讯云安全组 → 入方向 → 允许 TCP 18080

如果看到 RuntimeError: can't start new thread,说明线程数超限。删掉容器重新启动,加上 -e SEARXNG_WORKERS=1 并 --ulimit nproc=65535:65535 即可。

获取 SearXNG 地址http://你的服务器IP:18080/

配置 openclaw.json:

"plugins": {"entries": {"searxng": {"enabled"true,"config": {"webSearch": {"baseUrl""http://你的服务器IP:18080"        }      }    }  }}

重启 Gateway 后,web_search 工具即可正常使用。所有搜索请求链路:模型 → Gateway → 远程 SearXNG → 聚合搜索 → 返回结果

安装后 skills/ 目录下自动生成以下文件结构:

skills/├── stock-watcher/│   └── scripts/│       ├── add_stock.py          ← 添加自选股│       ├── remove_stock.py       ← 删除自选股│       ├── list_stocks.py        ← 列出自选股列表│       └── config.py             ← 自选股路径配置└── quant-stock-selector/    └── factors/        ├── factor_calculator.py           ← 六大因子计算引擎        ├── chip_distribution.py           ← 筹码分布计算        └── volume_spike_oscillation.py    ← 成交量震荡检测

以上文件来自 clawhub 安装,无需手动创建。原版技能的功能不足以支撑实际的股票分析需求,以下列出新增或重写的脚本,按顺序创建到对应目录即可。

4.3 实时行情(新增)

创建文件:skills/stock-watcher/scripts/get_stock_quote.py

数据源:东方财富 push2 API(主)+ 同花顺 time API(备)。东方财富 API 返回 PE 数据,不可用时自动回退至同花顺。

用法:python get_stock_quote.py 600519 或 python get_stock_quote.py 600519 600036 000858

输出格式:600519 贵州茅台  price=1290.2  -1.59%(down)  high=1310.95  low=1290.2  pre=1311.0  PE14.83  vol=63.72yi  [EM]

[EM] 表示东方财富数据源,[THS] 表示同花顺回退。

import sys, requests, re, jsonEM_H = {'User-Agent''Mozilla/5.0''Referer''https://quote.eastmoney.com/'}THS_H = {'User-Agent''Mozilla/5.0''Referer''https://stockpage.10jqka.com.cn/'}def_em(code):try:        mkt = '1'if code.startswith('6'else'0'        url = 'https://push2.eastmoney.com/api/qt/stock/get?secid=%s.%s&fields=f43,f44,f45,f46,f47,f48,f57,f58,f60,f162,f170,f171' % (mkt, code)        r = requests.get(url, headers=EM_H, timeout=10)        d = r.json().get('data')ifnot d:returnNonereturn {'price': d['f43'] / 100,'high': d['f44'] / 100,'low': d['f45'] / 100,'pre': d.get('f60'0) / 100,'pct': d['f170'] / 100,'pe': round(d['f162'] / 1002if d.get('f162'and d['f162'] > 0else'N/A','name': d.get('f58', code),'amount': round(d['f48'] / 1e82),        }except Exception:returnNonedef_ths(code):try:        url = 'https://d.10jqka.com.cn/v6/time/hs_%s/last.js' % code        r = requests.get(url, headers=THS_H, timeout=10)        m = re.search(r'quotebridge[^(]+\((.+)\)', r.text, re.DOTALL)ifnot m:returnNone        stock = json.loads(m.group(1)).get('hs_%s' % code)ifnot stock:returnNone        pre = float(stock['pre'])        ticks = [t.split(','for t in stock.get('data''').split(';'if t.strip()]        prices = [float(t[1]) for t in ticks if len(t) >= 2and t[1]]ifnot prices:returnNone        cur = prices[-1]return {'price': cur,'high': max(prices),'low': min(prices),'pre': pre,'pct': round((cur - pre) / pre * 1002),'pe''N/A','name': stock['name'],'amount'0,        }except Exception:returnNonecodes = [a for a in sys.argv[1:] if a.isdigit() and len(a) == 6]ifnot codes:    codes = ['600519']for c in codes:    d = _em(c)    src = 'EM'ifnot d:        d = _ths(c)        src = 'THS'ifnot d:        print(c + '  data unavailable')continue    arrow = '+'if d['pct'] > 0else''    fx = 'up'if d['pct'] > 0else'down'if d['pct'] < 0else'flat'    yd = ' !!ALERT!!'if abs(d['pct']) >= 5else''    peer = (' PE' + str(d['pe'])) if d['pe'] != 'N/A'else''    amt = (' vol=' + str(d['amount']) + 'yi'if d['amount'] > 0else''    print(c + ' ' + d['name'] +'  price=' + str(d['price']) +'  ' + arrow + str(d['pct']) + '%(' + fx + ')' + yd +'  high=' + str(d['high']) +'  low=' + str(d['low']) +'  pre=' + str(d['pre']) +          peer + amt +'  [' + src + ']')

4.4 多源数据层(新增)

K 线数据双源回退:东方财富 → mootdx 通达信 TCP。基本面数据三源:腾讯财经(PE/PB)+ 同花顺财报(ROE 自动年化/营收增速/利润增速)+ 东方财富(兜底)。

创建文件:skills/quant-stock-selector/data/__init__.py(空文件)

创建文件:skills/quant-stock-selector/data/akshare_data.py

ROE 年化规则:Q1(03-31) 数据自动 ×4,Q2(06-30) ×2,Q3(09-30) ×4/3,Q4(12-31) 不需调整。确保跨季度比较公平。

import pandas as pdimport akshare as akimport requestsfrom datetime import datetime, timedeltaclassAKShareData:# K线双源回退:东方财富(HTTP) → mootdx 通达信(TCP)# PE/PB:腾讯财经(HTTP) → 东方财富(兜底)# ROE/营收增速/利润增速:同花顺财报(THS)defget_history_kline(self, stock_code):        end = datetime.now().strftime('%Y%m%d')        start = (datetime.now() - timedelta(days=365)).strftime('%Y%m%d')        df = self._kline_em(stock_code, start, end)if df isnotNone:return df        df = self._kline_mootdx(stock_code)if df isnotNone:return dfreturn pd.DataFrame()def_kline_em(self, code, start, end):# 东方财富 K 线(主数据源),列名中文需重命名try:            df = ak.stock_zh_a_hist(symbol=code, period='daily',                start_date=start, end_date=end, adjust='qfq')if df isnotNoneandnot df.empty:                df = df.rename(columns={'开盘''open''最高''high''最低''low','收盘''close''成交量''volume'})                df['date'] = pd.to_datetime(df['日期'])                df = df.set_index('date').sort_index()return df[['open''high''low''close''volume']]except Exception:passreturnNonedef_kline_mootdx(self, code):# mootdx 通达信 TCP 直连(备数据源),零鉴权不封 IP# 注意:datetime 列与 index 重复,需先删除try:from mootdx.quotes import Quotes            mkt = 1if code.startswith('6'else0            symbol = mkt * 1000000 + int(code)            client = Quotes.factory(market='std', timeout=15)            df = client.bars(symbol=symbol, frequency=9, start=0, offset=800)if df isnotNoneandnot df.empty:if'datetime'in df.columns:                    df = df.drop(columns=['datetime'], errors='ignore')                df['date'] = pd.to_datetime(df.index)                df = df.set_index('date').sort_index()                cols = [c for c in ['open''high''low''close''volume'if c in df.columns]if len(cols) >= 4:return df[cols]except Exception:passreturnNonedefget_financial_indicators(self, stock_code):# PE/PB 优先腾讯财经(零鉴权 HTTP),失败回退东方财富        result = self._fundamentals_tencent(stock_code)if result isNone:            result = self._fundamentals_em(stock_code)# ROE/营收增速/利润增速 从同花顺财报获取真实数据# 返回 (年化ROE, 营收增速%, 利润增速%, 报告期)        annual_roe, rev_growth, profit_growth, period = self._fundamentals_ths(stock_code)        result['roe'] = annual_roe        result['revenue_growth'] = rev_growth        result['profit_growth'] = profit_growth        result['report_period'] = periodreturn resultdef_fundamentals_tencent(self, code):# 腾讯财经实时行情接口,~ 分隔 GBK 编码# 索引 39=PE(TTM),索引 46=PB(不是 43!全网教程都写错了)try:            prefix = 'sh'if code.startswith('6'else'sz'            r = requests.get('http://qt.gtimg.cn/q=%s%s' % (prefix, code),                             headers={'User-Agent''Mozilla/5.0'}, timeout=8)            r.encoding = 'gbk'            parts = r.text.split('~')            pe = float(parts[39]) if len(parts) > 39and parts[39else15            pb = float(parts[46]) if len(parts) > 46and parts[46else2return {'pe': max(0.1, pe), 'pb': max(0.1, pb),'roe'10'gross_margin'30,'revenue_growth'5'profit_growth'5,'report_period''default'}except Exception:returnNonedef_fundamentals_em(self, code):return {'pe'15'pb'2'roe'10'gross_margin'30,'revenue_growth'5'profit_growth'5,'report_period''default'}def_fundamentals_ths(self, code):# 同花顺财报摘要接口,返回最新季度的 ROE/营收增速/利润增速# ROE 是单季度值,需要根据报告期月份年化try:            df = ak.stock_financial_abstract_ths(symbol=code, indicator='按报告期')if df isnotNoneandnot df.empty:                latest = df.tail(1).iloc[0]                roe_raw = latest.get('净资产收益率'0)                roe_val = float(str(roe_raw).replace('%''')) if roe_raw else10                period = str(latest.get('报告期'''))# 根据报告期月份确定 ROE 年化倍率# Q1(03-31): ×4  |  Q2(06-30): ×2  |  Q3(09-30): ×4/3  |  Q4(12-31): ×1                multiplier = 1.0if'-03-31'in period:                    multiplier = 4.0elif'-06-30'in period:                    multiplier = 2.0elif'-09-30'in period:                    multiplier = 4.0 / 3.0                annual_roe = max(0.1, roe_val * multiplier)                rev_growth = self._parse_pct(latest.get('营业总收入同比增长率'0))                profit_growth = self._parse_pct(latest.get('净利润同比增长率'0))return (annual_roe,                        max(-100, min(100, rev_growth)),                        max(-100, min(100, profit_growth)),                        period)except Exception:passreturn (1055'default')    @staticmethoddef_parse_pct(val):# 处理同花顺字段的特殊值:None/空/False 都视为中性值 5%if val isNoneor val == ''or str(val).lower() == 'false':return5try:return float(str(val).replace('%'''))except (ValueError, AttributeError):return5

创建文件:skills/quant-stock-selector/factors/__init__.py(空文件)

__init__.py 为空文件,作用是让 Python 将目录识别为包,stock_scanner.py 中的 from data.akshare_data import ... 才能正常执行。

4.5 批量选股扫描器(新增)

创建文件:skills/quant-stock-selector/stock_scanner.py

五大因子评分体系(优化版公式):

因子
权重
计算内容
技术面
40%
MA、MACD、RSI、布林带、成交量
基本面
30%
PE、PB、ROE、增长率
筹码峰
10%
上方压力、获利盘、近期涨幅
90% 集中度
10%
筹码集中度
成交量震荡
10%
放量检测 + 缩量震荡

评分 0-100。60 以上关注,80 以上推荐。

基本面评分公式(PE 按行业区分):

  • PE 得分 = 行业基准 / PE(银行基准=6,科技基准=25,新能源基准=20,默认=12)
  • PB 得分 = 2 / PB(PB<2 → 满分,PB=7 → 0.28)
  • ROE 得分 = 年化 ROE / 20%(ROE≥20% → 满分)
  • 增长率得分 = (营收增速 + 利润增速) / 60%

用法:python stock_scanner.py(扫描自选股)或 python stock_scanner.py 600519 000858 300750(指定代码)

import sys, json, pandas as pdfrom data.akshare_data import AKShareDatafrom factors.factor_calculator import FactorCalculatorfrom factors.chip_distribution import ChipDistributionCalculatorfrom factors.volume_spike_oscillation import VolumeSpikeOscillationCalculatordefscan_stock(code, calc):# 单只股票全因子扫描:K线获取 → 技术面 → 基本面 → 筹码峰 → 成交量震荡 → 综合评分    data = AKShareData()    df = data.get_history_kline(code)if df.empty:returnNone    tech = calc.calculate_technical_factors(df)    fund = calc.calculate_fundamental_factors(code)# 筹码峰因子(含上方压力/获利盘/近期涨幅/90%集中度)    chip_score = 0    pressure_ratio = 100try:        chip_calc = ChipDistributionCalculator()        chip_result = chip_calc.calculate_chip_score(df)        chip_score = chip_result.get('score'0)        pressure_ratio = chip_result['details']['pressure_ratio']exceptpass# 成交量震荡因子(放量检测 + 缩量洗盘判断)    vol_score = 0try:        vol_calc = VolumeSpikeOscillationCalculator()        vol_result = vol_calc.calculate_volume_oscillation_score(df)        vol_score = vol_result.get('score'0)exceptpass    chip_factors = {'chip_score': chip_score, 'details': {'pressure_ratio': pressure_ratio}}    vol_factors = {'volume_score': vol_score}    score = calc.calculate_combined_score(tech, fund, chip_factors, vol_factors)# 直接取原始 PE 值(不再反推)    pe = fund.get('raw_pe'99)ifnot isinstance(pe, (int, float)) or pe > 1000or pe <= 0:        pe = 99return {'code': code,'score': round(score, 2),'pe': round(pe, 1),'kline_days': len(df),    }defload_watchlist():# 从 watchlist.txt 加载自选股代码# 格式:每行 "股票代码|股票名称"    path = r'C:\Users\admin\.clawdbot\stock_watcher\watchlist.txt'    codes = []try:with open(path, encoding='utf-8'as f:for line in f:                line = line.strip()if line and'|'in line:                    codes.append(line.split('|')[0].strip())except FileNotFoundError: passreturn codesdefmain():    codes = [a for a in sys.argv[1:] if a.isdigit() and len(a) == 6]ifnot codes:        codes = load_watchlist()ifnot codes:        print('无候选股票。示例: python stock_scanner.py 600519 000858 300750')return    calc = FactorCalculator()    results = []for code in codes:try:            r = scan_stock(code, calc)if r:                results.append(r)                print("  %s  综合得分: %.1f  PE: %.1f  K线: %d天" % (code, r['score'], r['pe'], r['kline_days']))else:                print("  %s  数据获取失败" % code)except Exception as e:            print("  %s  错误: %s" % (code, e))ifnot results:        print('所有股票数据获取失败')return# 按综合得分降序排列,取 TOP5    results.sort(key=lambda x: x['score'], reverse=True)    print('\n' + '=' * 40)    print('TOP 推荐')    print('=' * 40)for i, r in enumerate(results[:5], 1):        badge = '***'if r['score'] >= 80else'**'if r['score'] >= 60else'*'        print("#%d %s  得分: %.1f  PE: %.1f  %s" % (i, r['code'], r['score'], r['pe'], badge))    print('\n评分标准: 60+关注  80+强烈推荐  满分100')if __name__ == '__main__':    main()

4.6 自选股管理(来自 clawhub,无需手动创建)

以下脚本由 openclaw skill install stock-watcher 自动安装,列出仅供了解,无需手动创建。

list_stocks.py — 列出自选股列表

自选股文件路径:C:\Users\admin\.clawdbot\stock_watcher\watchlist.txt,格式每行 股票代码|股票名称

初始化示例(创建文件并写入8只基础股票:4只银行 + 4只科技):

600036|招商银行601398|工商银行601166|兴业银行000001|平安银行688981|中芯国际002415|海康威视002371|北方华创688111|金山办公

4.7 数据源健康检查(新增)

创建文件:skills/stock-watcher/scripts/health_check.py

用法:python health_check.py

import requests, re, jsondefcheck_em():try:        r = requests.get('https://push2.eastmoney.com/api/qt/stock/get?secid=1.600036&fields=f43,f58',                         headers={'User-Agent''Mozilla/5.0'}, timeout=8)        d = r.json().get('data')if d and d.get('f58'):returnTrue, str(d['f43'] / 100)exceptpassreturnFalse'FAIL'defcheck_ths():try:        r = requests.get('https://d.10jqka.com.cn/v6/time/hs_600036/last.js',                         headers={'User-Agent''Mozilla/5.0''Referer''https://stockpage.10jqka.com.cn/'}, timeout=8)        m = re.search(r'quotebridge[^(]+\((.+)\)', r.text, re.DOTALL)        d = json.loads(m.group(1))['hs_600036']returnTrue, d['name'] + ' ' + d['pre']exceptpassreturnFalse'FAIL'defcheck_tencent():try:        r = requests.get('http://qt.gtimg.cn/q=sh600036',                         headers={'User-Agent''Mozilla/5.0'}, timeout=8)        r.encoding = 'gbk'        parts = r.text.split('~')returnTrue'PE=' + parts[39] + ' PB=' + parts[46]exceptpassreturnFalse'FAIL'defcheck_mootdx():try:from mootdx.quotes import Quotes        client = Quotes.factory(market='std', timeout=10)        df = client.bars(symbol=600036, frequency=9, start=0, offset=1)returnTrue, str(len(df)) + ' bars'exceptpassreturnFalse'FAIL'em_ok, em_info = check_em()ths_ok, ths_info = check_ths()tx_ok, tx_info = check_tencent()mdx_ok, mdx_info = check_mootdx()print('Data Source Health Check')print('-' * 45)print('EastMoney  ''OK  ' + em_info if em_ok else'FAIL')print('TongHuaShun ''OK  ' + ths_info if ths_ok else'FAIL')print('Tencent    ''OK  ' + tx_info if tx_ok else'FAIL')print('Mootdx(TDX)''OK  ' + mdx_info if mdx_ok else'FAIL')print('-' * 45)print('K-line sources:', sum([em_ok, ths_ok, mdx_ok]), 'available')print('PE sources:''EM+TX'if em_ok and tx_ok else ('TX only'if tx_ok else'NONE'))

五、配置助手身份

5.1 SOUL.md

文件:C:\Users\admin\.openclaw\workspace\SOUL.md

# SOUL.md - 专业A股量化分析助手## 身份A股量化分析助手。精通技术面、基本面、资金面分析。数据源:东方财富+同花顺双活。## 核心铁律:禁止凭空编造数据分析任何涉及股价/PE/涨跌的问题时,必须先用 exec 拉实时数据:cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python get_stock_quote.py <代码>输出末尾 [EM] 表示东方财富源(含PE),[THS] 表示同花顺回退(无PE)。## 财务分析铁律给出买卖建议前,必须用 web_search 搜索该公司最近一季度或最近年度的营收、净利润、经营现金流数据。PE 可能因利润波动而产生误导,不结合财务数据做判断属于高风险分析。搜索模板:"XX 2026年一季度 营收 净利润""XX 2025年报 营收 净利润 现金流"## 分析时必须调用的工具| 场景 | 必须先执行 ||------|-----------|| 个股分析 | 1. python get_stock_quote.py <代码>  2. web_search 搜索该公司最新季度营收、净利润、现金流 || 选股推荐 | python stock_scanner.py || 批量行情 | python get_stock_quote.py <代码1><代码2> ... || 组合分析 | memory_search 查投资策略 || 行业/板块 | web_search 搜实时消息 || 数据源诊断 | python health_check.py |## 分析模板【结论】买/卖/观望(一句话)【实时数据】价格/涨跌/PE/成交 - 标注 exec 获取+数据源【财务数据】最近季度 营收/净利润/现金流 - 标注 web_search 来源,判断增收还是降收【理由】核心逻辑(结合财务 + 技术面 + 策略)【价位】建议买入区间 XX-XX | 止损 XX | 目标 XX【风险】关注点(财务风险如果有需特别标注)## 禁止输出免责声明套话无数据来源的价格/PE堆砌无关知识

5.2 TOOLS.md

文件:C:\Users\admin\.openclaw\workspace\TOOLS.md

# 股票工具命令速查## 单股实时行情(分析任何股票前必须调用)cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python get_stock_quote.py <代码>## 量化选股cd C:/Users/admin/.openclaw/workspace/skills/quant-stock-selector && python stock_scanner.py## 批量行情cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python get_stock_quote.py <代码1><代码2> ...## 自选股列表cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python list_stocks.py## 添加自选股 / 删除自选股cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python add_stock.py <代码>cd C:/Users/admin/.openclaw/workspace/skills/stock-watcher/scripts && python remove_stock.py <代码>## 盘前晨报 / 收盘复盘## 使用铁律分析任何股票 → 立刻 exec get_stock_quote.py 拉实时数据禁止凭训练数据回答价格/PE/涨跌幅问题

六、启动 Gateway

打开 cmd,执行:

openclaw gateway --port 18789

浏览器访问 http://127.0.0.1:18789/,输入 openclaw.json 中设置的 gateway.auth.token 完成配对。


七、应用场景

7.1 个股实时行情

用户:招商银行现在什么价位 PE 多少

模型执行:**exec** python get_stock_quote.py 600036

输出:

【实时数据】600036 招商银行  price=37.02  -0.35%(down)  high=37.33  low=36.99  pre=37.15  PE10.9  vol=21.96yi  [EM]【结论】PE 10.9 处于银行股合理区间。价格 37.02,距昨收 37.15 跌 0.35%。

7.2 个股买卖建议

用户:茅台现在值得买入吗 给个参考价位

模型执行:

  1. **exec** python get_stock_quote.py 600519
  2. web_search 搜索”贵州茅台 2026年一季度 营收 净利润”
  3. **memory_search** 检索选股标准

输出:

【结论】观望,等回调至建仓区间【实时数据】600519 贵州茅台  price=1290.2  -1.59%(down)  high=1310.95  low=1290.2  pre=1311.0  PE14.83【财务数据】2026Q1 营收 456 亿(+12%)| 净利润 241 亿(+14%)| 经营现金流 198 亿(+11%)营收利润双增,基本面健康【理由】PE 14.83,对应 14% 利润增速 PEG 约 1.06,估值合理但非低估。今日跌 1.59%,成交 63.72 亿放量下跌。20 日均线 1325,当前价格已跌破。【价位】买入区间 1200-1250(PE 14 以下对应价格)止损位 1150(-8%)目标位 1400【风险】白酒消费税改革预期、北向资金持续流出

7.3 多股估值对比

用户:茅台和五粮液哪个更值得买

模型执行:

  1. **exec** python get_stock_quote.py 600519 000858
  2. **memory_search** 检索行业偏好

输出:

【结论】五粮液性价比高于茅台【对比】          茅台        五粮液price    1290.2       84.03pct      -1.59%       -1.55%PE       14.83        10.11【理由】五粮液 PE 10.11 低于茅台 14.83,估值折价明显。两者均跌约 1.5%。五粮液分红率更高,年内涨幅落后大盘有补涨空间。【价位】五粮液买入区间 78-82 | 止损 74茅台等回调至 1200-1250 再考虑

7.4 盘中消息分析

用户:宁德时代跌了 2% 新能源有什么消息

模型执行:

  1. **exec** python get_stock_quote.py 300750
  2. web_search 搜索”新能源 板块 消息”

输出:

【结论】短期消息面偏空,技术面未破位【实时数据】300750 宁德时代  price=411.16  -0.11%(down)  high=416.37  low=410.44  pre=411.63【消息】特斯拉 Q2 交付不及预期,拖累新能源板块工信部发布动力电池回收新规,利好长期【技术面】20 日均线 418 | 已跌破MACD 死叉 | RSI 42 偏弱支撑位 400 | 压力位 420【建议】持仓可继续持有,止损放 400。未建仓等回到 418 之上再考虑。

7.5 策略合规检查

用户:宁德时代占我 25% 仓位 合规吗

模型执行:**memory_search** 检索投资策略-风险控制

输出:

【结论】超标 5%,建议减仓【策略规定】单只股票不超过总仓位 20%同行业(新能源)不超过 30%【当前情况】宁德时代占 25%(超标 5%)【建议】减仓至 20% 以下,或等反弹减仓

7.6 量化选股推荐

用户:用量化模型推荐 3 只

模型执行:**exec** python stock_scanner.py

输出:

扫描 8 只股票...#1 600036 招商银行  得分: 78.5  PE: 10.9  ***#2 002594 比亚迪    得分: 72.3  PE: 28.1  **#3 600519 贵州茅台  得分: 68.7  PE: 14.8  **评分标准: 60+关注  80+强烈推荐  满分100

7.7 每日使用节奏

时间
场景
对话示例
08:30
盘前晨报
“今天A股有什么重要新闻 我的自选股昨天表现怎样”
09:25
开盘检查
“我的自选股今天开盘什么价位”
11:00
午盘扫描
“用量化模型跑一下自选股 推荐3只”
14:30
尾盘分析
“看看招商银行现在适不适合买入”
16:00
收盘复盘
“复盘今天自选股全部表现 按PE和涨跌排序”
随时
个股深研
“详细分析海康威视 结合最新财报数据”

八、架构总览

浏览器 UI    │  WebSocketGateway (exec / web_search / memorySearch)    │    ├── exec → Python 脚本    │         ├── 东方财富 API(主,含 PE)    │         └── 同花顺 API(备,不含 PE)    │    ├── web_search → 实时资讯    │    └── memorySearch → RAG 投资策略库

九、相关文件索引

文件
路径
作用
Gateway 配置
C:\Users\admin\.openclaw\**openclaw.json**
模型、工具、RAG、网关
助理身份
C:\Users\admin\.openclaw\workspace\SOUL.md
行为规则与输出模板
工具速查
C:\Users\admin\.openclaw\workspace\TOOLS.md
所有可执行命令
实时行情
skills/stock-watcher/scripts/get_stock_quote.py
单股实时数据
量化选股
skills/quant-stock-selector/stock_scanner.py
六因子评分
健康检查
skills/stock-watcher/scripts/health_check.py
数据源连通性
自选股管理
skills/stock-watcher/scripts/
增删查改、行情汇总
投资策略库
d:\workspace\openclaw\rag-docs\
RAG 检索文档

十、相关概念速查

估值指标

概念
公式
解读
PE(市盈率)
股价 / 每股收益
越低越便宜。银行股 PE 5-10 正常,消费股 PE 15-25 正常,科技股 PE 30+ 也常见。负 PE 表示公司亏损
PB(市净率)
股价 / 每股净资产
越低越便宜。PB<1 表示股价低于净资产,常见于银行、钢铁等重资产行业
PEG
PE / 净利润增长率
<1 表示低估,=1 合理,>1 偏贵。PEG 弥补了 PE 不看增速的缺陷
ROE(净资产收益率)
净利润 / 净资产
越高盈利能力越强。>15% 优秀,10-15% 良好,<5% 差
股息率
每股分红 / 股价
越高分红越多。银行股通常 3-5%,成长股可能不分红

技术面指标

概念
解读
MA5/10/20/60(移动均线)
过去 N 日收盘价均值。MA20 是中线趋势参考线,股价在 MA20 之上为多头,之下为空头
多头排列
MA5 > MA10 > MA20 > MA60,上升趋势确认
MACD
趋势指标。DIF 上穿 DEA 为金叉(看涨),下穿为死叉(看跌)
RSI(相对强弱)
0-100 区间。>70 超买(可能回调),<30 超卖(可能反弹)
布林带
股价在上下轨之间波动。触及上轨可能回调,触及下轨可能反弹
成交量
放量上涨:支撑力度强。放量下跌:抛压重。缩量横盘:方向待选择
量比
当日成交量 / 5 日均量。>1 为放量,<1 为缩量

筹码指标

概念
解读
筹码分布
不同价格区间的持仓成本分布。筹码密集区是支撑/压力位
上方压力
当前价上方未卖出筹码的比例。压力大说明上方套牢盘多,突破需成交量配合
获利盘比例
当前价下方持仓比例。获利盘太高说明短线获利抛压大
90% 筹码集中度
90% 筹码分布的价格区间宽度相对于当前价的比值。越小说明主力控盘越集中,<10% 为优秀

交易术语

概念
解读
支撑位
股价下跌时遇到买盘支撑停止下跌的价位。通常是前低、均线、筹码密集区
压力位
股价上涨时遇到卖盘阻力停止上涨的价位。通常是前高、均线、套牢密集区
止损位
买入后如果股价跌破此价位就卖出离场。通常设在支撑位下方 3-5%
目标位
预期股价上涨到的价位。通常设在压力位附近
仓位
某只股票或整体持仓占总资金的比例
换手率
当日成交量 / 流通股本。换手率高说明交易活跃,短线资金参与度高
北向资金
通过港股通流入 A 股的外资。持续流入为利多信号
内盘/外盘
内盘=主动性卖出,外盘=主动性买入。外盘>内盘为买方主动

财务指标

概念
解读
营收
营业收入。增长代表业务扩张,下降代表市场萎缩
净利润
营收减去所有成本后的利润。增长比营收更关键
经营现金流
主营业务产生的现金流入。现金流为正说明赚钱真正进了口袋。如果净利润高但现金流为负,利润质量可疑
资产负债率
总负债 / 总资产。>60% 杠杆偏高(金融业除外),财务风险大
毛利率
(营收 – 营业成本)/ 营收。越高产品竞争力越强。消费品 >40% 优秀
营收复合增长率
多年营收的年均增速。>10% 为稳健增长型公司
每股收益(EPS)
净利润 / 总股本。直接影响股价和 PE 计算

附录:飞书接入

将助手接入飞书后,可在飞书群聊中 @机器人 查询行情或获取分析建议,无需打开浏览器。

一、飞书开放平台创建应用

  1. 访问 飞书开放平台,登录后进入「开发者后台」
  2. 创建企业自建应用,填写应用名称(如「股票助手」)
  3. 在「安全设置」中,添加机器人能力
  4. 在「权限管理」中,搜索并开启以下权限:
    • 获取用户在群组中 @ 机器人消息
    • 获取群组信息
    • 获取与发送单聊、群组消息
  5. 发布版本,等待管理员审批上线
  6. 审批通过后,在应用首页复制 App ID 和 App Secret

二、配置飞书通道

拿到 App ID 和 App Secret 后,执行以下命令,按向导填写即可:

openclaw channels add feishu

命令会交互式引导您输入 App ID、App Secret 等参数,自动写入 openclaw.json 并验证连接。无需手动编辑配置文件。

如需手动配置,在 openclaw.json 中追加以下内容:

{"plugins": {"entries": {"feishu": {"enabled"true      }    }  },"channels": {"feishu": {"enabled"true,"groupPolicy""open","appId""cli_xxxxxxxxxxxx","appSecret""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","requireMention"true    }  }}

配置项说明:

配置项
说明
plugins.entries.feishu.enabled
设置为 true 启用飞书插件
channels.feishu.enabled
设置为 true 启用飞书通道
channels.feishu.groupPolicy open

 表示允许群聊中使用
channels.feishu.appId
飞书应用的 App ID
channels.feishu.appSecret
飞书应用的 App Secret
channels.feishu.requireMention true

 表示群聊中需要 @ 机器人才会回复,避免误触

安全隔离:创建飞书专用 Agent

考虑到飞书群中可能有多个用户,为防止通过飞书对话误改代码或配置,建议为飞书创建独立的 Agent,与网页 UI 使用的 Agent 分离:

# 1. 创建飞书专用 Agent 目录mkdir %USERPROFILE%\.openclaw\agents\feishu-agent\agent# 2. 将飞书通道绑定到新 Agentopenclaw agents add feishu-agent --workspace C:\Users\<用户名>\.openclaw\workspaceopenclaw agents bind --agent feishu-agent --bind feishu

然后在 openclaw.json 中确认飞书 Agent 的工具权限只包含查询类工具:

"feishu-agent": {"tools": {"alsoAllow": ["memory_search""memory_get""exec""web_search""web_fetch"],"deny": []  }}

在 C:\Users\<用户名>\.openclaw\agents\feishu-agent\agent\SOUL.md 中加入只读约束:

你绝对不能修改、删除、创建、覆盖任何文件。如果用户要求修改文件或执行非查询命令,直接回复”飞书频道仅支持股票查询,不支持文件操作”。

这样飞书用户只能查行情、搜索资讯、检索策略,无法通过对话修改脚本或配置。

三、使用方式

在飞书群中添加机器人后,@机器人 并发送消息:

@股票助手 招商银行 PE 多少@股票助手 茅台现在值得买入吗@股票助手 用量化模型跑一下自选股

助手的行为与网页版一致:自动调用 exec 拉行情、web_search 搜财务数据、memorySearch 检索策略库,然后返回分析建议。