63 lines
1.4 KiB
Python
63 lines
1.4 KiB
Python
# 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
|