RevNLabs

Projects

Dynamic Pricing to anticipate demand and guide rates

A Dynamic Pricing component being designed for a short-term rental PMS. It links demand anticipation to rate decisions. The figures are fictitious and do not report commercial results.

An iKeeLabs project. Dynamic Pricing is a component being designed for a property management system. Huu Huy Truong leads its AI and data architecture. The figures use fictitious data.

Category
iKeeLabs project
Role
Huu Huy Truong — AI & Data Architecture
Stage
In design
  • .NET
  • Python
  • LightGBM
  • Azure Machine Learning
  • MLflow
  • Microsoft Foundry
  • Azure AI Search
  • Channex
  • Property Management
  • Dynamic Pricing
  • Applied AI

A calendar that is still mostly empty can make it feel as though nothing is urgent. Yet an international marathon may be taking shape a few kilometres away, a trade show may be approaching, or the next school holidays may change how people stay. Future demand may already be present in those signals, before it appears in the manager's reservations.

For a short-term rental management company, the question is which price to offer for each night, on the basis of which information, and with what level of risk. Raising a rate too early can slow sales. Keeping a rate too low can let nights go that would have found a guest on better terms.

RevNLabs is an iKeeLabs project. The Dynamic Pricing service described here is a component being designed for a PMS, the software used to manage properties and their reservations. It aims to connect anticipation of the market with the manager's decisions. The figures below are fictitious. They explain the approach. They do not claim commercial results.

Anticipating periods of demand

Some market shifts are prepared a long time in advance. Tourist seasons, the year-end holidays and school holidays provide reference points. Recurring events provide another kind of visibility: a marathon, a festival or an international fair can draw visitors with specific accommodation needs.

Those reference points do not justify a uniform increase. Christmas does not have the same effect in a ski resort and in a business district. A trade show may matter mostly to properties that are well connected to the exhibition grounds. A festival that offers its own camping does not necessarily create the same demand as a professional event of comparable size.

The approach is therefore to estimate a usual demand for a destination and a period, then to study what the event may change. The comparison has to take previous editions into account and avoid counting twice a peak that is already present in the seasonal history.

This anticipation stays open to revision. The fact that an event recurs guarantees neither the exact dates nor the scale of its next edition.

Estimating accommodation needs

A number of visitors is not enough to measure accommodation needs. Part of the audience lives locally. Other people come for the day, stay with friends or relatives, or choose a solution offered by the organiser. Visitors who book a property may share an apartment and stay for several nights.

The path therefore runs, step by step, from the expected attendance to accommodation needs by night and by area. The length of stays matters as much as the day of the event: some arrivals come before it opens and some departures follow it.

Take the fictitious Harbor City marathon. For one night in the area under study, the demonstration scenario estimates:

  • A usual demand of 650 properties.
  • An additional need linked to the event of 540 properties.
  • A supply of 900 properties for that night.

The illustrated total demand therefore reaches 1,190 properties. Demand above supply signals possible pressure. It does not mean that 1,190 reservations will be made, or that every property will find a guest at any price.

Location, access and property type remain decisive. A neighbourhood forecast still has to be interpreted for each property.

Revising the forecast as information arrives

Six months before the event, the manager mainly has historical recurrence and an expected period. Three months before, dates and elements of the organisation may be confirmed. One month out, the pace of reservations and new information about the event can sharpen the scenario. One week out, the remaining availability and recent changes carry more weight.

The anticipation view lets the manager move across these horizons and see how the forecast changes. New information can strengthen the scenario, call it into question, or widen the range of possible outcomes. Getting closer to the event does not guarantee that everything becomes more certain.

One rule is essential: at each observation date, only information that is already available may enter the analysis. An announcement published in May must not be used to explain a decision supposed to have been taken in February.

Explore the diagram. On smaller screens, scroll sideways for details.

Scroll sideways to read the whole figure. Synthetic data, not a production forecast.

Mode
Observe at
Demand Anticipation & Seasonal Intelligence Illustrative dynamic pricing view for a multi-tenant PMS. Mode: Recurring event (Harbor International Marathon), observed at D−30. Zone Alpha, Harbor City. Forecast for 19 Jun 2027: baseline 650, additional event demand 540, total 1,190 accommodation units, supply 900. Synthetic data, not a production forecast. Demand Anticipation & Seasonal Intelligence Anticipate accommodation demand in a zone before it appears in the manager’s bookings. TENANT-DEMO · Harbor City · Zone Alpha · APT-042 · Europe/Paris Illustrative model · Synthetic data · Not a production forecast A · PREDICTABLE DEMAND SIGNALS Seasonal patterns Summer holidays Jul – Aug Christmas & New Year 24 Dec – 1 Jan School holidays published calendars Public holidays & long weekends fixed + moveable Recurring events Recurring ≠ next edition certain Harbor International Marathon In forecast Recurrence Annual · 14 editions Next edition 2027 · confirmed Dates 19 Jun 2027 (conf.) Estimated scale 18k–22k unique (est.) Location Waterfront · Zone Alpha Information available Dates pub. D−120 Harbor Sound Festival Recurrence Annual · 9 editions Next edition 2027 · confirmed Dates 16–18 Jul 2027 (conf.) Estimated scale 28k–32k unique (est.) Location North Docks Information available Dates pub. D−200 Harbor Trade Expo Recurrence Biennial · odd years Next edition 2027 · unconfirmed Dates ~Oct 2027 (est.) Estimated scale 8k–12k unique (est.) Location Expo Centre · Zone Gamma Information available Venue TBC D · ANTICIPATION TIMELINE Observation date, not stay dates · data published later is excluded Observing on 20 May 2027 8/10 sources D−180 21 Dec D−90 21 Mar D−30 20 May D−7 12 Jun C · FORECAST DEMAND BY NIGHT · ZONE ALPHA Recurring event · Harbor International Marathon 19 Jun 2027 Sat night · Event day Seasonal baseline 650 Additional event demand +540 Total forecast demand 1,190 Accommodation supply 900 Demand exceeds supply by 290 units · occupancy capped at 100% · estimated need, not bookings 0 200 400 600 800 1,000 1,200 1,400 1,600 Accommodation units demanded per night Stay date (night of) 17 JunThu 18 JunFri 19 JunSat 20 JunSun 21 JunMon Event day 735 890 1,190 900 735 Supply · 900 Low–high scenarios Forecast incl. event Seasonal baseline B · FROM ATTENDANCE TO ACCOMMODATION DEMAND Select a step to inspect its assumption 01EST.Uniquevisitors20,000unique, not entries 02ASSUMPTIONFrom outsidethe region60%= 12,000 people 03ASSUMPTIONUse commerciallodging50%= 6,000 guests 04ASSUMPTIONAveragestay3 nights= 18,000 guest-nights 05ASSUMPTIONPersonsper unit2.0= 9,000 unit-nights 06ASSUMPTIONZone Alpha share& night profile20%= 1,800 unit-nights 07ASSUMPTIONBaseline overlap& displacement−25%= 1,350 unit-nights City-wide gross 9,000 unit-nights Zone Alpha gross 1,800 unit-nights Net additional · Zone Alpha 1,350 unit-nights Night profile 10% · 20% · 40% · 20% · 10% → 135 · 270 · 540 · 270 · 135 units 1,350 unit-nights = sum over 5 nights, not 1,350 extra physical units. Attendance ≠ accommodation demand · Unique visitors ≠ cumulative entries · −25% is a teaching hypothesis DETAIL What is known at D−30 · 20 May 2027 · Central scenario: 20,000 unique visitors. · Registrations 12,400 to date (not visitors). · Synthetic booking pace in line with forecast. · Aviation context: indirect signal, not local nights. 8 of 10 sources published by this date. Sources PRICING REVIEW Review suggested Forecast exceeds supply on 19 Jun; near supply 18 Jun, 20 Jun. Rates may be re-examined within tenant rules (floors, ceilings, min stay). Revenue manager decides · no automatic price change · no revenue estimate. Confirmed fact Estimate Manual assumption Data published after the observation date never enters the displayed forecast · Aviation context · IATA integration planned (indirect signal) iKeeLabs Illustrative model · Synthetic data · Not a production forecast
RevNLabsDemand Anticipation & Seasonal IntelligenceThe drawing separates the seasonal reference demand, the expected effect of the event and the information available at each horizon. The time control shows what the manager could reasonably anticipate at that moment.

Testing a decision before changing rates

A forecast becomes useful to the business when it helps examine a concrete choice. What happens if the event draws fewer visitors? If the pace of reservations slows? If an assumption about air traffic changes? If the owner wants to keep a rate ceiling?

The "What if" simulator is there to explore these questions. The manager changes an assumption and sees the nights concerned, the associated forecast and the rate recommendation. Manual assumptions stay identifiable, and distinct from confirmed facts.

In the teaching model used for the simulator, a raw recommendation reaches €167 for one night. A demonstration ceiling brings it back to €160. When the event is switched off, with everything else held equal in this simulation, the recommendation becomes €149.

These amounts come from an illustrative formula. They show the logic of a decision, not an optimal price validated on a real market. The simulator makes it possible, in particular, to see why a stronger demand signal may stop changing the price once the ceiling applies.

Explore the diagram. On smaller screens, scroll sideways for details.

WHAT-IF CONTROLS · SYNTHETIC SIMULATION · NOT A TRAINED PRICING MODEL

Toggle the event or move a slider: the blue curve, the shaded gap to the reference, the calendar and the values update. Click a night (or use the arrow keys) to inspect it.

index points, −20 to +30
−10 to +20 · fictitious data, IATA connection planned
€ per night, €120 to €200
Dynamic Pricing What-If Simulator Deterministic, pedagogical what-if simulation for listing APT-042 (tenant TENANT-DEMO, Europe/Paris), nights of 16 to 22 June 2027. Synthetic simulation, not a trained pricing model. For each night a unitless demand index is the sum of a base of 100, a calendar contribution, a booking pace contribution, an event contribution (+25 on 18, 19 and 20 June when the event is active) and an aviation proxy contribution based on fictitious data, bounded between 50 and 220. The unconstrained rate is round(120 × [1 + 0.006 × (index − 100)]); the recommended rate bounds it between €80 and the selected ceiling. The published rate stays at €120 and is shown separately. Initial state: event on, booking pace +18, aviation proxy +10, ceiling €160, night of 19 June selected: demand index 165, unconstrained rate €167, recommended rate €160 (ceiling applied). The fixed reference curve uses event off, booking pace +18, aviation +10, ceiling €160 (19 June: index 140, recommended €149). The demand index is not an occupancy rate; no revenue gain, booking probability or confidence interval is estimated. {"context": {"property": "APT-042", "tenant": "TENANT-DEMO", "timezone": "Europe/Paris", "year": 2027, "month": 6, "monthLabel": "June"}, "nights": [16, 17, 18, 19, 20, 21, 22], "weekdays": ["Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue"], "model": {"base": 100, "calendar": [0, 0, 8, 12, 6, 0, 0], "event": {"nights": [18, 19, 20], "contribution": 25}, "pace": {"min": -20, "max": 30}, "aviation": {"min": -10, "max": 20, "note": "fictitious data · IATA connection planned"}, "index": {"min": 50, "max": 220}, "publishedRate": 120, "slope": 0.006, "floor": 80, "ceiling": {"min": 120, "max": 200}}, "initial": {"night": 19, "event": true, "pace": 18, "aviation": 10, "ceiling": 160}, "reference": {"event": false, "pace": 18, "aviation": 10, "ceiling": 160}, "geometry": {"x0": 135, "dx": 140, "yBottom": 860, "yTop": 410, "vMin": 60, "vMax": 220, "cellX0": 70, "cellY0": 140, "cellW": 130, "cellH": 170, "barZero": 1400, "barPxPerPt": 4}} Dynamic Pricing What-If Simulator APT-042 · TENANT-DEMO · Europe/Paris · Nights 16–22 June 2027 · Published rate €120 / night, kept separate from recommendations Synthetic simulation · Not a trained pricing model Deterministic pedagogical model · Aviation data fictitious NIGHTS · JUNE 2027 Recommended rate and demand index per night · select a night Wed 16 Jun · night 16→17 €140 = ref vs ref index 128 Event +25 Ceiling applied Thu 17 Jun · night 17→18 €140 = ref vs ref index 128 Event +25 Ceiling applied Fri 18 Jun · night 18→19 €160 +€14 vs ref index 161 Event +25 Ceiling applied Sat 19 Jun · night 19→20 €160 +€11 vs ref index 165 Event +25 Ceiling applied Sun 20 Jun · night 20→21 €160 +€16 vs ref index 159 Event +25 Ceiling applied Mon 21 Jun · night 21→22 €140 = ref vs ref index 128 Event +25 Ceiling applied Tue 22 Jun · night 22→23 €140 = ref vs ref index 128 Event +25 Ceiling applied RATE PER NIGHT · € PER NIGHT Current scenario · recommended Fixed reference · recommended Unconstrained rate, above ceiling Published Ceiling Scenario = fixed reference €160 · raw €167 €60 €80 €100 €120 €140 €160 €180 €200 €220 € per night Wed 16 Jun Thu 17 Jun Fri 18 Jun Sat 19 Jun Sun 20 Jun Mon 21 Jun Tue 22 Jun Night of (date, June 2027 · Europe/Paris) Published rate €120 · unchanged Ceiling €160 Fixed reference: event off · booking pace +18 · aviation proxy +10 · ceiling €160. Shaded area = gap between scenario and reference. Recommendations are never auto-published. SELECTED NIGHT Sat 19 June 2027 Night 19→20 June · Europe/Paris Demand index 165 unitless · 50 to 220 Unconstrained rate €167 €/night · unbounded Recommended rate €160 +€11 vs reference Ceiling applied Unconstrained €167 is above the €160 ceiling, so the recommendation is held at €160. Published rate · unchanged €120 Recommendation · current scenario €160 Recommendation · fixed reference €149 DEMAND INDEX BUILD-UP index points · unitless, not occupancy Base demand 100 Calendar +12 Booking pace +18 Event +25 Aviation proxy* +10 +20 0 −20 Sum of contributions 165 Demand index (50–220) 165 bound applied DETERMINISTIC DEMO MODEL demandIndex = clamp(Σ contributions, 50, 220) rawRate = round(120 × [1 + 0.006 × (index − 100)]) recommendedRate = clamp(rawRate, €80, ceiling) SCENARIO Event on · Booking pace +18 · Aviation proxy +10 · Ceiling €160 *Aviation proxy data are fictitious; the IATA data connection is planned, not live. The demand index is unitless and is not an occupancy rate. No revenue gain, booking probability or confidence interval is estimated. Synthetic simulation · Not a trained pricing model

RevNLabsDynamic Pricing What-If SimulatorThe simulator compares a reference scenario with a modified hypothesis. It separates the rate calculated before constraints, the final recommendation and the rate currently published.

The recommended rate is not yet an applied rate. The validation policy has to state what the system may publish automatically, what requires a review, and the limits that belong to the portfolio. The bounds shown in the demonstration are not rules imposed on the product.

Understanding a recommendation

An amount on its own answers a manager or an owner poorly. Why does this night deserve particular attention? Which elements influence the forecast? Why does the recommendation stop at this level?

A useful explanation separates three levels.

The first concerns the factors the model uses to forecast demand. The second concerns the rules that bound the rate, such as a ceiling. The third brings the documentary context: which event is involved, where it takes place, and which information is confirmed.

This distinction avoids confusing a cautious recommendation with weak demand, or an interesting piece of information with a factor that is actually used in the calculation.

Explore the diagram. On smaller screens, scroll sideways for details.

Explainable Pricing Decision Explainability view of one pricing decision for listing APT-042 (tenant TENANT-DEMO, Europe/Paris), night of 19 June 2027, forecast produced on 20 May 2027. All values are fictitious and do not constitute measured results. Zone 1, model contributions: an illustrative SHAP-style waterfall in demand index points (not computed SHAP values, not euros, not causal effects): baseline 100, calendar effect +12, booking pace +18, local event +25, aviation proxy +10, final demand index 165. Zone 2, pricing rules: reference rate €120, unconstrained recommendation €167 from the pedagogical formula round(120 × [1 + 0.006 × (165 − 100)]), demo maximum rate €160, final recommendation €160; the currently published rate €120 is kept separate and unchanged. Zone 3, evidence and explanation: a short generated explanation grounded only in these values, citing fictitious references DEMO-PMS-042, DEMO-EVT-017 and DEMO-AVIATION-01; aviation is an indirect signal and IATA is an envisaged integration. Interaction: Tab to move between elements, Enter or Space to select, arrow keys within a zone, Escape to clear. One detail panel shows the selection. {"context": {"property": "APT-042", "tenant": "TENANT-DEMO", "night": "2027-06-19", "timezone": "Europe/Paris", "forecastDate": "2027-05-20", "disclaimer": "All values are fictitious and do not constitute measured results."}, "demand": {"unit": "Demand index points", "baseline": 100, "contributions": {"cal": 12, "pace": 18, "event": 25, "avia": 10}, "final": 165, "check": "100 + 12 + 18 + 25 + 10 = 165"}, "pricing": {"referenceRate": 120, "slope": 0.006, "raw": 166.8, "unconstrained": 167, "demoMaximum": 160, "final": 160, "published": 120, "formula": "round(120 × [1 + 0.006 × (165 − 100)]), then min(·, 160)"}, "panel": {"nameWidth": 330, "valueWidth": 170, "sourceWidth": 300, "availableWidth": 170, "transformWidth": 408, "emptyKind": "Nothing selected", "emptyName": "Select an element", "emptySource": "Zone 1: a bar · Zone 2: a rate row or the €160 ceiling · Zone 3: a reference or a sentence", "emptyTransform": "Click a contribution to see its value, source, availability date and transformation. Click the ceiling to see the €167 → €160 gap. Click a reference to highlight the sentences it supports."}, "items": {"contrib-base": {"group": "contrib", "kind": "Zone 1 · Model contribution · starting point", "name": "Baseline demand index", "value": "100 index points", "source": "DEMO-PMS-042 · fictitious PMS history for APT-042", "available": "2027-05-20 (forecast date)", "transform": "Reference level of the index, 100 by convention. Starting point of the waterfall. Not a euro amount, not an occupancy rate.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "contrib-cal": {"group": "contrib", "kind": "Zone 1 · Model contribution · illustrative", "name": "Calendar effect", "value": "+12 index points", "source": "Calendar features derived from the stay date (no external document)", "available": "Known in advance · used on 2027-05-20", "transform": "Saturday night in June mapped to calendar features → illustrative +12 points. Running total 100 → 112.", "refs": [], "transformLabel": "TRANSFORMATION"}, "contrib-pace": {"group": "contrib", "kind": "Zone 1 · Model contribution · illustrative", "name": "Booking pace", "value": "+18 index points", "source": "DEMO-PMS-042 · on-the-books snapshot", "available": "2027-05-20 (snapshot at forecast date)", "transform": "Bookings on the books for the night compared with a reference pace → illustrative +18 points. Running total 112 → 130.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "contrib-event": {"group": "contrib", "kind": "Zone 1 · Model contribution · illustrative", "name": "Local event", "value": "+25 index points", "source": "DEMO-EVT-017 · fictitious event-feed entry, 18–20 June 2027", "available": "2027-03-02", "transform": "Event active on the night and in scope of the property → illustrative +25 points. Running total 130 → 155.", "refs": ["DEMO-EVT-017"], "transformLabel": "TRANSFORMATION"}, "contrib-avia": {"group": "contrib", "kind": "Zone 1 · Model contribution · illustrative · indirect signal", "name": "Aviation proxy", "value": "+10 index points", "source": "DEMO-AVIATION-01 · fictitious indirect aviation indicator", "available": "2027-05-18", "transform": "Regional-airport context mapped to an indicator → illustrative +10 points. Running total 155 → 165. Not a passenger count; IATA integration envisaged, not connected.", "refs": ["DEMO-AVIATION-01"], "transformLabel": "TRANSFORMATION"}, "contrib-final": {"group": "contrib", "kind": "Zone 1 · Model output → input of zone 2", "name": "Final demand index", "value": "165 index points", "source": "Sum of the baseline and the four contributions", "available": "2027-05-20 (forecast date)", "transform": "100 + 12 + 18 + 25 + 10 = 165 index points. Feeds the pricing rules. Contributions are illustrative, not computed SHAP values, and not causal effects.", "refs": ["DEMO-PMS-042", "DEMO-EVT-017", "DEMO-AVIATION-01"], "transformLabel": "TRANSFORMATION"}, "rate-ref": {"group": "rate", "kind": "Zone 2 · Pricing rule input", "name": "Reference rate", "value": "€120 per night", "source": "DEMO-PMS-042 · rate configuration", "available": "2027-05-20", "transform": "Anchor of the pedagogical formula: a demand index of 100 corresponds to €120.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "rate-unc": {"group": "rate", "kind": "Zone 2 · Pricing rule output · before cap", "name": "Unconstrained recommendation", "value": "€167 per night", "source": "Pedagogical formula applied to the index 165", "available": "Computed on 2027-05-20", "transform": "round(120 × [1 + 0.006 × (165 − 100)]) = round(120 × 1.39) = round(166.8) = €167.", "refs": [], "transformLabel": "TRANSFORMATION"}, "rate-cap": {"group": "rate", "kind": "Zone 2 · Pricing rule · ceiling", "name": "Demo maximum rate (ceiling)", "value": "€160 per night", "source": "DEMO-PMS-042 · demo rate rule", "available": "2027-05-20", "transform": "Cap rule: final = min(unconstrained, €160). Gap shown in zone 2: €167 − €160 = €7 removed by the ceiling.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "rate-rec": {"group": "rate", "kind": "Zone 2 · Recommended (not published)", "name": "Final recommendation", "value": "€160 per night", "source": "Pedagogical formula, then ceiling", "available": "Computed on 2027-05-20", "transform": "min(€167, €160) = €160. A recommendation only: +€40 versus the published rate, not published automatically.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "rate-pub": {"group": "rate", "kind": "Zone 2 · Published (unchanged)", "name": "Currently published rate", "value": "€120 per night", "source": "DEMO-PMS-042 · published rate snapshot", "available": "2027-05-20", "transform": "Rate currently live. It is kept separate from the recommendation and is not changed automatically.", "refs": ["DEMO-PMS-042"], "transformLabel": "TRANSFORMATION"}, "ref-DEMO-PMS-042": {"group": "ref", "kind": "Zone 3 · Fictitious reference", "name": "DEMO-PMS-042", "value": "Fictitious PMS extract", "source": "Fictitious PMS extract · APT-042", "available": "2027-05-20", "transform": "Supports S1, S2, S4, S5 (highlighted in zone 3).", "supports": ["s1", "s2", "s4", "s5"], "transformLabel": "SUPPORTS"}, "ref-DEMO-EVT-017": {"group": "ref", "kind": "Zone 3 · Fictitious reference", "name": "DEMO-EVT-017", "value": "Fictitious event-feed entry", "source": "Fictitious event-feed entry · 18–20 Jun 2027", "available": "2027-03-02", "transform": "Supports S1, S2 (highlighted in zone 3).", "supports": ["s1", "s2"], "transformLabel": "SUPPORTS"}, "ref-DEMO-AVIATION-01": {"group": "ref", "kind": "Zone 3 · Fictitious reference", "name": "DEMO-AVIATION-01", "value": "Fictitious indirect aviation indicator", "source": "Fictitious indirect aviation indicator", "available": "2027-05-18", "transform": "Supports S1, S3 (highlighted in zone 3). Indirect signal; IATA integration envisaged.", "supports": ["s1", "s3"], "transformLabel": "SUPPORTS"}, "sentence-s1": {"group": "sentence", "kind": "Zone 3 · Generated sentence S1", "name": "Sentence S1", "value": "Grounded", "source": "DEMO-PMS-042 · DEMO-EVT-017 · DEMO-AVIATION-01", "available": "—", "transform": "The scenario shows a demand index of 165, above the baseline of 100.", "refs": ["DEMO-PMS-042", "DEMO-EVT-017", "DEMO-AVIATION-01"], "transformLabel": "TEXT"}, "sentence-s2": {"group": "sentence", "kind": "Zone 3 · Generated sentence S2", "name": "Sentence S2", "value": "Grounded", "source": "DEMO-EVT-017 · DEMO-PMS-042", "available": "—", "transform": "The local event (+25) and the booking pace (+18) contribute to this increase.", "refs": ["DEMO-EVT-017", "DEMO-PMS-042"], "transformLabel": "TEXT"}, "sentence-s3": {"group": "sentence", "kind": "Zone 3 · Generated sentence S3", "name": "Sentence S3", "value": "Grounded", "source": "DEMO-AVIATION-01", "available": "—", "transform": "The aviation proxy (+10) is an indirect signal; IATA is an envisaged integration.", "refs": ["DEMO-AVIATION-01"], "transformLabel": "TEXT"}, "sentence-s4": {"group": "sentence", "kind": "Zone 3 · Generated sentence S4", "name": "Sentence S4", "value": "Grounded", "source": "DEMO-PMS-042", "available": "—", "transform": "The formula gives €167; the demo maximum rate then limits the rate to €160.", "refs": ["DEMO-PMS-042"], "transformLabel": "TEXT"}, "sentence-s5": {"group": "sentence", "kind": "Zone 3 · Generated sentence S5", "name": "Sentence S5", "value": "Grounded", "source": "DEMO-PMS-042", "available": "—", "transform": "The published rate remains €120; the recommendation is not published automatically.", "refs": ["DEMO-PMS-042"], "transformLabel": "TEXT"}}} iKeeLabs · DYNAMIC PRICING · EXPLAINABILITY Explainable Pricing Decision APT-042 · TENANT-DEMO · Night of Sat 19 → Sun 20 June 2027 · Europe/Paris · Forecast produced on 20 May 2027 Synthetic data · Fictitious values · Not measured results Forecast → rules → explanation · three separate layers Illustrative contributions · Not computed SHAP values Unit: Demand index points 0 50 100 150 100 Baseline demand +12 100→112 Calendar effect +18 112→130 Booking pace +25 130→155 Local event +10 155→165 Aviation proxy* 165 Final index Check: 100 + 12 + 18 + 25 + 10 = 165 ✓ Not euros · not causal effects Pedagogical formula · not a production pricing model round(120 × [1 + 0.006 × (165 − 100)]) = round(120 × 1.39) = round(166.8) = €167 then ceiling: min(€167, €160) = €160 €100 €120 €140 €160 €180 € per night · shared scale Reference rate · input €120 Unconstrained recommendation · formula €167 Demo maximum rate · ceiling rule €160 Final recommendation RECOMMENDED €160 Currently published PUBLISHED €120 €167 − €160 = €7 above the ceiling Recommended ≠ published · nothing is published automatically Generated explanation · grounded only in zones 1–2 S1 The scenario shows a demand index of 165,above the baseline of 100. ✓ S2 The local event (+25) and the booking pace(+18) contribute to this increase. ✓ S3 The aviation proxy (+10) is an indirectsignal; IATA is an envisaged integration. ✓ S4 The formula gives €167; the demo maximumrate then limits the rate to €160. ✓ S5 The published rate remains €120; therecommendation is not publishedautomatically. ✓ No added statistics · no causal claim · fictitious references REFERENCES · FICTITIOUS DEMO-PMS-042 Fictitious PMS extract · APT-042 2027-05-20 S1 · S2 · S4 · S5 DEMO-EVT-017 Fictitious event-feed entry · 18–20 Jun 2027 2027-03-02 S1 · S2 DEMO-AVIATION-01 Fictitious indirect aviation indicator 2027-05-18 S1 · S3 Aviation is an indirect signal · IATA is an envisaged integration DETAIL · ONE SELECTION AT A TIME Select an element Nothing selected Tab · Enter / Space · ← → within a zone · Esc clears VALUE — SOURCE Zone 1: a bar · Zone 2: a rate row orthe €160 ceiling · Zone 3: a referenceor a sentence AVAILABLE — HOW TO USE Click a contribution to see its value, source,availability date and transformation. Click theceiling to see the €167 → €160 gap. Click a referenceto highlight the sentences it supports. All values are fictitious and do not constitute measured results. Contributions are illustrative (not computed SHAP values), expressed in demand index points, never in euros, and are not demonstrated causal effects. iKeeLabs · dp04
RevNLabsExplainable Pricing DecisionThe drawing separates the forecast factors, the pricing constraints and the documents that inform the decision. The contributions shown in the demonstration are not measurements from a trained model.

Traceability also makes it possible to revisit a decision after the stay. The manager can find the information that was available, the constraints that were applied and any human interventions, rather than judging an old choice with what is known today.

Steering a portfolio with clear priorities

For a company managing several destinations, this approach aims to concentrate attention on the periods and properties that deserve a review. An important event, a fragile forecast or a change of pace can justify a priority check.

The aim is not to multiply price changes. It is to make commercial policy more consistent, to make the conversation with owners easier, and to reduce the monitoring and comparison work done by hand.

The value will have to be measured in operation: time spent on rate review, net revenue relative to nights that can be sold, occupancy, and respect for the owners' constraints. None of these indicators should be read alone. A property filled earlier, or sold at a higher price, does not automatically imply a better overall result.

Predictive and generative models

The functional views rest on several complementary mechanisms. Their role is easier to understand when numerical forecasting, document analysis and explanation are kept distinct.

Numerical forecasting

Machine learning learns relationships from historical data. It can examine how the season, the lead time before the stay, the pace of reservations and characteristics of events are associated with a measurable target.

That target has to be defined precisely. Observed reservations do not describe all potential demand: a property that is already sold can no longer record further requests. A demand index also needs a definition and a method of validation.

The target architecture envisages Python models, in particular of the LightGBM type, with Azure Machine Learning for training and operation, and MLflow to track versions. Microsoft positions Azure Machine Learning on this cycle of custom models, and Foundry on generative applications and agents. Microsoft Learn

Forecasting demand pressure is not, however, enough to find an optimal price. The response of guests to different price levels also has to be understood. A historical association between high prices and strong sales does not prove that an increase will produce more revenue.

Explainability tools such as SHAP help show the factors of a prediction. On their own, they do not demonstrate a causal effect. If the model predicts a demand index, its contributions explain that index, not extra euros directly. SHAP documentation

Document analysis and context

Generative AI can help turn an event description into usable information: dates, place, category or an indication of scale. That information then has to be checked before it feeds the forecasts. A supposed next edition must not become a confirmed date simply because a model phrased it that way.

Aviation data is another possible source of context. IATA offers, in particular through AirportIS, historical traffic data and future flight schedules. The integration under consideration still has to specify the accessible product, its granularity, its frequency and its terms of use. Seats offered or expected passengers do not correspond directly to local nights. IATA AirportIS

Explanations tied to their sources

RAG, for Retrieval-Augmented Generation, means retrieving relevant information before asking a language model to write an answer. In this project it would bring the event documents, the calculated decision and the manager's question closer together.

Microsoft Foundry and Azure AI Search are envisaged for this generative and documentary layer. The search has to respect the management company's scope, the dates and the location. The presence of sources improves the possibility of verification, but it does not remove the need to evaluate the answers. Microsoft Learn on RAG

The numerical calculation keeps its own logic. The .NET backend remains responsible for authorisation, pricing constraints and publication through the Channex adapter. A generated text must not become a sufficient instruction to change a price.

Evaluating forecasts and pricing decisions

A convincing demonstration has to be followed by an evaluation on suitable data. For the forecast, that means in particular holding out periods the model did not use for learning, then replaying successive decisions through time. This approach is called backtesting. Microsoft Learn on forecast evaluation

Each forecast must use only the information available on its original date. A PMS-data approach can then be compared with an approach enriched by events and external signals, on an observable target and under the same evaluation conditions.

Generative explanations need other checks: fidelity to the calculated results, relevance of the documents, absence of invented figures, and respect for authorisations. Good writing quality does not replace the accuracy of the forecasting model.

Finally, a smaller forecast error does not yet prove a commercial gain. That gain will have to be examined in a progressive experiment, with suitable comparisons and operational indicators. The fictitious scenarios make the behaviour understandable. They replace neither this validation nor the economic measures.

A better informed commercial decision

The Dynamic Pricing described here aims to give the manager a reading of the market ahead, a way to examine assumptions, and an explanation of the recommendations.

Seasonality and events provide early reference points. Reservations and new information make it possible to revise them. Predictive models organise these signals, while generative AI can make them easier to use and to understand.

The criterion of success remains the management decision: knowing why a night deserves particular attention, which information supports that choice, and when it should be reviewed.

Sources