Skip to content

Trailing deadlocked after restart on Bybit: position updatedTime is a few ms after last fill execTime (position_fill_confirmation_pending) #1323

Description

@rylos

Version: master 8b433cc2 (not present in v8.0.0)

Summary

On Bybit, after restarting a bot with an open position whose trailing state must be reconciled, the new restart reconciliation logic permanently reports:

WARNING [bybit] [trailing] trailing state unavailable reason=position_fill_confirmation_pending symbols=HYPE action=mark_nontradable_until_fresh

every ~3s, and the symbol stays nontradable — so no trailing close order is placed for the open position until a new fill happens, which may never come while the symbol is nontradable.

Cause

_position_update_timestamp_from_row() uses Bybit's info.updatedTime as the authoritative position update time. On restart (previous_position_state is None branch), freshness requires a cached fill anchor with timestamp >= position_ts.

However, Bybit always sets the position's updatedTime a few milliseconds after the fill's execTime. Observed on a live account:

  • last fill (trade) timestamp: 1784466966634 (2026-07-19T13:16:06.634Z)
  • position updatedTime: 1784466966638 (4 ms later)

So fill_is_current is always false right after a restart, the pending confirmation keys on pending_min_timestamps[key] = position_ts, and the escape condition (current_timestamp >= minimum_timestamp with an epoch different from baseline) can only be satisfied by a genuinely new fill. Result: deadlock on every restart with an open trailing position on Bybit.

Repro

  1. Run a bot on Bybit with an open position using a trailing strategy (observed with strategy_kind=trailing_grid_v7).
  2. Restart the bot.
  3. Trailing state stays position_fill_confirmation_pending indefinitely; symbol is marked nontradable.

Expected

Restart reconciliation should tolerate the exchange-side skew between fill execTime and position updatedTime (e.g. allow a small tolerance window, or treat a same-state fill anchor within a few hundred ms of updatedTime as current).

Workaround

Rolled back to v8.0.0 (logic absent there); trailing resumes immediately on the same account/position.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions