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

Parallax Rebalance

skill-bencharoenwong-parallax-workflows-parallax-rebalance · by bencharoenwong

Portfolio rebalancing with health flags and macro context: analyze current state, flag issues, generate a prioritized, information-framed rebalancing analysis (candidate actions per conventions §12) with score rationale via Parallax MCP tools. Holdings as [{symbol, weight}]. NOT for initial portfolio construction (use /parallax-portfolio-builder), not for diagnostic-only review (use /parallax-cli…

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-bencharoenwong-parallax-workflows-parallax-rebalance

✓ 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-rebalance)

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 Rebalance? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Portfolio Rebalance

When not to use

  • Building a new portfolio from scratch → use /parallax-portfolio-builder
  • Diagnostic review without trade recommendations → use /parallax-client-review
  • Single stock analysis → use /parallax-should-i-buy

Gotchas

  • JIT-load _parallax/parallax-conventions.md for fallback patterns and parallel execution
  • JIT-load _parallax/house-view/loader.md FIRST; if active view present, follow §2 (validation), §3 (multipliers), §4 (conflict resolution), §5 (output rendering), §6 (audit). Tilts in the view become trade-direction signals: rebalancing should move portfolio toward view-tilted weights.
  • When active view is present, use the view-aware disclaimer per loader.md §5 rule 5; otherwise use the standard disclaimer
  • JIT-load ../parallax-client-review/references/recommendation-matrix.md for priority classification. If missing, use inline fallback: High=3+ flags (trim/exit), Medium=2 flags (investigate/trim), Low=1 flag (monitor/hold)
  • Health flags feed directly into trade action determination — High priority = strong trim/exit
  • Call analyze_portfolio at most once. Build its request from the discovered live schema and request only compact current-state/concentration blocks; never request rolling, drawdown, return-period, benchmark-price, or other daily time-series blocks in the normal rebalance path. If the capability is absent, the request cannot be mapped unambiguously, the response is oversized/truncated, or schema/field validation fails, do not retry it with a guessed shape — use discovered concentration/scoring fallbacks.
  • buildstockuniverse can find replacement candidates for positions being trimmed
  • Output must include specific candidate weight changes, framed per conventions §12 (analysis, not instructions), not just vague suggestions
  • For portfolios with 10+ holdings, prioritize score trend scans for top/bottom 5 by weight to manage latency
  • When policy= is supplied, JIT-load _parallax/client-policy/policy-loader.md and run Batch C2. The S3 solver (_parallax/client-policy/reconcile.py) needs scipy and fails closed without it — solver_unavailable renders UNVERIFIED per conventions §4.0, never a partial trade list. Deterministic math lives in the helper; never reproduce the LP in prose.
  • 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. Audience mode resolution (§13.1) is a separate seam call, not a dict read of branding["render"]: this skill does not use the RM seam (rm_consumer.py::load_rm_branding_context) for branding, but it DOES call that module's resolve_audience() function directly, via the one Bash python3 -c step documented under Pre-Render — never re-derive the §13.1 precedence in prose.

Generate prioritized trade recommendations using health flags, macro context, and Parallax scores.

Usage

/parallax-rebalance [{"symbol":"AAPL.O","weight":0.30},{"symbol":"MSFT.O","weight":0.25},{"symbol":"XOM.N","weight":0.20},{"symbol":"JNJ.N","weight":0.25}]
/parallax-rebalance [holdings] target="reduce concentration, improve quality score"
/parallax-rebalance [holdings] constraints="max 25% per position, no energy sector"
/parallax-rebalance [holdings] policy=path/to/client-policy.yaml
/parallax-rebalance [holdings] audience=client_safe

policy= accepts the same client-policy artifact parallax-client-review consumes (inline YAML/JSON or a file path; schema in _parallax/client-policy/schema.yaml). When supplied, Batch C2 runs the S3 reconciliation optimizer and its targets replace the multiplier-derived ones.

Optional audience= argument: client_safe | internal_analyst; precedence follows parallax-conventions.md §13.1.

Workflow

Execute with the exact Parallax callables and input schemas exposed by live capability discovery in the current runtime. Logical tool names below describe intent; they are not a fixed MCP namespace or permission to use a stale request shape. JIT-load _parallax/parallax-conventions.md for discovery, execution mode, fallback patterns, and macro reasoning. JIT-load _parallax/house-view/loader.md for active-view validation and tilt application. JIT-load ../parallax-client-review/references/recommendation-matrix.md for the priority system.

Pre-flight: house-view drift check

JIT-load _parallax/house-view/auto-on-load-judge-pattern.md and follow its protocol. If the protocol surfaces a banner, render it before proceeding to this skill's main workflow.

Skip this pre-flight if invoked with --skip-drift-check or if no active house view exists.

Batch 0 — Live Capability Discovery & Active House View

Use the host's live discovery surface per conventions §0.1 (ToolSearch with "+Parallax" in Claude Code). Build a session-local map from each logical capability used below to the exact callable name and live input schema returned now. Live discovery overrides every namespace, parameter, and schema example in this file. Do not synthesize missing callables from a remembered server alias.

Classify failures before any retry: a transient transport/cancellation/empty-success may retry only the affected call once; tool-not-found, schema-validation, or response invalid_fields failures do not permit a same-payload or guessed-shape retry. Use a discovered fallback and record the affected coverage instead.

Per loader.md §1-§2: read view if present, validate hash and expiry. If view present, capture tilt vector + excludes. The view's tilts define direction of rebalance — current weights that diverge from view-tilted weights become rebalance candidates beyond the standard health-flag triggers. If validation fails or no view present, run rebalance using only health flags + macro context.

Batch A — Current state (parallel, best-effort)

The parameter column states the semantic intent. Construct every payload from that callable's discovered live schema, using only advertised keys and types. If the schema cannot represent the intent unambiguously, treat that logical capability as unavailable and follow its fallback without probing guessed variants.

| Tool | Parameters | Notes | |---|---|---| | analyze_portfolio | Map the supplied symbol/weight holdings into the live schema. If fields is advertised, request the compact intersection of portfolio_summary, concentration_metrics, sector_allocation, and company_contribution; omit time-series blocks. | Exactly one call maximum. Supply a date per holding only when the discovered live schema requires one. The date is an as-of date over a price history, not a snapshot key: a deployed connector may need a date early enough that each holding has sufficient prior price history, 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. Skip after 30s, oversized/truncated output, schema validation, or any non-empty result._meta.invalid_fields; do not retry this capability. Use discovered check_portfolio_redundancy for overlap/concentration and per-holding score aggregation for factor context. | | get_peer_snapshot | per holding | Primary scoring source for PARALLAX_LOADER_V2=1. Timeout handling: fire in parallel; if N≥2 calls timeout, mark those holdings as "scores unavailable" and continue with health-flags-only scoring. Collect successful scores only. Aggregate client-side per loader.md §3b. For 10+ holdings: prioritize top/bottom 5 by weight; timeout on remaining holdings is acceptable — fall back to health flags for those positions. Distinguish a timeout from an empty response: a timeout leaves the holding unscored and health-flag-driven per the handling above. A successful call that carries no data for the listing is a coverage gap, not a timeout — fall back to get_company_info plus get_score_analysis for that holding, label every figure derived this way a profile-derived score, and name every profile-derived holding in the report. See the Batch C2 coefficient bullet for the same-scale guard required before a profile-derived score enters the solver. | | get_company_info | per holding | Ground-truth check oracle per loader.md §5 rule 3 — records expected_name for mismatch check against get_peer_snapshot.target_company. Timeout handling: if timeout, mark holding as "name verification unavailable" and flag ⚠ UNVERIFIED. | | get_score_analysis | per holding | Score trend (improving/stable/declining) for the Score Momentum table and the Exit classification. Input is symbol + weeks only — no Batch A dependency, so it fires here in parallel. For 10+ holdings: prioritize top/bottom 5 by weight. Timeout handling: mark the holding's trend "unavailable" and continue. | | check_portfolio_redundancy | Map the normalized holdings into the live schema. | Overlap detection and the compact fallback when analyze_portfolio is unavailable. Timeout fallback: if exceeds 20s, flag "redundancy check skipped" and continue. When analyze_portfolio.sector_allocation also came back, cross-check the two sector breakdowns per "After Batch A" item 4 before rendering either. | | list_macro_countries | — | Check market coverage. Timeout fallback: skip if exceeds 5s. | | quick_portfolio_scores| Map the normalized holdings into the live schema. | Discovered Legacy/V1 fallback only. Do NOT use if PARALLAX_LOADER_V2=1 and view active. Timeout fallback: if exceeds 10s, degrade to health-flags-only scoring. A successful call with no data for a listing (distinct from a timeout) is the same coverage-gap case as the get_peer_snapshot row above — fall back to get_company_info plus get_score_analysis for that holding and label it a profile-derived score. |

After Batch A (best-effort completion):

  1. Cross-check returned names against get_company_info results per loader.md §5 rule 3. For PARALLAX_LOADER_V2=1, any mismatch in get_peer_snapshot is flagged ⚠ MISMATCH and excluded from aggregate calculations. Unverified holdings (name check timeout) are flagged ⚠ UNVERIFIED.
  2. For holdings with no scores (timeouts), scoring is determined by health flags only — these holdings cannot be ranked by factor scores and must be evaluated by "High/Medium/Low priority" categories based on flags alone.
  3. Summary output: "Batch A completed: N/M holdings scored (M-N unavailable or timed out). Portfolio snapshot: available/fallback/unavailable. Rebalance will proceed with health-flag-driven recommendations for scoring-unavailable holdings." Keep this execution receipt inside the rendered report only where the Output Format calls for the information; never leak it as pre-report scaffold. Under audience=client_safe, this receipt is ops apparatus per conventions §13.2 — relocate the receipt line to the Methodology appendix (internal) defined in Output Format, and keep in the body only a plain-language note naming the holdings whose scores were unavailable.
  4. Redundancy coverage cross-check (only when both analyze_portfolio.sector_allocation and check_portfolio_redundancy sector weights came back): write each sector-weights payload to a private mktemp JSON file, then one Bash step — python3 "/../_parallax/coverage_check.py" --portfolio-sectors "$PORTFOLIO_SECTORS" --redundancy-sectors "$REDUNDANCY_SECTORS" --holdings "$HOLDINGS" — and render from its JSON verdict. Tag every --holdings entry with its sector from the analyze_portfolio sector mapping (per-holding backstop as usual): the live redundancy payload is aggregate-only, and without sector tags the helper cannot infer absent holdings and resolves absent_holdings_basis to not_computable. Cite the operator-agnostic-helper rationale by reference to _parallax/house-view/loader.md §2 ("Why the helper, not inline math") — the same argument applies here: the coverage arithmetic must be identical across operator LLMs, so it is never reproduced in prose. On coverage_limited, label the redundancy output coverage-limited in Current Portfolio Assessment, name the diverging_sectors and any absent_holdings, and prefer the analyze_portfolio sector weights for every rendered concentration figure. absent_holdings is basis-qualified via absent_holdings_basis: when it is sector_inference, note that the absent-holdings list is inferred from diverging sectors (the redundancy payload carried no per-holding data) rather than confirmed directly; when it is not_computable, render nothing about absent holdings at all — do not claim absence and do not claim confirmed coverage. On consistent, render normally.

Batch B — Macro (after Batch A)

  1. Call the discovered macro_analyst capability for each unique covered market (cap 3), using the live schema's tactical-component value when advertised — fire all calls in one parallel batch. (Score trends moved into Batch A: get_score_analysis has no Batch A dependency, so it no longer waits behind the portfolio snapshot.)

Batch C — Health flags + trade decisions

  1. Parse mandate parameters (if constraints= and/or target= were passed):
  • constraints=: split on commas; match each clause against two recognized patterns — "max N% per position" (a per-position weight cap, applied to Target Weight in step 5) and "no " (a sector/name exclusion, applied to Replacement Candidates in step 6 exactly like tilts.excludes).
  • target=: match against recognized phrases — "reduce concentration" (prioritize Reweight/Trim of concentration-flagged holdings in step 5) and "improve quality score" (rank Replacement Candidates by quality sub-score in step 6). Any other phrase is unrecognized.
  • Fail-loud rule: any constraints= clause that matches neither recognized pattern is never silently dropped — it renders "constraint not recognized — not applied" in the Mandate Constraints Applied output block. Any unrecognized target= phrase is echoed verbatim there with a statement of how the standard recommendations already address it.
  1. Evaluate the 5 health flags per holding — binding flag conditions in ../parallax-client-review/references/recommendation-matrix.md (same taxonomy and threshold values as parallax-portfolio-checkup/references/health-flags.md, whose canonical portfolio-level weighted-average definitions apply to portfolio-checkup, not here): Low Score (holding total score ≤5.0), Concentration (holding weight >15%, or holding among the top-3 when their combined weight >45%), Redundancy (holding is part of a redundant pair), Value Trap (holding value score ≤3.0), Macro Misalignment (holding's sector has a negative tactical outlook). Per-holding flag counts drive priority assignment.
  2. House-view alignment check (if view active): for each holding, compute view-tilted target weight using loader.md §3 multipliers; flag holdings >25% off target as "View Misalignment." For holdings on tilts.excludes, flag as "View Excluded — must trim." The multiplier-derived target is benchmark-free — it tilts current weights, not a policy. When a client policy is supplied, Batch C2's optimizer targets (computed against the policy benchmark) supersede it in Trade Recommendations; the multiplier target then serves only this flag check.
  3. Assign priority per recommendation-matrix.md (count View Misalignment / View Excluded as flags):
  • High (3+ flags or View Excluded): Strong trim/exit candidate
  • Medium (2 flags): Investigate + potential trim
  • Low (1 flag): Monitor, hold unless constraints vi

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.