Metadata-Version: 2.4
Name: revmng
Version: 0.1.0
Summary: Revenue management for Python: single-leg seat protection (Littlewood, EMSR-a/b), overbooking, pricing, network bid prices and the standard performance metrics. Computed from standard methods and validated against published worked examples.
Author: Atakan Arikan
License: MIT
Project-URL: Homepage, https://github.com/arikanatakan/revmng
Project-URL: Repository, https://github.com/arikanatakan/revmng
Project-URL: Issues, https://github.com/arikanatakan/revmng/issues
Keywords: revenue-management,yield-management,pricing,overbooking,emsr,littlewood,bid-price,newsvendor,airline,hotel,capacity-control,revpar
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: network
Requires-Dist: scipy>=1.7; extra == "network"
Provides-Extra: plot
Requires-Dist: matplotlib>=3.5; extra == "plot"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: scipy>=1.7; extra == "dev"
Requires-Dist: matplotlib>=3.5; extra == "dev"
Dynamic: license-file

# revmng

[![PyPI](https://img.shields.io/pypi/v/revmng.svg)](https://pypi.org/project/revmng/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![CI](https://github.com/arikanatakan/revmng/actions/workflows/ci.yml/badge.svg)](https://github.com/arikanatakan/revmng/actions/workflows/ci.yml)

Revenue management for Python: the building blocks for selling fixed, perishable
capacity well. Single-leg seat protection, overbooking, pricing, network bid
prices and the standard performance metrics, computed from the textbook methods
and validated against published worked examples.

The core has **no third-party dependencies**. Every result carries provenance
(library version, input hash, timestamp) and a JSON-safe `to_dict()`.

```bash
pip install revmng
```

## Quick start

```python
import revmng

# Two-class seat protection (Littlewood's rule)
revmng.littlewood(fare_high=1000, fare_low=400, mean_high=50, sd_high=18)
# -> protect this many seats for the high fare; sell the low fare below it

# Multi-class nested booking limits (EMSR-b, the industry-standard heuristic)
a = revmng.emsr_b(
    [(1000, 30, 12), (700, 40, 15), (400, 60, 20)],   # (fare, demand mean, sd)
    capacity=120,
)
a.booking_limits_int          # nested whole-seat booking limits
print(a.summary())

# Overbooking: balance the cost of bumping against the cost of empty seats
o = revmng.overbooking_limit(100, no_show_rate=0.12,
                             denied_cost=400, spoilage_cost=180)
o.authorization_limit         # how many reservations to accept

# Pricing: the newsvendor stocking quantity and the profit-maximising price
revmng.newsvendor(price=10, cost=4, demand_mean=100, demand_sd=30).optimal_quantity
revmng.optimal_price(revmng.LinearDemand(intercept=100, slope=2), unit_cost=10)

# Score booking limits against perfect-hindsight and no-control benchmarks
revmng.revenue_opportunity([1000, 800, 600, 200], [25, 30, 20, 50], capacity=100,
                           booking_limits=[100, 70, 45, 32]).rom

# Exact optimal protection levels (and the expected revenue EMSR leaves behind)
opt = revmng.optimal_protection_levels(
    [(1000, 30, 12), (700, 40, 15), (400, 60, 20)], capacity=120)
opt.expected_revenue

# Should we take this group? (displacement analysis)
cost = revmng.group_displacement(group_size=30, capacity=100,
                                 demand=[70, 95, 85], value_per_unit=70)
revmng.evaluate_group(group_rate=60, units=90, displacement_cost=cost,
                      variable_cost=50).accept

# Should we accept this multi-night stay? (length-of-stay bid-price control)
revmng.evaluate_stay({"Mon": 80, "Tue": 120, "Wed": 90},
                     ["Mon", "Tue", "Wed"], total_rate=320).accept
```

Network bid prices need SciPy and the charts need matplotlib:

```bash
pip install "revmng[network]"   # bid_prices via the deterministic LP
pip install "revmng[plot]"      # booking-limit, overbooking and ROM charts
```

```python
from revmng import Product
n = revmng.bid_prices(
    [Product(fare=200, uses={"AB": 1}, demand=60),
     Product(fare=300, uses={"AB": 1, "BC": 1}, demand=40)],
    capacities={"AB": 100, "BC": 100},
)
n.bid_prices                       # marginal value of each resource
n.accept(fare=250, uses={"AB": 1, "BC": 1})
```

## What it covers

| Area | Functions |
| --- | --- |
| Single-leg capacity control | `littlewood`, `emsr_a`, `emsr_b` |
| Exact optimal control | `optimal_protection_levels`, `policy_revenue` |
| Overbooking | `overbooking_limit` (service level and cost based) |
| Pricing | `newsvendor`, `optimal_price` (`LinearDemand`, `ConstantElasticityDemand`) |
| Group evaluation | `evaluate_group`, `group_displacement` |
| Length-of-stay | `evaluate_stay` |
| Performance metrics | `revpar`, `adr`, `occupancy`, `yield_`, `load_factor`, `rasm`, `casm`, `spill`, `spoilage` |
| Revenue opportunity | `revenue_opportunity`, `nested_revenue` |
| Network (needs SciPy) | `bid_prices`, `Product` |
| Charts (needs matplotlib) | `booking_limit_chart`, `overbooking_cost_curve`, `revenue_opportunity_chart` |

`optimal_protection_levels` computes the exact optimal nested protection levels
by dynamic programming (the policy the EMSR heuristics approximate) and reports
the optimal expected revenue; `policy_revenue` scores any policy against it.
Group and length-of-stay decisions share one idea: accept a request when its
contribution covers the opportunity cost of the capacity it displaces (a
marginal seat value or a sum of nightly bid prices).

Demand for the capacity-control methods is assumed normal and independent, with
the classic low-before-high booking assumption. EMSR-a and EMSR-b are
heuristics; for two classes both reduce to Littlewood's optimal rule.

## What is out of scope

revmng computes **decisions from the demand you supply**. It does not forecast
demand, estimate willingness-to-pay, or unconstrain censored bookings, and it
does not connect to any reservation, property-management or distribution system.
Those belong upstream; keeping them out is what lets every result here be
reproduced and audited.

## Validation

The methods are checked against published and hand-derived worked examples (see
[`tests/validation_cases.json`](tests/validation_cases.json)):

| Method | Source | Result |
| --- | --- | --- |
| Littlewood booking limits | Phillips, *Pricing and Revenue Optimization* (2005), Ex. 9.2 | 25 / 50 / 76 reproduced |
| Revenue opportunity metric | Phillips (2005), Ex. 9.7 | perfect 66000, no-control 46000, realized 59200, ROM 66% |
| EMSR-b (two classes) | Belobaba (1989) | equals Littlewood's optimal rule |
| EMSR-b (three classes) | Belobaba (1989) formula, arithmetic shown | protection 23.71 / 70.83, limits 97 / 50 |
| Optimal control (DP) | Talluri and van Ryzin (2004) | matches Littlewood for two classes; expected revenue at least EMSR-b's |
| Group displacement | standard displacement analysis, arithmetic shown | 40 displaced room-nights, cost 2800, break-even rate 81.11 |
| Length-of-stay bid price | Talluri and van Ryzin (2004), arithmetic shown | 290 hurdle, accept at rate 320 |
| Newsvendor quantity | critical-fractile rule | reproduced |
| Overbooking (service level) | deterministic no-show formula | reproduced |

### Definitions and methods

- K. Littlewood, "Forecasting and control of passenger bookings" (1972).
- P. Belobaba, "Application of a probabilistic decision model to airline seat
  inventory control," *Operations Research* (1989). EMSR-a and EMSR-b.
- K. Talluri and G. van Ryzin, *The Theory and Practice of Revenue Management*
  (2004).
- R. Phillips, *Pricing and Revenue Optimization* (2005).

## License

MIT. See [LICENSE](LICENSE).
