Find the Best Investment Portfolio in Python

Algo Forex Lab By · · 5 min read

Imagine you have a pile of money (your starting balance) and you want to grow it over one year. But there’s a villain in the story called inflation (prices going up). Inflation makes your money buy less than before, so even if your money grows a bit, it might not feel like it grew in real life.

This program is like a robot financial coach. It tries thousands of different “money mixes” (called portfolios) using these choices:

  • Bank fixed income (very safe, small growth)
  • Gold (can grow a lot, but can bounce around)
  • Bitcoin (can grow a lot, but very bouncy)
  • Stock exchange (can grow, but can be very bouncy)
  • Cash (doesn’t really grow)

What it’s for (the goal)

The goal is to find the best mix of these choices that gives you:

  1. Good real growth (growth after inflation steals some value)
  2. Not too much risk (not too scary / bouncy)

To judge “best,” it uses a score called the Sharpe Ratio:

  • High Sharpe Ratio = “good reward for the risk you take.”
  • Low Sharpe Ratio = “you’re taking a lot of risk for not much reward.”

What it does (the actions)

  1. You type your starting money (example: 1000).
  2. It knows inflation is 5% per year, so it reduces each investment’s “growth score” by 5% to get real return.
  3. Then it tries 10,000 random mixes of the investments.
    • Like: 20% gold, 10% bitcoin, 50% stocks, 15% bank, 5% cash… and so on.
  4. For every mix it calculates:
    • Real expected return (how much it should grow after inflation)
    • Risk (how bouncy or unpredictable it is)
    • Sharpe Ratio (best “reward vs risk” score)
    • End-of-year balance (your money after one year, using that real return)
  5. It chooses the mix with the highest Sharpe Ratio and calls it the best portfolio.

What the output is

You get two kinds of output:

1) A plot (a picture with dots)

It shows 10,000 dots, one dot for each money mix the robot tried.

2) Printed results (text)

It prints:

  • The best percentage to put in each investment (weights)
  • The best portfolio’s:
    • Real expected return
    • Risk
    • Sharpe Ratio
    • End-of-year balance

So in the end, it tells you something like:

  • “Put 0.30 in Gold, 0.10 in Bitcoin, 0.50 in Stocks…”
  • “If you start with X, you’ll end with Y (after inflation-adjusted growth).”

How to read the plot (super important)

Think of the plot like a video game map of choices:

✅ The X-axis (left → right) = Risk

  • Left side = safer, less bouncy
  • Right side = riskier, more bouncy

✅ The Y-axis (down → up) = Real return

  • Higher = your money grows more after inflation
  • Lower = grows less (or can even be negative)

✅ The color of each dot = Sharpe Ratio score

  • The color bar on the side shows what colors mean.
  • Colors that represent a higher Sharpe Ratio mean “better deal for the risk.”

✅ The red dot = the best one

That red dot marks the portfolio with the highest Sharpe Ratio.
It’s basically the robot saying:

“This is the smartest risk-to-reward choice I found.”


What you should do after (what action comes next)

After you see the results, you can:

  1. Look at the red dot’s position
    • Is it too far right? (too risky for you)
    • Is it too low? (not enough growth)
  2. Read the printed weights
    • Those are the “recipe amounts” for your money mix.
  3. Compare end-of-year balance
    • That shows what your money might become in one year (based on the model).
  4. Try a different starting balance
    • If you enter a bigger or smaller number, the best “recipe” usually stays similar, but the final money changes.

Investment Portfolio Python Code

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Define assets with their expected return and risk (standard deviation)
assets = {
    'Bank_Fixed_Income': {'expected_return': 0.03, 'risk': 0.00},
    'Gold': {'expected_return': 0.50, 'risk': 0.20},
    'Bitcoin': {'expected_return': 0.60, 'risk': 0.30},
    'StockExchange': {'expected_return': 0.50, 'risk': 0.45},
    'Cash': {'expected_return': 0.00, 'risk': 0.0},
}

# Define annual inflation rate
annual_inflation = 0.05

# Define initial investment balance
initial_balance = float(input("Enter the initial investment balance: "))

# Calculate real returns by adjusting for inflation
for asset in assets:
    assets[asset]['real_return'] = assets[asset]['expected_return'] - annual_inflation

# Number of portfolios to simulate
num_portfolios = 10000
results = np.zeros((5, num_portfolios))
weights_record = []

for i in range(num_portfolios):
    weights = np.random.random(len(assets))
    weights /= np.sum(weights)
    weights_record.append(weights)

    portfolio_return = sum([weights[j] * list(assets.values())[j]['real_return'] for j in range(len(assets))])
    portfolio_risk = np.sqrt(sum([(weights[j] * list(assets.values())[j]['risk']) ** 2 for j in range(len(assets))]))
    sharpe_ratio = portfolio_return / portfolio_risk if portfolio_risk != 0 else 0
    end_of_year_balance = initial_balance * (1 + portfolio_return)

    results[0, i] = portfolio_return
    results[1, i] = portfolio_risk
    results[2, i] = sharpe_ratio
    results[3, i] = end_of_year_balance

# Get the portfolio with the maximum Sharpe ratio
max_sharpe_idx = np.argmax(results[2])
max_sharpe_portfolio = results[:, max_sharpe_idx]

# Plotting the portfolios
plt.figure(figsize=(12, 8))
plt.scatter(results[1, :], results[0, :], c=results[2, :], cmap='viridis')
plt.colorbar(label='Sharpe Ratio')
plt.scatter(max_sharpe_portfolio[1], max_sharpe_portfolio[0], c='red', s=50, edgecolors='black')
plt.title('Portfolio Performance (Adjusted for Inflation)')
plt.xlabel('Risk (Standard Deviation)')
plt.ylabel('Real Expected Return (Adjusted for Inflation)')
plt.grid(True)
plt.show()

# Display the best portfolio weights and end-of-year balance
best_weights = weights_record[max_sharpe_idx]
asset_names = list(assets.keys())
best_portfolio = {asset_names[i]: best_weights[i] for i in range(len(asset_names))}

print("Best Portfolio Weights:")
for asset, weight in best_portfolio.items():
    print(f"{asset}: {weight:.2f}")

print(f"\nReal Expected Return: {max_sharpe_portfolio[0]:.2f}")
print(f"Risk: {max_sharpe_portfolio[1]:.2f}")
print(f"Sharpe Ratio: {max_sharpe_portfolio[2]:.2f}")
print(f"End-of-Year Balance: {max_sharpe_portfolio[3]:.2f}")
Python
Expand

Hassan Safari Hassan Safari
Hassan Safari is a Forex trader, financial risk manager, and full-stack trading systems developer specializing in brokerage infrastructure and algorithmic trading. With hands-on experience in Forex brokerage operations, he works on risk management, liquidity monitoring, and MetaTrader 5 (MT5) server administration. Hassan develops automated trading tools and investment platforms using Python, JavaScript, and PHP, combining financial market expertise with advanced technical execution. His work focuses on building secure, scalable, and risk-optimized trading environments for brokers and investors.