{"id":13533772,"url":"https://github.com/skfolio/skfolio","last_synced_at":"2026-03-15T03:22:54.083Z","repository":{"id":212560988,"uuid":"731792488","full_name":"skfolio/skfolio","owner":"skfolio","description":"Python library for portfolio optimization built on top of scikit-learn","archived":false,"fork":false,"pushed_at":"2025-04-17T09:08:42.000Z","size":127668,"stargazers_count":1451,"open_issues_count":19,"forks_count":129,"subscribers_count":26,"default_branch":"main","last_synced_at":"2025-05-07T23:45:43.514Z","etag":null,"topics":["asset-allocation","asset-management","convex-optimization","cvar-optimization","cvxpy","efficient-frontier","hierarchical-clustering","machine-learning","portfolio","portfolio-optimization","quantitative-finance","quantitative-investment","risk-parity","scikit-learn","trading-strategies"],"latest_commit_sha":null,"homepage":"https://skfolio.org","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skfolio.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-14T22:24:42.000Z","updated_at":"2025-05-06T06:19:29.000Z","dependencies_parsed_at":"2024-01-02T00:48:09.790Z","dependency_job_id":"76156397-05f8-4f6c-b7bc-07e8986083cb","html_url":"https://github.com/skfolio/skfolio","commit_stats":{"total_commits":147,"total_committers":13,"mean_commits":"11.307692307692308","dds":"0.33333333333333337","last_synced_commit":"09af26457c2a669eae5e19a88d2c8b58df795ccd"},"previous_names":["skfolio/skfolio"],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skfolio%2Fskfolio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skfolio%2Fskfolio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skfolio%2Fskfolio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skfolio%2Fskfolio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skfolio","download_url":"https://codeload.github.com/skfolio/skfolio/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254040560,"owners_count":22004565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asset-allocation","asset-management","convex-optimization","cvar-optimization","cvxpy","efficient-frontier","hierarchical-clustering","machine-learning","portfolio","portfolio-optimization","quantitative-finance","quantitative-investment","risk-parity","scikit-learn","trading-strategies"],"created_at":"2024-08-01T07:01:22.927Z","updated_at":"2026-03-08T23:02:15.702Z","avatar_url":"https://github.com/skfolio.png","language":"Python","funding_links":[],"categories":["Analytic tools","Python","Curated List","Strategies \u0026 Research"],"sub_categories":["Optimization","Trading \u0026 Backtesting","交易与回测","Analytics","Portfolio Management"],"readme":".. -*- mode: rst -*-\n\n|Licence| |Codecov| |Black| |PythonVersion| |PyPi| |CI/CD| |Downloads| |Ruff| |Contribution| |Website| |JupyterLite| |Discord| |DOI|\n\n.. |Licence| image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg\n   :target: https://github.com/skfolio/skfolio/blob/main/LICENSE\n\n.. |Codecov| image:: https://codecov.io/gh/skfolio/skfolio/graph/badge.svg?token=KJ0SE4LHPV\n   :target: https://codecov.io/gh/skfolio/skfolio\n\n.. |PythonVersion| image:: https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg\n   :target: https://pypi.org/project/skfolio/\n\n.. |PyPi| image:: https://img.shields.io/pypi/v/skfolio\n   :target: https://pypi.org/project/skfolio\n\n.. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n   :target: https://github.com/psf/black\n\n.. |CI/CD| image:: https://img.shields.io/github/actions/workflow/status/skfolio/skfolio/release.yml.svg?logo=github\n   :target: https://github.com/skfolio/skfolio/raw/main/LICENSE\n\n.. |Downloads| image:: https://static.pepy.tech/badge/skfolio\n   :target: https://pepy.tech/project/skfolio\n\n.. |Ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\n   :target: https://github.com/astral-sh/ruff\n\n.. |Contribution| image:: https://img.shields.io/badge/Contributions-Welcome-blue\n   :target: https://github.com/skfolio/skfolio/blob/main/CONTRIBUTING.md\n\n.. |Website| image:: https://img.shields.io/website.svg?down_color=red\u0026down_message=down\u0026up_color=53cc0d\u0026up_message=up\u0026url=https://skfolio.org\n   :target: https://skfolio.org\n\n.. |JupyterLite| image:: https://jupyterlite.rtfd.io/en/latest/_static/badge.svg\n   :target: https://skfolio.org/lite\n\n.. |Discord| image:: https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord\u0026logoColor=white\n   :target: https://discord.gg/Bu7EtNYugS\n\n.. |DOI| image:: https://zenodo.org/badge/731792488.svg\n   :target: https://doi.org/10.5281/zenodo.16148630\n\n.. |PythonMinVersion| replace:: 3.10\n.. |NumpyMinVersion| replace:: 1.23.4\n.. |ScipyMinVersion| replace:: 1.8.0\n.. |PandasMinVersion| replace:: 1.4.1\n.. |CvxpyBaseMinVersion| replace:: 1.5.0\n.. |ClarabelMinVersion| replace:: 0.9.0\n.. |SklearnMinVersion| replace:: 1.6.0\n.. |JoblibMinVersion| replace:: 1.3.2\n.. |PlotlyMinVersion| replace:: 5.22.0\n\n\n===============\n|icon|  skfolio\n===============\n.. |icon| image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/logo_animate.svg\n    :width: 100\n    :alt: skfolio documentation\n    :target: https://skfolio.org/\n\n\n**skfolio** is a Python library for portfolio optimization and risk management built on\ntop of scikit-learn. It offers a unified interface and tools compatible with\nscikit-learn to build, fine-tune, cross-validate and stress-test portfolio models.\n\nIt is distributed under the open-source 3-Clause BSD license.\n\n**skfolio**  is backed by `Skfolio Labs \u003chttps://skfoliolabs.com\u003e`_, which provides enterprise support and SLAs for\ninstitutions.\n\n.. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg\n    :target: https://skfolio.org/auto_examples/\n    :alt: examples\n\nImportant links\n~~~~~~~~~~~~~~~\n\n- `Documentation \u003chttps://skfolio.org/\u003e`_\n- `Examples \u003chttps://skfolio.org/auto_examples/\u003e`_\n- `User Guide \u003chttps://skfolio.org/user_guide/\u003e`_\n- `GitHub Repo \u003chttps://github.com/skfolio/skfolio\u003e`_\n- `Enterprise Support \u003chttps://skfoliolabs.com\u003e`_\n\nFeatured in\n~~~~~~~~~~~\n\n* `Portfolio Optimization: Theory and Application \u003chttps://portfoliooptimizationbook.com/\u003e`_ by Daniel P. Palomar, includes Python code examples using skfolio.\n\nInstallation\n~~~~~~~~~~~~\n\n`skfolio` is available on PyPI and can be installed with::\n\n    pip install -U skfolio\n\n\nDependencies\n~~~~~~~~~~~~\n\n`skfolio` requires:\n\n- python (\u003e= |PythonMinVersion|)\n- numpy (\u003e= |NumpyMinVersion|)\n- scipy (\u003e= |ScipyMinVersion|)\n- pandas (\u003e= |PandasMinVersion|)\n- cvxpy-base (\u003e= |CvxpyBaseMinVersion|)\n- clarabel (\u003e= |ClarabelMinVersion|)\n- scikit-learn (\u003e= |SklearnMinVersion|)\n- joblib (\u003e= |JoblibMinVersion|)\n- plotly (\u003e= |PlotlyMinVersion|)\n\nDocker\n~~~~~~\n\nYou can also spin up a reproducible JupyterLab environment using Docker:\n\nBuild the image::\n\n    docker build -t skfolio-jupyterlab .\n\nRun the container::\n\n    docker run -p 8888:8888 -v \u003cpath-to-your-folder-containing-data\u003e:/app/data -it skfolio-jupyterlab\n\nBrowse:\n\nOpen localhost:8888/lab and start using `skfolio`\n\nKey Concepts\n~~~~~~~~~~~~\nSince the development of modern portfolio theory by Markowitz (1952), mean-variance\noptimization (MVO) has received considerable attention.\n\nUnfortunately, it faces a number of shortcomings, including high sensitivity to the\ninput parameters (expected returns and covariance), weight concentration, high turnover,\nand poor out-of-sample performance.\n\nIt is well-known that naive allocation (1/N, inverse-vol, etc.) tends to outperform\nMVO out-of-sample (DeMiguel, 2007).\n\nNumerous approaches have been developed to alleviate these shortcomings (shrinkage,\nadditional constraints, regularization, uncertainty set, higher moments, Bayesian\napproaches, coherent risk measures, left-tail risk optimization, distributionally robust\noptimization, factor model, risk-parity, hierarchical clustering, ensemble methods,\npre-selection, etc.).\n\nGiven the large number of methods, and the fact that they can be combined, there is a\nneed for a unified framework with a machine-learning approach to perform model\nselection, validation, and parameter tuning while mitigating the risk of data leakage\nand overfitting.\n\nThis framework is built on scikit-learn's API.\n\nAvailable models\n~~~~~~~~~~~~~~~~\n\n* Portfolio Optimization:\n    * Naive:\n        * Equal-Weighted\n        * Inverse-Volatility\n        * Random (Dirichlet)\n    * Convex:\n        * Mean-Risk\n        * Risk Budgeting\n        * Maximum Diversification\n        * Distributionally Robust CVaR\n        * Benchmark Tracker\n    * Clustering:\n        * Hierarchical Risk Parity\n        * Hierarchical Equal Risk Contribution\n        * Schur Complementary Allocation\n        * Nested Clusters Optimization\n    * Ensemble Methods:\n        * Stacking Optimization\n\n* Expected Returns Estimator:\n    * Empirical\n    * Exponentially Weighted\n    * Equilibrium\n    * Shrinkage\n\n* Covariance Estimator:\n    * Empirical\n    * Gerber\n    * Denoising\n    * Detoning\n    * Exponentially Weighted\n    * Ledoit-Wolf\n    * Oracle Approximating Shrinkage\n    * Shrunk Covariance\n    * Graphical Lasso CV\n    * Implied Covariance\n\n* Distance Estimator:\n    * Pearson Distance\n    * Kendall Distance\n    * Spearman Distance\n    * Covariance Distance (based on any of the above covariance estimators)\n    * Distance Correlation\n    * Variation of Information\n\n* Distribution Estimator:\n    * Univariate:\n        * Gaussian\n        * Student's t\n        * Johnson Su\n        * Normal Inverse Gaussian\n    * Bivariate Copula\n        * Gaussian Copula\n        * Student's t Copula\n        * Clayton Copula\n        * Gumbel Copula\n        * Joe Copula\n        * Independent Copula\n    * Multivariate\n        * Vine Copula (Regular, Centered, Clustered, Conditional Sampling)\n\n* Prior Estimator:\n    * Empirical\n    * Black \u0026 Litterman\n    * Factor Model\n    * Synthetic Data (Stress Test, Factor Stress Test)\n    * Entropy Pooling\n    * Opinion Pooling\n\n* Uncertainty Set Estimator:\n    * On Expected Returns:\n        * Empirical\n        * Circular Bootstrap\n    * On Covariance:\n        * Empirical\n        * Circular Bootstrap\n\n* Pre-Selection Transformer:\n    * Non-Dominated Selection\n    * Select K Extremes (Best or Worst)\n    * Drop Highly Correlated Assets\n    * Select Non-Expiring Assets\n    * Select Complete Assets (handle late inception, delisting, etc.)\n    * Drop Zero Variance\n\n* Cross-Validation and Model Selection:\n    * Compatible with all `sklearn` methods (KFold, etc.)\n    * Walk Forward\n    * Combinatorial Purged Cross-Validation\n    * Multiple Randomized Cross-Validation\n\n* Hyper-Parameter Tuning:\n    * Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV)\n\n* Risk Measures:\n    * Variance\n    * Semi-Variance\n    * Mean Absolute Deviation\n    * First Lower Partial Moment\n    * CVaR (Conditional Value at Risk)\n    * EVaR (Entropic Value at Risk)\n    * Worst Realization\n    * CDaR (Conditional Drawdown at Risk)\n    * Maximum Drawdown\n    * Average Drawdown\n    * EDaR (Entropic Drawdown at Risk)\n    * Ulcer Index\n    * Gini Mean Difference\n    * Value at Risk\n    * Drawdown at Risk\n    * Entropic Risk Measure\n    * Fourth Central Moment\n    * Fourth Lower Partial Moment\n    * Skew\n    * Kurtosis\n\n* Optimization Features:\n    * Minimize Risk\n    * Maximize Returns\n    * Maximize Utility\n    * Maximize Ratio\n    * Transaction Costs\n    * Management Fees\n    * L1 and L2 Regularization\n    * Weight Constraints\n    * Group Constraints\n    * Budget Constraints\n    * Tracking Error Constraints\n    * Turnover Constraints\n    * Cardinality and Group Cardinality Constraints\n    * Threshold (Long and Short) Constraints\n\nQuickstart\n~~~~~~~~~~\nThe code snippets below are designed to introduce the functionality of `skfolio` so you\ncan start using it quickly. It follows the same API as scikit-learn.\n\nImports\n-------\n.. code-block:: python\n\n    from sklearn import set_config\n    from sklearn.model_selection import (\n        GridSearchCV,\n        KFold,\n        RandomizedSearchCV,\n        train_test_split,\n    )\n    from sklearn.pipeline import Pipeline\n    from scipy.stats import loguniform\n\n    from skfolio import RatioMeasure, RiskMeasure\n    from skfolio.datasets import load_factors_dataset, load_sp500_dataset\n    from skfolio.distribution import VineCopula\n    from skfolio.model_selection import (\n        CombinatorialPurgedCV,\n        WalkForward,\n        cross_val_predict,\n    )\n    from skfolio.moments import (\n        DenoiseCovariance,\n        DetoneCovariance,\n        EWMu,\n        GerberCovariance,\n        ShrunkMu,\n    )\n    from skfolio.optimization import (\n        MeanRisk,\n        HierarchicalRiskParity,\n        NestedClustersOptimization,\n        ObjectiveFunction,\n        RiskBudgeting,\n    )\n    from skfolio.pre_selection import SelectKExtremes\n    from skfolio.preprocessing import prices_to_returns\n    from skfolio.prior import (\n        BlackLitterman,\n        EmpiricalPrior,\n        EntropyPooling,\n        FactorModel,\n        OpinionPooling,\n        SyntheticData,\n     )\n    from skfolio.uncertainty_set import BootstrapMuUncertaintySet\n\nLoad Dataset\n------------\n.. code-block:: python\n\n    prices = load_sp500_dataset()\n\nTrain/Test split\n----------------\n.. code-block:: python\n\n    X = prices_to_returns(prices)\n    X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)\n\n\nMinimum Variance\n----------------\n.. code-block:: python\n\n    model = MeanRisk()\n\nFit on Training Set\n-------------------\n.. code-block:: python\n\n    model.fit(X_train)\n\n    print(model.weights_)\n\nPredict on Test Set\n-------------------\n.. code-block:: python\n\n    portfolio = model.predict(X_test)\n\n    print(portfolio.annualized_sharpe_ratio)\n    print(portfolio.summary())\n\n\n\nMaximum Sortino Ratio\n---------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        risk_measure=RiskMeasure.SEMI_VARIANCE,\n    )\n\n\nDenoised Covariance \u0026 Shrunk Expected Returns\n---------------------------------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        prior_estimator=EmpiricalPrior(\n            mu_estimator=ShrunkMu(), covariance_estimator=DenoiseCovariance()\n        ),\n    )\n\nUncertainty Set on Expected Returns\n-----------------------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        mu_uncertainty_set_estimator=BootstrapMuUncertaintySet(),\n    )\n\n\nWeight Constraints \u0026 Transaction Costs\n--------------------------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        min_weights={\"AAPL\": 0.10, \"JPM\": 0.05},\n        max_weights=0.8,\n        transaction_costs={\"AAPL\": 0.0001, \"RRC\": 0.0002},\n        groups=[\n            [\"Equity\"] * 3 + [\"Fund\"] * 5 + [\"Bond\"] * 12,\n            [\"US\"] * 2 + [\"Europe\"] * 8 + [\"Japan\"] * 10,\n        ],\n        linear_constraints=[\n            \"Equity \u003c= 0.5 * Bond\",\n            \"US \u003e= 0.1\",\n            \"Europe \u003e= 0.5 * Fund\",\n            \"Japan \u003c= 1\",\n        ],\n    )\n    model.fit(X_train)\n\n\nRisk Parity on CVaR\n-------------------\n.. code-block:: python\n\n    model = RiskBudgeting(risk_measure=RiskMeasure.CVAR)\n\nRisk Parity \u0026 Gerber Covariance\n-------------------------------\n.. code-block:: python\n\n    model = RiskBudgeting(\n        prior_estimator=EmpiricalPrior(covariance_estimator=GerberCovariance())\n    )\n\nNested Cluster Optimization with Cross-Validation and Parallelization\n---------------------------------------------------------------------\n.. code-block:: python\n\n    model = NestedClustersOptimization(\n        inner_estimator=MeanRisk(risk_measure=RiskMeasure.CVAR),\n        outer_estimator=RiskBudgeting(risk_measure=RiskMeasure.VARIANCE),\n        cv=KFold(),\n        n_jobs=-1,\n    )\n\nRandomized Search of the L2 Norm\n--------------------------------\n.. code-block:: python\n\n    randomized_search = RandomizedSearchCV(\n        estimator=MeanRisk(),\n        cv=WalkForward(train_size=252, test_size=60),\n        param_distributions={\n            \"l2_coef\": loguniform(1e-3, 1e-1),\n        },\n    )\n    randomized_search.fit(X_train)\n\n    best_model = randomized_search.best_estimator_\n\n    print(best_model.weights_)\n\n\nGrid Search on Embedded Parameters\n----------------------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        risk_measure=RiskMeasure.VARIANCE,\n        prior_estimator=EmpiricalPrior(mu_estimator=EWMu(alpha=0.2)),\n    )\n\n    print(model.get_params(deep=True))\n\n    gs = GridSearchCV(\n        estimator=model,\n        cv=KFold(n_splits=5, shuffle=False),\n        n_jobs=-1,\n        param_grid={\n            \"risk_measure\": [\n                RiskMeasure.VARIANCE,\n                RiskMeasure.CVAR,\n                RiskMeasure.VARIANCE.CDAR,\n            ],\n            \"prior_estimator__mu_estimator__alpha\": [0.05, 0.1, 0.2, 0.5],\n        },\n    )\n    gs.fit(X)\n\n    best_model = gs.best_estimator_\n\n    print(best_model.weights_)\n\n\nBlack \u0026 Litterman Model\n-----------------------\n.. code-block:: python\n\n    views = [\"AAPL - BBY == 0.03 \", \"CVX - KO == 0.04\", \"MSFT == 0.06 \"]\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        prior_estimator=BlackLitterman(views=views),\n    )\n\nFactor Model\n------------\n.. code-block:: python\n\n    factor_prices = load_factors_dataset()\n\n    X, factors = prices_to_returns(prices, factor_prices)\n    X_train, X_test, factors_train, factors_test = train_test_split(\n        X, factors, test_size=0.33, shuffle=False\n    )\n\n    model = MeanRisk(prior_estimator=FactorModel())\n    model.fit(X_train, factors_train)\n\n    print(model.weights_)\n\n    portfolio = model.predict(X_test)\n\n    print(portfolio.calmar_ratio)\n    print(portfolio.summary())\n\nFactor Model \u0026 Covariance Detoning\n----------------------------------\n.. code-block:: python\n\n    model = MeanRisk(\n        prior_estimator=FactorModel(\n            factor_prior_estimator=EmpiricalPrior(covariance_estimator=DetoneCovariance())\n        )\n    )\n\nBlack \u0026 Litterman Factor Model\n------------------------------\n.. code-block:: python\n\n    factor_views = [\"MTUM - QUAL == 0.03 \", \"VLUE == 0.06\"]\n    model = MeanRisk(\n        objective_function=ObjectiveFunction.MAXIMIZE_RATIO,\n        prior_estimator=FactorModel(\n            factor_prior_estimator=BlackLitterman(views=factor_views),\n        ),\n    )\n\nPre-Selection Pipeline\n----------------------\n.. code-block:: python\n\n    set_config(transform_output=\"pandas\")\n    model = Pipeline(\n        [\n            (\"pre_selection\", SelectKExtremes(k=10, highest=True)),\n            (\"optimization\", MeanRisk()),\n        ]\n    )\n    model.fit(X_train)\n\n    portfolio = model.predict(X_test)\n\n\n\n\nK-fold Cross-Validation\n-----------------------\n.. code-block:: python\n\n    model = MeanRisk()\n    mmp = cross_val_predict(model, X_test, cv=KFold(n_splits=5))\n    # mmp is the predicted MultiPeriodPortfolio object composed of 5 Portfolios (1 per testing fold)\n\n    mmp.plot_cumulative_returns()\n    print(mmp.summary())\n\n\nCombinatorial Purged Cross-Validation\n-------------------------------------\n.. code-block:: python\n\n    model = MeanRisk()\n\n    cv = CombinatorialPurgedCV(n_folds=10, n_test_folds=2)\n\n    print(cv.summary(X_train))\n\n    population = cross_val_predict(model, X_train, cv=cv)\n\n    population.plot_distribution(\n        measure_list=[RatioMeasure.SHARPE_RATIO, RatioMeasure.SORTINO_RATIO]\n    )\n    population.plot_cumulative_returns()\n    print(population.summary())\n\n\nMinimum CVaR Optimization on Synthetic Returns\n----------------------------------------------\n.. code-block:: python\n\n    vine = VineCopula(log_transform=True, n_jobs=-1)\n    prior = SyntheticData(distribution_estimator=vine, n_samples=2000)\n    model = MeanRisk(risk_measure=RiskMeasure.CVAR, prior_estimator=prior)\n    model.fit(X)\n    print(model.weights_)\n\n\nStress Test\n-----------\n.. code-block:: python\n\n    vine = VineCopula(log_transform=True, central_assets=[\"BAC\"], n_jobs=-1)\n    vine.fit(X)\n    X_stressed = vine.sample(n_samples=10_000, conditioning = {\"BAC\": -0.2})\n    ptf_stressed = model.predict(X_stressed)\n\n\nMinimum CVaR Optimization on Synthetic Factors\n----------------------------------------------\n.. code-block:: python\n\n    vine = VineCopula(central_assets=[\"QUAL\"], log_transform=True, n_jobs=-1)\n    factor_prior = SyntheticData(\n        distribution_estimator=vine,\n        n_samples=10_000,\n        sample_args=dict(conditioning={\"QUAL\": -0.2}),\n    )\n    factor_model = FactorModel(factor_prior_estimator=factor_prior)\n    model = MeanRisk(risk_measure=RiskMeasure.CVAR, prior_estimator=factor_model)\n    model.fit(X, factors)\n    print(model.weights_)\n\n\nFactor Stress Test\n------------------\n.. code-block:: python\n\n    factor_model.set_params(factor_prior_estimator__sample_args=dict(\n        conditioning={\"QUAL\": -0.5}\n    ))\n    factor_model.fit(X, factors)\n    stressed_dist = factor_model.return_distribution_\n    stressed_ptf = model.predict(stressed_dist)\n\nEntropy Pooling\n---------------\n.. code-block:: python\n\n    entropy_pooling = EntropyPooling(\n        mean_views=[\n            \"JPM == -0.002\",\n            \"PG \u003e= LLY\",\n            \"BAC \u003e= prior(BAC) * 1.2\",\n        ],\n        cvar_views=[\n            \"GE == 0.08\",\n        ],\n    )\n    entropy_pooling.fit(X)\n    print(entropy_pooling.relative_entropy_)\n    print(entropy_pooling.effective_number_of_scenarios_)\n    print(entropy_pooling.return_distribution_.sample_weight)\n\nCVaR Hierarchical Risk Parity optimization on Entropy Pooling\n-------------------------------------------------------------\n.. code-block:: python\n\n    entropy_pooling = EntropyPooling(cvar_views=[\"GE == 0.08\"])\n    model = HierarchicalRiskParity(\n        risk_measure=RiskMeasure.CVAR,\n        prior_estimator=entropy_pooling\n    )\n    model.fit(X)\n    print(model.weights_)\n\nStress Test with Entropy Pooling on Factor Synthetic Data\n---------------------------------------------------------\n.. code-block:: python\n\n    # Regular Vine Copula and sampling of 100,000 synthetic factor returns\n    factor_synth = SyntheticData(\n        n_samples=100_000,\n        distribution_estimator=VineCopula(log_transform=True, n_jobs=-1, random_state=0)\n    )\n\n    # Entropy Pooling by imposing a CVaR-95% of 10% on the Quality factor\n    factor_entropy_pooling = EntropyPooling(\n        prior_estimator=factor_synth,\n        cvar_views=[\"QUAL == 0.10\"],\n    )\n\n    factor_entropy_pooling.fit(X, factors)\n\n    # We retrieve the stressed distribution:\n    stressed_dist = factor_model.return_distribution_\n\n    # We stress-test our portfolio:\n    stressed_ptf = model.predict(stressed_dist)\n\nOpinion Pooling\n---------------\n.. code-block:: python\n\n    # We consider two expert opinions, each generated via Entropy Pooling with\n    # user-defined views.\n    # We assign probabilities of 40% to Expert 1, 50% to Expert 2, and by default\n    # the remaining 10% is allocated to the prior distribution:\n    opinion_1 = EntropyPooling(cvar_views=[\"AMD == 0.10\"])\n    opinion_2 = EntropyPooling(\n        mean_views=[\"AMD \u003e= BAC\", \"JPM \u003c= prior(JPM) * 0.8\"],\n        cvar_views=[\"GE == 0.12\"],\n    )\n\n    opinion_pooling = OpinionPooling(\n        estimators=[(\"opinion_1\", opinion_1), (\"opinion_2\", opinion_2)],\n        opinion_probabilities=[0.4, 0.5],\n    )\n\n    opinion_pooling.fit(X)\n\n\nRecognition\n~~~~~~~~~~~\n\nWe would like to thank all contributors to our direct dependencies, such as\n`scikit-learn \u003chttps://github.com/scikit-learn/scikit-learn\u003e`_ and `cvxpy \u003chttps://github.com/cvxpy/cvxpy\u003e`_, as well as the contributors of the following resources:\n\n    * PyPortfolioOpt\n    * Riskfolio-Lib\n    * scikit-portfolio\n    * statsmodels\n    * rsome\n    * `Microprediction \u003chttps://github.com/microprediction\u003e`_ (Peter Cotton)\n    * `Portfolio Optimization Book \u003chttps://portfoliooptimizationbook.com/\u003e`_ (Daniel P. Palomar)\n    * `quantresearch.org \u003chttps://quantresearch.org\u003e`_ (Marcos López de Prado)\n    * gautier.marti.ai (Gautier Marti)\n\n\nCitation\n~~~~~~~~\n\nIf you use `skfolio` in a scientific publication, we would appreciate citations:\n\n**The library:**\n\n.. code-block:: bibtex\n\n        @software{skfolio,\n          title     = {skfolio},\n          author    = {Delatte, Hugo and Nicolini, Carlo and Manzi, Matteo},\n          year      = {2024},\n          doi       = {10.5281/zenodo.16148630},\n          url       = {https://doi.org/10.5281/zenodo.16148630}\n        }\n\nThe above uses the concept DOI, which always resolves to the latest release.\nIf you need precise reproducibility, especially for journals or conferences that require\nit, you can cite the version-specific DOI for the exact release you used. To find it,\ngo to our `Zenodo project page \u003chttps://doi.org/10.5281/zenodo.16148630\u003e`_, locate the\nrelease you wish to reference (e.g. \"v0.10.2\"), and copy the DOI listed next to that\nversion.\n\n**The paper:**\n\n.. code-block:: bibtex\n\n        @article{nicolini2025skfolio,\n          title         = {skfolio: Portfolio Optimization in Python},\n          author        = {Nicolini, Carlo and Manzi, Matteo and Delatte, Hugo},\n          journal       = {arXiv preprint arXiv:2507.04176},\n          year          = {2025},\n          eprint        = {2507.04176},\n          archivePrefix = {arXiv},\n          url           = {https://arxiv.org/abs/2507.04176}\n        }\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskfolio%2Fskfolio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskfolio%2Fskfolio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskfolio%2Fskfolio/lists"}