"""Backward-compatible facade for precheck internals. The reusable implementation has been split into smaller modules: - precheck_constants : paths and thresholds - time_utils : UTC/local time helpers - data_utils : json, hash, float, symbol normalization - state_manager : load/save/sanitize state - market_data : exchange, ohlcv, metrics - candidate_scoring : top candidate selection - snapshot_builder : build_snapshot - adaptive_profile : trigger profile builder - trigger_analyzer : analyze_trigger Keep this module importable so older entrypoints continue to work. """ from __future__ import annotations from importlib import import_module from ..runtime import get_runtime_paths _PATH_ALIASES = { "PATHS": lambda: get_runtime_paths(), "BASE_DIR": lambda: get_runtime_paths().root, "STATE_DIR": lambda: get_runtime_paths().state_dir, "STATE_FILE": lambda: get_runtime_paths().precheck_state_file, "POSITIONS_FILE": lambda: get_runtime_paths().positions_file, "CONFIG_FILE": lambda: get_runtime_paths().config_file, "ENV_FILE": lambda: get_runtime_paths().env_file, } _MODULE_MAP = { "BASE_PRICE_MOVE_TRIGGER_PCT": ".precheck_constants", "BASE_PNL_TRIGGER_PCT": ".precheck_constants", "BASE_PORTFOLIO_MOVE_TRIGGER_PCT": ".precheck_constants", "BASE_CANDIDATE_SCORE_TRIGGER_RATIO": ".precheck_constants", "BASE_FORCE_ANALYSIS_AFTER_MINUTES": ".precheck_constants", "BASE_COOLDOWN_MINUTES": ".precheck_constants", "TOP_CANDIDATES": ".precheck_constants", "MIN_ACTIONABLE_USDT": ".precheck_constants", "MIN_REAL_POSITION_VALUE_USDT": ".precheck_constants", "BLACKLIST": ".precheck_constants", "HARD_STOP_PCT": ".precheck_constants", "HARD_MOON_PCT": ".precheck_constants", "MIN_CHANGE_PCT": ".precheck_constants", "MAX_PRICE_CAP": ".precheck_constants", "HARD_REASON_DEDUP_MINUTES": ".precheck_constants", "MAX_PENDING_TRIGGER_MINUTES": ".precheck_constants", "MAX_RUN_REQUEST_MINUTES": ".precheck_constants", "utc_now": ".time_utils", "utc_iso": ".time_utils", "parse_ts": ".time_utils", "get_local_now": ".time_utils", "session_label": ".time_utils", "load_json": ".data_utils", "stable_hash": ".data_utils", "to_float": ".data_utils", "norm_symbol": ".data_utils", "load_env": ".state_manager", "load_positions": ".state_manager", "load_state": ".state_manager", "load_config": ".state_manager", "clear_run_request_fields": ".state_manager", "sanitize_state_for_stale_triggers": ".state_manager", "save_state": ".state_manager", "update_state_after_observation": ".state_manager", "get_exchange": ".market_data", "fetch_ohlcv_batch": ".market_data", "compute_ohlcv_metrics": ".market_data", "enrich_candidates_and_positions": ".market_data", "regime_from_pct": ".market_data", "_liquidity_score": ".candidate_scoring", "_breakout_score": ".candidate_scoring", "top_candidates_from_tickers": ".candidate_scoring", "build_snapshot": ".snapshot_builder", "build_adaptive_profile": ".adaptive_profile", "_candidate_weight": ".adaptive_profile", "analyze_trigger": ".trigger_analyzer", } __all__ = sorted(set(_MODULE_MAP) | set(_PATH_ALIASES) | {"main"}) def __getattr__(name: str): if name in _PATH_ALIASES: return _PATH_ALIASES[name]() if name not in _MODULE_MAP: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") module_name = _MODULE_MAP[name] module = import_module(module_name, __package__) return getattr(module, name) def __dir__(): return sorted(set(globals()) | set(__all__)) def main(): import sys from .precheck_service import run as _run_service return _run_service(sys.argv[1:]) if __name__ == "__main__": raise SystemExit(main())