name: elab-futu-research invocation: user description: Archive public profiles from Futu (q.futunn.com) or Tiger (laohu8.com): save visible dynamics and posts, columns (Futu only), raw evidence and media (Futu only), enrich time-frozen claims with market context, compare trading behavior across regimes, and generate auditable blogger research. Dispatcher routes by URL domain — full laohu8.com URL → Tiger; numeric UID or q.futunn.com URL → Futu. Use when a user provides one or more q.futunn.com or laohu8.com profile URLs or asks to crawl, save, review, compare, or analyze Futu or Tiger bloggers, posts, trading style, discipline, tone, or historical calls.
Elab Futu Research
Turn one or more public profile URLs — Futu (q.futunn.com) or Tiger (laohu8.com) — into a resumable archive and an evidence-bounded research report. Make the default experience one-shot: accept the URL, choose safe defaults, run the workflow, and return the report plus audit status.
Version: 1.3.1 · Last updated: 2026-07-23
Startup alignment (required)
Before running any capture or producing any deliverable, align on the following items. If the user's initial message already answers an item, do not re-ask it — simply acknowledge it in the summary line below.
Collect only what is still missing, in one message (not one question per item):
- Research target — which profile URL(s)? If the user has not provided a URL, ask for it: this skill requires a
q.futunn.com/profile/<id>orlaohu8.com/personal/<id>/URL. Do not guess or substitute example UIDs. Supports q.futunn.com (Futu) and laohu8.com (Tiger). Pass a full laohu8.com URL for Tiger; a numeric UID defaults to Futu. - Time range — required explicit choice; no silent default to full history. Ask the user to pick one of:
- 近半年 (
--sincesix months ago) - 近 1 年
- 近 18 个月
- 全量历史 Do not start full-history capture without the user explicitly choosing it. High-volume bloggers (thousands of posts) can take a very long time to capture in full (example: a blogger with 10 000+ posts may require hours of run time and produce hundreds of MB of output); recommend a bounded window for first runs.
- 近半年 (
- 探量给预期 — before launching any full-history or unknown-volume capture, run
doctor --profile <url>(or fetch the first list page) first to obtain the post count signal (sample_post_count; the profile page also shows dynamic/column totals). Report a concrete estimate to the user — e.g., "这个博主约 N 帖,全量约 X 小时/MB,近 1 年约 Y 帖" — and let the user confirm the window before proceeding. This step is mandatory before full-history or unknown-volume captures; it may be skipped only when the user has already selected and confirmed a bounded time window. - Deliverables — one or more of: ① 完整归档 ② 研究报告 ③ 多博主对比 ④ 规则卡 (multiple allowed).
- Other constraints — skip media, custom output directory, redaction needs, or anything else that changes the run.
Once all items are known, reply with one summary line before issuing any command:
博主 <X> · 范围 <Y> · 交付 <Z> · 输出目录 <W> · elab-futu-research by 杰尼马(EdgeLab)
<Y> must be the user-confirmed specific window (e.g., "近 1 年(2025-07-23 起)") — not "全量历史" without explicit user confirmation.
Then proceed with the workflow.
Default behavior
- Require only a profile URL or numeric UID. The dispatcher routes by domain: a full
laohu8.comURL → Tiger; a numeric UID orq.futunn.comURL → Futu. - If no date is supplied, capture all content still visible at run time.
- Capture all expected streams per platform:
- Futu: dynamics/all (
type=301) and columns (type=302) - Tiger: dynamics only (no columns concept)
- Futu: dynamics/all (
- Preserve original posts and reposts. Exclude reposts from ability scoring by default, but keep them searchable.
- Download public post media in three modes:
all(default),none(skip),evidence(only posts matching built-in order/fill/position evidence keywords — recommended for order-screenshot bloggers).--skip-mediais retained as an alias for--media none. For Tiger profiles,--mediais treated asnoneregardless of the flag; media download is not yet supported. - Write to
./futu-research-output/unless the user names another directory. - Resume safely from cached pages/details/media. Never delete raw evidence; rebuild derived files atomically.
- Use conservative request rates. Stop and report interface drift, login, CAPTCHA, or access denial; do not bypass access controls.
- Follow the Startup alignment section above before starting any capture.
Fast path
Locate the script before running. The path depends on how the skill was installed:
| Installation | Script path |
|---|---|
| Claude Code | ~/.claude/skills/elab-futu-research/scripts/futu_research.py |
| Codex | ~/.codex/skills/elab-futu-research/scripts/futu_research.py |
| Repo clone | elab-futu-research/scripts/futu_research.py (run from repo root) |
| Other / unknown | clone the repo, then use elab-futu-research/scripts/futu_research.py from the repo root |
If you are unsure which path applies, run the following to auto-detect:
python3 ~/.claude/skills/elab-futu-research/scripts/futu_research.py --help 2>/dev/null \
|| python3 ~/.codex/skills/elab-futu-research/scripts/futu_research.py --help 2>/dev/null \
|| python3 elab-futu-research/scripts/futu_research.py --help
All references/ paths are relative to the skill installation directory, not the --output output directory.
All commands below use the relative form scripts/futu_research.py; substitute the full prefix from the table above when running outside the skill directory.
python3 scripts/futu_research.py run \
--profile "https://q.futunn.com/profile/<uid>" \
--output "./futu-research-output"
For Tiger (laohu8.com) profiles:
python3 scripts/futu_research.py run \
--profile "https://www.laohu8.com/personal/<uid>/" \
--output "./futu-research-output"
run is a machine-only exploratory pipeline: it executes all steps in sequence and marks every output as exploratory. Human claim review (step 3) can be performed after run completes; re-run market and report afterwards to incorporate reviewed decisions. To enforce the claim-freeze gate strictly — no outcome data visible before claims are frozen — run the steps individually in the order documented below. Default: use run for the full automatic pipeline; outputs are labeled exploratory and claim review can follow. Switch to step-by-step mode only when the user explicitly requires "no outcome data visible before claims are frozen" (strict no-time-travel).
For multiple bloggers, repeat --profile. Optional --since YYYY-MM-DD and --until YYYY-MM-DD limit the archive. Use --media none (or legacy alias --skip-media) to skip media; --media evidence limits downloads to posts matching order-evidence keywords.
Platform routing: the dispatcher identifies the platform by URL domain. Pass a full laohu8.com URL to target Tiger. Numeric-only UIDs are routed to Futu because both platforms use numeric UIDs and they cannot be distinguished without a domain.
Tiger current limits: media download is not supported (--media has no effect); no column stream; repost detection is not yet implemented (posts are marked is_repost=False).
Run the environment and endpoint check first when the interface may have changed:
python3 scripts/futu_research.py doctor \
--profile "https://q.futunn.com/profile/<uid>"
--profile is optional for doctor: without it, only local environment checks run and the overall status is reported as PARTIAL (endpoint checks skipped).
Workflow
All steps use the same <dir> (default ./futu-research-output); keep it unchanged for the entire session.
1. Capture and normalize
Run archive, or use run for the full deterministic pipeline.
python3 scripts/futu_research.py archive --profile "<profile-url>" --output "<dir>"
Do not call an archive complete unless qa/crawl_audit.json confirms:
- all expected streams were attempted (Futu: dynamics + columns; Tiger: dynamics only);
- each requested stream reached
has_more=0, or crossed the requested start boundary; - all retained feed IDs have cached detail responses or appear in an explicit failure list;
- normalized IDs are unique;
- media failures are listed rather than silently dropped.
“All history” means all public content returned by Futu at capture time. It cannot include deleted, private, region-restricted, or otherwise unavailable content.
2. Create claim candidates
prepare creates deterministic, reviewable candidates. Treat them as prelabels, never final truth.
python3 scripts/futu_research.py prepare --output "<dir>"
Use these evidence levels:
A: order/fill/cost/position/P&L evidence verified from an image or primary record.B: explicit first-person trade action in text.C: market or security opinion without verified action.D: mention, repost, joke, question, or attention only.
Never infer a holding from C or D. The script never assigns A automatically.
Trailing tag noise reduction: if a post ends with ≥3 consecutive $symbol$ tag blocks and a symbol does not appear in the body text, the script downgrades those mentions to D and excludes them from directional claim scoring.
3. Review before outcomes
Read analysis/candidates.jsonl, the cited post text, and relevant images. Write reviewed decisions to analysis/claims.reviewed.jsonl following the Reviewed claim section in references/data-schema.md. Required fields: claim_id, feed_id, evidence_level, evidence_span, direction, published_at, reviewer, reviewed_at.
Freeze each claim before fetching or inspecting forward returns. Record:
- quoted evidence span;
- symbol and direction;
- action, horizon, conditions, invalidation, and risk rule;
- evidence level and whether image evidence was actually inspected;
- confidence and unresolved ambiguity.
If using OCR or vision, preserve the source image path and extracted text. Do not upgrade to A from a filename, thumbnail, or unverified OCR alone.
4. Add time-frozen market context
python3 scripts/futu_research.py market --output "<dir>"
The context cutoff is the last completed daily bar known at post time. Evaluation begins at the next tradable daily open. Keep symbol mappings in analysis/symbol_overrides.json; unresolved mappings remain unresolved.
Use 1/5/20/60-session forward paths, MFE (Maximum Favorable Excursion), MAE (Maximum Adverse Excursion), and benchmark-relative returns when data are available; MFE and MAE are direction-aware (see references/analysis-method-v1.md). Do not fabricate option returns from an underlying chart.
5. Build reports
python3 scripts/futu_research.py report --output "<dir>"
python3 scripts/futu_research.py audit --output "<dir>"
Read references/analysis-method-v1.md before writing final judgments. Produce:
- evidence coverage and limitations;
- capability matrix, not one total leaderboard;
- market-regime episodes and before/after changes;
- trading style, strategy completeness, discipline, and risk handling;
- counterexamples and confidence;
- transferable rule cards for the user.
Do not diagnose personality or mental illness. Do not turn the report into a follow-trading recommendation. Separate author claims, observed public execution evidence, market outcomes, and inference.
If qa/adversarial_audit.json top-level status is FAIL, do not deliver any final research conclusions; report the missing coverage areas to the user and stop. If status is WARN, the report may be delivered but must annotate every identified gap.
Output contract
The run directory contains:
raw/list/<uid>/{all,columns}/page_*.json
raw/details/<uid>/<feed_id>.json
raw/feed_index.json
raw/media_manifest.json
media/<uid>/<feed_id>/*
archive/posts.jsonl
archive/posts.csv
archive/monthly/*.md
analysis/candidates.jsonl
analysis/prepare_summary.json
analysis/review_guide.md
analysis/claims.reviewed.jsonl
analysis/episodes.jsonl
analysis/market/claims_market.jsonl
analysis/market/market_manifest.json
analysis/market/raw/*.json
analysis/market/*.csv
archive/by-author/<author-name>_<uid>.md
archive/by-author/index.md
reports/profile.md
reports/capability_matrix.md
reports/rule_cards.md
reports/report_manifest.json
qa/crawl_audit.json
qa/adversarial_audit.json
manifest.json
Some later files appear only after their corresponding step. Preserve raw/ as immutable evidence.
archive/by-author/ is a readable per-blogger split of the combined archive, produced by report (or on demand via export-authors). Each author gets one markdown file named with their display name, posts newest-first with full text and links; index.md lists all authors by post count. Use this to browse one blogger's content by name instead of digging through numeric-UID raw/ folders.
Reporting rules
- Lead with one actionable conclusion, then evidence and caveats.
- Label machine-only output as
exploratory. - A favorable sample is not stable alpha.
- With fewer than 20 eligible claims per author/window, report descriptive results only.
- For larger samples, use uncertainty intervals and correct multiple comparisons as described in the method.
- Explicitly distinguish mention, opinion, claimed action, verified position evidence, and account-level return.
- Include failures and missingness in the report.
References
Read only what the task requires:
- Capture, pagination, fallback, and completeness:
references/capture-and-runtime.md - Market-data adapters, CSV fallback, and symbol mapping:
references/market-data.md - Claim/episode/profile methodology and statistics:
references/analysis-method-v1.md - File and record schemas:
references/data-schema.md - Privacy, publishing, and compliance:
references/privacy-and-compliance.md
Safety boundary
Use only public content or content the user is authorized to access. Never export browser cookies, tokens, private messages, follower-only data, or unrelated personal data. Respect site terms, robots guidance, rate limits, and applicable law. If the API or page requires new authentication or anti-bot circumvention, stop and explain the legitimate next step.