- 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>
41 lines
1.7 KiB
Python
Executable File
41 lines
1.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Prices for materials across all exchanges, with VWAP and daily traded volume; optional fill price for a quantity.
|
|
tools/price.py BHP STL # all CX
|
|
tools/price.py BHP --cx AI1 --qty 200 # avg fill price to buy/sell 200 at AI1 (walks the live book)
|
|
"""
|
|
import argparse, sys
|
|
from pathlib import Path
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
from puga import config, market
|
|
|
|
|
|
def f(x, w=7):
|
|
return f"{x:{w}.0f}" if x is not None else f"{'-':>{w}}"
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("tickers", nargs="+")
|
|
ap.add_argument("--cx", help="limit to one exchange")
|
|
ap.add_argument("--qty", type=float, help="show avg fill price for this quantity (needs --cx or uses default CX)")
|
|
ap.add_argument("--refresh", action="store_true")
|
|
a = ap.parse_args()
|
|
snap = market.snapshot(a.refresh)
|
|
print(f"{'mat':5} {'cx':4} {'bid':>7} {'ask':>7} {'vwap7':>7} {'vwap30':>7} {'trd/d7':>7} {'trd/d30':>7} {'demand':>7} {'supply':>7}")
|
|
for t in map(str.upper, a.tickers):
|
|
for cx in market.CXS:
|
|
if a.cx and cx != a.cx:
|
|
continue
|
|
q = snap.get((t, cx))
|
|
if q:
|
|
print(f"{t:5} {cx:4} {f(q.bid)} {f(q.ask)} {f(q.vwap7)} {f(q.vwap30)} {q.traded7:7.1f} {q.traded30:7.1f} {q.demand:7.0f} {q.supply:7.0f}")
|
|
if a.qty:
|
|
cx = a.cx or config.DEFAULT_CX
|
|
b, s = market.walk(t, cx, a.qty, "buy"), market.walk(t, cx, a.qty, "sell")
|
|
print(f" fill {a.qty:.0f} @ {cx}: buy avg {f(b['avg'])} (worst {f(b['worst'])}, filled {b['filled']:.0f}) | "
|
|
f"sell avg {f(s['avg'])} (worst {f(s['worst'])}, filled {s['filled']:.0f})")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|