All skills
tradermonty avatar

/trading-skills-navigator

@c6bb7d2

Recommend the right trading workflow, skillset, API profile, and setup path from a natural-language goal. Use this as the on-ramp when a user expresses a trading or investing goal and needs to know which skill/workflow to use, where to start, or whether something works without paid API keys — e.g. "where do I start", "which skill should I use", "I want to swing trade only when the market is favorable", "what works without API keys", "どれを使えばいい", "API キー無しで 使えるものは". Routes and explains only; it never executes trades or auto-runs other skills, and it is honest when no workflow has shipped yet.

Use this Skill: https://skilld.dev/gh/tradermonty/claude-trading-skills/trading-skills-navigator

This session only. Nothing lands on disk.

referencesintent_routing.md

≈3.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Intent Routing Rubric

scripts/recommend.py is the single source of truth for routing. This document explains the engine; assets/intent_benchmark_v1.json is the explicitly labeled 211-case EN/JA gold corpus, and scripts/intent_benchmark.py is its fail-closed evaluator.

Engine overview

  1. Normalize the query (lowercase, collapse whitespace). Bilingual — every persona carries both English and Japanese trigger terms, so the recommender routes a JA goal (e.g. 「配当株を探したい」「APIキー無しで使えるもの」「スイング トレードをしたい」) the same as its English equivalent. (.lower() leaves Japanese unchanged; mixed-case "API" folds to "api", which the JA no-API terms account for.)
  2. Walk the ordered persona table. The first matching persona wins.
  3. A persona either names a primary workflow (+ optional secondary), or an gap_category (honest gap — no workflow shipped).
  4. Apply constraint filters (--no-api, --time-budget, --experience).
  5. Emit a stable JSON recommendation, including no_api_path and routing_diagnostics (see below).

If no persona matches, the input is treated as unmapped → a graceful beginner default (market-regime-daily, honest_gap: false) with a note asking the user to rephrase. This is distinct from an honest gap (persona #1), which is a recognized intent with no shipped workflow. routing_diagnostics.status is fallback in this path, so the default is not presented as a confident exact match.

Persona table (order matters)

Evaluated top-to-bottom; first match wins. Order encodes precedence:

# Persona Trigger gist Result
1 short-strategy-trader "short strategies / shorting / parabolic short" honest gap → advanced-satellite
2 strategy-researcher "backtest / research a strategy / strategy ideas" strategy-research-pipeline
3 shapiro-contrarian-futures-trader "COT / Shapiro / crowded futures" shapiro-contrarian
4 no-api-path "without API / no subscription / free only" market-regime-daily + {trade-memory-loop, monthly-performance-review}, force no_api
5 stockbee-20pct-researcher "20% movers / explosive mover model book" stockbee-20pct-study-daily
6 stockbee-episodic-pivot-trader "episodic pivot / Day 1 EP / delayed EP" stockbee-ep-daily
7 stockbee-fluency-learner "setup fluency / setup model book" stockbee-fluency-loop
8 multi-asset-opportunity-trader "multi-asset / cross-asset opportunities" multi-asset-opportunity-daily
9 part-time-swing-trader-regime-gated "swing" AND regime-conditional ("only when", "favorable", "when the market") market-regime-daily + swing-opportunity-daily
10 morning-risk-check "15 min each morning / can I take risk today" market-regime-daily
11 separate-core-satellite "separate / split long-term from short-term risk" (not "dividend") market-regime-daily + core-portfolio-weekly
12 kanchi-dividend-investor "Kanchi / high-dividend screening" kanchi-dividend-weekly
13 dividend-long-term-investor "dividend / holdings / rebalance / long-term investor" core-portfolio-weekly
14 swing-trader "swing / breakout" (no regime gate) swing-opportunity-daily
15 beginner-onramp "beginner / where do I start / getting started" market-regime-daily
16 monthly-reviewer "monthly review / end of month / performance review" monthly-performance-review
17 trade-journaler "journal / postmortem / closed trade / lessons learned" trade-memory-loop

Critical orderings

  • #1/#2 before everything so "short strategies" / "backtest" are not swallowed by accidental keyword overlap. Only #1 remains an honest gap.
  • #1 triggers only on short-selling phrases ("short strateg", "shorting", "go short", "short position"…) — it deliberately does not match "short-term", so #6 ("separate long-term holdings from short-term risk") still routes to the regime layer.
  • #9 (swing and regime-conditional) before #14 (generic swing): Q1 ("swing trade only when the market is favorable") → regime first; Q5 ("do swing trading") → swing directly.
  • #11 before #13 and excludes "dividend": "separate long-term holdings from short-term risk" → regime/core split, not the dividend bucket.
  • #12 before #13: specific Kanchi candidate sourcing wins over broad dividend portfolio maintenance while both candidates remain visible in diagnostics.
  • #16 before #17: specific JA monthly phrases such as 「今月の振り返り」 win over the generic journal term 「振り返り」.

Routing diagnostics and benchmark gate

routing_diagnostics.candidate_personas contains every persona whose matches() predicate succeeds, in PERSONAS order and before no-API/time constraints are applied. The first candidate remains the selected persona for backward compatibility. One match is exact; multiple matches are ambiguous; no matches are fallback with selected_persona: null.

The versioned corpus requires all 17 personas and all 12 workflows to carry positive and hard-negative coverage in both English and Japanese. Its metamorphic cases cover EN case/punctuation/word-order/orthographic changes and JA punctuation/word-order/orthographic/particle/conjugation changes. Candidate precision, candidate recall, selected accuracy, and workflow accuracy are all fixed at 1.0. Static shadowing contracts fingerprint every ordered cross-persona term containment; a new overlap, stale allowlist entry, contradictory require/exclude group, or unlabeled ambiguous contract fails CI.

Run the same gate locally:

python3 skills/trading-skills-navigator/scripts/intent_benchmark.py \
  --project-root .

The 10-Question Contract

PROJECT_VISION.md §12 lists 9 example questions and a DoD of "10". Q1–Q9 are verbatim; Q10 is authored to complete the executable contract. Each row is a golden test in tests/test_recommend.py (the hard Phase-1 gate).

# Question Primary Secondary Skillset no-API honest-gap
1 invest long term but swing trade only when market favorable market-regime-daily swing-opportunity-daily market-regime no no
2 15 min each morning, can I take risk today market-regime-daily — market-regime yes no
3 separate long-term holdings from short-term risk market-regime-daily core-portfolio-weekly market-regime no no
4 review holdings and dividend candidates this week core-portfolio-weekly — core-portfolio no no
5 do swing trading swing-opportunity-daily — swing-opportunity no no
6 find dividend stocks core-portfolio-weekly — core-portfolio no no
7 use short strategies null — advanced-satellite — yes
8 what works without API keys market-regime-daily trade-memory-loop, monthly-performance-review market-regime yes no
9 beginner-friendly starting path market-regime-daily — market-regime yes no
10 research and backtest new strategy ideas (authored) strategy-research-pipeline — strategy-research yes no

Q8 honors the single-primary_workflow schema: primary is market-regime-daily; the rest of the no-API set are secondary_workflows; skillset is the primary's category (market-regime).

For backtest execution terms (backtest, back-test, back test, バックテスト), Q10 still recommends the offline research workflow but includes a capability note in JSON and text: the workflow evaluates metrics from a separate backtest and cannot perform that backtest itself. no_api_path: true describes only this workflow, not the external tool or its historical data.

Skillset rule

skillset.id = the skills-index category of the workflow's first required skill (manifest order). Not "most common category": e.g. swing-opportunity-daily's required skills span swing-opportunity / trade-planning / trade-memory; only the first (vcp-screener → swing-opportunity) yields the contract-correct skillset. source is always skills-index.category.

manifest_status (PR-N2): active iff a skillsets/<skillset.id>.yaml manifest ships (the manifest id == the skills-index category, so the lookup is a direct match — carried as the skillsets list in the SSoT / bundled snapshot). Today the shipped set is market-regime, core-portfolio, swing-opportunity, trade-memory, strategy-research → those report active. Categories with no manifest — including the honest-gap category advanced-satellite for #7 — report deferred. The skillset object shape is unchanged ({id, source, manifest_status}); only the status value reflects manifest presence.

skillset.manifest (PR-N3): always present in the skillset object — a 5-key view {display_name, required_skills, recommended_skills, optional_skills, related_workflows} when manifest_status == active, else null. It describes the primary (dominant-category) skillset only — it is not the install list.

setup_bundle (PR-N3, top-level): the actionable install union over the primary skillset/workflow plus every secondary workflow's required/optional, deterministically ordered (primary first, then secondaries in secondary_workflows order) and tier-deduped (required > recommended > optional). sources records each contributor (skillset:<id> / workflow:<id>). This exists because a single skillset cannot cover a multi-workflow recommendation — e.g. Q1's market-regime skillset alone would drop swing-opportunity-daily's vcp-screener. Honest gap → all-empty (suggested_skills is the install list there). setup_bundle is what setup_paths.md / SKILL.md Step 4 instruct the user to install.

The --no-api credential rule

A workflow needs a paid key if either:

  • api_profile ∈ {fmp-required, finviz-required, alpaca-required}, or
  • any entry in its required_skills has an integration with id ∈ {fmp, finviz, alpaca} and requirement == required.

api_profile: mixed is never trusted on its own — the required-skill credentials are always inspected. Consequences:

  • core-portfolio-weekly is mixed but its required portfolio-manager needs Alpaca (required) → excluded under --no-api.
  • swing-opportunity-daily is fmp-required → excluded.
  • market-regime-daily is no-api-basic; its required skills use public_csv at required — not a paid key → kept.
  • trade-memory-loop / monthly-performance-review are no-api-basic; trader-memory-core has FMP at optional (not required) → kept.

When --no-api removes the persona's primary, the engine falls back to the universal no-API on-ramp (market-regime-daily) and records the exclusion reason in rationale. Honest gaps are unaffected (they have no primary).

no_api vs no_api_path (the DoD's API-vs-no-API separation)

Two distinct booleans — narrate no_api_path, not no_api:

  • no_api — request-side: was no-API constraint mode active (the --no-api flag, or the no-api-path persona forcing it). It says nothing about whether the result actually needs keys.
  • no_api_path — path-side: does the entire recommendation (primary and every secondary) work without paid API keys? workflow_paid_api_reason(primary) is None and all(... for secondary). null on an honest gap (no path). This is the 10-Question Contract's "no-API" column.

This is why Q1 and Q2 both recommend market-regime-daily yet differ: Q2 has no secondary → no_api_path: true; Q1 also pulls in fmp-required swing-opportunity-daily → no_api_path: false. A bare market-regime-daily/trade-memory-loop/monthly-performance-review path is true even without --no-api, which is exactly the DoD's "separate API-key and no-API paths".

Tie-breaks

  • --time-budget (15m/30m/60m/90m/any): secondary workflows whose estimated_minutes exceed the budget are dropped (primary is never dropped — it stays as the best intent match, with a rationale note if it is over budget).
  • --experience: beginner sorts beginner-difficulty secondaries first.
  • Secondary order is otherwise deterministic: (beginner_first, estimated_minutes, id).

Honest gap output

For persona #1 (advanced-satellite): primary_workflow: null, secondary_workflows: [], skillset.id = the gap category, suggested_skills = that category's non-deprecated skills (id-sorted, {id, display_name, category}), honest_gap: true, and a note stating the workflow manifest is deferred. Exit code is still 0 — an honest gap is a successful, honest recommendation.

Source: SKILL.md on GitHub

1 warningtoday3 checks · Risk SAFE
  • Gen Agent Trust Hubtoday

    The skill is a routing assistant for trading workflows that uses a deterministic Python script to recommend skillsets based on natural-language goals. It is well-documented and includes comprehensive tests and benchmarks. However, it presents a surface for indirect prompt injection because user-supplied goals are processed and reflected in the recommendation output without extensive sanitization.

  • Sockettoday

    No alerts

  • Snyktoday

    Risk: MEDIUM · 1 issue

Signed by skilld at c6bb7d2. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 17 hours ago.

Activeupdated 2 days ago

README badge

README badge for tradermonty/claude-trading-skills/trading-skills-navigator