Tariffs
Annular supports simulating the effect of market interventions through various policies and tariffs. We aim to support a wide range of potential tariffs, and provide an easy interface for accessing their values in the internals of any bidding strategy.
This page will explain the:
design philosophy
expected data format and schema
provided runtime interface
Design philosophy
Tariffs can be defined for many different scenarios, and are commonly separated according to both some categorical values and some temporal aspect. Each tariff should be recorded in a separate file to avoid having to specify unnecessary values for all possible index combinations. This means that each file only specifies the required indexing levels relevant for that particular tariff. As an added benefit, this makes the system very modular, as replacing a single tariff means exactly replacing a single file, without being bound by indexing levels of those other tariffs.
In use, we see the main distinction between ‘categorial’ and ‘temporal’ index levels, with the categorical index assumed to be fixed during the runtime of a simulation. This leaves the temporal index to be selected at runtime through a simple interface.
We acknowledge that some of these categories may depend on the maximum used capacity, with jumps in tariff value between them. In such cases, we assume that the final category in which you end up is known to you beforehand with a high degree of certainty.
Data format and schema
All tariffs should be defined in tidy CSV files. A single CSV file
<tariff_name>.csv should contain the full specification of a single tariff.
The name of the file will be used as the identifier for that tariff when loaded.
The collection of tariff files should be contained in a single folder. This
should include any other tariff-related variables such as weighting factors.
Each CSV file should be formatted as follows:
Grid level |
Consumer type |
… |
month |
weekday/weekend |
… |
hour |
value |
|---|---|---|---|---|---|---|---|
… |
… |
… |
… |
… |
… |
… |
… |
In order, the file should contain the following columns, preferably in this order:
Categorical index levels (Grid level, Consumer type, …)
Temporal index levels if relevant (month, weekday/weekend, …, hour)
Value
Each file should only contain those columns that are necessary to specify the
tariff. E.g., if there is no monthly variance in a tariff, a month column
should not be specified.
Runtime interface
A folder of tariffs can be loaded using the TariffManager.from_folder()
method. This takes an argument of type Path pointing to the folder containing
the collection of CSV files defining the tariffs. Additionally, a dictionary of
categorical index keys must be passed in with the preselect argument to select
values that remain fixed for the runtime of the simulation.
Once the TariffManager has been instantiated, tariff values can be retrieved
by name and date using the fetch(name=..., date=...) method. The tariff
returned by the fetch method can be either a single value, or a pandas Series
object of tariff values indexed by hour.
Fetch types
We distinguish between the following ‘tariff fetching scenarios’:
A tariff is not temporally indexed:
fetch(name) -> floatIf there is no time to vary by, then the only relevant selection is the preselection that’s already happened. Just return the relevant value.
A tariff is at least indexed by hour:
fetch(name, timestamps) -> pd.Series, withtimestampsas its index.If it is at least indexed by hour, then we want to have an exact value for each timestamp. Date-parsing should happen as part of this.
A tariff only date-indexed, not time-indexed:
fetch(name, timestamps) -> pd.SeriesWhen not time-indexed, there is no need to return a value for every timestamp. But it will still be necessary to distinguish between e.g. January/February within a single ‘fetch’ cycle. The fetch function should boil down the index to only those columns for which a selection can still be made, with the only relevant values being those that can be parsed from the given collection of timestamps.
Temporal index level parsing
Since all remaining index levels are temporal in nature, the date argument
of the fetch method is used to select the relevant values. The TariffManager
supports automatically parsing the date to certain kinds of index levels if the
column name exactly matches one of the following:
"year""month""weekday/weekend"(where Dutch national holidays are included in the ‘weekend’ category)