Three prices on every line, and a ledger behind each
A sold line carries three prices: the regular price the item was meant to sell at, the price on the ticket when the sale began, and the price actually charged. The gaps between them are the whole of pricing analytics. Regular minus charged is markdown. Ticket minus charged plus any line discount is the POS markdown. An override reason explains why the ticket price was not the ledger price. If those three prices are not stored on the line, every markdown and promotion measure has to be reconstructed afterwards, and it will be wrong.
The Cybex Pricing & Promotion dataset is five facts on one item and one calendar. One is the price ledger: what each item is priced at, where, from when. One is the events that change it, as dated batches. One is the sold price, line by line. One is the markdown position, the styles that need a price decision. One is promotion performance, what a promotion returned against what would have happened anyway. Nothing here is specific to one retailer: price levels, regions, discount types, batch codes and rounding rules are mapped to generic values at load time.
Five facts, one item and one calendar
| Fact | Grain | Question it answers | Loaded from |
|---|---|---|---|
| Price ledger | One row per SKU, price level or region, and effective date | What is this item priced at, where, and since when? | Item master prices, price level and region tables, applied batches, web price feed |
| Price events | One row per batch; one row per batch and item beneath it | What changed, when, by how much, on what basis, and who approved it? | Markdown and promotion batches, price updates and changes, promotion templates, rounding rules |
| Sold price | One row per ticket line | What was charged versus regular and ticket price, and why? | Ticket lines with regular, original and charged price, discount type, coupon, override reason |
| Markdown position | One row per style, colour and site (or cluster) as of a date | Which styles need a price decision, how deep, and what will it cost? | Stock and cover from the position fact, sell-through and lifecycle from performance, markdown plan from the merchandise plan |
| Promotion performance | One row per promotion, item group, store and period | What did the promotion return against baseline, net of what it took from elsewhere? | Sold price during and around the event, baseline from the demand feature, promotion cost |
Figure: the five facts share item and calendar; the batch that changed a price and the ticket line that sold at it resolve to the same ledger row.
Generic dataset attributes
Attributes are grouped by role. BI marks the ones the markdown workbench, price history and discount reports aggregate; AI marks the ones the elasticity, timing and lift models consume. Most are both.
Price ledger
| Group | Attributes | Notes | Used by |
|---|---|---|---|
| Identity | SKU, Style, Colour, Size, Price level, Price region, Site, Effective date, End date, Currency | A price is keyed by level or region and dated; a site resolves to its level, so store-specific pricing and chain pricing share one ledger. | BIAI |
| Prices | Regular price, Current price, MSRP, Ticket price, Discount prices 1 to 4 (quantity or member tiers), Cost (last, average), Cost retail, Price group | Regular is the basis for retail valuation across the suite; current is what the shelf shows today; the difference is the permanent markdown in force. | BIAI |
| State | Source batch, Batch type (markdown, promotion, regular change), Status (planned, applied, expired, reverted), Applied date, Web price, Web synced flag | Every ledger row points at the batch that created it; a shelf price with no batch is an integrity exception. | BI |
| History | Price at week for the trailing three years (per SKU and site), Price change count, Days at current price, Depth from regular % | Weekly price history is what the elasticity model reads; it is stored, not reconstructed from batches. | AI |
Price events
| Group | Attributes | Notes | Used by |
|---|---|---|---|
| Batch | Batch id, Type (markdown, promotion), Description, Effective date, Expiry date (promotions), Status, Created by, Approved by, Created and applied timestamps, Price region or level, Site scope | A markdown is permanent and has no expiry; a promotion is dated and reverts to the ledger price at expiry. | BIAI |
| Rule | Basis (original retail, current retail), Percent, New price, Rounding rule (none, up, down, nearest), Round-to value, Quantity required, Quantity discounted, Amount required, Amount discounted | Quantity and amount rules express multi-buy and threshold promotions; the rule is stored with the batch so it can be replayed. | BIAI |
| Items | SKU, Style, Colour, Size, Site, Quantity on hand at batch, Regular price, Current price, New price, Markdown per unit, Markdown cost (on hand × depth), Applied flag, Error text | Markdown cost at commit is the number finance wants; it is stored at the batch, not recalculated later against moved stock. | BIAI |
| Template | Promotion template id, Template items and prices, Template reuse count | A saved promotion shape that a new batch can be built from. | BI |
Sold price
| Group | Attributes | Notes | Used by |
|---|---|---|---|
| Identity | Ticket number, Line, Site, Date, SKU, Style, Colour, Size, Customer key (if captured), Cashier, Channel | Same line identity as the sales and audit facts, so a discount finding drills to the same row. | BIAI |
| Three prices | Regular price, Ticket price (original at the till), Charged price, Units, Net sales, Cost, Gross margin | Regular from the ledger as of the sale date; ticket from the price level in force; charged from the line. | BIAI |
| Reductions | Markdown (regular − charged) × units, POS markdown (ticket − charged) × units + line discount, Discount amount, Discount type (percent, dollars, transaction, staff, coupon, local, promo code), Coupon or promo code, Price override reason, Price batch on the line | Markdown separates the permanent price position from the till-time reduction; discount type and coupon carry the promotion back to its batch. | BIAI |
| Flags | Full-price flag, Markdown flag, Promotion flag, Staff flag, Override flag, Programme item flag | Full-price share is charged = regular; a line can be on markdown and on promotion at once. | BIAI |
Markdown position
| Group | Attributes | Notes | Used by |
|---|---|---|---|
| Identity | Style, Colour, Site or cluster, Price region, As-of date, Season, Department, Class, Vendor, Lifecycle stage | As-of dated, rebuilt nightly, so a decision made on Monday can be reproduced on Friday. | BIAI |
| Position | On hand, On hand at retail, On hand at cost, Weeks of supply, Weeks since last receipt, Weeks since last sale, Sell-through, Aged flag (over 13 weeks), Full-price share to date | Cover and age from the store position and performance facts; a style out of stock is not aged, it is sold. | BIAI |
| Plan | Markdown plan for the period (retail), Markdown taken to date, Markdown remaining, Margin plan, Margin to date | The markdown budget comes from the merchandise plan; commits consume it. | BIAI |
| Decision | Candidate flag, Candidate reason (age, cover, sell-through, lifecycle, season end), Recommended depth, Recommended timing, Expected units at depth, Expected margin at depth, Markdown cost at depth, Guardrail state (within, breached) | Depth and timing come from elasticity by class and cluster; the guardrail is a margin floor per class. | AI |
Promotion performance
| Group | Attributes | Notes | Used by |
|---|---|---|---|
| Identity | Promotion (batch), Discount type, Item group, Store or cluster, Period (pre, during, post), Channel, Campaign link (if targeted) | Pre and post windows are stored with the event so pull-forward and post-dip are measured, not assumed. | BIAI |
| Observed | Units, Sales, Margin, Tickets, Units per ticket, Average charged price, Depth realised, Redemptions (coupons), Attach (multi-buy) | From the sold-price fact filtered to the promotion's items, sites and window. | BI |
| Baseline | Baseline units, Baseline sales, Baseline margin, Baseline method (demand feature, control stores, pre-period), Baseline confidence | Baseline is what the item would have sold without the promotion; the method is stored with the result. | AI |
| Result | Lift units, Lift %, Incremental sales, Incremental margin, Cannibalised units (same class, not on promotion), Halo units (other classes), Pull-forward and post-dip, Promotion cost (funding, markdown, coupons), ROI, Elasticity observed | Incremental margin net of cannibalisation and cost is the number that decides whether the promotion runs again. | BIAI |
MarkdownCost(batch) = Σ OnHand × (CurrentPrice − NewPrice) · FullPriceShare = Units(charged = regular) ÷ Units
Lift = Units(during) − BaselineUnits · IncrementalMargin = LiftMargin − CannibalisedMargin − PromotionCost
Functional areas and what each reads
| Functional area | Reads | Deciding attributes | BI output | AI output |
|---|---|---|---|---|
| Price maintenance | Price ledger, Price events | Regular, current, MSRP, level and region, batch status, web sync | Price by region and level; price history per style; unbatched and unsynced exceptions | Price-band consistency checks; regular-price proposals for new styles from comparable items |
| Markdown planning and commit | Markdown position, Price events | Age, cover, sell-through, lifecycle, markdown plan remaining, depth, rounding, guardrail | Markdown workbench: candidates in a pivot by style, colour and site; depth or new price entered; markdown cost; commit as a dated batch | Recommended depth and timing per style and cluster from elasticity; expected margin at each depth; guardrail warnings |
| Promotion planning | Price events, Promotion performance | Templates, multi-buy and threshold rules, effective and expiry, past lift by type | Promotion calendar; templates; batch items and cost; expiry and reversion list | Promotion selection and depth by expected lift; overlap and cannibalisation warnings before the batch is applied |
| Sold-price and discount audit | Sold price | Discount type, coupon, override reason, staff flag, full-price share | Discount analysis by type, store and cashier; price overrides; full-price versus markdown versus promotion mix | Anomalous discounting patterns; overrides that should have been a batch |
| Markdown budget and margin | Markdown position, Sold price | Markdown plan, markdown taken, margin plan and actual | Markdown taken versus plan by class and period; margin rate trend; markdown cadence | Reforecast of season-end markdown need from cover and lifecycle |
| Elasticity and scenarios | Price ledger history, Sold price | Weekly price and units, stockout weeks excluded, class and cluster | Price and volume history charts; realised elasticity by class | Hierarchical elasticity by class and cluster; scenario simulation of depth against margin and sell-through |
| Promotion effectiveness | Promotion performance | Baseline, lift, cannibalisation, halo, cost, ROI | Promotion results by type, store and period; ROI league table; pre, during and post curves | Lift forecasting for planned promotions; baseline modelling; attribution across overlapping events |
| Web price sync | Price ledger, Price events | Web price, web promotion effective and expiry, sync flag | Store versus web price differences; unsynced batches | Channel price-gap alerts |
Rules the dataset carries
Ledger and batch
- No price changes outside a batch. Every ledger row points at the batch that created it, with basis, depth, rounding and approver; a shelf price without a batch is an exception, not history.
- Markdown is permanent, promotion is dated. A promotion reverts to the ledger price at expiry by rule; a markdown becomes the new current price. The two are never confused in a report.
- Regular price is the valuation basis. Retail on hand, markdown and full-price share are measured against regular price, the same basis the plan and the commitments use.
- Markdown cost is stored at commit. Units on hand at the moment of the batch times the depth; it is not recomputed against stock that has since moved.
Sold price
- Three prices on the line. Regular, ticket and charged are stored per line at the time of sale; markdown and POS markdown are derived from them and never from a later ledger lookup.
- Discount type carries the promotion. Every reduction names its type or code, so a promotion's sales are found by code, not by date range alone.
- Overrides are explained. A charged price that matches neither ledger nor batch carries an override reason; unresolved reasons are kept as raw values, never dropped.
Decisions and measurement
- Age and cover decide candidacy; elasticity decides depth. A style is a candidate because of its position; the depth comes from how its class and cluster respond to price.
- Stockout weeks are excluded from elasticity. A week with no stock is not a week with no demand.
- Lift is measured against a baseline with its method stored. Pre and post windows are part of the event so pull-forward and post-dip count; cannibalisation and cost are netted before ROI.
- Guardrails are per class. A margin floor per class is a data attribute the workbench and the model both read.
Process workflow
The pricing cycle is weekly for markdowns and per event for promotions. The Hub keeps the ledger, position and sold-price facts current; pricing and merchandising decide and commit; the AI layer recommends depth and timing ahead of the decision and measures lift behind it.
Cadence
| When | Step | Output | Owner |
|---|---|---|---|
| Continuous | Capture | Sold-price lines; ledger and batch state | POS, web, pricing system |
| Nightly | Load, position, recommend | Ledger history, sold-price fact, markdown candidates with depth and timing, guardrail flags | AI Data Hub |
| Weekly | Decide and commit markdowns | Markdown batches with cost; plan remaining updated | Pricing, merchandising |
| Per event | Plan, execute and measure promotions | Promotion batch, expiry, results with lift and ROI | Marketing, pricing |
| Weekly | Discount audit | Discount analysis by type, store and cashier; overrides | Sales audit |
| Monthly | Learn and tune | Elasticity refresh, guardrail review, promotion type league table | Pricing, data science, finance |
Where BI ends and AI begins
BI on the pricing dataset
AI on the same dataset
Both read the same five facts. The candidate a pricer sees in the workbench is the row the elasticity model scored, and the lift a promotion report shows is computed from the same sold-price lines the audit reads.
What a conforming dataset delivers
Markdowns that are decisions, not events. Candidates come from position, depth from elasticity, cost is known at commit, and every change is a batch with an approver.
Promotions measured as lift. Every event carries its baseline method, pre and post windows, cannibalisation and cost, so ROI is comparable across types and seasons.
One sold-price truth. Three prices on every line feed pricing, planning and audit alike, so markdown $, full-price share and discount analysis never disagree.
Deployment approach
Map price levels and regions, the price columns on the item master, batch types and statuses, discount types and coupon codes, and the rounding rules; confirm the three prices are present on ticket lines.
Build the ledger with weekly history, the batch and item events, and the sold-price fact; tie markdown $ and full-price share to the sales fact; publish price history, discount analysis and the markdown summary.
Build the nightly markdown position from stock, cover and the plan; connect the workbench to it with batch commit and markdown cost; set class guardrails. Train the first elasticity models on the price history.
Add promotion templates, baseline modelling and the performance fact with pre and post windows; run the first measured promotion; switch on depth and timing recommendations and the monthly elasticity refresh.