From raw signals to one price, with the working shown
Every night, the engine runs this loop for 365 nights × 4 room types: 1,460 decisions. Pick a night and follow one decision through the pipeline. The numbers below are the engine's own working, not illustrations.
- 1 Read the signals
- 2 Forecast demand
- 3 Estimate price response
- 4 Optimise contribution
- 5 Apply the guardrails
- 6 Explain and publish
- 7 Learn from what happened
Read the signals
Production adds weather, DMK–KOP flight seats, Thai–Lao bridge traffic and booking-engine searches. In the PoC these signals are synthetic.
Forecast demand
The forecast predicts unconstrained demand: how many rooms we would sell with unlimited inventory. It blends two views and trusts the bookings more as the stay date gets closer.
Estimate price response
How many fewer rooms do we sell if we charge more? That is price elasticity, and it differs by night. Festival guests barely react to price; a drive-in family on a rainy Tuesday reacts a lot.
For this night the engine uses sensitivity β = 1.12. Pace ahead of the curve reads as lower sensitivity. About 0.5 more rooms are expected at today's price.
Optimise contribution
The optimizer scores every price on the ladder: expected extra rooms × (price − 9.7% commission − THB 380). It maximises contribution, not occupancy or ADR alone.
| Step | Price | Extrarooms | Contribution | vs published |
|---|---|---|---|---|
| -2 | 1,490 | 0.5 | 512 | −15 |
| -1published | 1,610 | 0.5 | 527 | +0 |
| 0chosen | 1,740 | 0.5 | 538 | +11 |
| +1 | 1,880 | 0.4 | 544 | +17 |
| +2 | 2,030 | 0.4 | 544 | +18 |
Apply the guardrails
The optimizer proposes; the GM's rules decide what is allowed. These rules are signed by people, and you can change them in the Strategy studio.
- Stay inside the tier band (THB 1,490–2,030)
Checked, not binding - Move at most 1 step a day
Applied to this decision - No price drop inside 14 days on A/A+ nights
Checked, not binding - A/A+ moves inside 7 days need the revenue manager
Applied to this decision - Keep room categories ≥ 8% apart
Checked, not binding
Explain and publish
- Chulalongkorn Day long weekend sets this night to tier A.
- On the books: 49 of 50 rooms, +9% vs the tier-A booking curve at 2 days out.
- One step up to THB 1,740 adds about THB 11 expected contribution.
- Explains each move in one plain sentence for the RM, in Thai or English.
- Maps messy PMS export columns during upload.
- Drafts candidate local events (fairs, seminars) for the GM to confirm.
- Never sets the price. Prices come from the forecast, optimizer and rules, so they are repeatable and auditable.
In the PoC the reasons are generated from templates.
Learn from what happened
Stop-rules keep it safe: if forecast error goes above 10% for two weeks, or the RevPAR index drops under 95, every decision goes back to "recommend only" until people re-sign the rules.
PoC today vs production
| Component | In this PoC | In production |
|---|---|---|
| Data | Synthetic hotel, deterministic | PMS, channel manager, POS, rate shopper, events, weather |
| Demand forecast | Pickup model + seasonal prior | Gradient-boosted trees, P10/P50/P90, retrained weekly |
| Price response | Hand-set sensitivity per tier | Bayesian elasticity per segment × tier, learned from price tests |
| Optimizer | Contribution search over the ladder | Same, plus multi-night displacement |
| Packages | Ranking from prior acceptance rates | Contextual bandit learning from bookings |
| Explanations | Template text | Claude, Thai and English |
| Publishing | Nothing is sent | Channel-manager push (OpenTravel XML) |