v0.27.0
What's New
Features
-
Forager composite-score auto-exclude (#146, #147) — A second-tier auto-exclude path that scores each coin on three dimensions and pauses quoting when the blended score falls below a threshold, separate from the existing markout-driven
auto_exclude. The score combines activity (close-event flow vs. idle), close-quality (maker close rate, with a minimum-closes gate before the dimension is trusted), and cost (per-1K-volume net cost). Each dimension is weighted independently so operators can re-balance without touching the score formula. Opt-in via--forager; tuning via--forager-threshold(default30.0) plus--forager-w-activity / -quality / -cost(defaults0.3 / 0.4 / 0.3). Cooldown and consecutive-strike gates mirror the existingauto_excludesemantics so the two features compose cleanly. The five non-CLI knobs (FORAGER_WINDOW_SECONDS,FORAGER_CHECK_INTERVAL_SECONDS,FORAGER_ACTIVITY_IDLE_MIN_SECONDS,FORAGER_COST_MAX_PER_1K,FORAGER_MIN_CLOSES_FOR_QUALITY) stay env-only to keep the CLI surface manageable. (#147 promotes the previously hardcoded 5-close quality gate to the same env knob, so all formula thresholds are configurable.) -
JSON config as a layered input source (#148, #149) — New
--config <path>CLI flag (repeatable; later files override earlier) andBOT_CONFIG=<path>env var that load a JSON file as a config layer between the dataclass defaults and CLI/env. Final precedence is CLI > env > JSON > defaults, so the rollout is opt-in and pure-additive: existing CLI/env workflows are byte-identical when no--configis supplied. The loader auto-detects flat ({"spread_bps": 10, …}) vs. nested ({"market_making": {"spread_bps": 10, …}}) form; nested keys are flattened against_NESTED_TO_FLAT_MAPso downstreamMMConfig.from_legacy_dict()is unchanged. JSON values under therisknamespace are wired through toConfig.{KEY.upper()}via a new_apply_json_risk_overrideshelper (closes the gap from the initial #148 wiring); CLI risk flags still beat JSON, JSON beats env, and the helper pops applied keys so they don't leak back intostrategy_config. Unknown keys log a typo warning but otherwise pass through; malformed JSON aborts startup with exit code 2 (fail-safe). Anexamples/config.example.jsoncovers the nested form.
Fixes
_STRATEGY_PARAMS/_COMMON_PARAMSat module scope (#150) — Latent bug discovered during round-trip migration-tool verification: PR #148 lazily imports these lists invalidation.strategy_validator.known_market_making_keys()for typo detection, but only_RISK_PARAMSwas promoted to module level in #149 — the other two stayed insidemain(), so any--configinvocation hitImportErrorat startup. This release moves both lists out ofmain()(call-sites unchanged) and adds aTestKnownMarketMakingKeysregression class that pins the contract via direct import + indirect function calls; future demotion will fail CI rather than reach production.
Upgrade Notes
- All changes are backward compatible — defaults preserve existing behaviour:
- Forager is default-disabled. Without
--foragerthe strategy and shutdown paths are byte-identical to v0.26.0. Operators flipping it on are advised to start with the default weights and--forager-threshold 30, observe[forager]log lines for at least one full session, and tighten only after the per-coin score distribution stabilises. - JSON config is opt-in. With neither
--confignorBOT_CONFIGset, the JSON loader is never invoked. When set, the layer sits below env/CLI; existing.env.farming+start_farming*.shflows continue to win on every shared key. - Migration tool: a companion
scripts/env_to_json.pylives in thehip-3-farming-agent-teamrepo — it converts.env.farmingto a nested JSON config, skipping credentials/DEX/framework keys. Useful for staging a JSON deployment without re-typing the existing knob set. - Level 1 risk guardrails (
risk_manager.pyhardcoded values) are untouched in this release.
- Forager is default-disabled. Without
Operator Checklist
- Forager Phase A (default weights,
min_fills=3, score threshold 30): turn on viaFORAGER_ENABLED=true+--forager. Watch the per-coin score component breakdown in the periodic[forager]summary; confirm no coin is scored below threshold purely on a single dimension before tightening any weight. - JSON config Phase A (loader path validation): set
BOT_CONFIG=/abs/path/config.jsonin.env.farmingwhile leaving all CLI flags instart_farming*.shintact. Confirm[config] Loaded N key(s) from …and[config] JSON layer loaded: N key(s) from 1 file(s)appear at startup with no warnings beyond intentional skips. Phase B (stripping CLI flags so JSON drives values) is a separate operator step after a 24h observation window.