The order is not arbitrary

Four conversions are applied, always in this order:

  1. Strip VAT. Before anything else, because VAT is a percentage of the price as quoted, in the currency as quoted.
  2. Convert currency. After VAT, because the VAT rate belongs to the country whose currency the price is in.
  3. Convert the volume basis. After currency, because the unit ratio is a property of the wood, not of the money, so it commutes with FX — but doing it here keeps every downstream figure in one unit.
  4. Uplift to delivered. Last, because the uplift factor is indexed by product stage and applies to a per-cubic-metre figure. Applying it before the unit conversion would multiply a stacked-cubic-metre price by a solid-cubic-metre factor.

Swapping steps 1 and 2 changes the answer whenever the FX rate and the VAT rate come from different days, which they routinely do. The order is fixed in code and covered by roughly 280 golden fixtures — 7 currencies × 8 unit forms × 5 transport terms — so a change to any constant fails a snapshot rather than quietly re-pricing the index.

1. VAT

A row arrives flagged VAT-included or VAT-excluded, with the rate recorded for that source. VAT-excluded rows pass through untouched. VAT-included rows are divided, not discounted:

ex_vat = amount / (1 + vat_rate_pct / 100)

Dividing rather than subtracting matters more than it looks. A net price of 100 at 19% VAT is published as 119. Subtracting 19% of 119 gives 96.39, not 100 — an understatement of about 3.6% on every VAT-inclusive row in the index, applied silently and in one direction. Dividing by 1.19 returns exactly 100.

2. Currency

Rates come from the European Central Bank’s daily reference feed, loaded at 04:00 UTC, and are stored as eur_per_unit — how many euro one unit of the currency buys. A row is converted at the rate for its own sale date, not at today’s rate, so a 2024 auction stays priced at 2024 money.

3. Volume basis

Eight unit forms are recognised and collapse to four bases. The matching is order-sensitive: the specific patterns are tried before the general ones, so m³ brutto is read as stacked rather than as a bare cubic metre.

Written asBasisTo solid m³
m3sub, m3fub, m³ub, m³ net, Solid cubic metre× 1.00
m³ brutto, Raummeter, rmStacked cubic metre× 0.90
SterFirewood stack× 0.65
piece, pc, StückDiscrete countnot converted

Stacked wood contains air. A stacked cubic metre of roundwood holds about 0.9 solid cubic metres of wood; a ster of split firewood holds about 0.65. Piece prices are kept as normalized_eur_per_piece and never guessed into a volume — the conversion would need a log diameter and length the source did not publish.

4. Transport term

A price for a tree still standing in a forest and a price for the same wood on a lorry at a buyer’s yard differ by the cost of felling, extraction and haulage. To compare them, at-source prices are multiplied up to their delivered equivalent. Every factor is ≥ 1.0 — the index only ever adds the logistics it can justify, never subtracts.

Product stageStanding →Roadside →Ex works →
Standing tree× 1.70× 1.25× 1.10
Roadside log× 1.70× 1.25× 1.10
Sawlog× 1.55× 1.20× 1.08
Veneer log× 1.50× 1.18× 1.08
Pulpwood× 1.70× 1.30× 1.12
Firewood× 1.55× 1.20× 1.08
Sawn board× 1.15× 1.08× 1.04
Slab× 1.15× 1.08× 1.04
Finished panel× 1.10× 1.05× 1.02

Already-delivered prices are multiplied by 1.0, which is to say left alone. The gap between a 1.70 standing-tree uplift and a 1.15 sawn-board uplift is the honest one: most of a standing tree’s journey to a yard is still ahead of it, and most of a sawn board’s is behind it.

A row whose transport term is unknown is dropped, not assumed. There is no default uplift. Guessing here would bury a 70% adjustment inside a number presented as a measurement, and the guess would be invisible in the output.

Worked example

Take a row as it arrives from a standing-tree auction. The inputs below are an illustration; the VAT rate and FX rate applied to any real row are the ones recorded against that row.

StepOperationResult
As published250 RON/m³, VAT included at 19%, standing, sawlog250.00 RON
1 · VAT250 / 1.19210.08 RON
2 · FX210.08 × 0.2010 (EUR per RON, that sale date)€42.23
3 · UnitAlready solid m³ — no conversion€42.23
4 · Transport42.23 × 1.55 (sawlog, standing → delivered)€65.46/m³

The published figure and the index figure differ by a factor of about 1.3 in euro terms, and every part of that gap is a stated conversion rather than a judgement. That is the entire claim this page makes: not that our number is more right, but that you can get from theirs to ours with a calculator.

What the pipeline refuses to do

Each of these produces a dropped row rather than an estimated one. The index is smaller as a result, which is the intended trade.

Checking us

The normalized rows are public. /api/v1/prices returns individual observations with their confidence score; the per-cell endpoints return the sources and weights behind every aggregate. If a number here disagrees with a number you have, the disagreement is reproducible in both directions — see the API reference, and the changelog for every past correction to how these figures are computed.

Normalizing timber prices to €/m³ · KORENA Timber Index