Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
left-nullspace authored Jul 22, 2024
0 parents commit 4c85cb8
Show file tree
Hide file tree
Showing 5 changed files with 531 additions and 0 deletions.
93 changes: 93 additions & 0 deletions OptContentManager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

#storing all the big bodies of text here for the optimization tool
class OptContent:

@staticmethod
def howToUse():
return """
### Step-by-Step Instructions for Using the Portfolio Optimizer:
**1. Set Start and End Date:**
- Go to the sidebar and set the start and end dates for the period over which you want to analyze and optimize your portfolio. These dates define the historical data range that will be used for calculations.
**2. Set Initial Portfolio Value:**
- Specify how much money you're starting with in your portfolio. This is your initial investment amount. Enter this value in the sidebar.
**3. Set Benchmark:**
- Choose a benchmark ETF from the sidebar dropdown. This ETF is what we'll compare our portfolio's performance against. It helps to see if our optimized portfolio is performing better or worse than a common market index or a standard investment choice.
**4. Enter Stock Tickers:**
- Input the symbols of the stocks or assets you want to include in your portfolio in a comma-separated list. For example, you might enter: `SPY, TLT, GLD, AAPL, TSLA, QQQ, BTC-USD`. These tickers represent the assets you're considering for investment, and you can find valid ticker symbols on financial websites like [Yahoo Finance](https://finance.yahoo.com/).
**5. Select 'Optimize Portfolio' and Analyze the Results:**
- After entering your data, click the 'Optimize Portfolio' button. This will calculate and display the optimal allocations for two types of portfolios:
- **Maximum Sharpe Ratio Portfolio:** Best Return/Risk ratio — think of it as a choice for the more adventurous investor.
- **Minimum Volatility Portfolio:** Lowest possible risk for the expected return. It's great for more conservative investors who prefer stability, like someone who prioritizes preservation of capital over high returns.
"""

@staticmethod
def importantDefinitions():
return """
### Portfolio Insights:
**Understanding the Process:**
- We calculate returns and risks for various asset weightings, plotting them on a scatter plot. Through **optimization**, we identify the 'Efficient Frontier' — the best return for a given risk level. From this, we derive the **Maximum Sharpe Ratio** portfolio, which offers the highest return per unit of risk. Learn more about the Efficient Frontier [here](https://www.investopedia.com/terms/e/efficientfrontier.asp).
**📈 Maximum Sharpe Ratio Portfolio:**
- This portfolio provides the best risk-adjusted return. For instance, a Sharpe ratio of 1.5 means 1.5 units of gain for each unit of risk. It's ideal for those seeking maximum growth with controlled risk.
**🛡️ Minimum Volatility Portfolio:**
- Designed to minimize risk for a given return level, this portfolio is suited for risk-averse investors seeking stability.
**📊 Analyze Performances:**
- View the historically backtested performance of these portfolios over your selected period to see potential long-term growth.
"""


@staticmethod
def exampleWalkthrough():
return """
### Example Walkthrough: Optimizing a Diverse Portfolio
#### Process:
1. **Stock Tickers Entered:** `SPY, TLT, GLD, BTC-USD, TSLA, QQQ`
- These represent a mix of asset classes including large-cap stocks (SPY, QQQ), government bonds (TLT), gold (GLD), cryptocurrency (BTC-USD), and high-tech stocks (TSLA).
2. **Select Date Range:**
- Choose a historical period over which you want to analyze and optimize the portfolio. The start date will automatically adjust to the earliest date for which all selected assets have available data. This ensures that the analysis is based on a complete dataset for all included assets.
3. **Enter Initial Portfolio Value:**
- Set an amount you are planning to invest. This could be any starting value that fits your investment plan.
4. **Optimize Portfolio:**
- Click on the 'Optimize Portfolio' button to generate the optimal asset allocations based on historical data.
#### Analyzing Results:
- The tool uses the data from the specified period to calculate two main types of portfolios: Maximum Sharpe Ratio and Minimum Volatility. Lets go through an example output:
**📈 Maximum Sharpe Ratio Portfolio:**
- This portfolio configuration is designed to offer the highest return for the risk taken.
- **Weights:**
- `QQQ`: 43% (Tech-heavy stocks indicating a preference for growth)
- `GLD`: 32% (Gold, typically a safe haven during market turbulence)
- `BTC-USD`: 21% (High-risk, high-reward asset)
- `TSLA`: 4% (High growth potential but volatile)
- `TLT`: 0% (No allocation to bonds, indicating a more aggressive strategy)
- `SPY`: 0% (No allocation to broad market index, focusing on more specific sectors)
- The absence of traditional bonds and broad market indices like SPY in this portfolio highlights a strategic focus on higher growth and technology-oriented assets.
**🛡️ Minimum Volatility Portfolio:**
- This portfolio aims to minimize risk while providing reasonable returns.
- **Weights:**
- `TLT`: 37% (Heavy allocation towards bonds, emphasizing safety)
- `SPY`: 34% (Stable, broad market exposure)
- `GLD`: 29% (Continued preference for the stability of gold)
- `BTC-USD`: 0% (Avoids the volatility of cryptocurrencies)
- `QQQ`: 0% (No exposure to tech-heavy stocks, reducing risk)
- `TSLA`: 0% (Avoids the high volatility associated with Tesla)
- The focus on bonds and gold, with no allocation towards high-volatility assets like tech stocks or cryptocurrencies, suggests a conservative approach, aiming to preserve capital with minimal fluctuations.
**Blended Strategy:**
- While each portfolio targets specific risk preferences, a blended approach may appeal to investors looking for a balance between growth and safety.
By combining elements of both the Maximum Sharpe Ratio and Minimum Volatility portfolios, investors can tailor their exposure to match their individual risk tolerance and investment goals.
"""
83 changes: 83 additions & 0 deletions PortfolioUtils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import pandas as pd
import numpy as np
import yfinance as yf

def load_and_prepare_data(ticker, start_date, end_date):
df = yf.download(ticker, start=start_date, end=end_date)
df.reset_index(inplace=True)
df['Date'] = pd.to_datetime(df['Date'])
return df

def rebalance_portfolio(file_paths,
benchmark_file_path,
initial_balance,
asset_weights,
rebalance_period,
start_date=None,
end_date=None):
datasets = [load_and_prepare_data(file_path, start_date, end_date) for file_path in file_paths]
benchmark_data = load_and_prepare_data(benchmark_file_path, start_date, end_date)
period_length = {
'annually': 12,
'semi-annually': 6,
'quarterly': 3,
'monthly': 1,
'none': np.inf
}[rebalance_period]

portfolio_balance = initial_balance
benchmark_balance = initial_balance
asset_balances = [weight * initial_balance for weight in asset_weights]

common_dates = sorted(set.intersection(*(set(df['Date']) for df in datasets), set(benchmark_data['Date'])))
common_dates = [date for date in common_dates if (start_date is None or date >= pd.to_datetime(start_date)) and (end_date is None or date <= pd.to_datetime(end_date))]

start_date = common_dates[0]
last_rebalance_date = start_date

portfolio_history = []
benchmark_history = []
rebalance_dates = []

for date in common_dates:
if date <= start_date:
continue

for i, df in enumerate(datasets):
previous_price = df.loc[df['Date'] < date, 'Adj Close'].iloc[-1]
current_price = df.loc[df['Date'] == date, 'Adj Close'].iloc[0]
asset_balances[i] *= current_price / previous_price

previous_price = benchmark_data.loc[benchmark_data['Date'] < date, 'Adj Close'].iloc[-1]
current_price = benchmark_data.loc[benchmark_data['Date'] == date, 'Adj Close'].iloc[0]
benchmark_balance *= current_price / previous_price

portfolio_balance = sum(asset_balances)

portfolio_history.append({'Date': date, 'Balance': portfolio_balance})
benchmark_history.append({'Date': date, 'Balance': benchmark_balance})

months_since_last_rebalance = (date.year - last_rebalance_date.year) * 12 + (date.month - last_rebalance_date.month)
if months_since_last_rebalance >= period_length:
desired_balances = [weight * portfolio_balance for weight in asset_weights]
asset_balances = desired_balances
last_rebalance_date = date
rebalance_dates.append(date)

portfolio_history = pd.DataFrame(portfolio_history).set_index('Date')['Balance']
benchmark_history = pd.DataFrame(benchmark_history).set_index('Date')['Balance']

return portfolio_history, benchmark_history, rebalance_dates

def calculate_cumulative_returns(data, weights, initial_value):
returns = data.pct_change().dropna()
portfolio_returns = returns.dot(weights)
cumulative_returns = (1 + portfolio_returns).cumprod() * initial_value
return cumulative_returns

def calculate_metrics(history):
returns = history.pct_change().dropna()
mean_return = returns.mean() * 252
std_dev = returns.std() * np.sqrt(252)
sharpe_ratio = mean_return / std_dev
return mean_return, std_dev, sharpe_ratio
85 changes: 85 additions & 0 deletions SimContentManager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
class SimContent:
@staticmethod
def howToUse():
return """
### Step-by-Step Instructions for Using the Portfolio Simulator:
**1. Set Start and End Date:**
- Specify the period over which you want to analyze your portfolio's performance. Adjust the start and end dates in the sidebar to set the range of historical data that will be used.
**2. Enter Initial Portfolio Value:**
- Set the initial amount of money you are investing in the sidebar. This figure represents your starting capital.
**3. Select Benchmark:**
- Choose a benchmark ETF from the sidebar dropdown to compare your portfolio’s performance against. This helps evaluate whether your strategy outperforms common market indices.
**4. Enter Stock Tickers:**
- Input the symbols of the stocks or assets you want to simulate in your portfolio. Enter them in a comma-separated list in the sidebar. For example: `SPY, TLT, GLD, BTC-USD, TSLA, QQQ`.
**5. Enter Initial Weights:**
- Define how much of your total investment should be allocated to each asset, ensuring that the percentages add up to 100%. For example: `30%, 20%, 10%, 20%, 10%, 10%`.
**6. Select Rebalance Period:**
- Choose how often you want to adjust your portfolio back to these initial weights. Options include annually, semi-annually, quarterly, monthly, or not at all, allowing you to simulate the effect of different rebalancing strategies on your investment's performance.
"""

@staticmethod
def insights():
return """
### Portfolio Insights:
**📈 Performance Metrics:**
- Simulate and analyze various performance metrics such as expected annual return, annual volatility, and the Sharpe Ratio, giving you insights into the risk-adjusted returns of your strategy.
**📊 Portfolio Balance Over Time:**
- Observe how your portfolio's balance evolves over time with or without regular rebalancing. Graphical representations will highlight the portfolio's response to market changes, and red vertical lines will mark rebalancing events.
**🛡️ Risk Management:**
- Learn how strategic rebalancing can help manage risk and align your portfolio with your financial goals, maintaining desired asset proportions and adjusting to market shifts.
"""

@staticmethod
def exampleWalkthrough1():
return """
### Example Walkthrough 1: 60/40 Stock-Bond Split with Annual Rebalancing
**Overview:**
- The [60/40 portfolio](https://www.experian.com/blogs/ask-experian/what-is-60-40-portfolio/) is a classic investment strategy where 60% of your money is in stocks (for growth) and 40% is in bonds (for stability). This mix aims to offer a balance between earning potential and risk reduction.
**Setting Up Your Portfolio:**
- **Tickers and Weights:** Enter `SPY` (60%), `TLT` (40%) in the tool.
- **How to Enter Data:** Type the tickers as `SPY, TLT` and weights as `0.60, 0.40` in the input fields.
- **Rebalancing Frequency:** Once a year (Annually).
- **Investment Period:** From January 1, 2010, to December 31, 2020.
**Rebalancing Explanation:**
- Imagine starting with 10000: investing 6000 in SPY and 4000 in TLT.
- **End of Year 1:** Let’s say SPY grows to 6600 and TLT to 4200, making your portfolio total 10800.
- **Rebalancing Goal:** To maintain your 60/40 split, you need to adjust the amounts to keep the same ratio.
- **Action:** Move 120 from SPY (which has grown more) to TLT (to restore the 60/40 balance).
**Simulate Portfolio:**
- After setting up your portfolio and understanding the rebalancing process, click the "Simulate Portfolio" button to see how your investments perform over the specified period.
"""

@staticmethod
def exampleWalkthrough2():
return """
### Example Walkthrough 2: Ray Dalio's All Weather Portfolio
**Overview:**
- Ray Dalio's [All Weather Portfolio](https://www.robomarkets.com/blog/investing/strategies/understanding-ray-dalios-all-weather-portfolio-a-diversified-investment-approach/) is designed to perform steadily in different economic conditions by diversifying across various asset classes.
**Setting Up Your Portfolio:**
- **Tickers and Weights:** Enter `SPY` (30%), `GLD` (15%), `TLT` (40%), `TIP` (7.5%), `DBC` (7.5%).
- **How to Enter Data:** Type the tickers as `SPY, GLD, TLT, TIP, DBC` and weights as `0.30, 0.15, 0.40, 0.075, 0.075`.
- **Rebalancing Frequency:** Once a year (Annually).
- **Investment Period:** From January 1, 2010, to December 31, 2020.
**Rebalancing Explanation:**
- Refer to example 1, in short we readjust to the initial weights (`0.30, 0.15, 0.40, 0.075, 0.075`) once a year
**Simulate Portfolio:**
- After setting up your portfolio and understanding the rebalancing process, click the "Simulate Portfolio" button to see how the All Weather Portfolio performed over the specified period.
"""
Loading

0 comments on commit 4c85cb8

Please sign in to comment.