Skip to content

Emission trading

Back to general structure

Without emission trading, the reductions and mitigation costs attributed to a region are the reductions and costs that physically occur within that region. Emission trading allows this attribution to differ, for example because reductions are cheaper elsewhere or because an effort-sharing regime assigns a different distribution of emission allowances.

The emission trading module can be chosen using the parameter emissiontrade module.

Physical and attributed reductions and costs

Emission trading distinguishes between where an emission reduction takes place and the region to which the reduction and its cost are attributed:

  • regional_emission_reductions is the physical reduction within a region.
  • attributed_emission_reductions is the reduction attributed to a region after trading.
  • domestic_mitigation_costs_abs is the cost of the physical reductions within a region.
  • mitigation_costs_abs is the cost attributed to a region after trading.

With emission trading, the two pairs are connected through the trading balances:

\[ \begin{align} \text{attributed emission reductions}_{t,r} &= \text{regional emission reductions}_{t,r} + \text{emission reduction trading balance}_{t,r},\\ \text{mitigation costs abs}_{t,r} &= \text{domestic mitigation costs abs}_{t,r} + \text{mitigation cost trading balance}_{t,r}. \end{align} \]

A positive trading balance means that a region buys reductions and pays other regions. A negative balance means that a region sells reductions and receives payment. Without emission trading, both balances are zero, so physical and attributed reductions and costs are the same.

Variables in the model results

Variable Meaning Unit Availability
regional_emission_reductions Physical emission reduction within the region Emissions per year Both options
attributed_emission_reductions Emission reductions attributed to the region after trading Emissions per year Emission trading only
emission_reduction_trading_balance Reductions bought (positive) or sold (negative) by the region Emissions per year Both options; always zero without trade
regional_emission_allowances Emissions assigned to the region after accounting for its attributed reductions Emissions per year Both options
domestic_mitigation_costs_abs Cost of reductions taking place within the region Currency per year Both options
mitigation_costs_abs Mitigation costs attributed to the region after trading Currency per year Both options
mitigation_cost_trading_balance Payments made (positive) or received (negative) by the region Currency per year Both options; always zero without trade
carbon_price Marginal carbon price in a region Currency per unit of emissions Both options
global_carbon_price Population-weighted average carbon price used to convert payments into traded reductions Currency per unit of emissions Emission trading only

The exact units are determined by the configured model units. With the default units, emissions flows are expressed per year and costs are expressed in trillion 2010 US dollars per year.

Checking emission-trading results

For every timestep with emission trading, the payments sum to zero across regions:

\[ \sum_r \text{mitigation cost trading balance}_{t,r} = 0. \]

Because all payments are converted at the same global carbon price, the emission reduction trading balances also sum to zero. Therefore, trading changes the regional attribution of reductions and costs, but not their global totals. Small non-zero sums can occur in numerical results because of solver tolerances.

The regional emission allowances are calculated from the reductions attributed to a region:

\[ \text{regional emission allowances}_{t,r} = \text{baseline emissions}_{t,r} - \text{attributed emission reductions}_{t,r}. \]

Without emission trading, regional_emission_allowances is simply equal to regional_emissions.

Interaction with other modules

Emission trading is often used with an effort-sharing module. Effort sharing determines how allowances or costs should be distributed among regions, while emission trading connects that distribution to the physical reductions and costs in each region.

The financial transfer module is separate. Its transfers redistribute damage costs and do not change attributed_emission_reductions, regional_emission_allowances, or either emission-trading balance.

Available options

Usage:

params = load_params()
params["model structure"]["emissiontrade module"] = "notrade"
model = MIMOSA(params)

Without emission trading, both trading balances are always zero:

\[ \begin{align} \text{emission reduction trading balance}_{t,r} &= 0,\\ \text{mitigation cost trading balance}_{t,r} &= 0. \end{align} \]

Therefore, the reductions attributed to a region are the physical reductions within that region, and mitigation_costs_abs is equal to domestic_mitigation_costs_abs (see Mitigation costs). The model does not create a separate attributed_emission_reductions result for this option.

Without trade, regional emission allowances are simply equal to regional emissions:

\[ \text{regional emission allowances}_{t,r} = \text{regional emissions}_{t,r}. \]
Source code in mimosa/components/emissiontrade/notrade.py
def get_constraints(
    m: AbstractModel, context: ModelContext
) -> Sequence[GeneralConstraint]:
    """
    Without emission trading, both trading balances are always zero:

    $$
    \\begin{align}
    \\text{emission reduction trading balance}_{t,r} &= 0,\\\\
    \\text{mitigation cost trading balance}_{t,r} &= 0.
    \\end{align}
    $$

    Therefore, the reductions attributed to a region are the physical reductions within that region, and
    `mitigation_costs_abs` is equal to `domestic_mitigation_costs_abs` (see
    [Mitigation costs](mitigation.md#mitigation-costs)). The model does not create a separate
    `attributed_emission_reductions` result for this option.

    Without trade, regional emission allowances are simply equal to regional emissions:

    $$
    \\text{regional emission allowances}_{t,r} = \\text{regional emissions}_{t,r}.
    $$
    """
    constraints = []  # No constraints here

    m.emission_reduction_trading_balance = Param(
        m.t, m.regions, units=quant.unit("emissionsrate_unit"), initialize=0
    )
    m.mitigation_cost_trading_balance = Param(
        m.t, m.regions, units=quant.unit("currency_unit"), initialize=0
    )
    m.regional_emission_allowances = Var(
        m.t, m.regions, units=quant.unit("emissionsrate_unit")
    )

    constraints.append(
        # When there is no emission trading, emission allowances are simply equal to the emissions
        RegionalEquation(
            m.regional_emission_allowances, lambda m, t, r: m.regional_emissions[t, r]
        )
    )

    return constraints

Usage:

params = load_params()
params["model structure"]["emissiontrade module"] = "emissiontrade"
model = MIMOSA(params)

In MIMOSA, every region can physically reduce its own emissions. The domestic cost is determined by the area under the MAC (see Mitigation). Emission trading allows the reductions and mitigation costs attributed to a region to differ from the reductions and costs occurring within that region.

The associated financial flow is captured by \(\text{mitigation cost trading balance}_{t,r}\). A positive balance increases the mitigation costs attributed to a region; a negative balance reduces them. For every timestep, the sum of these transfers should be zero:

\[ \sum_r \text{mitigation cost trading balance}_{t,r} = 0 \]

A single global carbon price is used to convert the financial flow (mitigation_cost_trading_balance) into a flow of attributed emission reductions (emission_reduction_trading_balance):

\[ \text{emission reduction trading balance}_{t,r} = \frac{\text{mitigation cost trading balance}_{t,r}}{\text{global carbon price}_{t}}, \]

where the global carbon price is the population weighted average of the regional carbon prices:

\[ \text{global carbon price}_{t} = \frac{\sum_r \text{carbon price}_{t,r} \cdot \text{population}_{t,r}}{\sum_r \text{population}_{t,r}}. \]

The emission reductions attributed to a region are calculated as the physical reductions in that region plus its emission reduction trading balance:

\[ \text{attributed emission reductions}_{t,r} = \text{regional emission reductions}_{t,r} + \text{emission reduction trading balance}_{t,r}. \]

Regional emission allowances are the baseline emissions minus the reductions attributed to the region:

\[ \text{regional emission allowances}_{t,r} = \text{baseline emissions}_{t,r} - \text{attributed emission reductions}_{t,r}. \]
Source code in mimosa/components/emissiontrade/emissiontrade.py
def get_constraints(
    m: AbstractModel, context: ModelContext
) -> Sequence[GeneralConstraint]:
    """
    In MIMOSA, every region can physically reduce its own emissions. The domestic cost is determined
    by the area under the MAC (see [Mitigation](mitigation.md#mitigation-costs)). Emission trading
    allows the reductions and mitigation costs attributed to a region to differ from the reductions
    and costs occurring within that region.

    The associated financial flow is captured by
    $\\text{mitigation cost trading balance}_{t,r}$. A positive balance increases the mitigation costs
    attributed to a region; a negative balance reduces them. For every timestep,
    the sum of these transfers should be zero:

    $$
    \\sum_r \\text{mitigation cost trading balance}_{t,r} = 0
    $$

    A single global carbon price is used to convert the financial flow
    (`mitigation_cost_trading_balance`) into a flow of attributed emission reductions
    (`emission_reduction_trading_balance`):

    $$
    \\text{emission reduction trading balance}_{t,r} = \\frac{\\text{mitigation cost trading balance}_{t,r}}{\\text{global carbon price}_{t}},
    $$

    where the global carbon price is the population weighted average of the regional carbon prices:

    $$
    \\text{global carbon price}_{t} = \\frac{\\sum_r \\text{carbon price}_{t,r} \\cdot \\text{population}_{t,r}}{\\sum_r \\text{population}_{t,r}}.
    $$

    The emission reductions attributed to a region are calculated as the physical reductions in that region plus its
    emission reduction trading balance:

    $$
    \\text{attributed emission reductions}_{t,r} = \\text{regional emission reductions}_{t,r} + \\text{emission reduction trading balance}_{t,r}.
    $$

    Regional emission allowances are the baseline emissions minus the reductions attributed to the region:

    $$
    \\text{regional emission allowances}_{t,r} = \\text{baseline emissions}_{t,r} - \\text{attributed emission reductions}_{t,r}.
    $$

    """
    constraints = []

    m.global_carbon_price = Var(m.t)

    # Emissions are traded at the global carbon price
    constraints.extend(
        [
            # Constraint that sets the global carbon price to the average of the regional carbon prices:
            GlobalEquation(
                m.global_carbon_price,
                lambda m, t: sum(
                    m.carbon_price[t, r] * m.population[t, r] for r in m.regions
                )
                / m.global_population[t],
            ),
        ]
    )

    ## Extra reporting variables:

    m.attributed_emission_reductions = Var(
        m.t, m.regions, units=quant.unit("emissionsrate_unit")
    )
    m.regional_emission_allowances = Var(
        m.t, m.regions, units=quant.unit("emissionsrate_unit")
    )
    m.emission_reduction_trading_balance = Var(
        m.t, m.regions, units=quant.unit("emissionsrate_unit")
    )
    m.mitigation_cost_trading_balance = Var(
        m.t, m.regions, units=quant.unit("currency_unit")
    )
    constraints.extend(
        [
            GlobalConstraint(
                lambda m, t: sum(
                    m.mitigation_cost_trading_balance[t, r] for r in m.regions
                )
                == 0.0,
                "sum_mitigation_equals_sum_area_under_mac",
            ),
            # Convert the mitigation-cost trading balance into the emission-reduction trading balance
            RegionalEquation(
                m.emission_reduction_trading_balance,
                lambda m, t, r: (
                    m.mitigation_cost_trading_balance[t, r]
                    / soft_min(m.global_carbon_price[t])
                    if t > 0
                    else 0
                ),
            ),
            # Constraint: emission reductions attributed to the region after trading
            RegionalEquation(
                m.attributed_emission_reductions,
                lambda m, t, r: (
                    m.regional_emission_reductions[t, r]
                    + m.emission_reduction_trading_balance[t, r]
                    if t > 0
                    else Constraint.Skip
                ),
            ),
            # Constraint: regional emission allowances, equal to baseline minus attributed emission reductions
            RegionalEquation(
                m.regional_emission_allowances,
                lambda m, t, r: (
                    m.baseline_emissions[t, r] - m.attributed_emission_reductions[t, r]
                    if t > 0
                    else m.baseline_emissions[t, r]
                ),
            ),
        ]
    )

    return constraints