Skip to content

Stale-alert guard#

TradingView can — and occasionally does — replay alerts. The most common causes:

  • A TradingView server hiccup retries an alert that already arrived.
  • A user re-runs a saved alert from the alert history.
  • An indicator misbehaves and re-fires the same alert in quick succession.
  • A long-queued alert is delivered minutes late after an outage.

The stale-alert guard is HookTrader's first line of defence.

How it works#

Some webhook payloads may include a ts (timestamp). When present, HookTrader compares it to the server clock:

if (now - ts) > STALE_ALERT_SECONDS:
    reject as stale

The freshness window defaults to 30 seconds. Rejected stale alerts:

  • Are logged to the strategy's webhook log with reason stale_alert.
  • Do not raise a user notification (they're considered noise).
  • Do not affect any open trade.

Why timestamps?#

A 30-second freshness window strikes a balance:

  • Long enough to tolerate normal network latency and processing delays.
  • Short enough that a replay 5 minutes later (the most common failure mode) is always rejected.
  • Cheap to verify — no per-alert state needed, just the payload's own ts.

What it doesn't guard against#

The stale guard catches replays, but not legitimately-fast duplicates. For those:

  • Per-token rate limiting caps how many alerts per second a single webhook can fire. The bucket is configured server-side and surfaces as 429 Too Many Requests.
  • HookTrader enforces invariants like "one active trade per webhook" and "one symbol across all of a user's strategies" — duplicate entry alerts while a trade is already open are silently ignored.

So:

Scenario Caught by
Same alert replayed 5 min later Stale-alert guard
Same alert fired 10× in 100ms Rate limit
Entry alert when trade already open HookTrader (silent ignore)
Wrong-symbol alert on a pair-locked strategy HookTrader (rejected)

Tuning#

The freshness window is a global setting; it isn't user-configurable today. If you're running an exotic setup where alerts legitimately arrive minutes late (e.g. an indicator that batches signals), open a feature request rather than disabling the guard.