Coverage for agentlib_flexquant/data_structures/market.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-10-20 14:09 +0000

1""" 

2Market specification data models for flexibility offer acceptance strategies. 

3 

4Defines Pydantic models for configuring different market behaviors including 

5random acceptance, single offer acceptance, and custom strategies with 

6associated parameters and validation. 

7""" 

8from typing import Literal, Union 

9 

10import pydantic 

11 

12from agentlib_flexquant.data_structures.globals import FlexibilityDirections, COLLOCATION, CONSTANT 

13 

14 

15class RandomOptions(pydantic.BaseModel): 

16 """Configuration options for random market behavior.""" 

17 

18 type: Literal["random"] 

19 random_seed: int = pydantic.Field( 

20 name="random_seed", 

21 default=None, 

22 description="Random seed for reproducing experiments", 

23 ) 

24 

25 pos_neg_rate: float = pydantic.Field( 

26 name="pos_neg_rate", 

27 default=0, 

28 description="Determines the likelihood positive and the negative flexibility." 

29 "A higher rate means that more positive offers will be accepted.", 

30 le=1, 

31 ge=0, 

32 ) 

33 

34 offer_acceptance_rate: float = pydantic.Field( 

35 name="offer_acceptance_rate", 

36 default=0.5, 

37 description="Determines the likelihood of an accepted offer", 

38 le=1, 

39 ge=0, 

40 ) 

41 

42 

43class SingleOptions(pydantic.BaseModel): 

44 """Configuration options for single offer acceptance market behavior.""" 

45 

46 type: Literal["single"] 

47 offer_acceptance_time: float = pydantic.Field( 

48 description="After this time, the first available flex offer is accepted" 

49 ) 

50 direction: FlexibilityDirections = pydantic.Field( 

51 default="positive", description="Direction of the flexibility" 

52 ) 

53 

54 

55class CustomOptions(pydantic.BaseModel): 

56 """Configuration options for custom market behavior with flexible parameters.""" 

57 

58 type: Literal["custom"] 

59 

60 model_config = pydantic.ConfigDict(extra="allow") 

61 

62 

63class MarketSpecifications(pydantic.BaseModel): 

64 """Base specification for flexibility market behavior and parameters.""" 

65 

66 type: str = pydantic.Field(default=None, description="Name of market type") 

67 

68 cooldown: int = pydantic.Field( 

69 name="cooldown", 

70 default=6, 

71 description="cooldown time (no timesteps) after a provision", 

72 ) 

73 

74 minimum_average_flex: float = pydantic.Field( 

75 name="minimum_average_flex", 

76 default=0, 

77 unit="W", 

78 description="minimum average of an accepted offer", 

79 ) 

80 

81 options: Union[RandomOptions, SingleOptions, CustomOptions] = pydantic.Field( 

82 ..., 

83 description="Market options, changes depending on 'type'", 

84 discriminator="type", 

85 ) 

86 

87 accepted_offer_sample_points: Literal[COLLOCATION, CONSTANT] = pydantic.Field( 

88 default='collocation', 

89 description="Method defining how to send the accepted flexibility power back" 

90 "to the baseline mpc so that the system can deliver it. " 

91 "This is relevant for collocation, as the power profile is only " 

92 "defined at the collocation points. If you choose constant here, " 

93 "the values are averaged and set for the whole time step." 

94 "Set to constant if the power only depends on control or if " 

95 "system has low inertial. Otherwise, use collocation.", 

96 ) 

97 

98 # Root validator to automatically populate the options.type from the top-level type 

99 @pydantic.model_validator(mode="before") 

100 @classmethod 

101 def set_options_type(cls, values): 

102 """Automatically set the options type field from the top-level market type.""" 

103 market_type = values.get("type") 

104 options = values.get("options", {}) 

105 

106 # Ensure the options dict contains the correct 'type' field 

107 if isinstance(options, dict) and "type" not in options: 

108 options["type"] = market_type 

109 values["options"] = options 

110 

111 return values 

112 

113 

114class RandomMarket(MarketSpecifications): 

115 """Market specification for random flexibility offer acceptance behavior.""" 

116 

117 type: str = "random"