/docs/guard
ERS Guard
Add an entry-risk check to your bot in 3 lines. Works with a free 7-day trial key.
What it is, and what it is not
ERS Guard is a small open-source client (MIT) that asks the Entry Risk Score API one question before your bot opens a position: how risky is it to enter this symbol and side now, compared with that coin's own history? It returns a level your own rules can use.
It is not a strategy and not advice: it computes nothing, leaves your bot's logic unchanged and never decides for you. Python 3.9+ without dependencies, a single-file JavaScript client and a local sidecar for any language. Source: github.com/entryriskscore/ers-guard · release v0.1.1. Tested on Linux, Windows and macOS with Python 3.9–3.13.
Install
pip install git+https://github.com/entryriskscore/ers-guard export ERS_API_KEY=ers_your_key # dashboard → API & MCP; a free 7-day trial key works (10 coins)
Quickstart (3 lines)
from ers_guard import Guard
guard = Guard()
print(guard.check("ETHUSDT", "LONG", hold="60m"))r = guard.check("ETHUSDT", "LONG", hold="60m") # hold: 60m | 8h | 24h
r.level, r.score, r.as_of, r.reason
if guard.allow_entry("ETHUSDT", "LONG", block={"HIGH"}): # your policy
place_order(...)| level | Meaning |
|---|---|
| HIGH | Risk Score 80/100 or above |
| ELEVATED | 60–79 |
| NORMAL | below 60 (not HIGH does not mean low risk) |
| UNKNOWN | no current answer: data older than 12 min, API unreachable, key problem |
| NOT_COVERED | not in your key's plan, or not a USDT-M perpetual |
Policies
allow_entry(symbol, side, hold="60m", block={"HIGH"}) blocks any set of levels. Guard(on_unknown="allow") (default) or "block" decides what UNKNOWN and NOT_COVERED mean for your bot. Guard never presents stale data as current.
Quota behaviour
One GET /api/v1/state per 5-minute update cycle, cached until meta.next_update_at; never more than one request per 60 seconds, whatever your code does; Retry-After respected. A trial key needs at most 288 requests a day (quota 500).
Command line
ers-guard check ETHUSDT LONG --hold 8h --json ers-guard check ETHUSDT LONG --fail-on HIGH && ./my_entry.sh # exit 0 ok, 2 matched, 3 UNKNOWN/NOT_COVERED ers-guard status
Sidecar for any language
ers-guard serve --port 8787 --file ers_state.json curl "http://127.0.0.1:8787/check?symbol=ETHUSDT&side=LONG&hold=60m"
Listens on 127.0.0.1 only; /check, /state, /health. On Windows, read the state file and close it at once, or use the HTTP endpoint.
Integrations
Freqtrade
from ers_guard_mixin import ErsGuardMixin
class MyStrategy(ErsGuardMixin, IStrategy):
ers_block = {"HIGH"} # checked in confirm_trade_entry; exits are never blocked
ers_hold = "60m"Hummingbot
from ers_guard import Guard
GUARD = Guard()
if GUARD.allow_entry("ETH-USDT", "LONG", block=("HIGH",)):
... # your orderccxt
from guarded import guarded_create_order, EntryBlocked order = guarded_create_order(exchange, "ETH/USDT:USDT", "limit", "buy", 0.1, 2500) # reduceOnly orders pass through
JavaScript (Node 18+)
const { ErsGuard } = require('./js/ers-guard.js');
const guard = new ErsGuard(); // ERS_API_KEY from the environment
if (await guard.allowEntry('ETH/USDT:USDT', 'LONG', { block: ['HIGH'] })) { /* your order */ }Go and C# snippets that read the sidecar are in the repository's examples/ folder.