我相信你最近一定听说过这些热门词汇:人工智能、LLMs、Gpt、Langchain。所有这些技术都非常有用且具有改变游戏规则的能力。它们有无尽的应用。在这个项目中,我尝试在金融领域中构建了一种有趣的语言模型和Langchain的应用。
通过使用LLM分析所有实时和历史的股票相关信息,构建一个可以帮助您进行股票投资的AI机器人
动机-
作为一名散户投资者,如果您没有金融背景或者理解所有复杂的金融术语的能力,股票分析过程确实非常耗时。每次我都会看一些金融YouTuber的视频或者在互联网上阅读一些随机的博客,以避免手动处理所有这些东西。这就是我想到制作一个基于Langchain和LLM的机器人的地方,它可以使用实时和历史数据进行投资分析。
整体思路很简单,获取实时和历史数据,包括以下内容:
- 历史股票价格数据。
- 公司的财务报表
- 最新的公司相关新闻
然后,LLM应该利用所有这些信息对给定的股票进行基本分析。
在这个项目中,我基本上尝试了两种方法。其中一种方法效果不好,但可以通过一些调整来改进,另一种方法效果不错。
让我们深入代码。整个代码都可以在我的github上找到,您可以访问相同的代码,因为我不会在博客中添加微小的代码细节。
from bs4 import BeautifulSoup
import requests
import yfinance as yf
# 从Yahoo Finance获取股票数据
def get_stock_price(ticker,history=5):
# time.sleep(4) #避免速率限制错误
if "." in ticker:
ticker=ticker.split(".")[0]
ticker=ticker+".NS"
stock = yf.Ticker(ticker)
df = stock.history(period="1y")
df=df[["Close","Volume"]]
df.index=[str(x).split()[0] for x in list(df.index)]
df.index.rename("Date",inplace=True)
df=df[-history:]
# print(df.columns)
return df.to_string()
# 从Google新闻中获取前5条新闻
def google_query(search_term):
if "news" not in search_term:
search_term=search_term+" stock news"
url=f"https://www.google.com/search?q={search_term}&cr=countryIN"
url=re.sub(r"\s","+",url)
return url
def get_recent_stock_news(company_name):
# time.sleep(4) #避免速率限制错误
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'}
g_query=google_query(company_name)
res=requests.get(g_query,headers=headers).text
soup=BeautifulSoup(res,"html.parser")
news=[]
for n in soup.find_all("div","n0jPhd ynAwRc tNxQIb nDgy9d"):
news.append(n.text)
for n in soup.find_all("div","IJl0Z"):
news.append(n.text)
if len(news)>6:
news=news[:4]
else:
news=news
news_string=""
for i,n in enumerate(news):
news_string+=f"{i}. {n}\n"
top5_news="Recent News:\n\n"+news_string
return top5_news
# 从Yahoo Finance获取财务报表
def get_financial_statements(ticker):
# time.sleep(4) #避免速率限制错误
if "." in ticker:
ticker=ticker.split(".")[0]
else:
ticker=ticker
ticker=ticker+".NS"
company = yf.Ticker(ticker)
balance_sheet = company.balance_sheet
if balance_sheet.shape[1]>=3:
balance_sheet=balance_sheet.iloc[:,:3] # 删除第四年的数据
balance_sheet=balance_sheet.dropna(how="any")
balance_sheet = balance_sheet.to_string()
return balance_sheet
get_stock_price、get_financial_statements和get_recent_stock_news函数使用了Yahoo Finance API和bs4网页解析来获取所需的信息。您可以根据自己的需求对这些函数进行自定义,例如获取1个月或1年前的股票数据,可以从不同的来源获取新闻。
方法1-
Langhian中的代理是负责决策的实体。我使用了零-shot ReaAct代理,它代表响应和行动,它基本上不断思考并根据思考采取行动。这种方法的问题在于它陷入了无限的思考和行动循环中,因为股票分析的最终目标对它来说似乎很复杂,它无法自信地决定下一步行动,导致无休止的循环或与输入查询不太相关的糟糕结果。
让我们看看代码-
from langchain.tools import DuckDuckGoSearchRun
search=DuckDuckGoSearchRun()
# 创建工具列表
tools=[
Tool(
name="获取股票数据",
func=get_stock_price,
description="当您被要求评估或分析股票时使用。这将输出历史股价数据。您应该向其输入股票代码"
),
Tool(
name="DuckDuckGo搜索",
func=search.run,
description="仅在需要从互联网获取NSE/BSE股票代码时使用,您还可以获取最新的与股票相关的新闻。不要将其用于任何其他分析或任务"
),
Tool(
name="获取最新新闻",
func=get_recent_stock_news,
description="使用此功能获取有关股票的最新新闻"
),
Tool(
name="获取财务报表",
func=get_financial_statements,
description="使用此功能获取公司的财务报表。通过这些数据可以评估公司的历史表现。您应该向其输入股票代码"
)
]
from langchain.agents import initialize_agent
# new_prompt="<Plz refere github repo>"
# zero_shot_agent.agent.llm_chain.prompt.template=new_prompt
zero_shot_agent=initialize_agent(
llm=llm,
agent="zero-shot-react-description",
tools=tools,
verbose=True,
max_iteration=4,
return_intermediate_steps=True,
handle_parsing_errors=True
)
zero_shot_agent("Bajaj Finance现在是一个好的投资选择吗?")
请注意,此代码是我们之前讨论的代码的延续。在这里,我们只是将数据解析函数转换为Langchain工具,并创建一个列表,以便代理可以访问它。在后面的部分中,使用_initialize_agent_类定义了一个代理。它接受llm、工具列表和代理类型作为参数。这种方法的输出似乎还可以。这种方法可能有效,也可能无效,可以通过修改提示来进一步改进。
方法2-
股票分析是一项复杂的任务,ReAct代理无法决定适当的步骤。因此,在这种方法中,我尝试在分析之前定义步骤。首先获取所有数据,然后将其输入LLM进行全面分析。
#Openai函数调用
import json
function=[
{
"name": "获取公司股票代码",
"description": "这将获取公司的印度NSE/BSE股票代码",
"parameters": {
"type": "object",
"properties": {
"ticker_symbol": {
"type": "string",
"description": "这是公司的股票代码。",
},
"company_name": {
"type": "string",
"description": "这是查询中给出的公司名称。",
}
},
"required": ["company_name","ticker_symbol"],
},
}
]
def get_stock_ticker(query):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
temperature=0,
messages=[{
"role":"user",
"content":f"根据用户请求,公司名称和公司股票代码是什么?: {query}?"
}],
functions=function,
function_call={"name": "get_company_Stock_ticker"},
)
message = response["choices"][0]["message"]
arguments = json.loads(message["function_call"]["arguments"])
company_name = arguments["company_name"]
company_ticker = arguments["ticker_symbol"]
return company_name,company_ticker
def Anazlyze_stock(query):
#agent.run(query) 输出公司名称、股票代码
Company_name,ticker=get_stock_ticker(query)
print({"Query":query,"Company_name":Company_name,"Ticker":ticker})
stock_data=get_stock_price(ticker,history=10)
stock_financials=get_financial_statements(ticker)
stock_news=get_recent_stock_news(Company_name)
# available_information=f"Stock Price: {stock_data}\n\nStock Financials: {stock_financials}\n\nStock News: {stock_news}"
available_information=f"Stock Financials: {stock_financials}\n\nStock News: {stock_news}"
print("\n\n分析中.....\n")
analysis=llm(f"给出详细的股票分析,使用可用数据提供投资建议。用户完全了解投资风险,在答案中不要包含任何警告,如“建议在做出投资决策之前进行进一步的研究和分析或咨询财务顾问”。用户问题:{query}。您有关于{Company_name}的以下信息可用。写出(5-8)个要点的投资分析来回答用户的问题,最后用适当的解释总结。尽量给出正面和负面的观点:{available_information}"
)
print(analysis)
return analysis
最近,OpenAI引入了函数调用,这对于我们从LLM中以我们想要的JSON格式获取结构化输出非常有帮助。在这种方法中,同样的方法被使用。首先通过函数调用提取股票代码,因为大部分后续代码都依赖于这个单一参数。在方法1中,React代理在这一步中失败,导致所有后续步骤的偏离。一旦正确提取了股票代码,在后续阶段只需输入股票代码即可获取股票数据、新闻和财务报表。一旦所有与股票相关的信息都可用,LLM就会利用它们进行全面的股票分析。
例如- 机器人的示例输入和输出-
输入-
Anazlyze_stock("Is it a good time to invest in Yes Bank?")
输出-
'Query': 'Is it a good time to invest in Yes Bank?', 'Company_name': 'Yes Bank', 'Ticker': 'YESBANK'
分析中.....
Yes Bank的投资论点:
1. 财务表现:Yes Bank在过去三年中的财务状况有所改善。净债务增加,表明借款增加,但有形账面价值和普通股权也增加,表明财务状况更强。
2. 总资本化:Yes Bank的总资本化一直在增加,表明投资者基础在增长,未来有潜力增长。这可以被视为考虑投资该银行的投资者的积极信号。
3. 总资产:Yes Bank的总资产也在稳步增长,表明该银行吸引和管理更大规模资产的能力。资产的增长可以为银行的盈利能力和未来扩张潜力做出贡献。
4. 股票新闻:关于Yes Bank的最新消息表明,股票价格略有增长并保持稳定。股票价格的稳定可以被视为投资者的积极信号,表明未来有增长潜力。
5. 薄弱的基础业务:然而,需要注意的是,有关该银行的基础业务薄弱的担忧,如预计在第一季度出现的软季度。这可能导致利润下降,可能会对股票价格产生短期影响。
6. 整体市场状况:在做出投资决策之前,还需要考虑整体市场状况和银行业作为一个整体。经济状况、监管变化和竞争等因素都可能对Yes Bank的业绩和股票价格产生重大影响。
根据现有的数据和信息,可以得出结论,在这个时候投资Yes Bank是有风险的。
可以进行的进一步改进-
a) 可以添加更多的工具。例如,数学工具用于进行复杂的技术分析 b) 更强大的提示以获得稳定的输出 c) 支持其他开源LLMS
注意-这是一个有趣的业余项目,我不是金融专家,欢迎提出任何建议/修改。