auto: hourly snapshot 2026-06-07 13:34
This commit is contained in:
+34
-18
@@ -84,15 +84,25 @@ DEFAULT_DAYS_GLOB = "20260415*"
|
||||
# (the whole point of this injector)
|
||||
MAP_SCALE = {
|
||||
# funding_rate from HL is per-hour. Annualised bps = rate * 8760 * 10000.
|
||||
# 100bps annualised → 1.0 dipole strength leg.
|
||||
# Cap at ±2.0 leg strength (i.e. ±200bps annualised funding).
|
||||
"funding_bps_per_strength": 100.0,
|
||||
"funding_strength_cap": 2.0,
|
||||
# Calibrated 2026-06-07 on 720 hourly rows from April BTC HL fundingHistory.
|
||||
# Real distribution: median |val|=620bps, q90=1265bps, q99=2320bps, max=3835bps.
|
||||
# 3000bps annualised → 1.0 dipole-leg strength.
|
||||
# Second rebalance 2026-06-07: previous scale (1000bps/strength, cap 2.5)
|
||||
# left funding firing as a near-constant DC offset at strength ~1.3 every
|
||||
# minute, dominating the stress tensor. Tripling the scale shrinks each
|
||||
# dipole leg to ~0.4 and lets minute-to-minute variance show through.
|
||||
"funding_bps_per_strength": 3000.0,
|
||||
"funding_strength_cap": 2.5,
|
||||
|
||||
# bs_ratio_signed ranges natively ±0.5 (since ratio is 0..1, minus 0.5).
|
||||
# Scale ×2 so full ±0.5 → ±1.0 strength.
|
||||
# Cap ±3.0 (rebalance 2026-06-07): single-blob encoding was mute (ρ<0.15)
|
||||
# because a single density blob doesn't couple to global telemetry channels.
|
||||
# Second rebalance 2026-06-07: bs_ratio is now a Y-AXIS DIPOLE (mechanically
|
||||
# equivalent to funding's x-axis dipole, rotated 90°). Couples cleanly to
|
||||
# stress_yy and vel_mean on equal footing with funding.
|
||||
"bs_ratio_per_strength": 0.5,
|
||||
"bs_ratio_strength_cap": 1.0,
|
||||
"bs_ratio_strength_cap": 3.0,
|
||||
|
||||
# activity_excess = (trade_count / rolling_500min_mean) - 1.
|
||||
# Centred at 0. -1 = zero activity. +2 = 3× baseline. +5 = 6× baseline.
|
||||
@@ -115,9 +125,9 @@ EPS_BPS = 0.5 # epsilon to prevent /0 in cvd_div denominator
|
||||
|
||||
# Lattice spatial geometry (lattice is 1024×1024, center 512,512)
|
||||
CENTER = (512.0, 512.0)
|
||||
DIPOLE_OFF = 64.0 # dipole leg offset from center
|
||||
OFFSET_OFF = 64.0 # velocity-bias single-blob offset from center
|
||||
RING_R = 96.0 # vorticity ring radius
|
||||
DIPOLE_OFF = 64.0 # dipole leg offset from center (funding x, bs_ratio y)
|
||||
RING_R = 192.0 # vorticity ring radius (was 96; doubled 2026-06-07 to
|
||||
# register in the global vorticity_mean metric)
|
||||
SIGMA = 32.0 # gaussian sigma of each injection blob
|
||||
|
||||
# Vorticity ring: N legs around the ring, alternating signs to create curl.
|
||||
@@ -319,8 +329,11 @@ def encode_funding_dipole(pub: zmq.Socket, funding_bps: float) -> None:
|
||||
|
||||
|
||||
def encode_bsratio_velocity(pub: zmq.Socket, bs_ratio_signed: float) -> None:
|
||||
"""bs_ratio_signed → y-axis offset blob. Positive = more buying = +y push.
|
||||
Y-axis chosen to keep funding (x-dipole) and bs_ratio orthogonal."""
|
||||
"""bs_ratio_signed → Y-AXIS dipole (mechanically equivalent to funding's
|
||||
x-axis dipole, rotated 90°). Positive = buy pressure pushes +y leg positive,
|
||||
-y leg negative. Couples to global stress_yy / vel_mean.
|
||||
Second rebalance 2026-06-07: was a single offset blob that didn't couple
|
||||
to any global telemetry channel."""
|
||||
if not np.isfinite(bs_ratio_signed):
|
||||
return
|
||||
strength = bs_ratio_signed / MAP_SCALE["bs_ratio_per_strength"]
|
||||
@@ -329,8 +342,8 @@ def encode_bsratio_velocity(pub: zmq.Socket, bs_ratio_signed: float) -> None:
|
||||
if abs(strength) < 1e-6:
|
||||
return
|
||||
cx, cy = CENTER
|
||||
sign = +1.0 if strength > 0 else -1.0
|
||||
_send_inject(pub, cx, cy + OFFSET_OFF * sign, abs(strength))
|
||||
_send_inject(pub, cx, cy - DIPOLE_OFF, -strength)
|
||||
_send_inject(pub, cx, cy + DIPOLE_OFF, +strength)
|
||||
|
||||
|
||||
def encode_activity_isotropic(pub: zmq.Socket, activity_excess: float) -> None:
|
||||
@@ -458,6 +471,8 @@ def main():
|
||||
help="comma-separated arm names to run (default A,T)")
|
||||
ap.add_argument("--skip-funding", action="store_true",
|
||||
help="don't fetch funding history (uses NaN; useful for dry run)")
|
||||
ap.add_argument("--cooldown-s", type=int, default=COOLDOWN_BETWEEN_ARMS_S,
|
||||
help="seconds to wait between arms (only applies after arm T)")
|
||||
args = ap.parse_args()
|
||||
|
||||
log(f"=== market_tension_injector run_id={RUN_ID} ===")
|
||||
@@ -505,7 +520,7 @@ def main():
|
||||
"map_scale": MAP_SCALE,
|
||||
"spatial": {
|
||||
"center": list(CENTER), "dipole_off": DIPOLE_OFF,
|
||||
"offset_off": OFFSET_OFF, "ring_r": RING_R,
|
||||
"ring_r": RING_R,
|
||||
"sigma": SIGMA, "vorticity_n_legs": VORTICITY_N_LEGS,
|
||||
},
|
||||
"timing": {
|
||||
@@ -534,15 +549,16 @@ def main():
|
||||
f"{(time.time()-tel.latest_wall)*1000 if tel.latest_wall else -1:.0f}")
|
||||
|
||||
try:
|
||||
arms_to_run = args.arms.split(",")
|
||||
arms_to_run = [a.strip().upper() for a in args.arms.split(",")]
|
||||
for ai, arm in enumerate(arms_to_run):
|
||||
arm = arm.strip().upper()
|
||||
if arm not in ("A", "T"):
|
||||
log(f"skipping unknown arm: {arm}")
|
||||
continue
|
||||
if ai > 0:
|
||||
log(f"--- cooldown {COOLDOWN_BETWEEN_ARMS_S}s ---")
|
||||
time.sleep(COOLDOWN_BETWEEN_ARMS_S)
|
||||
# Only cooldown AFTER arm T (the perturbing arm).
|
||||
# Arm A is passive, no field settling needed before/after it.
|
||||
if ai > 0 and arms_to_run[ai - 1] == "T":
|
||||
log(f"--- cooldown {args.cooldown_s}s (let field settle after arm T) ---")
|
||||
time.sleep(args.cooldown_s)
|
||||
arm_df = run_arm(tel, pub if arm == "T" else None, arm, df)
|
||||
outf = OUT_DIR / f"arm_{arm}_{'tension' if arm=='T' else 'no_inject'}.parquet"
|
||||
arm_df.to_parquet(outf)
|
||||
|
||||
Reference in New Issue
Block a user