From Inventory Optimization to Profit: Accounting KPIs, Working Capital and Explainable Recommendations

A forecast that is accurate and an inventory policy that is efficient are still not the same as a business that is profitable. This second part adds the missing layer: turnover and accounting KPIs to measure the financial impact of inventory decisions, and explainability to show managers why the system recommends what it recommends. We continue with the same supermarket example.

What you will learn
  • The difference between sales turnover and inventory turnover, and how GMROI, inventory days, and working capital relate to each other.
  • Why fill rate and cycle service level are different, with a worked example.
  • How accounting numbers (margin, cost, salvage value) set the newsvendor critical fractile.
  • How to compare policies financially, including marginal returns on extra inventory.
  • How to explain forecasts (SHAP), order decisions, and financial trade-offs.
Sales, stock,purchasing, accountingDemand forecastquantilesSimulate andoptimize policiesFinancial andservice KPIsExplain andmonitorTeal predicts, amber decides and measures, navy supplies and explains.
Figure 1. The extended framework. We no longer optimize inventory in isolation: every decision is measured financially and explained.

1. Two meanings of "turnover"

In retail, turnover can mean two different things, and both matter.

1.1 Sales turnover: revenue

If the supermarket sells 100 units at €5, revenue is \(R_t=P_t\,S_t=5\times100=500\text{ euros}\). For several products:

$$R_t=\sum_{j=1}^{J}P_{j,t}\,S_{j,t}$$

where \(j\) indexes products, \(P_{j,t}\) is the price, and \(S_{j,t}\) the units sold in period \(t\). Revenue is not profit: cost of goods, labor, waste, and financing still have to be paid. In financial statements, the exact definition also depends on VAT, discounts, and returns, so align your data with the company's reporting rules.

1.2 Inventory turnover: how fast stock sells and is replaced

$$\text{Inventory turnover}=\frac{\text{COGS}}{\text{Average inventory value (at cost)}}$$
TermMeaning
COGSCost of goods sold: the accounting cost of the products sold in the period
Average inventory valueAverage value of stock held during the period, measured at cost

With COGS of €360,000 and average inventory of €60,000, turnover is 6: the retailer sells and replaces its stock about six times a year.

Two common pitfalls

Mixed valuation: COGS is at cost, so average inventory must be at cost too, never at selling price. Crude averages: averaging only opening and closing stock misleads for seasonal products. Use monthly or daily snapshots.

Higher turnover often means less cash tied up in stock, but higher is not always better. If it is high because shelves are empty, sales are being lost. Always read turnover next to service level and profitability.

2. Accounting KPIs: connecting operations to profit

A better forecast or a lower stockout rate does not automatically raise profit. Extra inventory buys availability, but it also ties up cash. We need financial KPIs to judge each policy.

2.1 Gross profit, gross margin, and markup

A product sells at €5 and costs €3. For 100 units: revenue €500, \(COGS=c\times S=300\text{ euros}\), and:

$$GP=R-COGS=200,\text{ euros}\qquad GM=\frac{R-COGS}{R}=40\%,\qquad \text{Markup}=\frac{GP}{COGS}=\frac{200}{300}=66.7\%$$

Margin and markup are easy to confuse. Margin is a share of revenue; markup is a share of cost. They are linked by \(\text{Markup}=GM/(1-GM)\). Gross profit is also not net profit: it excludes warehousing, labor, transport, and financing.

2.2 GMROI: gross profit per euro of stock

Gross Margin Return on Inventory Investment measures how much gross profit each euro of average inventory generates:

$$GMROI=\frac{\text{Gross profit}}{\text{Average inventory at cost}}$$

With €120,000 of annual gross profit and €40,000 of average inventory, GMROI is 3: €3 of gross profit per €1 invested in stock. It is not a 300% net return, because it ignores all costs below gross profit.

Key identity $$GMROI=\underbrace{\frac{COGS}{\text{Avg inventory}}}_{\text{inventory turnover}}\times\underbrace{\frac{GP}{COGS}}_{\text{markup}}$$

A product earns a high GMROI through fast turnover, a fat markup, or both. This is why a low-margin product that sells very fast can beat a high-margin product that sits on the shelf.

GMROI = 3.0gross profit ÷ average inventoryInventory turnover = 7.0COGS ÷ average inventoryMarkup = 0.43gross profit ÷ COGS×Inventory days = 52365 ÷ turnoverGross margin = 30%markup = margin ÷ (1 − margin)
Figure 2. The KPI tree, using Policy A from section 7: 3.0 = 7.0 × 0.43. Inventory days and gross margin are two further ways to read the same numbers.

Here is a two-product comparison (illustrative values):

KPIProduct AProduct B
Annual revenue€100,000€100,000
COGS€70,000€75,000
Gross profit€30,000€25,000
Average inventory at cost€10,000€20,000
Inventory turnover7.03.75
GMROI3.01.25

Same revenue, but A earns more gross profit with half the stock. A forecasting and replenishment system can use this to find where better decisions would free working capital. Still, treat GMROI as a performance KPI, not as the objective of every optimization: maximizing a ratio can push a model to sacrifice sales or service just to shrink the denominator.

3. Working capital: money tied up in stock

3.1 Inventory value and its carrying cost

Holding 1,000 units at €3 each means €3,000 of capital in stock: \(V=I\times c\). Cutting average stock to 700 units, without hurting sales, releases \(\Delta V=(1000-700)\times 3=900\text{ euros}\). That is cash freed, not profit earned.

Holding inventory also has a running cost, usually expressed as an annual rate \(i\) on inventory value:

$$h_{\text{year}}=c\times i,\qquad \text{where } i\text{ covers cost of capital, storage, insurance, shrinkage, obsolescence}$$

At an illustrative \(i=10\%\), the €900 released saves about €90 a year. This is how the holding cost \(h\) from the simulation (Part 8 of the first guide) connects to accounting.

3.2 Inventory days and the cash conversion cycle

$$DIO=\frac{\text{Average inventory}}{COGS}\times T=\frac{T}{\text{Inventory turnover}}$$

With €60,000 of average inventory, €360,000 of annual COGS, and \(T=365\): \(DIO=60{,}000/360{,}000\times365\approx60.8\) days. This equals \(365/6\), as the identity says. Cutting DIO from 60 to 30 days may be great for a predictable item with a reliable supplier, and dangerous for a seasonal item with a long lead time.

Inventory days are one piece of the cash conversion cycle:

$$CCC=DIO+DSO-DPO$$
TermMeaningSupermarket example
DIODays inventory outstandingabout 61 days
DSODays sales outstanding (time to collect from customers)about 0, customers pay at checkout
DPODays payables outstanding (time to pay suppliers)30 days, if suppliers allow it
CCCDays cash is tied upabout 31 days

Better replenishment lowers DIO, but negotiating payment terms moves DPO. Both change how long cash is tied up, so a finance team may value them differently.

4. Service-level KPIs: the customer side

Financial metrics alone can mislead. A retailer can raise turnover and release cash simply by running out of stock. Operational KPIs keep the optimization honest.

4.1 Fill rate and unmet demand

$$\text{Fill rate}=\frac{\text{Units fulfilled immediately}}{\text{Units demanded}},\qquad \text{Unmet-demand rate}=\frac{\text{Unmet units}}{\text{Units demanded}}$$

If customers demand 1,000 units in a week and 950 are supplied immediately, the fill rate is 95% and the unmet-demand rate is 5%. For these unit-based definitions they sum to 100%. Other metrics called "stockout rate" may not: a stockout-event rate, for instance, counts the share of product-days with zero stock. Some companies also measure fill rate on order lines rather than units. Always state the definition.

4.2 Cycle service level is not fill rate

These two are often mixed up, and they can differ a lot:

$$\text{CSL}=P(D\leq S),\qquad \beta=1-\frac{\mathbb{E}[(D-S)^+]}{\mathbb{E}[D]}$$

CSL is the probability of no stockout in a cycle. The fill rate \(\beta\) is the share of units served, so it depends on how large the shortages are, not just how often they happen. For normal demand, \(\mathbb{E}[(D-S)^+]=\sigma\,L(z)\) with \(z=(S-\mu)/\sigma\) and \(L(z)=\varphi(z)-z\,(1-\Phi(z))\), where \(\varphi\) and \(\Phi\) are the standard normal density and CDF.

Worked example

Single period, demand \(\mathcal{N}(100,20^2)\), stock \(S=130\). Then \(z=1.5\), so CSL \(=\Phi(1.5)=93.3\%\). The loss function is \(L(1.5)=0.1295-1.5\times0.0668=0.0293\), so expected shortage is \(20\times0.0293=0.59\) units, and:

$$\beta=1-\frac{0.59}{100}\approx99.4\%$$

The same stock gives a 93.3% chance of no stockout, but 99.4% of units are served.

50%60%70%80%90%100%100110120130140150160Order-up-to level S (units)Service levelcycle service level 93.3%fill rate 99.4%demand ~ Normal(100, 20²), single period
Figure 3. Same stock, two service levels. When a business says "95% service", ask which definition it means.

This is why the constraint in an optimization problem must name its metric. \(\operatorname{FillRate}(\pi)\geq0.95\) and \(\operatorname{CSL}(\pi)\geq0.95\) lead to very different inventory levels.

5. A KPI dashboard in three groups

GroupKPIDefinition
Financial performanceRevenuePrice × units sold
Gross profit and marginRevenue − COGS; gross profit ÷ revenue
GMROIGross profit ÷ average inventory at cost
Inventory-related costsHolding, ordering, waste, markdowns
Capital efficiencyAverage inventory valueAverage units × unit cost
Inventory turnoverCOGS ÷ average inventory at cost
Inventory daysAverage inventory ÷ COGS × days in period
Operational performanceFill rateUnits fulfilled immediately ÷ units demanded
Stockout frequencyShare of product-days with zero stock
Waste rateWasted units ÷ relevant quantity base
Supplier lead-time performanceActual versus promised lead times

Tracking all three groups stops a model from looking successful by improving one metric while damaging another.

6. How accounting numbers set the critical fractile

In the first guide, the newsvendor order is the quantile \(\tau^*=C_u/(C_u+C_o)\). Accounting data tells you what \(C_u\) and \(C_o\) are:

$$C_u=\underbrace{p-c}_{\text{lost unit margin}}+g,\qquad C_o=\underbrace{c-s}_{\text{loss on a leftover unit}}+h$$

where \(p\) is price, \(c\) unit cost, \(s\) salvage value of a leftover unit (markdown or resale), \(g\) a goodwill cost of disappointing a customer, and \(h\) holding cost.

Case\(C_u\)\(C_o\)Critical fractile
Fresh item, €5 price, €3 cost, no salvage230.40
Same item, markdown salvage of €2.5020.500.80
Fresh item, no salvage, €1 goodwill cost330.50
0.40.60.81.00.511.522.533.54Overage cost Co: loss per leftover unit (€)Critical fractileno salvage: Co = 3, fractile 0.40markdown salvage: Co = 0.5, fractile 0.80underage cost fixed at Cu = 2 (€5 price, €3 cost)
Figure 4. The more a leftover unit costs, the lower the fractile: with no salvage, the best order is below the median of demand.

This is a useful result for managers: a product with thin margin and no resale value should be stocked below median demand, even though it will sometimes sell out. A product with good margin or an easy markdown deserves a large buffer. It also shows that one service-level target for every product is rarely optimal. These formulas assume a single period; in multi-period lost-sales systems, a stockout also costs future sales, which raises \(C_u\).

7. Putting KPIs inside the simulation

For each simulated period, we compute revenue \(R_t=\sum_jP_{j,t}S_{j,t}\), gross profit \(GP_t=R_t-COGS_t\), and the inventory-related cost:

$$C_{\text{inventory}}=C_{\text{holding}}+C_{\text{ordering}}+C_{\text{shortage}}+C_{\text{waste}}$$
Avoid double counting

If gross profit is already computed after lost sales, do not subtract the lost revenue again as a shortage cost. Decide whether \(C_{\text{shortage}}\) represents an extra economic cost (such as customer dissatisfaction) or a substitute for the lost margin, and use only one.

7.1 Two policies compared

Policy A is conservative: smaller orders, less stock, more stockout risk. Policy B is availability-focused: larger orders, more stock, fewer stockouts. Hypothetical annual simulation results:

KPIPolicy APolicy B
Revenue€500,000€520,000
COGS€350,000€364,000
Gross profit€150,000€156,000
Average inventory at cost€50,000€70,000
Inventory turnover (COGS ÷ inventory)7.05.2
GMROI (gross profit ÷ inventory)3.02.23
Fill rate91%97%
Inventory-related costs outside COGS€15,000€18,000
Gross profit minus those costs€135,000€138,000

Note which numerator each KPI uses: turnover uses COGS, GMROI uses gross profit. Mixing them up is a classic bug in KPI pipelines; \(364{,}000/70{,}000=5.2\) while \(156{,}000/70{,}000=2.23\).

Policy B wins on revenue, gross profit, fill rate, and net contribution (by €3,000). Policy A wins on turnover, GMROI, and capital use. Which is better depends on constraints and the cost of capital.

7.2 Marginal analysis: is the extra inventory worth it?

Moving from A to B adds €20,000 of stock and €6,000 of gross profit, a marginal return of 0.30 per euro invested, before costs. After the extra €3,000 of costs, it is €3,000 on €20,000, a 15% return on the additional capital. If the cost of capital is not already inside those costs and is, say, 10%, subtract \(0.10\times20{,}000=2{,}000\text{ euros}\): B's advantage shrinks from €3,000 to €1,000. The comparison with the cost of capital is what decides.

Returns usually diminish. Take three target levels (hypothetical):

Target inventoryGross profitAverage inventoryFill rate
100 units€150,000€50,00091%
115 units€153,000€58,00094%
130 units€156,000€70,00097%
€148k€150k€152k€154k€156k€158k€50k€60k€70kAverage inventory at costAnnual gross profittarget 100: fill rate 91%target 115: fill rate 94%target 130: fill rate 97%+€0.375 gross profit per extra € of stock+€0.25 per extra €
Figure 5. Each extra euro of stock earns less than the last: €0.375 per euro from 100 to 115 units, then €0.25 from 115 to 130 (before other costs).

7.3 Computing the KPIs in code

def kpis(revenue, cogs, avg_inventory_cost, units_demanded,
         units_fulfilled, other_costs, days=365):
    gp = revenue - cogs
    return {
        "gross_profit": gp,
        "gross_margin": gp / revenue,
        "inventory_turnover": cogs / avg_inventory_cost,
        "inventory_days": days * avg_inventory_cost / cogs,
        "gmroi": gp / avg_inventory_cost,
        "fill_rate": units_fulfilled / units_demanded,
        "contribution": gp - other_costs,
    }

# Policy A from the table: turnover 7.0, GMROI 3.0, contribution 135,000
print(kpis(500_000, 350_000, 50_000, 100_000, 91_000, 15_000))

8. Explainability, level 1: why this demand forecast?

Managers will ask: why is demand so high for this product? Why order 150 and not 100? Why did GMROI drop while fill rate improved? There are three different things to explain, and they should not be confused: the forecast, the order decision, and the financial consequences.

8.1 SHAP values for a quantile forecast

SHAP splits one prediction into a baseline plus a contribution from each feature:

$$f(x)=\phi_0+\sum_{j=1}^{p}\phi_j$$

where \(\phi_0\) is the baseline prediction (the average over the reference data), \(p\) the number of features, and \(\phi_j\) the contribution of feature \(j\) for this instance. Suppose the model predicts the 80th percentile of demand, \(\hat Q_{0.80}(x)=130\), with a baseline of 100:

FeatureContribution
Baseline prediction100
Active promotion+18
Weekend+8
Recent sales trend+10
Higher price−6
Prediction130
90100110120130140Predicted Q0.80 (units)100Baseline+18Promotion+8Weekend+10Sales trend−6Higher price130Predictionvertical axis starts at 90 to make the contributions visible
Figure 6. Waterfall view of the same table. Contributions add up exactly to the prediction: 100 + 18 + 8 + 10 − 6 = 130.
import shap

explainer = shap.TreeExplainer(models[0.80])   # explain the 0.80 quantile model
phi = explainer.shap_values(X_row)             # shape (1, n_features)
base = float(np.ravel(explainer.expected_value)[0])
print(base + phi.sum(), models[0.80].predict(X_row))   # the two should match
What SHAP does and does not tell you
  • It explains how the trained model produces a prediction. It does not prove that the promotion caused the extra demand.
  • Explain the specific quantile being used. The promotion may add 18 units at Q0.80 but far more at Q0.95, because promotions also widen uncertainty. For a quantile-conditioned model \(f_\theta(x,\tau)\), state the \(\tau\) being explained.
  • Strongly correlated features (price and promotion, for example) share credit in ways that can surprise people. Say so when presenting.
  • Per-prediction (local) SHAP values explain one decision. Averaging their absolute values over time (global importance) is also a useful monitoring signal.

9. Explainability, level 2: why this order quantity?

Suppose the forecast says 130 but the system orders 75. This is not a contradiction: the forecast estimates demand, while the order depends on what you already have. With a target of 130 and an inventory position of 55:

$$O_t=\max(0,\,S-IP_t)=\max(0,\,130-55)=75$$
On hand 35On order 20Order now: 75inventory position IP = 55target S = 130 (the Q0.80 demand forecast)Order = S − IP = 130 − 55 = 75 units
Figure 7. Splitting the target into stock already available (35 on hand and 20 on order, assumed for illustration) and the new order.

SHAP explains the forecast; it does not explain this step. For decisions, expose the policy logic itself:

The model estimates an 80th-percentile demand of 130 units for the planning period. The current inventory position is 55 units (35 on hand, 20 on order). Under the order-up-to policy, the target is 130, so the system recommends ordering 75 units. The 80th percentile comes from the chosen cost and service-level assumptions.

10. Explainability, level 3: why is this financially attractive?

A manager may object: "Inventory turnover is going down, so why hold more stock?" The answer must rest on measured trade-offs. Compare the proposed policy with a baseline:

$$\Delta KPI=KPI_{\text{new}}-KPI_{\text{baseline}}$$

From the table in section 7.2, moving from target 100 to 130 changes gross profit by \(\Delta GP=6{,}000\text{ euros}\), inventory by \(\Delta V=20{,}000\text{ euros}\), and fill rate by six percentage points. A counterfactual explanation puts it in words:

Raising the target from 100 to 130 units is estimated to add €6,000 of annual gross profit and six points of fill rate, while adding €20,000 of average inventory. An intermediate target of 115 units gets half of that gross profit gain with €8,000 of extra stock.

Managers often find this more useful than a feature-importance chart. But these figures must come from a properly designed simulation or backtest, and they are estimates, not guarantees. A change in gross profit is also not a change in net profit: include every relevant incremental cost.

11. Explainability, level 4: how reliable is it?

A recommendation is more useful with its uncertainty attached. Report the distribution of each KPI across simulated scenarios (for example the 10th to 90th percentile), not just the mean. Then stress the assumptions that matter most:

Sensitivity testWhat changesQuestion answered
Lead time +1 daySupplier delayDoes fill rate stay above the target?
Demand +10% or −10%Forecast biasHow fragile is the order-up-to level?
Cost of capital doubledFinancing environmentDoes the higher-stock policy still pay?

The four levels together:

LevelQuestionMethod
ForecastWhy this demand quantile?SHAP, feature analysis, calibration checks
DecisionWhy this order quantity?Explicit policy rules, inventory-position breakdown, constraints
FinancialWhy is it attractive?KPI deltas, counterfactual scenarios, marginal analysis
UncertaintyHow reliable is it?Scenario distributions, intervals, sensitivity tests

Instead of "Recommended order: 130 units", the system can say: "Target 130 (80th-percentile demand), driven mainly by the promotion and recent trend. Inventory position is 55, so order 75. Simulation estimates a 97% fill rate versus 91% under the current policy, with uncertainty from demand variability and model error."

12. A fuller optimization objective

The first guide minimized expected cost. A retailer may prefer to maximize expected profit under operational limits:

$$\max_{\pi\in\Pi}\ \mathbb{E}\bigl[R(\pi)-COGS(\pi)-C_{\text{other}}(\pi)\bigr]\quad\text{s.t.}\quad \operatorname{FillRate}(\pi)\geq\alpha,\quad \mathbb{E}[V_{\text{inventory}}(\pi)]\leq B$$
SymbolMeaning
\(\pi\), \(\Pi\)An inventory policy and the set of feasible policies
\(R(\pi)\), \(COGS(\pi)\)Revenue and cost of goods sold under \(\pi\)
\(C_{\text{other}}(\pi)\)Other relevant costs: holding, ordering, waste, shortage
\(\alpha\)Minimum required fill rate
\(V_{\text{inventory}}(\pi)\), \(B\)Inventory value under \(\pi\), and the permitted maximum

Turnover and GMROI work better as constraints, reporting metrics, or secondary objectives than as terms in one weighted score. Otherwise the optimizer may exploit the chosen KPI at the expense of overall value.

Key idea: spending a shared inventory budget

With thousands of products sharing a budget \(B\), the best allocation equalizes the marginal gross profit per euro of stock across products: \(\partial\,\mathbb{E}[GP_j]/\partial V_j\approx\lambda\) for every product \(j\) that gets stock, where \(\lambda\) is the shadow price of the budget. Figure 5 is that idea for one product: stop adding stock when the next euro earns less than \(\lambda\), or less than your cost of capital.

13. Implementing it as a data science project

  1. Data engineering: reconcile sales, catalog, prices, promotions, inventory snapshots, purchase orders, lead times, product costs, and accounting data under consistent product IDs, periods, and cost definitions.
  2. Forecasting: a point baseline, quantile models, and optionally a full distributional model, validated on held-out data.
  3. Inventory simulation: demand scenarios, stock, replenishment, lead times, lost sales or backorders, holding, ordering, and waste costs.
  4. Policy optimization: search reorder points, order-up-to levels, service targets, and order quantities under the constraints above.
  5. KPI computation: revenue, gross profit and margin, turnover, inventory days, GMROI, average inventory value, fill rate, stockout and waste metrics, all matching the company's reporting.
  6. Explainability and monitoring: for each recommendation, show the forecast and its quantile, top features, inventory position, policy and constraints, order quantity, expected KPI changes versus baseline, and uncertainty.

Monitoring should include:

  • Forecast calibration: does the Q0.80 forecast cover about 80% of actual outcomes, by product group?
  • Bias and drift: forecast error over time, and changes in feature distributions or SHAP importance.
  • Simulation versus reality: compare realized fill rate, turnover, and gross profit with what the simulator predicted.
  • Overrides: log when planners reject a recommendation, and why. Patterns in overrides often reveal missing constraints.
  • Censored demand: track stockout days so that low sales caused by empty shelves are not mistaken for low demand when retraining.
  • 14. Final perspective

    With accounting KPIs and explainability, the project becomes a decision-support system for retail operations and financial performance:

    1. Historical sales, inventory, and accounting data.
    2. Demand forecasting and quantile estimation.
    3. Inventory policy and stochastic simulation.
    4. Financial and operational KPI evaluation.
    5. Policy optimization under business constraints.
    6. Explainable recommendations and monitoring.

    The key principle is that forecast accuracy, inventory efficiency, and financial performance are related but not interchangeable. A good forecast estimates demand reliably, a good policy turns it into sensible orders, a good simulation measures the consequences, accounting KPIs quantify the business impact, and explainability lets managers understand and trust the result.

Comments

Popular posts from this blog

Automate Blog Content Creation with n8n and Grok 3 API

LangGraph Tutorial: Understanding Concepts, Functionalities, and Project Implementation

Kaggle Tutorial · Data Science in Retail