rfq-rag

A demo to share intuition for how RAG and LLM can be used to automate finance tasks that require written comprehension


Project maintained by parrisma Hosted on GitHub Pages — Theme by mattgraham

Overview

Click here for Demo project repository & full code.

NOTES

Table of Contents

  1. Design Overview
  2. Problem Statement
  3. Application of RAG
  4. Full Prompt with examples
  5. Request & Response example
  6. Demo Operation
    1. Creating Example RFQs
    2. Retrieve Relevant Examples
    3. The full Flow

Problem Statement

Objective:

Key Results:


Application of RAG

  1. Create Examples Select a cross section of relevant data to act as examples in prompt.
  2. Receive RFQ to automate
  3. Retrieve Relevant Examples: Gather examples related to the current RFQ automation.
  4. Augment the Prompt: Add examples directly in the prompt to automate RFQ response.
  5. Prioritize the Examples: LLM responds with given examples as a source of truth.
  6. Reply to Client: Process RFQ of if LLM response ambiguous, seek client clarification

Creating Example RFQs

We need to create a varied set of RFQ examples, covering different clients, languages, and products, and manually verify the pricing for each, given a request and response we can save for later use.

Creation of Examples

The demo project creates totally fictional requests for quotes for two financial products. These RFQ,s, by design, are colloquial, with typo’s and abbreviations and are in three languages, examples below

> Veuillez tarifer cette eln. Coupon 3 pct fix, Action RSH.T,  40 pct, Taille USD $40000, Terme 2 ans, Fréq Cpn annuel, Part 70 pct. Veuillez répondre quand vous le pouvez. David

> Necesito un precio para esta autocall RFQ, gracias. Monto USD $50000, Sub EDA.US, Venc 3 años, Cupón an, frecuencia auto trim, barr auto 100 porcentaje,  60 pct,  15 pct. Saludos, avísame. Alejandro

> Need a price on dis eln RFQ, thx.  40 percent, Cpn 2 % fixed, Under TPH.SW, Notional USD $5000,  quarterly, Participation 90 percent, Mat 2 yrs. Thank you in advance for your prompt response. Grace

For each example we also remember the exact details, such that we can save and use the text and the expected result as examples to give to the model. Ultimately it is these details we need to automated the pricing reply to the client. e.g.

"parameters": {
    "underlying": "TGF.PA",
    "maturity": "1 years",
    "barrier": "60 percent",
    "coupon_frequency": "annually",
    "coupon": "10 percent",
    "autocall_frequency": "annual",
    "autocall_barrier": "102 percent",
    "notional": "USD $10000",
    "from": "Ben Davis",
    "language": "en"
}

Retrieve Relevant Examples

Explanation

A big part of RAG is being able to find examples to add to the prompt that are similar in meaning, in our case similar quotes.

To solve this, we use embeddings and vector databases. Embeddings turn quotes into sets of numbers that capture their meaning. Think of it as creating a map where quotes with similar meanings are placed closer together.

Vector databases store these number-maps along with the original quotes. So when you ask for quotes with similar meaning, the database finds the number-maps that are closest to your example, and then gives you the corresponding quotes.

So, it allows computers to understand the “gist” of the quotes and find related ones based on their meaning, not just their words.

Example

if we get the RFQ

¿Podría cotizar este instrumento autocall?  1 años, Subyac CIF.T,  semestralmente,  semestralmente, Barrera 60 pct,  12 porcentaje,  105 %, Nominal USD $20000. Por favor avisa cuando tengas precios disponibles. Enrique Martínez

We need five similar examples, with the expected parameters (as JSON) to embed in the prompt. So we ask the vector DB (Chroma) to search for similar examples we saved earlier.

As we can see below it has found examples in spanish (even though the database has english and spanish also), they are also for the same financial product.

The Dist number is the measure of how far they are away in meaning terms from the given rfq.

> Dist: [7661.57], Doc: Oye, cotiza esta autocall. barr auto 105 porcentaje, Nominal USD $10000, frec llamada semestralmente, Subyacente LZL.US, Plazo 1 años,  12 %, Barrera 50 %, Cupón semi. Por favor, házmelo saber cuando tengas el precio. Francisco Martínez

> Dist: [9708.86], Doc: Estoy buscando una cotización rápida para esta autocall. Barrera 50 %, frec auto anual,  anual, Venc 2 años,  15 porcentaje, Subyac YSR.MX, Nominal USD $40000, barrera auto 100 %. Gracias, avísame pronto. Francisco Martínez

> Dist: [14481.69], Doc: Oye, ¿alguna idea de precio para esta autocall RFQ? Cantidad USD $45000, Barrera 50 %, barr auto 102 pct,  15 %, Expiración 2 años, frecuencia auto anualmente, Cupón anualmente,  CDM.HK. Avísame tus pensamientos. Alejandro Ruiz

> Dist: [18032.08], Doc: Necesitamos un precio para esta autocall. frecuencia de autocall anual, Plazo 5 años,  anual, Acción LZL.US,  70 pct, barrera de autocall 102 porcentaje, Cantidad USD $20000,  10 porcentaje. Por favor avisa cuando tengas un precio. Ivonne Williams

> Dist: [18782.44], Doc: ¿Alguna posibilidad de conseguir una cotización para esta nota autocall?  8 porcentaje,  102 %, Cup anualmente, frec anualmente, Ticker LVL.PA,  USD $40000, Barrera 50 %, Expiración 5 años. Avísame cuando lo tengas. Jacobo

Resulting Prompt

Here is a full example of an RFQ prompt with examples. The added examples are in red and the prompt being parsed is shown in blue.

This prompt was formed using langchain library, which takes a simple text template and allows values to be embedded.

The rfq prompt above is all totally imaginary data, but if you cut and paste the whole prompt into any web based LLM such as Gemini, you will see that it can parse the rfq and will give output as below. This is exactly what we do in the demo, except the LLM we call is one running locally (privately) on our computer.

Here is a real json response from running the demo prompt

[
    {
        "product": "eln",
        "underlying": "TER.L",
        "maturity": "12 years",
        "participation": "80 percent",
        "barrier": "50 percent",
        "coupon": "2 percent",
        "coupon_type": "fixed",
        "coupon_frequency": "quarterly",
        "notional": "USD $35000",
        "from": "Ali",
        "confidence": "100%",
        "explanation": "Extracted all parameters based on the patterns observed in the provided examples. The term 'qtr' is interpreted as 'quarterly', and 'Und' is interpreted as 'underlying'. 'Mat' is interpreted as maturity. The coupon is indicated as '2 % fixed' which is parsed as coupon of 2 percent and coupon type of fixed.",
        "advice": "ok to quote"
    }
]

e.g. a simplified example of a prompt template

# A very simplified RFQ template
template = PromptTemplate.from_template(
    """
    Please quote this RFQ {rfq-text}
    with respect to these example rfq's and associated results
    {example-1} = {example-1-params-json}
    {example-2} = {example-2-params-json}
    response as valid json of format
    "{'cpn'='?','maturity'='?','strike'='?'}"
    """
)

# Inject the configurable details
prompt = template.format(
    rfq-text="Please quote this eln with terms a, b, c... ",
    example-1="Please quote this eln with terms d, e, f... ",
    example-1-params-json="{'cpn'='d','maturity'='e','strike'='f'}",
    example-2="Please quote this eln with terms g, h, i ... ",
    example-2-params-json="{'cpn'='g','maturity'='h','strike'='i'}",
)

The full Flow

The full workflow is shown below.

Creation of Examples

  1. RFQ From Client
    • free test in any of three languages for two product types
  2. Get similar examples to client RFQ
    • Use embeddings & vector DB to get semantically similar quotes
  3. Create the prompt with RFQ & examples
    • Supply examples to prompt to give LLM specialist knowledge
  4. Ask LLM to extract parameters & explanation
    • The explanation helps with the AI explainability problem if the result is questioned by client in the future
  5. If all OK price the product
    • If extract is confident, we can auto price
  6. Pass price or error report to trader
    • The price will be sent back, normally via person for sanity checks
    • Trader can also look a clarification commentary from model
  7. Pass price or request for clarification with client

A real demo example

The RFQ request

J'ai besoin d'un prix pour la eln suivante. Cpn 6 pourcentage fix,  USD $40000,  90 %, Terme 18 ans, Fréq Cpn annuellement, Barrière 60 pourcentage, Sous-jac FAF.MX. Merci, j'apprécie votre assistance. François Martin

The LLM generated explanation, goes some way to address explainability

The RFQ explicitly mentions eln in the context of a structured equity derivative product. The terms provided, such as coupon (Cpn), barrier level, and underlying asset (Sous-jac FAF.MX), are consistent with an ELN (Equity Linked Note) structure. However, there is some ambiguity regarding the term Terme 18 ans which could be interpreted as a very long maturity period for an ELN, which is unusual but not impossible

The LLM generated advice, trust extract or ask for clarification

Dear François Martin, thank you for your request. Could you please clarify if the 18-year term is correct and intended for this ELN? Additionally, could you confirm the barrier level of 60% and how it applies to the structure? This will help ensure we provide an accurate quote. Best regards.