Hotel pricing engine

Six demand signals set the rate for every room, every night.

Data and BI · Python · Browsable demo

Hotel pricing engine

The problem

A hotel room expires every night: the one empty tonight is not sold tomorrow, it is lost. Price it high and it stays empty, price it low and margin is given away — so the decision repeats daily, per room type.

What it does

  • Encodes the pricing decision as an algorithm built on six demand factors.
  • One of them is booking lead time: a last-minute premium within thirty days.
  • Projects the revenue impact sixty days out.
  • Computes the industry indicators: average daily rate, revenue per available room and occupancy.

What was decided while building it

A safety band the model cannot jump
The final rate is capped between seventy and two hundred and twenty per cent of the base price, whatever the factors do. A multiplicative model with no ceiling produces, on the day high season, weekend, event and last-minute all land together, a price no manager would sign off. The band is what gets signed, and a test refuses to let anything out of it.
The last-minute premium switches off at thirty days
Booking well in advance carries no premium at all: the surcharge grows linearly only inside the last thirty days and tops out at twenty-nine per cent. Charging for advance booking is charging people for planning ahead, which is the opposite of what you want to reward.
Occupancy pressure looks at fourteen days, not yesterday
The last two weeks of occupancy are averaged and turned into three steps: high pressure, normal or slack. Reacting to yesterday's figure turns any noise into a rate change, and a rate that moves every day stops being a pricing policy and becomes an alarm.
The seed is stated, and so is the fact that it is not enough
The generator seeds on import, so two consecutive calls give different numbers: anyone who needs to reproduce a dataset has to re-seed explicitly. There are two tests, one for each side, because promising reproducibility and not testing it is the most common way of not having it.

How far it goes

  • The six factors act on the forecast. The two-year history behind average rate and occupancy uses only three: season, day of week and event.
  • It is not an optimiser. There is no demand curve and no elasticity: expected occupancy is computed without looking at the proposed price, so raising the rate does not lower it. It does not demonstrate that the model increases revenue.
  • Four of the six factors are pure calendar — month, weekday, marked date and lead time — hand-written tables. Only occupancy pressure observes anything, and what it observes is data the script itself generated.
  • The data is synthetic, the event calendar is American and the amounts are in dollars. The dashboard that draws them lives in a different repository.
  • 6 pricing factors
  • 730 days of history
  • 60 days of forecast

Built with

  • Python
  • NumPy
  • React

Where the data comes from

Synthetic data generated by the repository itself: no client information involved.

Backs this service

Power BI dashboards for small businesses

Read the code · Open the demo