Companion to: fuel-impact-2026-05-16.html
Generated: 2026-05-16 by build_report.py (fuel-impact-report skill, MC-3483)
Purpose: step-by-step record of every input value used — verify the math from this doc alone.
| # | Source | File | Last read |
|---|---|---|---|
| 1 | IATA Jet Fuel Price Monitor | ~/Dropbox/Safair/Reporting Data/Data Fuel.xlsx |
2026-05-16 |
| 2 | B4i Fuel Feedback (Bernd Feucht) | ~/PKA/SecondBrain/wiki/concepts/Fuel-Prices-B4i.md |
embedded as base64 in HTML |
| 3 | Radixx route surcharge | ~/PKA/SecondBrain/wiki/concepts/fuel-surcharge-data/surcharge_history.json |
embedded as pivot JSON in HTML |
| 4 | FinDash kpi_data | ~/PKA/Projects/findash/data/kpi_data.json |
2026-05-16 |
| 5 | May MTD dashboard | ~/Dropbox/Safair/Reporting Data/dashboard/dashboard_data.json |
2026-05-16 |
| Parameter | Value | Basis | As-of |
|---|---|---|---|
| MAY_FLIGHTS | 5,031 flights | May schedule | 2026-05-16 |
| MAY_SEATS | 950,475 seats | May schedule | 2026-05-16 |
MC-3517 note: March + April estimate constants removed. All cost fields now read
directly from kpi_data.json actuals (fuel_r, fuel_uplift,
avg_fuel_per_liter_uplifted, total_costs, pbt_r).
NON_FUEL_PER_FLIGHT derived at runtime from April actuals: (total_costs − fuel_r) / flights.
| Metric | Value | kpi_data key |
|---|---|---|
| Flights | 5,640 | flights |
| Pax | 952,408 | pax |
| Seats | 1,062,072 | seats |
| Load Factor | 89.7% | load_factor |
| Yield | R1,329 | yield |
| Revenue | R1,233.5M | revenue_r |
| Fuel uplift | 28.613M L | fuel_uplift — ACTUAL |
| Fuel R/L delivered | R14.62 | avg_fuel_per_liter_uplifted — ACTUAL |
| Fuel cost | R418.4M | fuel_r — ACTUAL |
| Non-fuel cost | R717.8M = total_costs − fuel_r | derived |
| Total costs | R1,136.3M | total_costs — ACTUAL |
| PBT | R127.4M | pbt_r — ACTUAL |
| Reconciliation check | revenue − fuel − non_fuel = R97.2M vs pbt_r R127.4M | gap R30.22M |
| Metric | Value | kpi_data key |
|---|---|---|
| Flights | 5,307 | flights |
| Pax | 864,907 | pax |
| Seats | 999,135 | seats |
| Load Factor | 86.6% | load_factor |
| Yield | R1,628 | yield |
| Revenue | R1,427.2M | revenue_r — ACTUAL |
| Fuel uplift | 26.637M L | fuel_uplift — ACTUAL |
| Fuel R/L delivered | R26.52 | avg_fuel_per_liter_uplifted — ACTUAL |
| Fuel cost | R706.5M | fuel_r — ACTUAL |
| Non-fuel cost | R683.5M = total_costs − fuel_r | derived |
| Total costs | R1,390.1M | total_costs — ACTUAL |
| PBT | R43.7M | pbt_r — ACTUAL |
| Reconciliation check | revenue − fuel − non_fuel = R37.2M vs pbt_r R43.7M | gap R6.56M |
| Non-fuel/flight | R128,797 | (apr non_fuel_total) / apr flights — used for May |
| L/flight | 5,019 | apr fuel_uplift / apr flights — used for May |
| Lens | Result |
|---|---|
| Per-pax yield recovery | R299 ÷ R378 = 79% |
| Per-flight rev recovery | R50K ÷ R59K = 85% |
| Network revenue ÷ fuel hike | R194M ÷ R288M = 67% |
| Total absorption (rev + nonfuel saving) ÷ fuel hike | R228M ÷ R288M = 79% |
Step 1 — April actual delivered R/L anchor:
Apr fuel_r = R706.54M (kpi_data fuel_r)
Apr fuel_uplift = 26.637M L (kpi_data fuel_uplift)
Apr actual R/L = 706.54M ÷ 26.637M = R26.5200/L
Step 2 — May fuel R/L derivation (M2 priority chain):
Priority 1 (preferred): May MTD actual avg_fuel_per_liter_uplifted from kpi_data.json
→ Used when present: NOT AVAILABLE — fell through to IATA estimate
Priority 2: Apr actual R/L × (IATA×FX latest) / (IATA×FX Apr)
Priority 3: Apr actual R/L × IATA ratio only (FX unavailable)
Priority 4: Apr actual × 0.97 (IATA unavailable; B4i-corroborated 3% ease)
Actual source used: Apr actual R26.52 × IATA ratio (162.89/167.96=0.9698). USD/ZAR not available — excluded from scaling. CAVEAT: monthly contracts lag IATA weekly spot.
April IATA $/bbl reference = 167.96
Latest IATA $/bbl = $162.89 (May 08, Data Fuel.xlsx)
May base R/L result = R25.7200
CAVEAT (M2): IATA-scaled estimates assume supplier contracts track IATA weekly spot. Monthly contracts lag IATA weekly; April delivered R26.52 rose while IATA fell in that period. A Rand move can flip the sign of the implied R/L change. This estimate is directional. Superseded by May MTD actual delivered R/L (priority 1) when kpi_data.json is updated.
Step 3 — B4i corroboration (direction check): May B4i tariff data shows broad decreases: Astron −332cpl, Shell −215cpl, PetroSA −171cpl, Engen −222cpl. This corroborates the downward IATA direction. Base R/L of R25.72 is anchored to actual April R26.52 minus documented easing.
Step 4 — Scenario band: Opt = base − R1.50 = R24.22 Base = R25.72 Pess = base + R2.00 = R27.72
| Metric | Value | Source |
|---|---|---|
| Period | May 2026 MTD (14 days, through 14 May) | dashboard_data.json |
| Flights | 2222 | dashboard_data.json |
| Pax | 336517 | dashboard_data.json |
| Revenue | R531.8M | dashboard_data.json |
| Yield | R1,580 | dashboard_data.json |
| LF | 80.2% | dashboard_data.json |
May MTD LF is a partial-month observation (~14 days). Bookings continue to mature. The full-month projection uses April actual full-month LF as the maturity proxy.
May MTD LF = 80.2% (from dashboard_data.json kpis_mtd — partial, ~14 days)
April actual LF = 86.6% (from kpi_data.json months[3] load_factor — ACTUAL full month close)
Projection method = MTD 80.2% @14d → full-month 86.6% using April actual full-month close
as maturity proxy; assumes April-like booking maturation
Flag = if May booking pace differs materially from April, this proxy
will over- or under-state full-month LF
Base — MTD actual vs full-month projected:
| Variant | LF | Revenue | Fuel | Non-fuel | PBT | Margin |
|---|---|---|---|---|---|---|
| [live MTD] | 80.2% | R1,204M | R649M | R648M | R-93M | -7.7% |
| [full-month proj] | 86.6% | R1,300M | R649M | R648M | R3M | 0.2% |
| Parameter | Value | Basis |
|---|---|---|
| Flights | 5,031 | May schedule |
| Seats | 950,475 | May schedule |
| L/flight | 5,019 | Apr actual fuel_uplift ÷ Apr flights |
| Non-fuel/flight | R128,797 | Apr actual (total_costs−fuel_r)÷flights |
| Non-fuel total | R648M | 5,031 × R128,797 |
| Scenario | Fuel R/L | Yield | LF | Revenue | Fuel | Non-fuel | PBT | Margin |
|---|---|---|---|---|---|---|---|---|
| Optimistic | R24.22 | R1,628 | 82.2% | R1,272M | R612M | R648M | R12M | 1.0% |
| Base case [live MTD] | R25.72 | R1,580 | 80.2% | R1,204M | R649M | R648M | R-93M | -7.7% |
| Pessimistic | R27.72 | R1,533 | 78.2% | R1,139M | R700M | R648M | R-209M | -18.3% |
| Base [full-month proj] | R25.72 | R1,580 | 86.6% | R1,300M | R649M | R648M | R3M | 0.2% |
Assertion: (revenue − total_costs) ≈ pbt_r.
Gap = non-operating IS items (finance costs, tax, other income) not captured in total_costs.
Warn gate: max(R15M, 1% revenue) — amber NOTE in report.
Fail gate: R50M — red WARNING block in report.
| Month | rev − costs | pbt_r | Gap | other_is | Warn gate | Status |
|---|---|---|---|---|---|---|
| Mar | R97.2M | R127.4M | R30.2M | R30.2M | R15.0M | WARN |
| Apr | R37.2M | R43.7M | R6.6M | R6.6M | R15.0M | PASS |
Identity: revenue_Δ − fuel_hike + nonfuel_saving + other_IS_movement = −pbt_drop
Revenue increase: +R193.7M
Fuel hike: −R288.1M
Non-fuel saving: +R34.3M
Other IS movement: R-23.7M (apr_other_is=R6.6M, mar_other_is=R30.2M)
PBT drop: −R83.7M
Bridge check: R288.1M ≈ R288.1M
fuel_r, fuel_uplift, total_costs, pbt_r). No estimates used.CONSTANTS dict in build_report.py.Generated 2026-05-16 · build_report.py · MC-3483/MC-3517