Algorithmic Pricing &
Profitability
Variables and Identification Plan
This note specifies outcome variables, explanatory dimensions, and identification strategies to evaluate whether algorithmic pricing improves retailer profitability. Emphasis is placed on firm-level financial indicators available in the dataset and on causal methods suitable for staggered adoption across markets.
The study links retailer–product level evidence of algorithmic
pricing on PriceSpy to firm-year financial outcomes. Adoption is
detected at the firm level (AlgoRetailer = 0/1).
Profitability impacts are estimated by comparing adopters with matched
non-adopters using CEM/PSM, supplemented with DiD and SCM designs.
All firm-level monetary variables are expressed in EUR, nominal, after standardising magnitudes and converting currencies as described under “Accounting units and currency standardisation”. Unless stated otherwise, statistics and estimations use the winsorised versions of continuous variables.
Winsorisation (implemented after currency
conversion):
Within year, trim to the 1st/99th percentiles and store
suffixed variables used in matching and regressions:
ROA_W, ProfitMargin_W, SalesPerTA_W, AvgInv_W, InvTurnover_W, DIO_W, SalesGrowth_W, OpProfitGrowth_W, ROAGrowth_W, ProfitMarginGrowth_W, SalesPerTAGrowth_W, DebtRatio_W, LogTA_W, LogSales_W.
(Sensitivity: a stricter variant winsorises within Country×Year; results available on request.)
Treatment
AlgoRetailer (0/1): Firm classified as algorithmic
retailer (treatment group).onPSpy: Indicator of presence on the PriceSpy platform
(treated as 1 when missing for CH rows during integration).Market presence and portfolio
Market coverage: number of categories and products listed (if
aggregated).
Firm identifiers: StoreID, Identifier,
CompanyName.
Identifier: not used in analysis, but included for data
merging and tracking.StoreID: links firm data to PriceSpy records.CompanyName: unique firm identification
(canonical).Contextual dimensions: Country,
Industry, Sector, SectorNew.
Country: one of the seven major markets where PriceSpy
operates.Industry: fine-grained sub-industry classification
(Eikon) and 21 SNI codes (SHOF).Sector: contains empty strings for Swedish data (no
Sector column provided).SectorNew: coarser aggregation of Industry
used for grouping.Scale and structure
TA (total assets), Sales (turnover),
TCap (capital).DebtLT, DebtIntB,
DebtRatio (and DebtRatio_W).Cash,
AccRec, AccPay, Inv,
AvgInv (and AvgInv_W).COGS, Expenses,
Interest, Tax.Construct a control group of non-adopters matched on pre-treatment characteristics. Suggested coarsening:
Notes:
Difference-in-Differences (staggered adoption)
Synthetic Control (SCM) for targeted cases
Sensitivity
We standardise units before computing ratios and growth rates:
Magnitude adjustment
Currency conversion to EUR
SekEur) for the
corresponding year.GbpEur) for the corresponding
year.SekEur/GbpEur columns and proceed to
construct ratios.Order of operations
Implications for interpretation
| Name | Definition / formula | Source |
|---|---|---|
| EBIT | Operating profit before interest & tax | Financial accounts |
| OpProfit | Operating profit (alt. measure) | Financial accounts |
| NetIncome | Profit after tax and financing | Financial accounts |
| Sales | Turnover | Financial accounts |
| TA | Total assets | Financial accounts |
| ROA | OpProfit ÷ TA | Derived |
| ProfitMargin | OpProfit ÷ Sales | Derived |
| SalesPerTA | Sales ÷ TA (asset turnover) | Derived |
| SalesGrowth | ΔSales / Sales (YoY) | Derived |
| ROAGrowth | ΔROA / ROA (YoY) | Derived |
| ProfitMarginGrowth | ΔProfitMargin / ProfitMargin (YoY) | Derived |
| SalesPerTAGrowth | ΔSalesPerTA / SalesPerTA (YoY) | Derived |
| DebtRatio | Debt ÷ TA | Financial accounts |
| AvgInv | Average inventory | Financial accounts |
| InvTurnover | Sales ÷ AvgInv | Derived |
| DIO | Days inventory outstanding | Derived |
| LogTA | log(TA) | Derived |
| LogSales | log(Sales) | Derived |
| *_W variables | Winsorised versions of above (see list) | Derived (trimmed) |
| AlgoRetailer | 0/1 adoption indicator | Platform data |
| onPSpy | Presence on PriceSpy | Platform data |
| Country, SectorNew | Firm context | Metadata |
Notes
We load the harmonised firm–year panel, inspect structure and coverage, and generate a few quick tables.
| Country | Unique algos | Unique on PriceSpy | Unique firms |
|---|---|---|---|
| Denmark | 1 | 10 | 1234 |
| Finland | 1 | 12 | 3403 |
| France | 3 | 24 | 41188 |
| Norway | 2 | 35 | 6863 |
| Sweden | 22 | 374 | 974671 |
| UK | 10 | 50 | 14095 |
| Total | 33 | 493 | 1041443 |
Before turning to the descriptive comparison, we clarify the meaning of key variables:
| Country | Group | Unique firms | ROA | Profit margin | Asset turnover | Log TA | Log Sales |
|---|---|---|---|---|---|---|---|
| Denmark | Non-algo | 10 | -0.109 (0.666) | -0.192 (1.175) | 3.382 (1.759) | 10.619 (1.192) | 11.811 (1.255) |
| Finland | Non-algo | 12 | 0.045 (0.104) | 0.007 (0.060) | 3.609 (2.377) | 9.654 (1.731) | 10.755 (1.584) |
| France | Non-algo | 22 | 0.061 (0.174) | -0.201 (1.403) | 2.214 (1.078) | 9.790 (2.642) | 10.196 (2.766) |
| France | Algo | 2 | 0.117 (0.031) | 0.025 (0.010) | 4.916 (0.730) | 7.059 (0.221) | 8.306 (0.794) |
| Norway | Non-algo | 34 | 0.110 (0.162) | 0.045 (0.076) | 2.947 (1.498) | 8.725 (1.712) | 9.644 (1.595) |
| Norway | Algo | 1 | 0.100 (0.155) | 0.010 (0.017) | 6.653 (4.151) | 8.351 (2.033) | 9.542 (2.206) |
| Sweden | Non-algo | 506 | 0.057 (0.211) | -0.026 (0.598) | 2.770 (1.683) | 13.181 (2.281) | 13.839 (2.196) |
| Sweden | Algo | 31 | 0.000 (0.294) | -0.123 (0.916) | 3.359 (1.659) | 12.618 (2.455) | 13.494 (2.299) |
| UK | Non-algo | 41 | 0.135 (0.285) | 0.001 (0.787) | 2.445 (1.634) | 10.575 (2.963) | 11.145 (2.728) |
| UK | Algo | 9 | 0.082 (0.264) | -0.026 (0.442) | 3.370 (1.193) | 13.560 (3.250) | 14.141 (2.857) |
Scope. We merge the main panel
(APfullDATA.rds) with Companies House (CH) and harmonise
identifiers, industry labels, accounting magnitudes, currencies, and
derived measures.
after, CompanyID,
IndustryGroup).dataSource ("Eikon",
"SHOF", "CH"), set onPSpy = 1
where missing in CH.Country = "Sweden" for SHOF rows; coerce IDs to
character.CompanyName as
CompanyNameOriginal; standardise via
_scripts/standardize_company_names.R and
_scripts/standardize_names_shof_eikon.R.CompanyName for matching; when both Eikon
and SHOF exist for the same
(CompanyName,Year), keep
Eikon, drop SHOF.SectorNew from Sector with
fallbacks; map CH “RETAILER” → “Retail Trade”.SekEur
(EXR.D.SEK.EUR.SP00.A) and GbpEur (EXR.D.GBP.EUR.SP00.A),
selecting the last non-NA December observation per
year; fall back to the latest non-NA earlier in the year if
needed.SekEur and GbpEur afterwards.ROA = OpProfit/TA,
ProfitMargin = OpProfit/Sales,
SalesPerTA = Sales/TA.AvgInv = (Inv + lag(Inv))/2 (by firm),
InvTurnover = COGS/AvgInv,
DIO = 365/InvTurnover.DebtRatio = DebtLT/TA,
LogTA = log(TA+1),
LogSales = log(Sales+1).AlgoRetailer==1)
solely for missing TA/Sales/OpProfit in raw sources; otherwise drop rows
missing these keys.Inf,
-Inf, or NaN; retain expected first-year
NAs in growth rates._W copies used for matching and estimation. (Sensitivity:
Country×Year.)_data/interim/backup_pre_final_clean.csv,
_data/interim/backup_final_clean.csv, and final
_data/processed/financials_final_clean.csv._W variables.