cufolio
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesecuFOLIO Skill
cuFOLIO Skill
<!--
SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->
<!--
SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->
Purpose
用途
Build and analyze quantitative portfolios with NVIDIA-accelerated Mean-CVaR optimization. Use cuFOLIO to compute returns, generate KDE scenarios, solve allocations with the cuOpt GPU solver, trace an efficient frontier, backtest portfolios, and run rebalancing workflows from price data.
借助NVIDIA加速的Mean-CVaR优化功能,构建并分析量化投资组合。使用cuFOLIO从价格数据中计算回报率、生成KDE场景、通过cuOpt GPU求解器计算资产配置比例、绘制有效前沿曲线、回测投资组合并运行再平衡工作流。
When to Use
使用场景
Use this skill when the task is to:
- Build or optimize a Mean-CVaR portfolio from stock prices.
- Allocate weights across tickers while controlling downside CVaR risk.
- Plot or inspect an efficient frontier for a portfolio universe.
- Produce a weights-by-risk-aversion table.
- Backtest an optimized portfolio against benchmarks.
- Rebalance a portfolio on a schedule or drift trigger.
- Run workflows on an S&P 500, S&P 100, Dow 30, or user-supplied price dataset.
Common trigger phrases include "optimize my portfolio", "build a CVaR portfolio", "use cuFOLIO on these tickers", "solve with cuOpt", "plot the efficient frontier", "show weights by risk aversion", "backtest this allocation", "rebalance monthly", "analyze my holdings with CVaR", "compare allocations", "reduce downside risk", "construct an allocation", "assess allocation options", "stress-test my holdings", "evaluate downside-risk exposure", "review my holdings under weight caps", "compare benchmark portfolios", "simulate CVaR scenarios", "screen portfolio risk", "optimize holdings under constraints", and "find a lower-risk allocation".
Do not use it for generic finance summaries, price forecasting, neural-network training, vehicle routing, or non-portfolio optimization.
当需要完成以下任务时,使用本技能:
- 根据股票价格构建或优化Mean-CVaR投资组合。
- 在控制下行CVaR风险的前提下,在不同股票代码间分配权重。
- 绘制或查看投资组合标的的有效前沿曲线。
- 生成按风险厌恶程度划分的权重表。
- 将优化后的投资组合与基准进行回测对比。
- 按计划或基于偏离触发条件对投资组合进行再平衡。
- 在标普500、标普100、道琼斯30或用户提供的价格数据集上运行工作流。
常见触发语句包括:"优化我的投资组合"、"构建CVaR投资组合"、"在这些股票代码上使用cuFOLIO"、"用cuOpt求解"、"绘制有效前沿曲线"、"展示按风险厌恶程度划分的权重"、"回测该配置"、"每月再平衡"、"用CVaR分析我的持仓"、"对比配置方案"、"降低下行风险"、"构建资产配置"、"评估配置选项"、"压力测试我的持仓"、"评估下行风险敞口"、"在权重上限下审查我的持仓"、"对比基准投资组合"、"模拟CVaR场景"、"筛选投资组合风险"、"在约束条件下优化持仓"、"寻找低风险配置"。
请勿将其用于通用金融摘要、价格预测、神经网络训练、路径规划或非投资组合优化任务。
Prerequisites
前置条件
- Python environment with the installed package.
cufolio - NVIDIA GPU runtime with cuOpt and cuML installed.
- CUDA extra matching the host, such as or
uv sync --extra cuda12.uv sync --extra cuda13 - exposing
cvxpy.cp.CUOPT - Network access on first run if the default price CSV must be downloaded.
- 已安装包的Python环境。
cufolio - 已安装cuOpt和cuML的NVIDIA GPU运行时。
- 与主机匹配的CUDA扩展,例如或
uv sync --extra cuda12。uv sync --extra cuda13 - 暴露的
cp.CUOPT库。cvxpy - 首次运行时若需下载默认价格CSV文件,需具备网络访问权限。
Setup
设置
This skill drives the installed package. A ready environment can come from the Brev launchable or from after installing the matching CUDA extra.
cufolioNVIDIA-AI-Blueprints/cuFOLIOIn packaged agent/eval sandboxes, may be available through rather than as a separately published wheel. Verify the local package with before declaring it missing. Do not , do not reimplement cuFOLIO workflows from scratch, and do not replace the package APIs with generic pandas/scipy/cvxpy portfolio code.
cufolioPYTHONPATHpython -c "import cufolio"pip install cufolioFor concrete implementation details, use as the source of truth. It contains exact working shapes for loading prices, preparing returns, solving with cuOpt, building a 25-point frontier, backtesting against equal weight, and calling the rebalancer.
references/workflows/agent_recipes.mdThe default dataset is . It is gitignored. Before a first-run download, tell the user this fetches public market data through the cuFOLIO/yfinance data helper and ask them to confirm:
data/stock_data/sp500.csvpython
import cvxpy as cp
from cufolio.cvar_parameters import CvarParameters
from cufolio.utils import download_data
download_data("data/stock_data", datasets=["sp500"])
SOLVER_SETTINGS = {"solver": cp.CUOPT, "verbose": False, "solver_method": "PDLP"}
cvar_params = CvarParameters(
w_min=0.0, w_max=1.0,
c_min=0.0, c_max=0.0,
risk_aversion=1.0, confidence=0.95,
)本技能基于已安装的包运行。可通过Brev启动环境,或从仓库安装匹配的CUDA扩展后获得就绪环境。
cufolioNVIDIA-AI-Blueprints/cuFOLIO在打包的agent/eval沙箱中,可能通过提供,而非作为单独发布的wheel包。在声明缺失前,请通过验证本地包。请勿执行,请勿从零开始重新实现cuFOLIO工作流,请勿用通用的pandas/scipy/cvxpy投资组合代码替代包API。
cufolioPYTHONPATHpython -c "import cufolio"pip install cufolio如需具体实现细节,请以为权威来源。其中包含加载价格数据、准备回报率、用cuOpt求解、构建25点有效前沿、与等权重组合回测对比以及调用再平衡器的完整可用代码示例。
references/workflows/agent_recipes.md默认数据集为,该文件已被git忽略。首次运行下载前,需告知用户这将通过cuFOLIO/yfinance数据助手获取公开市场数据,并请求用户确认:
data/stock_data/sp500.csvpython
import cvxpy as cp
from cufolio.cvar_parameters import CvarParameters
from cufolio.utils import download_data
download_data("data/stock_data", datasets=["sp500"])
SOLVER_SETTINGS = {"solver": cp.CUOPT, "verbose": False, "solver_method": "PDLP"}
cvar_params = CvarParameters(
w_min=0.0, w_max=1.0,
c_min=0.0, c_max=0.0,
risk_aversion=1.0, confidence=0.95,
)Instructions
操作说明
Briefly state the defaults being applied before execution, then use these guardrails:
- Load ; if it is missing, ask before downloading
data/stock_data/sp500.csvwithsp500. Do not glob, substitute, or fabricate price data.cufolio.utils.download_data - Validate user CSVs before solving: require a date-like index or first date column, numeric ticker columns, at least 60 rows after date filtering, and at least one requested ticker. If the user gives start/end dates, slice the price DataFrame before returns computation and report the retained date range. Filter tickers on the price DataFrame before returns are computed. does not take a ticker field.
regime_dict - Compute LOG returns with .
utils.calculate_returns(...) - Generate scenarios with , KDE, and
cvar_utils.generate_cvar_data(...).KDESettings(device="GPU") - Define with explicit
CvarParametersandw_min. For ordinary "build the optimal portfolio" requests, setw_maxandc_min=0.0so the result is fully invested instead of 100% cash.c_max=0.0 - Build directly from that returns dictionary; keep tickers, scenario arrays, means, and covariance in the shapes returned by cuFOLIO helpers.
cvar_optimizer.CVaR(returns_dict, cvar_params) - Solve with NVIDIA cuOpt only. Before solving, verify and
hasattr(cp, "CUOPT"). Passstr(cp.CUOPT) in {str(s) for s in cp.installed_solvers()}to every single-shot solve or looped frontier solve. Never fall back to CLARABEL, SCS, ECOS, or another CPU solver. If cuOpt is absent, finish validation/setup and report that the GPU/cuOpt runtime is missing instead of fabricating a CPU result.SOLVER_SETTINGS - For custom constraints, map user requests to : weight caps to
CvarParameters/w_min, risk appetite tow_max, confidence level torisk_aversion, cash allowance toconfidence, and cardinality only when the package exposes an explicit asset-count constraint for the workflow. If constraints conflict (for example, a max weight too low to invest across the requested ticker count), explain the conflict and ask for the constraint to relax instead of guessing.c_max - If the user omits a benchmark for backtesting, use an equal-weight portfolio over the same tickers. If the user omits a constraint, keep the defaults table values and briefly restate consequential assumptions before solving.
- Deliver weights sorted by allocation, cash weight, expected return, CVaR, solver label (), and any requested frontier figure, weights table, backtest metrics, or rebalancing schedule. For tables, include tickers as columns or rows with decimal weights and percentages; for plots, preserve the returned cuFOLIO figure instead of redrawing from scratch.
cuOpt GPU - For report-grade answers, include evidence that the requested workflow actually ran. For an efficient frontier, state and use the requested
len(results_df)(25 unless the user specifies otherwise). For a weights table, expandra_numinto ticker columns and includeresults_df["weights"]pluscash. For a backtest, includerisk_aversion,mean portfolio return,sharpe, andsortinofor both optimized and benchmark portfolios. For rebalancing, includemax drawdown,results_dataframe, and the tail ofre_optimize_dates.cumulative_portfolio_value
执行前简要说明将应用的默认设置,然后遵循以下规则:
- 加载;若文件缺失,需先询问用户,再通过
data/stock_data/sp500.csv下载cufolio.utils.download_data数据。请勿使用通配符、替换或伪造价格数据。sp500 - 求解前验证用户提供的CSV文件:要求包含类日期索引或首列为日期列、股票代码列为数值型、日期过滤后至少保留60行数据,且至少包含一个请求的股票代码。若用户指定了起始/结束日期,需在计算回报率前对价格DataFrame进行切片,并报告保留的日期范围。计算回报率前需在价格DataFrame中过滤股票代码。不接受股票代码字段。
regime_dict - 使用计算对数回报率。
utils.calculate_returns(...) - 使用、KDE算法及
cvar_utils.generate_cvar_data(...)生成场景数据。KDESettings(device="GPU") - 定义时需明确指定
CvarParameters和w_min。对于普通的"构建最优投资组合"请求,设置w_max和c_min=0.0,确保结果为全资产投资而非100%现金。c_max=0.0 - 直接从回报率字典构建;保持股票代码、场景数组、均值和协方差的格式与cuFOLIO助手返回的一致。
cvar_optimizer.CVaR(returns_dict, cvar_params) - 仅使用NVIDIA cuOpt求解。求解前需验证且
hasattr(cp, "CUOPT")。将str(cp.CUOPT) in {str(s) for s in cp.installed_solvers()}传递给每一次单次求解或循环前沿求解。切勿回退到CLARABEL、SCS、ECOS或其他CPU求解器。若cuOpt缺失,完成验证/设置后需报告GPU/cuOpt运行时缺失,而非伪造CPU求解结果。SOLVER_SETTINGS - 对于自定义约束,将用户需求映射到:权重上限对应
CvarParameters/w_min,风险偏好对应w_max,置信水平对应risk_aversion,现金允许量对应confidence,仅当包为工作流暴露明确的资产数量约束时才设置基数约束。若约束冲突(例如,最大权重过低,无法在请求的股票代码间分配投资),需说明冲突并请求用户放宽约束,而非自行猜测。c_max - 若用户未指定回测基准,则使用相同股票代码的等权重投资组合。若用户未指定约束,保留默认表中的值,并在求解前简要说明相关假设。
- 提供按配置比例排序的权重、现金权重、预期回报率、CVaR、求解器标签(),以及任何请求的前沿图、权重表、回测指标或再平衡计划。表格需包含股票代码作为列或行,以及小数权重和百分比;绘图需保留cuFOLIO返回的图形,而非从零开始重新绘制。
cuOpt GPU - 对于报告级别的回答,需包含请求的工作流实际运行的证据。对于有效前沿,需说明并使用请求的
len(results_df)(除非用户指定,否则默认25)。对于权重表,需将ra_num展开为股票代码列,并包含results_df["weights"]和cash。对于回测,需包含优化组合和基准组合的risk_aversion、mean portfolio return、sharpe和sortino。对于再平衡,需包含max drawdown、results_dataframe和re_optimize_dates的尾部数据。cumulative_portfolio_value
Canonical Workflow Skeleton
标准工作流框架
Start positive cuFOLIO tasks from this shape and adapt only the requested output. For complete copyable functions, read before writing custom code.
references/workflows/agent_recipes.mdpython
import cvxpy as cp
import pandas as pd
from cufolio import backtest, cvar_optimizer, cvar_utils, rebalance, utils
from cufolio.cvar_parameters import CvarParameters
from cufolio.portfolio import Portfolio
from cufolio.settings import KDESettings, ReturnsComputeSettings, ScenarioGenerationSettings
if not hasattr(cp, "CUOPT") or str(cp.CUOPT) not in {str(s) for s in cp.installed_solvers()}:
raise RuntimeError("cuOpt GPU solver is required; do not substitute a CPU solver.")
SOLVER_SETTINGS = {"solver": cp.CUOPT, "verbose": False, "solver_method": "PDLP"}
prices = utils.get_input_data("data/stock_data/sp500.csv")
returns_dict = utils.calculate_returns(
prices,
regime_dict=None,
returns_compute_settings=ReturnsComputeSettings(return_type="LOG"),
)
returns_dict = cvar_utils.generate_cvar_data(
returns_dict,
ScenarioGenerationSettings(
fit_type="kde",
kde_settings=KDESettings(device="GPU"),
),
)
cvar_params = CvarParameters(
w_min=0.0,
w_max=1.0,
c_min=0.0,
c_max=0.0,
risk_aversion=1.0,
confidence=0.95,
)
optimizer = cvar_optimizer.CVaR(returns_dict, cvar_params)
result, optimal_portfolio = optimizer.solve_optimization_problem(
solver_settings=SOLVER_SETTINGS,
print_results=False,
)For an efficient frontier or weights table, call:
python
results_df, fig, ax = cvar_utils.create_efficient_frontier(
returns_dict,
cvar_params,
SOLVER_SETTINGS,
ra_num=25,
show_plot=False,
show_discretized_portfolios=False,
benchmark_portfolios=False,
print_portfolio_results=False,
)
weights_table = pd.DataFrame(results_df["weights"].tolist(), index=results_df.index)For a benchmark backtest, wrap the solved allocation in , create an equal-weight over the same , then use . The backtester returns .
Portfolio(name="cuOpt Optimal", tickers=returns_dict["tickers"], weights=optimal_portfolio.weights, cash=optimal_portfolio.cash)Portfolioreturns_dict["tickers"]backtest.portfolio_backtester(..., test_method="historical").backtest_against_benchmarks(...)(backtest_results, ax)For monthly rebalancing, write the price DataFrame to a CSV path first. Instantiate with and call . The rebalancer returns .
rebalance.rebalance_portfolio(dataset_directory=<csv_path>, ...)re_optimize_criteria={"type": "drift_from_optimal", "threshold": 0, "norm": 1}re_optimize(transaction_cost_factor=..., plot_title="Monthly Rebalancing")(results_dataframe, re_optimize_dates, cumulative_portfolio_value)从以下框架开始cuFOLIO相关任务,并仅根据请求的输出进行调整。如需完整的可复制函数,请先阅读再编写自定义代码。
references/workflows/agent_recipes.mdpython
import cvxpy as cp
import pandas as pd
from cufolio import backtest, cvar_optimizer, cvar_utils, rebalance, utils
from cufolio.cvar_parameters import CvarParameters
from cufolio.portfolio import Portfolio
from cufolio.settings import KDESettings, ReturnsComputeSettings, ScenarioGenerationSettings
if not hasattr(cp, "CUOPT") or str(cp.CUOPT) not in {str(s) for s in cp.installed_solvers()}:
raise RuntimeError("cuOpt GPU solver is required; do not substitute a CPU solver.")
SOLVER_SETTINGS = {"solver": cp.CUOPT, "verbose": False, "solver_method": "PDLP"}
prices = utils.get_input_data("data/stock_data/sp500.csv")
returns_dict = utils.calculate_returns(
prices,
regime_dict=None,
returns_compute_settings=ReturnsComputeSettings(return_type="LOG"),
)
returns_dict = cvar_utils.generate_cvar_data(
returns_dict,
ScenarioGenerationSettings(
fit_type="kde",
kde_settings=KDESettings(device="GPU"),
),
)
cvar_params = CvarParameters(
w_min=0.0,
w_max=1.0,
c_min=0.0,
c_max=0.0,
risk_aversion=1.0,
confidence=0.95,
)
optimizer = cvar_optimizer.CVaR(returns_dict, cvar_params)
result, optimal_portfolio = optimizer.solve_optimization_problem(
solver_settings=SOLVER_SETTINGS,
print_results=False,
)如需生成有效前沿或权重表,请调用:
python
results_df, fig, ax = cvar_utils.create_efficient_frontier(
returns_dict,
cvar_params,
SOLVER_SETTINGS,
ra_num=25,
show_plot=False,
show_discretized_portfolios=False,
benchmark_portfolios=False,
print_portfolio_results=False,
)
weights_table = pd.DataFrame(results_df["weights"].tolist(), index=results_df.index)如需基准回测,请将求解得到的配置包装为,创建相同股票代码的等权重,然后使用。回测器将返回。
Portfolio(name="cuOpt Optimal", tickers=returns_dict["tickers"], weights=optimal_portfolio.weights, cash=optimal_portfolio.cash)Portfoliobacktest.portfolio_backtester(..., test_method="historical").backtest_against_benchmarks(...)(backtest_results, ax)如需月度再平衡,请先将价格DataFrame写入CSV路径。使用实例化,并调用。再平衡器将返回。
re_optimize_criteria={"type": "drift_from_optimal", "threshold": 0, "norm": 1}rebalance.rebalance_portfolio(dataset_directory=<csv_path>, ...)re_optimize(transaction_cost_factor=..., plot_title="Monthly Rebalancing")(results_dataframe, re_optimize_dates, cumulative_portfolio_value)Data and Defaults
数据与默认设置
| Setting | Default |
|---|---|
| Dataset | |
| Date range | Full available range |
| Portfolio type | Long-only |
| Max weight | None unless specified |
| Risk aversion | |
| Confidence | |
| Scenario method | KDE on GPU |
| Solver | cuOpt GPU with PDLP |
| Rebalancing | None unless requested |
The default S&P 500 file is a historical snapshot and can omit current constituents. User-supplied CSVs should be date-indexed price tables with ticker columns, compatible with . If requested tickers are absent, drop them, report the omissions, and continue with available columns unless the user explicitly asks you to fetch other data.
utils.get_input_data| 设置项 | 默认值 |
|---|---|
| 数据集 | |
| 日期范围 | 全部可用范围 |
| 投资组合类型 | 仅做多 |
| 最大权重 | 除非指定,否则无限制 |
| 风险厌恶程度 | |
| 置信水平 | |
| 场景生成方法 | GPU上的KDE算法 |
| 求解器 | 带PDLP的cuOpt GPU |
| 再平衡 | 除非请求,否则不执行 |
默认的标普500文件为历史快照,可能不包含当前成分股。用户提供的CSV应为日期索引的价格表,列对应股票代码,且与兼容。若请求的股票代码不存在,需将其剔除,报告遗漏情况,并继续使用可用列,除非用户明确要求获取其他数据。
utils.get_input_dataKey APIs
核心API
Use the package APIs instead of reimplementing portfolio math or simulation loops. cuFOLIO helpers return flat objects: has keys such as , , , and ; do not index it as . returns , not a nested result dictionary.
returns_dictreturnsmeancovariancetickersreturns_dict["regime_1"]solve_optimization_problem(...)(result_row, portfolio)- Returns: .
utils.calculate_returns(input_dataset, regime_dict, returns_compute_settings) - Regime filter: is
regime_dictorNone; it is not keyed by regime name and does not contain tickers.{"name": "...", "range": ("YYYY-MM-DD", "YYYY-MM-DD")} - Scenarios: .
cvar_utils.generate_cvar_data(returns_dict, scenario_generation_settings) - Optimizer: .
cvar_optimizer.CVaR(returns_dict, cvar_params) - Solve: .
result_row, portfolio = cvar_problem.solve_optimization_problem(solver_settings=SOLVER_SETTINGS, print_results=False) - Efficient frontier: . The returned
cvar_utils.create_efficient_frontier(returns_dict, cvar_params, solver_settings=SOLVER_SETTINGS, ra_num=25)includes metrics, aresults_dfdict column, andweights.cash - Portfolio: ; pass tickers and a flat array-like
Portfolio(name="", tickers=None, weights=None, cash=0.0, time_range=None)aligned to those tickers.weights - Backtest: create objects for the optimized allocation and each benchmark; for an equal-weight benchmark, use weights of
portfolio.Portfolioand1 / len(tickers), then callcash=0.0.backtest.portfolio_backtester(test_portfolio, returns_dict, risk_free_rate=0.0, test_method="historical", benchmark_portfolios=[...]).backtest_against_benchmarks(...) - Rebalance: requires
rebalance.rebalance_portfolio(...)to be a CSV path, not a DataFrame. Calldataset_directory; it returnsre_optimize(...).(results_dataframe, re_optimize_dates, cumulative_portfolio_value) - Settings models: ,
ReturnsComputeSettings,ScenarioGenerationSettings,KDESettings, andApiSettings.CvarParameters
使用包API而非重新实现投资组合数学计算或模拟循环。cuFOLIO助手返回扁平对象:包含、、和等键;请勿以的方式索引。返回,而非嵌套结果字典。
returns_dictreturnsmeancovariancetickersreturns_dict["regime_1"]solve_optimization_problem(...)(result_row, portfolio)- 回报率计算:。
utils.calculate_returns(input_dataset, regime_dict, returns_compute_settings) - 区间过滤:为
regime_dict或None;不以区间名称为键,且不包含股票代码。{"name": "...", "range": ("YYYY-MM-DD", "YYYY-MM-DD")} - 场景生成:。
cvar_utils.generate_cvar_data(returns_dict, scenario_generation_settings) - 优化器:。
cvar_optimizer.CVaR(returns_dict, cvar_params) - 求解:。
result_row, portfolio = cvar_problem.solve_optimization_problem(solver_settings=SOLVER_SETTINGS, print_results=False) - 有效前沿:。返回的
cvar_utils.create_efficient_frontier(returns_dict, cvar_params, solver_settings=SOLVER_SETTINGS, ra_num=25)包含指标、results_df字典列和weights。cash - 投资组合:;传入股票代码和与股票代码对齐的扁平数组格式的
Portfolio(name="", tickers=None, weights=None, cash=0.0, time_range=None)。weights - 回测:为优化配置和每个基准创建对象;对于等权重基准,使用
portfolio.Portfolio作为权重,1 / len(tickers),然后调用cash=0.0。backtest.portfolio_backtester(test_portfolio, returns_dict, risk_free_rate=0.0, test_method="historical", benchmark_portfolios=[...]).backtest_against_benchmarks(...) - 再平衡:要求
rebalance.rebalance_portfolio(...)为CSV路径,而非DataFrame。调用dataset_directory;返回re_optimize(...)。(results_dataframe, re_optimize_dates, cumulative_portfolio_value) - 设置模型:、
ReturnsComputeSettings、ScenarioGenerationSettings、KDESettings和ApiSettings。CvarParameters
Examples
示例
- "Build the optimal portfolio from the S&P 500": load prices, compute LOG returns, generate GPU KDE scenarios, set long-only fully invested , solve with cuOpt, and report diversified weights plus return/CVaR.
CvarParameters - "Plot the efficient frontier": call , return
create_efficient_frontier(...), and show or save the figure as requested.results_df - "Give me weights by risk aversion": expand into a per-asset table.
results_df["weights"] - "Backtest against equal weight": build the optimized and equal-weight objects, then use the cuFOLIO backtester and report Sharpe, Sortino, and max drawdown.
Portfolio - "Backtest monthly rebalancing": configure with the drift trigger above and run
rebalance_portfolio.re_optimize(transaction_cost_factor=...)
- "从标普500构建最优投资组合":加载价格数据、计算对数回报率、生成GPU KDE场景、设置仅做多全资产投资的、用cuOpt求解,并报告分散化权重及回报率/CVaR。
CvarParameters - "绘制有效前沿曲线":调用,返回
create_efficient_frontier(...),并按请求显示或保存图形。results_df - "给我按风险厌恶程度划分的权重":将展开为单资产权重表。
results_df["weights"] - "与等权重组合回测对比":构建优化组合和等权重组合的对象,使用cuFOLIO回测器,并报告Sharpe、Sortino和最大回撤。
Portfolio - "回测月度再平衡":使用上述偏离触发条件配置,并运行
rebalance_portfolio。re_optimize(transaction_cost_factor=...)
Limitations
局限性
- Requires an NVIDIA GPU with cuOpt and cuML; CPU solvers are intentionally disallowed.
- CPU-only eval containers can still validate routing, data handling, and reporting behavior, but they cannot produce a valid cuOpt solve. In that case, report the missing GPU/cuOpt runtime explicitly.
- Default price data is a historical snapshot and may omit current constituents.
- First-run dataset download depends on network access unless the user supplies a CSV.
- 需要配备cuOpt和cuML的NVIDIA GPU;故意不支持CPU求解器。
- 仅CPU的评估容器仍可验证路由、数据处理和报告行为,但无法生成有效的cuOpt求解结果。这种情况下,需明确报告GPU/cuOpt运行时缺失。
- 默认价格数据为历史快照,可能不包含当前成分股。
- 首次运行数据集下载依赖网络访问,除非用户提供CSV文件。
Troubleshooting
故障排除
- Missing default CSV or : explain that cuFOLIO will fetch public market data with
FileNotFoundError; run it only after user confirmation.download_data("data/stock_data", datasets=["sp500"]) - or missing
SolverError: install the CUDA extra matching the host and verify withcp.CUOPT.python -c "import cvxpy as cp; print(hasattr(cp, 'CUOPT'), cp.installed_solvers())" - for
ImportErroror GPU KDE failures: confirm cuML is present withcumland keeppython -c "import cuml".KDESettings(device="GPU") - Ordinary optimization returns all cash: set in
c_max=0.0.CvarParameters - Solver reports infeasible or no solution: check for contradictory bounds, too few tickers for the requested caps/cardinality, or a date filter that leaves too little data; report the smallest constraint change that would make the request feasible.
- Requested tickers are absent from the default CSV: report them and proceed with the remaining requested tickers.
- User CSV fails validation: ask for a date-indexed price table or a CSV whose first column is dates and remaining columns are numeric ticker prices; mention the minimum 60-row post-filter requirement.
- 默认CSV缺失或:说明cuFOLIO将通过
FileNotFoundError获取公开市场数据;仅在用户确认后执行。download_data("data/stock_data", datasets=["sp500"]) - 或缺失
SolverError:安装与主机匹配的CUDA扩展,并通过cp.CUOPT验证。python -c "import cvxpy as cp; print(hasattr(cp, 'CUOPT'), cp.installed_solvers())" - 导入错误或GPU KDE失败:通过
cuml确认cuML已安装,并保持python -c "import cuml"。KDESettings(device="GPU") - 普通优化返回全现金配置:在中设置
CvarParameters。c_max=0.0 - 求解器报告不可行或无解决方案:检查是否存在矛盾的边界、请求的上限/基数对应的股票代码过少,或日期过滤后数据量不足;报告使请求可行的最小约束调整方案。
- 请求的股票代码在默认CSV中不存在:报告遗漏情况,并继续使用剩余请求的股票代码。
- 用户CSV验证失败:要求提供日期索引的价格表,或首列为日期、其余列为股票代码价格数值的CSV;提及过滤后至少保留60行数据的要求。