An alert fires at 14:32:07. An HTTPS request carrying a small block of JSON lands on your server in the same second. Your code reads the symbol, the side and the size, calls the broker API, and a fill comes back at 14:32:09. That is the appeal of webhook automation: the setup gets taken while you are on a call or asleep, at the size you decided in advance rather than the size your nerves suggest at the moment of entry.
The same pipeline keeps running when things go wrong, faster than you can intervene. Almost every painful automation story traces back to one of five mechanisms below, and none of them are exotic.
What actually sits between the alert and the fill
People describe this as "the webhook", singular, as if it were one thing. It is at least four things, and each one can fail independently. There is the alert engine on the charting side, which evaluates your condition and decides to fire. There is the public internet hop, which delivers an HTTP POST to a URL you control. There is your relay: a small server that parses the message, decides whether to act, and translates it into an order. And there is the broker connection, which may be a REST API, a bridge into a trading platform, or a terminal listening on a local socket.
Each hop has its own timeout, its own retry behaviour and its own idea of what "delivered" means. When someone tells me their automation "missed a trade", the first question is which of the four hops logged the message and which did not. If you cannot answer that from your own logs within a minute, the system is not ready to hold real risk. How webhooks work in a charting platform is worth reading before you wire anything to a funded account.
Alerts fire on ticks, and indicators change their minds
This is the failure that catches new automators first. A condition like "close crosses above the 50 period average" is evaluated on the live bar, which means it can be true at 14:32 and false at 14:44 when the bar closes lower. The alert already fired. Your order is already open. The chart, when you look at it later, shows no crossover at all, so you conclude the system is broken. It is not: the signal existed for eleven minutes and then stopped existing.
Indicators that redraw their own historical output make this worse, because a backtest of the strategy will show entries that were never available in real time. If you build on moving averages or any smoothing that uses future bars in its calculation, check the behaviour on a replay before you trust the equity curve. Setting alerts to evaluate once per bar close removes most of the ambiguity at the cost of entering later.
Automation does not reduce risk. It removes hesitation, which cuts both ways: a bad rule executed perfectly a hundred times in a row is worse than the same bad rule executed sloppily by hand, because you will notice the sloppy version sooner.
Assume every message arrives twice, or not at all
HTTP delivery is at-least-once in practice. If your server takes four seconds to reply because the broker API was slow, the sender may decide the delivery failed and post the identical payload again. Your code, which has no memory, opens a second position. Now you are at double size on a setup you sized carefully.
The fix is boring and works. Give every alert payload a unique identifier that you generate in the alert message itself, including the symbol, the direction and the bar timestamp. Store the identifiers you have already acted on. Discard repeats. Reply with a success status the instant you have accepted the message, and do the broker call afterwards on a queue. A relay that answers in 40 milliseconds is rarely retried.
The opposite case matters too. Messages get dropped, providers have outages, and your server will occasionally be restarted by whoever runs the host. An automation that only knows how to open positions and relies on a later webhook to close them will eventually be holding something with no exit instruction coming. Attach a broker-side stop to every entry at the moment of entry, not in a follow-up message. Stop placement becomes an availability question, not only a strategy question.
Risk limits belong on the receiving side
The alert sender should not be trusted to size your trades. It has no idea what your equity is this morning, how many positions are already open, or whether you are 3% down on the day. Put those checks in your relay, where you can change them without touching a chart.
The list that earns its place in almost every setup I have seen work:
- A maximum number of open positions per symbol, usually one.
- A daily loss threshold that flips the relay into reject-everything mode until you clear it by hand.
- A maximum position size expressed as a percentage of current equity, computed at execution time rather than hard-coded in the alert.
- A trading window, so a stale alert queued during an outage cannot execute into the Monday open.
- A single kill switch, reachable from a phone, that stops new entries without touching open trades.
These are the same limits a firm applies at the platform level for exactly the same reason. The mechanics behind position level risk rules do not change because the order came from a script.
A webhook URL is a password
Anyone who obtains your endpoint address can post the same JSON your alerts post. If your relay does not verify anything beyond the shape of the message, that person can open trades in your account. Include a shared secret inside the payload, compare it in constant time, reject on mismatch, and rotate it whenever you paste an alert message into a screenshot, a support ticket or a community chat. Log every rejected request with its source address; a sudden burst of them is the only warning you will get.
Keep the relay narrow as well. It should accept one message shape and refuse everything else. A relay that will execute an arbitrary symbol at an arbitrary size because the payload said so is one typo in an alert template away from selling an index future you have never traded.
What to prove before real money touches it
Run the full chain on a demo account for at least a month, and treat the log rather than the profit as the deliverable. You want to see a duplicate delivery rejected, a restart that did not orphan a position, an alert that arrived while the market was closed, and a broker error that your code handled instead of swallowing. Traders who skip this step discover all four in the same week, with real size on. Demo and live behaviour differ enough that the exercise is about plumbing, not results.
Automating someone else's signals adds one question: what happens when the provider sends a correction, a cancellation, or nothing at all for three weeks. Assessing a signal service is a separate job from making the pipe reliable.
"The webhook is never the risky part. The risky part is that nobody is watching the account at three in the morning while it does exactly what you told it to do."
— Alex Onta, Executive Director, SINGUARD
Key Takeaways
- An alert chain is four independent systems, and your logs must show which one dropped a message.
- Alerts evaluated on the live bar can fire on conditions that vanish before the bar closes.
- Deduplicate by a unique payload identifier and answer the sender fast, or expect double positions.
- Size limits, daily loss caps and the kill switch belong in your relay, never in the alert text.
Frequently Asked Questions
Is webhook automation safer than an expert advisor?
It is different, not safer. An expert advisor runs inside the terminal and keeps working if your home internet drops, because the terminal sits on a VPS near the broker. A webhook chain depends on a chart provider, a relay server and a broker API all being reachable in the same second. Webhooks give you signal logic that is easier to write and read; expert advisors give you fewer moving parts between the decision and the order.
Why did my webhook fire twice on the same signal?
Most alert senders retry when they do not receive a fast success response. If your server processed the first request but answered slowly, or answered with an error after already placing the order, the sender treats it as failed and posts again. The fix is on your side: give every alert a unique identifier, store the ones you have acted on, and ignore repeats. Reply with a success status immediately, then do the work.
Do I need a VPS to run webhook automation?
You need a machine that is always on and always reachable from the public internet, which in practice means a hosted server rather than a laptop. Latency matters less than uptime here: a few extra milliseconds of network distance rarely changes a fill, but a machine that sleeps, reboots for updates or loses its public address will quietly stop taking trades and stop managing the ones already open. See the VPS guide for what to look for.