Press "Enter" to skip to content

“用GPT-4打造个性化的人工智能交易顾问”

介绍

近年来,将人工智能(AI)整合到股票交易中已经改变了投资者的决策方式。随着大型语言模型(LLMs)如GPT-3和GPT-4的出现,发生了一场范式转变,使个人投资者和交易者更容易获得复杂的市场分析和见解。这种革命性的技术利用大量的数据和复杂的算法,提供了以前仅由机构投资者独占的市场理解深度。本文重点介绍使用LLMs开发个性化AI交易顾问,旨在根据风险偏好、投资时间、预算和期望回报来匹配个人投资者的投资配置,为零售投资者提供个性化、战略性的投资建议。

“用GPT-4打造个性化的人工智能交易顾问” 四海 第1张

由GPT-3和GPT-4等大型语言模型(LLMs)驱动的股票交易顾问已经彻底改变了金融咨询服务。它们可以利用人工智能来分析历史股票数据和当前的财经新闻,为投资者提供与其独特投资组合和财务目标相符合的个性化投资建议。我们将尝试构建一个顾问来预测市场行为和趋势,根据个人风险承受能力、投资期限、可用资本和期望回报提供量身定制的建议。

学习目标

通过本文,读者将能够:

  • 了解AI和像GPT-3这样的LLMs如何改变股市分析和交易。
  • 认识到基于个人风险偏好和投资目标的AI驱动工具提供个性化投资建议的能力。
  • 了解AI如何利用历史和实时数据制定投资策略和预测。
  • 了解股票交易中的AI如何使复杂的投资策略对更广泛的受众(包括零售投资者)可行。
  • 发现如何利用AI驱动的工具进行个人投资和股票交易决策。
  • 了解利用LLMs构建股票交易顾问的概念。

本文作为数据科学博文马拉松的一部分进行发布。

关于数据集

该项目的数据集从纽约证券交易所获取,并在Kaggle上提供,包括覆盖七年的四个CSV文件。其中包括关键的财务指标“fundamentals.csv”,提供历史股价和股票分割调整的“prices.csv”和“prices-split-adjusted.csv”,以及提供附加公司信息(如部门分类和总部)的“securities.csv”。这些文件的综合提供了对公司业绩和股票市场动态的全面了解。

数据准备

使用类似GPT-4这样的大型语言模型(LLMs)来实现股票交易顾问,需要进行关键的数据准备。这个过程包括重要的任务:数据清洗、归一化和分类,使用提供的数据集:fundamentals.csv、prices.csv、prices-split-adjusted.csv和securities.csv。

步骤1:数据清洗

  • 在“基本数据集”中,我们使用中值插补来处理“For Year”、“Earnings Per Share”和“Estimated Shares Outstanding”的缺失值(173个、219个和219个缺失值)。
  • 我们将“Period Ending”列转换为日期时间格式,使其适合进行数字字段分析。
import pandas as pd# 加载数据集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')# 处理基本数据集中的缺失值和数据类型转换fundamentals_info = fundamentals.info()fundamentals_missing_values = fundamentals.isnull().sum()# 格式化所有数据集中的日期列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'])# 显示基本数据集中的缺失值信息fundamentals_missing_values

“用GPT-4打造个性化的人工智能交易顾问” 四海 第2张

# 删除不必要的'Unnamed: 0'列
fundamentals.drop(columns=['Unnamed: 0'], inplace=True)
# 使用中位数填充'Earnings Per Share'和'Estimated Shares Outstanding'中的缺失值
for column in ['Earnings Per Share', 'Estimated Shares Outstanding']:
    median_value = fundamentals[column].median()
    fundamentals[column].fillna(median_value, inplace=True)
# 补充填充后再次检查缺失值
fundamentals_missing_values_post_imputation = fundamentals.isnull().sum()
fundamentals_missing_values_post_imputation

“用GPT-4打造个性化的人工智能交易顾问” 四海 第3张

  • “日期”列在价格和价格分割调整数据集中已经是一致的。我们验证数据的一致性,特别是股票拆分的相关信息。
# 检查价格数据集和价格分割调整数据集之间的一致性
# 我们将在两个数据集中选择相同的股票代号和日期样本进行比较
# 选择股票样本
sample_tickers = prices['symbol'].unique()[:5]
# 为样本中的每个股票代号创建比较数据框架
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
# 以第一个股票代号的比较结果作为示例展示
comparison_data[sample_tickers[0]].head()

“用GPT-4打造个性化的人工智能交易顾问” 四海 第4张

价格数据集(prices.csv)和价格分割调整数据集(prices-split-adjusted.csv)对于样本股票(WLTW)的比较显示出了开盘价、收盘价、最低价和最高价的差异,这是由于股票拆分调整导致的。交易数量的列是一致的,表明交易数量数据是准确的。

步骤2:价格归一化

我们使用价格分割调整数据集(prices-split-adjusted.csv)作为股票交易顾问,因为它提供了一个持续的股票价格视图,考虑了股票拆分。

步骤3:数据集成

最后的数据准备步骤涉及集成这些数据集。我们将fundamentals.csv、prices-split-adjusted.csv和securities.csv进行合并,创建一个包含完整股票分析所需的数据框架。鉴于它们的大尺寸,我们基于股票代号和日期字段选择了最相关的列与财务数据、股票价格和公司信息进行匹配。

# 从每个数据集中选择相关列进行集成
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']
# 为了保持一致性重命名列名
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'})
# 合并数据集
merged_data = pd.merge(pd.merge(fundamentals_renamed, prices_split_adjusted_renamed, on=['symbol', 'date']), securities_renamed, on='symbol')
# 显示集成数据集的前几行
merged_data.head()

“用GPT-4打造个性化的人工智能交易顾问” 四海 第5张

得到的数据集包括关键指标:每股收益、总收入、开盘价/收盘价/最低价/最高价的股票价格、交易数量和所属行业的信息。

探索性数据分析(EDA)

接下来,我们将进行EDA,以了解数据集中的分布和关系,这对特征选择和模型训练至关重要。

import matplotlib.pyplot as plt
import seaborn as sns

# 探索性数据分析(EDA)
# 数值列的概括统计
numerical_summary = merged_data.describe()

# 通过相关矩阵了解不同数值特征之间的关系
correlation_matrix = merged_data.corr()

# 使用热力图可视化相关矩阵
plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('数值特征的相关矩阵')
plt.show()
correlation_matrix

“用GPT-4打造个性化的人工智能交易顾问” 四海 第6张

“用GPT-4打造个性化的人工智能交易顾问” 四海 第7张

EDA为我们的综合数据集提供了有价值的见解:

  • 我们观察到各种公司的财务健康状况多样化。每股收益从负值到正值的极端不一,总收入反映了不同公司规模的广泛范围。
  • 显著的波动标志着股票价格的种类,而交易量凸显了不同实体间市场活动的多样性。
  • 我们的相关性研究揭示了不同股票价格点之间的强联系,公司收益和股价之间的中度关联,以及营收规模和交易量之间的轻微关系。
  • 一个有趣的发现是交易量和股票价格之间的反向关系,这表明交易活动的增加不一定与股票价格的上涨有关。

特征工程

凭借这些分析见解,我们将通过特征工程来增强我们的数据集:

  • 我们引入了预测性财务指标:
    • PE_Ratio:这个比率代表市盈率,是通过将收盘股价除以每股收益来计算的。
    • Price_Change:这反映了股票价格的变动,通过减去开盘价来计算。
    • Average_Price:这个指标对当天的开盘价、收盘价、最低价和最高价进行平均。
  • 为解决数据中的异常值,我们将使用四分位距(IQR)方法来识别和处理数值字段中的异常值。
  • 我们将使用MinMaxScaler对每股收益和总收入等重要的数值特征进行归一化处理,确保模型输入具有标准化的尺度。
  • “GICS Sector”类别将进行独热编码,将行业分类转换为与算法学习过程兼容的二进制格式。
  • 这个过程的最终结果是一个包含103个列的丰富数据集,整合了原始数据、新的工程特征以及独热编码的行业分类。
from sklearn.preprocessing import MinMaxScaler

# 重命名列以保持一致性
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'})

# 合并数据集
merged_data = pd.merge(pd.merge(fundamentals_renamed, prices_split_adjusted_renamed, on=['symbol', 'date']), securities_renamed, on='symbol')

# 创建新特征
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

# 处理异常值:使用IQR方法识别和处理数值列中的异常值
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))]

# 特征缩放:对数值特征进行归一化处理
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])

# 编码类别变量:将'GICS Sector'进行独热编码
merged_data_encoded = pd.get_dummies(merged_data, columns=['GICS Sector'])

# 显示预处理后的数据集样本
merged_data_encoded.head()

“用GPT-4打造个性化的人工智能交易顾问” 四海 第8张

模型训练与测试

“用GPT-4打造个性化的人工智能交易顾问” 四海 第9张

对于我们的股票价格预测项目,我们必须选择一个在处理回归任务方面表现出色的机器学习模型,因为我们正在处理预测连续的股票价格值。鉴于我们的数据集的多样性和复杂性,我们的模型需要熟练地捕捉数据中的复杂模式。

  • 模型选择:我们选择随机森林回归器(Random Forest Regressor),因为它具有多样性和稳健性,非常适合处理我们数据集的复杂性和各种特征。它在回归任务中表现优秀,不容易过拟合,并且可以处理非线性关系。
  • 数据划分:数据集被划分为80%用于训练和20%用于测试。这确保了全面的训练阶段,同时保留了一个重要的数据集用于验证。
  • 处理缺失值:使用sklearn.impute中SimpleImputer的中位数填充策略来处理缺失值,确保数据集的完整性和一致性。
  • 训练过程:模型在填充后的训练数据上进行训练,反映了存在缺失数据点的真实世界情况。
  • 性能评估:在训练后,使用填充后的测试集评估模型的预测准确性,为其在实际中的适用性提供见解。

以下代码演示了此过程的步骤:

from sklearn.model_selection import train_test_splitfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.metrics import mean_squared_error, r2_scorefrom sklearn.impute import SimpleImputer# 假设'close_price'为预测目标变量X = merged_data_encoded.drop(['close_price', 'symbol', 'date'], axis=1)  # 去除非数值和目标变量y = merged_data_encoded['close_price']# 检查数据集中的非数值列non_numeric_columns = X.select_dtypes(include=['object']).columns# 如果存在非数值列,将其从数据集中删除if len(non_numeric_columns) > 0:    X = X.drop(non_numeric_columns, axis=1)# 将数据集划分为训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 初始化随机森林回归器random_forest_model = RandomForestRegressor(n_estimators=100, random_state=42)# 创建一个使用中位数填充策略的填充器对象imputer = SimpleImputer(strategy='median')# 将填充器应用于训练和测试集X_train_imputed = imputer.fit_transform(X_train)X_test_imputed = imputer.transform(X_test)# 训练模型random_forest_model.fit(X_train_imputed, y_train)# 在测试集上进行预测y_pred = random_forest_model.predict(X_test_imputed)# 评估模型mse = mean_squared_error(y_test, y_pred)r2 = r2_score(y_test, y_pred)mse, r2

“用GPT-4打造个性化的人工智能交易顾问” 四海 第10张

模型性能

我们的随机森林回归器模型的输出表明以下结果:

  • 均方误差(MSE):低的MSE值8.592×10−5表明我们模型的预测值非常接近实际值,说明在预测股票价格方面具有较高的准确性。
  • 决定系数 (R²):近似0.96的R²值说明该模型可以解释约96%的股票价格变动性,这对于股票市场预测来说是异常高的。

与GPT-4 API的集成

在训练随机森林回归器模型并使其能够进行预测之后,我们将无缝集成它与GPT-4 API。这种集成使模型能够分析和预测股票价格,并将这些洞察力有效地传达给用户。凭借其先进的自然语言处理能力,GPT-4 API可以解释复杂的金融数据,并以用户友好的方式呈现。

集成是如何工作的?

下面是集成工作原理的详细说明:

  • 用户查询处理:函数get_model_predictions处理用户的查询,提取相关信息,如股票代码。由于我们没有最新的数据,我们将利用有关特定股票的摘要生成测试数据。
  • 模型预测和缩放:随机森林模型使用测试数据预测股票价格,并使用之前定义的缩放方法将其还原到原始值。
  • 为GPT-4准备提示:函数query_gpt4_with_context将用户的查询、模型预测和其他上下文(包括价格趋势、基本面和证券信息)结合起来。这个提示指导GPT-4根据用户的查询和模型的分析提供量身定制的金融咨询。
  • GPT-4查询和回复:提示根据数据和用户的财务资料生成量身定制的回复。
import osfrom openai import OpenAIfrom sklearn.impute import SimpleImputeros.environ["OPENAI_API_KEY"] ='YOUR API KEY'client = OpenAI()imputer = SimpleImputer(strategy='median')# 基于用户查询获取模型预测的函数def get_model_predictions(user_query):    ticker_symbol = user_query[0].split()[-1].strip().upper()    # 对数据应用imputer并使用模型进行预测    imputed_test_data = imputer.fit_transform(test_data)    predicted_scaled_value = random_forest_model.predict(imputed_test_data)[0]    confidence = 0.9  #假设我们对预测有90%的信心    # 创建一个与原始缩放数据形状相同的占位数组    placeholder_array = np.zeros((1, len(numerical_features)))    # 在正确的位置插入预测的缩放值    placeholder_array[0][3] = predicted_scaled_value    # 进行逆转换    predicted_original_value = scaler.inverse_transform(placeholder_array)    # 提取 'close_price' 的还原值    predicted_stock_price = predicted_original_value[0][3]    return {        "predicted_stock_price": predicted_stock_price,        "confidence": confidence    }# 带有模型上下文查询GPT-4的函数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()

现在,让我们用一些测试案例来测试我们的股票顾问的效果:

测试案例1

我是一个25岁的单身男性,对高风险具有较高的容忍度。我希望我的股票投资每年至少增长15%。两年前,我以每股40美元的价格购买了100股ABBV股票。我应该卖掉我的ABBV股票吗?这次销售可能的利润是多少美元和百分比?

让我们将这个查询输入我们的模型,看看我们得到什么输出。

user_query = ["我是一个25岁的单身男性。鉴于我的身份,我对风险具有较高的容忍度,并且希望我的股票投资每年至少增长15%。两年前,我以每股40美元的价格购买了100股ABBV股票。我应该考虑出售ABBV公司的股票吗?","这次销售的利润可能是多少美元和百分比?"]# 基于摘要统计信息为查询的股票生成一行随机数据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']].Ttest_data['random_value'] = np.random.randn(len(test_data)) * test_data['std'] + test_data['mean']# 仅选择随机值来形成DataFrametest_data = pd.DataFrame(test_data['random_value']).transpose()model_predictions = get_model_predictions(user_query)# 生成模型上下文model_context = f"当前预测的股票价格为{ticker_symbol},为${model_predictions['predicted_stock_price']},置信水平为{model_predictions['confidence']*100}%。"# 生成额外的数据上下文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回复:{gpt4_response}")

“用GPT-4打造个性化的人工智能交易顾问” 四海 第11张

测试案例2

我今年40岁,已婚女性。鉴于我的身份,我对风险的容忍度较低,并希望我的所有股票投资每年至少增长10%。我在两年前以每股100美元购买了100股ALXN公司的股票。我应该考虑出售ALXN公司的股票吗?从这次销售中,我可能获得的利润是多少美元和百分比?

  user_query = ["我今年40岁,已婚女性。鉴于我的身份,我对风险的容忍度较低,并希望我的所有股票投资每年至少增长10%。我在两年前以每股100美元购买了100股ALXN公司的股票。我应该考虑出售ALXN公司的股票吗?","从这次销售中,我可能获得的利润是多少美元和百分比?"]#基于其摘要统计信息,为被查询股票生成随机数据行的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' ]]。Ttest_data ['random_value'] = np.random.randn(len(test_data )) * test_data ['std'] + test_data ['mean']#只选择随机值以形成DataFrame test_data = pd.DataFrame(test_data ['random_value' ]).transpose()model_predictions = get_model_predictions(user_query)#生成模型上下文model_context = f“{ticker_symbol}的当前预测股票价格为${model_predictions['predicted_stock_price'] },置信度为{model_predictions ['confidence'] * 100%}。”#生成其他数据上下文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}”) 

“用GPT-4打造个性化的人工智能交易顾问” 四海 第12张

挑战

  • 实施此类项目的最大挑战之一是确保准确性和及时性的财务数据至关重要。不准确或过时的数据可能导致误导性的预测和建议。
  • 包括地缘政治事件,经济变化和公司特定新闻在内的众多不可预测因素影响股市。这些因素可能使人工智能预测不太可靠。
  • 尽管其先进能力,但人工智能模型可能难以完全掌握复杂的金融术语和概念,可能影响投资建议的质量。
  • 金融咨询受到严格的监管。确保基于人工智能的建议符合法律标准和道德准则是一个重大挑战。

结论

我们对股票交易中的人工智能的探索表明,像GPT-3和GPT-4这样的模型重新定义了这个领域,吸纳了大量数据,应用了复杂分析,并提供了精确的个性化见解。股票交易顾问的发展标志着每个人都能够进行可靠、熟知的交易的一大跃升。

关键要点

  • 将人工智能融入股票交易并不是未来的事情,而是正在改变我们与股票市场的互动方式。
  • 基于人工智能的模型,如GPT-3和GPT-4,提供个性化的策略,与个人风险承受能力和财务目标相符。
  • 人工智能利用历史和实时数据来预测市场趋势并指导投资策略。
  • 复杂的投资策略不再仅限于机构投资者,现在普通投资者也能够利用人工智能进行投资,这要归功于人工智能的进步。
  • 人工智能赋予投资者做出明智决策的能力,在投资领域的波动中提供战略优势。

常见问题

本文所示的媒体不归Analytics Vidhya所有,仅基于作者的决定使用。

Leave a Reply

Your email address will not be published. Required fields are marked *