Forecasting Model
Bioloupe Forecasting Model
Section titled “Bioloupe Forecasting Model”Scope: Business/domain documentation covering forecasting concepts, patient flow, and calculations. For technical architecture (Jotai state, React Query, component patterns), see ARCHITECTURE.md.
Table of Contents
Section titled “Table of Contents”- Introduction & Model Overview
- Patient Flow Model
- Addressable Population Calculations
- Market Share Model
- Revenue/Sales Calculations
- User Workflow (7 Stages)
- Monte Carlo Simulation
- Data Inputs Reference
1. Introduction & Model Overview
Section titled “1. Introduction & Model Overview”Purpose
Section titled “Purpose”The Bioloupe forecasting model predicts pharmaceutical sales revenue by modeling the patient journey from disease incidence through treatment and calculating market share capture across multiple therapy lines.
High-Level Flow
Section titled “High-Level Flow”flowchart TB
A[Annual Incidence] --> B[Addressable Population]
B --> C[Treatment Eligible Patients]
C --> D[Market Share Applied]
D --> E[New Patients per Therapy Line]
E --> F[Revenue Calculation]
F --> G[Total Sales Forecast]
Key Business Concepts
Section titled “Key Business Concepts”| Concept | Description |
|---|---|
| Incidence | New disease cases per year in a population |
| Addressable Population | Patients who can potentially receive treatment |
| Therapy Line | Sequential treatment stage (1L, 2L, 3L+) |
| Peak Share | Maximum market share a product can achieve |
| Loss of Exclusivity (LoE) | When patent protection ends and generics enter |
| Class Share | Percentage of patients suitable for the therapy class (adjusts Peak Share) |
1b. Domain Concepts Explained
Section titled “1b. Domain Concepts Explained”This section provides intuitive explanations of the forecasting domain to help understand the “why” behind the formulas.
Why Addressable = Incidence + Relapse (Not Just Incidence)
Section titled “Why Addressable = Incidence + Relapse (Not Just Incidence)”Incidence only counts NEW diagnoses in a given year. It does not include patients diagnosed in prior years.
Think of it like hospital admissions:
- Incidence = New patients walking in the door THIS YEAR
- Relapse = Prior patients coming BACK because their disease returned
Timeline Example (Breast Cancer):
| Year | Event | Where Counted |
|---|---|---|
| 2023 | Patient diagnosed with EARLY stage cancer | 2023 Early Incidence |
| 2024 | Patient completes early stage treatment | Not counted |
| 2025 | Cancer returns and has now SPREAD | 2025 Early→Met Relapse |
This 2025 relapse patient:
- ❌ NOT in 2025 Metastatic Incidence (wasn’t newly diagnosed as metastatic)
- ✅ IS in 2025 Early-to-Met Relapse count
- ✅ DOES need metastatic treatment now
Who needs metastatic treatment in 2025?
Metastatic Addressable = New Met diagnoses (incidence) + Returning patients (relapse) = 87,000 + 20,300 = 107,300 patientsKey Insight: Metastatic Addressable is ALWAYS ≥ Metastatic Incidence because relapse ADDS patients.
Why Multiply by Healthcare Access × Treatment Rate?
Section titled “Why Multiply by Healthcare Access × Treatment Rate?”Not everyone with a disease gets treated. Real-world barriers reduce the population at each step:
100 patients with metastatic cancer │ ├─► Healthcare Access (95%) │ - 5 patients can't access care (no insurance, remote location, unaware) │ = 95 patients remaining │ └─► Treatment Rate (80%) - 19 patients don't get treated (refuse, too sick, contraindicated) = 76 patients actually receive 1L treatmentReal-world reasons for each barrier:
| Barrier | Examples |
|---|---|
| Healthcare Access | No insurance, lives far from hospital, undiagnosed, dies before treatment |
| Treatment Rate | Patient refuses treatment, doctor advises against it, comorbidities prevent treatment |
Solid Tumors vs Hematology
Section titled “Solid Tumors vs Hematology”The model handles two disease categories differently:
Solid Tumors (Stage-Aware)
Section titled “Solid Tumors (Stage-Aware)”What they are: Cancers that form physical masses in specific organs (breast, lung, colon, prostate).
Why stage matters:
- Early Stage = Tumor is localized, hasn’t spread, often curable with surgery
- Metastatic = Cancer has spread to distant organs, requires systemic treatment
Example: Breast Cancer├── 70% diagnosed Early Stage (localized to breast)│ └── Some will relapse → adds to metastatic pool└── 30% diagnosed Metastatic (already spread at diagnosis)Treatment approaches differ drastically between stages, so the model tracks them separately.
Hematology (No Stage Split)
Section titled “Hematology (No Stage Split)”What they are: Blood cancers (leukemia, lymphoma, multiple myeloma).
Why NO stage split:
- Cancer is IN the blood or bone marrow
- Already “systemic” from day one - no localized tumor
- No meaningful “early vs metastatic” distinction
- All patients flow directly to therapy lines
Solid Tumor: Incidence → [Early | Metastatic] → Relapse → Addressable → TherapyHematology: Incidence → Addressable → Therapy (no stage split)Formula difference:
Solid Tumor Met Addressable = (Incidence × Met%) + (Incidence × Early% × Relapse%)Hematology Addressable = Incidence × Healthcare Access%The Treatment Funnel Visualized
Section titled “The Treatment Funnel Visualized”┌─────────────────────────────────────────────────────────────────────┐│ INCIDENCE: 290,000 new breast cancer cases/year (USA) │└─────────────────────────────────────────────────────────────────────┘ │ ┌───────────────┴───────────────┐ ▼ ▼┌───────────────────────────┐ ┌───────────────────────────┐│ EARLY STAGE │ │ METASTATIC STAGE ││ 70% = 203,000 │ │ 30% = 87,000 ││ (localized tumor) │ │ (spread to organs) │└───────────────────────────┘ └───────────────────────────┘ │ ▲ │ RELAPSE (10% of early) │ └────────────────────────────────────┤ +20,300 patients │ │ ┌───────────────────────────────┴───┐ │ METASTATIC ADDRESSABLE │ │ = 87,000 + 20,300 = 107,300 │ │ (incidence + relapse) │ └───────────────────────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Healthcare Access (95%) │ │ = 107,300 × 0.95 = 101,935 │ └───────────────────────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Treatment Rate (80%) │ │ = 101,935 × 0.80 = 81,548 │ │ ← 1L Met Treated Patients │ └───────────────────────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Market Share (35%) │ │ = 81,548 × 0.35 = 28,542 │ │ ← Patients on YOUR product │ └───────────────────────────────────┘Common Confusion: “1L Met < Met Incidence - Is That Wrong?”
Section titled “Common Confusion: “1L Met < Met Incidence - Is That Wrong?””It depends on what number you’re looking at:
| Metric | Value | Can be < Incidence? |
|---|---|---|
| Met Addressable (before funnel) | 107,300 | ❌ NO - always ≥ incidence |
| 1L Met Treated (after funnel) | 81,548 | ✅ YES - funnel reduces it |
| 1L Met on Your Product (after share) | 28,542 | ✅ YES - much smaller |
The bug we fixed: The code was showing Addressable as lower than Incidence, which is mathematically impossible since Addressable = Incidence + Relapse.
Patient Flow Tree & Panel Display
Section titled “Patient Flow Tree & Panel Display”The Configuration section has a left panel and a right panel.
Left panel — SummaryCard: Shows incidence, stage distribution, and relapse rates at a glance.
Right panel — Varies by tree selection (TreeSelection: summary | line):
| Selection | Panel | Content |
|---|---|---|
| Summary | SummaryPanel | Editable incidence, stage mix, relapse rates |
| Line | LinePanel | Line-specific config (treatment rate, transition rate, custom variables, etc.) |
Tree structure: Lines are listed directly within each stage section (Early/Met for solid tumors), with custom lines per-stage. There are no separate “Incidence” or “Stage” tree nodes — the summary view covers those.
Summary ← SummaryPanel (incidence + stage mix)│├── Early Stage│ ├── Early 1L: 37,500 ← LinePanel (addressable count)│ └── Early Custom Line ← LinePanel (editable name)│└── Metastatic ├── Met 1L: 80,500 ← LinePanel (addressable count) └── Met 2L: 20,963 ← LinePanel (addressable count)- Reference lines have read-only names; only custom lines have editable names
- Default lines show addressable count in the header; treatment eligible appears in a summary card at the end of the Patient Flow section
Key insight: Numbers go UP from Stage → 1L because relapse ADDS patients:
- Met Stage: 70,000 (raw incidence × 70%)
- Met 1L: 80,500 (70,000 + 10,500 relapse from early stage)
For 2L and beyond:
- Only patients who ACCESSED previous treatment can progress
- 2L Addressable = 1L Eligible × Transition Rate (not 1L Addressable)
- This is clinically correct: you can’t progress from treatment you never received
2b. Biomarker Filtering (Funnel Multiplier)
Section titled “2b. Biomarker Filtering (Funnel Multiplier)”Concept
Section titled “Concept”Some cancer indications have biomarker-defined sub-populations — subsets of patients who test positive for a specific biomarker. For example, Oropharyngeal Cancer has an HPV Positive sub-population representing ~68% of cases.
When a biomarker filter is active, the model applies a funnel multiplier to the first-line addressable population. Biomarker does not modify incidence — it filters within the patient flow funnel.
Formula
Section titled “Formula”biomarkerFactor = (biomarkerPercentage / 100) × (biomarkerTestingRate / 100) [when active] = 1.0 [when inactive]Applied in the funnel:
Addressable Population (incidence + relapse — unchanged by biomarker) │ × biomarkerFactor ← applied here (first line only) │ × Healthcare Access % │ × Neo/Adj Factor (if applicable) │ × Drug Treatment Rate │ = Treatment Eligible- Biomarker Percentage: prevalence of the biomarker in the disease population (e.g., 68%)
- Testing Rate: percentage of patients actually tested for this biomarker (e.g., 93%)
Example: HPV Positive, Oropharyngeal Cancer (USA)
Section titled “Example: HPV Positive, Oropharyngeal Cancer (USA)”| Parameter | Value |
|---|---|
| Addressable Population | 15,004 |
| HPV Positive Prevalence | 68% |
| HPV Testing Rate | 93% |
| biomarkerFactor | 0.68 × 0.93 = 0.6324 |
| Filtered Addressable | 15,004 × 0.6324 = 9,489 |
Behavior
Section titled “Behavior”- Biomarker filtering is optional (toggle OFF by default)
- Only one biomarker can be active per indication at a time
- Applied to first lines only (Early 1L, Met 1L, Therapy 1L for hematology); subsequent lines inherit the filtered count via transition rates
- Toggling OFF sets factor to 1.0 (no filtering)
- Incidence count is never modified — biomarker is a derived multiplier via
biomarkerFactorAtom
UI Location
Section titled “UI Location”Biomarker UI appears in first-line panels (LinePanel → FirstLineExtras) under the “Biomarker” section, between relapse rates and patient flow fields.
Implementation Reference
Section titled “Implementation Reference”- Atoms:
biomarkerFactorAtom,activeBiomarkerAtom,toggleBiomarkerAtominatoms.ts - Computation:
biomarkerFactorparam oncalculateLineFunnelForDisplay,calculateLinePatients,calculateLineSales,calculateTreatmentEligiblePatients - UI:
FirstLineExtrascomponent inLinePanel.tsx
2c. Neoadjuvant / Adjuvant Split (Early Stage Solid Tumors Only)
Section titled “2c. Neoadjuvant / Adjuvant Split (Early Stage Solid Tumors Only)”Concept
Section titled “Concept”For early-stage solid tumors, patients may receive treatment in different settings:
- Neoadjuvant = treatment before surgery (shrink the tumor, then operate)
- Adjuvant = treatment after surgery (operate, then treat to prevent recurrence)
- Other = other treatment settings (e.g. maintenance, palliative)
The user selects one category and sets a single percentage that acts as a simple multiplier on the eligible population.
Formula
Section titled “Formula”neoAdjFactor = neoAdjPercent / 100- When disabled or not applicable, factor = 1.0 (no effect)
- The selected category (
neoAdjSetting) is a label only — does not affect the math
Default: 100% = factor 1.0 (no reduction)
Where It Fits in the Patient Funnel
Section titled “Where It Fits in the Patient Funnel”Addressable Population │ × Healthcare Access │ × Drug Treatment Rate │ × [Setting] Split ← neoAdjPercent / 100 │ = Treatment EligibleThe neo/adj factor is applied after drug treatment rate. The toggle is per-line — any early-stage line can have it enabled independently. In sales/Monte Carlo calculations, the factor is applied to the first line only.
UI Behavior
Section titled “UI Behavior”- Toggle: User enables/disables the split per line
- Segmented control: Pick one of 3 categories: Neoadjuvant, Adjuvant, or Other
- Percentage input: Single percentage (0-100%) applied as a multiplier (default 100%)
- Rollback: Resets percentage to 100%
Implementation Reference
Section titled “Implementation Reference”- Type:
UnifiedLineData.neoAdjSetting(“neo” | “adj” | “other”),neoAdjPercent(0-100) - Formula: Simple multiplier —
neoAdjPercent / 100applied to eligible population - Calculation:
getNeoAdjFactor()incomputations.ts - UI: Segmented control + single percentage in
LinePanel.tsx
2d. Custom Variables (Addressable Population Multipliers)
Section titled “2d. Custom Variables (Addressable Population Multipliers)”Concept
Section titled “Concept”Users can define up to 5 custom multiplier variables per therapy line (MAX_CUSTOM_VARIABLES = 5). Each custom variable represents a percentage applied multiplicatively to the addressable population, allowing users to model additional filtering factors not covered by the built-in parameters.
Formula
Section titled “Formula”customMultiplier = Π(customVar.value / 100) — product of all custom variable percentagesApplied in the patient funnel (order matches code):
Addressable Population │ × Healthcare Access % │ × Neo/Adj Factor (if applicable — see section 2c) │ × Drug Treatment Rate │ × customMultiplier ← product of all custom variable percentages │ = Treatment EligibleFirst-Line Coupling
Section titled “First-Line Coupling”First-line (1L) custom variables are synced to incidenceVars.customVariables for use in Monte Carlo and Tornado simulations. This ensures probabilistic analyses include the custom variable effects.
Multi-Line Support
Section titled “Multi-Line Support”For 2L+ lines, the system uses findMatchingLineCustomVariable() to locate matching custom variables across lines, enabling consistent filtering across the therapy cascade.
Implementation Reference
Section titled “Implementation Reference”- Computation:
getCustomMultiplier()incomputations.ts - Matching:
findMatchingLineCustomVariable()incomputations.ts - Constant:
MAX_CUSTOM_VARIABLESinconstants.ts
2. Patient Flow Model
Section titled “2. Patient Flow Model”The model tracks patients through a funnel from initial diagnosis to treatment across multiple therapy lines.
Patient Population Funnel
Section titled “Patient Population Funnel”flowchart TD
subgraph Incidence["Disease Incidence"]
I[Base Incidence] --> PG[Population Growth Adjustment]
PG --> RF[Regional Factor Adjustment]
end
subgraph StageSplit["Stage Split (Solid Tumors Only)"]
RF --> |Solid Tumor| ES[Early Stage %]
RF --> |Solid Tumor| MS[Metastatic %]
RF --> |Hematology| TH[Full Incidence]
ES --> E2E[+ Early to Early Relapse %]
ES --> E2M[Early to Met Relapse %]
E2M --> MS
end
subgraph Addressable["Addressable Population (1L)"]
E2E --> BF1["× Biomarker Factor"]
BF1 --> EA["Early Addressable × HC%"]
MS --> BF2["× Biomarker Factor"]
BF2 --> MA["Met Addressable × HC%"]
TH --> BF3["× Biomarker Factor"]
BF3 --> TA["Therapy Addressable × HC%"]
end
Disease Categories
Section titled “Disease Categories”The model handles two main disease categories differently:
| Category | Stage Split | Example Indications |
|---|---|---|
| Solid Tumors | Yes - Early Stage + Metastatic | Breast Cancer, Lung Cancer, Melanoma |
| Hematology | No - Full incidence flows to therapy | Leukemia, Lymphoma, Multiple Myeloma |
Therapy Line Transitions
Section titled “Therapy Line Transitions”flowchart TD
A[1L Addressable Population] --> |Treatment Rate %| B[1L Eligible Patients]
B --> |Market Share %| C[1L New Patients on Product]
B --> |Pool minus Retreatment| D[Available for 2L]
D --> |Transition Rate %| E[2L Eligible Patients]
E --> |Treatment Rate %| E2[2L Treated]
E2 --> |Market Share %| F[2L New Patients on Product]
E2 --> |Pool minus Retreatment| G[Available for 3L]
G --> |Transition Rate %| H[3L Eligible Patients]
H --> |Market Share %| I[3L New Patients on Product]
Key Transition Parameters:
- Drug Treatment Rate: Percentage of eligible patients who receive any treatment (applied to 1L and 2L only)
- Transition Rate: Percentage of patients who move from one therapy line to the next
- Retreatment Factor: Patients staying on current therapy (reduces pool for next line)
- Re-treatment Toggle: Binary on/off setting that enables/disables the retreatment calculation for a line
Important: Drug Treatment Rate is applied to 1L and 2L lines. Lines 3L and beyond do not apply Drug Treatment Rate - all transitioned patients are considered eligible.
3. Addressable Population Calculations
Section titled “3. Addressable Population Calculations”Incidence Calculation
Section titled “Incidence Calculation”The base incidence grows with population and adjusts for regional factors:
Year Incidence = Base Incidence × (Pop[Year] / Pop[BaseYear]) × Regional FactorExample:
- Base Incidence (2024): 50,000 patients
- Population 2024: 330 million
- Population 2030: 345 million
- Regional Factor (USA): 1.0
Incidence 2030 = 50,000 × (345M / 330M) × 1.0 = 52,273 patientsAddressable Population by Disease Category
Section titled “Addressable Population by Disease Category”Solid Tumors (Stage-Aware)
Section titled “Solid Tumors (Stage-Aware)”Solid tumors split into Early Stage and Metastatic populations with relapse transitions:
Early Addressable:
Early Addressable = Incidence × EarlyStage% × (1 + EarlyToEarlyRelapse%) × HealthcareAccess%Metastatic Addressable:
Met Addressable = (Incidence × MetStage% + Incidence × EarlyStage% × EarlyToMetRelapse%) × HealthcareAccess%Example (Breast Cancer):
- Incidence: 50,000
- Early Stage: 70%
- Metastatic: 30%
- Early to Early Relapse: 15%
- Early to Met Relapse: 10%
- Healthcare Access: 95%
Early Addressable = 50,000 × 0.70 × (1 + 0.15) × 0.95 = 38,238 patientsMet Addressable = (50,000 × 0.30 + 50,000 × 0.70 × 0.10) × 0.95 = 17,575 patientsHematology (Direct Flow)
Section titled “Hematology (Direct Flow)”Hematology indications do not have stage splits:
Addressable = Incidence × HealthcareAccess%Stage Mix Parameters
Section titled “Stage Mix Parameters”| Parameter | Description | Typical Range |
|---|---|---|
| Early Stage % | Initial early-stage diagnosis | 60-80% |
| ↳ Localized % | Sub-breakdown: localized early stage (optional) | Varies |
| ↳ Locally Advanced % | Sub-breakdown: locally advanced III-IVB (optional) | Varies |
| Metastatic % | Initial metastatic diagnosis (derived: 100 - Early%) | 20-40% |
| Unknown Stage % | Patients with unknown stage at diagnosis (optional) | 0-100% |
| Early to Early Relapse % | Early (Local + Locally Advanced) patients who relapse but stay early | 5-20% |
| Early to Met Relapse % | Early (Local + Locally Advanced) patients who progress to metastatic | 5-15% |
Note: Early Stage % + Metastatic % + Unknown Stage % = 100% (Unknown defaults to 0).
Early Stage Sub-Variables (Solid Tumors Only)
Section titled “Early Stage Sub-Variables (Solid Tumors Only)”Some solid tumors have granular staging data that breaks Early Stage into Localized and Locally Advanced (III-IVB) sub-populations. These sub-variables are display-only — the computation layer always uses the combined earlyStagePercent.
Behavior matrix:
| Data Available | Parent (Early Stage %) | Localized | Locally Advanced | Example |
|---|---|---|---|---|
| Both subs | Read-only (auto-sum) | Editable | Editable | Oropharyngeal: 15.8 + 72.9 = 88.7% |
| Parent + one sub | Editable | Read-only | Read-only | Partial reference data |
| Parent only | Editable | Hidden | Hidden | Most indications (today’s behavior) |
| No data | Fallback chain | Hidden | Hidden | Missing geo-specific data |
Auto-computation: When both sub-variables are present, the parent is derived:
earlyStagePercent = earlyStageLocalizedPercent + earlyStageLocallyAdvancedPercentmetStagePercent = 100 - earlyStagePercentReset behavior: Resetting a sub-variable also resets the parent and metastatic percentage to maintain consistency.
Healthcare Access by Geography
Section titled “Healthcare Access by Geography”| Geography | Healthcare Access |
|---|---|
| USA | 95% |
| EU5 | 98% |
| Japan | 99% |
| China | 95% |
4. Market Share Model
Section titled “4. Market Share Model”Peak Share Calculation
Section titled “Peak Share Calculation”Peak Share is the maximum market share a product can achieve, determined by competitive positioning:
flowchart LR
subgraph Inputs["Peak Share Inputs"]
LO[Launch Order<br/>1st to 10th]
BIC[Best-in-Class?<br/>Yes/No]
DVC[Delay vs Competition<br/>Quarters]
end
subgraph Calculation["Peak Share Calculation"]
LO --> BASE[Base Share from Matrix]
BIC --> BONUS[Best-in-Class Bonus]
DVC --> PENALTY[Delay Penalty]
BASE --> PS[Peak Share %]
BONUS --> PS
PENALTY --> PS
end
Formulas:
Peak Share (within class):
PeakShare = min(100, max(0, BaseShare[LaunchOrder] + BestInClassBonus - DelayPenalty))Effective Peak Share (used in market share calculations):
EffectivePeakShare = CustomEffectivePeakShare (if user has toggled Custom Input) OR PeakShare × (ClassShare / 100) (Bioloupe Guidance — default)Where:
BaseSharecomes from a 10x10 launch order matrix (indexed by launch order and number of competitors)BestInClassBonusis added if the product is best-in-class (indexed by number of competitors)DelayPenalty = DelayQuarters > 3 ? DelayQuarters × 0.5 : 0ClassShareis the percentage of patients suitable for the therapy class (default 100%)
Example:
- Launch Order: 2nd to market (with 3 competitors)
- Best in Class: Yes
- Delay: 6 quarters behind first entrant
- Base Share (2nd position, 3 competitors): 29%
- Best-in-Class Bonus (3 competitors): +30%
- Delay Penalty: 6 × 0.5 = 3%
Peak Share = 29% + 30% - 3% = 56%Peak Share vs Uptake Curve
Section titled “Peak Share vs Uptake Curve”Key Insight:
- Peak Share is the CEILING - the maximum market share your product can ever achieve
- Uptake Curve determines HOW FAST you reach that ceiling
flowchart TB
subgraph "Peak Share = Maximum Market Capture"
INPUT1["Launch Order<br/>(Earlier = Better)"]
INPUT2["Best in Class<br/>(Better Drug = Bonus)"]
INPUT3["Delay vs Competition<br/>(Late = Penalty)"]
INPUT1 --> CALC["Calculate Peak Share"]
INPUT2 --> CALC
INPUT3 --> CALC
CALC --> OUTPUT["Peak Share %<br/>(Your ceiling)"]
end
Think of it like a race:
- Peak Share = How far you can ultimately run (your maximum distance)
- Uptake Curve = How quickly you accelerate to your top speed
A product with 60% peak share using a “3 Year Fast” uptake curve will reach 60% × 60% = 36% market share in Year 1, then 60% × 85% = 51% in Year 2, and finally the full 60% in Year 3.
Uptake Curves (Speed to Peak)
Section titled “Uptake Curves (Speed to Peak)”Products don’t achieve peak share immediately. The uptake curve determines how quickly market share ramps up.
The system provides 30+ uptake curves organized by years to peak (1-12) and speed (Slow/Medium/Fast).
Example: 3-Year Curves
| Curve Name | Year 1 | Year 2 | Year 3+ |
|---|---|---|---|
| 3 Year Slow | 10% | 50% | 100% |
| 3 Year Medium | 26% | 66% | 100% |
| 3 Year Fast | 60% | 85% | 100% |
Note: Curves are named like “3 Year Medium”, “5 Year Fast”, etc. The number indicates years to reach 100% of peak share.
Market Share Over Time
Section titled “Market Share Over Time”flowchart LR
subgraph PreLaunch["Pre-Launch"]
PL[Market Share = 0%]
end
subgraph Ramp["Ramp Period"]
PS[Peak Share] --> UC[Uptake Curve Applied]
UC --> MS1[Growing Share]
end
subgraph Mature["Mature Period"]
MS1 --> PEAK[At Peak Share]
end
subgraph PostLoE["Post-LoE"]
PEAK --> ER[Erosion Curve]
ER --> FINAL[Declining Share]
end
PreLaunch --> Ramp
Ramp --> Mature
Mature --> PostLoE
Year N Market Share Formula:
MarketShare[Year] = UptakeCurve[YearOffset] × EffectivePeakShare × (1 - ErosionRate[YearsPostLoE])Where EffectivePeakShare = CustomEffectivePeakShare (if set) or PeakShare × (ClassShare / 100)
First Year Weighting (for mid-year launches):
WeightedShare = (Uptake[Y1] × (13 - LaunchMonth) + Uptake[Y0] × (LaunchMonth - 1)) / 12Loss of Exclusivity (LoE) Erosion
Section titled “Loss of Exclusivity (LoE) Erosion”After LoE, market share erodes due to generic/biosimilar competition:
| Molecule Type | Year 1 | Year 2 | Year 3 |
|---|---|---|---|
| Small Molecule | 60% | 80% | 84% |
| Biologic | 3% | 30% | 70% |
Note: Small molecules face rapid generic erosion; biologics erode more slowly due to biosimilar complexity.
5. Revenue/Sales Calculations
Section titled “5. Revenue/Sales Calculations”Revenue Calculation Flow
Section titled “Revenue Calculation Flow”flowchart LR
NP[New Patients] --> CALC((×))
PRICE[Net Price per Month] --> CALC
CALC --> CALC2((×))
COMP[Compliance %] --> CALC2
CALC2 --> CALC3((×))
MOT[Months of Therapy] --> CALC3
CALC3 --> DIV[÷ 1,000,000]
DIV --> SALES[Line Sales $M]
Net Price Over Time
Section titled “Net Price Over Time”Price typically changes annually from the launch price:
NetPrice[Year] = LaunchPrice × (1 + AnnualPriceChange%)^(Year - LaunchYear)Example:
- Launch Price: $15,000/month
- Annual Price Change: -2%
- Year of Launch: 2025
| Year | Calculation | Net Price |
|---|---|---|
| 2025 | $15,000 × (0.98)^0 | $15,000 |
| 2026 | $15,000 × (0.98)^1 | $14,700 |
| 2027 | $15,000 × (0.98)^2 | $14,406 |
| 2030 | $15,000 × (0.98)^5 | $13,537 |
Sales Formula
Section titled “Sales Formula”LineSales ($M) = Σ(CohortPatients[yearOffset] × NetPrice × Compliance% × MonthsThisYear[yearOffset]) / 1,000,000MonthsOfTherapy is distributed across calendar years using cohort logic — each cohort year contributes up to 12 months. For example, a 24-month therapy generates 12 months of revenue in year 0 (from that year’s new patients) and 12 months in year 1 (from the prior year’s cohort). When MonthsOfTherapy ≤ 12, only one cohort year contributes and the formula reduces to NewPatients × NetPrice × Compliance% × MonthsOfTherapy / 1M.
Example (1L Therapy):
- New Patients: 5,000
- Net Price: $12,000/month
- Compliance: 85%
- Months of Therapy: 10
LineSales = 5,000 × $12,000 × 0.85 × 10 / 1,000,000 = $510MTotal Sales
Section titled “Total Sales”TotalSales = Sum of LineSales across all therapy lines (1L + 2L + 3L...)Complete Worked Example
Section titled “Complete Worked Example”Scenario: Oncology product, 2nd line therapy, Year 3 post-launch
| Input | Value |
|---|---|
| Addressable Population | 30,000 |
| Treatment Rate | 80% |
| Transition Rate (from 1L) | 60% |
| Market Share (Year 3) | 35% |
| Net Price | $14,000/month |
| Compliance | 90% |
| Months of Therapy | 8 |
Calculation:
1. Eligible Pool = 30,000 - 1L_Patients retained (Assume 15,000 available after 1L retention)
2. 2L Eligible = 15,000 × 60% × 80% = 7,200 patients
3. New Patients = 7,200 × 35% = 2,520 patients
4. Sales = 2,520 × $14,000 × 0.90 × 8 / 1,000,000 = $254M6. User Workflow (7 Stages)
Section titled “6. User Workflow (7 Stages)”The application guides users through seven sequential stages to build their forecast:
flowchart LR
S1[1. Incidence Info] --> S2[2. Landscape]
S2 --> S3[3. Key Assumptions]
S3 --> S4[4. Model]
S4 --> S5[5. Sales Chart]
S4 --> S6[6. Monte Carlo]
S4 --> S7[7. Custom Data]
S1 -.-> |"Geography<br/>Indication"| S2
S2 -.-> |"Patient Populations<br/>Line Definitions"| S3
S3 -.-> |"Market & Price<br/>Parameters"| S4
S4 -.-> |"Calculated Sales"| S5
S4 -.-> |"Variable Ranges"| S6
S7 -.-> |"Override Curves"| S4
Stage 1: Incidence Info
Section titled “Stage 1: Incidence Info”Purpose: Define the disease context and patient population
User Inputs:
- Geography selection (USA, EU5, Japan, China)
- Indication/disease selection
- Base incidence numbers
- Stage mix parameters (for solid tumors)
Outputs: Base patient population for modeling
Stage 2: Landscape
Section titled “Stage 2: Landscape”Purpose: Define the competitive landscape and therapy lines
User Inputs:
- Therapy lines (1L, 2L, 3L, etc.)
- Products in each line
- Launch dates
- Categories (early, metastatic, therapy)
Outputs: Market structure for competitive analysis
Stage 3: Key Assumptions
Section titled “Stage 3: Key Assumptions”Purpose: Set market and pricing parameters
User Inputs:
- Loss of Exclusivity (LoE) date
- Molecule type (biologic vs small molecule)
- Launch price per month
- Annual price change
- Peak share inputs (launch order, best-in-class, delay)
- Speed to peak selection
Outputs: Parameters for market share and revenue calculations
Stage 4: Model
Section titled “Stage 4: Model”Purpose: View calculated forecasts by therapy line
Displays:
- Year-by-year patient numbers
- Market share progression
- Sales by therapy line
- Total sales summary
Interactivity: Accordion views for each therapy line with detailed metrics
Stage 5: Sales Chart
Section titled “Stage 5: Sales Chart”Purpose: Visualize sales forecast
Displays:
- Stacked area chart of sales by therapy line
- Year-over-year trends
- Peak sales identification
Stage 6: Monte Carlo
Section titled “Stage 6: Monte Carlo”Purpose: Analyze forecast uncertainty
User Inputs:
- Variable ranges (min, max, most likely)
- Distribution types
- Number of simulations
Outputs:
- Percentile forecasts (P10, P50, P90)
- Tornado chart showing variable sensitivity
Stage 7: Custom Data (DefaultDataUpload)
Section titled “Stage 7: Custom Data (DefaultDataUpload)”Purpose: Fine-tune projection curves for model accuracy
User Inputs:
- Net Price Change: Year-over-year price changes (when annual price is changeable)
- Share Erosion: Post-LoE share erosion curves (Small Molecule or Biologics, when molecule type is changeable)
- Incidence Evolution: Projected growth rates (%) that cascade-recalculate incidence values
Incidence Evolution Feature:
- 3-row display: Year | Projected Growth Rate (%) | Incidence
- Editing a growth rate at year N cascades updates to all subsequent years
- Growth rate is constant across all years (acceleration is baked into the API-provided rate)
- Formula:
incidence[N+1] = incidence[N] × (1 + growthRate / 100) - Incidence values are read-only (auto-calculated from growth rates)
- First year shows ”-” for growth rate (no prior year to compare)
Outputs: Customized evolution curves that feed back into model calculations
7. Monte Carlo Simulation
Section titled “7. Monte Carlo Simulation”Purpose
Section titled “Purpose”Monte Carlo simulation quantifies forecast uncertainty by running 1,000 to 100,000 scenarios with randomly sampled variable values. The simulation count is configurable via a badge in the section header; counts above 1,000 run in a Web Worker to keep the UI responsive.
Simulation Flow
Section titled “Simulation Flow”flowchart TD
subgraph Inputs["Variable Definitions"]
V1["Variable 1<br/>Min: 10 | Mode: 15 | Max: 25"]
V2["Variable 2<br/>Min: 50 | Mode: 70 | Max: 80"]
VN["Variable N<br/>Min: 5 | Mode: 8 | Max: 12"]
end
subgraph Simulation["Monte Carlo Engine"]
V1 --> SAMPLE[Sample from Distributions]
V2 --> SAMPLE
VN --> SAMPLE
SAMPLE --> |"1K–100K iterations"| MODEL[Run Full Sales Model]
MODEL --> COLLECT[Collect Results]
end
subgraph Outputs["Analysis Outputs"]
COLLECT --> DIST[Distribution of Outcomes]
COLLECT --> PERC["Percentiles<br/>P10 / P50 / P90"]
COLLECT --> TORNADO[Tornado Chart]
end
Variable Types
Section titled “Variable Types”Variables that can be simulated include:
| Category | Variables |
|---|---|
| Incidence | Base incidence, Stage mix percentages, Unknown stage percentage, Relapse rates |
| Treatment | Treatment rate, Healthcare access |
| Market | Peak share, Months of therapy |
| Pricing | Launch price |
| Custom | Custom multiplier variables (up to 5 per line) |
Note: Transition rate, Compliance, and Annual price change are not currently simulated in Monte Carlo analysis.
Incidence Evolution: Monte Carlo and Tornado analyses use the evolved incidence values from Custom Inputs (Stage 7). For each simulated year, getYearIncidence(year) is called to apply the growth rates defined in the Incidence Evolution table, ensuring projections reflect year-over-year incidence changes.
Distribution Types
Section titled “Distribution Types”| Distribution | Use Case | Parameters |
|---|---|---|
| Triangular | Most common - when you have min/max/mode | Min, Mode, Max |
| Normal | Symmetric uncertainty | Mean, Std Dev |
| Uniform | Equal probability across range | Min, Max |
Tornado Analysis
Section titled “Tornado Analysis”The tornado chart ranks variables by their impact on forecast uncertainty:
For each variable:1. Hold all other variables at most likely values2. Run model at variable's minimum value -> Low result3. Run model at variable's maximum value -> High result4. Impact = |High - Low|5. Rank variables by impact (largest at top)Interpretation:
- Variables at the top of the tornado have the greatest influence on uncertainty
- Focus validation efforts on high-impact variables
- Consider strategies to reduce uncertainty in key drivers
Percentile Interpretation
Section titled “Percentile Interpretation”| Percentile | Meaning |
|---|---|
| P10 | 10% chance results will be lower (pessimistic) |
| P50 | Median outcome (50% above, 50% below) |
| P90 | 90% chance results will be lower (optimistic) |
8. Data Inputs Reference
Section titled “8. Data Inputs Reference”Disease Configuration Structure
Section titled “Disease Configuration Structure”Each indication requires configuration of:
Disease Config├── name: "Non-Small Cell Lung Cancer"├── type: "Solid Tumor" | "Hematology"├── abbreviation: "NSCLC"├── incidence│ ├── base: 230000│ └── stageMix (Solid Tumors only)│ ├── earlyStagePercent: 30│ ├── earlyStageLocalizedPercent?: 15.8 (optional sub-breakdown)│ ├── earlyStageLocallyAdvancedPercent?: 72.9 (optional sub-breakdown)│ ├── metStagePercent: 70│ ├── unknownStagePercent?: 0 (optional, defaults to 0)│ ├── earlyToEarlyRelapse: 10│ └── earlyToMetRelapse: 15└── retreatment: 0.8Geographic Adjustments
Section titled “Geographic Adjustments”The initialization flow is geo-aware: each geography derives its own baseIncidence, growthRate, healthcareAccess, stage mix, and treatment line configuration from the API data. When geo-specific data is unavailable, the fallback chain is: Requested geo → USA → EU5 → Japan → China → field-level defaults.
This means diseases with geo-specific incidenceGrowth values in the API will produce different incidence evolution projections per geography, rather than applying USA values to all geos.
| Geography | Regional Factor | Healthcare Access |
|---|---|---|
| USA | 1.0 (baseline) | 95% |
| EU5 | Varies by indication | 98% |
| Japan | Varies by indication | 99% |
| China | Varies by indication | 95% |
Default Values
Section titled “Default Values”Stage Mix Defaults (Solid Tumors)
Section titled “Stage Mix Defaults (Solid Tumors)”| Parameter | Default |
|---|---|
| Early Stage % | 100% |
| Metastatic % | 0% |
| Early to Early Relapse % | 0% |
| Early to Met Relapse % | 0% |
Erosion Rates by Molecule Type
Section titled “Erosion Rates by Molecule Type”| Year Post-LoE | Small Molecule | Biologic |
|---|---|---|
| Year 1 | 60% | 3% |
| Year 2 | 80% | 30% |
| Year 3 | 84% | 70% |
Line Parameter Defaults
Section titled “Line Parameter Defaults”| Parameter | Default |
|---|---|
| Drug Treatment Rate | 100% |
| Transition Rate | 100% |
| Compliance | 100% |
| Months of Therapy | 12 |
Projection Timeline
Section titled “Projection Timeline”- Data array length: 20 years (maximum projection horizon)
- Default visible range: 10-11 years (configurable in UI)
- Start year: Current year or user-selected
- Data points: Annual values
Appendix: Formula Quick Reference
Section titled “Appendix: Formula Quick Reference”Incidence
Section titled “Incidence”YearIncidence = BaseIncidence × (Pop[Year]/Pop[Base]) × RegionalFactorAddressable (Solid Tumor - Early)
Section titled “Addressable (Solid Tumor - Early)”EarlyAddressable = Incidence × EarlyStage% × (1 + E2E%) × HC%Addressable (Solid Tumor - Met)
Section titled “Addressable (Solid Tumor - Met)”MetAddressable = (Incidence × MetStage% + Incidence × EarlyStage% × E2M%) × HC%Addressable (Hematology)
Section titled “Addressable (Hematology)”Addressable = Incidence × HC%Peak Share
Section titled “Peak Share”PeakShare = BaseShare[LaunchOrder, Competitors] + BestInClassBonus[Competitors] - DelayPenaltyDelayPenalty = Delay > 3 ? Delay × 0.5 : 0Market Share
Section titled “Market Share”EffectivePeakShare = CustomEffectivePeakShare OR PeakShare × (ClassShare / 100)MarketShare = Uptake[Year] × EffectivePeakShare × (1 - Erosion[YearsPostLoE])Unknown Stage Percent
Section titled “Unknown Stage Percent”When stage distribution includes an “Unknown” category, the unknown portion is redistributed proportionally across known stages (Option A: Proportional Redistribution):
knownTotal = earlyStagePercent + metStagePercenteffectiveEarlyPct = earlyStagePercent / knownTotaleffectiveMetPct = metStagePercent / knownTotal
earlyIncidence = totalIncidence × effectiveEarlyPctmetIncidence = totalIncidence × effectiveMetPctExample: Incidence=154,270, Early=71%, Met=23%, Unknown=6%
knownTotal = 71 + 23 = 94effectiveEarly = 71/94 = 75.53% → 116,523 patientseffectiveMet = 23/94 = 24.47% → 37,747 patientsTotal accounted: 154,270 (100%)When unknownStagePercent = 0 (default), knownTotal = 100% and the formula
reduces to the identity — no change from direct percentage usage.
Unknown is logically a child of Early Stage. The UI constraint
earlyStagePercent + metStagePercent + unknownStagePercent = 100% is enforced as:
- When Unknown changes:
earlyStagePercent = max(0, 100 - metStagePercent - unknownStagePercent)(Early absorbs the change; Met stays fixed). Sub-variables (Localized, Locally Advanced) scale proportionally. - When Early changes:
metStagePercent = max(0, 100 - earlyStagePercent - unknownStagePercent)(Met absorbs the change; Unknown stays fixed).
Neo/Adj Factor (Early Stage Solid Tumors)
Section titled “Neo/Adj Factor (Early Stage Solid Tumors)”neoAdjFactor = neoAdjPercent / 100 = 1.0 when disabled or 100%Therapy Line Patients
Section titled “Therapy Line Patients”1L: Eligible = Addressable × HC% × NeoAdjFactor × TreatmentRate% NewPatients = Eligible × MarketShare%
2L: Pool = 1L_Eligible - (1L_NewPatients × Retreatment) Eligible = Pool × TransitionRate% × TreatmentRate% NewPatients = Eligible × MarketShare%
3L+: Pool = PriorEligible - (PriorNewPatients × Retreatment) Eligible = Pool × TransitionRate% (NO TreatmentRate applied) NewPatients = Eligible × MarketShare%Notes:
- Treatment Rate only applies to 1L and 2L. Lines 3L and beyond do not apply an additional Treatment Rate filter.
- Neo/Adj Factor only applies to the first line of an early-stage solid tumor cascade. When disabled, factor = 1.0.
Net Price
Section titled “Net Price”NetPrice[Year] = LaunchPrice × (1 + AnnualChange%)^(Year - LaunchYear)LineSales = Σ(CohortPatients[yearOffset] × NetPrice × Compliance% × MonthsThisYear[yearOffset]) / 1,000,000TotalSales = Sum(LineSales) for all lines