Skip to content

Release v0.15.0#230

Merged
ArthurBernard merged 13 commits into
masterfrom
develop
Jul 14, 2026
Merged

Release v0.15.0#230
ArthurBernard merged 13 commits into
masterfrom
develop

Conversation

@ArthurBernard

Copy link
Copy Markdown
Owner

Release v0.15.0 — the daemon-logging epic (PRs #226#228 + plan #225).

Added

ArthurBernard and others added 13 commits July 14, 2026 14:04
Wire a real logging setup for the daemon path (start [--serve]):

- LoggingConfig (level/dir/retention_days) as an additive logging: section
  on AppConfig — a manifest without one keeps the defaults (INFO, logs/, 14d).
- configure_daemon_logging(): midnight-rotated TimedRotatingFileHandler
  (daemon.log, backupCount=retention_days) + a stderr StreamHandler on the
  root logger, ISO-8601 local timestamps with numeric UTC offset; noisy
  third-party namespaces (apscheduler/uvicorn/httpx/websockets) capped at
  WARNING; idempotent via owned-handler tagging.
- _run_daemon routes its lifecycle lines through trading_bot.daemon:
  started/stopped log + console, per-tick line log-only, tick errors via
  logger.exception so tracebacks land in the file.

Interactive CLI commands keep their rich-console output unchanged.
feat: daemon logging spine — rotated, timestamped, manifest-configurable
…rs, fills

Make the daemon log tell each unit's story so "why hasn't alloc1-kraken
traded since genesis?" is answerable by grepping logs/daemon.log, while an
idle steady-state tick still adds zero per-unit INFO lines.

- PortfolioRunner: one INFO rebalance-summary per evaluated tick
  (unit / asof / legs / submitted / round_up / skipped / on_target — the four
  counters partition the universe); elevate round_up/skip leg decisions to
  pinned INFO lines carrying the LegDecision.reason; INFO on each accepted
  order (cid/side/qty/symbol/px/venue_id) and WARN on a refused leg. Plain
  submits stay summary-only (no double INFO). Idle ticks are gated before
  rebalance() runs, so they emit nothing.
- OrderFillSync: optional unit_name; INFO per applied fill
  (cid / signed qty / price / fee / fee_asset-or-quote), prefixed unit= when
  known, threaded from service_factory for a single-unit slice.
- StrategySupervisor: INFO on unit start/stop, ERROR (logger.exception) when a
  unit's step raises, DEBUG on a no-new-bar tick.

Verified on today's real dccd bars via a scratch daemon (fresh empty books,
port 8099): both units' genesis rebalance summaries, skip lines with full
reasons, submit lines and their matching fills — one fill cross-checked to
the store (cid/qty/price exact) — and an idle tick adding only the heartbeat.
feat: per-unit daemon log trail — rebalance summaries, skip reasons, order/fill lines
…elds

Measure and expose the daemon's tick cadence so the ~74 s-vs-60 s realised
shortfall a health audit measured can be proven or refuted with data.

- cli/main.py: a `_TickMetrics` closure counter times every `step_all` with a
  monotonic clock; the leaf-01 heartbeat now carries the duration
  (`stepped N strategy(ies) in <s.mmm>s`) and an interval overrun logs a WARN.
  The tick job is scheduled with explicit `coalesce=True`, `max_instances=1`,
  and `misfire_grace_time=<interval>` (derived, not hardcoded; 30 s for a cron
  trigger) — APScheduler's 1 s default grace silently skips a late tick, the
  presumed source of the shortfall.
- supervisor.py: `step` times the unit's evaluation onto `last_step_duration_ms`
  (survives stop, like the cached accounting report); surfaced on StrategyStatus.
- api/app.py: additive-only serialization — `/api/health` gains
  `last_tick_duration_ms`, `last_tick_ts`, `ticks_total`, `ticks_overrun`
  (null/0 with no scheduler hook); `/api/strategies` rows gain
  `last_step_duration_ms`. No existing field changed name, type, or semantics.

Real-data scratch run (10 ticks, 60 s): tick 1 = 46.4 s (dccd load + genesis
rebalance), steady-state ticks ~1.9-2.0 s, zero overruns, clean 60 s cadence —
refuting the tick-exceeds-60 s hypothesis and pointing the production shortfall
at misfire-grace skips, which the explicit grace now prevents.
feat: tick timing — durations, pinned scheduler semantics, health metrics
@ArthurBernard
ArthurBernard merged commit 24bc4da into master Jul 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant