Conversation
lecfab
left a comment
There was a problem hiding this comment.
Thanks for all the dusting and testing that it takes to revive the permit trading!
I left comments here and there, mainly about aesthetics and documentation.
| cm_pemittraderatio "Percentage of restricted permit trading" | ||
| ; | ||
| cm_pemittraderatio = 0.2; !! def = 0.2 | ||
| *' |
There was a problem hiding this comment.
I find the existing names of "permit trades scenarios" a little confusing, in the sense that we would always need to refer to the main.gms to understand what they mean. The big undertaking of reactivating permit trade is possibly a good opportunity to simplify that. Two suggestions (either/or):
- simpler one: rename the "no permit trade" to
cm_permittradescen = 0 - nicer one: remove
cm_permittradescen, because it is redundant withcm_pemittraderatio(0% for no trade, 100% for full trade, and whatever in-between for limited trade)
There was a problem hiding this comment.
In general, I agree! The switch cm_permittradescen was already there and is used in other 41 realizations like PerCapitaConvergence and AbilityToPay. Changing this would require some refactoring there, and currently I don't fully understand the other realizations.
For not having to look into the main.gms I copied it also into the realization
There was a problem hiding this comment.
Ah understood thanks! Would this still make sense to ignore to ignore cm_permittradescen in your new realisation?
Also the new switch names will probably need to be changed in the other realisations too?
| *' * (2): no permit trade (only domestic mitigation) | ||
| *' * (3): limited trade (certain percentage of regional allowances) | ||
| *' for limited trade use cm_pemittradefinalyr to set the final year until permit trading is allowed | ||
| *' with cm_pemittraderatio set the percentage of allowed trade |
There was a problem hiding this comment.
see comment for main.gms
https://github.com/remindmodel/remind/pull/2285/changes#r2799231804
There was a problem hiding this comment.
Here the switch names that have been updated in main.gms could be updated as well (and everywhere else where they appear =))
benjaminpeeters
left a comment
There was a problem hiding this comment.
Hey @RahelMA
Thanks for the PR.
Added just a few comments from my side, notably on the changes for etaSL.
Not sure this is useful. Hope it is.
I just have another (small) question:
why cm_pemittradefinalyr and cm_pemittraderatio instead of cm_permittradefinalyr and cm_permittraderatio (with an 'r' in 'permit')?
| p80_etaST(tradePe) = 0.3; | ||
| p80_etaST("good") = 0.25; | ||
| p80_etaST("perm") = 0.3; | ||
| p80_etaST("perm") = 0.8; |
There was a problem hiding this comment.
As far as I understand these p.._etaST/LT haven't been changed since the codebase was open-sourced in December 2019 with the explicit indication "These parameters are pretty sensitive" :)
The permit market also does not "benefit" from the adaptive convergence boosting mechanism (the 4x/8x/16x escalation after iterations 15/20/25) -- only applies to tradePe and good if I'm not wrong (see https://github.com/remindmodel/remind/blob/develop/modules/80_optimization/nash/postsolve.gms#L139C1-L173C19).
I wonder:
- what motivate to such a big shift (from 0.3 to 0.8)?
- why
p80_etaST("pebiolc") = 0.8;was already fixed to 0.8 back then? @LaviniaBaumstark - have we try the "adaptative boosting"? wouldn't it be more consistent with the rest of the code? Are there good reasons to treat "perm" differently in that regard (e.g., much smaller fraction of the world exchanges wrt "good"? "pebiolc" does seem to have this boost as well)
- don't we need to be even more strict on
p80_etaSAfor "perm" given the fact that the inter iteration adjustment cost parameter is much lower than for other goods (https://github.com/remindmodel/remind/blob/develop/modules/80_optimization/nash/datainput.gms#L45-L48) and therefore has more risk of oscillation? (not sure) Likewise, wouldn't it lead to better convergence (less oscillation while adjustment) to decrease the adjustment cost even further to not be so aggressive aboutp80_etaST? In other words, instead of forcing the market with heavy-handed price corrections (high etaST), why not make the planners more responsive to prices (lower etaAdj) so the market clears more?
There was a problem hiding this comment.
In general, I had the issue that the surplus was too high and the permit price did not change enough to motivate adjustments. I did not have the issue of oscillation in my runs.
| *** | AGPL-3.0, you are granted additional permissions described in the | ||
| *** | REMIND License Exception, version 1.0 (see LICENSE file). | ||
| *** | Contact: remind@pik-potsdam.de | ||
| *** SOF ./modules/41_emicapregi/AbilityToPay/bounds.gms |
There was a problem hiding this comment.
new files reference AbilityToPay instead of TradingOnRef
| p41_co2eq(t, regi) = p41_co2eq_in(t,regi,"co2"); | ||
|
|
There was a problem hiding this comment.
Is it used anywhere or come from the copy paste from AbilityToPay?
There was a problem hiding this comment.
No, I first load the entire emission as intermediate step p41_co2eq_in = vm_emiAll.l and in a second step only use the CO2 emissions to allocate the permits: p41_co2eq(t, regi) = p41_co2eq_in(t,regi,"co2");
| p80_surplusMaxTolerance(tradePe) = 2* 1.5 * sm_EJ_2_TWa; !! convert EJ/yr into internal unit TWa | ||
| p80_surplusMaxTolerance("good") = 2* 100/1000; !! in internal unit, trillion Dollar | ||
| p80_surplusMaxTolerance("perm") = 2* 300 * 12/44 / 1000; !! convert MtCO2eq into internal unit GtC | ||
| p80_surplusMaxTolerance("perm") = 3* 300 * 12/44 / 1000; !! convert MtCO2eq into internal unit GtC |
There was a problem hiding this comment.
What is the actual relative residual permit surplus at convergence in the test runs? Could you share the p80_surplusMaxRel values? do the iterations converge below the tolerance, or does it tend to stay blocked close to it?
There was a problem hiding this comment.
So an edge case is e.g. if trade is only allowed for a short period in EC650-PC-Trade20-2060 here the surplus goes to 2060 perm 63 -0.24 this was not converging with 2* 300 * 12/44 / 1000= 0.16 now the tolerance is 0.245.
/p/tmp/rahelma/Committed/Equity/permTrading/output/EC650-PC-Trade20-2060_2026-02-06_15.10.31 (trading)$ dumpgdx fulldata.gdx p80_surplusMaxRel perm,63,
perm 63 2030 0.388459318122543
perm 63 2035 0.388459318122543
perm 63 2040 0.388459318122543
perm 63 2045 0.388459318122543
perm 63 2050 0.388459318122543
perm 63 2055 0.388459318122543
perm 63 2060 1.94757151310855
perm 63 2070 1.94757151310855
perm 63 2080 1.94757151310855
perm 63 2090 1.94757151310855
perm 63 2100 1.94757151310855
perm 63 2110 1.94757151310855
perm 63 2130 1.94757151310855
perm 63 2150 1.94757151310855
lecfab
left a comment
There was a problem hiding this comment.
Looks good!
Please just ensure that all the instances of the changed switch name are updated (also in other realisations), for instance the
- cm_pemittraderatio
+ cm_permitTradeRatio| cm_pemittraderatio "Percentage of restricted permit trading" | ||
| ; | ||
| cm_pemittraderatio = 0.2; !! def = 0.2 | ||
| *' |
There was a problem hiding this comment.
Ah understood thanks! Would this still make sense to ignore to ignore cm_permittradescen in your new realisation?
Also the new switch names will probably need to be changed in the other realisations too?
| *' * (2): no permit trade (only domestic mitigation) | ||
| *' * (3): limited trade (certain percentage of regional allowances) | ||
| *' for limited trade use cm_pemittradefinalyr to set the final year until permit trading is allowed | ||
| *' with cm_pemittraderatio set the percentage of allowed trade |
There was a problem hiding this comment.
Here the switch names that have been updated in main.gms could be updated as well (and everywhere else where they appear =))
Purpose of this PR
This PR tries to reactivate permit trading ;)
With the new realization
TradingOnRefin41_emicapregi, a reference run is used to allocate emission allowances for each region and timestep.Overall, there are three different types of permit trading:
(1): full permit trade (no restrictions)
(2): no permit trade (only domestic mitigation)
(3): limited trade (certain percentage of regional allowances)
for limited trade use
cm_pemittradefinalyrto set the final year until permit trading is allowedwith
cm_pemittraderatioset the percentage of allowed tradeIn these exemplary runs, I used 20% of permit allocation until 2060 and 2100:
Please note that I increased the surplus tolerance to also allow more aggressive trade patters like full trading or with a very short time frame. Honestly, it's hard for me to judge if it is a reasonable scale:
p80_surplusMaxTolerance("perm") = 2* 300 * 12/44 / 1000; to p80_surplusMaxTolerance("perm") = 3* 300 * 12/44 / 1000;
@LaviniaBaumstark what do you think?
Type of change
Indicate the items relevant for your PR by replacing ◻️ with ☑️.
Do not delete any lines. This makes it easier to understand which areas are affected by your changes and which are not.
Parts concerned
Impact
Checklist
Do not delete any line. Leave unfinished elements unchecked so others know how far along you are.
In the end all checkboxes must be ticked before you can merge.
make test) after my final commit and all tests pass (FAIL 0)remind2if and where it was neededforbiddenColumnNamesin readCheckScenarioConfig.R in case the PR leads to deprecated switchesCHANGELOG.mdcorrectly (added, changed, fixed, removed, input data/calibration)Further information (optional)
/p/tmp/rahelma/Committed/Equity/permTrading/p/tmp/rahelma/Committed/Equity/permTrading/compScen-tradingScen-2026-02-10_20.52.00-H12.pdf