This framework defines how product prices are adjusted under two distinct pricing contexts:
- Platform based pricing (structural, long-term discounts)
- Promotional pricing (short-term, event-based discounts)
Both modes share common guardrails (margin protection, discount caps, rounding), but differ in how the target discount is derived.
The objective is consistent, explainable pricing decisions under operational constraints.
Pricing decisions are not about finding a single “optimal” price. They are about navigating trade-offs between margin protection, inventory risk, and commercial governance.
This project demonstrates how pricing decisions can be:
- policy-driven, but adaptive
- explainable to non-technical stakeholders
- constrained by real business guardrails
| Term | Definition |
|---|---|
| List Price | Reference price before any discount |
| Cost | Unit cost of the product |
| Margin | (price − cost) / price |
| Discount | 1 − (price / list_price) |
| Margin Floor | Minimum acceptable margin |
| Max Discount | Absolute upper bound on discount |
| Rounding Step | Price granularity (e.g. 1, 5, 10) |
All prices are evaluated relative to list price and cost, without VAT, FX, or country-specific adjustments.
Maintain a stable, policy-driven discount while gradually increasing aggressiveness if sell-through lags behind expectations.
This mode reflects strategic pricing, not urgency.
For each product:
- Compute current margin from list price and cost
- Observe progress against an expected sell-through trajectory
- Estimate time pressure (e.g. weeks behind target or distance to end-of-life)
A revised target margin is computed as:
revised_margin =
current_margin
− (time_pressure × margin_decay_rate)
margin_decay_rate represents how much margin can be sacrificed per unit of time pressure.
Time pressure is capped to avoid extreme reactions.
The revised margin is constrained by:
revised_margin = max(
margin_floor,
min(revised_margin, current_margin)
)
This ensures:
- Margins never drop below a strategic floor
- Prices never increase as a result of the adjustment
The revised margin is converted back into a price, then rounded to the nearest allowed step.
The output is a recommended platform based price.
Maximize sell-through during short promotional windows while strictly respecting margin and governance constraints.
This mode reflects tactical pricing under urgency.
For each product, compute:
- Margin-based discount ceiling (derived from margin floor)
- Governance-based discount ceiling (category / lifecycle cap)
The maximum feasible discount is the minimum of these constraints.
Inventory pressure is mapped into discrete tiers:
| Stock Pressure | Effect |
|---|---|
| Low | No uplift |
| Medium | Moderate discount uplift |
| High | Aggressive discount uplift |
This signal influences how close the discount moves toward the feasible maximum.
A target discount is proposed based on stock pressure and promo intensity, then clamped:
final_discount = min(
proposed_discount,
margin_based_max,
governance_max
)
This makes the binding constraint explicit.
The discounted price is computed from list price and rounded according to pricing rules.
The output is a promo-specific price, valid only for the event window.
To keep the framework focused on decision logic, the following are intentionally omitted:
- VAT and tax handling
- FX conversion
- Country-specific pricebooks
- Brand-level contractual exceptions
- Platform-specific operational rules
These elements increase operational complexity but do not change the core decision structure.
Although both modes share guardrails, they answer different questions:
| Mode | Core Question |
|---|---|
| Platform Based | “How should prices evolve over time if sell-through deviates from plan?” |
| Promo | “How aggressive can we be right now without breaking constraints?” |
Keeping these strategies distinct is essential for explainability and governance.
For each product, the framework produces:
- A recommended platform based price
- A recommended promotional price
- An explicit explanation of which constraint is binding
| Column | Type | Example | Notes |
|---|---|---|---|
product_id |
string | P000123 |
synthetic ID |
category |
string | Shoes |
used for discount caps / policy |
platform |
string | Platform_A |
for platform based policy differentiation |
lifecycle_stage |
string | new, core, end_of_life |
controls floors/caps |
list_price |
float | 250.0 | base price |
unit_cost |
float | 110.0 | must be < list_price |
stock_on_hand |
int | 45 | drives stock pressure |
avg_weekly_sales |
float | 2.3 | used to derive “time pressure” proxy |
weeks_to_eol |
int | 18 | used in platform based TM mode |
target_sell_through |
float | 0.55 | target by now (0–1) |
actual_sell_through |
float | 0.42 | current (0–1) |
max_discount |
float | 0.60 | governance cap (0–0.8) |
margin_floor |
float | 0.10 | floor (0–0.3) |
rounding_step |
int | 5 | 1/5/10 |