Initial PuGa toolkit: data layer, econ, depth-aware scan, state sync, plan push
- puga/: cached FIO + PRUNplanner clients, market view with order-book walk, econ formulas ported from PRUNplanner (tested against its suite and live FIO), saturation model v1 (reviewed by Opus) - tools/: scan (depth-aware), price, book, chain, state sync, plan_push (dry run default, [PuGa]-prefixed plans only), legacy prun_scan/prun_cxarb - docs/: mechanics (PRUNplanner is source of truth), roadmap, decisions, saturation design, archived handoff - secrets stay in .env (gitignored); ref/ holds PRUNplanner source (ignored) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Order-book ladder for one material at one exchange: price levels with cumulative units and value.
|
||||
tools/book.py BHP --cx AI1 --levels 8
|
||||
"""
|
||||
import argparse, sys
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
from puga import config, fio
|
||||
|
||||
|
||||
def ladder(orders, reverse):
|
||||
lv = defaultdict(int)
|
||||
for o in orders:
|
||||
if o.get("ItemCount") != 0:
|
||||
lv[o["ItemCost"]] += 10**9 if o.get("ItemCount") is None else o["ItemCount"] # 10**9 = market maker, unlimited
|
||||
cum, out = 0, []
|
||||
for price in sorted(lv, reverse=reverse):
|
||||
cum += lv[price]
|
||||
out.append((price, lv[price], cum))
|
||||
return out
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("ticker")
|
||||
ap.add_argument("--cx", default=config.DEFAULT_CX)
|
||||
ap.add_argument("--levels", type=int, default=8)
|
||||
ap.add_argument("--refresh", action="store_true")
|
||||
a = ap.parse_args()
|
||||
t = a.ticker.upper()
|
||||
ob = fio.order_book(t, a.cx, a.refresh)
|
||||
asks, bids = ladder(ob["SellingOrders"], False), ladder(ob["BuyingOrders"], True)
|
||||
print(f"{t}.{a.cx} ask {ob.get('Ask')} bid {ob.get('Bid')} supply {ob.get('Supply')} demand {ob.get('Demand')} "
|
||||
f"MMBuy {ob.get('MMBuy')} MMSell {ob.get('MMSell')}")
|
||||
print(f"{'ASKS':>8} {'units':>7} {'cum':>7} | {'BIDS':>8} {'units':>7} {'cum':>7}")
|
||||
for i in range(a.levels):
|
||||
l = f"{asks[i][0]:8.0f} {asks[i][1]:7d} {asks[i][2]:7d}" if i < len(asks) else " " * 24
|
||||
r = f"{bids[i][0]:8.0f} {bids[i][1]:7d} {bids[i][2]:7d}" if i < len(bids) else ""
|
||||
print(f"{l} | {r}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user