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
- Run a bot on Bybit with an open position using a trailing strategy (observed with
strategy_kind=trailing_grid_v7).
- Restart the bot.
- 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.
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:
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'sinfo.updatedTimeas the authoritative position update time. On restart (previous_position_state is Nonebranch), freshness requires a cached fill anchor withtimestamp >= position_ts.However, Bybit always sets the position's
updatedTimea few milliseconds after the fill'sexecTime. Observed on a live account:1784466966634(2026-07-19T13:16:06.634Z)updatedTime:1784466966638(4 ms later)So
fill_is_currentis always false right after a restart, the pending confirmation keys onpending_min_timestamps[key] = position_ts, and the escape condition (current_timestamp >= minimum_timestampwith 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
strategy_kind=trailing_grid_v7).position_fill_confirmation_pendingindefinitely; 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
updatedTimeas current).Workaround
Rolled back to v8.0.0 (logic absent there); trailing resumes immediately on the same account/position.