cufolio

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cuFOLIO 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
    cufolio
    package.
  • NVIDIA GPU runtime with cuOpt and cuML installed.
  • CUDA extra matching the host, such as
    uv sync --extra cuda12
    or
    uv sync --extra cuda13
    .
  • cvxpy
    exposing
    cp.CUOPT
    .
  • Network access on first run if the default price CSV must be downloaded.
  • 已安装
    cufolio
    包的Python环境。
  • 已安装cuOpt和cuML的NVIDIA GPU运行时。
  • 与主机匹配的CUDA扩展,例如
    uv sync --extra cuda12
    uv sync --extra cuda13
  • 暴露
    cp.CUOPT
    cvxpy
    库。
  • 首次运行时若需下载默认价格CSV文件,需具备网络访问权限。

Setup

设置

This skill drives the installed
cufolio
package. A ready environment can come from the Brev launchable or from
NVIDIA-AI-Blueprints/cuFOLIO
after installing the matching CUDA extra.
In packaged agent/eval sandboxes,
cufolio
may be available through
PYTHONPATH
rather than as a separately published wheel. Verify the local package with
python -c "import cufolio"
before declaring it missing. Do not
pip install cufolio
, do not reimplement cuFOLIO workflows from scratch, and do not replace the package APIs with generic pandas/scipy/cvxpy portfolio code.
For concrete implementation details, use
references/workflows/agent_recipes.md
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.
The default dataset is
data/stock_data/sp500.csv
. 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:
python
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,
)
本技能基于已安装的
cufolio
包运行。可通过Brev启动环境,或从
NVIDIA-AI-Blueprints/cuFOLIO
仓库安装匹配的CUDA扩展后获得就绪环境。
在打包的agent/eval沙箱中,
cufolio
可能通过
PYTHONPATH
提供,而非作为单独发布的wheel包。在声明缺失前,请通过
python -c "import cufolio"
验证本地包。请勿执行
pip install cufolio
,请勿从零开始重新实现cuFOLIO工作流,请勿用通用的pandas/scipy/cvxpy投资组合代码替代包API。
如需具体实现细节,请以
references/workflows/agent_recipes.md
为权威来源。其中包含加载价格数据、准备回报率、用cuOpt求解、构建25点有效前沿、与等权重组合回测对比以及调用再平衡器的完整可用代码示例。
默认数据集为
data/stock_data/sp500.csv
,该文件已被git忽略。首次运行下载前,需告知用户这将通过cuFOLIO/yfinance数据助手获取公开市场数据,并请求用户确认:
python
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:
  1. Load
    data/stock_data/sp500.csv
    ; if it is missing, ask before downloading
    sp500
    with
    cufolio.utils.download_data
    . Do not glob, substitute, or fabricate price data.
  2. 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.
    regime_dict
    does not take a ticker field.
  3. Compute LOG returns with
    utils.calculate_returns(...)
    .
  4. Generate scenarios with
    cvar_utils.generate_cvar_data(...)
    , KDE, and
    KDESettings(device="GPU")
    .
  5. Define
    CvarParameters
    with explicit
    w_min
    and
    w_max
    . For ordinary "build the optimal portfolio" requests, set
    c_min=0.0
    and
    c_max=0.0
    so the result is fully invested instead of 100% cash.
  6. Build
    cvar_optimizer.CVaR(returns_dict, cvar_params)
    directly from that returns dictionary; keep tickers, scenario arrays, means, and covariance in the shapes returned by cuFOLIO helpers.
  7. Solve with NVIDIA cuOpt only. Before solving, verify
    hasattr(cp, "CUOPT")
    and
    str(cp.CUOPT) in {str(s) for s in cp.installed_solvers()}
    . Pass
    SOLVER_SETTINGS
    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.
  8. For custom constraints, map user requests to
    CvarParameters
    : weight caps to
    w_min
    /
    w_max
    , risk appetite to
    risk_aversion
    , confidence level to
    confidence
    , cash allowance to
    c_max
    , 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.
  9. 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.
  10. Deliver weights sorted by allocation, cash weight, expected return, CVaR, solver label (
    cuOpt GPU
    ), 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.
  11. For report-grade answers, include evidence that the requested workflow actually ran. For an efficient frontier, state
    len(results_df)
    and use the requested
    ra_num
    (25 unless the user specifies otherwise). For a weights table, expand
    results_df["weights"]
    into ticker columns and include
    cash
    plus
    risk_aversion
    . For a backtest, include
    mean portfolio return
    ,
    sharpe
    ,
    sortino
    , and
    max drawdown
    for both optimized and benchmark portfolios. For rebalancing, include
    results_dataframe
    ,
    re_optimize_dates
    , and the tail of
    cumulative_portfolio_value
    .
执行前简要说明将应用的默认设置,然后遵循以下规则:
  1. 加载
    data/stock_data/sp500.csv
    ;若文件缺失,需先询问用户,再通过
    cufolio.utils.download_data
    下载
    sp500
    数据。请勿使用通配符、替换或伪造价格数据。
  2. 求解前验证用户提供的CSV文件:要求包含类日期索引或首列为日期列、股票代码列为数值型、日期过滤后至少保留60行数据,且至少包含一个请求的股票代码。若用户指定了起始/结束日期,需在计算回报率前对价格DataFrame进行切片,并报告保留的日期范围。计算回报率前需在价格DataFrame中过滤股票代码。
    regime_dict
    不接受股票代码字段。
  3. 使用
    utils.calculate_returns(...)
    计算对数回报率。
  4. 使用
    cvar_utils.generate_cvar_data(...)
    、KDE算法及
    KDESettings(device="GPU")
    生成场景数据。
  5. 定义
    CvarParameters
    时需明确指定
    w_min
    w_max
    。对于普通的"构建最优投资组合"请求,设置
    c_min=0.0
    c_max=0.0
    ,确保结果为全资产投资而非100%现金。
  6. 直接从回报率字典构建
    cvar_optimizer.CVaR(returns_dict, cvar_params)
    ;保持股票代码、场景数组、均值和协方差的格式与cuFOLIO助手返回的一致。
  7. 仅使用NVIDIA cuOpt求解。求解前需验证
    hasattr(cp, "CUOPT")
    str(cp.CUOPT) in {str(s) for s in cp.installed_solvers()}
    。将
    SOLVER_SETTINGS
    传递给每一次单次求解或循环前沿求解。切勿回退到CLARABEL、SCS、ECOS或其他CPU求解器。若cuOpt缺失,完成验证/设置后需报告GPU/cuOpt运行时缺失,而非伪造CPU求解结果。
  8. 对于自定义约束,将用户需求映射到
    CvarParameters
    :权重上限对应
    w_min
    /
    w_max
    ,风险偏好对应
    risk_aversion
    ,置信水平对应
    confidence
    ,现金允许量对应
    c_max
    ,仅当包为工作流暴露明确的资产数量约束时才设置基数约束。若约束冲突(例如,最大权重过低,无法在请求的股票代码间分配投资),需说明冲突并请求用户放宽约束,而非自行猜测。
  9. 若用户未指定回测基准,则使用相同股票代码的等权重投资组合。若用户未指定约束,保留默认表中的值,并在求解前简要说明相关假设。
  10. 提供按配置比例排序的权重、现金权重、预期回报率、CVaR、求解器标签(
    cuOpt GPU
    ),以及任何请求的前沿图、权重表、回测指标或再平衡计划。表格需包含股票代码作为列或行,以及小数权重和百分比;绘图需保留cuFOLIO返回的图形,而非从零开始重新绘制。
  11. 对于报告级别的回答,需包含请求的工作流实际运行的证据。对于有效前沿,需说明
    len(results_df)
    并使用请求的
    ra_num
    (除非用户指定,否则默认25)。对于权重表,需将
    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
references/workflows/agent_recipes.md
before writing custom code.
python
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
Portfolio(name="cuOpt Optimal", tickers=returns_dict["tickers"], weights=optimal_portfolio.weights, cash=optimal_portfolio.cash)
, create an equal-weight
Portfolio
over the same
returns_dict["tickers"]
, then use
backtest.portfolio_backtester(..., test_method="historical").backtest_against_benchmarks(...)
. The backtester returns
(backtest_results, ax)
.
For monthly rebalancing, write the price DataFrame to a CSV path first. Instantiate
rebalance.rebalance_portfolio(dataset_directory=<csv_path>, ...)
with
re_optimize_criteria={"type": "drift_from_optimal", "threshold": 0, "norm": 1}
and call
re_optimize(transaction_cost_factor=..., plot_title="Monthly Rebalancing")
. The rebalancer returns
(results_dataframe, re_optimize_dates, cumulative_portfolio_value)
.
从以下框架开始cuFOLIO相关任务,并仅根据请求的输出进行调整。如需完整的可复制函数,请先阅读
references/workflows/agent_recipes.md
再编写自定义代码。
python
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)
,创建相同股票代码的等权重
Portfolio
,然后使用
backtest.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

数据与默认设置

SettingDefault
Dataset
data/stock_data/sp500.csv
Date rangeFull available range
Portfolio typeLong-only
Max weightNone unless specified
Risk aversion
1.0
Confidence
0.95
Scenario methodKDE on GPU
SolvercuOpt GPU with PDLP
RebalancingNone 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
utils.get_input_data
. 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.
设置项默认值
数据集
data/stock_data/sp500.csv
日期范围全部可用范围
投资组合类型仅做多
最大权重除非指定,否则无限制
风险厌恶程度
1.0
置信水平
0.95
场景生成方法GPU上的KDE算法
求解器带PDLP的cuOpt GPU
再平衡除非请求,否则不执行
默认的标普500文件为历史快照,可能不包含当前成分股。用户提供的CSV应为日期索引的价格表,列对应股票代码,且与
utils.get_input_data
兼容。若请求的股票代码不存在,需将其剔除,报告遗漏情况,并继续使用可用列,除非用户明确要求获取其他数据。

Key APIs

核心API

Use the package APIs instead of reimplementing portfolio math or simulation loops. cuFOLIO helpers return flat objects:
returns_dict
has keys such as
returns
,
mean
,
covariance
, and
tickers
; do not index it as
returns_dict["regime_1"]
.
solve_optimization_problem(...)
returns
(result_row, portfolio)
, not a nested result dictionary.
  • Returns:
    utils.calculate_returns(input_dataset, regime_dict, returns_compute_settings)
    .
  • Regime filter:
    regime_dict
    is
    None
    or
    {"name": "...", "range": ("YYYY-MM-DD", "YYYY-MM-DD")}
    ; it is not keyed by regime name and does not contain tickers.
  • 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:
    cvar_utils.create_efficient_frontier(returns_dict, cvar_params, solver_settings=SOLVER_SETTINGS, ra_num=25)
    . The returned
    results_df
    includes metrics, a
    weights
    dict column, and
    cash
    .
  • Portfolio:
    Portfolio(name="", tickers=None, weights=None, cash=0.0, time_range=None)
    ; pass tickers and a flat array-like
    weights
    aligned to those tickers.
  • Backtest: create
    portfolio.Portfolio
    objects for the optimized allocation and each benchmark; for an equal-weight benchmark, use weights of
    1 / len(tickers)
    and
    cash=0.0
    , then call
    backtest.portfolio_backtester(test_portfolio, returns_dict, risk_free_rate=0.0, test_method="historical", benchmark_portfolios=[...]).backtest_against_benchmarks(...)
    .
  • Rebalance:
    rebalance.rebalance_portfolio(...)
    requires
    dataset_directory
    to be a CSV path, not a DataFrame. Call
    re_optimize(...)
    ; it returns
    (results_dataframe, re_optimize_dates, cumulative_portfolio_value)
    .
  • Settings models:
    ReturnsComputeSettings
    ,
    ScenarioGenerationSettings
    ,
    KDESettings
    ,
    ApiSettings
    , and
    CvarParameters
    .
使用包API而非重新实现投资组合数学计算或模拟循环。cuFOLIO助手返回扁平对象:
returns_dict
包含
returns
mean
covariance
tickers
等键;请勿以
returns_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(...)
    要求
    dataset_directory
    为CSV路径,而非DataFrame。调用
    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
    CvarParameters
    , solve with cuOpt, and report diversified weights plus return/CVaR.
  • "Plot the efficient frontier": call
    create_efficient_frontier(...)
    , return
    results_df
    , and show or save the figure as requested.
  • "Give me weights by risk aversion": expand
    results_df["weights"]
    into a per-asset table.
  • "Backtest against equal weight": build the optimized and equal-weight
    Portfolio
    objects, then use the cuFOLIO backtester and report Sharpe, Sortino, and max drawdown.
  • "Backtest monthly rebalancing": configure
    rebalance_portfolio
    with the drift trigger above and run
    re_optimize(transaction_cost_factor=...)
    .
  • "从标普500构建最优投资组合":加载价格数据、计算对数回报率、生成GPU KDE场景、设置仅做多全资产投资的
    CvarParameters
    、用cuOpt求解,并报告分散化权重及回报率/CVaR。
  • "绘制有效前沿曲线":调用
    create_efficient_frontier(...)
    ,返回
    results_df
    ,并按请求显示或保存图形。
  • "给我按风险厌恶程度划分的权重":将
    results_df["weights"]
    展开为单资产权重表。
  • "与等权重组合回测对比":构建优化组合和等权重组合的
    Portfolio
    对象,使用cuFOLIO回测器,并报告Sharpe、Sortino和最大回撤。
  • "回测月度再平衡":使用上述偏离触发条件配置
    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
    FileNotFoundError
    : explain that cuFOLIO will fetch public market data with
    download_data("data/stock_data", datasets=["sp500"])
    ; run it only after user confirmation.
  • SolverError
    or missing
    cp.CUOPT
    : install the CUDA extra matching the host and verify with
    python -c "import cvxpy as cp; print(hasattr(cp, 'CUOPT'), cp.installed_solvers())"
    .
  • ImportError
    for
    cuml
    or GPU KDE failures: confirm cuML is present with
    python -c "import cuml"
    and keep
    KDESettings(device="GPU")
    .
  • Ordinary optimization returns all cash: set
    c_max=0.0
    in
    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缺失或
    FileNotFoundError
    :说明cuFOLIO将通过
    download_data("data/stock_data", datasets=["sp500"])
    获取公开市场数据;仅在用户确认后执行。
  • SolverError
    或缺失
    cp.CUOPT
    :安装与主机匹配的CUDA扩展,并通过
    python -c "import cvxpy as cp; print(hasattr(cp, 'CUOPT'), cp.installed_solvers())"
    验证。
  • cuml
    导入错误或GPU KDE失败:通过
    python -c "import cuml"
    确认cuML已安装,并保持
    KDESettings(device="GPU")
  • 普通优化返回全现金配置:在
    CvarParameters
    中设置
    c_max=0.0
  • 求解器报告不可行或无解决方案:检查是否存在矛盾的边界、请求的上限/基数对应的股票代码过少,或日期过滤后数据量不足;报告使请求可行的最小约束调整方案。
  • 请求的股票代码在默认CSV中不存在:报告遗漏情况,并继续使用剩余请求的股票代码。
  • 用户CSV验证失败:要求提供日期索引的价格表,或首列为日期、其余列为股票代码价格数值的CSV;提及过滤后至少保留60行数据的要求。