Swarm MultiAgents Financial Analyst Framework
Swarm MultiAgents Financial Analyst Framework
1
� So, How to set up the Swarm multi-agent framework for financial analysis purpose?
I created 4 agents:
• manager_agent: This agent will handle determning and switching between agents to trans-
fer the user’s request to the best suited agent.
• stock_price_agent: This agent is responsible of fetching the last available price, volume,
average price 50d, 200d, EPS, PE, and the next earnings annoucement.
• company_basic_information_agent: This agent is responsible of collecting the company
basic data like description market capitalization, sector, industry…
• income_statement_agent: This agent is responsible of gathering the last income state-
ment data such as revenue, gross profit, net income, EBITDA, EPS.
• For each sub-agent, I define a set of functions to handle collecting the appropriate data.
• The manager agent will manage functions that distribute the request to the various agents.
• Each sub-agent will have a function to transfer request back to the manager.
� Discover how this framework works in this notebook: �
Hanane DUPOUY
2 Install Swarm
[ ]: pip install git+https://github.com/openai/swarm.git -q
import os
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
import requests
FINANCIAL_MODELING_PREP_API_KEY = userdata.
↪get('FINANCIAL_MODELING_PREP_API_KEY')
2
"""
url = f"https://financialmodelingprep.com/api/v3/quote-order/{symbol}?
↪apikey={FINANCIAL_MODELING_PREP_API_KEY}"
response = requests.get(url)
data = response.json()
try:
price = data[0]['price']
volume = data[0]['volume']
priceAvg50 = data[0]['priceAvg50']
priceAvg200 = data[0]['priceAvg200']
eps = data[0]['eps']
pe = data[0]['pe']
earningsAnnouncement = data[0]['earningsAnnouncement']
return {"symbol": symbol.upper(), "price": price, "volume":
↪volume,"priceAvg50":priceAvg50, "priceAvg200":priceAvg200, "EPS":eps, "PE":
↪pe, "earningsAnnouncement":earningsAnnouncement }
def get_company_financials(symbol):
"""
Fetch basic financial information for the given company symbol such as the␣
↪industry, the sector, the name of the company, and the market capitalization.
"""
url = f"https://financialmodelingprep.com/api/v3/profile/{symbol}?
↪apikey={FINANCIAL_MODELING_PREP_API_KEY}"
response = requests.get(url)
data = response.json()
try:
results = data[0]
financials = {
"symbol": results["symbol"],
"companyName": results["companyName"],
"marketCap": results["mktCap"],
"industry": results["industry"],
"sector": results["sector"],
"website": results["website"],
"beta":results["beta"],
"price":results["price"],
}
return financials
except (IndexError, KeyError):
return {"error": f"Could not fetch financials for symbol: {symbol}"}
def get_income_statement(symbol):
"""
3
Fetch last income statement for the given company symbol such as revenue,␣
↪gross profit, net income, EBITDA, EPS.
"""
url = f"https://financialmodelingprep.com/api/v3/income-statement/{symbol}?
↪period=annual&apikey={FINANCIAL_MODELING_PREP_API_KEY}"
response = requests.get(url)
data = response.json()
try:
results = data[0]
financials = {
"date": results["date"],
"revenue": results["revenue"],
"gross profit": results["grossProfit"],
"net Income": results["netIncome"],
"ebitda": results["ebitda"],
"EPS": results["eps"],
"EPS diluted":results["epsdiluted"]
}
return data, financials
except (IndexError, KeyError):
return {"error": f"Could not fetch financials for symbol: {symbol}"}
manager_agent = Agent(
name="Manager Agent",
instructions="Determine which agent is best suited to handle the user's␣
↪request, and transfer the conversation to that agent.",
4
stock_price_agent = Agent(
name="Stock Price Agent",
instructions="Fetch Hsitorical prices for a given stock symbol, the current␣
↪volume, the average price 50d and 200d, EPS, PE and the next earnings␣
↪Announcement.",
functions=[get_stock_price],
)
company_basic_information_agent = Agent(
name="Company basic information Agent",
instructions="Fetch basic financial information for the given company␣
↪symbol such as the industry, the sector, the name of the company, and the␣
↪market capitalization.",
functions=[get_company_financials],
)
income_statement_agent = Agent(
name="Income Statement Agent",
instructions=" Fetch last income statement for the given company symbol␣
↪such as revenue, gross profit, net income, EBITDA, EPS.",
functions=[get_income_statement],
)
def transfer_back_to_manager():
"""Call this function if a user is asking about a topic that is not handled␣
↪by the current agent."""
return manager_agent
def transfer_to_stock_price():
return stock_price_agent
def transfer_to_company_basic_info():
return company_basic_information_agent
def transfer_to_income_statement():
return income_statement_agent
manager_agent.functions = [transfer_to_stock_price,␣
↪transfer_to_company_basic_info, transfer_to_income_statement]
stock_price_agent.functions.append(transfer_back_to_manager)
company_basic_information_agent.functions.append(transfer_back_to_manager)
income_statement_agent.functions.append(transfer_back_to_manager)
5
5 Chating with the Agents:
I asked different questions:
• What is the current stock price of Amazon and Nvidia
• What is their market capitalization?
• What is the EPS of Apple?
• When will the next earnings announcement be?
• What is the revenue of Amazon?
You can see the different calls and communications between the manager agent and the different
sub-agents:
[15]: # You can get this code from "from swarm.repl import run_demo_loop"==>I've␣
↪extracted here to add "exit" to break the loop.
import json
def process_and_print_streaming_response(response):
content = ""
last_sender = ""
if "response" in chunk:
6
return chunk["response"]
def run_demo_loop(
starting_agent, context_variables=None, stream=False, debug=False
) -> None:
client = Swarm()
print("Starting Swarm CLI �")
messages = []
agent = starting_agent
while True:
user_input = input("\033[90mUser\033[0m: ")
if user_input.lower() == "exit":
break
messages.append({"role": "user", "content": user_input})
response = client.run(
agent=agent,
messages=messages,
context_variables=context_variables or {},
stream=stream,
debug=debug,
7
)
if stream:
response = process_and_print_streaming_response(response)
else:
pretty_print_messages(response.messages)
messages.extend(response.messages)
agent = response.agent
**Amazon (AMZN)**:
- Current Price: $191.23
- Volume: 15,906,252
- Average Price (50 days): $182.20
- Average Price (200 days): $178.90
- Earnings Per Share (EPS): $4.20
- Price to Earnings Ratio (PE): 45.53
- Next Earnings Announcement: October 31, 2024
**Nvidia (NVDA)**:
- Current Price: $143.91
- Volume: 166,377,366
- Average Price (50 days): $122.37
- Average Price (200 days): $100.89
- Earnings Per Share (EPS): $2.14
- Price to Earnings Ratio (PE): 67.25
- Next Earnings Announcement: November 21, 2024
User: What is their market capitalization?
Stock Price Agent: transfer_back_to_manager()
Manager Agent:
transfer_to_company_basic_info()
transfer_to_company_basic_info()
Company basic information Agent:
get_company_financials("symbol"= "AMZN")
8
get_company_financials("symbol"= "NVDA")
Company basic information Agent: Here are the market capitalizations
for the companies:
6 Key Takeways:
• A highly customizable framework: Each agent is equipped with specific instructions to ensure
clarity and optimal outcomes.
• The implementation is broken down to the most granular level, allowing you to build your
agent exactly as you desire.
• There is no built-in memory management like the Assistant AI API provides.