# engine/execution.py from datetime import datetime from state import load_state, save_state from ledger import log_event def _as_float(value): if hasattr(value, "item"): try: return float(value.item()) except Exception: pass if hasattr(value, "iloc"): try: return float(value.iloc[-1]) except Exception: pass return float(value) def try_execute_sip( now, market_open, sip_interval, sip_amount, sp_price, gd_price, eq_w, gd_w, ): state = load_state() if not market_open: return state, False last = state["last_sip_ts"] if last and (now - datetime.fromisoformat(last)).total_seconds() < sip_interval: return state, False sp_price = _as_float(sp_price) gd_price = _as_float(gd_price) eq_w = _as_float(eq_w) gd_w = _as_float(gd_w) sip_amount = _as_float(sip_amount) sp_qty = (sip_amount * eq_w) / sp_price gd_qty = (sip_amount * gd_w) / gd_price state["sp_units"] += sp_qty state["gd_units"] += gd_qty state["total_invested"] += sip_amount state["last_sip_ts"] = now.isoformat() save_state(state) log_event("SIP_EXECUTED", { "sp_units": sp_qty, "gd_units": gd_qty, "sp_price": sp_price, "gd_price": gd_price, "amount": sip_amount }) return state, True