{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3fd3d3a8",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "97330215",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.llms.openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "dc086cc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core import (\n",
    "    StorageContext,\n",
    "    VectorStoreIndex,\n",
    "    SimpleDirectoryReader,\n",
    "    load_index_from_storage,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "93549f19",
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core.tools import QueryEngineTool, ToolMetadata\n",
    "from llama_index.core.query_engine import SubQuestionQueryEngine\n",
    "from dotenv import load_dotenv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "15d43e1f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca35fe7d",
   "metadata": {},
   "source": [
    "### Configure the language model and load the document"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd2c5bd0",
   "metadata": {},
   "source": [
    "First, we configure the language model with specific parameters and load the document."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "30c58e66",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = OpenAI(temperature=0, model_name=\"gpt-4o\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d92fcf7f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded NVDA 10-K with 80 pages\n"
     ]
    }
   ],
   "source": [
    "doc = SimpleDirectoryReader(input_files=[\"nvda.pdf\"]).load_data()\n",
    "print(f\"Loaded NVDA 10-K with {len(doc)} pages\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7615156",
   "metadata": {},
   "source": [
    "We set the language model to use the GPT-4 model with a temperature of 0 for deterministic responses. The model is configured to use an unlimited number of tokens. We then load the NVDA 10-K document from a PDF file and print the number of pages loaded."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2c67a6e",
   "metadata": {},
   "source": [
    "### Create an index to enable querying of the document"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba9502c6",
   "metadata": {},
   "source": [
    "Next, we create an index from the loaded document to facilitate efficient querying."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "22eff79d",
   "metadata": {},
   "outputs": [],
   "source": [
    "index = VectorStoreIndex.from_documents(doc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4651c1a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "engine = index.as_query_engine(similarity_top_k=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77f2ee27",
   "metadata": {},
   "source": [
    "We create a VectorStoreIndex from the loaded document, which enables us to perform similarity searches. We then set up a query engine with a similarity search parameter to return the top 3 most relevant results for each query."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d36f8d48",
   "metadata": {},
   "source": [
    "### Query specific financial information from the document"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fefd8e4",
   "metadata": {},
   "source": [
    "Now, we can use the query engine to extract specific financial information from the document."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a0ff7054",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The revenue of NVIDIA in the last period reported was $30,040 million for the three months ended July 28, 2024, as shown on page 3 of the document.\n"
     ]
    }
   ],
   "source": [
    "response = await engine.aquery(\"What is the revenue of NVDIA in the last period reported? Answer in millions with page reference. Include the period.\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4c70926e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "NVIDIA's fiscal period begins on the last Sunday in January.\n"
     ]
    }
   ],
   "source": [
    "response = await engine.aquery(\"What is the beginning and end date of NVIDA's fiscal period?\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "625a2cd7",
   "metadata": {},
   "source": [
    "We use the query engine to asynchronously ask questions about NVIDIA's financial report. The first query asks for the revenue in the last reported period, including the page reference. The second query asks for the beginning and end dates of NVIDIA's fiscal period. The responses are printed to the console."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c589df9b",
   "metadata": {},
   "source": [
    "### Set up a tool for sub-question querying"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b5b7372",
   "metadata": {},
   "source": [
    "We will now set up a tool to handle more complex queries by breaking them down into sub-questions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c880739e",
   "metadata": {},
   "outputs": [],
   "source": [
    "query_engine_tool = [\n",
    "    QueryEngineTool(\n",
    "        query_engine=engine,\n",
    "        metadata=ToolMetadata(name='nvda_10k', description='Provides information about NVDA financials for year 2024')\n",
    "    )\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "99229480",
   "metadata": {},
   "outputs": [],
   "source": [
    "s_engine = SubQuestionQueryEngine.from_defaults(query_engine_tools=query_engine_tool)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3f0d7e2",
   "metadata": {},
   "source": [
    "We create a list of QueryEngineTool objects with metadata describing the tool's function. We then initialize a SubQuestionQueryEngine with the list of tools. This engine can break down complex queries into smaller, more manageable sub-questions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5a0e20f5",
   "metadata": {},
   "source": [
    "### Perform complex queries on customer segments and risks"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "268e67df",
   "metadata": {},
   "source": [
    "Finally, we perform more complex queries on the document to extract detailed information about customer segments and business risks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "194b22a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generated 2 sub questions.\n",
      "\u001b[1;3;38;2;237;90;200m[nvda_10k] Q: What are the customer segments that grew the fastest in terms of revenue in 2024?\n",
      "\u001b[0m\u001b[1;3;38;2;90;149;237m[nvda_10k] Q: Which geographies showed the highest growth in revenue for NVDA in 2024?\n",
      "\u001b[0m\u001b[1;3;38;2;237;90;200m[nvda_10k] A: Networking revenue grew the fastest in terms of revenue in 2024.\n",
      "\u001b[0m\u001b[1;3;38;2;90;149;237m[nvda_10k] A: Data Center revenue showed the highest growth in revenue for NVDA in 2024.\n",
      "\u001b[0mNetworking revenue grew the fastest in terms of revenue in 2024, while Data Center revenue showed the highest growth in revenue for NVDA in the same year.\n"
     ]
    }
   ],
   "source": [
    "response = await s_engine.aquery(\"Compare and contrast the customer segments and geographies that grew the fastest\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "56bc8833",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generated 1 sub questions.\n",
      "\u001b[1;3;38;2;237;90;200m[nvda_10k] Q: What risks are highlighted in NVDA's 10-K document for the year 2024?\n",
      "\u001b[0m\u001b[1;3;38;2;237;90;200m[nvda_10k] A: Long manufacturing lead times, uncertain supply and component availability, failure to estimate customer demand accurately, mismatches between supply and demand, product shortages, excess inventory, and the impact of changes in product development cycles, competing technologies, business and economic conditions, government lockdowns, technology advancements, and other factors on revenue and supply levels.\n",
      "\u001b[0mThe risks highlighted in the document for NVIDIA's business include long manufacturing lead times, uncertain supply and component availability, failure to estimate customer demand accurately, mismatches between supply and demand, product shortages, excess inventory, and the impact of changes in product development cycles, competing technologies, business and economic conditions, government lockdowns, technology advancements, and other factors on revenue and supply levels.\n"
     ]
    }
   ],
   "source": [
    "response = await s_engine.aquery(\"What risks to NVDIA's business are highlighted in the document?\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "2c0c2b4e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generated 2 sub questions.\n",
      "\u001b[1;3;38;2;237;90;200m[nvda_10k] Q: What are the key risks highlighted in the NVDA 10K document?\n",
      "\u001b[0m\u001b[1;3;38;2;90;149;237m[nvda_10k] Q: How does NVDA plan to mitigate the risks mentioned in the 10K document?\n",
      "\u001b[0m\u001b[1;3;38;2;237;90;200m[nvda_10k] A: The key risks highlighted in the NVDA 10K document include potential challenges related to manufacturing lead times, uncertain supply and component availability, inaccurate estimation of customer demand leading to mismatches between supply and demand, product shortages or excess inventory, inability to secure sufficient commitments for capacity, impeded ability to sell products if necessary components are unavailable, extended lead times on orders, increased product costs due to securing future supply, and the impact of various factors on underestimating or overestimating customer demand.\n",
      "\u001b[0m\u001b[1;3;38;2;90;149;237m[nvda_10k] A: NVDA plans to mitigate the risks mentioned in the 10K document by increasing supply and capacity purchases with existing and new suppliers to support their demand projections. Additionally, they aim to accurately estimate customer demand to avoid mismatches between supply and demand, which have previously harmed their financial results. They may enter into long-term supply agreements and capacity commitments to address their business needs and secure sufficient commitments for capacity. Furthermore, they acknowledge the potential impact of factors such as changes in product development cycles, competitor actions, economic conditions, and technology advancements on their revenue and strive to manage these uncertainties effectively.\n",
      "\u001b[0mNVDIA sees the risks highlighted in the document impacting financial performance through potential challenges related to manufacturing lead times, uncertain supply and component availability, inaccurate estimation of customer demand leading to mismatches between supply and demand, product shortages or excess inventory, inability to secure sufficient commitments for capacity, impeded ability to sell products if necessary components are unavailable, extended lead times on orders, increased product costs due to securing future supply, and the impact of various factors on underestimating or overestimating customer demand. These risks could lead to financial implications such as decreased revenue, increased costs, reduced profitability, and potential negative effects on overall financial results.\n"
     ]
    }
   ],
   "source": [
    "response = await s_engine.aquery(\"How does NVDIA see the risks highlighted in the document impacting financial performance?\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1ac62ee",
   "metadata": {},
   "source": [
    "We use the sub-question query engine to ask complex questions about NVIDIA's customer segments and geographies and the business risks highlighted in the document. The engine breaks these questions into smaller sub-questions, processes them, and compiles the responses. Each response is then printed to the console."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b47d32f0",
   "metadata": {},
   "source": [
    "<a href=\"https://pyquantnews.com/\">PyQuant News</a> is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to <a href=\"https://gettingstartedwithpythonforquantfinance.com/\">get started with Python for quant finance</a>. For educational purposes. Not investment advise. Use at your own risk."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6d8773b-4b58-43c0-829c-c56fd603703d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
