Our passion project revolved around the creation of a finance-based website equipped with a wide range of features, including a stock viewer, data reader, AI assistant, and an optimizer. Throughout the development process, I played two significant roles: delving into the foundational mathematics and finance aspects of the website and contributing to the frontend design.

In this project, I found that my contributions were particularly impactful, primarily within my area of expertise. My team and I recognized the value of leveraging our individual strengths to benefit the project while also supporting each other in areas where we faced challenges. My primary strength lay in my solid understanding of finance, thanks to a summer finance class I had taken. I delved into the mathematical intricacies on my student repository and subsequently collaborated with our backend developers. Among my contributions, I formulated the algorithm responsible for training our AI, which examined patterns, trends, correlations, volatility, and graphical data to make informed stock purchase recommendations. Additionally, I worked on the optimizer, which explored a staggering 6000 different scenarios, plotting them on three axes - volatility, profit, and the Sharpe ratio.

# AI Code 

priceCORR = price.corr()

colors = ['gold', 'red', 'blue', 'royalblue', 'black', 'purple', 'pink', 'green']

fig, ax = plt.subplots(figsize=(10, 6))
priceCORR.plot(kind='bar', stacked=True, ax=ax, color=colors)
ax.set_ylabel("Correlation", fontsize=12)
ax.set_xlabel("Stocks", fontsize=12)
ax.set_title("Correlation between Stocks", fontsize=16)

plt.legend(title='Stocks', loc='upper right')
plt.xticks(rotation=0)  # Rotate x-axis labels if needed
plt.show()

# Finding average correlation to show profability of portfolio
averageCorr = price.corr()
averageCorrMean = averageCorr.mean()
averageCorrMean

column_sum = 0

# For loop to find the mean of the entire data table
for i in range(len(averageCorrMean)):
    column_sum += averageCorrMean[i]
column_sum = column_sum/len(averageCorrMean)
column_sum

# Reading in the stocks of each stock and then creating a central data frame of each. 

import numpy as np
import pandas as pd
import pandas_datareader.data as web
# Get stock data  
all_data = {ticker: web.DataReader(ticker,'stooq')
           for ticker in ['AAPL', 'NVDA', 'MSFT', 'TSLA', 'AMZN', 'NFLX', 'QCOM', 'SBUX']}
# Extract the 'Adjusted Closing Price'
price = pd.DataFrame({ticker: data['Close']
                     for ticker, data in all_data.items() })

price
# Optimizer: 

# Reading in the stocks of each stock and then creating a central data frame of each. 

import numpy as np
import pandas as pd
import pandas_datareader.data as web
# Get stock data  
all_data = {ticker: web.DataReader(ticker,'stooq')
           for ticker in ['AAPL', 'NVDA', 'MSFT', 'TSLA', 'AMZN', 'NFLX', 'QCOM', 'SBUX']}
# Extract the 'Adjusted Closing Price'
price = pd.DataFrame({ticker: data['Close']
                     for ticker, data in all_data.items() })

price

fig1, axes1 = plt.subplots(2,4, sharex = True, sharey = True)

axes1[0,0].plot(price['AAPL'],'-', color = 'gold', label = 'AAPL')
axes1[0,0].legend(loc = 'best')

axes1[0,1].plot(price['NVDA'],'-', color = 'red', label = 'NVDA')
axes1[0,1].legend(loc = 'best')

axes1[0,2].plot(price['MSFT'],'-', color = 'blue', label = 'MSFT')
axes1[0,2].legend(loc = 'best')

axes1[0,3].plot(price['TSLA'],'-', color = 'royalblue', label = 'TSLA')
axes1[0,3].legend(loc = 'best')

axes1[1,0].plot(price['AMZN'],'-', color = 'black', label = 'AMZN')
axes1[1,0].legend(loc = 'best')

axes1[1,1].plot(price['NFLX'],'-', color = 'purple', label = 'NFLX')
axes1[1,1].legend(loc = 'best')

axes1[1,2].plot(price['QCOM'],'-', color = 'pink', label = 'QCOM')
axes1[1,2].legend(loc = 'best')

axes1[1,3].plot(price['SBUX'],'-', color = 'green', label = 'SBUX')
axes1[1,3].legend(loc = 'best') 

# fig1.savefig('stocks1.pdf')

# finding weights, return, volitilty, and sharpe ratio. 

stocks = pd.concat([price['AAPL'], price['NVDA'], price['MSFT'], price['TSLA'], price['AMZN'], price['NFLX'], price['QCOM'], price['SBUX']], axis = 1)
log_ret = np.log(stocks/stocks.shift(1))

# setting up variables
np.random.seed(42)
num_ports = 6000
num_stocks = 8
all_weights = np.zeros((num_ports, len(stocks.columns)))
ret_arr = np.zeros(num_ports)
vol_arr = np.zeros(num_ports)
sharpe_arr = np.zeros(num_ports)

# going through all possible weights
for x in range(num_ports):
    # Weights
    weights = np.array(np.random.random(num_stocks))
    weights = weights/np.sum(weights)
    
    # Save weights
    all_weights[x,:] = weights
    
    # Expected return
    ret_arr[x] = np.sum( (log_ret.mean() * weights * 252))
    
    # Expected volatility
    vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov()*252, weights)))
    
    # Sharpe Ratio
    sharpe_arr[x] = ret_arr[x]/vol_arr[x]
    
# printing the max sharpe ratio
print("Max Sharpe Ratio = ",sharpe_arr.max())
sharpe_arr.argmax()
max_sr_ret =  ret_arr[sharpe_arr.argmax()]
max_sr_vol =  vol_arr[sharpe_arr.argmax()]

Following my involvement in the mathematical and financial aspects, I transitioned to working on the website’s frontend. At the project’s inception, I contributed to the creation of a Figma design, and I later played a pivotal role in translating that design into the actual website. Our team engaged in collective discussions to outline our frontend objectives and goals. We arrived at the idea of a minimalist design that prioritized user-friendliness and ease of navigation. Notable enhancements to the frontend included the incorporation of animated buttons and interactive graphs.

# JS code for button animation

%%JS
%%HTML

body {
            text-align: center;
            margin: 0;
            padding: 0;
            font-family: Arial, sans-serif;
            background-color: #222; 
            color: #fff; 
        }
        h1 {
            background-color: #004d99; 
            color: white;
            padding: 20px;
            margin: 0;
        }
        p {
            max-width: 800px;
            margin: 30px auto;
            padding: 10px;
            background-color: #333; 
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            color: #fff; 
        }
        label {
            display: block;
            margin-top: 20px;
            color: #fff; 
        }
        input {
            font-size: 16px;
            padding: 10px;
            border: 2px solid #e81cff; 
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); 
        }
        .button-container {
            display: flex;
            justify-content: center;
            margin-top: 20px;
        }
        .button {
            position: relative;
            width: 120px;
            height: 40px;
            background-color: #000;
            display: flex;
            align-items: center;
            color: white;
            flex-direction: column;
            justify-content: center;
            border: none;
            padding: 12px;
            gap: 12px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px; 
        }
        .button::before {
            content: '';
            position: absolute;
            inset: 0;
            left: -4px;
            top: -1px;
            margin: auto;
            width: 128px;
            height: 48px;
            border-radius: 10px;
            background: linear-gradient(-45deg, #e81cff 0%, #004d99 100%);
            z-index: -10;
            pointer-events: none;
            transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        }
        .button::after {
            content: "";
            z-index: -1;
            position: absolute;
            inset: 0;
            background: linear-gradient(-45deg, #fc00ff 0%, #00dbde 100%);
            transform: translate3d(0, 0, 0) scale(0.95);
            filter: blur(20px);
        }
        .button:hover::after {
            filter: blur(30px);
        }
        .button:hover::before {
            transform: rotate(-180deg);
        }
        .button:active::before {
            scale: 0.7;
        }
        .button-container2 { 
            display: flex;
            justify-content: center;
            margin-top: 20px;
            margin-bottom: 40px;
        }
    </style>

In hindsight, there are certain aspects I would approach differently in future group projects. One important lesson is the necessity of ensuring all group members actively participate and carry their fair share of the workload. Toward the project’s conclusion, I and another team member assumed a heavier workload compared to the rest of the group, which was an inequitable distribution of effort. Furthermore, I would emphasize more collaborative work throughout the project. Although we initially outlined our website’s objectives, much of the work was carried out individually, limiting the synergy and creative input that could have emerged from more robust teamwork.