- puga/contd.py, tools/contd.py: price open CONTD contract offers against real buy-fresh cost, flagging conditions that can't be priced from the API alone. - tools/buyat.py: cheapest bid price likely to fill by a hard deadline (stockout risk), using the empirical first-passage model from history.py. - puga/actpkg.py, tools/actpkg.py: Refined PrUn XIT ACT buy-list JSON packages. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
"""Refined PrUn (github.com/refined-prun/refined-prun) XIT ACT action-package JSON - the semi-auto
|
|
buy-list format: importing one pre-fills the in-game CXPO buy tile for each material, the player
|
|
still clicks the real buy button themselves. Schema confirmed from the extension's own source
|
|
(src/store/user-data.types.d.ts, src/features/XIT/ACT/actions/cx-buy/cx-buy.ts, 2026-10-17).
|
|
|
|
Gotcha (verified against the real extension, not just reading the source): `global.name` (and group/
|
|
action names) get turned directly into an in-game command string by ActionPackageList.vue - spaces
|
|
become underscores but other punctuation survives into the command literally, and APEX's command
|
|
parser then rejects it with a generic "Illegal command" error on Edit/Execute (NOT on import, so it
|
|
looks like the JSON is fine until you actually open it). sanitize_name() strips anything but
|
|
letters/digits/spaces to avoid this.
|
|
"""
|
|
import re
|
|
|
|
|
|
def sanitize_name(name: str) -> str:
|
|
return re.sub(r"[^A-Za-z0-9 ]", "", name).strip()
|
|
|
|
|
|
def build_package(name: str, materials: dict[str, float], exchange: str = "AI1") -> dict:
|
|
"""materials: {ticker: qty}. Quantities are rounded up to whole units (CXPO buy amounts aren't
|
|
fractional)."""
|
|
name = sanitize_name(name)
|
|
group = sanitize_name(name.lower()) or "group"
|
|
import math
|
|
mats = {tk.upper(): math.ceil(qty) for tk, qty in materials.items() if qty > 0}
|
|
return {
|
|
"global": {"name": name},
|
|
"groups": [
|
|
{"type": "Manual", "name": group, "materials": mats},
|
|
],
|
|
"actions": [
|
|
{
|
|
"type": "CX Buy",
|
|
"name": f"Buy {name}",
|
|
"group": group,
|
|
"exchange": exchange,
|
|
"priceLimits": {},
|
|
"buyPartial": False,
|
|
"allowUnfilled": False,
|
|
"useCXInv": True,
|
|
}
|
|
],
|
|
}
|