The Index Funds Performance Tracker is a sophisticated tool designed for investors who are keen on making informed decisions backed by data. Developed in April 2023, this project employs Python, particularly the pandas library, to amalgamate data from 10 distinct index funds into a single, comprehensive CSV file. The data, rich and varied, is then processed to calculate key metrics, offering insights into the performance and trends associated with each fund. It’s a blend of technology and finance, aiming to simplify the complex world of index funds for both novice and seasoned investors.
The core of the project lies in its ability to transform raw data into actionable insights. Utilizing pandas, a powerful data manipulation library, the project calculates essential metrics like price change, moving averages, and percent change. Each metric is meticulously computed, offering a granular view of the funds’ performance over time. It’s not just about numbers but about painting a vivid picture of the market trends, fluctuations, and potential investment opportunities.
The final masterpiece of this project is visualized in an interactive Tableau dashboard. Every calculated metric, every trend, and every piece of data is represented visually, offering users an intuitive interface to explore and analyze the index funds. Users can filter data based on specific stock symbols or date ranges, diving deep into detailed views that cater to their unique investment interests. It’s more than a dashboard; it’s a dynamic tool that adapts to the users’ needs, making the exploration of index funds an insightful and personalized experience.
import os
import pandas as pd
#defining the folder path
folder_path = r'C:\Users\My PC\Desktop\python\index fund'
#get the list of files in the folder
files = os.listdir(folder_path)
# Filter the list to include only CSV files
csv_files = [file for file in files if file.endswith('.csv')]
# Print the list of CSV file names
print("files names in the folder:")
for file in csv_files:
print(file)
files names in the folder: DIA.csv FNILX.csv IVV.csv QQQ.csv SPY.csv SWPPX.csv TRIWX.csv VOO.csv VTI.csv VTWO.csv
# Define the list of file names
files = ['DIA.csv', 'FNILX.csv', 'IVV.csv', 'QQQ.csv', 'SPY.csv', 'SWPPX.csv', 'TRIWX.csv', 'VOO.csv', 'VTI.csv', 'VTWO.csv']
# Create an empty DataFrame to hold the combined data
combined_data = pd.DataFrame()
# Loop through the allowed in the folder
for filename in files:
file_path = os.path.join(folder_path, filename)
if os.path.isfile(file_path):
# Read the CSV file into a DataFrame
data = pd.read_csv(file_path)
# Add a new column 'stock' with the file name as the value
data['stock'] = filename
# Concatenate the data to the combined_data DataFrame
combined_data = pd.concat([combined_data, data], ignore_index=True)
print(f"Added data from {filename} to combined_data")
Added data from DIA.csv to combined_data Added data from FNILX.csv to combined_data Added data from IVV.csv to combined_data Added data from QQQ.csv to combined_data Added data from SPY.csv to combined_data Added data from SWPPX.csv to combined_data Added data from TRIWX.csv to combined_data Added data from VOO.csv to combined_data Added data from VTI.csv to combined_data Added data from VTWO.csv to combined_data
# Save the combined data to a new CSV file
combined_data.to_csv(os.path.join(folder_path, 'top 10 index funds historical data.csv'), index=False)
print("Finished combining and saving data to 'top 10 index funds historical data.csv'.")
Finished combining and saving data to 'top 10 index funds historical data.csv'.
# Replace '.csv' with blank space in the 'stock' column
combined_data['stock'] = combined_data['stock'].str.replace('.csv', '')
C:\Users\My PC\AppData\Local\Temp\ipykernel_14436\1526864209.py:2: FutureWarning: The default value of regex will change from True to False in a future version. combined_data['stock'] = combined_data['stock'].str.replace('.csv', '')
combined_data
Date | Open | High | Low | Close | Adj Close | Volume | stock | |
---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA |
... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO |
46164 rows × 8 columns
def calculate_moving_averages(data):
# Calculate SMA50 and SMA200
data['SMA50'] = data['Close'].rolling(window=50).mean()
data['SMA200'] = data['Close'].rolling(window=200).mean()
return data
# Calculate moving averages
combined_data = calculate_moving_averages(combined_data)
combined_data.head()
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.81250 | 78.843750 | 77.40625 | 78.81250 | 45.937397 | 1744600 | DIA | NaN | NaN |
1 | 1998-01-21 | 78.09375 | 78.375000 | 77.28125 | 77.84375 | 45.372757 | 1839600 | DIA | NaN | NaN |
2 | 1998-01-22 | 77.18750 | 77.859375 | 76.93750 | 77.18750 | 44.990253 | 1662600 | DIA | NaN | NaN |
3 | 1998-01-23 | 77.50000 | 77.750000 | 76.31250 | 77.00000 | 44.880993 | 1693700 | DIA | NaN | NaN |
4 | 1998-01-26 | 77.37500 | 77.671875 | 76.93750 | 77.31250 | 45.063141 | 1172800 | DIA | NaN | NaN |
# Extract day of the week from 'Date' column
combined_data['DayOfWeek'] = pd.to_datetime(combined_data['Date']).dt.day_name()
combined_data
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | Monday |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | Tuesday |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | Wednesday |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | Thursday |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | Friday |
46164 rows × 11 columns
# Shift the 'Close' column by 1 to get the previous day's closing price
combined_data['PrevDayClose'] = combined_data['Close'].shift(1)
combined_data
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek | PrevDayClose | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday | NaN |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday | 78.812500 |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday | 77.843750 |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday | 77.187500 |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday | 77.000000 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | Monday | 70.250000 |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | Tuesday | 71.000000 |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | Wednesday | 71.540001 |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | Thursday | 71.029999 |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | Friday | 71.949997 |
46164 rows × 12 columns
# Calculate the change in price (Close - PrevDayClose)
combined_data['ChangePriceClose'] = combined_data['Close'] - combined_data['PrevDayClose']
combined_data.head()
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek | PrevDayClose | ChangePriceClose | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.81250 | 78.843750 | 77.40625 | 78.81250 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday | NaN | NaN |
1 | 1998-01-21 | 78.09375 | 78.375000 | 77.28125 | 77.84375 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday | 78.81250 | -0.96875 |
2 | 1998-01-22 | 77.18750 | 77.859375 | 76.93750 | 77.18750 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday | 77.84375 | -0.65625 |
3 | 1998-01-23 | 77.50000 | 77.750000 | 76.31250 | 77.00000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday | 77.18750 | -0.18750 |
4 | 1998-01-26 | 77.37500 | 77.671875 | 76.93750 | 77.31250 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday | 77.00000 | 0.31250 |
# Calculate the percent change
combined_data['PercentChangeClose'] = ((combined_data['ChangePriceClose']) /
combined_data['PrevDayClose']) * 100
combined_data
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek | PrevDayClose | ChangePriceClose | PercentChangeClose | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday | NaN | NaN | NaN |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday | 78.812500 | -0.968750 | -1.229183 |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday | 77.843750 | -0.656250 | -0.843035 |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday | 77.187500 | -0.187500 | -0.242915 |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday | 77.000000 | 0.312500 | 0.405844 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | Monday | 70.250000 | 0.750000 | 1.067616 |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | Tuesday | 71.000000 | 0.540001 | 0.760565 |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | Wednesday | 71.540001 | -0.510002 | -0.712891 |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | Thursday | 71.029999 | 0.919998 | 1.295225 |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | Friday | 71.949997 | -0.649994 | -0.903397 |
46164 rows × 14 columns
# Shift the 'Volume' column by 1 to get the previous day's Volume price
combined_data['PrevDayVolume'] = combined_data['Volume'].shift(1)
# Calculate the change in price (Volume - PrevDayVolume)
combined_data['ChangePriceVolume'] = combined_data['Volume'] - combined_data['PrevDayVolume']
# Calculate the percent change Volume
combined_data['PercentChangeVolume'] = ((combined_data['ChangePriceVolume']) /
combined_data['PrevDayVolume']) * 100
# Calculate the percent change
combined_data['PercentChangeVolume'] = ((combined_data['ChangePriceVolume']) /
combined_data['PrevDayVolume']) * 100
combined_data
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek | PrevDayClose | ChangePriceClose | PercentChangeClose | PrevDayVolume | ChangePriceVolume | PercentChangeVolume | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday | NaN | NaN | NaN | NaN | NaN | NaN |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday | 78.812500 | -0.968750 | -1.229183 | 1744600.0 | 95000.0 | 5.445374 |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday | 77.843750 | -0.656250 | -0.843035 | 1839600.0 | -177000.0 | -9.621657 |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday | 77.187500 | -0.187500 | -0.242915 | 1662600.0 | 31100.0 | 1.870564 |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday | 77.000000 | 0.312500 | 0.405844 | 1693700.0 | -520900.0 | -30.755151 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | Monday | 70.250000 | 0.750000 | 1.067616 | 1055200.0 | -127700.0 | -12.101971 |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | Tuesday | 71.000000 | 0.540001 | 0.760565 | 927500.0 | 413500.0 | 44.582210 |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | Wednesday | 71.540001 | -0.510002 | -0.712891 | 1341000.0 | -209900.0 | -15.652498 |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | Thursday | 71.029999 | 0.919998 | 1.295225 | 1131100.0 | -285600.0 | -25.249757 |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | Friday | 71.949997 | -0.649994 | -0.903397 | 845500.0 | 258400.0 | 30.561798 |
46164 rows × 17 columns
#Moving Average Convergence Divergence MACD = 12-day EMA - 26-day EMA
def calculate_macd_signal(df, n_fast=12, n_slow=26):
"""
Calculate Moving Average Convergence Divergence (MACD).
"""
ema_fast = df['Close'].ewm(span=n_fast, min_periods=n_fast).mean()
ema_slow = df['Close'].ewm(span=n_slow, min_periods=n_slow).mean()
macd = ema_fast - ema_slow
return macd
# Call the function to calculate MACD
combined_data['MACD']= calculate_macd_signal(combined_data)
# Find the best day to trade for each stock
best_day_df = combined_data.groupby(['stock', 'DayOfWeek'])['MACD'].mean().reset_index()
best_day_df = best_day_df.sort_values(['stock', 'MACD'], ascending=[True, False])
best_day_df = best_day_df.groupby('stock').head(1)
best_day_df = best_day_df[['stock', 'DayOfWeek']]
print(best_day_df)
stock DayOfWeek 3 DIA Tuesday 7 FNILX Thursday 13 IVV Tuesday 15 QQQ Friday 21 SPY Monday 26 SWPPX Monday 30 TRIWX Friday 36 VOO Monday 44 VTI Wednesday 48 VTWO Tuesday
# Merge the best day of the week with the original DataFrame
df_merged = pd.merge(combined_data, best_day_df, on='stock', how='left')
df_merged = df_merged.rename(columns={"DayOfWeek_y": "BestDayTrade"})
df_merged
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | DayOfWeek_x | PrevDayClose | ChangePriceClose | PercentChangeClose | PrevDayVolume | ChangePriceVolume | PercentChangeVolume | MACD | Signal | BestDayTrade | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | Tuesday | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Tuesday |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | Wednesday | 78.812500 | -0.968750 | -1.229183 | 1744600.0 | 95000.0 | 5.445374 | NaN | NaN | Tuesday |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | Thursday | 77.843750 | -0.656250 | -0.843035 | 1839600.0 | -177000.0 | -9.621657 | NaN | NaN | Tuesday |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | Friday | 77.187500 | -0.187500 | -0.242915 | 1662600.0 | 31100.0 | 1.870564 | NaN | NaN | Tuesday |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | Monday | 77.000000 | 0.312500 | 0.405844 | 1693700.0 | -520900.0 | -30.755151 | NaN | NaN | Tuesday |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | Monday | 70.250000 | 0.750000 | 1.067616 | 1055200.0 | -127700.0 | -12.101971 | -0.819975 | -1.066325 | Tuesday |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | Tuesday | 71.000000 | 0.540001 | 0.760565 | 927500.0 | 413500.0 | 44.582210 | -0.701938 | -0.993447 | Tuesday |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | Wednesday | 71.540001 | -0.510002 | -0.712891 | 1341000.0 | -209900.0 | -15.652498 | -0.642143 | -0.923186 | Tuesday |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | Thursday | 71.029999 | 0.919998 | 1.295225 | 1131100.0 | -285600.0 | -25.249757 | -0.514587 | -0.841466 | Tuesday |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | Friday | 71.949997 | -0.649994 | -0.903397 | 845500.0 | 258400.0 | 30.561798 | -0.460637 | -0.765301 | Tuesday |
46164 rows × 20 columns
# Save the modified data back to the new file
df_merged.to_csv('top 10 index funds historical data.csv', index=False)
# Define a function to generate the paragraph based on the stock ticker symbol
def generate_paragraph(stock):
if stock == 'VTWO':
return 'VTWO is the ticker symbol for the Vanguard Russell 2000 ETF, which is an exchange-traded fund that tracks the performance of the Russell 2000 index. This index includes 2000 small-cap US companies, providing investors with exposure to the small-cap equity market. As of 2021, VTWO had over $20 billion in assets under management.'
elif stock == 'VTI':
return 'VTI is the ticker symbol for the Vanguard Total Stock Market ETF, which is an exchange-traded fund that tracks the performance of the CRSP US Total Market Index. It provides investors with exposure to the entire US stock market, including large, mid, and small-cap companies across various sectors. As of 2021, VTI had over $200 billion in assets under management.'
elif stock == 'VOO':
return 'VOO is the ticker symbol for the Vanguard S&P 500 ETF, which is an exchange-traded fund that tracks the performance of the S&P 500 index. It provides investors with exposure to 500 of the largest companies in the US, spanning various sectors. As of 2021, VOO was one of the largest ETFs in the world, with assets under management of over $700 billion.'
elif stock == 'TRIWX':
return 'TRIWX is the ticker symbol for the T. Rowe Price Institutional Large Cap Growth Fund, which is a mutual fund that invests in large-cap US growth stocks. It aims to provide long-term capital growth through investments in companies with strong growth potential. The fund has a minimum investment of $1 million and is targeted at institutional investors.'
elif stock == 'SWPPX':
return 'SWPPX is the ticker symbol for the Schwab S&P 500 Index Fund, which is an index fund that tracks the performance of the S&P 500 index. It provides investors with exposure to 500 of the largest companies in the US, spanning various sectors. The fund has a low expense ratio and no minimum investment, making it an attractive option for investors seeking broad market exposure.'
elif stock == 'SPY':
return 'SPY is the ticker symbol for the SPDR S&P 500 ETF Trust, which is an exchange-traded fund that tracks the performance of the S&P 500 index. It provides investors with exposure to 500 of the largest companies in the US, spanning various sectors. As of 2021, SPY was one of the largest ETFs in the world, with assets under management of over $350 billion.'
elif stock == 'QQQ':
return 'QQQ is the ticker symbol for the Invesco QQQ Trust, which is an exchange-traded fund that tracks the performance of the NASDAQ-100 index. This index includes the largest non-financial companies listed on the NASDAQ stock exchange, with a focus on technology and growth stocks. As of 2021, QQQ had over $150 billion in assets under management.'
elif stock == 'IVV':
return 'IVV is the ticker symbol for the iShares Core S&P 500 ETF, which is an exchange-traded fund that tracks the performance of the S&P 500 index. It provides investors with exposure to the largest 500 companies in the US, spanning various sectors. As of 2021, IVV had over $300 billion in assets under management, making it one of the largest ETFs in the world.'
elif stock == 'FNILX':
return 'FNILX is the ticker symbol for the Fidelity ZERO Large Cap Index Fund, which is an index fund that tracks the performance of large-cap US stocks. It aims to provide investors with broad exposure to the US large-cap equity market while maintaining a low expense ratio. The fund has no minimum investment and no annual fees, making it an attractive option for cost-conscious investors.'
elif stock == 'DIA':
return 'DIA is the stock symbol for an ETF that tracks the performance of the Dow Jones Industrial Average, a stock market index of 30 large-cap companies in the US. It provides investors with exposure to a diverse range of industries. As of 2021, DIA had over $25 billion in assets under management.'
df_merged['paragraph'] = df_merged['stock'].apply(generate_paragraph)
# Save the modified data back to the new file
df_merged.to_csv('top 10 index funds historical data.csv', index=False)
df_merged
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | ... | PrevDayClose | ChangePriceClose | PercentChangeClose | PrevDayVolume | ChangePriceVolume | PercentChangeVolume | MACD | Signal | BestDayTrade | paragraph | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | ... | 78.812500 | -0.968750 | -1.229183 | 1744600.0 | 95000.0 | 5.445374 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | ... | 77.843750 | -0.656250 | -0.843035 | 1839600.0 | -177000.0 | -9.621657 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | ... | 77.187500 | -0.187500 | -0.242915 | 1662600.0 | 31100.0 | 1.870564 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | ... | 77.000000 | 0.312500 | 0.405844 | 1693700.0 | -520900.0 | -30.755151 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | ... | 70.250000 | 0.750000 | 1.067616 | 1055200.0 | -127700.0 | -12.101971 | -0.819975 | -1.066325 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | ... | 71.000000 | 0.540001 | 0.760565 | 927500.0 | 413500.0 | 44.582210 | -0.701938 | -0.993447 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | ... | 71.540001 | -0.510002 | -0.712891 | 1341000.0 | -209900.0 | -15.652498 | -0.642143 | -0.923186 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | ... | 71.029999 | 0.919998 | 1.295225 | 1131100.0 | -285600.0 | -25.249757 | -0.514587 | -0.841466 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | ... | 71.949997 | -0.649994 | -0.903397 | 845500.0 | 258400.0 | 30.561798 | -0.460637 | -0.765301 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... |
46164 rows × 21 columns
# Define a function to generate the paragraph based on the stock ticker symbol
def generate_links(stock):
if stock == 'VTWO':
return 'https://finance.yahoo.com/quote/VTWO'
elif stock == 'FNILX':
return 'https://finance.yahoo.com/quote/FNILX'
elif stock == 'IVV':
return 'https://finance.yahoo.com/quote/IVV'
elif stock == 'QQQ':
return 'https://finance.yahoo.com/quote/QQQ'
elif stock == 'SPY':
return 'https://finance.yahoo.com/quote/SPY'
elif stock == 'SWPPX':
return 'https://finance.yahoo.com/quote/SWPPX'
elif stock == 'VOO':
return 'https://finance.yahoo.com/quote/VOO'
elif stock == 'VTI':
return 'https://finance.yahoo.com/quote/VOO'
elif stock == 'TRIWX':
return 'https://finance.yahoo.com/quote/TRIWX'
elif stock == 'DIA':
return 'https://finance.yahoo.com/quote/DIA'
df_merged['link'] = df_merged['stock'].apply(generate_links)
# Save the modified data back to the new file
df_merged.to_csv('top 10 index funds historical data.csv', index=False)
df_merged
Date | Open | High | Low | Close | Adj Close | Volume | stock | SMA50 | SMA200 | ... | ChangePriceClose | PercentChangeClose | PrevDayVolume | ChangePriceVolume | PercentChangeVolume | MACD | Signal | BestDayTrade | paragraph | link | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1998-01-20 | 77.812500 | 78.843750 | 77.406250 | 78.812500 | 45.937397 | 1744600 | DIA | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... | https://finance.yahoo.com/quote/DIA |
1 | 1998-01-21 | 78.093750 | 78.375000 | 77.281250 | 77.843750 | 45.372757 | 1839600 | DIA | NaN | NaN | ... | -0.968750 | -1.229183 | 1744600.0 | 95000.0 | 5.445374 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... | https://finance.yahoo.com/quote/DIA |
2 | 1998-01-22 | 77.187500 | 77.859375 | 76.937500 | 77.187500 | 44.990253 | 1662600 | DIA | NaN | NaN | ... | -0.656250 | -0.843035 | 1839600.0 | -177000.0 | -9.621657 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... | https://finance.yahoo.com/quote/DIA |
3 | 1998-01-23 | 77.500000 | 77.750000 | 76.312500 | 77.000000 | 44.880993 | 1693700 | DIA | NaN | NaN | ... | -0.187500 | -0.242915 | 1662600.0 | 31100.0 | 1.870564 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... | https://finance.yahoo.com/quote/DIA |
4 | 1998-01-26 | 77.375000 | 77.671875 | 76.937500 | 77.312500 | 45.063141 | 1172800 | DIA | NaN | NaN | ... | 0.312500 | 0.405844 | 1693700.0 | -520900.0 | -30.755151 | NaN | NaN | Tuesday | DIA is the stock symbol for an ETF that tracks... | https://finance.yahoo.com/quote/DIA |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
46159 | 2023-04-10 | 69.889999 | 71.019997 | 69.879997 | 71.000000 | 71.000000 | 927500 | VTWO | 74.203801 | 73.08885 | ... | 0.750000 | 1.067616 | 1055200.0 | -127700.0 | -12.101971 | -0.819975 | -1.066325 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... | https://finance.yahoo.com/quote/VTWO |
46160 | 2023-04-11 | 71.300003 | 71.860001 | 71.129997 | 71.540001 | 71.540001 | 1341000 | VTWO | 74.104801 | 73.10290 | ... | 0.540001 | 0.760565 | 927500.0 | 413500.0 | 44.582210 | -0.701938 | -0.993447 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... | https://finance.yahoo.com/quote/VTWO |
46161 | 2023-04-12 | 72.230003 | 72.239998 | 70.919998 | 71.029999 | 71.029999 | 1131100 | VTWO | 74.016001 | 73.10380 | ... | -0.510002 | -0.712891 | 1341000.0 | -209900.0 | -15.652498 | -0.642143 | -0.923186 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... | https://finance.yahoo.com/quote/VTWO |
46162 | 2023-04-13 | 71.230003 | 72.150002 | 71.050003 | 71.949997 | 71.949997 | 845500 | VTWO | 73.910001 | 73.10765 | ... | 0.919998 | 1.295225 | 1131100.0 | -285600.0 | -25.249757 | -0.514587 | -0.841466 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... | https://finance.yahoo.com/quote/VTWO |
46163 | 2023-04-14 | 71.980003 | 72.370003 | 70.820000 | 71.300003 | 71.300003 | 1103900 | VTWO | 73.766401 | 73.11510 | ... | -0.649994 | -0.903397 | 845500.0 | 258400.0 | 30.561798 | -0.460637 | -0.765301 | Tuesday | VTWO is the ticker symbol for the Vanguard Rus... | https://finance.yahoo.com/quote/VTWO |
46164 rows × 22 columns