Empowering the AI Stock Analysis Agent with Universe Scanning

Introduction

Welcome back to this ongoing series on building an AI-powered stock analysis agent! In the previous articles, I’ve covered many topics, from laying the foundation with LangChain, OpenBB, and Claude 3 Opus to enhancing the agent’s capabilities with fundamental and technical analysis tools, sentiment analysis, relative strength rankings, and chart-based analysis. Today, I’ll take a significant leap forward by introducing the concept of universe scanning.

Universe scanning is a powerful feature that enables the AI agent to analyze multiple stocks simultaneously and identify the most promising opportunities. Expanding the agent’s scope from a single stock to a diverse universe of stocks can unlock new insights and streamline the process of finding winning trades. The repo has been updated.

Setting Up the Universe Scanning Framework

To implement universe scanning, I must first define the stock universe the agent will analyze. The stock universe is a carefully curated list of stocks that meet specific criteria, ensuring a diverse and representative market sample. In this example, I’ll use the finvizfinance library to fetch a custom stock universe based on predefined criteria.

Python
import warnings

warnings.filterwarnings("ignore", category=FutureWarning)

from finvizfinance.screener.overview import Overview

# Custom universe criteria, please see FinViz for all available filters
UNIVERSE_CRITERIA = {
    "Market Cap.": "+Small (over $300mln)",
    "Average Volume": "Over 750K",
    "Price": "Over $10",
    "Industry": "Stocks only (ex-Funds)",
    "20-Day Simple Moving Average": "Price above SMA20",
    "50-Day Simple Moving Average": "Price above SMA50",
    "200-Day Simple Moving Average": "SMA200 below SMA50",
    "EPS growththis year": "Over 20%",
    "EPS growthnext year": "Positive (>0%)",
    "EPS growthqtr over qtr": "Over 20%",
    "Sales growthqtr over qtr": "Over 20%",
    "Gross Margin": "Positive (>0%)",
    "Return on Equity": "Positive (>0%)",
}

def screener(filters):
    """
    Returns a DataFrame of the screener view with the given filters, sorted by Market Cap.
    """
    view = Overview()
    view.set_filter(filters_dict=filters)
    df = view.screener_view(verbose=0)
    return df.sort_values(by="Market Cap", ascending=False)

def fetch_custom_universe():
    """
    Returns a custom universe of stocks based on the UNIVERSE_CRITERIA dictionary.
    """
    return screener(UNIVERSE_CRITERIA)

In this code, I define a dictionary UNIVERSE_CRITERIA that holds the custom criteria for my stock universe. These criteria include filters for market capitalization, average trading volume, price, industry, moving averages, earnings growth, sales growth, gross margin, and return on equity. One can customize these criteria based on their specific requirements using the filters on FinViz’s screener page.

The screener function takes a dictionary of filters and returns a pandas DataFrame of the screener view, sorted by market capitalization in descending order. It uses the Overview class from finvizfinance to set the filters and retrieve the screener data. The fetch_custom_universe function calls the screener function with the UNIVERSE_CRITERIA dictionary to fetch the custom stock universe.

To integrate this custom universe fetching functionality into the AI agent, I can create a LangChain tool using the @tool decorator.

Python
@tool
def get_stock_universe() -> str:
    """Fetch the Trending Stocks Universe from FinViz."""
    try:
        return wrap_dataframe(fetch_custom_universe())
    except Exception as e:
        return f"\n<observation>\nError: {e}\n</observation>\n"

Finding Alpha

Below is an example of the DataFrame returned from fetch_custom_universe. The headers here vary based on the type of screener page that I invoke, in this case, the Overview page. finvizfinance has classes for other pages if one wants to load their agent with different data to pass to the executor.

I can then query the AI stock agent to pipeline the resulting tickers from FinViz into the other tools get_stock_price_history and get_relative_strength that I defined in previous posts. Here’s an example query that I gave to the agent and the final result.

Conclusion

Integrating universe scanning into the AI-powered stock analysis agent has significantly expanded its capabilities, enabling it to identify the most promising opportunities across diverse stocks. By leveraging the finvizfinance library and adapting the existing analysis tools, the agent can now comprehensively assess each stock based on a well-defined set of bullish criteria other traders can modify based on their own screening preferences.

Looking ahead, I’ll continue refining and expanding the agent’s capabilities. In upcoming blog posts, I’ll explore the crucial topic of risk management, which is essential for long-term success in the markets. I’ll also explore techniques such as position sizing, stop-loss strategies, and R multiples. So, stay tuned for more as I continue swapping symbols.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.