Skip to content

Releases: enarjord/passivbot

v7.8.4

06 Mar 16:28

Choose a tag to compare

Changed

  • Dual balance routing (raw vs hysteresis-snapped) - Live and orchestrator flows now carry both balance_raw (raw wallet balance) and balance (hysteresis-snapped balance). Sizing/order-shaping paths use snapped balance, while risk/accounting paths use raw balance (including realized-loss gate peak/floor checks, TWEL entry/auto-reduce gating, and auto-unstuck allowance calculations). This applies consistently across live and backtest via Rust orchestrator input.
  • WEL denominator behavior split by mode - Live now uses a hard fixed denominator for per-symbol WEL (total_wallet_exposure_limit / config.bot.{pside}.n_positions), removing runtime denominator drift from open-position count. Backtests now expose backtest.dynamic_wel_by_tradability (default true): when enabled, WEL uses tradability-aware denominator growth (min(n_positions, n_tradable_max)) based on coins with real candles, and does not shrink after delistings; when disabled, backtests use the same fixed denominator as live.
  • Bulk price fetch for Hyperliquid - calc_ideal_orders now uses a single allMids API call to get prices for all symbols instead of individual get_current_close calls per symbol (1 call vs ~70). Falls back to per-symbol fetches for non-Hyperliquid exchanges or on error.
  • Sequential margin mode setting for Hyperliquid - Margin mode and leverage API calls are now sequential with a small delay instead of being fired in parallel, reducing API burst on coin changes.

Fixed

  • Bybit fill-event qty inflation on duplicate pages - BybitFetcher now deduplicates fetch_my_trades rows by exec id before canonicalization/coalescing, preventing duplicate pagination rows from inflating canonical qty, fees, and close PnL.
  • Balance peak drift in wrong direction under hysteresis - Peak reconstruction (balance + (pnl_cumsum_max - pnl_cumsum_last)) previously used hysteresis-snapped balance in some paths. Since snapped balance can stay stale while pnl_cumsum_last changes fill-by-fill, this made reconstructed peak drift down after profits and up after losses. Peak/PnL-accuracy-sensitive paths now use raw balance (balance_raw) consistently.
  • Pytest Rust-module bootstrap fallback - Test bootstrap now tries the project venv passivbot_rust package before falling back to the lightweight stub when tests are launched outside the venv, reducing false failures from missing/incorrect Rust module resolution.
  • max_ohlcv_fetches_per_minute ignored when forager slots open - The rate limit config was only applied when all position slots were full. With open slots (the common case), all candidate symbols were fetched without rate limiting, causing 429 errors on Hyperliquid.
  • Hyperliquid positions+balance double fetch - fetch_positions and fetch_balance now share a single API call via a dedup lock instead of making two identical clearinghouseState requests per execution cycle.
  • Thundering herd on minute boundary - get_candles no longer force-refreshes all symbols simultaneously when a new minute boundary crosses. A 1-candle staleness tolerance prevents the TTL override that caused all symbols to fetch at once.
  • Candle refresh TTLs aligned to 1-minute finalization - Active candle refresh TTL raised from 10s to 60s and EMA close TTL from 30s to 60s, matching the actual 1-minute candle finalization interval.
  • Boot stagger for multi-bot setups - Added boot_stagger_seconds config (default 30s for Hyperliquid) to randomize startup delay, preventing simultaneous API bursts when multiple bots share the same IP.
  • Warmup and refresh fetch pacing - Added configurable warmup_fetch_delay_ms (default 200ms for Hyperliquid) with delays between individual symbol fetches during warmup, forager refresh, and active candle refresh loops.
  • Exponential backoff on 429 errors - WebSocket watch_orders uses exponential backoff (up to 30s) on rate limit errors. Execution loop backs off 5s on RateLimitExceeded. Hourly init_markets catches rate limits with 10s recovery.
  • Fill events pagination abort on repeated rate limits - HyperliquidFetcher now aborts after 5 consecutive rate limit retries with exponential backoff instead of retrying indefinitely.
  • EMA bundle and active candle sweep abort on rate limit - Both _load_orchestrator_ema_bundle and update_ohlcvs_1m_for_actives skip remaining symbols when the CandlestickManager's global rate limit backoff is active.
  • Live close-EMA failure handling in orchestrator feed - _load_orchestrator_ema_bundle() no longer silently drops failed/non-finite close EMA spans. It now fails loudly when no prior EMA exists, and otherwise reuses the last successfully computed close EMA for that exact symbol/span with explicit [ema] warning logs (including reason, age, and consecutive fallback count).
  • Required 1h log-range EMA handling in orchestrator feed - _load_orchestrator_ema_bundle() now fails loudly when required h1 log-range spans (from entry_volatility_ema_span_hours) are missing or non-finite, instead of deferring to downstream Rust MissingEma errors.
  • EMA bundle fetch stability under lock contention - Orchestrator EMA bundle loading now fetches per-symbol spans serially and drains all symbol task outcomes before re-raising, reducing same-symbol candle-lock contention and eliminating unretrieved sibling-task exception noise.

Added

  • Fill events doctor tool - Added src/tools/fill_events_doctor.py to audit cached fill events and auto-repair known Bybit duplicate-fill anomalies without requiring exchange API calls. Bybit startup now runs doctor by default (can be disabled with PASSIVBOT_FILL_EVENTS_DOCTOR=off).

Full changelog: v7.8.3...v7.8.4

v7.8.3

24 Feb 15:30

Choose a tag to compare

Added

  • Added live.max_realized_loss_pct (default 0.05) to block close orders that would realize losses beyond a peak-balance-relative threshold. This applies to normal closes, WEL/TWEL auto-reduce, and unstuck closes; panic closes remain exempt.

Fixed

  • Fixed false-positive stale Rust-extension detection after identical rebuilds.
  • Fixed suite base scenario coin fallback to use base approved coins.
  • Fixed aggregate-method handling in optimizer scoring and Pareto analysis so configured aggregate modes are respected without double-correcting objectives.

v7.8.2: Candle Interval, Exposure Metrics, and Plotting Fixes

09 Feb 21:23

Choose a tag to compare

Highlights

  • Added configurable backtest candle aggregation via backtest.candle_interval_minutes (default 1).
  • Added high-exposure duration metrics for long/short (high_exposure_hours_{mean,max}_{long,short}).
  • Added total_wallet_exposure.png output for backtests.

Fixed

  • Corrected total wallet exposure metrics for short-only configs by using absolute exposure magnitude.
  • Fixed timestamp day bucketing in analysis to avoid phantom first-day samples with aggregated intervals.
  • Fixed forager fills_plots alignment when using candle intervals > 1m by plotting against the effective backtest candle stream.
  • Fixed candle-interval test robustness and aggregation alignment behavior across suite/optimizer paths.

Changed

  • Updated configs/template.json defaults/bounds/scenarios (including btc_collateral_cap, maker_fee_override, and optimize limits).

Notes

  • Candle aggregation improves backtest/optimizer speed but loses intra-interval fill ordering granularity.
  • No user migration steps required.

Full Changelog: v7.8.1...v7.8.2

v7.7.0: FillEventsManager production + logging improvements

26 Jan 15:12

Choose a tag to compare

Highlights

FillEventsManager Production Transition

  • PnL tracking now uses FillEventsManager exclusively - Legacy update_pnls path removed
  • Fill events include psize/pprice - Each fill annotated with position size and VWAP entry price
  • Support for all exchanges: Binance, Bybit, Bitget, GateIO, Hyperliquid, KuCoin, OKX

Comprehensive Logging Improvements (7 rounds of refinement)

Tag Standardization:

  • [memory], [warmup], [hourly], [fills], [mapping], [candle], [ranking], [mode]

Level Adjustments:

  • Routine API/cache messages: INFO → DEBUG
  • CCXT API payloads: DEBUG → TRACE
  • Strict mode gaps: WARNING → DEBUG
  • Persistent gaps: WARNING → INFO

Throttling:

  • EMA ranking logs: every 5 minutes
  • Mode changes: 2 minutes per symbol
  • KucoinFetcher PnL discrepancy: 1 hour with delta-based deduplication

New Features:

  • WebSocket reconnection logs explicit [ws] reconnecting... messages
  • Health summary includes realized PnL when fills > 0

Bug Fixes

  • Bybit: Fixed missing PnL on some close fills - Pagination bug in _fetch_positions_history() caused records to be skipped when >100 existed

Documentation

  • New docs/ai/log_analysis_prompt.md - comprehensive logging guidelines
  • New docs/ai/exchange_api_quirks.md - exchange-specific limitations
  • New docs/ai/debugging_case_studies.md - debugging reference

Removed

  • --shadow-mode CLI flag
  • live.pnls_manager_shadow_mode config option
  • Legacy pnls methods

Migration Notes

  • No action required - FillEventsManager automatically fetches and caches fill data
  • Old {user}_pnls.json cache files can be safely deleted after upgrading

Full Changelog: v7.6.2...v7.7.0

v7.6.2: Logging Improvements & Bug Fixes

20 Jan 18:56

Choose a tag to compare

This release focuses on improving log verbosity, fixing critical candle data issues, and enhancing the overall user experience with better diagnostics.

🔧 Critical Bug Fixes

  • Zero-candle warmup fix: Large warmup spans (>2 days) now properly trigger gap-filling via CCXT even when end_ts touches present. Previously, bots would synthesize thousands of zero-candles for historical gaps instead of fetching real data. First warmup may take longer (one-time backfill), subsequent restarts are fast (~6s vs ~156s).

  • One-way mode entry fix: Disabled sides no longer block entries when using one-way mode. The bot now correctly respects side configuration when choosing initial entry direction.

  • Bybit leverage errors: "Leverage not modified" (110043) and "margin mode not modified" (110026) errors are now handled gracefully instead of logging full tracebacks.

📊 Logging Improvements

  • Structured log prefixes: All log messages now use bracketed category tags for easy filtering:

    • [config] - Configuration changes
    • [fills] - Fill events and PnL
    • [candle] - Candle synthesis/replacement
    • [bybit], [binance], etc. - Exchange-specific logs
  • Health summary enhancements: Now includes realized PnL sum when fills > 0 (e.g., fills=3 (pnl=+12.50))

  • Reduced log spam:

    • Zero-candle logs rate-limited to once per minute per symbol
    • BybitFetcher residual PnL warnings moved to debug level
    • FillEventsManager refresh logs consolidated to single summary line
  • Better timestamps: Zero-candle warnings now include human-readable UTC timestamps showing the exact range synthesized

⚙️ New Configuration Options

  • live.enable_archive_candle_fetch (default: false): Opt-in to use exchange archive data for candle fetching. Disabled by default to avoid timeout issues. Backtester always uses archives regardless of this setting.

  • live.warmup_jitter_seconds (default: 30): Random delay before warmup to prevent API rate limit storms when multiple bots start simultaneously.

  • live.max_concurrent_api_requests (default: null): Optional global concurrency limit for CCXT API calls.

  • backtest.maker_fee_override (default: null): Override maker fees in backtest/optimizer (useful for testing different fee tiers).

🖥️ UI Improvements

  • TWEL clarification: Startup banner now shows "TWEL" (Total Wallet Exposure Limit) instead of "Exposure" to clarify it's a limit, not current exposure. Long+short mode shows both limits (e.g., TWEL: L:125% S:85%).

  • Dynamic banner width: Startup banner now calculates width dynamically to prevent misaligned borders.

🐛 Other Fixes

  • Windows cache compatibility: folder names now replace : with _ on Windows or when WINDOWS_COMPATIBILITY=1 env var is set (#547, thanks @FelixJongleur42)

  • Pareto dashboard: Fixed JavaScript callback errors when switching between tabs (#550, thanks @646826)

📦 Dependencies

  • Added openpyxl to requirements-live.txt (required for Bitget archive XLSX parsing)

⚠️ Upgrade Notes

  1. First startup may be slower: The zero-candle fix causes a one-time backfill of historical data. Subsequent restarts will be fast.

  2. Windows users: Existing caches will be orphaned and re-downloaded due to the folder naming change.

  3. Archive fetching disabled by default: If you relied on archive data for live bots, set live.enable_archive_candle_fetch: true in your config.

📈 Statistics

  • 66 commits since v7.6.1
  • 62 files changed
  • +9,196 / -2,529 lines

Full changelog: https://github.com/enarjord/passivbot/blob/master/changelog.md

v7.6.0

03 Jan 17:58

Choose a tag to compare

See changelog.md for details.

Passivbot v7.5.7

27 Nov 18:38

Choose a tag to compare

Passivbot v7.5.7 Release Notes

Highlights

  • CCXT upgrade to 4.5.22 for better exchange compatibility, along with KuCoin hedge-mode enforcement and order payload fixes.
  • Canonical suite metrics & Pareto revamp ensuring optimizer/backtester share identical outputs, with centralized Pareto logic.
  • Cleaner balance/position orchestration: bots fetch balance and positions concurrently, logging once both are fresh.

Detailed Changes

Exchange & Bot Behavior

  • Upgraded CCXT to v4.5.22 and added regression tests to detect future CCXT-breaking changes.
  • KuCoin bot now enforces hedge mode (when supported), handles exchange refusal gracefully, and sends correct marginMode/positionSide order params.
  • All exchange wrappers now keep fetch_positions() and fetch_balance() separate; callers can refresh each independently.
  • update_positions_and_balance() gathers balance/positions concurrently, logs position deltas after both complete, and emits a single balance-change event so equity logging always uses fresh positions/uPnL.

Optimization & Backtesting

  • Added pareto_core.py consolidating Pareto dominance/crowding logic with extreme-preserving pruning.
  • Suite runner and optimizer now emit the same canonical suite metrics payload (aggregate stats + per-scenario means).
  • ParetoStore delegates to the shared helper so dominance/clustering rules are consistent across CLI tools.

Configuration & Overrides

  • Added forward/backward TP grid overrides (PR #532) plus template/normalize fixes when loading live or suite configs.
  • Improved parse_overrides behavior and logging for suite enablement.

Documentation

  • Expanded docs covering minimum effective cost calculations, trailing grid ratios, and the new changelog policy.
  • Documented KuCoin hedge-mode setup so users know what to expect after the CCXT upgrade.

Testing & Tooling

  • New KuCoin exchange-config regression tests (hedge/margin/leverage) plus refreshed passivbot balance tests.
  • Updated test stubs so passivbot_rust/CCXT mocks reflect the new fetch/log separation.

What's Changed

Full Changelog: v7.5.4...v7.5.7

Passivbot v7.5.4 – Collateral-Agnostic Metrics, Smarter Overrides, and Split Balance/Position Fetch

26 Nov 15:25

Choose a tag to compare

Highlights

  • Added collateral-agnostic performance metrics (adg_pnl, mdg_pnl, PnL-based Sharpe/Sortino, with weighted variants) and documented them.
  • Improved coin overrides UX and safety with new docs, tests, and debug logging.
  • Refactored position/balance handling to separate updates and optimize Hyperliquid’s combined fetch.
  • Robustified data-sync, fill-events cache layout, and Kucoin open-order pagination.
  • Expanded optimizer limit handling with a new limit_utils module and tighter limit/scoring integration.

Metrics & Analysis

  • New metrics: adg_pnl, mdg_pnl (mean/median daily PnL over end-of-day balance), and PnL-based sharpe_ratio_pnl/sortino_ratio_pnl, plus weighted versions.
  • Added docs/metrics.md entries clarifying equity vs PnL Sharpe/Sortino semantics.
  • Types/analysis wiring updated across Rust and Python consumers; optimization weights and config canonicalization recognize the new metrics.
  • Added optimizer-side limit utilities (limit_utils) and integration tests to enforce limit normalization/penalties consistently.

Coin Overrides

  • Documented full override behavior (docs/coin_overrides.md) with inline/file-based examples, allowed fields, path resolution, and pitfalls.
  • Added debug logs when overrides are initialized and when override values are used.
  • Expanded tests to cover path resolution, missing override files, and retention through config formatting.

Exchange & Sync Fixes

  • Kucoin: fetch_open_orders now paginates (no more 50-order cap).
  • Hyperliquid: fill_events_manager now supports the exchange; fetch positions/balance combined once per cycle.
  • General: position/balance fetching split for all exchanges (dedicated fetch_balance/fetch_positions), with balance caching to avoid double-hits on combined endpoints.
  • sync_tar.py: pulling a single file no longer nests an extra directory.
  • Optimizer: new limit handling pipeline (limit_utils), enhanced scoring/limits parsing, and additional tests for optimizer limits.

Fill Events

  • Cache root now caches/{exchange}/{user} (was caches/{exchange}_{user}).
  • Hyperliquid fetcher path registered; CLI no longer rejects hyperliquid users.

Core Refactors & Safeguards

  • update_positions and new update_balance separated; main loops call both.
  • Balance caching reuse and rate-limit/network guards added.
  • Tests added for balance split and Hyperliquid combined fetch reuse.
  • Added optimizer limit integration tests and helper coverage for limit utilities.

Docs

  • Added coin override guide and metrics reference updates.

QA/Tests

  • New tests: override path handling, balance split behavior, Hyperliquid fetch reuse, Hyperliquid fetcher wiring.
  • Optimizer limit integration and limit_utils tests added.
  • Existing suite continues to pass on targeted runs (spot-checked new tests).

Full Changelog: v7.5.0...v7.5.4

Passivbot v7.5.0 (TWEL Enforcer)

23 Nov 15:12
a4a5054

Choose a tag to compare

Passivbot v7.5.0 (TWEL Enforcer)

Highlights

  • Risk controls & TWEL enforcer

    • Added risk_we_excess_allowance_pct, risk_wel_enforcer_threshold, and companion Rust helpers that auto-reduce positions when wallet exposure drifts beyond the buffer.
    • Implemented TWEL (Total Wallet Exposure Limit) gating in Rust with Python wiring, per-position prioritisation, and optimizer bounds/CLI flags.
    • Refined unstuck logic so both live bot and backtester use the same Rust helpers; unstuck can now be disabled by setting a negative threshold.
  • Optimizer overhaul

    • Shared-memory HLCV bundles and per-scenario slicing remove per-worker copies, cutting RAM growth as CPU count increases.
    • Streaming evaluator outputs: each candidate logs Pareto updates immediately, duplicate detection got stricter, and starting-config logging/immediate termination handling improved.
    • Suite support landed: optimisations can now evaluate multiple scenarios per candidate (with config cleaners, override helpers, and scenario metrics aggregation).
    • Added Pareto dashboard (WIP) and metrics-only mode; template configs updated with new suites and defaults.
  • Logging & monitoring

    • Order-plan logging is now quiet when unchanged, but includes delta/context details when cancels/creates actually happen; tolerance gating prevents churn.
    • Candlestick manager detects sparse exchange feeds once per (exchange,symbol,tf) and still standardises gaps with synthetic zero-candles.
    • Balance snapshot/logging knobs moved to config.logging; log-once helper ensures repeated warnings appear only once per symbol.
  • Config & CLI improvements

    • Template config refreshed with new risk knobs, trailing weights, and optimizer bounds; config_utils tracks transforms and exposes _raw data.
    • CLI overrides for optimise bounds now only freeze the key you actually pass (e.g. -lnp 4 pins long positions to 4, leaving other bounds untouched).
    • Added knobs such as recv_window_ms, balance_sample_divider, logging.volume_refresh_info_threshold_seconds, and updated docs.
  • Backtest & analysis

    • Introduced HlcvsBundle and payload subset helpers; backtest payloads now carry coin metadata in Rust and Python tests cover slicing/validation.
    • New scoring metrics (entry_initial_balance_pct_long, drawdown limits, volatility-weighted trailing entries) and renamed config fields to match.
    • Added scripts/tools (shared_arrays.py, JSON streamliner, new Pareto utilities) plus doc updates (passivbot_agent_principles.yaml, CONTRIBUTING).
  • Fill events manager (WIP)

    • New src/fill_events_manager.py adds modular fetchers (Bitget, Bybit, Binance) with caching and enrichment plus a CLI runner and tests. Live bot still uses legacy fetch_pnls; the manager will coexist while it matures.

Thanks to everyone who tested TWEL enforcer, optimiser RAM fixes, and the expanding docs/tooling ecosystem.

What's Changed

Full Changelog: v7.4.4...v7.5.0

Last release before v7.5

23 Nov 14:50

Choose a tag to compare

Last release before v7.5

What's Changed

  • add metrics total_wallet_exposure_max, mean, median by @backstab in #528

New Contributors

Full Changelog: v7.4.1...v7.4.4