@@ -56,6 +56,8 @@ class PlatformRuntimeSettings:
5656 income_layer_enabled : bool | None = None
5757 income_layer_start_usd : float | None = None
5858 income_layer_max_ratio : float | None = None
59+ dca_mode : str | None = None
60+ dca_base_investment_usd : float | None = None
5961 runtime_execution_window_trading_days : int | None = None
6062 feature_snapshot_path : str | None = None
6163 feature_snapshot_manifest_path : str | None = None
@@ -172,6 +174,8 @@ def load_platform_runtime_settings(
172174 income_layer_enabled = _optional_bool_env ("INCOME_LAYER_ENABLED" ),
173175 income_layer_start_usd = _optional_non_negative_float_env ("INCOME_LAYER_START_USD" ),
174176 income_layer_max_ratio = _optional_ratio_env ("INCOME_LAYER_MAX_RATIO" ),
177+ dca_mode = _optional_dca_mode_env ("DCA_MODE" ),
178+ dca_base_investment_usd = _optional_positive_float_env ("DCA_BASE_INVESTMENT_USD" ),
175179 runtime_execution_window_trading_days = _runtime_execution_window_trading_days_env (
176180 strategy_definition .profile
177181 ),
@@ -314,6 +318,34 @@ def _optional_non_negative_float_env(name: str) -> float | None:
314318 return float (value )
315319
316320
321+ def _optional_positive_float_env (name : str ) -> float | None :
322+ value = resolve_optional_float_env (os .environ , name )
323+ if value is None :
324+ return None
325+ if not math .isfinite (value ):
326+ raise ValueError (f"{ name } must be finite, got { value } " )
327+ if value <= 0 :
328+ raise ValueError (f"{ name } must be positive, got { value } " )
329+ return float (value )
330+
331+
332+ def _optional_dca_mode_env (name : str ) -> str | None :
333+ raw_value = os .getenv (name )
334+ if raw_value is None or str (raw_value ).strip () == "" :
335+ return None
336+ value = str (raw_value ).strip ().lower ()
337+ aliases = {
338+ "ordinary" : "fixed" ,
339+ "ordinary_dca" : "fixed" ,
340+ "fixed_dca" : "fixed" ,
341+ "smart_dca" : "smart" ,
342+ }
343+ mode = aliases .get (value , value )
344+ if mode not in {"fixed" , "smart" }:
345+ raise ValueError (f"{ name } must be fixed or smart, got { raw_value !r} " )
346+ return mode
347+
348+
317349def _resolve_non_negative_float_env (name : str , * , default : float ) -> float :
318350 value = resolve_optional_float_env (os .environ , name )
319351 if value is None :
0 commit comments