How to Use ChatGPT-5.5 for Financial Modeling: Revenue Forecasting, Scenario Analysis, and Investment Memo Generation





End-to-End Tutorial: Using ChatGPT-5.5 for Financial Modeling (Revenue Forecasting, Scenario Analysis, DCF, Sensitivity Tables, and Investment Memos)


Using ChatGPT-5.5 for Financial Modeling: A Complete Guide

Build robust revenue forecasts, run bull/bear/base scenarios, generate institutional-grade investment memos, get DCF assistance, and automate sensitivity tables—augmented by ChatGPT-5.5.

How to Use ChatGPT-5.5 for Financial Modeling: Revenue Forecasting, Scenario Analysis, and Investment Memo Generation

Table of Contents

  1. Introduction and Key Concepts
  2. Setup and API Integration
  3. Prompt Design for Finance Use Cases
  4. Revenue Forecasting with ChatGPT-5.5
  5. Scenario Analysis: Bull, Base, and Bear
  6. Investment Memo Generation
  7. DCF Assistance: WACC, FCF, and Terminal Value
  8. Sensitivity Tables and What-If Analysis
  9. Building an End-to-End Modeling Pipeline
  10. Validation, Guardrails, and Auditability
  11. Exporting to Excel, CSV, and Sheets
  12. FAQ and Troubleshooting
  13. Next Steps

Introduction and Key Concepts

Financial modeling practitioners face three recurring challenges: speed, structure, and story. Speed is about producing reliable drafts fast; structure is about maintaining coherent logic across assumptions, calculations, and outputs; and story is the narrative that convinces decision-makers. ChatGPT-5.5 can help at each layer—summarizing input data, proposing initial assumptions, writing formulas and code, explaining methodologies, and drafting decision-ready narratives.

This tutorial is a hands-on, end-to-end guide to using ChatGPT-5.5 throughout your modeling workflow. We will apply it to revenue forecasting, scenario analysis (bull/base/bear), investment memo generation, DCF assistance, and sensitivity analysis. You will also learn how to integrate via API, request structured outputs (JSON), and export to Excel or Google Sheets.

Note: Replace the model identifier shown in code samples with the model ID available in your environment. If your provider exposes ChatGPT-5.5 under a different name, update the model parameter accordingly.

What You Will Build

  • A modular forecasting workbook (or Python notebook) where ChatGPT-5.5 assists with assumptions, formulas, and commentary.
  • Bull/base/bear scenario engine with assumptions tables your stakeholders can edit.
  • An automated pipeline to generate an investment memo from the model outputs.
  • A DCF calculator with ChatGPT-5.5 support for WACC, FCF, and terminal value reasoning.
  • One-way and two-way sensitivity tables that show what matters most.

When to Use ChatGPT-5.5 in Finance

  • Rapid prototyping of models and narratives.
  • Transforming unstructured data (customer interviews, 10-Ks, transcripts) into model-ready inputs.
  • Cross-checking formulas, documenting logic, and explaining complex steps to non-finance stakeholders.
  • Generating scenario assumptions based on industry heuristics.
Important: Always validate outputs. Treat LLM-generated numbers as a starting point, not final truth. For material decisions, verify assumptions, calculations, and sources.

Related:

For teams exploring related capabilities, our comprehensive guide on 25 ChatGPT-5.5 Prompts for DevOps Engineers provides detailed workflows and implementation strategies for prompts for CI/CD pipelines and infrastructure as code. The techniques covered there complement the approaches discussed in this article and offer additional depth for practitioners ready to expand their AI toolkit.

Setup and API Integration

In this section, you will connect to the API, send prompts, request structured data, and build small utilities you can reuse in the rest of the tutorial. We provide examples in Python, Node.js, and cURL.

Prerequisites

  • API key and access to a model compatible with ChatGPT-5.5 style prompts and JSON outputs.
  • Python 3.10+ or Node.js 18+ (if building scripts).
  • Basic familiarity with HTTP requests, JSON, and parsing.

Environment Variables

Store credentials securely via environment variables to avoid committing secrets to source control.

# macOS/Linux
export OPENAI_API_KEY="YOUR_API_KEY"

# Windows PowerShell
setx OPENAI_API_KEY "YOUR_API_KEY"

Python Quickstart

import os
import json
import requests

API_KEY = os.getenv("OPENAI_API_KEY")
API_BASE = "https://api.openai.com/v1"  # Update if your provider differs
MODEL_ID = "chatgpt-5.5"  # Replace with the actual model ID you have access to

def chat_completion(messages, response_format=None, temperature=0.2):
    url = f"{API_BASE}/chat/completions"
    headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
    payload = {
        "model": MODEL_ID,
        "messages": messages,
        "temperature": temperature
    }
    if response_format:
        # Some APIs support a "response_format" or "json_schema" parameter
        payload["response_format"] = response_format
    resp = requests.post(url, headers=headers, data=json.dumps(payload), timeout=120)
    resp.raise_for_status()
    data = resp.json()
    # Adjust parsing depending on your API response shape
    return data["choices"][0]["message"]["content"]

if __name__ == "__main__":
    system = {"role": "system", "content": "You are an expert financial modeling assistant."}
    user = {"role": "user", "content": "List the main components of a DCF model."}
    print(chat_completion([system, user]))

Node.js Quickstart

import fetch from "node-fetch";

const API_KEY = process.env.OPENAI_API_KEY;
const API_BASE = "https://api.openai.com/v1";  // Update if required
const MODEL_ID = "chatgpt-5.5";               // Replace with actual model name

async function chatCompletion(messages, { temperature = 0.2, response_format = null } = {}) {
  const body = {
    model: MODEL_ID,
    messages,
    temperature
  };
  if (response_format) body.response_format = response_format;

  const res = await fetch(`${API_BASE}/chat/completions`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(body)
  });
  if (!res.ok) {
    const errText = await res.text();
    throw new Error(`API error: ${res.status} - ${errText}`);
  }
  const data = await res.json();
  return data.choices[0].message.content;
}

(async () => {
  const system = { role: "system", content: "You are an expert financial modeling assistant." };
  const user = { role: "user", content: "What are typical revenue drivers for a SaaS business?" };
  const answer = await chatCompletion([system, user]);
  console.log(answer);
})();

cURL Example

curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "chatgpt-5.5",
    "messages": [
      {"role": "system", "content": "You are an expert financial modeling assistant."},
      {"role": "user", "content": "Explain terminal value in a DCF."}
    ],
    "temperature": 0.2
  }'

Requesting Structured Outputs (JSON)

For spreadsheets and code, structured outputs are invaluable. Ask for JSON and validate it before use.

# Python example requesting a JSON-like response
schema_instruction = {
    "role": "system",
    "content": (
        "Return a valid JSON object only. Keys: 'assumptions', 'notes'. "
        "assumptions is a list of {'name': str, 'value': number, 'unit': str}."
    )
}
user_prompt = {"role": "user", "content": "Propose base-case SaaS assumptions: MRR, churn %, CAC, ARPU."}
json_text = chat_completion([schema_instruction, user_prompt])
data = json.loads(json_text)  # ensure try/except around this in production
print(data)
Tip: If the API supports JSON schema or function/tool calling, define strict types for higher reliability, and fallback to robust parsing with validation.

See also:

Organizations implementing these workflows will also benefit from understanding The Codex Task Decomposition Playbook, which covers breaking complex projects into agent-ready subtasks in detail. The methodologies presented there provide a natural extension of the concepts explored above, particularly for teams scaling their AI-assisted processes.

Prompt Design for Finance Use Cases

Good prompts reduce noise and rework. For quantitative tasks, be explicit about:

  • Role and scope (e.g., “You are a buy-side analyst covering mid-cap SaaS”).
  • Outputs and format (JSON keys; table columns; units; rounding rules).
  • Assumption constraints (ranges, industry norms, time horizons).
  • Data lineage (cite dataset names or cells; reference where each number came from).

Reusable Prompt Template

Role: You are an expert financial modeling assistant.
Task: Given the inputs below, produce [OUTPUT_FORMAT] with [UNITS]. 
Constraints:
- Use [TIME_HORIZON] with [GRANULARITY].
- Respect ranges: [RANGE_TABLE_SUMMARY].
- Reference data lineages (sheet:cell or source note).
- Return only valid JSON with keys: [KEYS].

Inputs:
[PASTE_DATA_OR_LINKS]

Check:
- Are units and totals consistent?
- Are assumptions justified (1-2 bullets each)?

Example: Formula Debugging Prompt

System: You are a meticulous Excel and Python formula reviewer.
User: Here is an Excel formula and my intent. Identify errors and propose a corrected version.
Intent: "Compute monthly churned customers = prior_month_customers * churn_rate"
Formula: "=B10*C5" 
Context: B10 is "current month customers", C5 is "monthly churn rate".
Return JSON: {"issues":[...], "fix":"...", "explanation":"..."}

Revenue Forecasting with ChatGPT-5.5

Revenue forecasting converts growth drivers and unit economics into a time-series of bookings, billings, and recognized revenue. ChatGPT-5.5 can help you structure drivers, write equations, draft code, and narrate results.

How to Use ChatGPT-5.5 for Financial Modeling: Revenue Forecasting, Scenario Analysis, and Investment Memo Generation - Section 1

Step 1: Define Your Revenue Drivers

Start by enumerating drivers under a clear taxonomy. For a SaaS business, you might include acquisition, conversion, churn, expansion, pricing, and cohorts. For a marketplace, consider GMV growth, take rate, buyer/seller growth, and repeat purchase rates.

Driver Description Unit Typical Range
New leads Top-of-funnel inquiries per month Count 500–50,000
Lead-to-trial conversion Leads that start a trial % 5–30%
Trial-to-paid conversion Trials converting to paying customers % 10–40%
ARPU Average revenue per user per month $ $20–$400
Gross churn Customers canceling each month %/mo 0.6–4.0%
Net expansion Upsell/cross-sell net of downgrades %/mo 0–2.5%

Step 2: Ask ChatGPT-5.5 to Propose Base-Case Assumptions

# Python: get a JSON of base-case assumptions
messages = [
  {"role":"system","content":"Return valid JSON only with keys: assumptions (list), notes (string)."},
  {"role":"user","content":(
    "Propose base-case SaaS revenue drivers for a B2B product with $100 ARPU, 5,000 MRR customers. "
    "Horizon: 36 months. Give: new_leads, lead_to_trial_pct, trial_to_paid_pct, monthly_gross_churn_pct, net_expansion_pct, price_increase_pct_annual. "
    "Include ranges and justifications in notes."
  )}
]
assumptions_json = chat_completion(messages)
assumptions = json.loads(assumptions_json)
Use the model’s notes to inform a management review. Keep the model inputs easy to edit in a separate “Assumptions” sheet or YAML/JSON file.

Step 3: Translate Assumptions into a Cohort-Based Forecast

Cohort modeling distinguishes customers by acquisition month and tracks each cohort’s retention and expansion profile. This captures the natural lag between acquisition and churn and better reflects reality than a single aggregated churn rate.

Cohort Flow Equations

  • Cohort size (m) = new paid customers acquired in month m.
  • Retained customers in month t for cohort m = Cohort(m) × Π(1 − churn_rate_k) for k from m to t−1.
  • ARPU growth over time = base_ARPU × Π(1 + net_expansion_rate_k).
  • Monthly revenue (t) = Σ over all cohorts m≤t of Retained(m→t) × ARPU(t).

Python Implementation

import numpy as np
import pandas as pd

def monthly_churn_series(base_churn_pct, months, trend=0.0):
    # e.g., trend = -0.02 means churn improves by 2% per year, monthly compounded
    mtrend = (1 + trend) ** (1/12) - 1
    churn = np.array([base_churn_pct * ((1 + mtrend) ** i) for i in range(months)])
    return np.clip(churn, 0, 1)

def monthly_expansion_series(net_expansion_pct, months):
    # Net expansion applied multiplicatively to ARPU
    return np.array([net_expansion_pct for _ in range(months)])

def simulate_cohorts(months=36, start_customers=5000, arpu=100.0,
                     new_leads=4000, lead_to_trial=0.20, trial_to_paid=0.25,
                     base_churn_pct=0.015, net_expansion_pct=0.01):
    # Derive monthly new paid customers
    new_paid = int(new_leads * lead_to_trial * trial_to_paid)  # simple constant case
    churn = monthly_churn_series(base_churn_pct, months)
    expansion = monthly_expansion_series(net_expansion_pct, months)

    # Cohorts: number acquired each month (constant for simplicity; replace with growth vector)
    cohort_sizes = np.array([new_paid for _ in range(months)])
    # Add initial customers as a special cohort at t=0
    initial = start_customers

    # Retention per cohort per month
    retention_factors = np.ones((months, months))
    for m in range(months):
        # For cohort m, retention from m to t is product of (1 - churn_k)
        running = 1.0
        for t in range(m, months):
            if t > m:
                running *= (1 - churn[t-1])
            retention_factors[m, t] = running

    # ARPU path with expansion
    arpu_path = np.zeros(months)
    running_arpu = arpu
    for t in range(months):
        if t > 0:
            running_arpu *= (1 + expansion[t])
        arpu_path[t] = running_arpu

    customers = np.zeros(months)
    revenue = np.zeros(months)

    for t in range(months):
        # Initial cohort contribution
        init_retained = initial
        for k in range(t):
            init_retained *= (1 - churn[k])
        # New cohorts up to t
        cohort_retained = 0
        for m in range(t+1):
            cohort_retained += cohort_sizes[m] * retention_factors[m, t]
        customers[t] = init_retained + cohort_retained
        revenue[t] = customers[t] * arpu_path[t]

    df = pd.DataFrame({
        "month": np.arange(1, months+1),
        "customers": customers.astype(int),
        "arpu": np.round(arpu_path, 2),
        "revenue": np.round(revenue, 2)
    })
    return df

df = simulate_cohorts()
print(df.head())

Step 4: Use ChatGPT-5.5 to Explain, Audit, and Improve

Feed the code and summary outputs to ChatGPT-5.5 to request audits and alternatives:

messages = [
  {"role":"system","content":"You are a meticulous quant reviewer. Be concise and specific."},
  {"role":"user","content":(
    "Review this Python code for a cohort-based revenue forecast (below). "
    "Identify potential logic gaps, suggest more realistic acquisition growth vectors, and "
    "recommend how to separate bookings, billings, and revenue recognition if we move to annual contracts.\n\n"
    + open("forecast.py").read()
  )}
]
review = chat_completion(messages, temperature=0.1)
print(review)

Step 5: Generate a Clean, Importable Assumptions Table

# Request a CSV-formatted assumptions table
messages = [
  {"role":"system","content":"Return CSV only with headers: variable, value, unit, notes"},
  {"role":"user","content":"Create a clean assumptions table for the base case from the previous JSON output. Format values as decimals or integers; percent as 0.xx."}
]
csv_table = chat_completion(messages)
with open("assumptions_base.csv","w") as f:
    f.write(csv_table)
Best practice: Keep one source of truth (CSV/YAML/JSON). Load it into your model, and allow ChatGPT-5.5 to regenerate it whenever assumptions need re-baselining.

Scenario Analysis: Bull, Base, and Bear

Scenario analysis formalizes uncertainty by bracketing outcomes. Well-constructed bull/base/bear cases differ in both assumptions and narrative. ChatGPT-5.5 can help create these variations, document rationale, and surface the few variables that drive most of the variance.

How to Use ChatGPT-5.5 for Financial Modeling: Revenue Forecasting, Scenario Analysis, and Investment Memo Generation - Section 2

Step 1: Define the Scenario Knobs

In SaaS, this typically includes acquisition growth, conversion, pricing power, churn/retention, and net expansion. In capital-intensive industries, include utilization, capex ramp, and capacity constraints.

Variable Bear Base Bull Unit Notes
New leads MoM growth 0.5% 1.5% 3.0% %/mo Bull reflects strong marketing efficiency and virality.
Lead-to-trial 12% 18% 24% % Improves with better targeting and onboarding.
Trial-to-paid 15% 22% 32% % Influenced by pricing experiments and product-market fit.
Monthly gross churn 2.2% 1.5% 1.0% %/mo Bull assumes improved retention programs.
Net expansion 0.2% 0.8% 1.5% %/mo Upsell motion effectiveness.
ARPU (start) $90 $100 $110 $ Pricing power signals.

Step 2: Auto-Generate Scenario Sets with ChatGPT-5.5

# Python: prompt for three scenario JSONs in one response
messages = [
  {"role":"system","content":"Return valid JSON only with keys: bear, base, bull. Each is an object of {variable, value, unit, justification} array."},
  {"role":"user","content":(
    "Construct SaaS scenarios for 36 months. Variables: new_leads_mom_growth, lead_to_trial_pct, trial_to_paid_pct, gross_churn_pct, net_expansion_pct, arpu_start. "
    "Keep units consistent and add 1-2 sentence justification per variable referencing plausible industry rationale."
  )}
]
scenarios_json = chat_completion(messages)
scenarios = json.loads(scenarios_json)

Step 3: Run the Simulation for Each Scenario

def run_scenario(label, months, start_customers, arpu_start, new_leads_start,
                 new_leads_mom_growth, lead_to_trial, trial_to_paid,
                 gross_churn_pct, net_expansion_pct):
    df = simulate_cohorts(
        months=months,
        start_customers=start_customers,
        arpu=arpu_start,
        new_leads=new_leads_start,
        lead_to_trial=lead_to_trial,
        trial_to_paid=trial_to_paid,
        base_churn_pct=gross_churn_pct,
        net_expansion_pct=net_expansion_pct
    )
    # Apply leads growth over time by adjusting new cohorts if needed (simple example omitted for brevity)
    df["scenario"] = label
    return df

bear_df = run_scenario("bear", 36, 5000, 90, 3000, 0.005, 0.12, 0.15, 0.022, 0.002)
base_df = run_scenario("base", 36, 5000, 100, 3500, 0.015, 0.18, 0.22, 0.015, 0.008)
bull_df = run_scenario("bull", 36, 5000, 110, 4000, 0.030, 0.24, 0.32, 0.010, 0.015)

summary = pd.concat([bear_df, base_df, bull_df])
print(summary.groupby("scenario")["revenue"].tail(1))

Step 4: Narrative and Risks

Ask ChatGPT-5.5 to narrate what is driving the divergence among scenarios, and produce a risk/opportunity register.

messages = [
  {"role":"system","content":"You write crisp investment memos. Be analytical and cite drivers numerically."},
  {"role":"user","content":(
    "Given the attached scenario summaries (CSV below), explain key deltas in customers, ARPU, and revenue at 12, 24, 36 months. "
    "Highlight top 5 sensitivities (variable -> revenue delta). Then list 5 risks and 5 upside opportunities.\n\n"
    + summary.to_csv(index=False)
  )}
]
narrative = chat_completion(messages)
print(narrative)

Explore more:

For teams exploring related capabilities, our comprehensive guide on Codex Record and Replay provides detailed workflows and implementation strategies for OpenAI’s screen recording feature for workflow automation. The techniques covered there complement the approaches discussed in this article and offer additional depth for practitioners ready to expand their AI toolkit.

Investment Memo Generation

The best investment memos compress a lot of context into a persuasive, structured narrative. Use ChatGPT-5.5 to turn model outputs and qualitative insights into an LP-ready memo. You can also ask it to produce an executive summary slide outline and a one-page version.

Memo Outline Template

  • Executive Summary
  • Business Overview
  • Market and Competition
  • Product and Moat
  • Financial Overview (Revenue, Gross Margin, CAC/LTV, Burn)
  • Scenarios (Bull/Base/Bear) and Key Drivers
  • DCF/Valuation (Method, Assumptions, Results)
  • Risks and Mitigations
  • Recommendation
  • Appendix (Data Sources, Definitions, Model Notes)

Prompt the Memo with Model Outputs

# Python: generate an institutional-style memo as markdown or HTML
memo_messages = [
  {"role":"system","content":"You are a private equity associate producing institution-grade memos. Be concise, analytical, and use data."},
  {"role":"user","content":(
    "Write a 2,000-word memo using the outline below. Use the CSV outputs. "
    "Use tables for metrics, and a bullet-point style for risks and recommendation.\n\n"
    "Outline:\n"
    "1) Executive Summary\n2) Business Overview\n3) Market and Competition\n4) Product and Moat\n"
    "5) Financial Overview\n6) Scenarios and Drivers\n7) DCF/Valuation\n8) Risks\n9) Recommendation\n\n"
    "Data: Revenue forecasts by scenario (CSV):\n" + summary.to_csv(index=False)
  )}
]
memo_html = chat_completion(memo_messages)
with open("investment_memo.html","w") as f:
    f.write(memo_html)

Insert Charts and Source Notes

Ask ChatGPT-5.5 to output placeholders for charts (e.g., revenue by scenario, customer growth waterfall). Then you can programmatically inject actual images from your plotting library.

# Ask the model to include markers like: <div class="chart" id="rev_by_scenario"></div>
For diligence, require the model to provide footnotes mapping each number to its sheet and cell or to a raw data file. This dramatically improves auditability.

DCF Assistance: WACC, FCF, and Terminal Value

Discounted Cash Flow (DCF) valuation discounts expected future free cash flows (FCF) at a rate reflecting the risk (WACC). ChatGPT-5.5 can help with the mechanics and rationale—calculating WACC components, projecting FCF, and selecting a terminal value approach.

Key Formulas Refresher

  • WACC = (E/V)×Re + (D/V)×Rd×(1−Tc)
  • FCF = EBIT×(1−Tax rate) + D&A − Capex − ΔNWC
  • Terminal value (Gordon growth) = FCF_final × (1 + g) / (WACC − g)

Ask ChatGPT-5.5 for WACC Inputs

wacc_prompt = [
  {"role":"system","content":"Return valid JSON with keys: cost_of_equity, cost_of_debt, tax_rate, target_debt_to_total_capital, notes."},
  {"role":"user","content":(
    "Estimate WACC inputs for a mid-cap B2B SaaS in the U.S. Use ranges if uncertain. "
    "Assume current 10y risk-free ~4%, beta 1.1–1.4, market risk premium 5–6%. "
    "Debt cost ~7–9%, tax rate 21%. Provide notes explaining each input."
  )}
]
wacc_json = chat_completion(wacc_prompt)
wacc = json.loads(wacc_json)

Python DCF Implementation

import numpy as np
import pandas as pd

def compute_wacc(cost_of_equity, cost_of_debt, tax_rate, debt_ratio):
    equity_ratio = 1 - debt_ratio
    return equity_ratio*cost_of_equity + debt_ratio*cost_of_debt*(1 - tax_rate)

def dcf_valuation(fcf, wacc, terminal_growth=0.02):
    # fcf: list/array of forecast free cash flows per year
    # Returns NPV and a detail table
    years = len(fcf)
    discount_factors = [(1 / ((1 + wacc) ** t)) for t in range(1, years+1)]
    pv_fcf = [fcf[t-1] * discount_factors[t-1] for t in range(1, years+1)]
    tv = fcf[-1] * (1 + terminal_growth) / (wacc - terminal_growth)
    pv_tv = tv * discount_factors[-1]
    npv = sum(pv_fcf) + pv_tv
    df = pd.DataFrame({
        "year": np.arange(1, years+1),
        "fcf": fcf,
        "discount_factor": np.round(discount_factors, 6),
        "pv_fcf": np.round(pv_fcf, 2)
    })
    return npv, pv_tv, df

# Example: derive FCF from the revenue model using margins/assumptions
annual_fcf = [8_000_000, 12_000_000, 18_000_000, 22_000_000, 28_000_000]
wacc_val = compute_wacc(cost_of_equity=0.105, cost_of_debt=0.08, tax_rate=0.21, debt_ratio=0.20)
npv, pv_tv, fcf_table = dcf_valuation(annual_fcf, wacc=wacc_val, terminal_growth=0.02)
print("WACC:", round(wacc_val,4), "NPV:", round(npv,2), "PV of TV:", round(pv_tv,2))
print(fcf_table)

Ask the Model to Validate DCF Inputs and Ranges

validate_prompt = [
  {"role":"system","content":"You are a valuation professor. Return JSON {issues:[...], suggestions:[...]}."},
  {"role":"user","content":(
    "Review this DCF: wacc="+str(round(wacc_val,4))+", terminal_growth=2%, "
    "annual FCF: "+str(annual_fcf)+". Identify red flags, such as g near WACC, and typical sensitivity ranges."
  )}
]
validation_json = chat_completion(validate_prompt)
print(validation_json)

Reporting: Table of DCF Results

Year FCF Discount Factor PV of FCF
1 $8,000,000 0.904978 $7,239,824
2 $12,000,000 0.819960 $9,839,520
3 $18,000,000 0.742349 $13,362,282
4 $22,000,000 0.671680 $14,777,000
5 $28,000,000 0.607506 $17,810,168
Always triangulate: compare DCF-implied valuation to multiples (EV/Revenue, EV/EBITDA) and to precedent transactions. ChatGPT-5.5 can draft the comparison narrative and highlight inconsistencies.

Sensitivity Tables and What-If Analysis

Sensitivity analysis reveals which variables matter most. It informs risk, focus, and prioritization. We will build one-way and two-way tables and automate a heatmap-like summary. ChatGPT-5.5 can draft the code and explain results.

One-Way Sensitivity (e.g., Churn)

def one_way_sensitivity(var_name, values, base_params):
    rows = []
    for v in values:
        params = base_params.copy()
        params[var_name] = v
        df = simulate_cohorts(
            months=params["months"],
            start_customers=params["start_customers"],
            arpu=params["arpu"],
            new_leads=params["new_leads"],
            lead_to_trial=params["lead_to_trial"],
            trial_to_paid=params["trial_to_paid"],
            base_churn_pct=params["base_churn_pct"] if var_name!="base_churn_pct" else v,
            net_expansion_pct=params["net_expansion_pct"]
        )
        rows.append({"value": v, "m12_rev": df["revenue"].iloc[11], "m24_rev": df["revenue"].iloc[23], "m36_rev": df["revenue"].iloc[35]})
    return pd.DataFrame(rows)

base_params = {
    "months":36, "start_customers":5000, "arpu":100.0, "new_leads":3500, "lead_to_trial":0.18,
    "trial_to_paid":0.22, "base_churn_pct":0.015, "net_expansion_pct":0.008
}
churn_values = [0.010, 0.0125, 0.015, 0.0175, 0.020]
one_way = one_way_sensitivity("base_churn_pct", churn_values, base_params)
print(one_way)

Two-Way Sensitivity (WACC vs. Terminal Growth in DCF)

def two_way_dcf_sensitivity(wacc_values, g_values, fcf):
    grid = []
    for w in wacc_values:
        row = []
        for g in g_values:
            npv, pv_tv, df = dcf_valuation(fcf, wacc=w, terminal_growth=g)
            row.append(npv)
        grid.append(row)
    return np.array(grid)

wacc_values = [0.08, 0.09, 0.10, 0.11, 0.12]
g_values = [0.00, 0.01, 0.02, 0.03]
grid = two_way_dcf_sensitivity(wacc_values, g_values, annual_fcf)
print(pd.DataFrame(grid, index=wacc_values, columns=g_values))

Heatmap Rendering (ASCII/Console)

def heatmap_ascii(grid, row_labels, col_labels):
    # Normalize grid to 0-1
    grid = np.array(grid)
    mn, mx = np.min(grid), np.max(grid)
    shades = " .:-=+*#%@"
    out = []
    out.append("      " + " ".join([f"{c:>7.2%}" for c in col_labels]))
    for i, r in enumerate(row_labels):
        line = [f"{r:>5.2%}"]
        for j, _ in enumerate(col_labels):
            if mx - mn < 1e-9:
                idx = len(shades) - 1
            else:
                x = (grid[i, j] - mn) / (mx - mn)
                idx = min(int(x * (len(shades)-1)), len(shades)-1)
            line.append(f"   {shades[idx]*3}")
        out.append(" ".join(line))
    return "\n".join(out)

print(heatmap_ascii(grid, wacc_values, g_values))

Ask ChatGPT-5.5 to Interpret Sensitivities

interp_messages = [
  {"role":"system","content":"You are a chartered financial analyst. Explain implications clearly."},
  {"role":"user","content":(
    "Interpret this two-way sensitivity table (NPV) where rows=WACC and cols=terminal growth. "
    "Call out thresholds where valuation turns highly sensitive. Data:\n"
    + pd.DataFrame(grid, index=wacc_values, columns=g_values).to_csv()
  )}
]
interpretation = chat_completion(interp_messages)
print(interpretation)
Result: You get a fast read of which variables dominate valuation and how close your base case is to points of non-linearity (e.g., g approaching WACC).

Building an End-to-End Modeling Pipeline

Create a simple orchestration layer that pulls inputs, calls ChatGPT-5.5 for assumptions or narrative, runs simulations, and saves outputs. This modularity lets you re-run the whole stack as data changes.

Directory Structure

finance-model/
├─ data/
│  ├─ assumptions_base.json
│  ├─ raw/
│  └─ exports/
├─ scripts/
│  ├─ assumptions.py
│  ├─ forecast.py
│  ├─ scenarios.py
│  ├─ dcf.py
│  ├─ sensitivity.py
│  └─ memo.py
├─ notebooks/
├─ reports/
│  └─ investment_memo.html
└─ README.md

Python Orchestrator

import json, os
import pandas as pd
from datetime import datetime

from assumptions import get_base_assumptions  # your wrapper using ChatGPT-5.5
from forecast import simulate_cohorts
from scenarios import build_scenarios
from dcf import dcf_valuation, compute_wacc
from memo import generate_memo  # your wrapper using ChatGPT-5.5

EXPORT_DIR = "data/exports"

def ensure_dir(p):
    if not os.path.exists(p):
        os.makedirs(p)

def run_pipeline():
    ensure_dir(EXPORT_DIR)
    # 1) Assumptions
    base = get_base_assumptions()
    with open("data/assumptions_base.json","w") as f:
        json.dump(base, f, indent=2)
    # 2) Forecasts
    base_df = simulate_cohorts(months=36, start_customers=5000, arpu=base["arpu"],
                               new_leads=base["new_leads"], lead_to_trial=base["lead_to_trial"],
                               trial_to_paid=base["trial_to_paid"], base_churn_pct=base["churn"],
                               net_expansion_pct=base["net_expansion"])
    base_df.to_csv(os.path.join(EXPORT_DIR,"forecast_base.csv"), index=False)
    # 3) Scenarios
    scens = build_scenarios()
    # ... produce scenario CSVs
    # 4) DCF
    wacc = compute_wacc(0.105, 0.08, 0.21, 0.20)
    fcf = [8e6, 12e6, 18e6, 22e6, 28e6]
    npv, pv_tv, table = dcf_valuation(fcf, wacc, terminal_growth=0.02)
    table.to_csv(os.path.join(EXPORT_DIR,"dcf_table.csv"), index=False)
    # 5) Memo
    memo_html = generate_memo(forecast_csv=os.path.join(EXPORT_DIR,"forecast_base.csv"),
                              dcf_csv=os.path.join(EXPORT_DIR,"dcf_table.csv"),
                              npv=npv, wacc=wacc)
    with open("reports/investment_memo.html","w") as f:
        f.write(memo_html)
    print("Pipeline complete at", datetime.now())

if __name__ == "__main__":
    run_pipeline()

Tool Use: Asking ChatGPT-5.5 to Write Helper Code

For repetitive tasks (e.g., computing retention curves), ask the model to generate functions, then test and version them. This keeps your pipeline clean and maintainable.

Validation, Guardrails, and Auditability

Quantitative integrity is paramount. Here are simple practices to increase reliability:

  • Use structured outputs (JSON schemas) and validate types and ranges.
  • Keep an assumptions log with datetime, user, and reason for change.
  • Ask for “source notes” mapping each assumption to data, study, or cell.
  • Cross-check ChatGPT-5.5 outputs against deterministic calculations in your own code.
  • Add unit tests for core equations (e.g., churn application, ARPU compounding).

Validation Example: JSON Schema Check

from jsonschema import validate, Draft7Validator

schema = {
  "type":"object",
  "properties":{
    "assumptions":{
      "type":"array",
      "items":{
        "type":"object",
        "properties":{
          "name":{"type":"string"},
          "value":{"type":"number"},
          "unit":{"type":"string"}
        },
        "required":["name","value","unit"]
      }
    },
    "notes":{"type":"string"}
  },
  "required":["assumptions","notes"]
}

errors = sorted(Draft7Validator(schema).iter_errors(assumptions), key=lambda e: e.path)
for e in errors:
    print("Schema error:", e.message)

Unit Tests for Core Math

def test_retention_monotonicity():
    churn = 0.02
    df = simulate_cohorts(months=24, start_customers=1000, arpu=50, new_leads=100,
                          lead_to_trial=0.2, trial_to_paid=0.25,
                          base_churn_pct=churn, net_expansion_pct=0.0)
    # Customers should not jump arbitrarily if no growth in new leads
    assert (df["customers"].diff().iloc[1:] <= 150).all()
Do not overfit to the model’s suggestions. Use it as a copilot, but enforce review, tests, and independent verification.

Exporting to Excel, CSV, and Google Sheets

Once your forecasts and valuations are computed, you need to publish them. ChatGPT-5.5 can generate accompanying narratives, footnotes, and even dynamic chart captions.

Excel Export with Python

import pandas as pd
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.styles import Font

def export_to_excel(forecast_df, dcf_table, path="reports/model_export.xlsx"):
    wb = Workbook()
    ws1 = wb.active
    ws1.title = "Forecast"
    for r in dataframe_to_rows(forecast_df, index=False, header=True):
        ws1.append(r)
    ws2 = wb.create_sheet("DCF")
    for r in dataframe_to_rows(dcf_table, index=False, header=True):
        ws2.append(r)
    # Style headers
    for cell in ws1[1]: cell.font = Font(bold=True)
    for cell in ws2[1]: cell.font = Font(bold=True)
    wb.save(path)

export_to_excel(base_df, fcf_table)

Google Sheets Push (via gspread)

import gspread
from google.oauth2.service_account import Credentials

def push_to_sheets(df, sheet_name, worksheet_title="Forecast"):
    scopes = ["https://www.googleapis.com/auth/spreadsheets"]
    creds = Credentials.from_service_account_file("service_account.json", scopes=scopes)
    gc = gspread.authorize(creds)
    sh = gc.open(sheet_name)
    try:
        ws = sh.worksheet(worksheet_title)
        sh.del_worksheet(ws)
    except:
        pass
    ws = sh.add_worksheet(title=worksheet_title, rows=str(len(df)+10), cols=str(len(df.columns)+10))
    ws.update([df.columns.values.tolist()] + df.values.tolist())

push_to_sheets(base_df, "Financial Model", "Forecast")
push_to_sheets(fcf_table, "Financial Model", "DCF")

Attach Narrative from ChatGPT-5.5

caption_messages = [
  {"role":"system","content":"You generate concise chart captions for executive readers."},
  {"role":"user","content":(
    "Create 3 captions for a chart with monthly revenue for base/bull/bear. "
    "Tone: objective, data-first. Limit 18 words each. Data (CSV head):\n" + summary.head(12).to_csv(index=False)
  )}
]
captions = chat_completion(caption_messages)
print(captions)

FAQ and Troubleshooting

How do I ensure numeric outputs are actually numbers?

Use JSON schemas and validate them. For text responses, perform robust parsing with regex and type coercion. Ask ChatGPT-5.5 explicitly to return decimals (0.15) instead of percentages (15%).

What if I get hallucinatory justifications or implausible ranges?

Feed in your own historicals, impose ranges in the prompt, and ask for alternative sets with credibility scores. Include a “reject if out of range” instruction and require the model to restate constraints before answering.

Access 40,000+ AI Prompts for ChatGPT, Claude & Codex — Free!

Subscribe to get instant access to our complete Notion Prompt Library — the largest curated collection of prompts for ChatGPT, Claude, OpenAI Codex, and other leading AI models. Optimized for real-world workflows across coding, research, content creation, and business.

Get Free Access Now →

How do I keep prompts and model behavior consistent across runs?

Save prompt templates in version control and use the same seed/temperature settings if available. Log inputs/outputs with timestamps for audit trails.

Can I combine deterministic math with model explanations?

Yes—compute all math in your code or spreadsheet, then use ChatGPT-5.5 to explain, QA, and narrate. This division of labor reduces risk.

What’s the best way to expose this to stakeholders?

Publish an interactive dashboard or spreadsheet. Use scenario and sensitivity toggles. Attach the memo and footnotes generated by ChatGPT-5.5. Keep assumptions editable.

Any tips for faster iteration cycles?

  • Small, composable prompts scoped to a single task.
  • Cache intermediate outputs (assumptions JSON, scenario CSVs).
  • Automate with a simple orchestrator script and pre-flight checks.

Next Steps

  1. Clone the pipeline skeleton, wire the API calls, and run a base-case forecast.
  2. Generate scenarios using the template prompts and validate with your team.
  3. Compute DCF, produce one- and two-way sensitivities, and export to your reporting tool.
  4. Generate an investment memo and iterate with stakeholders until assumptions converge.
  5. Automate weekly re-runs with fresh data and a versioned assumptions log.

When you are ready, extend to cohort LTV/CAC analysis, cash runway modeling, and KPI dashboards. For more patterns, search within your knowledge base or check internal documentation at

To deepen your understanding of adjacent AI capabilities, explore our detailed analysis in 25 ChatGPT-5.5 Prompts for DevOps Engineers, which examines prompts for CI/CD pipelines and infrastructure as code. The frameworks and prompt patterns discussed there integrate seamlessly with the strategies outlined in this article.

.

Appendix: Additional API Integration Patterns

Function/Tool Calling (If Supported)

If your API supports tool calling, you can enforce strict argument shapes and let the model pick which tool to use (e.g., “calculate_dcf”, “simulate_revenue”).

# Pseudo-JSON of a tool definition (adapt to your provider)
{
  "tools":[
    {
      "type":"function",
      "function":{
        "name":"calculate_dcf",
        "description":"Compute DCF from FCF vector, WACC, terminal growth",
        "parameters":{
          "type":"object",
          "properties":{
            "fcf":{"type":"array","items":{"type":"number"}},
            "wacc":{"type":"number"},
            "terminal_growth":{"type":"number"}
          },
          "required":["fcf","wacc","terminal_growth"]
        }
      }
    }
  ]
}

Streaming Responses

For long memos or logs, streaming can improve UX. Here’s a Node.js sketch:

import fetch from "node-fetch";

async function streamChat(messages) {
  const res = await fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ model: "chatgpt-5.5", messages, stream: true })
  });
  for await (const chunk of res.body) {
    process.stdout.write(chunk.toString());
  }
}

streamChat([{role:"user", content:"Generate an executive summary for the base-case forecast."}]);

Error Handling and Retries

import time, random
import requests

def resilient_post(url, headers, payload, retries=3, backoff=1.5):
    for attempt in range(1, retries+1):
        try:
            resp = requests.post(url, headers=headers, json=payload, timeout=120)
            resp.raise_for_status()
            return resp.json()
        except Exception as e:
            if attempt == retries:
                raise
            sleep_time = backoff ** attempt + random.uniform(0, 0.3)
            time.sleep(sleep_time)

Logging and Observability

import logging, json, time
logging.basicConfig(level=logging.INFO)

def log_interaction(tag, messages, response):
    logging.info(json.dumps({
        "tag": tag,
        "ts": time.time(),
        "messages": messages,
        "response_preview": response[:200]
    }))

Internal reference:

Organizations implementing these workflows will also benefit from understanding The Codex Task Decomposition Playbook, which covers breaking complex projects into agent-ready subtasks in detail. The methodologies presented there provide a natural extension of the concepts explored above, particularly for teams scaling their AI-assisted processes.

© chatgptaihub.com — Financial Modeling with ChatGPT-5.5

This tutorial is for educational purposes. Validate all results before making investment or operational decisions.



Get Free Access to 40,000+ AI Prompts for ChatGPT, Claude & Codex

Subscribe for instant access to the largest curated Notion Prompt Library for AI workflows.

More on this