EAO package

Assets

class Asset(name: str = 'default_name', nodes: ~eaopack.basic_classes.Node | ~typing.List[~eaopack.basic_classes.Node] = <eaopack.basic_classes.Node object>, start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, freq: str = None, profile: ~pandas.core.series.Series = None)

Bases: object

Asset parent class. Defines all basic methods and properties of an asset In particular ‘setup_optim_problem’ makes a particular asset such as storage or contract

The base class to define an asset.

Parameters:
  • name (str) – Name of the asset. Must be unique in a portfolio

  • nodes (Union[str, List[str]]) – Nodes, in which the asset has a dispatch. Defaults to “default node”

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Grid for discretization

  • wacc (float, optional) – WACC to discount the cash flows as the optimization target. Defaults to 0.

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

convert_to_timegrid_freq(time_value: float, attribute_name: str, old_freq: str = None, timegrid: Timegrid = None, round: bool = True) float | int

Convert time_value from the old_freq to the timegrid.freq

Parameters:
  • time_value (float) – The time value in timegrid.main_time_unit

  • attribute_name (str) – The name of the attribute to be converted (only relevant for more specific warning)

  • old_freq (str) – The old freg. If this is None the timegrids main_time_unit is used. Defaults to None.

  • timegrid (Timegrid) – The timegrid from with main_time_unit and freq are used. If timegrid is None, the asset’s own timegrid self.timegrid is taken instead. Defaults to None.

  • round – If true the result is rounded to the next highest integer.

Returns:

time_value converted to timegrid.freq

Return type:

converted_time_value

dcf(optim_problem: OptimProblem, results: Results) array

Calculate discounted cash flow for the asset given the optimization results

Parameters:
  • optim_problem (OptimProblem) – optimization problem created by this asset

  • results (Results) – Results given by optimizer

Returns:

array with DCF per time step as per timegrid of asset

Return type:

np.array

make_vector(value: float | StartEndValueDict | str, prices: dict, default_value: float = None, convert=False)

Make a vector out of value :param value: The value to be converted to a vector

float: constant value dict: dict[‘start’] = array

dict[‘end’] = array dict[‘values’] = array

str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • default_value (float) – The value that is used if any of the entries of the resulting vector are not specified

Returns: vector in time grid

property node_names
set_timegrid(timegrid: Timegrid)

Set the timegrid for the asset :param timegrid: The timegrid to be set :type timegrid: Timegrid

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

set up optimization problem for the asset

Parameters:
  • prices (dict) – dictionary of price np.arrays. dict must contain a key that corresponds to str “price” in asset (if prices are required by the asset)

  • timegrid (Timegrid) – Grid to be used for optim problem. Defaults to none

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem that may be used by optimizer

Return type:

OptimProblem

class CHPAsset(name: str = 'default_name_contract', nodes: ~typing.List[~eaopack.basic_classes.Node] = [<eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>], start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, price: str = None, extra_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, max_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_take: ~eaopack.basic_classes.StartEndValueDict = None, max_take: ~eaopack.basic_classes.StartEndValueDict = None, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None, conversion_factor_power_heat: float | ~eaopack.basic_classes.StartEndValueDict | str = 1.0, max_share_heat: float | ~eaopack.basic_classes.StartEndValueDict | str = None, ramp: float = None, start_costs: float | ~typing.Sequence[float] | ~eaopack.basic_classes.StartEndValueDict = 0.0, running_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_runtime: float = 0, time_already_running: float = 0, min_downtime: float = 0, time_already_off: float = 0, last_dispatch: float = 0, start_ramp_lower_bounds: ~typing.Sequence = None, start_ramp_upper_bounds: ~typing.Sequence = None, shutdown_ramp_lower_bounds: ~typing.Sequence = None, shutdown_ramp_upper_bounds: ~typing.Sequence = None, start_ramp_lower_bounds_heat: ~typing.Sequence = None, start_ramp_upper_bounds_heat: ~typing.Sequence = None, shutdown_ramp_lower_bounds_heat: ~typing.Sequence = None, shutdown_ramp_upper_bounds_heat: ~typing.Sequence = None, ramp_freq: str = None, start_fuel: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, fuel_efficiency: float | ~eaopack.basic_classes.StartEndValueDict | str = 1.0, consumption_if_on: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, _no_heat=False)

Bases: Contract

CHPContract: Generate heat and power

Restrictions - time dependent capacity restrictions - MinTake & MaxTake for a list of periods - start costs - minimum runtime - ramps

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • nodes (Node) – One node each for generated power and heat (asset parameter) optional: node for fuel (e.g. gas)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float) – Minimum capacity for generating virtual dispatch (power + conversion_factor_power_heat * heat). Has to be greater or equal to 0. Defaults to 0.

  • max_cap (float) – Maximum capacity for generating virtual dispatch (power + conversion_factor_power_heat * heat). Has to be greater or equal to 0. Defaults to 0.

  • min_take (float) – Minimum volume within given period. Defaults to None

  • max_take (float) –

    Maximum volume within given period. Defaults to None float: constant value dict: dict[‘start’] = np.array

    dict[‘end’] = np.array dict[‘values”] = np.array

  • price (str) – Name of price vector for buying / selling

  • extra_costs (float, dict, str) –

    extra costs added to price vector (in or out). Defaults to 0. float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

  • conversion_factor_power_heat (float, dict, str) – Conversion efficiency from heat to power. Defaults to 1.

  • max_share_heat (float, dict, str) – Defines upper bound for the heat dispatch as a percentage of the power dispatch. Defaults to 1.

  • ramp (float) – Maximum increase/decrease of virtual dispatch (power + conversion_factor_power_heat * heat) in one timestep. Defaults to 1.

  • start_costs (float) – Costs for starting. Defaults to 0.

  • running_costs (float) – Costs when on. Defaults to 0.

  • min_runtime (int) – Minimum runtime in timegrids main_time_unit. (start ramp time and shutdown ramp time do not count towards the min runtime.) Defaults to 0.

  • time_already_running (int) – The number of timesteps the asset is already running in timegrids main_time_unit. Defaults to 0.

  • min_downtime (int) – Minimum downtime in timegrids main_time_unit. Defaults to 0.

  • time_already_off (int) – The number of timesteps the asset has already been off in timegrids main_time_unit. Defaults to 0.

  • last_dispatch (float) – Previous virtual dispatch (power + conversion_factor_power_heat * heat). Defaults to 0.

  • start_ramp_lower_bounds (Sequence) – The i-th element of this sequence specifies a lower bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq after starting. Defaults to None.

  • start_ramp_upper_bounds (Sequence) – The i-th element of this sequence specifies an upper bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq after starting. Defaults to None.

  • shutdown_ramp_lower_bounds (Sequence) – The i-th element of this sequence specifies a lower bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq before turning off. Defaults to None.

  • shutdown_ramp_upper_bounds (Sequence) – The i-th element of this sequence specifies an upper bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq before turning off. If it is None, it is set equal to shutdown_ramp_upper_bounds. Defaults to None.

  • start_ramp_lower_bounds_heat (Sequence) – The i-th element of this sequence specifies a lower bound of heat dispatch at i timesteps

  • start_ramp_upper_bounds_heat (Sequence) – as above

  • shutdown_ramp_lower_bounds_heat (Sequence) – as above

  • shutdown_ramp_upper_bounds_heat (Sequence) – as above

  • ramp_freq (str) – A string specifying the frequency of the start-and shutdown ramp specification. If this is None, the timegrids main_time_unit is used. Otherwise the start and shutdown ramps are interpolated to get values in the timegrids freq.

  • Optional – Explicit fuel consumption (e.g. gas) for multi-commodity simulation start_fuel (float, dict, str): detaults to 0 fuel_efficiency (float, dict, str): defaults to 1 consumption_if_on (float, dict, str): defaults to 0

  • _no_heat (optional) – No heat node given (making CHP a plain power plant). Defaults to False

setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class CHPAsset_with_min_load_costs(min_load_threshhold: float | Sequence[float] | StartEndValueDict = 0.0, min_load_costs: float | Sequence[float] | StartEndValueDict = None, **kwargs)

Bases: CHPAsset

CHPContract with additional Min Load costs:

adding costs when running below a threshhold capacity

Args:

CHPAsset arguments

additional:

min_load_threshhold (float: optional): capacity below which additional costs apply min_load_costs (float: optional): costs that apply below a threshhold (fixed costs “is below * costs” independend of capacity)

setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class Contract(name: str = 'default_name_contract', nodes: ~eaopack.basic_classes.Node = <eaopack.basic_classes.Node object>, start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, price: str = None, extra_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, max_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_take: ~eaopack.basic_classes.StartEndValueDict = None, max_take: ~eaopack.basic_classes.StartEndValueDict = None, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: SimpleContract

Contract Class, as an extension of the SimpleContract

Contract: buy or sell (consume/produce) given price and limited capacity in/out

Restrictions - time dependent capacity restrictions - MinTake & MaxTake for a list of periods Examples - with min_cap = max_cap and a detailed time series, implement must run RES assets such as wind - with MinTake & MaxTake, implement structured gas contracts

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • node (Node) – Node, the constract is located in (asset parameter)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float, dict, str) – Minimum flow/capacity for buying (negative) or selling (positive). Float or time series. Defaults to 0

  • max_cap (float, dict, str) –

    Maximum flow/capacity for selling (positive). Float or time series. Defaults to 0 float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • min_take (dict) – Minimum volume within given period. Defaults to None

  • max_take (dict) –

    Maximum volume within given period. Defaults to None dict: dict[‘start’] = np.array

    dict[‘end’] = np.array dict[‘values”] = np.array

  • price (str) – Name of price vector for buying / selling

  • extra_costs (float, dict, str) –

    extra costs added to price vector (in or out). Defaults to 0. float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class ExtendedTransport(name: str = 'default_name_ext_transport', nodes: ~typing.List[~eaopack.basic_classes.Node] = [<eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>], start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, costs_const: float = 0.0, costs_time_series: str = None, min_cap: float = 0.0, max_cap: float = 0.0, efficiency: float = 1.0, min_take: ~eaopack.basic_classes.StartEndValueDict = None, max_take: ~eaopack.basic_classes.StartEndValueDict = None, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: Transport

Extended Transport Class, as an extension of Transport

Transport:

name (str): Unique name of the asset (asset parameter) nodes (Node): 2 nodes, the transport links (asset parameter) timegrid (Timegrid): Timegrid for discretization (asset parameter) start (dt.datetime) : start of asset being active. defaults to none (-> timegrid start relevant) end (dt.datetime) : end of asset being active. defaults to none (-> timegrid start relevant) wacc (float): Weighted average cost of capital to discount cash flows in target (asset parameter) freq (str, optional): Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq)

The more granular frequency of portf & asset is used

profile (pd.Series, optional): If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week).

Defaults to None, only relevant if freq is not none

min_cap (float) : Minimum flow/capacity for transporting (from node 1 to node 2) max_cap (float) : Minimum flow/capacity for transporting (from node 1 to node 2) efficiency (float): efficiency of transport. May be any positive float. Defaults to 1. costs_time_series (str): Name of cost vector for transporting. Defaults to None costs_const (float, optional): extra costs added to price vector (in or out). Defaults to 0.

periodicity (str, pd freq style): Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None) periodicity_duration (str, pd freq style): Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

Extension of transport with more complex restrictions:

  • time dependent capacity restrictions

  • MinTake & MaxTake for a list of periods. With efficiency, min/maxTake refer to the quantity delivered FROM node 1

Examples
  • with min_cap = max_cap and a detailed time series

  • with MinTake & MaxTake, implement structured gas contracts

Additional args:

min_take (dict) : Minimum volume within given period. Defaults to None max_take (dict) : Maximum volume within given period. Defaults to None

dict: dict[‘start’] = np.array

dict[‘end’] = np.array dict[‘values”] = np.array

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class MultiCommodityContract(name: str = 'default_name_multi_commodity', nodes: ~eaopack.basic_classes.Node | ~typing.List[~eaopack.basic_classes.Node] = [<eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>], start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, price: str = None, extra_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, max_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_take: ~eaopack.basic_classes.StartEndValueDict = None, max_take: ~eaopack.basic_classes.StartEndValueDict = None, factors_commodities: list = [1, 1], freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: Contract

Multi commodity contract class - implements a Contract that generates two or more commoditites at a time. The main idea is to implement a CHP generating unit that would generate power and heat at the same time. Overall costs and prices relate directly (and only) to the dispatch variable. The simplest way of defining the asset is to think of the main commodity as the main variable. In this case define the first factor == 1 and add the other factors as “free side products” with the respective factor

Contract: buy or sell (consume/produce) given price and limited capacity in/out

Restrictions - time dependent capacity restrictions - MinTake & MaxTake for a list of periods Examples - with min_cap = max_cap and a detailed time series, implement must run RES assets such as wind - with MinTake & MaxTake, implement structured gas contracts

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float, dict, str) – Minimum flow/capacity for buying (negative) or selling (positive). Defaults to 0

  • max_cap (float, dict, str) –

    Maximum flow/capacity for selling (positive). Defaults to 0 float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • min_take (dict) – Minimum volume within given period. Defaults to None

  • max_take (dict) –

    Maximum volume within given period. Defaults to None dict: dict[‘start’] = np.array

    dict[‘end’] = np.array dict[‘values”] = np.array

  • price (str) – Name of price vector for buying / selling

  • extra_costs (float, dict, str) –

    extra costs added to price vector (in or out). Defaults to 0. float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

  • contract (New in comparison to)

  • nodes (Node) – different nodes the contract delivers to (one node per commodity)

  • factors_commodities – list of floats - One factor for each commodity/node. There is only one dispatch variable, factor[i]*var is the dispatch per commodity

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class OrderBook(name: str = 'default_name_order_book', nodes: ~eaopack.basic_classes.Node = <eaopack.basic_classes.Node object>, wacc: float = 0, orders: ~typing.Dict = None, full_exec: bool = False)

Bases: Asset

Contract Class

Order book: Provide a list of orders that are available for execution. Orders come with start, end (of delivery), capacity & price

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • node (Node) – Node, the constract is located in (asset parameter)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • orders (dict or pd.DataFrame) –

    Available orders for execution dict: dict[‘start’] = array of np.TimeStamps

    dict[‘end’] = array of np.TimeStamps dict[‘capa’] = array of float dict[‘price’] = array of float

  • full_exec (bool, optional) – Enforce full execution of orders (defaults to False - partial execution allowed)

abstract setup_optim_problem(prices: dict = None, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio –> not required here, for compatibility

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class Plant(name: str = 'default_name_plant', nodes: ~typing.List[~eaopack.basic_classes.Node] = [<eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>], start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, price: str = None, extra_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, max_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_take: ~eaopack.basic_classes.StartEndValueDict = None, max_take: ~eaopack.basic_classes.StartEndValueDict = None, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None, ramp: float = None, start_costs: float | ~typing.Sequence[float] | ~eaopack.basic_classes.StartEndValueDict = 0.0, running_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_runtime: float = 0, time_already_running: float = 0, min_downtime: float = 0, time_already_off: float = 0, last_dispatch: float = 0, start_ramp_lower_bounds: ~typing.Sequence = None, start_ramp_upper_bounds: ~typing.Sequence = None, shutdown_ramp_lower_bounds: ~typing.Sequence = None, shutdown_ramp_upper_bounds: ~typing.Sequence = None, ramp_freq: str = None, start_fuel: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, fuel_efficiency: float | ~eaopack.basic_classes.StartEndValueDict | str = 1.0, consumption_if_on: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, **kwargs)

Bases: CHPAsset

Plant: Generate power (or another commodity) from fuel (fuel optional). Derived from more complex CHP, taking out heat

Restrictions - time dependent capacity restrictions - MinTake & MaxTake for a list of periods - start costs - minimum runtime - ramps

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • nodes (Node) – One node for generated power (asset parameter) optional: node for fuel (e.g. gas)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float) – Minimum capacity for generating virtual dispatch (power + conversion_factor_power_heat * heat). Has to be greater or equal to 0. Defaults to 0.

  • max_cap (float) – Maximum capacity for generating virtual dispatch (power + conversion_factor_power_heat * heat). Has to be greater or equal to 0. Defaults to 0.

  • min_take (float) – Minimum volume within given period. Defaults to None

  • max_take (float) –

    Maximum volume within given period. Defaults to None float: constant value dict: dict[‘start’] = np.array

    dict[‘end’] = np.array dict[‘values”] = np.array

  • price (str) – Name of price vector for buying / selling

  • extra_costs (float, dict, str) –

    extra costs added to price vector (in or out). Defaults to 0. float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values”] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

  • ramp (float) – Maximum increase/decrease of virtual dispatch (power + conversion_factor_power_heat * heat) in one timestep. Defaults to 1.

  • start_costs (float) – Costs for starting. Defaults to 0.

  • running_costs (float) – Costs when on. Defaults to 0.

  • min_runtime (int) – Minimum runtime in timegrids main_time_unit. (start ramp time and shutdown ramp time do not count towards the min runtime.) Defaults to 0.

  • time_already_running (int) – The number of timesteps the asset is already running in timegrids main_time_unit. Defaults to 0.

  • min_downtime (int) – Minimum downtime in timegrids main_time_unit. Defaults to 0.

  • time_already_off (int) – The number of timesteps the asset has already been off in timegrids main_time_unit. Defaults to 0.

  • last_dispatch (float) – Previous virtual dispatch (power + conversion_factor_power_heat * heat). Defaults to 0.

  • start_ramp_lower_bounds (Sequence) – The i-th element of this sequence specifies a lower bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq after starting. Defaults to None.

  • start_ramp_upper_bounds (Sequence) – The i-th element of this sequence specifies an upper bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq after starting. Defaults to None.

  • shutdown_ramp_lower_bounds (Sequence) – The i-th element of this sequence specifies a lower bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq before turning off. Defaults to None.

  • shutdown_ramp_upper_bounds (Sequence) – The i-th element of this sequence specifies an upper bound of the virtual dispatch (power + conversion_factor_power_heat * heat) at i timesteps of freq ramp_freq before turning off. If it is None, it is set equal to shutdown_ramp_upper_bounds. Defaults to None.

  • ramp_freq (str) – A string specifying the frequency of the start-and shutdown ramp specification. If this is None, the timegrids main_time_unit is used. Otherwise the start and shutdown ramps are interpolated to get values in the timegrids freq.

  • Optional – Explicit fuel consumption (e.g. gas) for multi-commodity simulation start_fuel (float, dict, str): detaults to 0 fuel_efficiency (float, dict, str): defaults to 1 consumption_if_on (float, dict, str): defaults to 0

class ScaledAsset(name: str = 'default_name_scaled_asset', base_asset: ~eaopack.assets.Asset = <eaopack.assets.Asset object>, start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0.0, min_scale: float = 0.0, max_scale: float = 1.0, norm_scale: float = 1.0, fix_costs: float = 0.0)

Bases: Asset

Scaled asset - this allows to incorporate fix costs coming with an asset, optimally choosing the size of the asset

Initialize scaled asset, which optimizes the scale of a given base asset

and fix costs associated with it

Parameters:
  • name (str) – Name of the asset. Must be unique in a portfolio

  • nodes (Union[str, List[str]]) – Nodes, in which the asset has a dispatch

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Grid for discretization

  • wacc (float, optional) – WACC to discount the cash flows as the optimization target. Defaults to 0.

  • base_asset (Asset) – Any asset, that should be scaled

  • min_scale (float, optional) – Minimum scale. Defaults to 0.

  • max_scale (float, optional) – Maximum scale. Defaults to 1.

  • norm_scale (float, optional) – Normalization (i.e. size of base_asset is divided by norm_scale). Defaults to 1.

  • fix_costs (float, optional) – Costs in currency per norm scale and per main_time_unit (in timegrid). Defaults to 0.

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class SimpleContract(name: str = 'default_name_simple_contract', nodes: ~eaopack.basic_classes.Node = <eaopack.basic_classes.Node object>, start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, price: str = None, extra_costs: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, min_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, max_cap: float | ~eaopack.basic_classes.StartEndValueDict | str = 0.0, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: Asset

Contract Class

Simple contract: given price and limited capacity in/out. No other constraints

A simple contract is able to buy or sell (consume/produce) at given prices plus extra costs up to given capacity limits

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • node (Node) – Node, the constract is located in (asset parameter)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float, dict) – Minimum flow/capacity for buying (negative)

  • max_cap (float, dict) –

    Maximum flow/capacity for selling (positive) float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values’] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • price (str) – Name of price vector for buying / selling. Defaults to None

  • extra_costs (float, dict, str) –

    extra costs added to price vector (in or out). Defaults to 0. float: constant value dict: dict[‘start’] = array

    dict[‘end’] = array dict[‘values’] = array

    str: refers to column in “prices” data that provides time series to set up OptimProblem (as for “price” below)

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days over whole weeks) (defaults to None)

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class Storage(name: str, nodes: ~eaopack.basic_classes.Node = <eaopack.basic_classes.Node object>, start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0.0, size: float = None, cap_in: float = None, cap_out: float = None, start_level: float = 0.0, end_level: float = 0.0, cost_out: float = 0.0, cost_in: float = 0.0, cost_store: float = 0.0, block_size: str = None, eff_in: float = 1.0, eff_out: float = 1.0, inflow: float = 0.0, no_simult_in_out: bool = False, max_store_duration: float = None, price: str = None, freq: str = None, max_cycles_no: float = None, max_cycles_freq: str = 'd', profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: Asset

Storage Class in Python

Specific storage asset. A storage has the basic capability to
  1. take in a commodity within a limited flow rate (capacity)

  2. store a maximum volume of a commodity (size)

  3. give out the commodity within a limited flow rate

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • node (Node) – Node, the storage is located in (asset parameter) Two nodes may be defined in case input and output are located in different nodes [node_input, node_output]

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • size (float) – maximum volume of commodity in storage.

  • cap_in (float) – Maximum flow rate for taking in a commodity

  • cap_out (float) – Maximum flow rate for taking in a commodity

  • start_level (float, optional) – Level of storage at start of optimization. Defaults to zero.

  • end_level (float, optional) – Level of storage at end of optimization. Defaults to zero.

  • cost_out (float, optional) – Cost for taking out volumes ($/volume). Defaults to 0.

  • cost_in (float, optional) – Cost for taking in volumes ($/volume). Defaults to 0.

  • cost_store (float, optional) – Cost for keeping in storage ($/volume/main time unit). Defaults to 0. Note: Cost for stored inflow is correctly optimized, but constant contribution not part of output NPV

  • block_size (str, optional) – Mainly to speed optimization, optimize the storage in time blocks. Defaults None (no blocks). Using pandas type frequency strings (e.g. ‘d’ to have a block each day)

  • eff_in (float, optional) – Efficiency taking in the commodity. Means e.g. at 90%: 1MWh in –> 0,9 MWh in storage. Defaults to 1 (=100%).

  • eff_out – Efficiency taking out the commodity. Defaults to 1 (=100%)

  • max_cycles_no (float, optional) – Maximum number of cycles the battery can perform. Defaults to None – MIP!

  • max_cycles_freq (str, optional) – Frequency of the maximum number of cycles. Example: “d” for daily cycles. Defaults to ‘d’

  • inflow (float, optional) – Constant rate of inflow volumes (flow in each time step. E.g. water inflow in hydro storage). Defaults to 0.

  • no_simult_in_out (boolean, optional) – Enforce no simultaneous dispatch in/out in case of costs or efficiency!=1. Makes problem MIP. Defaults to False

  • max_store_duration (float, optional) – Maximal duration in main time units that charged commodity can be held. Makes problem a MIP. Defaults to none

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

fill_level(optim_problem: OptimProblem, results: Results) array

Calculate fill level of the storage incl. efficiencies etc

Parameters:
  • optim_problem (OptimProblem) – optimization problem created by this asset

  • results (Results) – Results given by optimizer

Returns:

array with fill level per time step as per timegrid of asset

Return type:

np.array

setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

class Transport(name: str = 'default_name_transport', nodes: ~typing.List[~eaopack.basic_classes.Node] = [<eaopack.basic_classes.Node object>, <eaopack.basic_classes.Node object>], start: ~datetime.datetime = None, end: ~datetime.datetime = None, wacc: float = 0, costs_const: float = 0.0, costs_time_series: str = None, min_cap: float = 0.0, max_cap: float = 0.0, efficiency: float = 1.0, freq: str = None, profile: ~pandas.core.series.Series = None, periodicity: str = None, periodicity_duration: str = None)

Bases: Asset

Contract Class

Transport: Link two nodes, transporting the commodity at given efficiency and costs

Parameters:
  • name (str) – Unique name of the asset (asset parameter)

  • nodes (list of nodes) – 2 nodes, the transport links (asset parameter)

  • timegrid (Timegrid) – Timegrid for discretization (asset parameter)

  • start (dt.datetime) – start of asset being active. defaults to none (-> timegrid start relevant)

  • end (dt.datetime) – end of asset being active. defaults to none (-> timegrid start relevant)

  • wacc (float) – Weighted average cost of capital to discount cash flows in target (asset parameter)

  • freq (str, optional) – Frequency for optimization - in case different from portfolio (defaults to None, using portfolio’s freq) The more granular frequency of portf & asset is used

  • profile (pd.Series, optional) – If freq(asset) > freq(portf) assuming this profile for granular dispatch (e.g. scaling hourly profile to week). Defaults to None, only relevant if freq is not none

  • min_cap (float) – Minimum flow/capacity for transporting (from node 1 to node 2)

  • max_cap (float) – Minimum flow/capacity for transporting (from node 1 to node 2)

  • efficiency (float) – efficiency of transport. May be any positive float. Defaults to 1.

  • costs_time_series (str) – Name of cost vector for transporting. Defaults to None

  • costs_const (float, optional) – extra costs added to price vector (in or out). Defaults to 0.

  • periodicity (str, pd freq style) – Makes assets behave periodicly with given frequency. Periods are repeated up to freq intervals (defaults to None)

  • periodicity_duration (str, pd freq style) – Intervals in which periods repeat (e.g. repeat days ofer whole weeks) (defaults to None)

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

convert_time_unit(value: float, old_freq: str, new_freq: str) float

Convert time value from old_freq to new_freq :param value: the time value to convert :type value: float :param old_freq: pandas frequency string, e.g. ‘d’, ‘h’, ‘min’, ‘15min’, ‘1d1h’ :param new_freq: pandas frequency string, e.g. ‘d’, ‘h’, ‘min’, ‘15min’, ‘1d1h’

Returns:

the time value converted from old_freq to new_freq

define_restr(my_take, my_type, my_n, map, timegrid, node=None)

encapsulates the generation of restriction from given min/max take or similar

Portfolio

class LinkedAsset(portfolio: Portfolio, asset1_variable: Tuple[Asset | str, str, Node | str], asset2_variable: Tuple[Asset | str, str, Node | str], asset2_time_already_running: str | float = 'time_already_running', time_back: float = 1, time_forward: float = 0, name: str = 'default_name_linkedAsset', *args, **kwargs)

Bases: StructuredAsset

Linked asset that wraps a portfolio in one asset and poses additional constraints on variables. This can be used to ensure that one asset turns on only after another asset has been running for at least a set amount of time.

Linked asset that wraps a portfolio in one asset and poses the following additional constraints on variable v1 of asset1 and (bool) variable v2 of asset2:

v1_t <= u1_t * v2_{t+i}, for all i = -time_back,…,time_forward and timesteps t = 0,…,timegrid.T

Here, v1_t and v2_t stand for variable v1 of asset1 at timestep t and variable v2 of asset2 at timestep t, respectively. u1_t stands for the upper bound for variable v1_t as specified in asset1.

This can be used to ensure that a dispatch or “on” variable v1 is 0 (or “off”) depending on the value of an “on” variable v2. For example, it can be ensured that asset1 only turns “on” or has positive dispatch once asset2 has been running for a minimum amount of time.

Parameters:
  • portf (Portfolio) – Portfolio to be wrapped

  • nodes (nodes as in std. asset) – where to connect the asset to the outside. Must correspond to (a) node(s) of the internal structure

  • name (str) – name of the linked asset

  • asset1_variable (Tuple[Union[Asset, str], str, Union[Node, str]]) – Tuple specifying the variable v1 consisting of - asset1 (Asset, str): asset or asset_name of asset in portfolio - v1 (str): name of a variable in asset1 - node1 (Node, str): node or node_name of node in portfolio

  • asset2_variable (Tuple[Union[Asset, str], str, Union[Node, str]]) – Tuple specifying the variable v2 consisting of - asset2 (Asset, str): asset or asset_name of asset in portfolio - v2 (str): name of a bool variable in asset2 - node2 (Node, str): node or node_name of node in portfolio

  • asset2_time_already_running (Union[str, float]) – Indicating the runtime asset2 has already been running for float: the time in the timegrids main_time_unit that asset2 has been ‘on’ for str: the name of an attribute of asset2 that indicates the time asset2 has been running This defaults to “time_already_running”

  • time_back (float) – The minimum amount of time asset2 has to be running before v1 of asset1 can be > 0

  • time_forward (float) – The minimum amount of time v1 of asset1 has to be 0 before asset2 is turned off

setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

set up optimization problem for the asset

Parameters:
  • prices (dict) – dictionary of price np.arrays. dict must contain a key that corresponds to str “price” in asset (if prices are required by the asset)

  • timegrid (Timegrid) – Grid to be used for optim problem. Defaults to none

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem that may be used by optimizer

Return type:

OptimProblem

class Portfolio(assets: List[Asset])

Bases: object

The portfolio class allows for collecting several assets in a network of nodes and optimizing them jointly. In terms of setting up the problem, the portfolio collects the assets and imposes the restriction of forcing the flows of a commodity in each node to be zero in each time step

The portfolio class allows for collecting several assets in a network of nodes and optimizing them jointly. In terms of setting up the problem, the portfolio collects the assets and imposes the restriction of forcing the flows of a commodity in each node to be zero in each time step.

Parameters:

assets (List[Asset]) – Collection of the assets. The assets are assigned to nodes, which, together with ‘Transport’ assets define the network of the portfolio.

create_cost_samples(price_samples: List, timegrid: Timegrid = None) List

create costs vectors for LP on basis of price samples :param price_samples: List of dicts of price arrays :type price_samples: list :param timegrid: Discretization grid for portfolio and all assets within.

Defaults to None, in which case it must have been set previously

Returns:

list of costs vectors for use in OptimProblem (e.g. for robust optimization)

get_asset(asset_name: str) Asset

Return the asset with name asset_name or None if no asset with this name exists in the portfolio.

Parameters:

asset_name (str) – The name of the asset

Returns:

The asset with name asset_name

Return type:

asset (Asset)

get_node(node_name: str) Node

Return the node with name node_name or None if no nodes with this name exists in the portfolio.

Parameters:

node_name (str) – The name of the node

Returns:

The node with name node_name

Return type:

node (Node)

set_timegrid(timegrid: Timegrid)

Set the timegrid for the portfolio. The timegrid will be used for all asset in the portfolio. :param timegrid: The timegrid to be set :type timegrid: Timegrid

setup_optim_problem(prices: dict = None, timegrid: Timegrid = None, costs_only: bool = False, skip_nodes: list = [], fix_time_window: Dict = None) OptimProblem

Set up optimization problem for portfolio

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio. Defaults to None

  • timegrid (Timegrid, optional) – Discretization grid for portfolio and all assets within. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

  • skip_nodes (List) – Nodes to be skipped in nodal restrictions (defaults to [])

  • fix_time_window (Dict) – Fix results for given indices on time grid to given values. Defaults to None fix_time_window[‘I’]: Indices on timegrid or alternatively date (all dates before date taken) fix_time_window[‘x’]: Results.x that results are to be fixed to in time window(full array, all times)

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

setup_split_optim_problem(prices: dict = None, timegrid: Timegrid = None, interval_size: str = 'd', skip_nodes: list = [], fix_time_window: Dict = None)
Set up a split optimization problem for portfolio, i.e. split the timegrid into intervals of size

interval_size and create a separate optimization problem for each interval

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio. Defaults to None

  • timegrid (Timegrid, optional) – Discretization grid for portfolio and all assets within. Defaults to None, in which case it must have been set previously

  • interval_size (bool) – Interval size according to pandas notation (‘15min’, ‘h’, ‘d’, …). Defaults to ‘d’

  • skip_nodes (List) – Nodes to be skipped in nodal restrictions (defaults to [])

  • fix_time_window (Dict) – Fix results for given indices on time grid to given values. Defaults to None fix_time_window[‘I’]: Indices on timegrid or alternatively date (all dates before date taken) fix_time_window[‘x’]: Results.x that results are to be fixed to in time window(full array, all times)

  • Returns – SplitOptimProblem: A Split Optimization problem

class StructuredAsset(portfolio: Portfolio, *args, **kwargs)

Bases: Asset

Structured asset that wraps a portfolio in one asset Example: hydro storage with inflow consisting of several linked storage levels

Structured asset that wraps a portfolio

Parameters:
  • portf (Portfolio) – Portfolio to be wrapped

  • nodes (nodes as in std. asset) – where to connect the asset to the outside. Must correspond to (a) node(s) of the internal structure

abstract setup_optim_problem(prices: dict, timegrid: Timegrid = None, costs_only: bool = False) OptimProblem

Set up optimization problem for asset

Parameters:
  • prices (dict) – Dictionary of price arrays needed by assets in portfolio

  • timegrid (Timegrid, optional) – Discretization grid for asset. Defaults to None, in which case it must have been set previously

  • costs_only (bool) – Only create costs vector (speed up e.g. for sampling prices). Defaults to False

Returns:

Optimization problem to be used by optimizer

Return type:

OptimProblem

Optimization

class OptimProblem(c: array, l: array, u: array, A: array = None, b: array = None, cType: str = None, mapping: DataFrame = None, timegrid: Timegrid = None, periodic_period_length: str = None, periodic_duration: str = None, map_nodal_restr: list = None)

Bases: object

Formulated optimization problem. LP problem.

Parameters:
  • c (np.array) – cost vector

  • l (np.array) – lower bound (per time step)

  • u (np.array) – upper bound (per time step)

  • A (np.array) – restiction matrix. Optional. Defaults to None (no restrictions given)

  • b (np.array) – bound of restriction. Optional. Defaults to None (no restrictions given)

  • cType (str - one letter per restriction) –

    Logic to define type of restriction: U-pper, L-ower, S-equal or other here specific types may be defined:

    sum of dispatch at node zero: N

    Optional. Defaults to None (no restrictions given)

  • mapping (pd.DataFrame) – Mapping of variables to ‘asset’, ‘node’, ‘type’ (‘d’ - dispatch and ‘i’ internal variable) and ‘time_step’

  • map_nodal_restr (list) – Mapping to identify node and timepoint for duals in the solution of the LP

  • periodic (--- if)

  • timegrid (Timegrid) – timegrid underneath optim problem (defaults to None)

  • periodic_period_length (str) – pandas freq defining the period length (defaults to None)

  • periodic_duration (str) – pandas freq defining the duration of intervals in which periods are repeated (defaults to None - then duration is inf)

optimize(target='value', samples=None, interface: str = 'cvxpy', solver=None, make_soft_problem=False, solver_params=None) Results

optimize the optimization problem

Parameters:
  • target (str) – Target function. Defaults to ‘value’ (maximize DCF). Alternative: ‘robust’, maximizing the minimum DCF across given price samples

  • samples (List) – Samples to be used in specific optimization targets - Robust optimization: list of costs arrays (maximizing minimal DCF)

  • interface (str, optional) – Chosen interface architecture. Defaults to ‘cvxpy’.

  • solver (str, optional) – Solver for interface. Defaults to None

  • make_soft_problem (bool, optional) – If true, relax the boolean variables and allow float values instead. Defaults to False

class Results(value: float, x: array, duals: dict)

Bases: object

collection of optimization results

Parameters:
  • value (float) – value of optimized target function

  • x (np.array) – optimal values of variables

  • duals (dict) – dual values for constraints. Dict with constraint types as keys (mostly interesting ‘N’ for nodes)

class SplitOptimProblem(ops, mapping)

Bases: OptimProblem

Collection of consecutive OptimProblems

Parameters:
  • ops – List of OptimProblems

  • mapping (pd.DataFrame) – Mapping of all result variables to ‘asset’, ‘node’, ‘type’ (‘d’ - dispatch and ‘i’ internal variable) and ‘time_step’

optimize(*args, **kwargs) Results

Optimize all OptimProblems in self.ops and piece the results together in one Result

Basic classes

class Node(name: str, commodity: str = None, unit: ~eaopack.basic_classes.Unit = <eaopack.basic_classes.Unit object>)

Bases: object

Class to define a node in the optimization problem. A node is a (virtual) point, where

assets are located. In a node, the sum of all commodity flows must be zero. Only one commodity may be present in each node. Per node we also define the units to be used for capacity (volume/energy and flow/capacity). Examples are MWh and MW or liters and liters per minute.

Parameters:
  • name (str) – Name of the node (must be unique in the portfolio)

  • commodity (str) – Commodity traded in the node. None possible if there is no distinction. Defaults to None

  • unit (Unit) – Units used in the node. Defaults to default unit

class StartEndValueDict

Bases: TypedDict

New type to contain info of the type start, end, value dict with

start: array of datetime end: array of datetime (optional) values: array of floats

end: Sequence[datetime]
start: Sequence[datetime]
class Timegrid(start: datetime, end: datetime, freq: str = 'h', main_time_unit='h', ref_timegrid=None, timezone: str = None)

Bases: object

Manage the timegrid used for optimization.

Parameters:
  • start (dt.datetime) – Start datetime

  • end (dt.datetime) – End datetime

  • freq (str, optional) – Frequency for discretization according to pandas notation (‘15min’, ‘h’, ‘d’, …). Defaults to ‘h’

  • main_time_unit (str, optional) – All times in the optimization problem are measured in the main_time_unit. Pandas notation. Defaults to ‘h’

  • timezone – Timezone for times. String according to pandas tz definitions (e.g. CET). Defaults to None (naive timezone)

  • ref_timegrid (Timegrid, optional) – reference TG in case this timegrid is a subset of a suber grid

Returns:

specific points in time of mesh T (float): number of time steps dt (np.array): time step for each step Dt (np.array): cummulative time steps (total duration since start)

Return type:

timepoints (daterange)

prep_date_dict(dd: dict)
Using dicts with keys “start”, “end” and “values” throughout. Could change to an own classe

but so far sticking to this definition. This function converts the dict e.g. by changing to timegrid time zone

Parameters:

dd (dict) – date dict – dict with keys “start’, “end”, “values”

Returns:

date dict with same keys

prices_to_grid(prices: dict)

Convert prices into a dataframe with index self.timepoints. If the price points already have (possibly different) timepoints, then the prices at self.timepoints are interpolated.

Parameters:

prices

This can be either a pandas dataframe with a Datetimeindex where each column corresponds to a price, or a dictionary of prices. In the case of a dict, the items can have the following forms: - array of length self.T. In this case it is assumed that the i-th entry of the array corresponds to the

i-th point in self.timepoints.

  • dict where the keys are timepoints and the corresponding items depict the prices at the specific

    timepoints

Return type:

prices

set_restricted_grid(start: datetime = None, end: datetime = None, freq: bool = None)
return dictionary of arrays restricted to start/end

used typically for assets valid in restricted timeframe

Parameters:
  • start (dt.datetime) – start and end of restricted arrays. Default to None –> full timegrid’s start/end

  • end (dt.datetime) – start and end of restricted arrays. Default to None –> full timegrid’s start/end

  • freq (bool, optional) – frequency for restr. timegrid. may be chosen less granular than tg. Defaults to None

set_wacc(wacc: float)

use wacc to create discount factors for discounted cash flows :param wacc: weighted average cost of capital :type wacc: float

values_to_grid(inp: StartEndValueDict) array

Assignment of data from interval data to timegrid :param inp: each defining time interval where value is to be used :type inp: dict

Returns:

array of values on the time grid

class Unit(volume: str = 'MWh', flow: str = 'MW', factor: float = 1.0)

Bases: object

Defines the units used in a node and how to convert between volums and flows (volume/time)

Parameters:
  • volume (str, optional) – ‘volume’ is a quantity unit, typically MWh or MJ for energy. Defaults to ‘MWh’.

  • flow (str, optional) – ‘flow’ is a quantity per time unit, typically MW (J/s) for energy. Defaults to ‘MW’.

  • factor (float, optional) – ‘factor’ is measured in the <main time unit> of the optimization problem (default ‘h’). It is the value of (volume/flow). Defaults to 1 <basic time unit>. The factor for conversions may prove very handy, particularly with multi commodity models however, it is not implemented yet. We included the factor to ensure at the start that only unit valid choices with factor 1 are used. Conversion to be added in later version

Input and output

extract_output(portf: Portfolio, op: OptimProblem, res: Results, prices: dict = None) dict
extract results into dataframes, containing readable

results such as asset dispatch and dcf

Parameters:
  • portf (Portfolio) – portfolio optimized

  • op (OptimProblem) – optimization problem

  • res (Results) – result

  • prices (dict) – used prices. Defaults to None if not to be added to output

Returns: dictionary with results

disp: dataframe with dispatch per asset internal_variables: dataframe with internal variables per asset dcfs: dataframe with discounted cash flows per asset prices: dataframe with nodal prices and given prices special: dataframe with specific asset parameters (such as size in scaled assets)

get_param(obj, path)

get specific parameter from an object using the path as generated from get_params_tree

Parameters:

path (_type_) – list down to parameter as given by get_params_tree (e.g. [asset, timegrid, start] –> value)

get_params_tree(obj) List | Dict

get parameters of object - typically asset or portfolio

Parameters:

obj (object) – object to analyze

Returns

dict of parameters (nested) list of parameter names (nested)

optimize(portf: Portfolio, timegrid: Timegrid, data=None, split_interval_size=None, solver=None) Dict

Optimization shortcut: Cast data into timegrid, do the optimization and extract the results in one go

Parameters:
  • portf (Portfolio) – The portfolio to be optimized

  • timegrid (Timegrid) – Timegrid for optimization

  • data (StartEndValueDict, DataFrame, optional) – input time series. Defaults to None (optional). Will be cast into timegrid

  • split_interval_size (str, optional, default to None) – Interval size for split optimization Hard cut of optimization into time split for faster calculation. Pandas convention ‘d’, ‘h’, ‘W’, … (none for no split)

  • solver (str, optional) – Solver to be used. Defaults to None (uses default solver)

Returns: Output dictionary with keys (if optimization feasible):
  • summary

  • dispatch

  • DCF (discounted cash flows)

  • prices

  • asset internal variables

  • special variables

output_to_file(output, file_name: str, format_output: str = 'xlsx', csv_ger: bool = False)

write extracted output to file(s)

Parameters:
  • output ([type]) – Target file (excel)

  • file_name (str) – file name

  • format_output (str) – xlsx, csv. format of output file. Defaults to ‘xlsx’

  • csv_ger (bool) – English (False) or German (True) csv format. Defaults to False.

set_param(obj, path, value)

Set parameters of EAO objects. Limited checks, but facilitating managing nested objects such as portfolios or assets

Parameters:

obj (object) – Object to manipulate

Returns:

Manipulated object status (bool): True - > successful, False -> not successful

Return type:

obj (object)

Serialization

json_deserialize_objects(obj)
json_serialize_objects(obj) dict

serialization function for JSON :param obj: object to be serialized :type obj: [type]

Returns:

serialized object for json

Return type:

dict

load_from_json(json_str: str = None, file_name: str = None)

create object from JSON in file or string :param file_name: Filename containing json string. Optional :type file_name: str :param json_str: json string. Optional

one of the two must be given

Returns:

object

run_from_json(json_str: str = None, file_name_in: str = None, prices: dict = None, timegrid: Timegrid = None, file_name_out: str = None, format_out: str = 'xlsx', csv_ger: bool = False)
  1. create object from JSON in file or string (2) run optimization (3) write output to file (if file name given)

Parameters:
  • file_name_in (str) – Filename containing json string. Optional

  • json_str (str) – json string. Optional one of the two must be given

  • prices (dict) – dict of prices to be used for optimization

  • timegrid (Timegrid) – timegrid to be used for optimization. Defaults to None (if portfolio comes with timegrid)

  • file_name_out (str) – file name for output

  • format_out (str) – xlsx, csv. format of output file. Defaults to ‘xlsx’

  • csv_ger (bool) – English (False) or German (True) csv format. Defaults to False.

Returns:

Optimization run successfully (bool) no file_name_out given: Results dict

Return type:

file_name_out given

to_json(obj, file_name=None)

serialize object to JSON and save to file

Parameters:
  • obj – json serializable object

  • file_name (str) – Filename. Defaults to None (return str)

Stochastic linear program

make_slp(optim_problem: OptimProblem, portf: Portfolio, timegrid: Timegrid, start_future: datetime, samples: List[Dict]) OptimProblem

Create a two stage SLP (stochastic linear program) from a given OptimProblem

Parameters:
  • optim_problem (OptimProblem) – start problem

  • portf (Portfolio) – portfolio that is the basis of the optim_problem (e.g. to translate price samples to effect on LP)

  • timegrid (TimeGrid) – timegrid consistent with optimproblem

  • start_future (dt.datetime) – divides timegrid into present with certain prices and future with uncertain prices, represented by samples

  • samples (List[Dict]) – price samples for future. (!) the future part of the original portfolio is added as an additional sample

Returns:

Two stage SLP formulated as OptimProblem

Return type:

OptimProblem

Network graphs

create_graph(portf: Portfolio, file_name: str = None, title=None, no_image_output=False)

generate a network graph from a portfolio and save to pdf

Parameters:
  • portf (Portfolio) – portfolio object

  • file_name (str) – file name. Defaults to None (show plot)

  • title (str) – plot title. Defaults to -Network graph for portfolio-

  • no_image_output (bool, optional) – no creation of graph, only return graph data