AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Parallax Scenario Analysis

skill-bencharoenwong-parallax-workflows-parallax-scenario-analysis · by bencharoenwong

React to a news event or scenario: assess portfolio exposure, macro regime shift, sector impact, identify most-exposed holdings, find rotation candidates, and output an information-framed action analysis via Parallax MCP tools. Also surfaces under PM/RIA vocabulary: 'stress book', 'scenario suite', 'stress test' (e.g., rates +100bps, USD shock, 2008 / 2020 / 2022 replays). Requires a portfolio an…

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-bencharoenwong-parallax-workflows-parallax-scenario-analysis

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-bencharoenwong-parallax-workflows-parallax-scenario-analysis)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
yesterday

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Parallax Scenario Analysis? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Scenario Analysis

When not to use

  • Routine morning brief → use /parallax-morning-brief
  • General macro outlook → use /parallax-macro-outlook
  • Single stock analysis → use /parallax-deep-dive
  • Portfolio rebalancing without a trigger event → use /parallax-rebalance

Gotchas

  • JIT-load _parallax/parallax-conventions.md for RIC resolution, parallel execution, and fallback patterns
  • get_assessment with a scenario-focused prompt is the core analytical engine — feed it everything from prior steps
  • getnewssynthesis may already surface the event — check before assuming the user's framing is complete
  • Score changes haven't happened yet if the event is breaking — use get_assessment for forward-looking analysis
  • For historical events, getscoreanalysis can show what actually moved
  • This skill produces FORWARD-LOOKING analysis — always caveat uncertainty
  • 78 billable tokens at 10 equity holdings, including the 10 classification probes (see _parallax/token-costs.md); scales roughly linearly per holding — the >20-holding cap in Phase 2 bounds large books.
  • JIT-load _parallax/house-view/loader.md if an active CIO view is present; portfolio-level skill, so apply §3 (multipliers) to replacement-candidate scoring + §4 (the user-supplied scenario is sovereign per §4 — if scenario CONTRADICTS view tilts, surface "scenario contradicts house view" banner; the Action Plan acts on the scenario, not the view) + §5 (preamble + view-aware rendering) + §6 (audit). For an ALIGNED scenario, the Action Plan is more aggressive; for a CONTRADICTING scenario, the conflict is surfaced and the user's stated framing wins.
  • When active view is present, use the view-aware disclaimer per loader.md §5 rule 5; otherwise use the standard disclaimer.
  • JIT-load _parallax/white-label/integration-pattern.md before the Pre-Render step. Loader call is load_visual_branding() (7-key visual subset; voice structurally excluded — branding["voice"] raises KeyError). Apply §5 (Branding Header) and §7 (About This Report) in Output Format.

Something happened (or might happen). What's exposed? What shifts? What do I do?

Usage

/parallax-scenario-analysis "China announces 25% tariff on US semiconductors" portfolio=[{"symbol":"NVDA.O","weight":0.15},{"symbol":"AAPL.O","weight":0.20},{"symbol":"TSM.N","weight":0.10},{"symbol":"JPM.N","weight":0.15},{"symbol":"XOM.N","weight":0.20},{"symbol":"JNJ.N","weight":0.20}]
/parallax-scenario-analysis "Fed cuts rates 50bps emergency" portfolio=[holdings]
/parallax-scenario-analysis "Oil spikes to $120 on Middle East escalation" portfolio=[holdings]

Workflow

Call ToolSearch with query "+Parallax" to load the deferred MCP tool schemas before the first mcp__claude_ai_Parallax__* call. Execute using mcp__claude_ai_Parallax__* tools. JIT-load _parallax/parallax-conventions.md for execution mode, RIC resolution, and fallback patterns.

Pre-Workflow — Load Active House View

Per _parallax/house-view/loader.md §1 and §2: load and validate any active house view BEFORE running the workflow. If view present, capture the load preamble for rendering at the top of Output Format per §5.1, capture the tilt vector + excludes, and check whether the user-supplied scenario aligns with or contradicts the view per §4. If no active view (or validation failure): run the workflow normally with the standard disclaimer.

Phase 1: Understand the Event (parallel)

Fire all three simultaneously. get_news_synthesis is async (30-90s) and NEVER gates Phase 2, Phase 3, or the assessment: per conventions §5, insert its section when it resolves, or render a "news: pending" placeholder — do not wait on it.

| Tool | Parameters | Notes | |---|---|---| | get_news_synthesis | 2-3 most affected sectors | What market already knows | | get_telemetry | fields: regime_tag, signals, commentary.headline, commentary.mechanism, divergences | Starting macro environment | | macro_analyst | relevant countries/regions; component "tactical" if macro event | Positioning implications |

Phase 2: Assess Portfolio Exposure

Phase 2 is staged into two parallel turns: 2a classification + ground-truth must complete before 2b per-equity scoring + sector can fire, because the asset-class decision in 2a determines which holdings are eligible for 2b's get_score_analysis (factor scores are equity-only). Within each sub-phase every call is independent and parallel-safe per _parallax/parallax-conventions.md §3.

Fan-out cap for large portfolios: for portfolios with >20 holdings, restrict 2b's get_score_analysis and the cost-bearing 2a per-holding fan-outs to the top 20 holdings by weight plus any holding already flagged (⚠ MISMATCH or otherwise). The classification fan-out remains uncapped. Render a degraded-coverage note in Output Format listing the symbols skipped by the cap.

Phase 2a — Classification + ground-truth (parallel, single tool-call turn)

| Tool | Parameters | Notes | |---|---|---| | analyze_portfolio | portfolio=[{date: , symbol: , weight: }], fields=["concentration_metrics","sector_allocation","company_contribution"] | Sector and concentration exposure. Supply a date per holding only when the discovered live schema requires one; it is an as-of date over a price history, not a snapshot key, so today's date can return empty or fail validation. Read the live schema's own description first. When the schema gives no guidance, date every holding at the most recent completed trading day at least 5 calendar days in the past, one date for all holdings, and state the date used in the report — live schema still wins over this default. analyze_portfolio returns no factor-exposure block; factor_exposures is not a field, and fields is a direct passthrough, so an invalid name is not rejected — the block is simply absent and the call still reports success. Check result._meta.invalid_fields after the call and treat any entry there as a caller error, not as unavailable data. Per-holding factor data comes from Phase 2b get_score_analysis instead. The parameters holdings and lens do not exist in the deployed schema. WARNING: may exceed 180K chars — fall back to check_portfolio_redundancy if truncated or on MCP schema validation error. Server-side ETF handling: ETFs included here without per-skill branching. | | etf_profile | per holding, plain ticker — all N calls fan out in parallel within 2a | Asset-class oracle. Non-error response → ETF; error response ({"error": "No profile data found"}) → equity. 1 token per call per _parallax/token-costs.md. Mirrors explain-portfolio Step 1a. | | get_company_info | per holding — all N calls fan out in parallel within 2a | Ground-truth name oracle for cross-validation per conventions §2. Per-holding only — do NOT use comma-joined: comma-joined calls fail-empty on partial coverage, which is risky for arbitrary user-supplied portfolios where any single unresolved RIC silently zeroes the entire batch. | | build_stock_universe | theme describing what benefits from this scenario (e.g., "domestic US semiconductor manufacturers" if China tariffs hit imports) | Beneficiary discovery (Phase 3 step 7), hoisted here — the theme derives from the scenario text alone, needs no Phase 2 output, so it fires in the 2a turn to overlap the rest of Phase 2. If the theme is genuinely not derivable from the scenario, defer it to after Phase 2b instead. |

Gate between 2a and 2b — perform the following checks on 2a results before firing 2b:

  1. Asset-class routing: partition holdings into equities (etfprofile error) and etfs (etfprofile non-error). Phase 2b's get_score_analysis runs ONLY on the equities set.
  2. Name cross-validation (per conventions §2): for each holding, find the analyze_portfolio company_contribution[] row whose ric equals that holding's RIC and compare the row's name against get_company_info.name, normalizing both sides first per conventions §2 step 2 — Apple Inc and Apple Inc. are the same company and must not flag ⚠ MISMATCH. analyze_portfolio has no top-level identity field and no peer rollup — company_contribution[] is the per-holding identity 2a requests, so it is the only one available at this gate. A holding with no company_contribution row, or whose get_company_info call fails or returns empty, has no name pair to compare and therefore cannot be identity-checked at all — record it as UNCHECKED and surface it in the Ground-truth Integrity table rather than treating a missing comparison as a pass. Do not defer such a holding to 2b's get_score_analysis data[0].symbol as a substitute: per conventions §2 step 2 the RIC is the input to both calls, so it agrees by construction and confirms nothing. UNCHECKED is not ⚠ MISMATCH — the holding stays in 2b and in the assessment prompt, and the output states that its identity was never confirmed. Mismatches are flagged ⚠ MISMATCH and the holding is fully excluded from downstream analysis — both from 2b's get_score_analysis and from Phase 3's get_assessment prompt construction. Do not include mismatched holdings with empty profiles; that produces hallucinated factor profiles in the assessor's output.
Phase 2b — Per-equity score trajectories (parallel, single tool-call turn)

| Tool | Parameters | Notes | |---|---|---| | get_score_analysis | per equity holding (excluding ETFs from 2a and ⚠ MISMATCH holdings), 4-8 weeks — all N calls fan out in parallel within 2b | Current factor trajectories. Skipped holdings are surfaced explicitly in output (see Output Format). | | get_peer_snapshot | top 5 beneficiary candidates from the 2a build_stock_universe result — fire in this 2b turn alongside get_score_analysis | Beneficiary scoring (Phase 3 step 8), hoisted here — candidate symbols come from the universe build (different symbols than the score fan-out), so the two are independent and batch together. |

Then call get_assessment with a prompt that:

  • Describes the scenario
  • Lists each equity, non-mismatched holding with its sector and factor profile
  • For ETF holdings: lists symbol + sector exposure from analyze_portfolio only (no per-holding factor profile)
  • Explicitly excludes ⚠ MISMATCH holdings from the prompt entirely
  • Asks: "Rank these holdings from most-exposed to least-exposed to this scenario. For each, explain the transmission mechanism (direct revenue impact, supply chain, regulatory, sentiment)."

Phase 3: Sector Rotation & Replacement Candidates (steps 7-8 overlap Phase 2 — see above)

  1. Identify Beneficiariesbuild_stock_universe is fired in the Phase 2a turn (theme is scenario-derived; see the 2a table).
  2. Score Beneficiariesget_peer_snapshot for the top 5 universe candidates is fired in the Phase 2b turn (see the 2b table).
  3. Compare Replacements — For the top 2-3 replacement candidates, call get_financials with statement "summary" to verify they're fundamentally sound, not just thematically relevant.

Phase 4: Action Plan

  1. Synthesize — Call get_assessment with a comprehensive prompt incorporating:
  • The scenario and its transmission mechanisms
  • Portfolio exposure ranking from Phase 2
  • Macro regime and tactical outlook
  • Replacement candidates and their scores
  • Active house view if present (basis_statement + relevant tilts + alignment-vs-contradiction flag with the user-supplied scenario)
  • Ask: "Given this scenario, which holdings' exposure the scenario most affects and what adjustment candidates follow, framed as information. Prioritize by urgency and magnitude of exposure."
  1. Audit log — Append entry per loader.md §6.1 if a view was loaded.

Pre-Render — Load white-label branding

Load _parallax/white-label/integration-pattern.md §2 and compute white_label_active + client_name per that section. Apply §5 (Branding Header) and §7 (About This Report) when composing the Output Format. The loader returns exactly seven keys; any other access (e.g. branding["voice"]) raises KeyError — structurally enforced by loader.py.

Output Format

  • House View Preamble (only if view active) — render per loader.md §5 rule 1 (banner from Pre-Workflow + low-confidence warnings). If user-supplied scenario CONTRADICTS view tilts, append a "Scenario contradicts house view" line stating which tilt(s) disagree — per loader.md §4, the user's scenario is sovereign. Per loader.md §5.1 the preamble goes at the very top — it precedes the Branding Header.
  • Branding Header (only if white_label_active AND client_name != "") — single line immediately below the House View Preamble (or at the very top if no view): **** scenario analysis. Logo handling per integration-pattern.md §5: empty path → text only; URL → embed; absolute local (/ or ~) → skip embed and append Logo on file: to About This Report.
  • Scenario Summary (what happened, why it matters — 2-3 sentences)
  • Ground-truth Integrity (only render if Phase 2a flagged any mismatches OR recorded any holding UNCHECKED OR ETFs were excluded from per-position trajectory) — table: symbol, returned_name, expected_name, status (⚠ MISMATCH / UNCHECKED / ETF — sector exposure only / TRUSTED). Mismatched holdings were fully excluded from the assessment prompt; ETF holdings are present in analyze_portfolio sector exposure but not in per-position factor trajectories. An UNCHECKED row fills whichever name is missing with no row (absent from company_contribution[]) or no oracle (get_company_info failed or returned empty); it was NOT excluded from the assessment, so state plainly that its identity could not be confirmed.
  • Macro Regime Impact (how this shifts the current regime, which factors are affected)
  • Exposure Heat Map (table: each equity holding ranked by exposure level — High/Medium/Low — with transmission mechanism. ETF holdings appear with sector-level exposure only; mismatched holdings are excluded.)
  • Most Exposed (the 2-3 holdings at greatest risk, with specific reasoning)
  • Least Affected (safe positions — brief explanation why)
  • Sector Rotation Thesis (what benefits from this scenario)
  • Replacement Candidates (table: symbol, name, sector, total score, why it fits)
  • Action Analysis (prioritized, per conventions §12: exposure-reduction candidates, addition candidates, hold rationale — weight arithmetic framed as analysis, not instructions). Render the informational preface and action-label framing per parallax-conventions.md §12.
  • What to Watch (2-3 signals that would confirm or invalidate this thesis)
  • Confidence & Caveats (how certain is this analysis, what could go wrong with the rotation)
  • About This Report (always present): one line stating branding state per integration-pattern.md §7 markdown column (render per table; do not collapse). If a logo was skipped per the Branding Header rule, append Logo on file: as a second About This Report line.

AI-interaction disclosure (required regardless of view state): Render parallax-conventions.md §9.2 immediately above the disclaimer below.

If active view: use the view-aware disclaimer per loader.md §5 rule 5. Otherwise:

"This is scenario-based analysis, not investment advice. Forward-looking assessments are inherently uncertain."

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.