{"id":61934,"date":"2024-05-28T16:46:14","date_gmt":"2024-05-28T16:46:14","guid":{"rendered":"https:\/\/www.askpython.com\/?p=61934"},"modified":"2025-04-10T20:28:10","modified_gmt":"2025-04-10T20:28:10","slug":"python-portfolio-optimization","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python\/examples\/python-portfolio-optimization","title":{"rendered":"Python Portfolio Optimization: Maximize Returns, Minimize Risk"},"content":{"rendered":"\n<p>Portfolio optimization aims to maximize returns and minimize risks by constructing an optimal asset allocation. Python&#8217;s powerful libraries like NumPy and CVXPY enable solving this optimization problem, which is subject to constraints like target return and weight restrictions, using techniques like quadratic programming.<\/p>\n\n\n\n<p>Big investors, such as Warren Buffet and Peter Lynch, follow the portfolio approach. Even mutual funds ( after you take out taxes ) work on the same principle of portfolio theory. This article will study the Modern Portfolio theory and its optimization.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>Portfolio optimization in Python involves using libraries like NumPy and CVXPY to maximize returns and minimize risks by adjusting asset weights based on the covariance matrix and expected returns, ensuring the sum of weights equals one and all weights are non-negative.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p><strong><em>Recommended: <a href=\"https:\/\/www.askpython.com\/python\/scrape-yahoo-finance-python-scrapy\">How to Scrape Yahoo Finance Data in Python using Scrapy<\/a><\/em><\/strong><\/p>\n\n\n\n<p><strong><em>Recommended: <a href=\"https:\/\/www.askpython.com\/resources\/future-of-reits-harnessing-ai-smarter-investments\">The Future of REITs: Harnessing AI for Smarter Investments<\/a><\/em><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Portfolios<\/h2>\n\n\n\n<p>A portfolio is essentially a collection of assets with different or the same weights. It is usually constructed using the Capital Asset Pricing Model(CAPM) and utility theory, and as mentioned before, it is done to maximize returns and minimize risks. Let us now look at the formula for how a portfolio is constructed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"526\" src=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-Return-Formula.webp\" alt=\"Portfolio Return Formula\" class=\"wp-image-61935\" style=\"width:749px;height:auto\" srcset=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-Return-Formula.webp 1024w, https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-Return-Formula-300x154.webp 300w, https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-Return-Formula-768x395.webp 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><strong><em>Calculating Portfolio Returns<\/em><\/strong><\/figcaption><\/figure>\n\n\n\n<p>In the above formula, <strong><em>W<sub>i<\/sub><\/em><\/strong> and <strong><em>R<sub>i<\/sub><\/em><\/strong> represent each asset&#8217;s weights and historical returns. The summation of all the assets is our portfolio return. Let us now look at how a portfolio is optimized.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Optimizing Portfolios with Python<\/h2>\n\n\n\n<p>We use Operations Research concepts to maximize our portfolios. Our objective function is the expected return on the portfolio. Sometimes, instead of maximizing returns, we have target returns. After that, we calculate and minimize the portfolio variance and define constraints. <\/p>\n\n\n\n<p>The sum of weights of all assets should be equal to 1, and they should be non-negative. It becomes an optimization problem in Operations, and then a Simple Greedy or Brute Force approach may be applied. Let us now look at the code and understand it step by step.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport numpy as np\nimport cvxpy as cp\n<\/pre><\/div>\n\n\n<p>We have imported two Python libraries, which will be used in further calculations. The Cvxpy library, our portfolio, is generally used for optimization problems.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef portfolio_optimization(expected_returns, cov_matrix, target_return):\n    num_assets = len(expected_returns)\n    \n    # Define the variables\n    weights = cp.Variable(num_assets)\n    \n    # Define the objective function (minimize portfolio variance)\n    portfolio_variance = cp.quad_form(weights, cov_matrix)\n    objective = cp.Minimize(portfolio_variance)\n    \n    # Define the constraints\n    constraints = &#x5B;\n        cp.sum(weights) == 1,  # Sum of weights equals 1\n        weights &gt;= 0,           # Non-negativity constraint on weights\n        weights.T @ expected_returns == target_return  # Target return constraint\n    ]\n<\/pre><\/div>\n\n\n<p>In the above block, we have declared variables, expected returns, a covariance matrix, and our targeted return. We have also created an objective function, the portfolio return. Additionally, we have added constraints, like the sum of all assets should be 100% and the weights should be non-negative.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n # Formulate and solve the optimization problem\n    problem = cp.Problem(objective, constraints)\n    problem.solve()\n    \n    # Retrieve the optimal portfolio weights\n    optimal_weights = weights.value\n    \n    return optimal_weights\n\n<\/pre><\/div>\n\n\n<p>In the above block, we have used the called modules to optimize our objective function value. We have used the field of operations research in finance.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Example usage\nif __name__ == &quot;__main__&quot;:\n    # Example data\n    expected_returns = np.array(&#x5B;0.08, 0.12, 0.1])  # Expected returns of assets\n    cov_matrix = np.array(&#x5B;&#x5B;0.1, 0.03, 0.05], &#x5B;0.03, 0.12, 0.07], &#x5B;0.05, 0.07, 0.15]])  # Covariance matrix\n    target_return = 0.1  # Target return\n    \n    # Perform portfolio optimization\n    optimal_weights = portfolio_optimization(expected_returns, cov_matrix, target_return)\n    print(&quot;Optimal weights:&quot;, optimal_weights)\n<\/pre><\/div>\n\n\n<p>Finally, we have randomly created asset returns, which, by performing matrix operations, gives us a covariance matrix. Finally, we print the results of our optimized value.<\/p>\n\n\n\n<p>Let us now look at the output of the code above.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"454\" height=\"45\" src=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-optimization-output.png\" alt=\"Portfolio Optimization Output\" class=\"wp-image-61936\" srcset=\"https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-optimization-output.png 454w, https:\/\/www.askpython.com\/wp-content\/uploads\/2024\/04\/Portfolio-optimization-output-300x30.png 300w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><figcaption class=\"wp-element-caption\"><strong><em>Expected Results of Portfolio Optimization<\/em><\/strong><\/figcaption><\/figure>\n\n\n\n<p>Therefore, the assets with returns of 8%, 12%, and 10% should be constructed with weights of 45%, 45%, and 10% to maximize returns and minimize variance. Let us look at the code used to get data from Yahoo Finance and determine the weights for the optimized portfolio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Putting It All Together<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nimport pandas as pd\nimport numpy as np\nimport cvxpy as cp\n\ndef portfolio_optimization_from_excel(file_path, target_return):\n    # Read returns data from Excel file into DataFrame\n    returns_data = pd.read_excel(file_path, index_col=0)\n    \n    # Calculate expected returns\n    expected_returns = returns_data.mean()\n    \n    # Calculate covariance matrix\n    cov_matrix = returns_data.cov()\n    \n    # Number of assets\n    num_assets = len(expected_returns)\n    \n    # Define the variables\n    weights = cp.Variable(num_assets)\n    \n    # Define the objective function (minimize portfolio variance)\n    portfolio_variance = cp.quad_form(weights, cov_matrix.values)\n    objective = cp.Minimize(portfolio_variance)\n    \n    # Define the constraints\n    constraints = &#x5B;\n        cp.sum(weights) == 1,  # Sum of weights equals 1\n        weights &gt;= 0,           # Non-negativity constraint on weights\n        weights.T @ expected_returns.values == target_return  # Target return constraint\n    ]\n    \n    # Formulate and solve the optimization problem\n    problem = cp.Problem(objective, constraints)\n    problem.solve()\n    \n    # Retrieve the optimal portfolio weights\n    optimal_weights = weights.value\n    \n    return optimal_weights\n\n# Example usage\nif __name__ == &quot;__main__&quot;:\n    # Path to the Excel file containing returns data\n    file_path = &quot;returns_data.xlsx&quot;\n    \n    # Target return\n    target_return = 0.1  # Adjust as needed\n    \n    # Perform portfolio optimization\n    optimal_weights = portfolio_optimization_from_excel(file_path, target_return)\n    print(&quot;Optimal weights:&quot;, optimal_weights)\n\n<\/pre><\/div>\n\n\n<p>We can download data from Yahoo Finance and calculate the mean, variance, and covariance matrix of the assets. The process remains the same after that.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Portfolio optimization is crucial to investment management, enabling investors to achieve their desired returns while minimizing risk exposure. Python&#8217;s versatility and robust optimization libraries make it an ideal tool for implementing advanced portfolio optimization techniques, leveraging real-world data from sources like Yahoo Finance. How could you extend this approach to incorporate additional constraints or objectives specific to your investment goals?<\/p>\n\n\n\n<p><strong><em>Recommended: <a href=\"https:\/\/www.askpython.com\/python\/examples\/capm-implementation-python\">Understanding Capital Asset Pricing Model (CAPM)<\/a><\/em><\/strong><\/p>\n\n\n\n<p><strong><em>Recommended: <a href=\"https:\/\/www.askpython.com\/python\/examples\/introduction-to-jensens-inequality\">Introduction To Jensen\u2019s Inequality<\/a><\/em><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Portfolio optimization aims to maximize returns and minimize risks by constructing an optimal asset allocation. Python&#8217;s powerful libraries like NumPy and CVXPY enable solving this optimization problem, which is subject to constraints like target return and weight restrictions, using techniques like quadratic programming. Big investors, such as Warren Buffet and Peter Lynch, follow the portfolio [&hellip;]<\/p>\n","protected":false},"author":80,"featured_media":63858,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-61934","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-examples"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/61934","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/80"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=61934"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/61934\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/63858"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=61934"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=61934"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=61934"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}