Test Inventory#

Our optimizer is automatically tested with 574 test cases. Below is an overview of these tests, grouped by module.

tests/test_absolute_soe.py#

Test Name

Description (Risk/Safety Check)

test_​capacity_​nominal_​with_​capacity_​schedule

No description available.

test_​capacity_​nominal_​with_​fixed_​capacity

No description available.

test_​no_​capacity_​nominal_​with_​capacity_​schedule

No description available.

test_​capacity_​nominal_​is_​optional_​and_​defaults_​to_​single_​capacity

No description available.

test_​initial_​soe_​kwh_​default

No description available.

test_​initial_​soe_​kwh_​must_​match_​initial_​soe

No description available.

test_​asset_​state_​soe_​target_​kwh_​default

No description available.

test_​asset_​state_​soe_​target_​kwh_​must_​match_​fraction

No description available.

tests/test_app/test_endpoints.py#

Test Name

Description (Risk/Safety Check)

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.PNL: 'pnl'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.MELMIL: 'melmil'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.MELMILBOA: 'melmilboa'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.BOD: 'bod'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.MELMILNOW: 'melmilnow'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'asyncio'

  • problem_type: <ProblemType.AFRR_ENERGY: 'afrr_energy'>

No description available.

test_​send_​max_​daily_​cycle_​requests_​to_​optimize_​endpoint

Parameters:

  • anyio_backend: 'asyncio'

  • fixture_name: 'request_2025_10_23_max_daily_cycle_parsing'

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/110129

test_​send_​max_​daily_​cycle_​requests_​to_​optimize_​endpoint

Parameters:

  • anyio_backend: 'asyncio'

  • fixture_name: 'request_2025_10_23_payload_vpp_utils'

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/110129

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.PNL: 'pnl'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.MELMIL: 'melmil'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.MELMILBOA: 'melmilboa'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.BOD: 'bod'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.MELMILNOW: 'melmilnow'>

No description available.

test_​optimize_​endpoint_​problem_​type_​supported

Parameters:

  • anyio_backend: 'trio'

  • problem_type: <ProblemType.AFRR_ENERGY: 'afrr_energy'>

No description available.

test_​send_​max_​daily_​cycle_​requests_​to_​optimize_​endpoint

Parameters:

  • anyio_backend: 'trio'

  • fixture_name: 'request_2025_10_23_max_daily_cycle_parsing'

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/110129

test_​send_​max_​daily_​cycle_​requests_​to_​optimize_​endpoint

Parameters:

  • anyio_backend: 'trio'

  • fixture_name: 'request_2025_10_23_payload_vpp_utils'

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/110129

tests/test_availabilities.py#

Test Name

Description (Risk/Safety Check)

test_​availability_​preprocessing_​modifies_​power_​limits

Parameters:

  • optimizer_class: <class 'battery_optimizer.uk.battery_optimization.UKBatteryOptimizer'>

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • country_fixture: 'request_epex_only_no_dc_prices'

Test that availability preprocessing correctly sets power limits to zero when availability is false.

test_​availability_​preprocessing_​modifies_​power_​limits

Parameters:

  • optimizer_class: <class 'battery_optimizer.de.battery_optimization.DEBatteryOptimizer'>

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • country_fixture: 'request_2025_07_11_de_test_day_ahead_request'

Test that availability preprocessing correctly sets power limits to zero when availability is false.

test_​optimization_​with_​limited_​availability_​basic

Parameters:

  • optimizer_class: <class 'battery_optimizer.uk.battery_optimization.UKBatteryOptimizer'>

  • country_fixture: 'request_epex_only_no_dc_prices'

Test optimization with availability constraints.

test_​optimization_​with_​limited_​availability_​basic

Parameters:

  • optimizer_class: <class 'battery_optimizer.de.battery_optimization.DEBatteryOptimizer'>

  • country_fixture: 'request_2025_07_11_de_test_day_ahead_request'

Test optimization with availability constraints.

test_​solver_​with_​varying_​unavailable_​periods

Parameters:

  • unavailable_ratio: 0.2

Test solver behavior with different amounts of unavailable periods.

test_​solver_​with_​varying_​unavailable_​periods

Parameters:

  • unavailable_ratio: 0.5

Test solver behavior with different amounts of unavailable periods.

test_​solver_​with_​varying_​unavailable_​periods

Parameters:

  • unavailable_ratio: 0.8

Test solver behavior with different amounts of unavailable periods.

test_​solver_​with_​varying_​unavailable_​periods

Parameters:

  • unavailable_ratio: 0.9

Test solver behavior with different amounts of unavailable periods.

test_​solver_​with_​varying_​unavailable_​periods

Parameters:

  • unavailable_ratio: 1.0

Test solver behavior with different amounts of unavailable periods.

tests/test_commercial_objectives.py#

Test Name

Description (Risk/Safety Check)

test_​de_​commercial_​objectives_​threshold

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - if no commercial objectives are defined, the optimization runs as usual - if the commercial objectives threshold is not reached, no trading takes place The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​de_​commercial_​objectives_​threshold

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - if no commercial objectives are defined, the optimization runs as usual - if the commercial objectives threshold is not reached, no trading takes place The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​de_​commercial_​objectives_​threshold

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - if no commercial objectives are defined, the optimization runs as usual - if the commercial objectives threshold is not reached, no trading takes place The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​objective_​span_​contains_​min_​revenue_​per_​sell_​adjustment

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

In this test we are testing that get_result_dict trace span contains the min_revenue_per_sell_adjustment_total objective.

test_​objective_​span_​contains_​min_​revenue_​per_​sell_​adjustment

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

In this test we are testing that get_result_dict trace span contains the min_revenue_per_sell_adjustment_total objective.

test_​objective_​span_​contains_​min_​revenue_​per_​sell_​adjustment

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

In this test we are testing that get_result_dict trace span contains the min_revenue_per_sell_adjustment_total objective.

test_​objective_​span_​contains_​min_​revenue_​per_​sell_​adjustment

Parameters:

  • associated_fixture: 'request_result_prod_dc_n2ex1h_2025_01_21'

In this test we are testing that get_result_dict trace span contains the min_revenue_per_sell_adjustment_total objective.

test_​objective_​span_​contains_​min_​revenue_​per_​sell_​adjustment

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead'

In this test we are testing that get_result_dict trace span contains the min_revenue_per_sell_adjustment_total objective.

test_​objective_​span_​results_​are_​the_​close_​enough_​to_​dataframe_​results

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test checks that the pnl based on the objective values in the get_result_dict span and the pnl based on the results dataframe are close enough.

test_​objective_​span_​results_​are_​the_​close_​enough_​to_​dataframe_​results

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

This test checks that the pnl based on the objective values in the get_result_dict span and the pnl based on the results dataframe are close enough.

test_​objective_​span_​results_​are_​the_​close_​enough_​to_​dataframe_​results

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

This test checks that the pnl based on the objective values in the get_result_dict span and the pnl based on the results dataframe are close enough.

test_​de_​commercial_​objectives_​threshold_​change_​in_​relative_​pnl

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - the relative pnl per sell position increases when a commercial objective threshold is set - the sell positions decrease when a commercial objective threshold is set The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​de_​commercial_​objectives_​threshold_​change_​in_​relative_​pnl

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - the relative pnl per sell position increases when a commercial objective threshold is set - the sell positions decrease when a commercial objective threshold is set The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​de_​commercial_​objectives_​threshold_​change_​in_​relative_​pnl

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - the relative pnl per sell position increases when a commercial objective threshold is set - the sell positions decrease when a commercial objective threshold is set The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​uk_​commercial_​objectives_​threshold_​change_​in_​relative_​pnl

Parameters:

  • associated_fixture: 'request_result_prod_dc_n2ex1h_2025_01_21'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - the relative pnl per sell position increases when a commercial objective threshold is set - the sell positions decrease when a commercial objective threshold is set The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​uk_​commercial_​objectives_​threshold_​change_​in_​relative_​pnl

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead'

This test shows the behavior of the commercial objectives threshold. The expected behaviour is: - the relative pnl per sell position increases when a commercial objective threshold is set - the sell positions decrease when a commercial objective threshold is set The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​de_​set_​commercial_​objectives_​dont_​get_​changed

Parameters:

  • market_for_battery_commercials: 'epexIDA1'

This test checks that when setting commercial objectives for different markets, the values for the other markets are set to the default value (currently 0.01). And when setting for both markets, both values are set correctly and don’t get overwritten.

test_​de_​set_​commercial_​objectives_​dont_​get_​changed

Parameters:

  • market_for_battery_commercials: 'intraday'

This test checks that when setting commercial objectives for different markets, the values for the other markets are set to the default value (currently 0.01). And when setting for both markets, both values are set correctly and don’t get overwritten.

test_​de_​set_​commercial_​objectives_​dont_​get_​changed

Parameters:

  • market_for_battery_commercials: 'both'

This test checks that when setting commercial objectives for different markets, the values for the other markets are set to the default value (currently 0.01). And when setting for both markets, both values are set correctly and don’t get overwritten.

test_​that_​min_​revenue_​sell_​prohibits_​small_​pnl

Parameters:

  • associated_fixture: 'get_request_and_result_for_uk_with_very_small_pnl'

This test checks that when setting a min revenue per sell that is higher than the relative pnl per sell, the optimizer avoids trading and the resulting pnl is lower than without the threshold. Additionally, it checks that the position change in the intraday market corresponds to the expected position change based on initial SoE and target SoE.

tests/test_datetime_records_to_dataframe.py#

Test Name

Description (Risk/Safety Check)

test_​datetime_​records_​to_​dataframe_​empty_​df

No description available.

test_​datetime_​records_​to_​dataframe_​records

No description available.

test_​datetime_​records_​to_​dataframe_​less_​than_​three

No description available.

test_​datetime_​records_​to_​dataframe_​non_​empty_​df

No description available.

test_​datetime_​records_​to_​dataframe_​index_​set

No description available.

test_​datetime_​records_​to_​dataframe_​index_​column_​missing

No description available.

tests/test_efa_blocks.py#

Test Name

Description (Risk/Safety Check)

test_​settlement_​period_​id_​within_​efa_​block

No description available.

tests/test_request_asset_validation.py#

Test Name

Description (Risk/Safety Check)

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • field: 'asset_id'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • field: 'battery_parameters'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • field: 'battery_initial_conditions'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • field: 'strategy_optimization'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • field: 'asset_id'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • field: 'battery_parameters'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • field: 'battery_initial_conditions'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​asset_​validation

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • field: 'strategy_optimization'

  • invalid_value: None

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • soe_target: 0.18

  • min_soe: 0.2

  • max_soe: 0.9

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • soe_target: 0.9

  • min_soe: 0.2

  • max_soe: 0.8

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • soe_target: 0.428

  • min_soe: 0.2

  • max_soe: 0.15

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • soe_target: 0.18

  • min_soe: 0.2

  • max_soe: 0.9

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • soe_target: 0.9

  • min_soe: 0.2

  • max_soe: 0.8

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

test_​validate_​asset_​state_​soe_​targets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • soe_target: 0.428

  • min_soe: 0.2

  • max_soe: 0.15

  • should_raise: True

Test to validate if soe targets for asset state exceed boundaries (min & max).

tests/test_request_strategy_optimization.py#

Test Name

Description (Risk/Safety Check)

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • frequency: 25

  • should_raise: True

Test to ensure minimum frequency validation error raised.

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • frequency: Timedelta('0 days 00:15:00')

  • should_raise: True

Test to ensure minimum frequency validation error raised.

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • frequency: 30

  • should_raise: False

Test to ensure minimum frequency validation error raised.

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • frequency: 25

  • should_raise: True

Test to ensure minimum frequency validation error raised.

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • frequency: Timedelta('0 days 00:15:00')

  • should_raise: True

Test to ensure minimum frequency validation error raised.

test_​validation_​min_​frequency

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • frequency: 30

  • should_raise: False

Test to ensure minimum frequency validation error raised.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • invalid_markets: 'string_market'

Test to ensure markets validation error is raised for invalid values.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • invalid_markets: {datetime.datetime(2025, 4, 1, 0, 0): 'not_a_set'}

Test to ensure markets validation error is raised for invalid values.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • invalid_markets: ['market1', 'market2']

Test to ensure markets validation error is raised for invalid values.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • invalid_markets: 'string_market'

Test to ensure markets validation error is raised for invalid values.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • invalid_markets: {datetime.datetime(2025, 4, 1, 0, 0): 'not_a_set'}

Test to ensure markets validation error is raised for invalid values.

test_​validation_​markets

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • invalid_markets: ['market1', 'market2']

Test to ensure markets validation error is raised for invalid values.

test_​validation_​end_​greater_​than_​start

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

Test to ensure horizon start and end daterange validation error raised.

test_​validation_​end_​greater_​than_​start

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

Test to ensure horizon start and end daterange validation error raised.

test_​validation_​horizon_​min_​max_​in_​trader_​exclusion_​timeframe

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

Test to ensure horizon min max trade exclusion timeframe validation error raised.

test_​validation_​horizon_​min_​max_​in_​trader_​exclusion_​timeframe

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

Test to ensure horizon min max trade exclusion timeframe validation error raised.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 1, 22, 59, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 2, 23, 30, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 4, 23, 30, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 1, 22, 59, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 2, 23, 30, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

test_​validation_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • start: datetime.datetime(2025, 4, 1, 23, 0, tzinfo=datetime.timezone.utc)

  • end: datetime.datetime(2025, 4, 4, 23, 30, tzinfo=datetime.timezone.utc)

  • should_raise: True

Test to ensure OptimizationHorizon validation error is raised for invalid start and end times.

tests/test_request_validation.py#

Test Name

Description (Risk/Safety Check)

test_​working_​request

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

Test that a working request will throw no validation error.

test_​working_​request

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

Test that a working request will throw no validation error.

test_​validation_​ensure_​soc_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'max_soe'

Test to check battery max soe and min soe in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​soc_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'min_soe'

Test to check battery max soe and min soe in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​soc_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'max_soe'

Test to check battery max soe and min soe in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​soc_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'min_soe'

Test to check battery max soe and min soe in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​efficiency_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'charging_efficiency'

Test to check battery efficiency range in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​efficiency_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'discharging_efficiency'

Test to check battery efficiency range in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​efficiency_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'charging_efficiency'

Test to check battery efficiency range in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​efficiency_​rate_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'discharging_efficiency'

Test to check battery efficiency range in expected range; otherwise, raise a validation error.

test_​validation_​max_​daily_​cycle_​feasible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

Test to check battery max daily cycle is feasible; otherwise, raise a validation error.

test_​validation_​max_​daily_​cycle_​feasible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

Test to check battery max daily cycle is feasible; otherwise, raise a validation error.

test_​validation_​ensure_​max_​daily_​cycles_​errors_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • max_daily_cycle: [{'date': '2023-01-17', 'max_daily_cycle': -1.0}, {'date': '2023-01-18', 'max_daily_cycle': 0.5}, {'date': '2023-01-19', 'max_daily_cycle': 1.0}]

  • should_raise: True

Test to check battery max daily cycle optimal in optimization horizon; otherwise, raise a validation error.

test_​validation_​ensure_​max_​daily_​cycles_​errors_​optimization_​horizon

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • max_daily_cycle: [{'date': '2023-01-17', 'max_daily_cycle': -1.0}, {'date': '2023-01-18', 'max_daily_cycle': 0.5}, {'date': '2023-01-19', 'max_daily_cycle': 1.0}]

  • should_raise: True

Test to check battery max daily cycle optimal in optimization horizon; otherwise, raise a validation error.

test_​ensure_​initial_​market_​commitments_​respect_​initial_​soe

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • initial_soe: 50

  • min_soe: 10

  • max_soe: 90

  • capacity_kwh: 100

  • sold_energy: 80

  • buy_energy: 0

  • should_raise: True

Test to ensure initial market commitment respect soe and value error raised.

test_​ensure_​initial_​market_​commitments_​respect_​initial_​soe

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • initial_soe: 80

  • min_soe: 10

  • max_soe: 90

  • capacity_kwh: 100

  • sold_energy: 0

  • buy_energy: 80

  • should_raise: True

Test to ensure initial market commitment respect soe and value error raised.

test_​ensure_​initial_​market_​commitments_​respect_​initial_​soe

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • initial_soe: 50

  • min_soe: 10

  • max_soe: 90

  • capacity_kwh: 100

  • sold_energy: 80

  • buy_energy: 0

  • should_raise: True

Test to ensure initial market commitment respect soe and value error raised.

test_​ensure_​initial_​market_​commitments_​respect_​initial_​soe

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • initial_soe: 80

  • min_soe: 10

  • max_soe: 90

  • capacity_kwh: 100

  • sold_energy: 0

  • buy_energy: 80

  • should_raise: True

Test to ensure initial market commitment respect soe and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2025, 1, 2, 0, 0)

  • should_raise: False

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2025, 1, 1, 0, 0)

  • should_raise: True

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2024, 1, 1, 0, 0)

  • should_raise: True

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2025, 1, 2, 0, 0)

  • should_raise: False

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2025, 1, 1, 0, 0)

  • should_raise: True

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​settlement_​periods_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • horizon_start: datetime.datetime(2025, 1, 1, 0, 0)

  • horizon_end: datetime.datetime(2024, 1, 1, 0, 0)

  • should_raise: True

Test to ensure asset states settlement period are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • min_soe: 0.1

  • soe_target: 0.456

  • max_soe: 0.9

Test to ensure asset states soe are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • min_soe: 0.9

  • soe_target: 0.457

  • max_soe: 0.9

Test to ensure asset states soe are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • min_soe: 0.225

  • soe_target: 0.112

  • max_soe: 0.85

Test to ensure asset states soe are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • min_soe: 0.1

  • soe_target: 0.456

  • max_soe: 0.9

Test to ensure asset states soe are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • min_soe: 0.9

  • soe_target: 0.457

  • max_soe: 0.9

Test to ensure asset states soe are sensible and value error raised.

test_​ensure_​asset_​state_​soe_​are_​sensible

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • min_soe: 0.225

  • soe_target: 0.112

  • max_soe: 0.85

Test to ensure asset states soe are sensible and value error raised.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'max_charging_power_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'max_discharging_power_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'capacity_kwh'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'grid_connection_export_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

  • key: 'grid_connection_import_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'max_charging_power_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'max_discharging_power_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'capacity_kwh'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'grid_connection_export_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​charging_​power_​in_​range

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

  • key: 'grid_connection_import_kw'

Test to check battery max charging & discharging power in expected range; otherwise, raise a validation error.

test_​rounding_​of_​price_​forecasts

Parameters:

  • request_class: <class 'battery_optimizer.uk.request.UKRequest'>

Test that a working request will throw no validation error.

test_​rounding_​of_​price_​forecasts

Parameters:

  • request_class: <class 'battery_optimizer.de.request.DERequest'>

Test that a working request will throw no validation error.

tests/test_result_max_charging_power_kw.py#

Test Name

Description (Risk/Safety Check)

test_​get_​soe_​with_​series_​max_​charging_​power_​kw_​deoptimizer

Integration test: Use DEBatteryOptimizer to test that result.get_soe works correctly when max_charging_power_kw is a Series (time-dependent).

tests/test_scip.py#

Test Name

Description (Risk/Safety Check)

test_​scip_​cmd_​solves_​simple_​linear_​problem

Minimal PuLP test solved by SCIP_CMD. Builds a 1-variable LP: max x s.t. x <= 1, x >= 0 Expects optimal solution x = 1.

tests/test_slack_rebuild.py#

Test Name

Description (Risk/Safety Check)

test_​constraint_​rebuild_​no_​inplace_​modification

Parameters:

  • constraint_sense: '=='

No description available.

test_​constraint_​rebuild_​no_​inplace_​modification

Parameters:

  • constraint_sense: '<='

No description available.

test_​constraint_​rebuild_​no_​inplace_​modification

Parameters:

  • constraint_sense: '>='

No description available.

test_​double_​call_​guard

No description available.

tests/test_time_dependent_battery_parameters.py#

Test Name

Description (Risk/Safety Check)

test_​all_​floats_​converted_​to_​series

No description available.

test_​series_​with_​correct_​index_​passes

No description available.

test_​series_​with_​wrong_​index_​raises

No description available.

test_​time_​varying_​capacity_​kwh

No description available.

tests/test_upper_bound_risk_increment.py#

Test Name

Description (Risk/Safety Check)

test_​upper_​bound_​risk_​increment_​effect_​on_​buy_​sell_​limits

This test checks that the failing buy/sell limits issue on 2025-10-14 is resolved

test_​computation_​of_​upper_​bound_​risk_​increment

Parameters:

  • max_charging_kw: 10000

  • max_discharging_kw: 15000

This test checks that the upper bound risk increment is computed correctly when not set by the user

test_​computation_​of_​upper_​bound_​risk_​increment

Parameters:

  • max_charging_kw: 15000

  • max_discharging_kw: 10000

This test checks that the upper bound risk increment is computed correctly when not set by the user

test_​computation_​of_​upper_​bound_​risk_​increment

Parameters:

  • max_charging_kw: 20000

  • max_discharging_kw: 30000

This test checks that the upper bound risk increment is computed correctly when not set by the user

test_​computation_​of_​upper_​bound_​risk_​increment

Parameters:

  • max_charging_kw: 30000

  • max_discharging_kw: 20000

This test checks that the upper bound risk increment is computed correctly when not set by the user

test_​upper_​bound_​risk_​increment_​not_​changed_​when_​already_​set

Parameters:

  • preset_expected_upper_bound_risk_increment: 2.0

  • max_charging_kw: 10000

  • max_discharging_kw: 15000

This test checks that the value of upper bound risk increment is not changed when already set in the received request

test_​upper_​bound_​risk_​increment_​not_​changed_​when_​already_​set

Parameters:

  • preset_expected_upper_bound_risk_increment: 3.0

  • max_charging_kw: 15000

  • max_discharging_kw: 10000

This test checks that the value of upper bound risk increment is not changed when already set in the received request

test_​upper_​bound_​risk_​increment_​not_​changed_​when_​already_​set

Parameters:

  • preset_expected_upper_bound_risk_increment: 4.0

  • max_charging_kw: 20000

  • max_discharging_kw: 30000

This test checks that the value of upper bound risk increment is not changed when already set in the received request

test_​upper_​bound_​risk_​increment_​not_​changed_​when_​already_​set

Parameters:

  • preset_expected_upper_bound_risk_increment: 5.5

  • max_charging_kw: 30000

  • max_discharging_kw: 20000

This test checks that the value of upper bound risk increment is not changed when already set in the received request

tests/test_utils.py#

Test Name

Description (Risk/Safety Check)

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'DE'

  • expected: <Country.DE: 'de'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'Germany'

  • expected: <Country.DE: 'de'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'de'

  • expected: <Country.DE: 'de'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'UK'

  • expected: <Country.UK: 'uk'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'GB'

  • expected: <Country.UK: 'uk'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'gb'

  • expected: <Country.UK: 'uk'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'Great Britain'

  • expected: <Country.UK: 'uk'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​valid

Parameters:

  • input_str: 'uk'

  • expected: <Country.UK: 'uk'>

Test valid string inputs to country enum converter. Confirms various aliases map correctly to ‘Country’ enum values.

test_​country_​from_​str_​invalid

Parameters:

  • input_str: 'FR'

Test invalid string inputs raise a KeyError when converting to ‘Country’. Ensures the converter fails on unsupported or unrecognized names.

test_​country_​from_​str_​invalid

Parameters:

  • input_str: 'France'

Test invalid string inputs raise a KeyError when converting to ‘Country’. Ensures the converter fails on unsupported or unrecognized names.

test_​country_​from_​str_​invalid

Parameters:

  • input_str: ''

Test invalid string inputs raise a KeyError when converting to ‘Country’. Ensures the converter fails on unsupported or unrecognized names.

test_​country_​from_​str_​invalid

Parameters:

  • input_str: 'us'

Test invalid string inputs raise a KeyError when converting to ‘Country’. Ensures the converter fails on unsupported or unrecognized names.

test_​country_​from_​str_​invalid

Parameters:

  • input_str: 'United States'

Test invalid string inputs raise a KeyError when converting to ‘Country’. Ensures the converter fails on unsupported or unrecognized names.

tests/tests_de/test_afrr.py#

Test Name

Description (Risk/Safety Check)

test_​de_​afrr_​base_​case

Parameters:

  • min_soe: 0.0

  • max_soe: 1.0

Test that aFRR constraints are respected during day ahead optimization when aFRR is requested.

test_​de_​afrr_​base_​case

Parameters:

  • min_soe: 0.05

  • max_soe: 0.95

Test that aFRR constraints are respected during day ahead optimization when aFRR is requested.

test_​de_​afrr_​base_​case

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

Test that aFRR constraints are respected during day ahead optimization when aFRR is requested.

test_​de_​afrr_​base_​case

Parameters:

  • min_soe: 0.1

  • max_soe: 0.9

Test that aFRR constraints are respected during day ahead optimization when aFRR is requested.

test_​de_​afrr_​base_​case

Parameters:

  • min_soe: 0.2

  • max_soe: 0.8

Test that aFRR constraints are respected during day ahead optimization when aFRR is requested.

test_​de_​afrr_​intraday_​respects_​marketed_​afrr

Parameters:

  • min_soe: 0.0

  • max_soe: 1.0

Test that aFRR volumes are respected during intraday optimization.

test_​de_​afrr_​intraday_​respects_​marketed_​afrr

Parameters:

  • min_soe: 0.05

  • max_soe: 0.95

Test that aFRR volumes are respected during intraday optimization.

test_​de_​afrr_​intraday_​respects_​marketed_​afrr

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

Test that aFRR volumes are respected during intraday optimization.

test_​de_​afrr_​intraday_​respects_​marketed_​afrr

Parameters:

  • min_soe: 0.1

  • max_soe: 0.9

Test that aFRR volumes are respected during intraday optimization.

test_​de_​afrr_​intraday_​respects_​marketed_​afrr

Parameters:

  • min_soe: 0.2

  • max_soe: 0.8

Test that aFRR volumes are respected during intraday optimization.

test_​de_​afrr_​input_​checks

Test that aFRR input checks work as expected.

test_​de_​afrr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.2

  • passed_periods: 6

  • direction_of_intraday_deal: 'sold'

Test that aFRR capacity volumes are respected during intraday optimization.

test_​de_​afrr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.7

  • passed_periods: 8

  • direction_of_intraday_deal: 'bought'

Test that aFRR capacity volumes are respected during intraday optimization.

test_​de_​afrr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.5

  • passed_periods: 11

  • direction_of_intraday_deal: 'sold'

Test that aFRR capacity volumes are respected during intraday optimization.

test_​de_​afrr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.85

  • passed_periods: 27

  • direction_of_intraday_deal: 'bought'

Test that aFRR capacity volumes are respected during intraday optimization.

test_​de_​afrr_​intraday_​behaviour_​for_​different_​soe

Test that intraday is within the limits of the battery and blocked aFRR power and that both intraday and aFRR are within the battery limits.

tests/tests_de/test_afrr_energy.py#

Test Name

Description (Risk/Safety Check)

test_​afrr_​energy_​untradable_​intraday

Parameters:

  • afrr_energy_market: <MarketType.AFRR_ENERGY_POS: 'afrr_energy_pos'>

  • timestamp_expected_buypack: Timestamp('2023-01-10 06:00:00+0000', tz='UTC')

Test aFRR Energy market participation with counter-trade on untradable intraday market.

test_​afrr_​energy_​untradable_​intraday

Parameters:

  • afrr_energy_market: <MarketType.AFRR_ENERGY_NEG: 'afrr_energy_neg'>

  • timestamp_expected_buypack: Timestamp('2023-01-10 06:00:00+0000', tz='UTC')

Test aFRR Energy market participation with counter-trade on untradable intraday market.

test_​afrr_​energy_​previous_​dayahead_​shifted_​intraday_​prices

Parameters:

  • afrr_energy_market: <MarketType.AFRR_ENERGY_POS: 'afrr_energy_pos'>

  • timestamp_expected_buypack: Timestamp('2023-01-10 06:00:00+0000', tz='UTC')

Test aFRR Energy market participation after day-ahead wholesale optimization with counter deals in price-shifted intraday continuous.

test_​afrr_​energy_​previous_​dayahead_​shifted_​intraday_​prices

Parameters:

  • afrr_energy_market: <MarketType.AFRR_ENERGY_NEG: 'afrr_energy_neg'>

  • timestamp_expected_buypack: Timestamp('2023-01-10 06:00:00+0000', tz='UTC')

Test aFRR Energy market participation after day-ahead wholesale optimization with counter deals in price-shifted intraday continuous.

test_​afrr_​energy_​wrapped_​request_​handling

Test aFRR energy wrapped request handling given existing day-ahead wholesale positions

test_​afrr_​energy_​wrapped_​intraday_​orderbook

Test aFRR energy wrapped request handling with intraday orderbook

test_​afrr_​energy_​wrapped_​with_​existing_​afrr_​energy_​positions

Parameters:

  • afrr_energy_products_marketed: {<MarketType.AFRR_ENERGY_NEG: 'afrr_energy_neg'>, <MarketType.AFRR_ENERGY_POS: 'afrr_energy_pos'>}

  • timestamps_afrr_energy_marketed: [Timestamp('2025-08-04 12:45:00+0000', tz='UTC'), Timestamp('2025-08-04 13:00:00+0000', tz='UTC'), Timestamp('2025-08-04 13:15:00+0000', tz='UTC')]

  • timestamps_afrr_energy_requested: [Timestamp('2025-08-04 13:30:00+0000', tz='UTC')]

Test aFRR energy with existing aFRR energy positions

test_​afrr_​energy_​wrapped_​with_​existing_​afrr_​energy_​positions

Parameters:

  • afrr_energy_products_marketed: {<MarketType.AFRR_ENERGY_NEG: 'afrr_energy_neg'>}

  • timestamps_afrr_energy_marketed: [Timestamp('2025-08-04 12:45:00+0000', tz='UTC'), Timestamp('2025-08-04 13:00:00+0000', tz='UTC'), Timestamp('2025-08-04 13:15:00+0000', tz='UTC')]

  • timestamps_afrr_energy_requested: [Timestamp('2025-08-04 13:30:00+0000', tz='UTC')]

Test aFRR energy with existing aFRR energy positions

test_​afrr_​energy_​wrapped_​with_​existing_​afrr_​energy_​positions

Parameters:

  • afrr_energy_products_marketed: {<MarketType.AFRR_ENERGY_POS: 'afrr_energy_pos'>}

  • timestamps_afrr_energy_marketed: [Timestamp('2025-08-04 12:45:00+0000', tz='UTC'), Timestamp('2025-08-04 13:00:00+0000', tz='UTC'), Timestamp('2025-08-04 13:15:00+0000', tz='UTC')]

  • timestamps_afrr_energy_requested: [Timestamp('2025-08-04 13:30:00+0000', tz='UTC')]

Test aFRR energy with existing aFRR energy positions

test_​setting_​of_​afrr_​energy_​throughput_​in_​request_​handler

Test aFRR energy wrapped request handling with intraday orderbook

test_​setting_​flex_​markets_​energy_​throughput

Parameters:

  • flex_markets_set: None

Test aFRR energy wrapped request handling with intraday orderbook

test_​setting_​flex_​markets_​energy_​throughput

Parameters:

  • flex_markets_set: 'afrr'

Test aFRR energy wrapped request handling with intraday orderbook

test_​setting_​flex_​markets_​energy_​throughput

Parameters:

  • flex_markets_set: 'fcr'

Test aFRR energy wrapped request handling with intraday orderbook

test_​setting_​flex_​markets_​energy_​throughput

Parameters:

  • flex_markets_set: 'afrr+fcr'

Test aFRR energy wrapped request handling with intraday orderbook

test_​2026_​01_​22_​afrr_​energy_​after_​idc_​afrr_​negative_​expected

No description available.

test_​2026_​01_​22_​afrr_​energy_​after_​idc_​afrr_​null_​premium

Parameters:

  • premium: 'missing'

No description available.

test_​2026_​01_​22_​afrr_​energy_​after_​idc_​afrr_​null_​premium

Parameters:

  • premium: 'null'

No description available.

test_​2026_​01_​23_​afrr_​energy_​after_​idc_​counterdeals_​expected

No description available.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.9

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.8

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.7

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.6

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.5

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.4

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.3

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.2

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.1

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​sequence_​idc_​04_​20_​initial_​soe_​scenarios

Parameters:

  • initial_soe_high_low_fraction: 0.0

Intraday continuous optimization run in the context of aFRR backtesting. Here we ensure that the current IDC optimization run respects the energy we need to reserve for potential full aFRR negative activation. Thus we expect that following existing aFRR negative marketed positions, the IDC optimizer does not propose buying any more intraday wholesale. We further ensure that his holds true even when we set the initial SoE high and low bounds to be increasingly wide around the initial SoE, thus restricting the intraday wholesale optimizer’s range of tradable SoE at the beginning of the optimization horizon. Args: request_2026_01_28_afrr_energy_sequence_idc_04_20 (dict): Test fixture with existing aFRR negative marketed positions. initial_soe_high_low_fraction (float): Fraction to set the initial SoE high and low bounds around the initial SoE. If 0, the bounds are not set.

test_​2026_​01_​28_​afrr_​energy_​parameter_​default_​values

Check that by default we reserve 60 minutes for aFRR capacity and 15 minutes for aFRR energy.

test_​setting_​affr_​energy_​with_​existing_​afrr_​capacity

Test aFRR energy wrapped request handling with intraday orderbook

tests/tests_de/test_blocked_capacities.py#

Test Name

Description (Risk/Safety Check)

test_​afrr_​energy_​wrapped_​intraday_​orderbook_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'empty'

Test aFRR energy optimization with blocked orderbook capacities

test_​afrr_​energy_​wrapped_​intraday_​orderbook_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'normal'

Test aFRR energy optimization with blocked orderbook capacities

test_​afrr_​energy_​wrapped_​intraday_​orderbook_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'high'

Test aFRR energy optimization with blocked orderbook capacities

test_​afrr_​energy_​wrapped_​intraday_​orderbook_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'low'

Test aFRR energy optimization with blocked orderbook capacities

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'buy'

  • volume: 1.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'buy'

  • volume: 5.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'buy'

  • volume: 100.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'sell'

  • volume: 1.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'sell'

  • volume: 5.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'sell'

  • volume: 100.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'both'

  • volume: 1.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'both'

  • volume: 5.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​block_​best_​orderbook_​buckets_​effect

Parameters:

  • direction: 'both'

  • volume: 100.0

Test that blocking reduces orderbook volumes correctly for different directions and volumes

test_​pnl_​optimization_​intraday_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'empty'

Test PNL optimization with blocked intraday orderbook capacities

test_​pnl_​optimization_​intraday_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'normal'

Test PNL optimization with blocked intraday orderbook capacities

test_​pnl_​optimization_​intraday_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'high'

Test PNL optimization with blocked intraday orderbook capacities

test_​pnl_​optimization_​intraday_​with_​blocked_​capacities

Parameters:

  • blocked_capacities_scenario: 'low'

Test PNL optimization with blocked intraday orderbook capacities

test_​market_​positions_​intraday_​prices_​after_​blocking

Test blocking capacities constrains volumes and degrades prices. Runs baseline first, identifies actual trading timestamps, then blocks more than baseline volume to force measurable constraint effects.

test_​afrr_​energy_​request_​with_​empty_​blocked_​capacities

Test that aFRR energy optimization works with empty blocked capacities. This validates that the aFRR energy optimization can handle empty blocked capacities in the request without errors, since blocking is not applicable for this optimization type.

test_​afrr_​energy_​blocked_​capacities_​match_​activation_​volume

Test that blocked capacities in output only include counter trades up to aFRR activation volume. This test verifies that: 1. Blocked capacities should not exceed aFRR activation volume 2. The cumsum filtering correctly separates counter trades from P&L optimization 3. Counter trades (blocked capacities) sum up to economically viable counter trades 4. Any gap between activation and blocked capacities represents unhedged activation (goes to imbalance penalty) 5. Any additional intraday trades beyond activation are P&L optimization (not blocked)

test_​afrr_​energy_​blocked_​capacities_​spillover_​effect

Test that blocked capacities correctly span multiple timestamps when constrained. When we block capacity at a timestamp where the optimizer wants to trade, and the remaining capacity is insufficient for the full activation volume, the optimizer should distribute trades across multiple timestamps rather than violating capacity limits. For negative aFRR, we counter-trade by selling to the market, which requires buy orders.

test_​aggregate_​blocked_​capacities_​groups_​and_​sums_​overlaps_​in_​isolation

No description available.

tests/tests_de/test_de_epexDA.py#

Test Name

Description (Risk/Safety Check)

test_​run_​epexda_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test is based on backtest results for Germany. The epexIDA1 entries are replaced with epexDA. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_DA - an intraday optimization without prior epexDA optimization - an intraday optimization with prior epexDA optimization

test_​run_​epexda_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

This test is based on backtest results for Germany. The epexIDA1 entries are replaced with epexDA. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_DA - an intraday optimization without prior epexDA optimization - an intraday optimization with prior epexDA optimization

test_​run_​epexda_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

This test is based on backtest results for Germany. The epexIDA1 entries are replaced with epexDA. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_DA - an intraday optimization without prior epexDA optimization - an intraday optimization with prior epexDA optimization

test_​epexda_​and_​epexida1_​work_​together

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test checks that epexDA and epexIDA1 can get optimized together. We increase the price forecasts such that - all selling happens on epexDA - all buying happens on epexIDA1

tests/tests_de/test_de_epexIDA1.py#

Test Name

Description (Risk/Safety Check)

test_​run_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_epexIDA1_only'

This test is based on backtest results for Germany. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​run_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_only'

This test is based on backtest results for Germany. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

test_​run_​optimization_​and_​compare_​to_​backtest_​result

Parameters:

  • associated_fixture: 'get_request_and_result_for_intraday_after_epexIDA1'

This test is based on backtest results for Germany. The expected behaviour is: - when going through the handling_request-route, the result type is of type DEResult - the result dataframe for the new implementation contains the same values as the data frame based on the backtest results - the columns ‘buyDischarge’, ‘sellDischarge’, ‘buyCharge’, ‘sellCharge’ are ignored The tested cases are: - only epex_IDA1 - an intraday optimization without prior epexIDA1 optimization - an intraday optimization with prior epexIDA1 optimization

tests/tests_de/test_de_inavailabilities.py#

Test Name

Description (Risk/Safety Check)

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_20240103T200000Z_with_day_ahead_request'

  • initial_soe: 0.8

  • soe_target: 0.2

  • use_availability: True

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_20240103T200000Z_with_day_ahead_request'

  • initial_soe: 0.1

  • soe_target: 0.9

  • use_availability: True

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_20240103T200000Z_with_day_ahead_request'

  • initial_soe: 0.8

  • soe_target: 0.2

  • use_availability: False

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_20240103T200000Z_with_day_ahead_request'

  • initial_soe: 0.1

  • soe_target: 0.9

  • use_availability: False

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_2025_07_11_de_test_day_ahead_request'

  • initial_soe: 0.8

  • soe_target: 0.2

  • use_availability: True

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_2025_07_11_de_test_day_ahead_request'

  • initial_soe: 0.1

  • soe_target: 0.9

  • use_availability: True

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_2025_07_11_de_test_day_ahead_request'

  • initial_soe: 0.8

  • soe_target: 0.2

  • use_availability: False

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

test_​de_​battery_​not_​available

Parameters:

  • request_json_dir: 'request_2025_07_11_de_test_day_ahead_request'

  • initial_soe: 0.1

  • soe_target: 0.9

  • use_availability: False

Test that battery does not charge or discharge during periods of unavailability and does not reach target SoE if target_soe is not reachable during availability. The test as well checks that setting unavailability via max charging/discharging power or via availability flag leads to the same result.

tests/tests_de/test_de_intraday.py#

Test Name

Description (Risk/Safety Check)

test_​de_​intraday

Test to ensure the functionality of intraday run for DE market. Run contain data for 2 days. Using the batteryoptimizer for DE, ensure the returned result has expected columns for evaluation, 15 min interval trades, intraday bought and sold volumes atleast greater than 0 MW.

test_​wrapped_​de_​intraday

Test to ensure the functionality of intraday run for DE market, using the APIWrapper function triggers the batteryoptimization. Run contain data for 2 days.

tests/tests_de/test_de_orderbook_bucketing.py#

Test Name

Description (Risk/Safety Check)

test_​get_​de_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.whole: 'whole'>

  • max_power_MW: 5

  • bucket_size: None

Test to get orderbook for DE market converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

test_​get_​de_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.vwap: 'vwap'>

  • max_power_MW: 5

  • bucket_size: 2.0

Test to get orderbook for DE market converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

test_​get_​de_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.max: 'max'>

  • max_power_MW: 5

  • bucket_size: 3.0

Test to get orderbook for DE market converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

tests/tests_de/test_de_request_debug.py#

Test Name

Description (Risk/Safety Check)

test_​request_​2025_​08_​15_​imbalance_​intraday

No description available.

tests/tests_de/test_de_solved_bugs.py#

Test Name

Description (Risk/Safety Check)

test_​bug_​108898_​de

This test checks that bug 108898 is solved. The results of the optimization are not showing the exaggerated buy/sell volumes any more. The buy/sell volumes for EPEX IDA1 should not exceed the max charging/discharging power of the battery because there are no negative bid ask spreads to be exploited.

test_​bug_​112816_​de

Parameters:

  • with_afrr_capacity_marketed: True

This test checks that bug 112816 is solved. The results of the optimization are no longer showing solutions where the battery max charging or discharging power is exceeded by the sum over all marketed volumes.

test_​bug_​112816_​de

Parameters:

  • with_afrr_capacity_marketed: False

This test checks that bug 112816 is solved. The results of the optimization are no longer showing solutions where the battery max charging or discharging power is exceeded by the sum over all marketed volumes.

test_​bug_​118168_​de

This test checks that bug 118168 is solved. The results of the optimization show no longer positions for epexIDA1 that are greater than 10.

tests/tests_de/test_decouple_optimization_from_trading.py#

Test Name

Description (Risk/Safety Check)

test_​payload_​parsing_​for_​decoupled_​optimization_​no_​tradeable_​time_​window

Test that the payload parsing for decoupled optimization works correctly: Since no tradeable time window is provided, the last intraday traded timestamp should be set to the end of the optimization horizon.

test_​payload_​parsing_​for_​decoupled_​optimization

Parameters:

  • tradeable_time_window_minutes: 180

  • expected_time_window: Timedelta('0 days 03:00:00')

  • raises: False

Test that the payload parsing for decoupled optimization works correctly: The last intraday traded timestamp should be set to the end of the optimization horizon minus the tradeable time window.

test_​payload_​parsing_​for_​decoupled_​optimization

Parameters:

  • tradeable_time_window_minutes: '180 minutes'

  • expected_time_window: Timedelta('0 days 03:00:00')

  • raises: False

Test that the payload parsing for decoupled optimization works correctly: The last intraday traded timestamp should be set to the end of the optimization horizon minus the tradeable time window.

test_​payload_​parsing_​for_​decoupled_​optimization

Parameters:

  • tradeable_time_window_minutes: '3h'

  • expected_time_window: Timedelta('0 days 03:00:00')

  • raises: False

Test that the payload parsing for decoupled optimization works correctly: The last intraday traded timestamp should be set to the end of the optimization horizon minus the tradeable time window.

test_​payload_​parsing_​for_​decoupled_​optimization

Parameters:

  • tradeable_time_window_minutes: '11 minutes'

  • expected_time_window: None

  • raises: True

Test that the payload parsing for decoupled optimization works correctly: The last intraday traded timestamp should be set to the end of the optimization horizon minus the tradeable time window.

test_​optimization_​for_​decoupled_​optimization_​with_​tradeable_​time_​window

Test that the optimization for decoupled optimization works correctly: Test that after the tradeable time window, no buckets are marked as to_market; before or at the window, all are. Validates correct handling of tradeable time windows in decoupled optimization.

tests/tests_de/test_fcr.py#

Test Name

Description (Risk/Safety Check)

test_​de_​fcr_​base_​case

Parameters:

  • min_soe: 0.0

  • max_soe: 1.0

Test that FCR constraints are respected during day ahead optimization when FCR is requested.

test_​de_​fcr_​base_​case

Parameters:

  • min_soe: 0.05

  • max_soe: 0.95

Test that FCR constraints are respected during day ahead optimization when FCR is requested.

test_​de_​fcr_​base_​case

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

Test that FCR constraints are respected during day ahead optimization when FCR is requested.

test_​de_​fcr_​base_​case

Parameters:

  • min_soe: 0.1

  • max_soe: 0.9

Test that FCR constraints are respected during day ahead optimization when FCR is requested.

test_​de_​fcr_​base_​case

Parameters:

  • min_soe: 0.2

  • max_soe: 0.8

Test that FCR constraints are respected during day ahead optimization when FCR is requested.

test_​de_​fcr_​intraday_​respects_​marketed_​fcr

Parameters:

  • min_soe: 0.0

  • max_soe: 1.0

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​respects_​marketed_​fcr

Parameters:

  • min_soe: 0.05

  • max_soe: 0.95

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​respects_​marketed_​fcr

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​respects_​marketed_​fcr

Parameters:

  • min_soe: 0.1

  • max_soe: 0.9

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​respects_​marketed_​fcr

Parameters:

  • min_soe: 0.2

  • max_soe: 0.8

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​after_​fcr_​activation

Parameters:

  • min_soe: 0.0

  • max_soe: 1.0

  • initial_soe: 0.3

  • passed_periods: 8

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​after_​fcr_​activation

Parameters:

  • min_soe: 0.05

  • max_soe: 0.95

  • initial_soe: 0.7

  • passed_periods: 6

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​after_​fcr_​activation

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.8

  • passed_periods: 11

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​after_​fcr_​activation

Parameters:

  • min_soe: 0.1

  • max_soe: 0.9

  • initial_soe: 0.65

  • passed_periods: 19

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​after_​fcr_​activation

Parameters:

  • min_soe: 0.2

  • max_soe: 0.8

  • initial_soe: 0.35

  • passed_periods: 35

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​input_​checks

Test that FCR input checks work as expected.

test_​de_​fcr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.2

  • passed_periods: 6

  • direction_of_intraday_deal: 'sold'

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.7

  • passed_periods: 8

  • direction_of_intraday_deal: 'bought'

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.5

  • passed_periods: 11

  • direction_of_intraday_deal: 'sold'

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.35

  • passed_periods: 19

  • direction_of_intraday_deal: 'sold'

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​testing_​load_​management_​for_​pq

Parameters:

  • min_soe: 0.1

  • max_soe: 0.95

  • initial_soe: 0.85

  • passed_periods: 27

  • direction_of_intraday_deal: 'bought'

Test that FCR volumes are respected during intraday optimization.

test_​de_​fcr_​intraday_​behaviour_​for_​different_​soe

Test that intraday deals are only done when SoC is not within PQ limits and no price incentives for intraday are present.

tests/tests_de/test_ongoing_debugging.py#

Test Name

Description (Risk/Safety Check)

test_​2025_​10_​10_​failing_​intraday

Request request_2025_10_10_failing_intraday contains duplicate price_forecast timestamps. Here, we check that the APIWrappedBatteryOptimizer raises a ValidationError for this.

test_​infeasible_​solution_​prep_​de_​afrre

Parameters:

  • request_fixture: 'request_2025_10_27_infeasible_solution_de_afrre'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​afrre

Parameters:

  • request_fixture: 'request_2025_10_29_prep_de_infeasible_solution_afrre_703_1'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​idc

Parameters:

  • request_fixture: 'request_2025_10_28_infeasible_solution_de_idc'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​idc

Parameters:

  • request_fixture: 'request_2025_10_29_prep_de_infeasible_solution_idc_702_1'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​idc

Parameters:

  • request_fixture: 'request_2025_10_29_prep_de_infeasible_solution_idc_702_2'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​idc

Parameters:

  • request_fixture: 'request_2025_10_29_prep_de_infeasible_solution_idc_890_1'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​infeasible_​solution_​prep_​de_​idc

Parameters:

  • request_fixture: 'request_2025_10_29_prep_de_infeasible_solution_idc_890_2'

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/110377/

test_​2025_​12_​10_​non_​aggregated_​blocked_​capacities_​de

Test that a request with non-aggregated blocked capacities is handled correctly.

test_​prod_​infeasible_​outage_​pnl

No description available.

test_​intraday_​fcr_​marketed_​but_​intraday_​outage

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/107364/ This request used to fail because mid-EFA block outages in combination with already marketed capacity were modelled incorrectly in the within day process.

test_​2026_​01_​02_​float_​division_​by_​zero

Test that a request that would lead to a float division by zero in the normalization of charging power raises a ValidationError instead.

test_​2025_​12_​22_​day_​ahead_​prod

Test that a request with day-ahead production is handled correctly.

test_​2026_​03_​25_​idc_​extreme_​orderbook

Test that a request with an extreme order book in the IDC market is handled correctly.

tests/tests_de/test_partial_outages.py#

Test Name

Description (Risk/Safety Check)

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.01

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.1

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.2

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.3

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.4

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.5

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.6

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.7

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.8

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 0.9

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​de

Parameters:

  • availability: 1.0

Test DE intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

tests/tests_de/test_rolling_optimizztion.py#

Test Name

Description (Risk/Safety Check)

test_​rolling_​optimization

Parameters:

  • mode: 'continuous'

Test rolling optimization: Extend an existing intraday-only optimization request with a full day of day-ahead

test_​rolling_​optimization

Parameters:

  • mode: 'next_day'

Test rolling optimization: Extend an existing intraday-only optimization request with a full day of day-ahead

tests/tests_de/test_unwind_intraday.py#

Test Name

Description (Risk/Safety Check)

test_​de_​intraday_​with_​fault

Parameters:

  • fault_mode: 'none'

  • soe_target_value: 0.5

No description available.

test_​de_​intraday_​with_​fault

Parameters:

  • fault_mode: 'partial_fault'

  • soe_target_value: 0.3

No description available.

test_​de_​intraday_​planned_​outage_​insertion

No description available.

test_​unplanned_​fault_​reaction_​without_​availability_​block

Parameters:

  • fault_start: Timestamp('2024-06-06 13:00:00+0000', tz='UTC')

  • fault_end: Timestamp('2024-06-07 06:00:00+0000', tz='UTC')

No description available.

test_​unplanned_​fault_​now

Parameters:

  • fault_duration: Timedelta('1 days 00:00:00')

  • constant_target_soe: False

  • is_planned: True

No description available.

test_​unplanned_​fault_​now

Parameters:

  • fault_duration: Timedelta('1 days 00:00:00')

  • constant_target_soe: False

  • is_planned: False

No description available.

tests/tests_de_ev/test_intraday_de_ev.py#

Test Name

Description (Risk/Safety Check)

test_​intraday_​de_​ev_​sample_​request

Test aFRR energy wrapped request handling with intraday orderbook

test_​bidirectional_​intraday_​de_​ev_​sample_​request

No description available.

test_​bidi_​reduced_​sample_​request

No description available.

test_​upper_​bound_​error

No description available.

test_​2025_​12_​18_​division_​by_​zero

No description available.

tests/tests_uk/integration_tests/test_request_asset_validation.py#

Test Name

Description (Risk/Safety Check)

test_​fill_​in_​sell_​and_​buy_​columns_​with_​mean_​column

Parameters:

  • data: {'n2ex1h': [10, 20, 30], 'n2ex1h_sell': [1, 2, 3], 'n2ex1h_buy': [4, 5, 6], 'epex30min': [15, 25, 35], 'epex30min_sell': [7, 8, 9], 'epex30min_buy': [10, 11, 12], 'intraday': [5, 10, 15], 'intraday_sell': [13, 14, 15], 'intraday_buy': [16, 17, 18]}

Test buy and sell columns are filled with mean column values.

test_​ensure_​PV_​forecast_​respects_​grid_​connection

Parameters:

  • PV_forecast_data: {'technical_maximum_kw': 50, 'production_forecast_kw': 40}

  • battery_params: {'grid_connection_export_kw': 80}

  • should_raise_error: False

Test to ensure the PV forecast values are within acceptable range for grid connection export.

test_​ensure_​PV_​forecast_​respects_​grid_​connection

Parameters:

  • PV_forecast_data: {'technical_maximum_kw': 100, 'production_forecast_kw': 95}

  • battery_params: {'grid_connection_export_kw': 80}

  • should_raise_error: False

Test to ensure the PV forecast values are within acceptable range for grid connection export.

test_​ensure_​PV_​forecast_​respects_​grid_​connection

Parameters:

  • PV_forecast_data: {'technical_maximum_kw': -10, 'production_forecast_kw': -25}

  • battery_params: {'grid_connection_export_kw': 80}

  • should_raise_error: True

Test to ensure the PV forecast values are within acceptable range for grid connection export.

test_​asset_​validation

Parameters:

  • field: 'allow_pv_to_battery'

  • invalid_value: 'invalid_boolean'

  • should_raise: True

Test that Asset class raises ValidationError when required fields are missing or invalid.

tests/tests_uk/integration_tests/test_request_strategy_optimization.py#

Test Name

Description (Risk/Safety Check)

test_​validation_​ensure_​energy_​cost_​provided_​if_​customer_​perspective

Parameters:

  • perspective: 'Customer'

  • should_raise: True

Test to ensure energy cost for customer perspective validation error raised.

test_​validation_​ensure_​energy_​cost_​provided_​if_​customer_​perspective

Parameters:

  • perspective: 'EON'

  • should_raise: False

Test to ensure energy cost for customer perspective validation error raised.

tests/tests_uk/integration_tests/test_request_validation.py#

Test Name

Description (Risk/Safety Check)

test_​validation_​ensure_​dc_​ramp_​rate_​not_​too_​steep

Test to ensure the DC ramp rate is within the expected range; otherwise, raise a validation error.

test_​validation_​ensure_​dc_​energy_​rec_​in_​range

Test to ensure the DC min energy recovery percentage in the expected range; otherwise, raise a validation error.

test_​validation_​ensure_​dc_​delivery_​duration_​in_​range

Test to ensure the DC duration is within the expected range; otherwise, raise a validation error.

test_​baseline_​buffer_​perc_​constraints_​dm

Test to ensure the DM baseline buffer in expected range; otherwise, raise a validation error.

test_​delivery_​duration_​buffer_​perc_​constraints_​dm

Test to ensure the DM delivery buffer in the expected range; otherwise, raise a validation error.

test_​min_​energy_​recovery_​perc_​constraints_​dm

Test to ensure the DM min energy recovery % in the expected range; otherwise, raise a validation error.

test_​delivery_​duration_​sec_​casting_​dm

Test to ensure the DM delivery duration in the expected range; otherwise, raise a validation error.

test_​baseline_​buffer_​perc_​constraints_​dr

Test to ensure the DR baseline buffer within the expected range; otherwise, raise a validation error.

test_​delivery_​duration_​buffer_​perc_​constraints_​dr

Test to ensure the DR delivery buffer is within the expected range; otherwise, raise a validation error.

test_​min_​energy_​recovery_​perc_​constraints_​dr

Test to ensure the DR min energy recovery in expected range; otherwise, raise a validation error.

test_​delivery_​duration_​sec_​casting_​dr

Test to ensure the DR delivery duration in the expected range; otherwise, raise a validation error.

test_​validation_​ensure_​grid_​connection_​not_​too_​steep

Parameters:

  • key: 'grid_connection_export_kw'

Test to check grid connection import & export in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​grid_​connection_​not_​too_​steep

Parameters:

  • key: 'grid_connection_import_kw'

Test to check grid connection import & export in expected range; otherwise, raise a validation error.

test_​validation_​ensure_​power_​swing_​limit

Parameters:

  • applies: 1

  • value_kw: 18.5

  • should_raise: False

Test to check battery power swing limit is feasible; otherwise, raise an error.

test_​validation_​ensure_​power_​swing_​limit

Parameters:

  • applies: 0

  • value_kw: 15.0

  • should_raise: False

Test to check battery power swing limit is feasible; otherwise, raise an error.

test_​validation_​ensure_​power_​swing_​limit

Parameters:

  • applies: -1

  • value_kw: -20

  • should_raise: <class 'pydantic_core._pydantic_core.ValidationError'>

Test to check battery power swing limit is feasible; otherwise, raise an error.

test_​validation_​ensure_​power_​swing_​limit

Parameters:

  • applies: 'A'

  • value_kw: 'C'

  • should_raise: <class 'ValueError'>

Test to check battery power swing limit is feasible; otherwise, raise an error.

test_​fixture_​epex_​ds_​battery_​marketed_​respects_​battery_​parameters

Test to given pytest fixture battery marketed respects batter parameters.

test_​battery_​marketed_​valid_​data

Test ensure battery marketed works with valid data.

test_​battery_​marketed_​missing_​field

Test ensure battery marketed raises validation error with invalid data.

test_​missing_​required_​fields_​trade_​exclusion

Test trade exclusion required fields have all fields; otherwise, raise validation error.

test_​ensure_​ds_​marketed_​in_​integer_​increments_​of_​MW

Parameters:

  • dcl_kw: 1000

  • dch_kw: 1000

  • dml_kw: 1000

  • dmh_kw: 1000

  • drl_kw: 1000

  • drh_kw: 1000

  • should_raise: False

Test to ensure ds marketed integer increments and value error raised.

test_​ensure_​ds_​marketed_​in_​integer_​increments_​of_​MW

Parameters:

  • dcl_kw: 50

  • dch_kw: 55

  • dml_kw: 40

  • dmh_kw: 45

  • drl_kw: 30

  • drh_kw: 35

  • should_raise: True

Test to ensure ds marketed integer increments and value error raised.

test_​ensure_​ds_​marketed_​in_​integer_​increments_​of_​MW

Parameters:

  • dcl_kw: 3.4

  • dch_kw: 3.8

  • dml_kw: 12.3

  • dmh_kw: 50.2

  • drl_kw: 10.5

  • drh_kw: 24.7

  • should_raise: True

Test to ensure ds marketed integer increments and value error raised.

tests/tests_uk/test_battery_optimizer.py#

Test Name

Description (Risk/Safety Check)

test_​efa_​blocks_​no_​dst_​change

No description available.

test_​efa_​blocks_​dst_​lose_​one_​hour_​at_​beginning

No description available.

test_​efa_​blocks_​dst_​lose_​gain_​hour_​at_​beginning

No description available.

tests/tests_uk/test_battery_optimizer_app.py#

Test Name

Description (Risk/Safety Check)

test_​handle_​request_​pnl_​with_​order_​book

Test pnl request with order book will return the correct result type.

test_​handle_​request_​pnl_​with_​only_​forecasts

Test pnl request with only forecasts is returning the correct result type.

test_​handle_​request_​bod

Test working Bod optimization. For problem type bod the corresponding response type is expected.

tests/tests_uk/test_bod.py#

Test Name

Description (Risk/Safety Check)

test_​bod_​computation

Test that bod computation gives the correct prices and volumes. Test data compares against static result.

test_​bod_​computation_​volume_​reservation_​zero_​mel

Test that the bod computation takes mel into account. For 0MW MEL and positive min_physical_notification, the pair_p1_offer price should be below the given maximal price per MWh. For 0MW MEL and negative min_physical_notification, the pair_p1_offer price should be the maximal price. This should prevent receiving a BOA lower than the required power for SOE Management after dynamic service delivery.

test_​bod_​computation_​volume_​reservation_​zero_​mil

Test that the bod computation takes mel into account. For 0MW MIL and negative max_physical_notification, the pair_n1_bid price should be below the given maximal price per MWh. For 0MW MIL and positive max_physical_notification, the pair_n1_bid price should be the maximal price. This should prevent receiving a BOA lower than the required power for SOE Management after dynamic service delivery.

test_​bod_​request_​missing_​keys

Test that missing data will result in a Validation Error

test_​bod_​result_​contains_​maximum_​four_​pairs

Test that the bod results consists of minimum 2 pairs and maximum 8. Also tested, but might be removed in the future: result only contains pair_n1 and pair_p1

tests/tests_uk/test_dynamic_services_buffers.py#

Test Name

Description (Risk/Safety Check)

test_​dynamic_​services_​buffers

Parameters:

  • ds_battery_marketed: {'drh_kw': 5000.0, 'drl_kw': 2000.0}

  • ds_energy_throughput: {'drh_MWh_per_MW': 0.06, 'drl_MWh_per_MW': 0.06}

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

tests/tests_uk/test_iis.py#

Test Name

Description (Risk/Safety Check)

test_​scip_​iis_​commandline

Test for implementing commandline-based IIS computation in SCIP. Payload based on https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/86190

test_​scip_​iis_​commandline_​no_​executable

Force the IIS computation to use a bogus SCIP executable name so the ‘SCIP binary not found’ branch in get_scip_iis_message is covered.

test_​scip_​iis_​commandline_​timeout

Force the IIS computation to run into a timeout so the ‘SCIP IIS computation timed out’ branch in get_scip_iis_message is covered.

tests/tests_uk/test_intraday.py#

Test Name

Description (Risk/Safety Check)

test_​intraday_​book_​keeping

Test that two consecutive intraday runs change the result. Both runs contain data for 3 days. The first run has an intraday price of 10 for the first half and 100 for the second half of timestamps.The second run has an updated intraday price of 30 for the first third, 5 for the second third and 100 for the last third of timestamps. Expectation: The first run will buy energy in the first half and sell energy in the second half. The second run should undo the trades, and rather sell energy in the first third, buy as much as possible in the second third and sell everything in the last third. This should result in a higher objective function result.

test_​intraday_​finding_​better_​solution_​with_​DA_​deals

Test that two consecutive intraday runs change the result. The first run optimizes a DA market with constant prices, except for 2 timestamps t1, t2 with low prices and 2 timestamps with high prices t3, t4. It is tested that energy is bought at a low price and sold at a high price. The result is put into the battery marketed of the second optimization run, optimizing the intraday market. Prices are constant again, except for timestamps t1, t2 with HIGH prices and timestamps t3, t4 with LOW prices (so the price structure is flipped). It is checked that the intraday buys more than was sold before and sells more than was bought before. This effectively will undo the epex trades and compensate in intraday market.

test_​that_​initial_​soe_​level_​outside_​allowed_​range_​is_​recovered_​in_​sp1

Test, that if the initial soe level is below min_soe or above max_soe, it is recovered in the first settlement period resulting in a target soe level in a valid range.

test_​cycles_​are_​respected_​in_​intraday_​with_​filled_​with_​DA

Test, that if the daily cycle is completely filled with DA positions, it is still respected in the intraday optimization. This means the intraday positions cannot exceed the given limit.

test_​intraday_​partial_​cycle_​limits

This test optimizes 3 days intraday. Each day has a different cycle limit (day 1: 1 cycle, day 2: 2 cycles, day 3: 3 cycles). We initiate a battery without third party costs and a limited efficiency. The full discharge in MW of one day is 2*battery_capacity, independent of the efficiency. For day 1 we assert that it is 1*full discharge, day2 2*full discharge, day 3 3*full discharge.

test_​intraday_​bucketing

The existing Result logic still works with intraday bucketing since intraday_sell and intraday_buy variables are simply the sum of the corresponding bucket volumes. Hence, when e.g. requesting a results dataframe, the corresponding entries for intraday equal the sum of bucket volumes: (Note that we checked above that there are no existing already marketed intraday positions, hence these volumes come from the current optimization run)

test_​intraday_​bucketing_​intraday_​strategy

Check for implemented intraday strategy and correct validation error.

test_​intraday_​bucketing_​vwap_​with_​price_​buckets

Test that requesting intraday strategy “{self.intraday_strategy}” with price_buckets as an input results in a validation error.

test_​intraday_​bucketing_​orderbook_​request

Test intraday bucketing result minmax aggregation

test_​intraday_​empty_​price_​buckets

Assert that an empty orderbook will result in default prices of 9999 £/MWh in the intraday buckets

test_​markets_​time_​series_​conversion

Assert that the orderbook data is correctly fetched for intraday strategy bucket for emtpy price buckets

test_​time_​series_​markets_​all_​the_​same_​intraday_​marketed

Test that already marketed intraday is not overwritten by the optimizer when re-running an optimization but is kept in the result.

test_​time_​series_​markets_​imbalance_​intraday

Test to validate the correct behavior of the optimization logic in a scenario where: Intraday markets are active throughout the optimization time range. Only the first settlement period is optimized for imbalance, while the rest are optimized for intraday. Intraday pre-marketed volumes are correctly enforced as lower bounds.

test_​intraday_​bucketing_​negative_​pnl

In this test we show that occasional negative P&L we see on particular continuous intraday runs result from numerical rounding issues (imbalances) due to existing market positions (e.g. existing day-ahead positions). The optimizer sees this numerical imbalance and chooses to fill this numerical imbalance in with either the intraday or the imbalance market as demonstrated below. Hence, it makes sense for us to refuse intraday results whose P&L is negative since our goal in continuous intraday trading is not to constantly fix numerical rounding issues. Our intention is to trade with a positive P&L while fixing numerical rounding issues happens as a by-product during positive P&L runs.

tests/tests_uk/test_iterative_rounding.py#

Test Name

Description (Risk/Safety Check)

test_​marketed_​volumes_​validation_​rounding_​methods

Test that the optimizer correctly validates and handles marketed volumes for the specific case on 2025-02-10. Solves the optimization problem using a two-stage MIP → IP process. Here we iterate over different rounding methods.

tests/tests_uk/test_joerg_dc_test_cases.py#

Test Name

Description (Risk/Safety Check)

test_​dc_​1

Start_SoE 0.5, DC low 0 GBP, DC high 12 GBP ==> We expect DCH only. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​2

Start_SoE 0.5, DC low 12 GBP, DC high 0 GBP ==> We expect DCL only. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​3

Start_SoE 0.5, DC low 11.9 GBP, DC high 12 GBP ==> We expect DC both limited by swing limit. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​4

Start_SoE 0.5, DC low 12 GBP, DC high 12 GBP ==> We expect DCL only. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​5

Start_SoE 0.5, DC low 12 GBP, DC high 0 GBP ==> We expect DCL only. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​6

Start_SoE 0.5, DC low 12. GBP, DC high 12 GBP ==> We expect DC both limited by 12% baselining constraint. Note that third party costs aren’t affected by the way we treat DC - i.e. our DC variables do not feed into a cost position in our objective function. Hence, here in a DC-only scenario we expect the optimizer to always fill in DC to maximize DC revenue, irrespective of DC prices.

test_​dc_​7

Start_SoE 0 0,2, DC low 5,00 GBP, DC High 5,00 GBP ==> DC high 6 MW

test_​dc_​8

Start_SoE 0 0,8, DC low 1,00 GBP, DC High 12,00 GBP ==> DC low 21 MW

tests/tests_uk/test_joerg_epex_test_cases.py#

Test Name

Description (Risk/Safety Check)

test_​spot_​epex_​1

Start SoE Level 80% and 1 hour spot = 111 ==> discharging in that hour and recharging afterwards (or maybe nothing in case the battery stays empty)

test_​spot_​epex_​2

Start SoE Level 20% and 1 hour spot = 111 ==> charging at the beginning (limited charging with 6.8 MW due to Grid constraint) discharging in that hour

test_​spot_​epex_​3

Start SoE Level 80% and 1 hour spot = 110. The battery is discharged in the 2 SPs with high price, it is brought form 80% SOE level to a SoE level of 20%. Not charged afterwards. As no charging event is needed to make money, it does not matter, if the high price is over or under the strike. By selling energy and empyting the battery you always make money over the optimisation horizon. But the battery is empty at the end!

test_​spot_​epex_​4

Start SoE Level 20% and 1 hour spot = 110 ==> no charging/discharging at the beginning (or maybe discharging at the end in case the battery will be emptiey to earn money at the end)

test_​spot_​epex_​5

Start SoE Level 50% and 1 hour spot = 111 ==> charging at the beginning, discharging in that hour and recharging afterwards (or maybe nothing in case the battery stays empty) the battery is charged at the beginning (SP 1 and SP2) from 50% up to 70% SOE level; but in SP1 only with 2MW, in the other SP with 6,8MW (=possible solution chosen by solver). The battery is discharged in the SP where the price is 111, it is brought back to a SoE level of 20%. As a discharge over 1 SP leads in maximum to a reduction of SoE of roughly 50%, the charging at the beginning only delivers a 50% higher SoE level [from 20% to 70%, not up to max of 80%]

tests/tests_uk/test_joerg_n2ex_cycles.py#

Test Name

Description (Risk/Safety Check)

test_​n2ex_​cycle_​0

start at SoE level of 80% and one hour (1:00 - 2:00) with a price of 111 GBP and cycle = 2; the result will be the same as in test N2EX spot 1, as expected. Optimum does not need more than 1 cycle in this situation

test_​n2ex_​cycle_​1

Start SoE Level 80% and 2 hour spot = 111, cycle = 1 ==> discharge in the first high price hour, charge in the period between the 2 hours, discharge again in the 2nd hour with 111 GBP, but charging and discharging will be limited to not have more than 1 cycle.

test_​n2ex_​cycle_​2

Start SoE Level 80% and 2 hour spot = 111, cycle = 2 ==> discharge in the first high price hour, charge in the period between the 2 hours, discharge again in the 2nd hour with 111 GBP; Discharging will use full range from 80% SoE to 20% SoE, charging will use fulll range between 20% SoE and 80% SoE.

test_​n2ex_​cycle_​3

Start SoE Level 20% and 2 hour spot = 111, cycle = 1 ==> charging at the beginning, discharge in the first high price hour, charge in the period between the 2 hours, discharge again in the 2nd hour with 111 GBP, but charging and discharging will be limited to not have more than 1 cycle

test_​n2ex_​cycle_​4

Start SoE Level 20% and 2 hour spot = 111, cycle = 2 ==> charging at the beginning, discharge in the first high price hour, charge in the period between the 2 hours, discharge again in the 2nd hour with 111 GBP; Discharging will use full range from 80% SoE to 20% SoE, charging will use fulll range between 20% SoE and 80% SoE

test_​DA_​DS_​low_​energy_​throughput_​cycle_​limit

Parameters:

  • energy_throughput_volume: 0.1

Test that the energy throughput of dynamic servie low contribute to the daily cycles. If the battery is already fully discharged in one day or if the daily cycle is set to 0, the dynamic services should be 0. for positive energy throughput. If the energy throughput is set to 0. the low DS do not contribute to the discharging cycle and therefore, DS low can be marketed.

test_​DA_​DS_​low_​energy_​throughput_​cycle_​limit

Parameters:

  • energy_throughput_volume: 0.0

Test that the energy throughput of dynamic servie low contribute to the daily cycles. If the battery is already fully discharged in one day or if the daily cycle is set to 0, the dynamic services should be 0. for positive energy throughput. If the energy throughput is set to 0. the low DS do not contribute to the discharging cycle and therefore, DS low can be marketed.

tests/tests_uk/test_joerg_n2ex_test_cases.py#

Test Name

Description (Risk/Safety Check)

test_​spot_​n2ex_​1

Start SoE Level 80% and 1 hour spot = 111 ==> discharging in that hour and recharging afterwards (or maybe nothing in case the battery stays empty)

test_​spot_​n2ex_​2

Start SoE Level 20% and 1 hour spot = 111 ==> charging at the beginning (limited charging with 6.8 MW due to Grid constraint) discharging in that hour

test_​spot_​n2ex_​3

Start SoE Level 80% and 1 hour spot = 110. The battery is discharged in the 2 SPs with high price, it is brought form 80% SOE level to a SoE level of 20%. Not charged afterwards. As no charging event is needed to make money, it does not matter, if the high price is over or under the strike. By selling energy and empyting the battery you always make money over the optimisation horizon. But the battery is empty at the end!

test_​spot_​n2ex_​4

Start SoE Level 20% and 1 hour spot = 110 ==> no charging/discharging at the beginning (or maybe discharging at the end in case the battery will be emptiey to earn money at the end)

test_​spot_​n2ex_​5

Start SoE Level 50% and 1 hour spot = 111 ==> charging at the beginning, discharging in that hour and recharging afterwards (or maybe nothing in case the battery stays empty)

test_​spot_​n2ex_​6

Start with SoE level of 20% and test strike price. At a price of 10.88 GBP the battery is not charged / discharged. With a low initial SoE at the strike price being 10.88 GBP, we don’t expect anything to happen since we have no initial “free” energy to sell and we’re below the strike price to buy and sell at a profit.

test_​spot_​n2ex_​7

Start with SoE level of 20% and test strike price. At a price of 10.89 GBP the battery is charged prior to high price, and discharged during high price periods. Compare with test case 6 where strike price is 10.88 GBP and no charging / discharging happens.

tests/tests_uk/test_logger.py#

Test Name

Description (Risk/Safety Check)

test_​get_​logger_​single_​line_​exceptions

Test that the logger formats exceptions as single-line messages given ‘single_line_exceptions=True’. Verifies that log output contains ‘ | ‘, indicating single-line formatting and no multi-line traceback is present.

test_​get_​logger_​default_​formatter

Test that the logger uses the default multi-line formatter when no special formatting options are specified. Verifies presence of ‘Traceback’ to confirm a full stack trace is included.

test_​get_​logger_​prepend_​pid_​direct

Test that the logger prepends the process ID (PID) to log messages.

test_​single_​line_​formatter_​all_​levels

Parameters:

  • level: 20

  • message: 'This is an info message\nwith a newline.'

No description available.

test_​single_​line_​formatter_​all_​levels

Parameters:

  • level: 30

  • message: 'Warning!\nSomething happened.'

No description available.

test_​single_​line_​formatter_​all_​levels

Parameters:

  • level: 40

  • message: 'Error occurred!\nCheck details.'

No description available.

test_​single_​line_​formatter_​exception

No description available.

test_​single_​line_​formatter_​edge_​cases

No description available.

test_​single_​line_​formatter_​tabs_​and_​spaces

No description available.

test_​single_​line_​formatter_​crlf

No description available.

test_​single_​line_​formatter_​message_​and_​exception

No description available.

test_​single_​line_​formatter_​empty_​message

No description available.

test_​single_​line_​formatter_​whitespace_​only

No description available.

test_​single_​line_​formatter_​with_​args

No description available.

tests/tests_uk/test_main.py#

Test Name

Description (Risk/Safety Check)

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_15_auto_intraday_solution'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • result_type: <class 'battery_optimizer.uk.result.UKResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_15_auto_intraday_solution_2'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • result_type: <class 'battery_optimizer.uk.result.UKResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_15_bod_solution'

  • problem_type: <ProblemType.BOD: 'bod'>

  • result_type: <class 'battery_optimizer.uk.bod.BodResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_15_bm_mel_mil_solution'

  • problem_type: <ProblemType.MELMIL: 'melmil'>

  • result_type: <class 'battery_optimizer.uk.mel_mil.MELMILResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_15_mel_mil_boa'

  • problem_type: <ProblemType.MELMILBOA: 'melmilboa'>

  • result_type: <class 'battery_optimizer.uk.mel_mil.MELMILResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead_non_iterative_gapRel_0'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • result_type: <class 'battery_optimizer.uk.result.UKResult'>

Test to ensure functionality of ‘optimize_wrapped_problem’ using different parameterized input, and returned result is of correct class type and does not return error.

test_​optimize_​wrapped_​problem_​bad_​request

Parameters:

  • associated_fixture: 'request_2025_05_15_auto_intraday_solution'

  • problem_type: 'ABC'

Test to ensure functionality of ‘optimize_wrapped_problem’ raises Error for a given incorrect problem type as part of bad request input.

test_​optimize_​wrapped_​problem_​validation_​error

Test to ensure ValidationError is raised when given incorrect arguments passed to function ‘optimize_wrapped_problem’

test_​logging_​queue_​put_​get_​dict

Test to check functionality of getting and putting dict item to and from logging queue.

test_​logging_​queue_​put_​get_​object

Test to check functionality of getting and putting object to and from logging queue.

test_​async_​optimizer_​initialization

Test to ensure functionality of optimizer initialization using MockEnv and MockKafkaConsumer.

test_​consume_​optimize_​write_​result_​error

Parameters:

  • associated_fixture: 'request_2025_05_15_bod_solution'

Test that the optimizer correctly captures and returns validation errors. Modifies input to trigger a validation failure and asserts error output.

test_​optimize_​file_​returns_​valid_​excel_​content

Parameters:

  • expected_sheet_name: 'result'

Test uploading an Excel file to the optimization endpoint returns expected sheets. Confirms sheet presence and validates that returned data is non-empty.

test_​optimize_​file_​returns_​valid_​excel_​content

Parameters:

  • expected_sheet_name: 'battery parameters'

Test uploading an Excel file to the optimization endpoint returns expected sheets. Confirms sheet presence and validates that returned data is non-empty.

test_​optimize_​file_​returns_​valid_​excel_​content

Parameters:

  • expected_sheet_name: 'tracing'

Test uploading an Excel file to the optimization endpoint returns expected sheets. Confirms sheet presence and validates that returned data is non-empty.

test_​optimize_​file_​varying_​content

Parameters:

  • fixture_name: 'sample_file_data_main'

  • expected_status: 200

  • file_type: 'xlsx'

Test optimization endpoint with varying file types and expected status codes. Handles supported formats and ensures unsupported types raise a ValueError.

test_​optimize_​file_​varying_​content

Parameters:

  • fixture_name: 'request_2025_02_06_marketed_volumes_validation'

  • expected_status: 200

  • file_type: 'json'

Test optimization endpoint with varying file types and expected status codes. Handles supported formats and ensures unsupported types raise a ValueError.

test_​optimize_​file_​varying_​content

Parameters:

  • fixture_name: 'get_uk_orderbook'

  • expected_status: 400

  • file_type: 'txt'

Test optimization endpoint with varying file types and expected status codes. Handles supported formats and ensures unsupported types raise a ValueError.

test_​optimize_​file_​json_​expected_​problem_​type

Parameters:

  • fixture_name: 'request_2025_05_15_mel_mil_boa'

  • problem_type: <ProblemType.MELMILBOA: 'melmilboa'>

Test optimization of different problem types via JSON input file. Verifies that the output Excel contains problem-type-specific result columns.

test_​optimize_​file_​json_​expected_​problem_​type

Parameters:

  • fixture_name: 'request_2025_05_15_bm_mel_mil_solution'

  • problem_type: <ProblemType.MELMIL: 'melmil'>

Test optimization of different problem types via JSON input file. Verifies that the output Excel contains problem-type-specific result columns.

test_​optimize_​file_​json_​expected_​problem_​type

Parameters:

  • fixture_name: 'request_2025_05_15_bod_solution'

  • problem_type: <ProblemType.BOD: 'bod'>

Test optimization of different problem types via JSON input file. Verifies that the output Excel contains problem-type-specific result columns.

test_​optimize_​file_​json_​expected_​problem_​type

Parameters:

  • fixture_name: 'request_2025_05_15_auto_intraday_solution'

  • problem_type: <ProblemType.PNL: 'pnl'>

Test optimization of different problem types via JSON input file. Verifies that the output Excel contains problem-type-specific result columns.

test_​2026_​03_​26_​uk_​idc_​division_​by_​zero

Error propagation test: For a divison by zero error in one of the validators, we want to pass back to the caller the full traceback to facilitate debugging on the caller side. This test ensures that the traceback is included in the error message when such an error occurs.

tests/tests_uk/test_mel_mil_business_scenarios.py#

Test Name

Description (Risk/Safety Check)

test_​business_​scenario_​1

Test that MEL MIL is calculated correctly under dynamic service and wholesale market trading. This does include possible recovery from a boa and fulfillment of future SOE-constraints. This test checks for the correct the power constraint of mel mil calculation, i.e. that mel mil are reduced by dynamic service but are not influenced by wholesale market trading.

test_​business_​scenario_​2

Test that MEL MIL is calculated correctly under dynamic service only. This test checks for the correct the power constraint of mel mil calculation, i.e. that mel mil are reduced by dynamic service but are not influenced by wholesale market trading.

test_​business_​scenario_​3

Test that MEL MIL is calculated correctly under dynamic service and wholesale market trading. This does include possible recovery from a boa and fulfillment of future SOE-constraints with declining recovery the closer dynamic service soe requirements have to be reached. It is tested, that the SoE Management buffers from dynamic services should be ignored in the MEl/MIL calculation. This test checks for the correct the power constraint of mel mil calculation, i.e. that mel mil are reduced by dynamic service but are not influenced by wholesale market trading.

test_​business_​scenario_​4

Test that MEL MIL is calculated correctly under dynamic service and wholesale market trading. In this test case, we start with small initial soe_level, have a buy and sell deal in the future. As soon as the buy deal is placed, MEL should increase, but only as long as it is recoverable. This means, as soon as the frozen period starts, it should be minimized again to allow the wohlesale market trade. This test also verfies the correct MEL MIL calculation in the energy limited MELMIL case.

tests/tests_uk/test_melmil_request.py#

Test Name

Description (Risk/Safety Check)

test_​maximum_​MELMIL_​for_​asymmetric_​charging_​discharging_​power

Test working MELMIL Request and correct handling. max_charging_power_kw and max_discharging_power_kw are not symmetrical, and MEL/MIL should take that correctly into account.

test_​MELMIL_​request_​mil_​zero_​for_​maximum_​soe

Test working MELMIL Request with no deals and inital soe = maximum soe. The expected MIL is 0 MW.

test_​MELMIL_​request_​mel_​zero_​for_​minimum_​soe

Test working MELMIL Request with no deals and inital soe = minimum soe. The expected MEL is 0 MW.

test_​bm_​availabilities

Test that mel mil calculation returns 0 MW, if the battery is not available.

test_​MELMIL_​request_​with_​DC

Test, that MELMIL is reduced by dynamic service

tests/tests_uk/test_melmil_validations.py#

Test Name

Description (Risk/Safety Check)

test_​MELMILBOA_​request_​requires_​end_​of_​boa_​timestamp_​in_​baseline

Test MELMILBOA Request requires end of boa timestamp in baseline to work

test_​MELMILBOA_​request_​requires_​soe_​after_​end_​of_​boa_​timestamp_​in_​baseline

Test MELMILBOA Request requires end of boa timestamp in baseline to work

test_​MELMILBOA_​request_​requires_​Baseline_​data

Test MELMILBOA Request requires baseline and boa data and throws an error if they are not present

test_​MELMIL_​request_​with_​Baseline_​and_​BOA_​data

Test that MEL MIL Request is ignoring baseline and boa data if they are given and the correct problemtype is returned

test_​MELMIL_​request_​requires_​boa_​or_​start

Test that MEL MIL BOA Request is requiring either start or boas, otherwise an error is thrown.

tests/tests_uk/test_melmilboa_request.py#

Test Name

Description (Risk/Safety Check)

test_​MelMilBoa_​request

Test working MELMILBOA request.

test_​MelMilBoa_​request_​creation

Parameters:

  • power_after_boa: 10000

  • market_string: 'sold_epex30min_kw'

Test working MELMILBOA request is updating the request as expected to guarantee that the running SP has the correct remaining power output. This is tested for positive and negative baseline values

test_​MelMilBoa_​request_​creation

Parameters:

  • power_after_boa: -10000

  • market_string: 'bought_epex30min_kw'

Test working MELMILBOA request is updating the request as expected to guarantee that the running SP has the correct remaining power output. This is tested for positive and negative baseline values

test_​MelMilBoa_​request_​with_​start_​parameter

Test working MELMILBOA request with start parameter instead of boas given.

test_​Boa_​request_​with_​DC_​during_​EFA_​block

Test working MELMILBOA request with Dynamic services during a running block.

test_​Boa_​request_​with_​trading

Test working MELMILBOA request with existing charging/discharging.

test_​MelMilBoa_​request_​with_​MEL_​0_​after_​maximum_​boa

Test working MELMILBOA request. First we do a normal mel mil optimization with a already low inital soe level. We take the MEL value and create a boa with exactly this power. This should result in a soe level at (almost) minimum soe. The resulting MEL after mel mil boa optimization should be 0 MW.

test_​MelMilBoa_​request_​with_​MIL_​0_​after_​maximum_​boa

Test working MELMILBOA request. First we do a normal mel mil optimization with a already high inital soe level. We take the MIL value and create a boa with exactly this power. This should result in a soe level at (almost) maximum soe. The resulting MIL after mel mil boa optimization should be 0 MW.

test_​Boa_​request_​with_​energy_​throughput

Test that the MEL MIL BOA requests takes the energy throughput of dynamic services correctly in account, when creating the updated running settlement period.

test_​MelMilBoa_​request_​with_​non_​overlapping_​boas

Test working MELMILBOA request. Mutiple boas are added, that are non overlapping. The result should contain a mel mil optimization after the latest boa, ignoring the time between the two boas.

tests/tests_uk/test_melmilnow_request.py#

Test Name

Description (Risk/Safety Check)

test_​MELMILNOW_​request

Test working MELMILNOW request with no restrictions. Expeted mel and mil are maximum discharge/ maximum charge power. Correct timestamp is checked.

test_​MELMILNOW_​request_​energy_​restricted

Test MELMILNOW with limited energy in the battery. The expected output should match the restricted energy that can be delivered for the remaining time of the settlement period. Also tested: a timestamp, that is not in the current but in the next SP. Still, the MELMILNOW should return only one SP with the remaining time of SP1.

test_​MELMILNOW_​request_​with_​dcl

Test mel mil now request with completely blocked power by dynamic serivces. Expected mel should be close to 0.

test_​MELMILNOW_​request_​with_​dcl_​power_​block

Test mel mil now request with blocked power by dynamic serivces, but no energy restriction. Expected mel should be max discharge - blocked power.

tests/tests_uk/test_ongoing_debugging.py#

Test Name

Description (Risk/Safety Check)

test_​2025_​02_​11_​ds_​both_​baseline_​buffer

Here we test that the optimizer respects the SoE management rules in case of marketing DS both Note that the below ‘min_energy_recovery_perc’ of 0.2 comes from the official guideline on this: “SOE Monitoring Guidance For Energy Limited DC/DM/DR Providers”: https://www.neso.energy/document/347241/download In case of participating in DC high and DC low at the same time, we need to keep 20% = 0.2 of the opposite direction free for SoE management, hence (for a 15-minute delivery duration for DC) 0.2 * 15 min / 30 min = 0.1 of the opposite direction free DC both rule as described in https://www.neso.energy/document/347241/download

test_​2025_​02_​10_​marketed_​volumes_​validation

Test that the optimizer correctly validates and handles marketed volumes for the specific case on 2025-02-10. Solves the optimization problem using a two-stage MIP → IP process.

test_​2025_​02_​20_​no_​dr

Test that we entered DR deals and no DC deals when DR prices are higher

test_​2025_​02_​21_​infeasible_​intraday

Test that the optimizer correctly throws an error when DS both positions with violating SoE management rules are provided in battery_marketed

test_​2025_​02_​25_​long_​running_​epex_​dc_​dm_​dr

Test that a long-running example json has a shorter optimization time than 180 s (was previously longer).

test_​2025_​03_​11_​infeasible_​melmil

https://eon-seed.visualstudio.com/Flexibility%20Trading%20Technologies/_workitems/edit/86190 PyDantic validator trips because an asset state target SoE is set to a value greater than the max SoE. Removing the validator leads to an infeasible solution - the optimizer cannot reach the target SoE. Implementing the asset state target SoE as a relaxed best effort target allows the optimizer to reach a feasible solution.

test_​2025_​03_​11_​infeasible_​epex

https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/86721 The end of day 1 of this EPEX request has a SoE target that is not reachable.

test_​2025_​03_​11_​infeasible_​melmil_​validate_​initial_​dch

Here, VPP sends an initial DCH position that is not supported by the initial SoE in the same request: https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/86190#14191306 As we are in the within-day process here (MELMIL optimization specificially), we expect that the relatively high initial SoE in this request is due to recent DS high activation. Hence, we expect that in this optimization run, we do not need to fully meet DS SoE requirements but that we rather need to restore these DS SoE requirements as quickly as possible: https://dev.azure.com/eon-seed/Flexibility%20Trading%20Technologies/_workitems/edit/90360

test_​2025_​04_​09_​initial_​soe_​check_​for_​ds_​energy_​too_​conservative

Test that initial dynamic services positions are only checked if we are optimizing dynamic services exclusively. If nothing but dynamic services are requested at the beginning of the request, then we cannot modify the SoE at the beginning of the optimization horizon, hence we need to ensure that we respect the initial SoE with our newly proposed dynamic services volumes. Test that warning log messages contain request IDs.

test_​2025_​03_​20_​melmil_​infeasible_​solution

Test that potential the undoing of a BOA in the soe scenarios for mel mil optimization will not result in a infeasible solution in case high and low dynamic services are in place. This test includes a specific json request, that resulted in an infeasible solution before.

test_​2025_​04_​23_​availability_​flag_​for_​planned_​outages_​only

Verify that the optimizer throws a validation error when the battery is unavailable but positions are provided in the ‘battery_marketed’ parameter. The error should no longer occur when the positions during the unavailability are set to 0.

test_​2025_​06_​30_​infeasible_​solution

Parameters:

  • fixture_name: 'request_2025_06_30_infeasible_solution_1'

No description available.

test_​2025_​06_​30_​infeasible_​solution

Parameters:

  • fixture_name: 'request_2025_06_30_infeasible_solution_2'

No description available.

test_​2025_​06_​30_​infeasible_​solution_​melmilboa

No description available.

test_​2025_​07_​24_​respect_​target_​soe

Test that the optimizer respects the target SoE at the end of the optimization horizon.

test_​2025_​12_​02_​prod_​infeasible_​solution

Test that we can solve a request that previously led to an infeasible solution in production.

test_​2026_​01_​29_​soe_​target_​bigger_​than_​1

Test that we correctly handle a request where the target SoE is bigger than 1.

tests/tests_uk/test_orderbook_bucketing.py#

Test Name

Description (Risk/Safety Check)

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 5

  • expected_fixture: 'simple_whole_sell'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 5

  • expected_fixture: 'simple_whole_buy'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 0.5

  • expected_fixture: 'simple_whole_sell'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 0.5

  • expected_fixture: 'simple_whole_buy'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 8

  • expected_fixture: 'simple_whole_sell'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​all_​orders_​per_​delivery_​time

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 8

  • expected_fixture: 'simple_whole_buy'

Test orderbook functionality with bucketing approach ‘whole’: The passed order book is filtered such that the returned orders are offering enough energy to fulfill the requested max energy. All orders needed to fulfill the requested energy based on the passed orderbook.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 5

  • expected_fixture: 'simple_max_sell'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 5

  • expected_fixture: 'simple_max_buy'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 0.5

  • expected_fixture: 'simple_max_sell'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 0.5

  • expected_fixture: 'simple_max_buy'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 8

  • expected_fixture: 'simple_max_sell'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​max_​prices_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 8

  • expected_fixture: 'simple_max_buy'

Test orderbook functionality with bucketing approach ‘max’: The maximum price of a bucket is always the maximum/minimum price that is needed to fulfill the bucket plus the buckets before.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 5

  • expected_fixture: 'simple_vwap_sell'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 5

  • expected_fixture: 'simple_vwap_buy'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 0.5

  • expected_fixture: 'simple_vwap_sell'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 0.5

  • expected_fixture: 'simple_vwap_buy'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'SELL'

  • max_vol: 8

  • expected_fixture: 'simple_vwap_sell'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​get_​vwap_​per_​bucket

Parameters:

  • market_trigger: 'BUY'

  • max_vol: 8

  • expected_fixture: 'simple_vwap_buy'

Test orderbook functionality with bucketing approach ‘vwap’: The vwap of a bucket is the vwap of all prices that are needed to fulfill energy needed in the bucket. If an order is needed in two buckets, the order is split into two orders for which the energy is the sum of the original order and the price is the same.

test_​convert_​to_​timestamp

Test to ensure the functionality of convert_to_timestamp function given a series, the returned result is of type pandas Series containing elements are of type Timestamp.

test_​read_​decompress_​convert_​orderbook

Test orderbook functionality with read gzipped_orderbook and return bytes, decompress to bytes orderbook to utf-8 and returns string and convert the unzipped string to dataframe.

test_​filter_​orderbook

Parameters:

  • delivery_length: 'HalfHour'

  • deliveryStartTime: ''

  • deliveryEndTime: ''

Test orderbook functionality to filter based on delivery_length type, deliveryStartTime and deliveryEndTime.

test_​filter_​orderbook

Parameters:

  • delivery_length: 'HalfHour'

  • deliveryStartTime: '2025-05-05 06:00:00+00:00'

  • deliveryEndTime: ''

Test orderbook functionality to filter based on delivery_length type, deliveryStartTime and deliveryEndTime.

test_​filter_​orderbook

Parameters:

  • delivery_length: 'HalfHour'

  • deliveryStartTime: ''

  • deliveryEndTime: '2025-05-05 09:00:00+00:00'

Test orderbook functionality to filter based on delivery_length type, deliveryStartTime and deliveryEndTime.

test_​filter_​orderbook

Parameters:

  • delivery_length: 'HalfHour'

  • deliveryStartTime: '2025-05-05 06:00:00+00:00'

  • deliveryEndTime: '2025-05-05 09:00:00+00:00'

Test orderbook functionality to filter based on delivery_length type, deliveryStartTime and deliveryEndTime.

test_​filter_​EPEX_​orderbook

Parameters:

  • product: 'XBID_Quarter_Hour_Power'

  • deliverystart: '2023-01-01 06:30:00+00:00'

  • expected_columns: 22

  • expected_rows: 38

Test orderbook functionality with filter EPEX based on product with parameterized inputs and deliveryStartTime.

test_​filter_​EPEX_​orderbook

Parameters:

  • product: 'XBID_Quarter_Hour_Power'

  • deliverystart: None

  • expected_columns: 22

  • expected_rows: 3739

Test orderbook functionality with filter EPEX based on product with parameterized inputs and deliveryStartTime.

test_​filter_​EPEX_​orderbook

Parameters:

  • product: None

  • deliverystart: None

  • expected_columns: 22

  • expected_rows: 3739

Test orderbook functionality with filter EPEX based on product with parameterized inputs and deliveryStartTime.

test_​get_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.whole: 'whole'>

  • max_power_MW: 5

  • bucket_size: None

Test to get orderbook converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

test_​get_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.vwap: 'vwap'>

  • max_power_MW: 5

  • bucket_size: 2.0

Test to get orderbook converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

test_​get_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.max: 'max'>

  • max_power_MW: 5

  • bucket_size: 3.0

Test to get orderbook converted into buckets based on various bucketing approaches, max power and bucket size for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.whole: 'whole'>

  • expected_key: 'intraday_sell'

  • bucket_size: None

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.vwap: 'vwap'>

  • expected_key: 'intraday_sell'

  • bucket_size: 2.0

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.max: 'max'>

  • expected_key: 'intraday_sell'

  • bucket_size: 3.0

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.whole: 'whole'>

  • expected_key: 'intraday_buy'

  • bucket_size: None

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.vwap: 'vwap'>

  • expected_key: 'intraday_buy'

  • bucket_size: 2.0

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​get_​EPEX_​orderbook_​in_​buckets

Parameters:

  • bucketing_approach: <BucketingApproach.max: 'max'>

  • expected_key: 'intraday_buy'

  • bucket_size: 3.0

Test to get EPEX orderbook in buckets based on varying bucketing approaches, expected key and bucket sizes for vwap and max.

test_​missing_​market_​sides_​are_​filled

Test to check for missing parts in orderbook if filled with default values for market sides.

tests/tests_uk/test_partial_outages.py#

Test Name

Description (Risk/Safety Check)

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.01

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.1

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.2

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.3

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.4

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.5

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.6

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.7

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.8

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.9

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: True

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 1.0

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.01

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.1

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.2

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.3

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.4

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.5

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.6

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.7

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.8

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 0.9

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

test_​partial_​outages_​intraday_​uk

Parameters:

  • flat_price_curve: False

  • initial_soe: 0.5

  • partial_availability_timestamp: Timestamp('2024-06-06 22:00:00+0000', tz='UTC')

  • availability: 1.0

Test UK intraday optimizer with partial outages (time-dependent battery parameters). In the first half, battery is fully available; in the second half, only partially available.

tests/tests_uk/test_prod_warrington.py#

Test Name

Description (Risk/Safety Check)

test_​2025_​09_​22_​prod_​intraday_​infeasible

Parameters:

  • max_soe: 0.82

No description available.

test_​2025_​09_​22_​prod_​intraday_​infeasible

Parameters:

  • max_soe: 0.5

No description available.

tests/tests_uk/test_result.py#

Test Name

Description (Risk/Safety Check)

test_​commit_​sha_​in_​result

Ensure that the result includes a commit SHA to enhance transparency, indicating the version the optimizer was run

tests/tests_uk/test_tracing.py#

Test Name

Description (Risk/Safety Check)

test_​trace_​in_​result

Test that trace with correct spans and resources are part of the result of the optimization.

tests/tests_uk/test_uk_optimization_refactor.py#

Test Name

Description (Risk/Safety Check)

test_​handle_​request_​auto_​intraday

Parameters:

  • associated_fixture: 'request_2025_05_15_auto_intraday_solution'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that intraday results before the refactor are the same as after the refactor.

test_​handle_​request_​auto_​intraday

Parameters:

  • associated_fixture: 'request_2025_05_15_auto_intraday_solution_2'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that intraday results before the refactor are the same as after the refactor.

test_​handle_​request_​bod

Parameters:

  • associated_fixture: 'request_2025_05_15_bod_solution'

  • problem_type: <ProblemType.BOD: 'bod'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that BOD results before the refactor are the same as after the refactor.

test_​handle_​request_​melmil

Parameters:

  • associated_fixture: 'request_2025_05_15_bm_mel_mil_solution'

  • problem_type: <ProblemType.MELMIL: 'melmil'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that MELMIL results before the refactor are the same as after the refactor.

test_​handle_​request_​melmil_​boa

Parameters:

  • associated_fixture: 'request_2025_05_15_mel_mil_boa'

  • problem_type: <ProblemType.MELMILBOA: 'melmilboa'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that MELMILBOA results before the refactor are the same as after the refactor.

test_​handle_​request_​day_​ahead

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that day-ahead EPEX+DS results before the refactor are the same as after the refactor.

test_​handle_​request_​day_​ahead_​non_​iterative

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead_non_iterative'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that day-ahead EPEX+DS results before the refactor are the same as after the refactor.

test_​handle_​request_​day_​ahead_​non_​iterative_​gapRel_​0

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead_non_iterative_gapRel_0'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that day-ahead EPEX+DS results before the refactor are the same as after the refactor.

test_​handle_​request_​day_​ahead_​epex30min_​only

Parameters:

  • associated_fixture: 'request_2025_05_19_day_ahead_epex30min_only'

  • problem_type: <ProblemType.PNL: 'pnl'>

  • wrapper_class: <class 'battery_optimizer_app.models.APIWrappedBatteryOptimizer'>

Ensures that day-ahead EPEX results before the refactor are the same as after the refactor.

tests/tests_uk/test_uk_regression_testing.py#

Test Name

Description (Risk/Safety Check)

test_​2025_​10_​15_​regression_​test_​dc_​parameters_​1

No description available.

tests/tests_uk_ev/test_intraday_uk_ev.py#

Test Name

Description (Risk/Safety Check)

test_​intraday_​uk_​ev_​sample_​request

Test EV UK wrapped request handling with intraday orderbook