examples/openbb_vs_langchain.ipynb
This notebook shows few examples on how to leverage OpenBB functionality via an Agent built with Langchain. It requires the user to have
For help on how to configure Colab Secrets, please refer to this article https://margaretmz.medium.com/use-colab-secrets-to-store-kaggle-api-key-b57c7464f9fa
This work was inspired by examples from this repo https://github.com/AlgoTrading101/Magentic-AlgoTrading101
Functionality shown in this notebook is purely an example of what can be done.
Marco Mistroni
!pip install openbb
!pip install openbb-yfinance
!pip install openbb-finviz
!pip install langchain
!pip install langchain_core
!pip install langchain_openai
from google.colab import userdata
OPENAI_KEY = userdata.get('OPENAI_KEY')
import os
from openbb import obb
from langchain_openai import ChatOpenAI
import logging
from langchain.agents import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-4.1", temperature=0, openai_api_key=OPENAI_KEY)
@tool
def get_industry_performance() -> list:
""" Return performance by industry for last week, last month, last quarter, last half year and last year"""
return obb.equity.compare.groups(group='industry', metric='performance').to_llm()
@tool
def get_strong_buy_for_sector(sector : str) -> list :
""" Return the strong buy recommendation for a given sector"""
new_sector = '_'.join(sector.lower().split()).lower()
data = obb.equity.screener(provider='finviz', sector=new_sector, recommendation='buy')
return data.to_llm()
@tool
def get_strong_buy_for_industry(industry : str) -> list :
""" Return the strong buy recommendation for a given industry"""
data = obb.equity.screener(provider='finviz', industry=industry, recommendation='buy')
return data.to_llm()
@tool
def get_best_stock_performers_for_sector(sector:str) -> list :
""" Return the best 5 stock performers for last week and last month for a given sector"""
data = obb.equity.screener(provider='finviz', filters_dict={'Sector' : sector, 'Performance' : 'Week Up', 'Performance 2' : 'Month Up'}, limit=5)
return data.to_llm()
@tool
def get_best_stock_performers_for_industry(industry:str) -> list :
""" Return the best 5 stock performers for last week and last month for an industry"""
data = obb.equity.screener(provider='finviz', filters_dict={'Industry' : industry, 'Performance' : 'Week Up', 'Performance 2' : 'Month Up'}, limit=3)
return data.to_llm()
@tool
def get_candidate_stocks_to_invest_relaxed(industry:str) -> list:
''' Use relaxed criteria to find best companies in an industry which are worth investing into'''
desc_filters = {
'Market Cap.': '+Small (over $300mln)',
'Average Volume': 'Over 200K',
}
fund_filters = {
'InstitutionalOwnership': 'Under 60%',
'Current Ratio' : 'Over 1.5',
'Debt/Equity' : 'Over 0.3',
#'EPS growthnext 5 years' : 'Positive (>0%)',
}
desc_filters.update(fund_filters)
try:
data = obb.equity.screener(provider='finviz', industry='semiconductors',
filters_dict=desc_filters
)
return data.to_llm()
except Exception as e:
logging.info(f'No data found:{str(e)}')
return []
@tool
def get_valuation_for_industries(input:str) -> list:
""" Return valuation metrics for the industry provided as input"""
data = obb.equity.compare.groups(group='industry', metric='valuation', provider='finviz').to_df()
filtered = data[data.name == input]
return filtered.to_json(
orient="records",
date_format="iso",
date_unit="s",
)
@tool
def get_consensus(ticker:str) -> list:
""" Return analyst consensus for the ticker provided
It returns the following fields:
- target_high: float, High target of the price target consensus.
- target_low: float Low target of the price target consensus.
- target_consensus: float Consensus target of the price target consensus.
- target_median: float Median target of the price target consensus
"""
data = obb.equity.estimates.consensus(symbol=ticker, limit=3, provider='yfinance').to_df()
return data.to_json(
orient="records",
date_format="iso",
date_unit="s",
)
from langchain_core.prompts import MessagesPlaceholder
from langchain.memory import ConversationTokenBufferMemory
from langchain.agents.format_scratchpad.openai_tools import (
format_to_openai_tool_messages,
)
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
from langchain_core.output_parsers import StrOutputParser, CommaSeparatedListOutputParser
from langchain.agents import AgentExecutor
from langchain_core.messages import AIMessage, HumanMessage
MEMORY_KEY = "chat_history"
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
""" You are very powerful stock financial researcher.
You will take the user questions and answer using the tools available.
Once you have the information you need, you will answer user's questions using the data returned.
Use the following tools to answer user queries:
- get_strong_buy_for_sector to find strong buy recommendations for a sector
- get_strong_buy_for_industry to find strong buy recommendations for an industry
- get_industry_performance to find the performance for an industry
- get_valuation_for_industries to find valuation metrics for industries
- get_candidate_stocks_to_invest_relaxed to fetch all companies using relaxed criteria
- def get_consensus(ticker:str) - to find analyst consensus for a company
You should call each function only once, and you should not call the function if you already have the information you need.
""",
),
MessagesPlaceholder(variable_name=MEMORY_KEY),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)
tools = [get_industry_performance, get_strong_buy_for_sector, get_strong_buy_for_industry, get_best_stock_performers_for_industry, get_valuation_for_industries,
get_candidate_stocks_to_invest_relaxed, get_consensus]
llm_with_tools = llm.bind_tools(tools)
chat_history = []
chat_history.append(HumanMessage(content="Your question here"))
chat_history.append(AIMessage(content="AI response here"))
memory = ConversationTokenBufferMemory(
llm=llm, # Required for token counting
max_token_limit=16000, # Leave buffer for functions + responses
memory_key="chat_history", # Must match your prompt's key
return_messages=True
)
agent = (
{
"input": lambda x: x["input"],
"agent_scratchpad": lambda x: format_to_openai_tool_messages(
x["intermediate_steps"]
),
"chat_history": lambda x: memory.load_memory_variables(x)["chat_history"],
}
| prompt
| llm_with_tools
| OpenAIToolsAgentOutputParser()
)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Then find the best performing company and check some metrics
input1 = '''
First, find an industry that has consistently shown positive performance across quarterly, monthly, and weekly timeframes.
Second, once you have identified the industry, extract its relevant valuation metrics (e.g., P/E, P/B, EV/EBITDA).
Third, extract companies from the selected industry using relaxed criteria.
Fourth, for the best performing companies get the analyst consensus
Finally, summarize your findings in no more than 80 words detailing:
- Best performing industry
- Best performing companies in industry
- A table displaying the analyst consensus for each of the companies you found at previous step'''
result = agent_executor.invoke({"input": input1, "chat_history": chat_history})
print(result['output'])
input1 = '''
First, find the stocks recommended fro strong buy in the Utilities Sector
Second, find the valuation metrics for this stock.
Third, summarize your findings in a short paragraph.
'''
result = agent_executor.invoke({"input": input1, "chat_history": chat_history})
print(result['output'])