Back to Openbb

Openbb Vs Langchain

examples/openbb_vs_langchain.ipynb

4.7.08.6 KB
Original Source

Brief Description

This notebook shows few examples on how to leverage OpenBB functionality via an Agent built with Langchain. It requires the user to have

  • an OpenAI Key. This is required as OpenAI is used as LLM

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.

Author

Marco Mistroni

Installing dependencies

python
!pip install openbb
!pip install openbb-yfinance
!pip install openbb-finviz
!pip install langchain
!pip install langchain_core
!pip install langchain_openai

Getting keys

python
from google.colab import userdata
OPENAI_KEY = userdata.get('OPENAI_KEY')
python
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)

OpenBB Useful functions

python
@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",
        )


Chat Memory

python
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"),
    ]
)
python
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)
python
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)

Let's try a chain of thought approach. We start with the industry with best performance.

Then find the best performing company and check some metrics

python
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'])

Finding strong buys in the Utilities sector

python
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'])