22from typing import Dict , List , Optional , Set , Tuple , Union
33
44from pydantic import Field , field_validator
5+ from pydantic_core .core_schema import ValidationInfo
56
6- from hummingbot .client .config .config_data_types import ClientFieldData
77from hummingbot .core .data_type .common import OrderType , PositionMode , PriceType , TradeType
88from hummingbot .core .data_type .trade_fee import TokenAmount
99from hummingbot .data_feed .candles_feed .data_types import CandlesConfig
@@ -137,19 +137,17 @@ class PMMConfig(ControllerConfigBase):
137137 )
138138 global_take_profit : Decimal = Decimal ("0.02" )
139139
140- # TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
141- # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
142- @validator ("take_profit" , pre = True , always = True )
140+ @field_validator ("take_profit" , mode = "before" )
141+ @classmethod
143142 def validate_target (cls , v ):
144143 if isinstance (v , str ):
145144 if v == "" :
146145 return None
147146 return Decimal (v )
148147 return v
149148
150- # TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
151- # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
152- @validator ('take_profit_order_type' , pre = True , allow_reuse = True , always = True )
149+ @field_validator ('take_profit_order_type' , mode = "before" )
150+ @classmethod
153151 def validate_order_type (cls , v ) -> OrderType :
154152 if isinstance (v , OrderType ):
155153 return v
@@ -165,20 +163,8 @@ def validate_order_type(cls, v) -> OrderType:
165163 pass
166164 raise ValueError (f"Invalid order type: { v } . Valid options are: { ', ' .join (OrderType .__members__ )} " )
167165
168- @property
169- def triple_barrier_config (self ) -> TripleBarrierConfig :
170- return TripleBarrierConfig (
171- take_profit = self .take_profit ,
172- trailing_stop = None ,
173- open_order_type = OrderType .LIMIT_MAKER , # Defaulting to LIMIT as is a Maker Controller
174- take_profit_order_type = self .take_profit_order_type ,
175- stop_loss_order_type = OrderType .MARKET , # Defaulting to MARKET as per requirement
176- time_limit_order_type = OrderType .MARKET # Defaulting to MARKET as per requirement
177- )
178-
179- # TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
180- # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
181- @validator ('buy_spreads' , 'sell_spreads' , pre = True , always = True )
166+ @field_validator ('buy_spreads' , 'sell_spreads' , mode = "before" )
167+ @classmethod
182168 def parse_spreads (cls , v ):
183169 if v is None :
184170 return []
@@ -188,18 +174,18 @@ def parse_spreads(cls, v):
188174 return [float (x .strip ()) for x in v .split (',' )]
189175 return v
190176
191- # TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
192- # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
193- @ validator ( 'buy_amounts_pct' , 'sell_amounts_pct' , pre = True , always = True )
194- def parse_and_validate_amounts ( cls , v , values , field ):
177+ @ field_validator ( 'buy_amounts_pct' , 'sell_amounts_pct' , mode = "before" )
178+ @ classmethod
179+ def parse_and_validate_amounts ( cls , v , validation_info : ValidationInfo ):
180+ field_name = validation_info . field_name
195181 if v is None or v == "" :
196- spread_field = field . name .replace ('amounts_pct' , 'spreads' )
197- return [1 for _ in values [spread_field ]]
182+ spread_field = field_name .replace ('amounts_pct' , 'spreads' )
183+ return [1 for _ in validation_info . data [spread_field ]]
198184 if isinstance (v , str ):
199185 return [float (x .strip ()) for x in v .split (',' )]
200- elif isinstance (v , list ) and len (v ) != len (values [ field . name .replace ('amounts_pct' , 'spreads' )]):
186+ elif isinstance (v , list ) and len (v ) != len (validation_info . data [ field_name .replace ('amounts_pct' , 'spreads' )]):
201187 raise ValueError (
202- f"The number of { field . name } must match the number of { field . name .replace ('amounts_pct' , 'spreads' )} ." )
188+ f"The number of { field_name } must match the number of { field_name .replace ('amounts_pct' , 'spreads' )} ." )
203189 return v
204190
205191 @field_validator ('position_mode' , mode = "before" )
@@ -211,6 +197,17 @@ def validate_position_mode(cls, v) -> PositionMode:
211197 raise ValueError (f"Invalid position mode: { v } . Valid options are: { ', ' .join (PositionMode .__members__ )} " )
212198 return v
213199
200+ @property
201+ def triple_barrier_config (self ) -> TripleBarrierConfig :
202+ return TripleBarrierConfig (
203+ take_profit = self .take_profit ,
204+ trailing_stop = None ,
205+ open_order_type = OrderType .LIMIT_MAKER , # Defaulting to LIMIT as is a Maker Controller
206+ take_profit_order_type = self .take_profit_order_type ,
207+ stop_loss_order_type = OrderType .MARKET , # Defaulting to MARKET as per requirement
208+ time_limit_order_type = OrderType .MARKET # Defaulting to MARKET as per requirement
209+ )
210+
214211 def update_parameters (self , trade_type : TradeType , new_spreads : Union [List [float ], str ], new_amounts_pct : Optional [Union [List [int ], str ]] = None ):
215212 spreads_field = 'buy_spreads' if trade_type == TradeType .BUY else 'sell_spreads'
216213 amounts_pct_field = 'buy_amounts_pct' if trade_type == TradeType .BUY else 'sell_amounts_pct'
0 commit comments