Install
openclaw skills install stock-kline-analysisGiven a stock name or code, auto-detect its market, fetch 6-month daily K-line, plot candlestick + MA/Bollinger/MACD/RSI/ATR with multi-timeframe confirmatio...
openclaw skills install stock-kline-analysisUse this skill when the user gives a stock name or code and wants K-line output and/or analysis, e.g.:
| Parameter | Default |
|---|---|
| Market | Auto-detect; only ask if unresolvable or genuinely ambiguous |
| K-line period | Daily (primary) + Weekly & Monthly for multi-timeframe |
| Time range | Last 6 months (today − 182 days) for daily; auto-extend for weekly/monthly |
| Price adjust | qfq for A-share; none for HK/US |
| Indicators | MA5/MA20/MA60, Bollinger Bands (20,2), MACD (12/26/9), RSI-14, ATR-14 |
| Language | Bilingual: Chinese label + English explanation |
User overrides these defaults at any time.
| Code pattern | Inferred market |
|---|---|
| 6-digit starting with 6 | A-share Shanghai |
| 6-digit starting with 0 or 3 | A-share Shenzhen |
| 5-digit starting with 0 | HK (prefix 0) |
| 4–5 chars, letters | US (NYSE/NASDAQ) |
| Name only | Search A-share first, then HK; disambiguate if needed |
If detection confidence is low, list top-2 candidates and ask once.
| Market | AkShare function |
|---|---|
| A-share daily | ak.stock_zh_a_hist(symbol, period="daily", start_date, end_date, adjust="qfq") |
| A-share real-time | ak.stock_zh_a_spot_em() (network may fail — wrap in try/except) |
| HK daily | ak.stock_hk_daily(symbol, adjust="qfq") |
| US daily | ak.stock_us_daily(symbol, adjust="qfq") |
| A-share symbol list | ak.stock_info_a_code_name() |
| Financial indicators | ak.stock_financial_analysis_indicator(symbol, start_year) — EPS, ROE, margins (use this; stock_a_lg_indicator does NOT exist) |
| Latest earnings summary | ak.stock_yjbb_em(date="YYYYMMDD") — EPS, revenue, net profit YoY, industry |
| Industry PE | ak.stock_industry_pe_ratio_cninfo(symbol) |
| Macro calendar | ak.news_economic_baidu() — date column is datetime.date objects; data may be stale (up to ~2 months behind current date) |
All implementation code lives in scripts/ next to this file. You can run a full analysis end-to-end with:
python .github/skills/stock-kline-analysis/scripts/run_analysis.py 000063
python .github/skills/stock-kline-analysis/scripts/run_analysis.py 贵州茅台
python .github/skills/stock-kline-analysis/scripts/run_analysis.py AAPL --out-dir /tmp/reports
| Script | Purpose |
|---|---|
scripts/run_analysis.py | CLI orchestrator — runs all steps end-to-end |
scripts/fetch_kline.py | Step 2 — multi-timeframe K-line fetch with retry/fallback |
scripts/indicators.py | Step 3 — compute MA/BB/MACD/RSI/ATR for all timeframes |
scripts/chart.py | Step 4 — 4-panel matplotlib chart (K线+BB | Vol | MACD | RSI-14) |
scripts/valuation.py | Step 5 — fetch EPS/revenue/ratios and compute PE/PB |
scripts/events.py | Step 7 — macro events with hardcoded fallback calendar |
Each script has a __main__ smoke-test (e.g. python fetch_kline.py 000063).
ak.stock_info_a_code_name() to confirm name.Completion check: one confirmed {code, name, market} tuple before fetching any data.
See scripts/fetch_kline.py — fetch_all_timeframes(code, adjust="qfq") returns (df_daily, df_weekly, df_monthly), all normalized.
Key implementation notes (do NOT get wrong):
stock_zh_a_hist returns 12 Chinese-named columns — always use explicit rename(col_map), never positional assignment.from scripts.fetch_kline import fetch_all_timeframes
df_daily, df_weekly, df_monthly = fetch_all_timeframes(code)
Fallback logic:
Completion check: len(df_daily) > 20 and all OHLCV columns present and non-null.
See scripts/indicators.py — add_indicators(df) and add_tf_indicators(df_weekly, df_monthly).
Critical notes:
bb_width = (upper − lower) / mid * 100 — result is a percentage (e.g. 12.7, not 0.127)..diff() twice on the same series.df.attrs["support"] / df.attrs["resistance"].from scripts.indicators import add_indicators, add_tf_indicators
df_daily = add_indicators(df_daily)
df_weekly, df_monthly = add_tf_indicators(df_weekly, df_monthly)
If fewer than 60 bars exist on daily, use all available and note the limitation. Bollinger Bands require minimum 20 bars.
Primary path — matplotlib (4-panel: K线+布林带 | 成交量 | MACD | RSI-14):
See scripts/chart.py — plot_kline(df, code, name, out_path, market_label, dpi) returns the saved path.
mplfinanceis NOT installed in the base environment.chart.pycallsmatplotlib.use("Agg")at module level — always import before pyplot.
from scripts.chart import plot_kline
chart_path = plot_kline(df_daily, code=code, name=name, market_label="A股",
out_path=f"{code}_kline.png")
Fallback (text table — only if matplotlib is also unavailable), latest 20 bars:
date close MA20 BB_up BB_low RSI14 ATR%
2026-02-10 15.38 14.90 16.20 13.60 58.3 1.4%
...
See scripts/valuation.py — fetch_valuation(code) and compute_pe_pb(result, last_close).
ak.stock_a_lg_indicatorandak.stock_a_indicator_lgdo not exist — usestock_yjbb_em+stock_financial_analysis_indicatorinstead (both implemented invaluation.py).
from scripts.valuation import fetch_valuation, compute_pe_pb
val = fetch_valuation(code)
val = compute_pe_pb(val, last_close=float(df_daily["close"].iloc[-1]))
# val keys: eps, revenue, revenue_yoy, net_profit, net_profit_yoy,
# book_value_per_share, roe, gross_margin, industry,
# report_date, fin_df, pe_ttm, pb
For HK/US: skip valuation section or note it as unavailable.
Report:
stock_a_lg_indicator; skip that sub-bullet and state the reason.Activated when user provides multiple symbols (e.g. "compare 600519 and 000858").
Single-symbol mode: compare to its own industry index if identifiable.
See scripts/events.py — fetch_events(lookback_days, lookahead_days, min_importance) returns a list of formatted strings.
news_economic_baidu()date column isdatetime.dateobjects — compare natively. Data lags 4–8 weeks;events.pyalways appends a hardcoded China macro calendar (PMI, Two Sessions, earnings windows) regardless of API success.
from scripts.events import fetch_events
event_lines = fetch_events() # returns list[str] ready to print
Overlay on analysis:
If event API is unavailable, note it and manually annotate the known calendar dates above.
Return in this exact order:
[Symbol Summary]
名称/代码: e.g. 贵州茅台 (600519) · A-Share Shanghai
分析区间: 2025-09-12 → 2026-03-12 (daily 6M, qfq-adjusted)
多周期确认: Weekly trend: Uptrend | Monthly trend: Consolidation
[K-Line Snapshot]
最新收盘: ¥1,580.00
1日涨跌: +1.2% (+18.80)
MA5 / MA20 / MA60: ¥1,572 / ¥1,540 / ¥1,490 (排列多头 Bullish stack)
布林带 Bollinger: Upper ¥1,640 | Mid ¥1,540 | Lower ¥1,440 (Width: 12.7%)
ATR-14 (波动幅): ¥22.4 / day (1.4% of price — moderate volatility)
20日区间: ¥1,420 – ¥1,610
成交量 vs 20日均: +35% (放量)
[Technical View — 技术面]
趋势 Trend: Daily Uptrend — MA5 > MA20 > MA60, price above all MAs
Weekly confirm: above weekly MA20 ✓
Monthly confirm: testing monthly MA20 resistance ⚠
动量 Momentum: 5D: +3.1% | 10D: +5.8% | 20D: +8.2% | Ann.Vol: 18%
MACD: MACD line above signal, histogram expanding → bullish momentum
RSI-14: 68 — approaching overbought; momentum still intact
布林挤压 BB Squeeze: Width 12.7% — expanding (breakout in progress, not overextended)
支撑 Support: ¥1,490 (MA60 + BB lower + prior swing low)
阻力 Resistance: ¥1,640 (BB upper) / ¥1,650 (6M high zone)
ATR止损参考: Trailing stop = last close − 1.5×ATR = ¥1,580 − ¥33.6 ≈ ¥1,546
[Valuation — 估值]
PE (TTM): 28x — 3-year 40th percentile (moderate)
PB: 8.2x
行业 PE 中位: 25x (white spirits industry) → slight premium to peers
[Relative Strength] (if multi-symbol mode)
Symbol 6M Return Vol Sharpe RSI ATR% Rank
600519 +22% 18% 1.22 68 1.4% 1st ← Leader
000858 +14% 21% 0.67 55 1.7% 2nd
[Event Overlay — 事件]
- 2026-03-15: NPC economic policy announcement (macro risk)
- 2026-04-30: Q1 earnings release window (re-rating trigger)
- No major gap days observed in 6M K-line window.
[Risk & Watchpoints — 风险]
- 多单失效: If price closes below MA20 (¥1,540) on volume → trend weakening
- 布林下轨破位: Price below BB lower (¥1,440) = volatility expansion to downside
- 超买风险: RSI near 70; daily overbought but weekly RSI 58 = room still exists
- ATR止损: Position sizing reference — 1 ATR = ¥22.4; adjust size accordingly
- 突破条件: Break above BB upper (¥1,640) + volume >+50% avg → momentum continuation