Academy
Updated on
Sep 4, 2025

How to build an AI Wealth Management Advisor

Build an AI Wealth Management Advisor using Qdrant, Gemini API, and LLMs. Enable users to query stocks, investments, and live market data with natural, human-like financial insights.

How to build an AI Wealth Management Advisor
Ready to ship your own agentic-AI solution in 30 days? Book a free strategy call now.

The AI Wealth Management Advisor is essentially a personal financial assistant powered by artificial intelligence. Its main purpose is to let users ask natural questions about stocks, investments, and finance, and then return answers that feel like they came from a real advisor. The system works by combining two worlds: a local knowledge base of stock data stored in Qdrant, and real-time market data fetched from the Gemini API.

When a user types a query such as “What is the PE ratio of Infosys?”, the query first goes through an LLM, which acts as the brain of the system. This LLM understands what the user is asking, extracts key details like the company name or stock symbol, and then decides where the answer should come from. If the information is already available in the preloaded dataset stored in Qdrant, the system retrieves and returns it. If the data isn’t available locally, or if it requires live updates such as the latest stock price, the system instead queries the Gemini finance API to fetch the latest figures.

Once the data is found, the LLM formats it into a clear, human-readable response, so instead of just showing raw numbers, the system provides a well-explained summary that sounds like financial advice. All of this is exposed to the user through a simple chat interface built with React, while the backend logic and orchestration happen through FastAPI.

In essence, this project behaves like an AI-powered wealth manager. It blends static knowledge with live financial insights, uses smart reasoning to figure out the best source of truth, and delivers answers in plain English, making finance and stock analysis more accessible to everyday users.




Step 1: User sends a natural language query

The entry point is simply asking the user for input.

# Ask user
user_query = input("Enter your query: ")

Here the system waits for the user’s natural language question, like “What is the PE ratio of Infosys?”




Step 2: Parsing the query

The system must interpret what the user actually means before deciding where to fetch the data.

parsed_query = parse_query(user_query)
stocks = parsed_query["stocks_mentioned"]
date_range = parsed_query["date_range"]
routing = parsed_query["if_vector_or_live"]
print(f"\nParsed Query: {parsed_query}")

This calls parse_query() from llm.py.
Inside that, the LLM extracts structured details:

  • Which stocks are mentioned

  • If there’s a time frame

  • Whether to use vector search or live data

So here the raw natural text is translated into structured instructions.




Step 3: Routing decision

Now the system decides: Should I look in the dataset or fetch live info?

if routing == "live":
    print("\n> Fetching live data...\n")
    print(get_finance_response(user_query))

 If the parsed result says "if_vector_or_live": "live", then the query is directly routed to live data retrieval.
This is where get_finance_response() in llm.py fetches the latest data and formats it into a natural response.




Step 4: Vector search in Qdrant

If the system decides to use the stored dataset, the query gets embedded and searched in Qdrant.

else:
    # Vector search
    query_vector = model.encode(user_query).tolist()
    query_filter = None
    if date_range != "none":
        query_filter = {"must": [{"key": "date", "match": {"value": date_range}}]}

    query_points = client.query_points(
        collection_name="stock",
        query=query_vector,
        limit=5,
        with_payload=True,
        query_filter=query_filter
    )

👉 What happens here:

  • The natural query is converted into an embedding using SentenceTransformer.

  • That embedding is sent to Qdrant, which searches the stock dataset for the closest match.

  • If a date range was parsed, it’s applied as a filter.




Step 5: Best match selection

After Qdrant returns results, the code picks the best-scoring one.

best_response = None
    best_score = float('-inf')
    for point in query_points.points:
        score = point.score
        payload = point.payload
        if score > best_score:
            best_score = score
            best_response = payload

 Here the system looks at all matches, compares similarity scores, and keeps only the best candidate result.




Step 6: Relevance check

Sometimes even the best match isn’t good enough.
So the system asks again: “Does this result actually answer the query?”

if not best_response or not is_relevant(user_query, best_response):
        print("\n> No good match in database. Fetching live data...\n")
        print(get_finance_response(user_query))

 If the match is weak or irrelevant, the system falls back to live data retrieval.




Step 7: Final response from the dataset

If the match is good, the system generates a natural language answer from the stored payload.


   else:
        print("\n> Found in database:\n")
        print(get_response(best_response))
        print(f"\n(Qdrant match score: {best_score:.2f})")

This uses get_response() from llm.py to take the raw stock payload and turn it into a nicely formatted text for the user.
It also shows the match score so you know how close the result was.

 End-to-end flow:

  1. User asks in plain English

  2. Query is parsed → structured into stocks, date, routing decision

  3. If “live” → go fetch fresh data

  4. If “vector” → embed and search Qdrant

  5. Pick the best result

  6. Check if relevant, else fallback to live

  7. Format and show final response

The  work flow:

 

https://github.com/piyushghughu-superteams-dotcom/Ai_chat_assistance_of_stock_market_qdrantDB/tree/main

Authors

We use cookies to ensure the best experience on our website. Learn more