Goal: Trigger A-share and related market analysis in OpenClaw via natural language, and output compact text suitable for QQ/Telegram.
- Runtime environment: Mac + Python 3.9
- akshare path:
/Users/molezz/Library/Python/3.9/lib/python3.9/site-packages - Suggested Skill entry point:
python3 skills/akshare-stock/main.py --query "${USER_QUERY}"
1) Overall architecture design
Adopt a Router -> Service -> Analyzer -> Formatter four-layer structure for easy extension and maintenance.
A. Directory organization (suggested)
skills/akshare-stock/
SKILL.md
main.py # OpenClaw 调用入口
router.py # 意图识别 + 参数解析
schemas.py # 数据结构定义(dataclass)
formatter.py # QQ/Telegram 输出模板
services/
market_service.py # 大盘/个股行情、K线、分时、涨跌停、资金流
fundamental_service.py# 财务指标、财报、融资融券、龙虎榜
sector_service.py # 行业/概念板块、轮动、板块资金流
cross_service.py # 期货/期权、基金、可转债、港股/美股
analyzers/
kline_analyzer.py # 均线、振幅、涨跌幅、量比等
flow_analyzer.py # 主力净流入、连续性、强弱排序
rotation_analyzer.py # 板块轮动强度、持续性
adapters/
akshare_adapter.py # 封装 akshare 接口,隔离 API 变化
utils/
trading_calendar.py # 交易日判断
symbols.py # 指数/股票/板块别名映射
cache.py # 短缓存(30~120 秒)
B. Core flow
main.pyReceive the natural language query.router.pyOutput structured intent:intent + symbols + timeframe + metric + top_n。services/*Fetch raw data (only data retrieval and light cleaning).analyzers/*Perform indicator calculation and conclusion generation.formatter.pyCompress output for the chat platform (short sentences, sections, emoji, key values).
C. Key design points
- Intent priority: First identify the "task type", then parse the target and parameters to avoid misjudgment.
- Adapter layer isolation: If an akshare interface is renamed, only
adapters/akshare_adapter.py。 - Fault-tolerant fallback: When the real-time interface fails, fall back to the most recent trading day's data and mark it as "non-real-time".
- Caching strategy:
- Market/fund flow: 30~60 seconds
- Sector rankings: 60~120 seconds
- Financial reports/financials: cached for the day
- Message length control: A single message should be <= 1000 characters; if too long, automatically split into 2~3 messages.
2) Trigger word design (natural language routing)
It is recommended to use a hybrid approach of "keywords + regex + alias dictionary".
A. Intent classification (Intent)
INDEX_REALTIME: real-time marketKLINE_ANALYSIS: historical K-lineINTRADAY_ANALYSIS: intraday analysisLIMIT_STATS: limit-up/limit-down statisticsMONEY_FLOW: fund flowFUNDAMENTAL: financial indicators / financial reportsMARGIN_LHB: margin trading / Dragon-Tiger ListSECTOR_ANALYSIS: industry/concept/rotation/sector fundsDERIVATIVES: futures/optionsFUND_BOND: fund NAV / convertible bondsHK_US_MARKET: Hong Kong stocks / US stocks
B. Trigger word examples
- Real-time market:
A股大盘上证现在多少沪深300实时 - K-line:
贵州茅台近60日K线宁德时代周线比亚迪月线复权 - Intraday:
看下000001分时平安银行今天分时走势 - Limit-up/limit-down:
今日涨停统计跌停家数连板梯队 - Fund flow:
主力资金流入前十北向资金行业资金净流入 - Fundamentals:
茅台财务指标宁德时代最新季报ROE和毛利率 - Margin trading/Dragon-Tiger List:
中兴通讯融资融券今日龙虎榜 - Sectors:
行业板块涨幅榜概念轮动AI板块资金流 - Other markets:
IF主力合约300ETF期权基金净值可转债行情腾讯港股英伟达美股
C. Parameter extraction rules
- Stock code:
\b\d{6}\b(e.g.600519) - Date:
YYYYMMDD/YYYY-MM-DD/今天/昨日/近N日 - Period:
1m/5m/15m/30m/60m/day/week/month - Ranking:
前N(default 10) - Adjustment:
前复权/后复权/不复权
3) Implementation approach for each function
Below is the implementation framework of "function -> recommended data -> analysis output" (interfaces are subject to the current akshare version, and are actually uniformly encapsulated by the adapter layer).
3.1 Real-time market quotes (basic version already available, upgrade points)
- Data: Shanghai Composite, Shenzhen Component, ChiNext, CSI 300, SSE 50, STAR 50.
- Enhancements: Add turnover, amplitude, leading sectors, and Northbound capital's daily net inflow.
- Output:
指数点位 + 涨跌幅 + 市场情绪一句话。
3.2 Market analysis
- Historical K-line:
- Data: daily/weekly/monthly K-line (adjusted optional).
- Indicators: N-day change, 5/10/20-day moving averages, volume changes, volatility.
- Output: trend judgment (bullish/rangebound/weakening) + key levels (support/resistance).
- Intraday data:
- Data: minute-level quotes.
- Indicators: VWAP deviation, intraday high/low, afternoon capital return.
- Limit-up/limit-down statistics:
- Data: limit-up pool, limit-down pool, consecutive limit-up ladder.
- Indicators: number of limit-ups, failed limit-up rate, highest consecutive limit-ups, sentiment score.
- Capital flows:
- Data: individual stock/industry/market capital flows.
- Indicators: TopN main-force net inflows, consecutive net inflow days, capital concentration.
3.3 Fundamental analysis
- Individual stock financial indicators: ROE, gross margin, net margin, debt-to-asset ratio, operating cash flow.
- Financial report data: revenue YoY, net profit YoY, non-recurring net profit YoY, EPS.
- Margin trading and securities lending: margin financing balance, securities lending balance, daily changes, identify leverage preference.
- Dragon-Tiger List: reason for listing, net amount of top five buy/sell seats, hot money activity.
- Output style:
核心指标摘要 + 同比/环比 + 风险提示。
3.4 Sector analysis
- Industry sector gainers and losers: industry gain/loss ranking, turnover, number of advancers.
- Concept sector rotation: strength over the past 5 days, sustainability, intraday switching speed.
- Sector capital flows: industry/concept net inflow ranking + leading stocks.
- Output:
强势板块Top3 + 轮动结论 + 次日观察点。
3.5 Others (cross-market)
- Futures/options: main contract price, change, position changes; option PCR (if available).
- Fund NAV: open-end fund NAV, valuation deviation, past one-week return.
- Convertible bonds: price, premium rate, underlying stock linkage, turnover.
- Hong Kong stocks/US stocks: real-time quotes, past 5-day performance, linkage hints with A-shares.
4) Code example framework (skeleton)
Note: the following is a minimal framework that can be directly implemented, without complete business details.
main.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
from router import parse_query
from services.market_service import MarketService
from services.fundamental_service import FundamentalService
from services.sector_service import SectorService
from services.cross_service import CrossService
from formatter import render_output
def dispatch(intent_obj):
intent = intent_obj.intent
if intent in {"INDEX_REALTIME", "KLINE_ANALYSIS", "INTRADAY_ANALYSIS", "LIMIT_STATS", "MONEY_FLOW"}:
data = MarketService().handle(intent_obj)
elif intent in {"FUNDAMENTAL", "MARGIN_LHB"}:
data = FundamentalService().handle(intent_obj)
elif intent == "SECTOR_ANALYSIS":
data = SectorService().handle(intent_obj)
elif intent in {"DERIVATIVES", "FUND_BOND", "HK_US_MARKET"}:
data = CrossService().handle(intent_obj)
else:
data = {"ok": False, "error": "未识别请求,请补充标的或时间范围"}
return data
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--query", required=True, help="自然语言请求")
parser.add_argument("--platform", default="qq", choices=["qq", "telegram"])
args = parser.parse_args()
intent_obj = parse_query(args.query)
result = dispatch(intent_obj)
text = render_output(intent_obj, result, platform=args.platform)
print(text)
if __name__ == "__main__":
main()
router.py
from dataclasses import dataclass, field
import re
@dataclass
class IntentObj:
intent: str
symbols: list = field(default_factory=list)
timeframe: str = "day"
days: int = 60
top_n: int = 10
date: str = ""
raw_query: str = ""
def parse_query(query: str) -> IntentObj:
q = query.strip()
obj = IntentObj(intent="INDEX_REALTIME", raw_query=q)
# 1) intent
if any(k in q for k in ["K线", "日线", "周线", "月线"]):
obj.intent = "KLINE_ANALYSIS"
elif "分时" in q:
obj.intent = "INTRADAY_ANALYSIS"
elif any(k in q for k in ["涨停", "跌停", "连板"]):
obj.intent = "LIMIT_STATS"
elif "资金" in q:
obj.intent = "MONEY_FLOW"
elif any(k in q for k in ["财务", "财报", "ROE", "毛利率"]):
obj.intent = "FUNDAMENTAL"
elif any(k in q for k in ["融资融券", "龙虎榜"]):
obj.intent = "MARGIN_LHB"
elif any(k in q for k in ["板块", "行业", "概念", "轮动"]):
obj.intent = "SECTOR_ANALYSIS"
elif any(k in q for k in ["期货", "期权"]):
obj.intent = "DERIVATIVES"
elif any(k in q for k in ["基金", "净值", "可转债"]):
obj.intent = "FUND_BOND"
elif any(k in q for k in ["港股", "美股", "纳斯达克", "道琼斯"]):
obj.intent = "HK_US_MARKET"
# 2) symbol
code_hits = re.findall(r"\b\d{6}\b", q)
if code_hits:
obj.symbols = code_hits
# 3) topN
m = re.search(r"前\s*(\d+)", q)
if m:
obj.top_n = int(m.group(1))
return obj
adapters/akshare_adapter.py
import akshare as ak
class AkAdapter:
def index_spot(self):
return ak.stock_zh_index_spot_sina()
def stock_kline(self, symbol: str, period: str = "daily", start_date: str = "", end_date: str = "", adjust: str = "qfq"):
# 实际参数与函数名按本地 akshare 版本适配
return ak.stock_zh_a_hist(symbol=symbol, period=period, start_date=start_date, end_date=end_date, adjust=adjust)
def stock_intraday(self, symbol: str, period: str = "1"):
return ak.stock_zh_a_minute(symbol=symbol, period=period)
def limit_up_pool(self, date: str):
return ak.stock_zt_pool_em(date=date)
def limit_down_pool(self, date: str):
return ak.stock_dt_pool_em(date=date)
formatter.py
from datetime import datetime
def render_output(intent_obj, result: dict, platform: str = "qq") -> str:
ts = datetime.now().strftime("%Y-%m-%d %H:%M")
if not result.get("ok", False):
return f"⚠️ 请求失败\n原因: {result.get('error', '未知错误')}\n时间: {ts}"
title = result.get("title", "A股分析")
lines = result.get("lines", [])
tips = result.get("tips", "")
# QQ/Telegram 友好输出:短行 + 分段 + 关键数字优先
text = [f"📊 {title}", f"🕒 {ts}", ""]
text.extend(lines[:15])
if tips:
text.extend(["", f"💡 {tips}"])
text.append("\n数据源: akshare")
# 长度保护
merged = "\n".join(text)
return merged[:1000]
Output template suggestion (QQ/Telegram)
It is recommended to unify into three sections:结论 -> 关键数据 -> 风险提示。
Example:
📊 A股午盘情绪
🕒 2026-02-18 11:31
- 上证指数 3210.35(+0.62%)
- 两市成交额 6821 亿,较昨日同期 +8.4%
- 涨停 52 / 跌停 7,连板高度 4
- 主力净流入前三:证券、AI算力、汽车零部件
💡 结论:指数偏强,情绪修复中;但午后关注高位分歧。
数据源: akshare
Implementation order (suggested)
- Keep the existing real-time market overview, abstract it into
MarketService.index_realtime()。 - First complete the four core pieces of market analysis: K-line/intraday/limit-up and limit-down/capital flow.
- Then add fundamental and sector analysis (medium-frequency requests, high caching benefit).
- Finally integrate futures/options/funds/convertible bonds/Hong Kong and US stocks.
- For each module, first do "readable text output", then gradually increase indicator depth.
This design ensures you can get something usable quickly first, then gradually enhance it, without piling up too many interfaces at once and causing maintenance difficulties.