Files
ai-exchange/scripts/run_execution_ticket.py
2026-05-07 00:12:12 +08:00

106 lines
3.6 KiB
Python

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())