Motivation
The motivation for developing the Investment Research Assistant stems from the need for Relationship Managers (RMs) in banks to efficiently query a stock universe and provide comprehensive investment advice to customers. Traditionally, RMs must navigate through a cumbersome click interface to find relevant stocks, particularly when specific criteria such as sector interest or geographical focus are involved. Furthermore, once stocks are identified, RMs need to delve into fact sheets to provide detailed rationales for each recommendation, explaining why a customer should invest in specific stocks or bonds. This process is time-consuming and labor-intensive. The Investment Research Assistant leverages GenAI to simplify this workflow, allowing RMs to use natural language queries and automate the extraction of relevant stock data and fact sheet insights.
Goal
The goal of the Investment Research Assistant, developed by Unique, is to streamline the process of querying a stock universe and preparing detailed investment recommendations. By integrating GenAI capabilities, it enables RMs to efficiently generate queries, extract pertinent stock data, and produce comprehensive rationales from fact sheets. This reduces the time and effort required to provide high-quality investment advice, enhancing the overall efficiency and effectiveness of RMs.
Structure and Logic of Assistant
Step 1: Extraction of Stock Data
The process begins when the RM inputs a natural language query specifying the customer's interests and criteria (e.g., "My client is interested in stocks with a 5 star Sustainability Rating"). The system then generates a query to an in-house or CSV-based stock database. The system extracts the most relevant stocks based on the given criteria, considering factors such as sustainability ratings or buy signals.
→ The extracted list of stocks is then prepared for further analysis.
Step 2: Extraction of Fact Sheet Rationales
In this step, the system loads the fact sheets of the stocks identified in Step 1 into an LLM (Large Language Model). The LLM processes each fact sheet to extract the most relevant rationales, providing detailed insights and justifications for why each stock is a suitable investment. The extracted rationales are then compiled into a coherent narrative.
→ The compiled rationales are presented in a chat interface, allowing the RM to review and refine the recommendations.
Step 3: Generating Follow-up Email
Once satisfied with the extracted stock data and rationales, the RM can generate a follow-up email to the customer. This email includes a detailed investment story, attaching relevant fact sheets and any additional necessary documents. The RM can customize the email content and attachments as needed.
→ The final email, complete with fact sheets and recommendations, is ready to be sent to the customer.
Possible Adaption of Assistant
The Investment Research Assistant can be adapted to various scenarios, enhancing its flexibility and applicability:
Custom Data Integration: Users can upload their own stock universe as a CSV file and attach their own fact sheets for analysis.
Tailored Outputs: The assistant can be customized to generate different types of outputs based on specific user needs, such as creating tailored investment stories.
Custom Query Optimization: The system allows for the integration of custom few-shot learning examples to improve the accuracy of query generation.
Required and optional modules
The following modules are required/optional for this assistant:
Required | Optional |
---|---|
Example AI Assistant Configuration:
Save the following example in a TXT file and then upload it into a new space as an AI Assistant configuration:
{ "modules": [ { "name": "InvestmentResearchTable", "weight": 800, "configuration": { "tableConfig": [ { "footer": "", "header": "# Stocks <sup>1</sup>\n\n", "columns": [ { "name": "Company Name", "type": "String", "displayed": true, "idenfiying": true }, { "name": "Recommendation", "type": "String", "displayed": true }, { "name": "Industry", "type": "String", "displayed": true }, { "name": "ISIN", "type": "String", "displayed": true, "idenfiying": true }, { "name": "Sustainability Rating", "type": "Number", "displayed": true }, { "name": "Currency", "type": "String", "displayed": true }, { "name": "Stock Price", "type": "Number", "displayed": true }, { "name": "Market Capitalization", "type": "Number", "displayed": true }, { "name": "Price to Earnings", "type": "Number", "displayed": true } ], "fallback": true, "language": "english", "nameColumn": "Company Name", "languageCode": "en", "noStocksFound": "No stocks found that match the criteria or I was unable to understand the request correctly", "stockFileName": "$ISIN$-factsheet.pdf", "tableFileName": "demo_stocks.csv", "repeatingTable": "\n--- \n \n## $Industry$ \n\n# $Company Name$ <mark>$Recommendation$</mark>\n\n| ISIN | Sustainability Rating | Stock Price | Market Cap (in US B) | Price to Earnings |\n| --- | --- | --- | --- | --- |\n| $ISIN$ | $Sustainability Rating$ | $Stock Price$ $Currency$ | $Market Capitalization$ | $Price to Earnings$ |\n" } ], "searchExamples": [ { "role": "user", "content": "Example 1: list all sustanabnility ratings" }, { "role": "assistant", "content": "{\n \"explanation\": \"While the user requested a list of all sustainability ratings, the SQL query is configured to select one stock corresponding to each sustainability rating category present in the table attributes (1Star, 2Star, 3Star, 4Star, 5Star). To ensure that only a single stock for each rating category is chosen, the query employs the 'LIMIT 1' clause. The results from these individual selections are then combined into a unified result set using the 'UNION' operator. In line with standard practice, the query will include all available columns for each stock selected using SELECT * FROM.\",\n \"SQLquery\": \"SELECT * FROM (SELECT * FROM csvTable WHERE [Sustainability Rating] = '1Star' LIMIT 1) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Sustainability Rating] = '2Star' LIMIT 1) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Sustainability Rating] = '3Star' LIMIT 1) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Sustainability Rating] = '4Star' LIMIT 1) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Sustainability Rating] = '5Star' LIMIT 1)\"\n}" }, { "role": "user", "content": "Example 2a: what was the last price and percentage price of Colgate" }, { "role": "assistant", "content": "{\n \"explanation\": \"The SQL query is designed to select the stock labeled as 'Colgate' from the 'Company Name' attribute. However, the 'Company Name' attribute does not explicitly list 'Colgate'. The closest match available is 'Colgate-Palmolive Co'. Therefore, the query will select 'Colgate-Palmolive Co' and include all columns using SELECT * FROM, even though the user may have requested specific attributes only.\",\n \"SELECT * FROM csvTable WHERE [Company Name] = 'Colgate-Palmolive Co' LIMIT 1\"\n}" }, { "role": "assistant", "content": "# Stocks <sup>1</sup>\n\n\n--- \n \n## Consumer Staples \n\n# Colgate-Palmolive Co <mark>Buy</mark>\n\n| ISIN | Investment Region | Sub-Sector | Sustainability Rating | Product Price | Market Cap (in EUR m) | Price to Earnings | Dividend Yield |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| US1111111111 | North America | Household ? Personal Products | 1Star | 10.31 USD | 111111210000 | 20.46 | 10.2 % |\n" }, { "role": "user", "content": "Example 2b: add Swach" }, { "role": "assistant", "content": "{\n \"explanation\": \"Despite the user's misspelling of 'Swach', the search will be for 'The Swatch Group Ltd', as listed in the 'Company Name' attribute. The SQL query will select the stocks with the [Company Name] 'Colgate-Palmolive Co' and 'The Swatch Group Ltd' and include all columns as designed using SELECT * FROM.\",\n \"SQLquery\": \"SELECT * FROM csvTable WHERE [Company Name] IN ('Colgate-Palmolive Co', 'The Swatch Group Ltd')\"\n}" }, { "role": "user", "content": "Example 3a: give me a buy rated stock from two different countries" }, { "role": "assistant", "content": "{\n \"explanation\": \"The SQL query is tailored to pick one stock for each country. However, since the 'Country' attribute is absent in the table, I'll use 'Investment Region' as a proxy. Selecting stocks from two distinct investment regions, Europe and Asia, ensures diversity in country representation, especially considering these regions have 'buy' ratings. These regions are recognized as valid values in the 'Investment Region' attribute of the table. To ensure exclusivity, the query incorporates a 'LIMIT 1' clause, which limits the selection to only one stock per region. Consistent with usual practices, the query retrieves all available columns for each stock selected using SELECT * FROM.\",\n \"SQLquery\": \"SELECT * FROM (SELECT * FROM csvTable WHERE [Investment Region] = 'Europe' AND [Rating] = 'Buy' LIMIT 1) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Investment Region] = 'Asia/Pacific ex Japan' AND [Rating] = 'Buy' LIMIT 1)\"\n}" }, { "role": "assistant", "content": "# Stocks <sup>1</sup>\n\n\n--- \n \n## Consumer Discretionary \n\n# Stellantis N.V. <mark>Buy</mark>\n\n| ISIN | Investment Region | Sub-Sector | Sustainability Rating | Product Price | Market Cap (in EUR m) | Price to Earnings | Dividend Yield |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| NL000000000Q9 | Europe | Automobiles ? Components | 3Star | 1.198 EUR | 111111160000 | 1.22 | 1.35 % |\n" }, { "role": "user", "content": "Example 3b: give me another one" }, { "role": "assistant", "content": "{\n \"explanation\": \"The SQL query will initially select the stock identified as 'Stellantis N.V.' which has already been extracted. Subsequently, it will choose a stock from North America, specifically those with a 'buy' rating. The choice of North America stems from the observation in the previously extracted table that only one row from Europe was returned, suggesting the absence of 'buy' rated stocks from Asia in the current table. Consistently, the query will include all available columns for each stock that is selected using SELECT * FROM.\",\n \"SQLquery\": \"SELECT * FROM (SELECT * FROM csvTable WHERE [Company Name] IN ('Stellantis N.V.')) UNION SELECT * FROM (SELECT * FROM csvTable WHERE [Rating] = 'Buy' AND [Investment Region] = 'North America' AND [Company Name] NOT IN ('Stellantis N.V.') LIMIT 1)\"\n}" }, { "role": "assistant", "content": "# Stocks <sup>1</sup>\n\n\n--- \n \n## Financials \n\n# Citigroup Inc <mark>Buy</mark>\n\n| ISIN | Investment Region | Sub-Sector | Sustainability Rating | Product Price | Market Cap (in EUR m) | Price to Earnings | Dividend Yield |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| US111114242 | North America | Banks | 4Star | 11.23 USD | 86561110000 | 1.83 | 1.79 % |\n\n\n\n--- \n \n## Consumer Discretionary \n\n# Stellantis N.V. <mark>Buy</mark>\n\n| ISIN | Investment Region | Sub-Sector | Sustainability Rating | Product Price | Market Cap (in EUR m) | Price to Earnings | Dividend Yield |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| NL1111001Q9 | Europe | Automobiles ? Components | 3Star | 18.798 EUR | 11111660000 | 1.22 | 1.35 % |\n" }, { "role": "user", "content": "Example 3c: add two more from Germany" }, { "role": "assistant", "content": "{\n \"explanation\": \"The SQL query is designed to retrieve all columns for specific companies based on the previous extraction criteria. It will select all available data for 'Citigroup Inc.' and 'Stellantis N.V.'. Additionally, although the attribute 'Investment Region' = Germany is not listed, the query will include 'Deutsche Post AG' and 'Deutsche Telekom AG', as these are the most relevant German companies. For each of these selected stocks, the query will use 'SELECT * FROM' to ensure all available columns are included in the output.\",\n \"SQLquery\": \"SELECT * FROM csvTable WHERE [Company Name] IN ('Deutsche Post AG', 'Deutsche Telekom AG', 'Citigroup Inc', 'Stellantis N.V.')\"\n}" }, { "role": "user", "content": "Forget about the previous answers and respond to the next question in the same way as above." }, { "role": "assistant", "content": "Ok, I forgot about the previous answers and will respond to the next question in the same way as above." } ] }, "isExternal": false }, { "name": "EmailWriter", "weight": 4000, "configuration": { "languageModel": "AZURE_GPT_35_TURBO_16K", "systemPromptEmailWriter": "You are a helpful assistant you can write an email in the language asked.\n\nThe output MUST be a in the following structure:\n\n# Subject: <subject>\n\nEmail Text: <email text>\n\nmail to: <email address>\n\n", "triggerPromptEmailWriter": "Write aneEmail according to the TASK given by the user. \nIf it is unclear what to write as an email, use the message given:\n\nMESSAGE:\n\nLAST_MESSAGE\n\nTASK: \n\nUSER_MESSAGE\n\nAnswer in the following format:\n\n# Subject: <subject>\n\nEmail Text: <email text>\n\nmail to: <email address>\n\n:" }, "isExternal": false, "toolDefinition": { "type": "function", "function": { "name": "EmailWriter", "parameters": { "type": "object", "properties": { "instruction": { "type": "string", "description": "The instruction given by the employee e.g., 'Write this as an email'." } } }, "description": "Useful if the task is ONLY asking to write an email e.g., 'Write the above message as an email to Christian' or 'write this as an email'. The employee is not asking a question." } } }, { "weight": 5300, "name": "InvestmentResearchDocuments", "configuration": { "tableConfig": [ { "footer": "", "header": "# Stocks <sup>1</sup>\n\n", "columns": [ { "name": "Company Name", "type": "String", "displayed": true, "idenfiying": true }, { "name": "Recommendation", "type": "String", "displayed": true }, { "name": "Industry", "type": "String", "displayed": true }, { "name": "ISIN", "type": "String", "displayed": true, "idenfiying": true }, { "name": "Sustainability Rating", "type": "Number", "displayed": true }, { "name": "Currency", "type": "String", "displayed": true }, { "name": "Stock Price", "type": "Number", "displayed": true }, { "name": "Market Capitalization", "type": "Number", "displayed": true }, { "name": "Price to Earnings", "type": "Number", "displayed": true } ], "fallback": true, "language": "english", "nameColumn": "Company Name", "languageCode": "en", "noStocksFound": "No stocks found that match the criteria or I was unable to understand the request correctly", "stockFileName": "$ISIN$-factsheet.pdf", "tableFileName": "demo_stocks.csv" } ] }, "isExternal": false, "toolDefinition": { "type": "function", "function": { "name": "InvestmentResearchDocuments", "parameters": { "type": "object", "properties": { "instruction": { "type": "string", "description": "The question to be answered based on the information in the stock factsheets, e.g., 'List rationals as bullet points'" } } }, "description": "Specializes in offering detailed, document-based analysis on individual stocks. Delivers in-depth information like investment rationales, company profiles, and market analysis. Refers to a single stock or a list or table of stocks like 'above stocks', 'from the list' or 'stocks we discussed'. Example use case: 'Give me the investment rationale for Alphabet.', 'what are the key points?', 'what are the P/E ratios for these stocks?'" } } } ] }
Author |
---|