Technical pre-order checks that prevent duplicate positions, wrong size, stale signals and accidental live execution.
In plain English
This guide is about preventing a technically functioning bot from taking an unintended action. Checks should run immediately before the important action, not only at startup.
Validation is not the same as a profitable strategy
Risk checks protect the system from operational mistakes. They cannot make a losing strategy profitable, but they can stop some avoidable failures.
Pre-order gate
def can_submit(event, state, cfg):
if cfg.environment != "demo" and not cfg.live_enabled:
return False, "live_disabled"
if event.age_seconds > cfg.max_signal_age:
return False, "stale_signal"
if state.has_open_position(event.symbol):
return False, "position_exists"
if event.size > cfg.max_size:
return False, "size_limit"
if state.seen(event.event_id):
return False, "duplicate_event"
return True, "ok"
Check position state immediately before submission
Do not rely only on a position snapshot from several seconds ago. Another process, manual trade or previous delayed order may have changed the account.
Stale-signal protection
A webhook arriving late should not automatically become a current trade. Include a signal timestamp and define the maximum acceptable age.
Before you rely on this in production
- Demo/paper behavior is proven first.
- Size and current position are checked immediately before action.
- A kill switch blocks new actions.
- Uncertain timeouts do not cause blind duplicates.
