Weekly Report 1
Weekly Report 1: Tuesday January 2, 2024¶
Welcome! This is my very first report of hopefully many to come on a little project I plan to work on for as long as possible (until I lose all my money 😅)
I call this project the Zhang Fund, although this really isn't a fund, but really just my family pooling some money together for me to manage (THANK YOU!!!)
Hopefully every week I'll be able to make a small report on some of the stuff I've been researching and reflect on my previous discussions!
The Portfolio¶
As of today I have $30,000 to work with and currently have all of this sitting in an Interactive Brokers Lite Account accruing interest as I continue to do reaserch on picking stocks.
My current plan for the portfolio is to be 100% invested in equities (with some margin for cash) and approach stock selection with a more fundamental perspective to determine stocks that are undervalued by the market. Does a 21 year old college student really think he can beat the market? We'll just have to find out!
Allocation¶
Interest Analysis¶
"""Importing Packages"""
import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
pd.options.display.float_format = '{:.0f}'.format
Interest Rate¶
According to Interactive Brokers' Interest Rate Page, investors can earn interest on any outstanding cash balance, and the annual interest rate is determined by the following
$$ \text{Interest Rate} = \text{Benchmark Rate} - \text{Fixed Spread} $$- The $\text{Fixed Spread}$ is determined by the type of brokerage account (Pro vs Lite)
- The $\text{Benchmark Rate}$ is determined by the Effective Overnight Federal Funds Rate (US Dollar Denominated Deposits)
Today we can express the variables as the following
$$ \text{Interest Rate} = 5.33% - 1.5% = 3.83%
# fixed interest rate spread for the Interactive Brokers Lite Account
interactive_brokers_lite_interest_spread = .015
# Overnight Federal Funds Rate
benchmark_rate = .0533
interest_rate = benchmark_rate - interactive_brokers_lite_interest_spread
print(f"Interest Rate: {interest_rate * 100}%")
Interest Rate: 3.83%
I should note that I still have some confusion on what the term Effective means and how that effects the benchmark rate. For this report I will naively ignore this confusion in my analysis below and for future reports when I have a better understanding I will return to my analysis and make any necessary adjustments
Propotional Rate¶
Unfortunately Interactive Brokers has some caveats to the stated interest rate we just calculated above! For accounts that have a $NAV < \$100,000$ the interest rate we recieve is the proportion of the $NAV$ of the account with $\$100,000$
This means that the interest rate we actually recieve is the following
$$ \text{Proportional Rate} = \text{Interest Rate} * NAV\text{ Proportion}$$In our case
$$ \text{Proportional Rate} = 3.83\% * (\frac{\$30,000}{\$100,000}) = 3.83\% * .3 = 1.149\%$$net_asset_value = 30000.00
benchmark_net_asset_value = 100000.00
proportion = net_asset_value/benchmark_net_asset_value
proportional_rate = interest_rate * proportion
print(f"Proportional Rate: {proportional_rate*100}%")
Proportional Rate: 1.149%
Blended Rate¶
The final caveat here is that the first $\$10,000$ of outstanding cash doesn't actually accrue any interest. Interactive Brokers have coined a term called the Blended Rate which incorporates the non-accrual of the $\$10,000$ that is the actual interest we recieve
$$\text{Blended Rate} = \frac{\text{Proportional Interest Rate} * (\text{Cash Balance} - \$10,000)}{\text{Cash Balance}}$$In our case
$$\text{Blended Rate} = \frac{1.149\% * (\$30,000 - \$10,000)}{\$30,000} = 0.766\%$$Sadly this is more than $3\%$ less than the original interest rate before the caveats. It may be smarter to have this money invested in TBills instead of earning a dismal $0.766\%$ per year
cash_balance = 30000.00
cash_deduction = 10000.00
cash_balance_after_deduction = cash_balance - cash_deduction
blended_rate = (proportional_rate * cash_balance_after_deduction) / cash_balance
print(f"Blended Rate: {blended_rate * 100}%")
Blended Rate: 0.766%
Interest Accural and Payment¶
According to the Interactive Brokers Website, Interst is accrued daily but paid out on a monthly basis on the 3rd business day of each month. If I'm understanding this correctly, this means interest is accuring behind the scenes every day but it is only paid out monthly. T
source: https://www.interactivebrokers.com/en/pricing/pricing-calculations-int.php
Simple Interest¶
If there are no compounding effects then the interest that is earned is considered simple interest. Assuming the interest rate stays at $0.776\%$ for the next 30 years then we will have the following payout
- Monthly: $19.15
- Annualy: $229.80
- 10 Year: $2298.00
def calculate_simple_interest(annual_interest_rate, principal, number_of_years):
principal_and_interest = principal * (1 + (annual_interest_rate) * (number_of_years))
just_principal = principal_and_interest - principal
return [principal_and_interest, just_principal]
months_per_year = 12
frequency = 1/months_per_year
monthly_simple_interest = cash_balance * (blended_rate * frequency)
annual_simple_interest = monthly_simple_interest * months_per_year
ten_year_simple_interest = annual_simple_interest * 10
print(f"Monthly Simple Interest: {monthly_simple_interest}")
print(f"Annual Simple Interest: {annual_simple_interest}")
print(f"10 Year Simple Interest: {ten_year_simple_interest}")
Monthly Simple Interest: 19.15 Annual Simple Interest: 229.79999999999998 10 Year Simple Interest: 2298.0
Compound Interest¶
With the same assumptions as above with compounding effects (leaving the paid interest in the brokerage account) every month then we will have the following payout:
- 1 Year:
- 5 Year: $229.80
- 10 Year: $2298.00
# utility function to calculate compound interest based on 4 parameters, returns an array with the principal + interest and just interest
def calculate_compound_interest(annual_interest_rate, principal, annual_compounding_frequency, number_of_years):
principal_and_interest = principal * (1 + annual_interest_rate/annual_compounding_frequency) ** (annual_compounding_frequency * number_of_years)
just_interest = principal_and_interest - principal
return [principal_and_interest, just_interest]
one_year_compound_interest = calculate_compound_interest(blended_rate, cash_balance, 12, 1)
five_year_compound_interest = calculate_compound_interest(blended_rate, cash_balance, 12, 5)
ten_year_compound_interest = calculate_compound_interest(blended_rate, cash_balance, 12, 10)
print(f"1 Year Compound Interest: {one_year_compound_interest[1]}")
print(f"5 Year Compound Interest: {five_year_compound_interest[1]}")
print(f"10 Year Compound Interest: {ten_year_compound_interest[1]}")
1 Year Compound Interest: 230.60850863684027 5 Year Compound Interest: 1170.9060938718649 10 Year Compound Interest: 2387.512890432601
"""Plotting Both Compound and Simple Interest"""
number_of_years = np.arange(1, 31)
years = np.arange(2023, 2053)
simple_interest = calculate_simple_interest(blended_rate, cash_balance, number_of_years)
compound_interest = calculate_compound_interest(blended_rate, cash_balance, months_per_year, number_of_years)
# stick in dataframe
interest_df = pd.DataFrame({"number of years": number_of_years, "years": years,"simple interest": simple_interest[0],"compound interest": compound_interest[0]})
interest_df["spread"] = interest_df["compound interest"] - interest_df["simple interest"]
sns.set_style("darkgrid")
fig, axs = plt.subplots(1,2, figsize=(12,5))
sns.lineplot(data=interest_df, x="number of years", y="compound interest", ax=axs[0])
sns.lineplot(data=interest_df, x="number of years", y="simple interest", ax=axs[0])
sns.lineplot(data=interest_df, x="number of years", y="spread", ax=axs[1])
<Axes: xlabel='number of years', ylabel='spread'>
19.20 * 12
19.20 * 12
230.39999999999998
19.20 / 20000
0.0009599999999999999
.0383 * .3
0.01149