Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
agents365-ai avatar

Daisy Financial Research

  • 3 installs
  • 27 repo stars
  • Updated May 17, 2026
  • agents365-ai/daisy-financial-research

daisy-financial-research is a Claude Code skill that autonomously researches stocks, companies, and sectors, runs DCF valuation, and produces a sourced report.

About

A Claude Code skill that runs an autonomous financial-research workflow: plan, gather data via Tushare and web search, validate numbers, and produce a sourced report. It supports DCF valuation, financial comparison, catalyst analysis, and stock screening across A-share, Hong Kong, and US markets. An analyst uses it for stock or sector deep-dives. It never presents investment advice as certainty.

  • Autonomous stock, company, and sector research producing a sourced report
  • DCF valuation with sensitivity analysis plus screening across A-share, HK, and US markets
  • Iterative agent loop with scratchpad, numerical validation, and Tushare data

Daisy Financial Research by the numbers

  • 3 all-time installs (skills.sh)
  • Ranked #847 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
  • Data as of Jul 31, 2026 (Skillselion catalog sync)
At a glance

daisy-financial-research capabilities & compatibility

Requires a TUSHARE_TOKEN for any Tushare call; core analysis needs no other paid CLI.

Capabilities
financial research · stock valuation · stock screening · report generation
Use cases
research · data analysis · trading
Platforms
macOS · Linux · Windows
Pricing
Bring your own API key
From the docs

What daisy-financial-research says it does

Autonomous stock / company / sector research workflow — plan, gather data, validate numbers, produce a sourced report.
SKILL.md
Output concise, sourced analysis with caveats; never present investment advice as certainty.
SKILL.md
npx skills add https://github.com/agents365-ai/daisy-financial-research --skill daisy-financial-research

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3
repo stars27
Last updatedMay 17, 2026
Repositoryagents365-ai/daisy-financial-research

What it does

Run autonomous stock, sector, or DCF valuation research and produce a sourced financial report.

Who is it for?

Stock, company, and sector deep-dives and DCF valuation across A-share, HK, and US markets.

Skip if: Buy/sell order execution or personalized portfolio advice without risk and timeline context.

When should I use this skill?

The user asks for stock/company/sector deep-dive research, DCF or valuation, or stock screening.

What you get

A sourced financial report with DCF valuation, sensitivity analysis, and caveats.

  • Sourced financial research report
  • DCF valuation
  • Screening results

By the numbers

  • Encodes 8 Dexter-inspired research principles
  • Scripts use documented exit codes 0-5

Files

SKILL.mdMarkdownGitHub ↗

Daisy Financial Research

Autonomous stock / company / sector research workflow — plan, gather data, validate numbers, produce a sourced report. Inspired by the virattt/dexter design patterns (iterative agent loop, scratchpad, soft loop limits, numerical validation), packaged as a multi-platform skill.

Dexter’s key ideas:

1. Treat financial research as an iterative agent loop, not a one-shot answer. 2. First create a compact research plan, then execute data-gathering steps. 3. Use a scratchpad as the single source of truth for tool calls, results, assumptions, and partial conclusions. 4. Prefer high-level meta-queries to finance data tools, but fall back to specific interfaces when needed. 5. Use soft loop limits and repeat-query detection to avoid runaway tool use. 6. Validate numerical answers before finalizing. 7. For valuation, use an explicit DCF workflow with sensitivity analysis and sanity checks. 8. Output concise, sourced analysis with caveats; never present investment advice as certainty.

Python interpreter convention

Command examples in this skill use a bare python. Substitute it with whichever interpreter in the caller's environment has tushare, pandas, and requests installed — for example python3, ~/.hermes/venv/bin/python, ~\.hermes\venv\Scripts\python.exe, a conda env, uv run python, or a pyenv-managed version. The skill does not assume any specific install location and works on macOS, Linux, and Windows.

Agent-native CLI conventions

All scripts under scripts/ follow a uniform agent-native contract so an LLM agent can call them without parsing prose:

  • Output format auto-detection. When stdout is not a TTY (e.g. captured by subprocess.run), scripts emit a single JSON envelope on stdout. When stdout is a TTY, scripts emit the legacy human table. Override with --format json|table.
  • Stable success envelope: {"ok": true, "data": {...}, "meta": {"schema_version", "request_id", "latency_ms"}}.
  • Stable error envelope: {"ok": false, "error": {"code", "message", "retryable", "context"}, "meta": {...}}. Error messages stay on stderr in table mode.
  • Schema introspection. python <this-skill-dir>/scripts/<name>.py --schema returns parameter types, preset registries, upstream interfaces, and error codes as JSON. Agents should prefer --schema over parsing --help.
  • Dry-run preview. --dry-run echoes the request shape (would_call, would_write, filters, search_window) without making upstream API calls or writing files. Available on all mutating scripts.
  • Documented exit codes: 0 ok · 1 runtime · 2 auth · 3 validation · 4 no_data · 5 dependency.
  • Long-running progress. screen_hk_connect.py --with-momentum and financial_report.py emit NDJSON progress events on stderr (one JSON per line) so agents can detect liveness during multi-second runs.
  • Idempotency. Output files are date-stamped (YYYYMMDD_* or YYYYMMDD-HHMMSS_*); re-runs are deterministic and overwrite the same path.

Agents calling these scripts should:

1. Run --schema once per script to learn parameters/presets, instead of parsing --help. 2. Capture stdout as JSON (auto-detected when piped) and branch on data.ok. 3. Read error.code (not error.message) to decide retry vs. escalate. retryable: true + a no_data code typically means "loosen filters or extend --lookback-days".

Trigger conditions

Use this skill for:

  • “研究一下 / analyze / deep dive” on a stock, company, ETF, index, sector, or market theme
  • “DCF / intrinsic value / fair value / undervalued / overvalued / price target”
  • Financial statement trend analysis, valuation comparison, earnings/catalyst analysis
  • “Compare A vs B” for companies/sectors
  • “Why did this stock move?” or “what changed recently?”
  • Chinese A-share/HK/ETF queries where Tushare can provide data
  • Stock screening / watchlist construction across A-share or Hong Kong markets, including dividend, quality, valuation, growth, momentum, and risk filters

Do not use for:

  • Direct buy/sell/order execution
  • Personalized portfolio advice without explicit risk/timeline context
  • Unverifiable rumors
  • Questions that can be answered from stable definitions without external data

Mandatory workflow

Step 0. Update check (notify, don't pull) — first use per conversation

Throttle to one check per 24 hours per installation; never mutate the skill directory without explicit user consent.

1. If <this-skill-dir>/.last_update exists and is less than 24 hours old, skip this step entirely.

2. Otherwise, fetch the latest tag from upstream:

   git -C <this-skill-dir> ls-remote --tags origin 'v*' 2>/dev/null \
     | awk '{print $2}' | sed 's|refs/tags/||' \
     | sort -V | tail -1

3. Compare with this skill's metadata.version from the frontmatter. If the upstream tag is strictly newer (semver), tell the user one line and ask:

"A newer version of this skill is available: vX.Y.Z → vA.B.C. Want me to git pull?"

If they say yes, run git -C <this-skill-dir> pull --ff-only. Refresh .last_update either way so the prompt doesn't repeat for 24 hours.

4. If upstream is the same or older, refresh .last_update silently and continue.

5. On any failure (offline, not a git checkout — e.g. ClawHub-installed copy, read-only path, no permission), swallow the error silently and continue with the user's task. Do not mention the failure.

0. State scope and assumptions briefly

Infer obvious defaults instead of asking:

  • “recent” = last 60 calendar days / ~40 trading days
  • “financial trend” = last 8 quarters or last 5 annual periods when available
  • “valuation” = DCF + multiple sanity check
  • “A股” = Tushare first; US stocks = web/search or available market APIs first

Ask only if ambiguity changes the analysis materially.

1. Create a research scratchpad

For any non-trivial finance task, keep a local scratchpad file under:

./financial-research/scratchpad/

Use the helper script in this skill when useful:

python <this-skill-dir>/scripts/dexter_scratchpad.py init "original query"
python <this-skill-dir>/scripts/dexter_scratchpad.py add /path/to/file.jsonl tool_result tool_name='tushare.daily' args='...' result='...'

If not using the helper, still preserve internally:

  • original query
  • plan
  • each data source/tool/interface used
  • parameters/date ranges
  • raw key data and transformed metrics
  • errors/empty results/permission issues
  • assumptions and interim conclusions

1b. Pull cross-session decision memory (optional but recommended)

The scratchpad is per-task. For learning across sessions and tickers, use the decision-log helper to read past calls before the plan step and to record the new call after the final answer:

# At plan step: pull recent same-ticker analyses + cross-ticker lessons
python <this-skill-dir>/scripts/dexter_memory_log.py context --ticker 600519.SH

# After final answer: record a pending decision
python <this-skill-dir>/scripts/dexter_memory_log.py record \
  --ticker 600519.SH --rating Buy --date 20260502 \
  --decision "Thesis: PE22, ROE30, dividend stable, demand resilient. Plan: re-check at next earnings."

# Later, when realized returns are known: resolve the pending entry.
# Recommended path — let daisy fetch close prices and benchmark automatically:
python <this-skill-dir>/scripts/dexter_memory_log.py auto-resolve \
  --ticker 600519.SH --date 20260502 \
  --reflection "Held 17d, raw +4.8% vs CSI300 +3.6%, alpha +1.2%. Dividend+ROE thesis worked."

# Or if you've already computed the numbers yourself:
python <this-skill-dir>/scripts/dexter_memory_log.py resolve \
  --ticker 600519.SH --date 20260502 \
  --raw-return 4.8 --alpha-return 1.2 --holding-days 17 \
  --reflection "..."

auto-resolve is the recommended path. It fetches close[decision_date] and close[as_of_date] for the ticker, walks forward / backward to the nearest trading day, fetches the right benchmark by ticker suffix (CSI 300 for *.SH/SZ/BJ, HSI for *.HK, SPY for US tickers), computes raw + alpha + holding days, then runs the same atomic-rewrite resolve logic as the manual path. For HK names, when Tushare's HK index endpoints aren't available in the user's plan, the helper falls through to AKShare's stock_hk_index_daily_sina for HSI (requires pip install akshare).

Use dexter_memory_log.py compute-returns to inspect the numbers without persisting:

python <this-skill-dir>/scripts/dexter_memory_log.py compute-returns \
  --ticker 600519.SH --date 20260415
# → JSON envelope with raw_return_pct / alpha_return_pct / benchmark_return_pct / holding_days

To audit your own track record across many resolved entries, run backtest:

# Auto-derived window covering every resolved entry
python <this-skill-dir>/scripts/dexter_memory_log.py backtest

# Explicit window, Buy ratings only
python <this-skill-dir>/scripts/dexter_memory_log.py backtest \
  --from 20260101 --to 20260430 --rating Buy

Returns per-rating count / mean alpha / alpha_hit_rate / alpha_t_stat / annualized_alpha_pct, plus an overall block with the cumulative-alpha drawdown. The metric names make explicit that this is decision-level — daisy logs decisions, not a continuous portfolio NAV, so a textbook Sharpe ratio doesn't apply.

When writing the --reflection text, follow the standard 2–4-sentence shape in references/reflection-prompt.md so lessons stay short enough to be re-injected on future runs.

Storage: a single Markdown file at ./financial-research/memory/decision-log.md. Entries are separated by the HTML comment <!-- ENTRY_END -->. Tag lines start as [YYYY-MM-DD | ticker | rating | pending] and become [YYYY-MM-DD | ticker | rating | +X.X% | +Y.Y% | Nd] on resolve. record is idempotent on (date, ticker) — re-running with the same key skips silently. Ratings are constrained to Buy / Overweight / Hold / Underweight / Sell (see references/decision-schema.md for the full rating vocabulary and report markdown contract). Use dexter_memory_log.py stats for a hit-rate / mean-alpha summary.

2. Plan before tools

Write a 3–7 item plan. Keep it tactical:

  • identify company/ticker/universe
  • collect price/market data
  • collect financials/ratios/estimates/filings/news as relevant
  • compute metrics or valuation
  • validate numbers and sources
  • synthesize concise answer

3. Tool/data routing policy

The canonical per-market routing reference (A-share / HK / US, primary + documented fallback chain for each data type) lives at references/data-source-routing.md. Read it before the plan step; the rest of this section is the agent-facing summary.

For Chinese market / Tushare-accessible data:

  • Load/use the tushare skill if not already loaded.
  • Use TUSHARE_TOKEN from environment.
  • Prefer Tushare for: A-share daily prices, stock_basic, daily_basic, income, balancesheet, cashflow, fina_indicator, forecast/express, moneyflow, margin, concept/index/ETF/fund/macro data.
  • Use date format YYYYMMDD and stock code format like 000001.SZ, 600000.SH.

For Hong Kong stocks:

  • Use Tushare HK interfaces when available before falling back to web quote sites.
  • pro.hk_basic(ts_code='00005.HK', ...) and pro.hk_daily(ts_code='00005.HK', start_date='YYYYMMDD', end_date='YYYYMMDD') are known-good for HK tickers such as HSBC 00005.HK.
  • For the user's Hong Kong Stock Connect universe (港股通) preference when explicitly requested, use pro.hk_hold(trade_date='YYYYMMDD') as a first-pass universe identifier. It returns Southbound Stock Connect holdings with fields such as code,trade_date,ts_code,name,vol,ratio,exchange.
  • Use the bundled helper to export the latest 港股通 universe:
python <this-skill-dir>/scripts/hk_connect_universe.py --date YYYYMMDD --top 20
  • The helper searches backward when the requested date has no data and writes a CSV under ./financial-research/universes/YYYYMMDD_hk-connect-universe.csv.
  • For 港股通 flow/capital attention, optionally use pro.ggt_top10(...), pro.ggt_daily(...), and pro.moneyflow_hsgt(...).
  • Do not assume every advertised HK interface works in the installed Tushare version; in this environment pro.hk_daily_basic(...) returned 请指定正确的接口名, so treat it as unavailable unless re-tested. Fallback: when an HK valuation/fundamentals call fails on Tushare, use the bundled AKShare helper (no Tushare token, no auth):
# PE-TTM / PB / PS / PCF snapshot + Stock Connect eligibility
python <this-skill-dir>/scripts/akshare_hk_valuation.py valuation --ts-code 00005.HK

# Annual or quarterly fundamentals: ROE_YEARLY, EPS_TTM, BPS, ROA, leverage
python <this-skill-dir>/scripts/akshare_hk_valuation.py fundamentals --ts-code 00005.HK --period 年度 --limit 8

# Local-dict-only Chinese name lookup (no API call) — covers ~30 HK majors
python <this-skill-dir>/scripts/akshare_hk_valuation.py name --ts-code 00700.HK

Sources: AKShare stock_hk_valuation_comparison_em + stock_hk_security_profile_em for valuation; stock_financial_hk_analysis_indicator_em for fundamentals. Optional pip install akshare; the helper emits dependency_missing (exit=5) with a clear install hint if the package is absent.

  • For banks, DCF is usually the wrong primary valuation frame. Prefer RoTE/ROE, CET1, dividend payout/yield, NIM/NII guidance, credit cost, P/B or P/E, buyback capacity, and analyst target sanity checks.
  • Maintain the user's preferred finance-search stack: Tushare for structured market/financial data; Brave MCP as primary web search; Bailian WebSearch MCP as Chinese/China-market supplement; Python for calculations; browser only for dynamic/interactive pages. Do not include Asta/Semantic Scholar as a default route for finance evidence.
  • Session detail: see references/hsbc-hk-bank-research-test-20260429.md for the HSBC test workflow and pitfalls.

For web/current context:

  • Prefer Brave MCP search (brave_web_search / brave_local_search when available) for current news, filings, company pages, market context, source discovery, and broad English/global web coverage.
  • Use Bailian WebSearch MCP (bailian_web_search) as an optional/secondary search channel, especially for Chinese-language queries, China-market news, general encyclopedia-style facts, weather/news/current info, or when Brave results are sparse.
  • Cross-check important claims with at least two independent sources when the answer depends on recent news, market rumors, policy, regulation, or company events.
  • Use browser only when interaction, dynamic pages, paywall/login behavior, or visual inspection is needed.
  • Use terminal Python for calculations and tabulation.
  • If a dedicated finance API/tool is unavailable, be explicit about source limits.

Routing heuristics adapted from Dexter:

  • Price / market movement / news / insider activity → market data or web search.
  • Income statement / balance sheet / cash flow / ratios / estimates → financials.
  • SEC filing details → filings/web sources.
  • Broad market or macro news → web search.
  • Screening by financial criteria → Tushare screening script or Python filtering.
  • DCF / fair value → follow the DCF checklist below.
  • Revenue breakdown by product / region / segment → A-share has a structured source (scripts/segments.py → AKShare stock_zygc_em); for HK / US there is no free segment API, so read the annual report's "Segment Information" note via filings / Brave search.

When the user asks "why is the market down today" / "今天大盘为什么跌" / "what's moving the Hang Seng" — no specific ticker — go straight to broad web search (Brave MCP for English / global, Bailian MCP for Chinese-language sources) with a market-wide query like 美股下跌 原因 YYYY-MM-DD or S&P 500 selloff YYYY-MM-DD. Do not pick one large-cap ticker and search its news as a proxy; the intent is macro / sector-rotation / rates / geopolitical catalysts, not a company event.

4. Soft loop limits

Avoid repetitive tool calls:

  • Suggested max per tool/interface: 3 attempts per query.
  • If a query/interface fails twice, change strategy: different endpoint, broader/narrower date range, web fallback, or explain limitation.
  • Do not keep calling the same endpoint with near-identical parameters.
  • If data is incomplete, proceed with caveated analysis rather than fabricating.

When the scratchpad helper is active, you can ask it to flag both failure modes before a tool call:

python <this-skill-dir>/scripts/dexter_scratchpad.py can-call \
  <scratchpad.jsonl> tushare.daily 'ts_code=600519.SH start=20240101 end=20240630'
# → {allowed: true, warning: null|string, current_count: int, similar_to: [...]}

allowed is always true (this is a soft warning, not a block). React to a non-null warning: if current_count >= max_calls, change endpoint; if similar_to is non-empty, the tool is about to repeat a recent call — adjust the query or skip.

5. Numerical validation checklist

Before final answer, verify:

  • Date ranges and units are stated.
  • Currency/unit scale is consistent: yuan vs USD, CNY vs HKD, millions/billions.
  • Growth rates use comparable periods.
  • Per-share metrics use correct shares if computed manually.
  • Market cap / EV / price are from a stated date.
  • Any ranking/screening has universe and filters stated.
  • If data is missing or permission-limited, say so.

6. Final answer format

Use this concise structure:

1. Scope/Data: tickers, period, sources/interfaces used. 2. Key Findings: 3–6 bullets with numbers. 3. Evidence Table: compact table when comparative/numerical. 4. Interpretation: what the data suggests, not overclaimed. 5. Risks / Missing Data / Caveats. 6. If exported: file path.

Always include: “Data analysis only, not investment advice.” when discussing securities.

7. Report export policy

For substantial research tasks, generate a durable report under:

./financial-research/reports/

Preferred report stack:

1. Markdown source (.md) as the canonical editable record. 2. HTML report (.html) as the primary polished output. 3. PDF (.pdf) only when the user asks for a printable/shareable file, or when HTML-to-PDF tooling is available and stable.

Default behavior:

  • For quick answers: reply in chat only, optionally with scratchpad path.
  • For medium/deep research: create both .md and .html.
  • For formal deliverables: create .md, .html, and .pdf if possible.

Hermes back-compat note. Hermes installations that want to keep the legacy archive layout (~/.hermes/reports/financial-research/) can pass --out-dir ~/.hermes/reports/financial-research to any script — the script appends the matching subdir (reports/, watchlists/, universes/, scratchpad/) automatically.

Use the bundled report generator:

# medium/deep research: Markdown + HTML
python <this-skill-dir>/scripts/financial_report.py report.md --title "Company Research Report" --slug company-research

# formal deliverable: Markdown + HTML + PDF
python <this-skill-dir>/scripts/financial_report.py report.md --title "Company Research Report" --slug company-research --pdf

The generator copies the Markdown source and renders the report to:

./financial-research/reports/YYYYMMDD-HHMMSS_slug.{md,html,pdf}

Why HTML first:

  • Easier to render tables, charts, color-coded risks, source links, and sensitivity matrices.
  • More reliable than PDF generation in CLI environments.
  • Can be opened directly in a browser and later printed/exported to PDF.

PDF guidance:

  • Use PDF for sharing, archiving, printing, or sending to non-technical readers.
  • Prefer generating PDF from the HTML report using browser print, Playwright/Chromium, or another available HTML-to-PDF tool.
  • If PDF generation fails, keep the HTML and state the limitation rather than blocking the analysis.

Recommended report sections:

1. Executive summary / investment view. 2. Company and ticker scope. 3. Data sources and dates. 4. Price and valuation snapshot. When the report needs a technical-analysis layer, pick up to 8 complementary indicators from references/technical-indicator-cheatsheet.md and compute them via scripts/technical_indicators.py --ts-code <code> (auto-routes A-share/HK/US, applies a strict look-ahead-bias guard at --as-of). Skip TA entirely for banks / insurers — RoTE / CET1 / NIM are the right frame for those. 5. Financial performance and key drivers. For A-share names, pulling a revenue-by-segment / 主营构成 breakdown often surfaces concentration risk (one product line / one region) that the headline P&L hides:

   # All classifications (按产品 / 按地区 / 按行业), 4 most recent reports
   python <this-skill-dir>/scripts/segments.py --ts-code 600519.SH

   # Filter to one axis
   python <this-skill-dir>/scripts/segments.py --ts-code 000001.SZ --classification 按地区

HK / US names: no free segment API — read the latest annual report's "Segment Information" note (10-K for US, annual report "Operating Segments" section for HK) via the filings tool or Brave search. 6. News/catalyst review. For A-share / 港股 names, pull China-market context (涨跌停 risk, 北向资金, 板块 rotation, 监管 backdrop) using the system prompt in references/cn-market-analyst-prompts.md. 7. Bull/base/bear scenarios. For balanced single-company research, run the three-prompt debate template in references/debate-prompts.md (Bull → Bear → Synthesis) instead of writing scenarios free-form. The synthesis output's 5-tier rating maps directly onto dexter_memory_log.py record --rating. For position-sizing follow-up after the directional rating is set, optionally run references/risk-debate-prompts.md (Aggressive → Conservative → Neutral → Portfolio Manager). All synthesis outputs use the markdown shape and rating vocabulary documented in references/decision-schema.md. Either loop can be driven mechanically by scripts/debate_runner.py (subcommands init / next / synthesize, --type research|risk) — the script enforces the rotation rules and exit conditions so the agent only has to write each speaker's argument; full usage in the "Programmatic loop driver" sections of the two prompt files. 8. Risks and what would change the view. 9. Evidence tables and calculations. 10. Disclaimer: data analysis only, not investment advice.

8. Stock screening and watchlist workflow

Use this when the user asks “怎么选股”, “筛一批股票”, “A股/港股有什么值得关注”, or wants a watchlist rather than a single-company report.

Reusable files:

  • Presets/reference: references/stock-screening-presets.md
  • Screening report template: templates/screening_report.md
  • A-share screener: scripts/screen_a_share.py
  • Hong Kong Stock Connect screener: scripts/screen_hk_connect.py (only when 港股通 is explicitly requested)
  • Report generator: scripts/financial_report.py

Common commands:

# A-share dividend/quality watchlist + Markdown report source
python <this-skill-dir>/scripts/screen_a_share.py --preset a_dividend_quality --top 50 --report

# A-share value watchlist
python <this-skill-dir>/scripts/screen_a_share.py --preset a_value --top 50 --report

# 港股通 watchlist only when explicitly requested
python <this-skill-dir>/scripts/screen_hk_connect.py --top 50 --with-momentum

# Turn generated Markdown into the three-layer report stack
python <this-skill-dir>/scripts/financial_report.py report.md --title "Watchlist Report" --slug watchlist --pdf

Watchlist outputs go under:

./financial-research/watchlists/

Do not try to predict winners directly. Build a funnel:

1. Define universe

  • A-share: all listed stocks, index constituents, industry, market-cap band, dividend universe, or user-defined list.
  • Hong Kong: HK main board / H-share / Hang Seng indexes / Hong Kong Stock Connect (港股通, when explicitly requested) / user-defined HK tickers.
  • Exclude suspended, ST/*ST, newly listed names, illiquid names, or missing-data names unless the user explicitly wants them.

2. Choose screening style

  • Dividend/income: dividend yield, payout sustainability, ROE/ROTE, cash flow, debt, earnings stability.
  • Quality compounder: ROE/ROIC, gross/net margin, revenue/profit CAGR, low leverage, stable cash flow.
  • Value: low PE/PB/EV metrics, but require profitability and no obvious balance-sheet trap.
  • Growth: revenue/profit growth, margin trend, industry tailwind, valuation sanity.
  • Turnaround/event: earnings inflection, policy catalyst, restructuring, buyback, sector cycle.
  • Momentum: 1/3/6/12-month returns, relative strength, drawdown, volume confirmation.

3. Apply hard filters first

  • Liquidity: daily turnover or volume threshold.
  • Size: market cap threshold.
  • Financial health: positive earnings or operating cash flow, leverage not extreme.
  • Valuation: remove obvious extreme outliers unless justified.
  • Data completeness: remove rows with missing critical fields.

4. Score candidates

  • Build 4–6 factor scores rather than one magic metric.
  • Suggested default weights: quality 30%, valuation 25%, growth 20%, shareholder return 15%, momentum 10%.
  • For bank/insurance stocks, replace generic DCF/gross-margin metrics with ROE/ROTE, CET1/solvency, NIM/NII, credit cost, PB/PE, dividend and buyback capacity.

5. Produce a shortlist

  • Output 10–30 names for broad screens, then 3–8 names for deep-dive priority.
  • Include “why selected”, key metrics, red flags, and next verification step.
  • Never present the screen as a buy list; call it a research watchlist.

6. Deep-dive the finalists

  • For each finalist, run the single-company research workflow: data, news/catalysts, valuation, risks, scenario view.
  • Generate Markdown + HTML reports for substantial screens; add PDF for formal deliverables.

Suggested output tables:

  • Universe and filters table.
  • Top candidates table with ticker, name, industry, market cap, PE/PB, ROE/ROTE, dividend yield, growth, momentum, score, red flag.
  • Priority deep-dive list: top 3–8 names and why they deserve follow-up.
  • Exclusion notes: important names removed and why.

Screening caveats:

  • Tushare/HK data availability varies by interface and user permissions; document missing fields.
  • A cheap stock can be a value trap; require at least one quality or catalyst confirmation.
  • A high dividend can be unsafe; check payout ratio, earnings stability, balance sheet and cash flow.
  • Momentum screens need risk controls; do not confuse recent price strength with intrinsic value.

DCF valuation workflow

Use when the user asks for intrinsic/fair value, DCF, price target, undervalued/overvalued.

Progress checklist:

  • [ ] Gather financial data
  • [ ] Calculate FCF base and historical FCF growth
  • [ ] Estimate discount rate / WACC
  • [ ] Project FCF for years 1–5 + terminal value
  • [ ] Discount to present value and compute fair value per share
  • [ ] Run sensitivity analysis
  • [ ] Validate result
  • [ ] Present assumptions and caveats

Data to gather

  • 5 years annual cash flow: operating cash flow, capex, free cash flow
  • latest balance sheet: cash, investments, total debt, shares outstanding
  • financial metrics: market cap, enterprise value, margins, ROE/ROIC, debt/equity, revenue growth
  • analyst estimates if available
  • latest price
  • sector/industry for WACC sanity

Assumptions

  • FCF = operating cash flow - capex if not directly available
  • Growth: use 5-year FCF CAGR if stable, haircut by 10–20%; cap sustained base growth at 15% unless justified
  • For volatile FCF, triangulate with revenue growth, EPS estimates, and margin trend
  • WACC: default 8–10% for mature companies; higher for cyclicals/small caps/high leverage; lower for stable defensives
  • Terminal growth: default 2.5%; sensitivity 2.0%, 2.5%, 3.0%
  • Years 1–5 growth decay: base growth × 1.00, 0.95, 0.90, 0.85, 0.80

DCF validation

  • Terminal value should usually be 50–80% of EV for mature companies; >90% is fragile.
  • Calculated EV should be directionally plausible vs market EV; if >30–50% away, explain drivers.
  • Cross-check fair value against FCF/share × 15–25 or sector multiple.
  • Include a 3×3 sensitivity matrix: WACC base ±1% vs terminal growth 2.0/2.5/3.0%.

A-share quick-start patterns with Tushare

Environment check:

import os, tushare as ts
assert os.getenv('TUSHARE_TOKEN') or ts.get_token(), 'Missing TUSHARE_TOKEN'
pro = ts.pro_api(os.getenv('TUSHARE_TOKEN') or ts.get_token())

Common interfaces:

# Stock list
pro.stock_basic(list_status='L', fields='ts_code,symbol,name,area,industry,list_date')

# Daily price
pro.daily(ts_code='000001.SZ', start_date='20240101', end_date='20241231')

# Daily valuation/market metrics
pro.daily_basic(ts_code='000001.SZ', start_date='20240101', end_date='20241231', fields='ts_code,trade_date,close,pe,pb,total_mv,circ_mv,turnover_rate,volume_ratio')

# Financial indicators
pro.fina_indicator(ts_code='000001.SZ', period='20231231')

# Income / balance sheet / cash flow
pro.income(ts_code='000001.SZ', period='20231231')
pro.balancesheet(ts_code='000001.SZ', period='20231231')
pro.cashflow(ts_code='000001.SZ', period='20231231')

Quality bar

A good Dexter-style answer should be:

  • grounded: every important number has a source/interface/date
  • multi-step: shows it planned, gathered, computed, validated
  • honest: says what is missing or permission-limited
  • compact: useful to a finance reader, not a data dump
  • reproducible: scratchpad/export path if the analysis used substantial data

Related skills

FAQ

What data source does it use?

Tushare (requires TUSHARE_TOKEN) plus web search, with numerical validation before finalizing.

Does it give investment advice?

No; it outputs sourced analysis with caveats and never presents investment advice as certainty.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.