In recent years, integrating artificial intelligence (AI) in stock trading has revolutionized investors’ decisions. With the emergence of Large Language Models (LLMs) such as GPT-3 and GPT-4, a paradigm shift has occurred, making complex market analyses and insights more accessible to individual investors and traders. This transformative technology leverages vast amounts of data and sophisticated algorithms to provide a depth of market understanding that was once the exclusive domain of institutional investors. This article focuses on developing a personalized AI trading consultant using LLMs, designed to match individual investment profiles based on risk appetite, investment timeframe, budget, and desired returns, empowering retail investors with personalized, strategic investment advice.
Take your AI innovations to the next level with GenAI Pinnacle. Fine-tune models like Gemini and unlock endless possibilities in NLP, image generation, and more. Dive in today! Explore Now
Stock trading consultants powered by Large Language Models (LLMs) like GPT-3 and GPT-4 have revolutionized financial advisory services. They can leverage AI to analyze historical stock data and current financial news, providing personalized investment advice that aligns with an investor’s unique portfolio and financial objectives. We will attempt to build a consultant to predict market behavior and trends, offering tailored recommendations based on individual risk tolerance, investment duration, available capital, and desired returns.
By the end of this article, readers will be able to:
This article was published as a part of the Data Science Blogathon.
The dataset for this project, sourced from the New York Stock Exchange and available on Kaggle, comprises four CSV files spanning seven years. It includes ‘fundamentals.csv’ with essential financial metrics, ‘prices.csv’ and ‘prices-split-adjusted.csv’ providing historical stock prices and adjustments for stock splits, and ‘securities.csv’ offering additional company information like sector classification and headquarters. Collectively, these files provide a comprehensive view of company performance and stock market dynamics.
Implementing the stock trading consultant with Large Language Models (LLMs) like GPT-4 starts with crucial data preparation. This process includes critical tasks: data cleaning, normalization, and categorization, using the provided datasets: fundamentals.csv, prices.csv, prices-split-adjusted.csv, and securities.csv.
import pandas as pd
# Loading the datasets
fundamentals = pd.read_csv('/content/fundamentals.csv')
prices = pd.read_csv('/content/prices.csv')
prices_split_adjusted = pd.read_csv('/content/prices-split-adjusted.csv')
securities = pd.read_csv('/content/securities.csv')
# Handling missing values and data type conversions in the Fundamentals dataset
fundamentals_info = fundamentals.info()
fundamentals_missing_values = fundamentals.isnull().sum()
# Formatting date columns in all datasets
fundamentals['Period Ending'] = pd.to_datetime(fundamentals['Period Ending'])
prices['date'] = pd.to_datetime(prices['date'])
prices_split_adjusted['date'] = pd.to_datetime(prices_split_adjusted['date'])
# Displaying information about missing values in the Fundamentals dataset
fundamentals_missing_values
# Dropping the unnecessary 'Unnamed: 0' column
fundamentals.drop(columns=['Unnamed: 0'], inplace=True)
# Imputing missing values in 'Earnings Per Share' and 'Estimated Shares Outstanding' with the median
for column in ['Earnings Per Share', 'Estimated Shares Outstanding']:
median_value = fundamentals[column].median()
fundamentals[column].fillna(median_value, inplace=True)
# Re-checking for missing values after imputation
fundamentals_missing_values_post_imputation = fundamentals.isnull().sum()
fundamentals_missing_values_post_imputation
# Checking for consistency between the
# Prices and Prices Split Adjusted datasets
# We will compare a sample of data for the
# same ticker symbols and dates in both datasets
# Selecting a sample of ticker symbols
sample_tickers = prices['symbol'].unique()[:5]
# Creating a comparison DataFrame for each ticker symbol in the sample
comparison_data = {}
for ticker in sample_tickers:
prices_data = prices[prices['symbol'] == ticker]
prices_split_data = prices_split_adjusted
[prices_split_adjusted['symbol'] == ticker]
merged_data = pd.merge(prices_data,
prices_split_data, on='date', how='inner',
suffixes=('_raw', '_split'))
comparison_data[ticker] = merged_data
# Displaying the comparison for the first ticker symbol as an example
comparison_data[sample_tickers[0]].head()
A comparison of prices.csv and prices-split-adjusted.csv for a sample ticker symbol (WLTW) reveals differences in open, close, low, and high stock prices due to stock split adjustments. Volume columns are consistent, indicating accurate trading volume data.
We use the prices-split-adjusted.csv dataset for the stock trading consultant as it offers a consistent view of stock prices over time, accounting for stock splits.
The final data preparation step involves integrating these datasets. We merge fundamentals.csv, prices-split-adjusted.csv, and securities.csv, creating a comprehensive data frame for analysis. Given their large size, we integrate the most relevant columns based on the ticker symbol and date fields to match financials with stock prices and company information.
# Selecting relevant columns from each dataset for integration
fundamentals_columns = ['Ticker Symbol',
'Period Ending', 'Earnings Per Share', 'Total Revenue']
prices_columns = ['symbol', 'date',
'open', 'close', 'low', 'high', 'volume']
securities_columns = ['Ticker symbol',
'GICS Sector', 'GICS Sub Industry']
# Renaming columns for consistency
fundamentals_renamed = fundamentals[fundamentals_columns]
.rename(columns={'Ticker Symbol': 'symbol', 'Period Ending': 'date'})
prices_split_adjusted_renamed = prices_split_adjusted
[prices_columns].rename(columns={'open': 'open_price',
'close': 'close_price', 'low': 'low_price', 'high': 'high_price',
'volume': 'trade_volume'})
securities_renamed = securities[securities_columns]
.rename(columns={'Ticker symbol': 'symbol'})
# Merging datasets
merged_data = pd.merge(pd.merge(fundamentals_renamed,
prices_split_adjusted_renamed, on=['symbol', 'date']),
securities_renamed, on='symbol')
# Displaying the first few rows of the integrated dataset
merged_data.head()
The resultant dataset includes key metrics: earnings per share, total revenue, open/close/low/high stock prices, trading volume, and sector information for each ticker symbol.
Next, we will conduct EDA to understand the distribution and relationships in the dataset, which is crucial for feature selection and model training.
import matplotlib.pyplot as plt
import seaborn as sns
# Exploratory Data Analysis (EDA)
# Summary statistics for numerical columns
numerical_summary = merged_data.describe()
# Correlation matrix to understand relationships between
# different numerical features
correlation_matrix = merged_data.corr()
# Visualizing the correlation matrix using a heatmap
plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('Correlation Matrix of Numerical Features')
plt.show()
correlation_matrix
The EDA provides valuable insights into our integrated dataset:
With these analytical insights, we move forward to enhance our dataset through feature engineering:
from sklearn.preprocessing import MinMaxScaler
# Renaming columns for consistency
fundamentals_renamed = fundamentals.rename(columns=
{'Ticker Symbol': 'symbol', 'Period Ending': 'date'})
prices_split_adjusted_renamed = prices_split_adjusted.
rename(columns={'symbol': 'symbol', 'date': 'date', 'open':
'open_price', 'close': 'close_price', 'low': 'low_price',
'high': 'high_price', 'volume': 'trade_volume'})
securities_renamed = securities.rename(columns={'Ticker
symbol': 'symbol'})
# Merging datasets
merged_data = pd.merge(pd.merge(fundamentals_renamed,
prices_split_adjusted_renamed, on=['symbol', 'date']),
securities_renamed, on='symbol')
# Creating new features
merged_data['PE_Ratio'] = merged_data['close_price'] /
merged_data['Earnings Per Share']
merged_data['Price_Change'] = merged_data['close_price'] -
merged_data['open_price']
merged_data['Average_Price'] = (merged_data['open_price'] +
merged_data['close_price'] + merged_data['low_price'] +
merged_data['high_price']) / 4
# Handling Outliers: Using the IQR method to identify and
handle outliers in numerical columns
Q1 = merged_data.quantile(0.25)
Q3 = merged_data.quantile(0.75)
IQR = Q3 - Q1
merged_data = merged_data[~((merged_data.isin([Q1 - 1.5 *
IQR, Q3 + 1.5 * IQR])).any(axis=1))]
# Feature Scaling: Normalizing the numerical features
numerical_features = ['Earnings Per Share', 'Total Revenue',
'open_price', 'close_price', 'low_price', 'high_price',
'trade_volume', 'PE_Ratio', 'Price_Change', 'Average_Price']
scaler = MinMaxScaler()
merged_data[numerical_features] = scaler.fit_transform
(merged_data[numerical_features])
# Encoding Categorical Variables: One-hot encoding for 'GICS Sector'
merged_data_encoded = pd.get_dummies(merged_data, columns=['GICS Sector'])
# Displaying a sample of the preprocessed dataset
merged_data_encoded.head()
For our stock price prediction project, we must choose a machine learning model that excels in handling regression tasks, as we are dealing with predicting continuous stock price values. Given our dataset’s diverse and complex nature, our model needs to capture intricate patterns within the data adeptly.
The following code demonstrates the steps involved in this process,
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.impute import SimpleImputer
# Assuming 'close_price' as the target variable for prediction
X = merged_data_encoded.drop(['close_price',
'symbol', 'date'], axis=1) # dropping non-numeric and target variable
y = merged_data_encoded['close_price']
# Checking for non-numeric columns in the dataset
non_numeric_columns = X.select_dtypes(include=['object']).columns
# If there are non-numeric columns, we'll remove them from the dataset
if len(non_numeric_columns) > 0:
X = X.drop(non_numeric_columns, axis=1)
# Splitting the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split
(X, y, test_size=0.2, random_state=42)
# Initializing the Random Forest Regressor
random_forest_model = RandomForestRegressor
(n_estimators=100, random_state=42)
# Creating an imputer object with a median filling strategy
imputer = SimpleImputer(strategy='median')
# Applying the imputer to the training and testing sets
X_train_imputed = imputer.fit_transform(X_train)
X_test_imputed = imputer.transform(X_test)
# Training the model
random_forest_model.fit(X_train_imputed, y_train)
# Predicting on the test set
y_pred = random_forest_model.predict(X_test_imputed)
# Evaluating the model
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
mse, r2
The output of our Random Forest Regressor model indicates the following:
After training the Random Forest Regressor model and enabling it for predictions, we will integrate it seamlessly with the GPT-4 API. This integration facilitates the model to analyze and predict stock prices and communicate these insights effectively to the users. The GPT-4 API, with its advanced natural language processing capabilities, can interpret complex financial data and present it in a user-friendly way.
Here’s a detailed explanation of how the integration works:
import os
from openai import OpenAI
from sklearn.impute import SimpleImputer
os.environ["OPENAI_API_KEY"] ='YOUR API KEY'
client = OpenAI()
imputer = SimpleImputer(strategy='median')
# Function to get model predictions based on user query
def get_model_predictions(user_query):
ticker_symbol = user_query[0].split()[-1].strip().upper()
# Applying imputter to the data and using the model to make
# predictions
imputed_test_data = imputer.fit_transform(test_data)
predicted_scaled_value = random_forest_model.predict(imputed_test_data)[0]
confidence = 0.9 #Assuming 90% confidence in our predictions
# Creaing a placeholder array with the same shape as the
# original scaled data
placeholder_array = np.zeros((1, len(numerical_features)))
# Inserting the predicted scaled value at the correct position
placeholder_array[0][3] = predicted_scaled_value
# Performing the inverse transformation
predicted_original_value = scaler.inverse_transform(placeholder_array)
# Extracting the scaled-back value for 'close_price'
predicted_stock_price = predicted_original_value[0][3]
return {
"predicted_stock_price": predicted_stock_price,
"confidence": confidence
}
# Function to query GPT-4 with model context
def query_gpt4_with_context
(model_context,additional_data_context, user_query):
prompt = f"{additional_data_context}\n\n
{model_context}\n\n{user_query}\n\nYou are a financial advisor,
an expert stock market consultant. Study the predictions, the data
provided and the client's profile to provide consultation
related to the stock, to the user based on the above information.
Also, focus your advise to the given stock only."
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "system", "content": prompt}]
)
return response.choices[0].message.content.strip()
Now, let’s test the efficacy of our stock consultant with a couple of scenarios:
I am a 25-year-old single male with a high-risk tolerance. I seek at least 15% annual growth in all my stock investments. Two years ago, I bought 100 shares of ABBV at $40 per share. Should I sell my ABBV shares? What is the likely profit in dollars and percentage from this sale?
Let’s feed this query into our model and see what output we get.
user_query = ["I am 25-year-old single male. Given my status,
I have a high risk tolerance and look for at least 15% growth
per year in all my stock investments. I bought 100 shares
of ABBV at $40 per share two years ago.
Should I look to sell my shares of company ABBV",
"What is my likely profit in $ and % from this sale?"]
# Generating a random row of data for the queried stock
# based on its summary statistics
ticker_symbol = user_query[0].split()[-1].strip().upper()
df1 = merged_data_encoded[merged_data_encoded['symbol'] == ticker_symbol]
df1 = df1.drop(['close_price'], axis=1)
test_data = df1.describe().loc[['mean', 'std']].T
test_data['random_value'] = np.random.randn(len(test_data))
* test_data['std'] + test_data['mean']
# Selecting only the random values to form a DataFrame
test_data = pd.DataFrame(test_data['random_value']).transpose()
model_predictions = get_model_predictions(user_query)
# Generating model context
model_context = f"The current predicted stock price of
{ticker_symbol} is ${model_predictions['predicted_stock_price']}
with a confidence level of {model_predictions['confidence']*100}%."
# Generating additional data context
additional_data_context = prices[prices['symbol']==ticker_symbol]
,fundamentals[fundamentals['Ticker Symbol']==ticker_symbol]
,securities[securities['Ticker symbol']==ticker_symbol]
gpt4_response = query_gpt4_with_context(model_context
,additional_data_context, user_query)
print(f"GPT-4 Response: {gpt4_response}")
I am 40 year old married female. Given my status, I have a low risk tolerance and look for atleast 10% growth per year in all my stock investments. I bought 100 shares of ALXN at $100 per share two years ago. Should I look to sell my shares of company ALXN? What is my likely profit in $ and % from this sale?
user_query = ["I am 40 year old married female.
Given my status, I have a low risk tolerance and
look for atleast 10% growth per year in all my stock
investments. I bought 100 shares of ALXN at $100 per
share two years ago. Should I look to sell my shares
of company ALXN?",
"What is my likely profit in $ and % from this sale?"]
# Generating a random row of data for the queried stock
# based on its summary statistics
ticker_symbol = user_query[0].split()[-1].strip().upper()
df1 = merged_data_encoded[merged_data_encoded['symbol'] == ticker_symbol]
df1 = df1.drop(['close_price'], axis=1)
test_data = df1.describe().loc[['mean', 'std']].T
test_data['random_value'] = np.random.randn(len(test_data))
* test_data['std'] + test_data['mean']
# Selecting only the random values to form a DataFrame
test_data = pd.DataFrame(test_data['random_value']).transpose()
model_predictions = get_model_predictions(user_query)
# Generating model context
model_context = f"The current predicted stock price of
{ticker_symbol} is ${model_predictions['predicted_stock_price']}
with a confidence level of {model_predictions['confidence']*100}%."
# Generating additional data context
additional_data_context = prices[prices['symbol']==ticker_symbol]
,fundamentals[fundamentals['Ticker Symbol']==ticker_symbol]
,securities[securities['Ticker symbol']==ticker_symbol]
gpt4_response = query_gpt4_with_context(model_context
,additional_data_context, user_query)
print(f"GPT-4 Response: {gpt4_response}")
Our exploration of AI in stock trading shows that models like GPT-3 and GPT-4 redefine the landscape, assimilating vast data, applying sophisticated analysis, and offering precise, personalized insights. The stock trading consultant development signifies a leap toward accessible, informed trading for everyone.
Dive into the future of AI with GenAI Pinnacle. From training bespoke models to tackling real-world challenges like PII masking, empower your projects with cutting-edge capabilities. Start Exploring.
A. LLMs are AI models that process and generate text. They analyze financial reports, news, and market data in stock trading to provide investment insights and predictions.
A. While AI can augment and enhance the decision-making process, it is not likely to replace human advisors entirely. AI provides data-driven insights, but human advisors consider the emotional and personal aspects of financial planning.
A. AI predictions are based on data and trends, making them quite accurate. However, the stock market is influenced by unpredictable factors, so there’s always an inherent level of uncertainty.
A. AI offers a powerful tool for investment advice, but it should be one of several resources. Diversifying your decision-making tools, including seeking human advice, is recommended for a balanced investment strategy.
A. Begin by using AI-driven platforms or consult with financial advisors who employ AI in their services. Ensure that you understand the AI’s input data and reasoning before following its advice.
The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion.