
Portfolio Optimization
FreeAccelerate mean-variance optimization with Conjugate Gradient.
Free · Opens the source repo
What Portfolio Optimization does
The Portfolio Optimization skill leverages the Conjugate Gradient (CG) method to solve mean-variance optimization problems efficiently. By replacing the legacy Neumann series approach, this skill offers a significant performance boost, achieving speeds that are 40-60 times faster for covariance matrices of size 256. This is particularly beneficial for developers and data scientists working in quantitative finance, where rapid calculations of optimal asset weights can lead to more timely investment decisions.
The skill operates by solving the equation (Σ · x = μ), where (Σ) is the covariance matrix and (μ) is the expected return vector. The covariance matrix is constructed as a symmetric positive-definite Gram matrix, ensuring that the CG method is optimal and converges quickly without requiring preconditioning. Users can easily integrate this skill into their existing workflows by utilizing the provided commands to read the covariance matrix and expected returns from the neural-trader API, and then calling the CG solver.
Additionally, the skill includes a fallback mechanism to the legacy Neumann method if certain conditions are not met, such as non-SPD matrices or if users choose to disable the CG path. This ensures reliability and flexibility in various scenarios, allowing users to validate results against the traditional method. The output includes important metadata about the optimization process, enabling users to track which method was used and the performance of the optimization.
This skill is ideal for quantitative analysts, algorithmic traders, and developers looking to enhance their trading strategies through efficient portfolio optimization. Its integration with existing tools like neural-trader makes it a valuable addition to any financial modeling toolkit.
When to use it
Use this skill when you need to perform mean-variance portfolio optimization quickly and efficiently, especially with large covariance matrices.
When not to use it
Avoid this skill if your covariance matrices are not symmetric positive-definite or if you require features not covered by the CG method.
What you can build with it
Quick Portfolio Analysis
Use this skill to rapidly analyze and optimize your portfolio's asset weights, improving decision-making speed.
Validation of Optimization Methods
Run the skill with the CG method and compare results against the legacy Neumann method for validation purposes.
Integration with Trading Systems
Incorporate this skill into your trading algorithms to enhance performance and efficiency in portfolio management.
How to install Portfolio Optimization
View source1. Install with the skills CLI
npx skills add ruvnet/ruflo/trader-portfolio-cg --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by ruvnetSolve the mean-variance optimization Σ · x = μ via Conjugate Gradient instead of the legacy Neumann series.
Why CG instead of Neumann (ADR-123 Wedge 8):
- Neumann series: ~50 µs at n=256 (legacy
npx neural-trader --portfolio optimize) - Conjugate Gradient: ~816 ns at n=256 (this skill)
- Measured speedup: 40-60×; parity within 1e-4 on a fixed seed.
The covariance matrix Σ is symmetric positive-definite by construction (it's a Gram matrix on real returns), so CG is provably optimal — it converges in at most n iterations with no preconditioning, and typically far fewer when eigenvalues cluster.
Disable flag: set RUFLO_NEURAL_TRADER_DISABLE_CG=1 to skip the CG path entirely and fall through to step 4's legacy Neumann route. Useful for A/B validation or when an upstream covariance regression breaks SPD.
Native dispatch flag: set RUFLO_SUBLINEAR_NATIVE=1 to force the adapter to attempt the native mcp__ruflo-sublinear__solve path even when globalThis doesn't expose the tool (e.g. when the harness mounts it via a different transport). On any native-dispatch failure the adapter cleanly falls back to the local JS CG and records method: 'cg-local' in the artifact metadata — so the regression is auditable.
Steps:
-
Ensure neural-trader is available:
npm ls neural-trader 2>/dev/null || npm install --ignore-scripts neural-trader -
Read the current covariance matrix Σ and expected-return vector μ from neural-trader's portfolio API:
# Primary path (preferred — clean JSON): npx neural-trader --portfolio current --json # Fallback paths if the --json flag is unavailable on the installed version: npx neural-trader --portfolio current # parse the text output # OR pull from AgentDB if a prior run stored the matrix there:mcp__plugin_ruflo-core_ruflo__memory_search({ query: "covariance matrix current", namespace: "trading-risk", limit: 1 })The skill expects the response to include
covariance: number[][](n × n) andexpectedReturns: number[](length n). -
Solve Σ · x = μ via the SublinearAdapter (preferred path) when
RUFLO_NEURAL_TRADER_DISABLE_CGis unset:import { sublinearAdapter } from '../../src/sublinear-adapter.mjs'; const result = await sublinearAdapter.solveCG(COVARIANCE, EXPECTED_RETURNS, { tolerance: 1e-6, maxIterations: 200, }); // result.solution — optimal weights (number[]) // result.iterations — CG iterations executed // result.residual — final ||A·x − b||₂ // result.latencyMs — wall-clock latency // result.method — 'cg-sublinear-native' | 'cg-local' <-- READ THIS // result.solver — 'sublinear-time-solver@1.7.0' | 'local-js-cg' // result.degraded — true if input failed SPD checks (fall back to step 4)The adapter does the dispatch itself: it probes for
mcp__ruflo-sublinear__solveonglobalThis(and honoursRUFLO_SUBLINEAR_NATIVE=1as a manual override), routes through the native kernel when reachable, and falls back transparently to the embedded ~50-LOC JS CG when not. The math is identical either way — CG, dense form, n × n SPD covariance. The operator readsresult.methodto know which backend produced the artifact.The native MCP tool's wire shape (for direct callers who want to bypass the adapter):
mcp__ruflo-sublinear__solve({ matrix: COVARIANCE, rhs: EXPECTED_RETURNS, algorithm: "cg", tolerance: 1e-6, maxIterations: 200 })Output:
{ solution: number[], iterations: number, residual: number } -
Fallback (legacy Neumann) — if step 3 reports
degraded: true(non-SPD input, non-square matrix, MCP error) OR ifRUFLO_NEURAL_TRADER_DISABLE_CG=1:npx neural-trader --portfolio optimizeCapture the weights output and tag the artifact metadata with
method: 'neumann-fallback'and areasonfield. -
Store the optimal weights to
trading-risknamespace with full provenance metadata. Takemethodandsolverstraight from the adapter's result so the operator can verify which backend ran:mcp__plugin_ruflo-core_ruflo__memory_store({ key: "portfolio-weights-PORTFOLIO_ID-TIMESTAMP", namespace: "trading-risk", value: JSON.stringify({ weights: result.solution, // number[] from step 3 (or weights from step 4 fallback) method: result.method, // 'cg-sublinear-native' | 'cg-local' | 'neumann-fallback' solver: result.solver, // 'sublinear-time-solver@1.7.0' | 'local-js-cg' | 'neural-trader-cli' iterations: result.iterations, residual: result.residual, latencyMs: result.latencyMs, capturedAt: NEW_DATE_ISO, reason: FALLBACK_REASON || null }) })The
trading-risknamespace is canonical (ADR-126 Phase 1; the five-namespace alignment). Long-lived — no TTL — because portfolio weights are the audit trail Phase 4 will Ed25519-sign. -
Cross-check against historical patterns (optional but recommended):
mcp__plugin_ruflo-core_ruflo__agentdb_pattern-search({ query: "portfolio weights Sharpe regime:CURRENT_REGIME", namespace: "trading-risk" })If the new weights differ by more than 30% in any single asset from the historical median, flag for human review before applying. This is a guard-rail, not a hard block.
Acceptance criteria (ADR-126 Phase 3):
- Latency < 1 ms on n = 256 covariance (local JS CG); native path target 40-60× faster (816 ns native vs 50 µs Neumann per sublinear-time-solver@1.7.0).
- Parity with legacy Neumann within
||cg − neumann||_∞ < 1e-4on a fixed seed. - Fallback path engages cleanly when native MCP unavailable / covariance non-SPD.
- Artifact metadata distinguishes
cg-sublinear-native,cg-local, andneumann-fallback.
Refs:
- ADR-126 Phase 3 (this skill's authoring ADR)
- ADR-123 §162 Row 8 (Wedge 8 speedup claim)
- ADR-123 §262-289 (the SublinearAdapter contract)
plugins/ruflo-neural-trader/src/sublinear-adapter.ts(the adapter)plugins/ruflo-neural-trader/benchmarks/portfolio-cg.bench.ts(the measured numbers)
Frequently asked questions about Portfolio Optimization
Similar skills
Power BI Semantic Modeling
Optimize your Power BI data models with best practices.
Data Context Extractor
Tailor data analysis skills to your company's needs.
Power BI Performance Troubleshooting
Systematic guidance for optimizing Power BI performance.
Power BI Model Design Review
Optimize your Power BI data models with expert reviews.
Power BI DAX Formula Optimizer
Optimize your DAX formulas for better performance and clarity.
Fabric Lakehouse
Optimize your data solutions with Lakehouse best practices.
