from pathlib import Path import json import os import sys from sqlalchemy.exc import SQLAlchemyError ROOT = Path(__file__).resolve().parents[1] os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://user:pass@localhost:5432/ai_ict_test") if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from scripts.run_execution import build_account_risk_state_from_env from src.services.execution import ExecutionService from src.services.market_state import MarketStateService, get_market_truth_supervisor def build_execution_mode_from_env(env=None) -> str: env = os.environ if env is None else env return str(env.get("EXECUTION_MODE") or "semi_auto").strip() or "semi_auto" def main(env=None) -> int: env = os.environ if env is None else env output_json = _get_bool(env, "EXECUTION_TICKET_OUTPUT_JSON", False) signal_id = _get_int(env, "EXECUTION_SIGNAL_ID", 1) execution_mode = build_execution_mode_from_env(env=env) account_equity = _get_float(env, "EXECUTION_ACCOUNT_EQUITY", 10000.0) risk_pct = _get_float(env, "EXECUTION_RISK_PCT", 0.01) confirm_ticket = _get_bool(env, "EXECUTION_CONFIRM_TICKET", False) confirmed_by = str(env.get("EXECUTION_CONFIRMED_BY") or "local_operator") service = ExecutionService( market_state_service=MarketStateService(market_truth_supervisor=get_market_truth_supervisor()) ) account_state = build_account_risk_state_from_env(env=env) try: ticket = service.create_execution_ticket( signal_id=signal_id, execution_mode=execution_mode, account_equity=account_equity, risk_pct=risk_pct, account_state=account_state, ) confirmed = None if ticket is not None and confirm_ticket: confirmed = service.confirm_execution_ticket( ticket.ticket_id, confirmed_by=confirmed_by, account_equity=account_equity, risk_pct=risk_pct, account_state=account_state, ) except SQLAlchemyError as exc: payload = { "passed": False, "signal_id": signal_id, "execution_mode": execution_mode, "error_type": exc.__class__.__name__, "error": str(exc), } if output_json: print(json.dumps(payload, default=str, ensure_ascii=False, sort_keys=True)) else: print(f"Database unavailable for execution ticket sample: {exc.__class__.__name__}") return 2 payload = { "passed": True, "signal_id": signal_id, "execution_mode": execution_mode, "ticket": ticket.to_dict() if ticket is not None else None, "confirmed": confirmed.to_dict() if confirmed is not None else None, } if output_json: print(json.dumps(payload, default=str, ensure_ascii=False, sort_keys=True)) else: print( f"Ticket status: {(ticket.status if ticket else 'missing')}; " f"confirmed status: {(confirmed.status if confirmed else 'not_confirmed')}" ) return 0 def _get_float(env, key: str, default: float) -> float: value = env.get(key) if value is None or value == "": return default return float(value) def _get_int(env, key: str, default: int) -> int: value = env.get(key) if value is None or value == "": return default return int(value) def _get_bool(env, key: str, default: bool) -> bool: value = env.get(key) if value is None or value == "": return default return str(value).strip().lower() in {"1", "true", "yes", "on"} if __name__ == "__main__": raise SystemExit(main())