Alert outcomes
What happened to each alert on each account, every reason an alert is refused, and how to fix it.
Every alert a hook accepts is recorded, refusals included, and kept in the dashboard's alert log for 30 days after it ends. One that ended while Pipsocket still has work for it (an exit still watching for late fills: see late_fill_closed under flags; or making sure nothing of a part-filled market order is left at the broker) is kept until that work is over, and 30 days more. Its detail says it is still watched. An alert goes to each account the hook targets; on each one it is a delivery, with its own outcome. The alert's state is the worst of its deliveries'.
An alert's detail shows, for each account, every step Pipsocket took (cancel, close, open, set stops) with its timing, how the size and levels were worked out, each MT5 request with MT5's answer, a suggested fix for a refusal, and the message as it arrived.
States
| State | Meaning |
|---|---|
queued | Waiting its turn for the account. Each account takes a hook's alerts strictly in the order they arrived. |
submitting | Being handed to the account's host. |
accepted | The host has it, with its plan of steps, stored before anything is sent. |
running | Its steps are being sent to MT5. |
done | Every step was answered as planned. |
partial | A step was refused or only partly filled. Steps that depend on it weren't sent (a ladder's later rungs, a reverse's open after its close); a close of several positions still went on to the others. The detail shows what actually happened, with volumes. |
refused | Not traded, for the reason shown (below). Nothing was sent to MT5, or MT5 rejected it (broker_rejected). |
unknown | A step got no answer from MT5 in time. See unknown outcomes. |
cancelled | Stopped before it reached the account, by a pause or a change to the hook. |
undelivered | Pipsocket couldn't reach the account's host within 15 minutes, and nothing reached it. You can resend it. |
submit_unknown | The host couldn't be reached for sure within 15 minutes, and an attempt may have arrived. Pipsocket never sends it again: it asks the host until it answers, and the alert then shows what really happened, or undelivered if the host never got it. |
MT5's answers are read, not passed through: a full fill is done, a partial fill is partial with the volumes, a rejection is refused broker_rejected with MT5's retcode and comment, and no answer is unknown.
Unknown outcomes
A step is unknown when MT5 didn't answer in time: the order may or may not have reached the broker. Pipsocket never sends it again, and never decides by time passing. It checks the account every 5 minutes against its positions, orders and history, and the terminal's own record of what it passed to MT5, and settles the step when it finds proof either way.
Until then, the unknown trade keeps the symbol busy: later trades that would conflict with it wait (alerts end account_busy after their limit; API calls answer 409 symbol_busy). The kill switch never waits for it.
If you've checked at your broker, an owner or admin can settle it by hand in the dashboard, as executed or not executed, with a reason. That is recorded with who did it, and the step is flagged settled_by_operator.
A trailing stop or break-even move can be unknown too. Its position's stop loss then moves no more, and later trades that would conflict with it wait, until the move settles, by the same checks or by hand. The account's page lists every such move, even once its position has closed, for an owner or admin to settle; the move's trace entry records who settled it and why. One from the account's earlier login or server is listed apart: it holds nothing up now, and is settled from that login's history at the broker.
Resend
From an alert's detail, owners and admins can resend it to accounts they choose. The resend is a new alert with the hook's current settings, the time now as sent_at, and :resend:1 (then :2 and so on) added to its event_id. Accounts where the alert ended refused, cancelled or undelivered (which never traded it) are chosen for you. Accounts where it ended done can be chosen too: that repeats the alert there on purpose (another entry, say, if pyramiding allows it). Accounts where it ended partial can't be resent at all: part of it traded. Accounts where it is submit_unknown or unknown, or where it ended but is still watched, can't be resent until that is settled. So nothing is sent twice by accident.
Reasons
| Reason | What it means | How to fix it |
|---|---|---|
invalid_json | The message isn't a JSON object. | Check the message in TradingView. In an alert() message, check the quotes and commas Pine writes. |
invalid_field | A field has the wrong type or value, a required field is missing, or a number rule is broken. The detail names the field. | Fix that field. A placeholder TradingView didn't fill in (such as {{ticker}} in an alert() message) arrives as text. |
unknown_field | A field the format doesn't have. | Fix the typo, or remove the field. |
duplicate | The hook received the same event_id and message in the last 24 hours (or the same message, without an event_id, in the last 60 seconds). | Usually TradingView sending again: nothing to do. If they were different events, make their event_ids different (see ids). |
conflict | The same event_id as an earlier alert, with a different message. | Give each event its own event_id; a strategy filling more than once in a bar needs a value from Pine in it. |
paused | The hook was paused. | Resume the hook, and resend if you still want the trade. |
quota | Over the hook's limit of alerts (see limits). Counted per minute, not stored one by one. | Send fewer alerts: an alert firing on every tick usually wants Once per bar close. |
queue_full | 200 of the hook's alerts were already waiting for this account. | Check the account: its host has likely been out of reach. |
stale | An entry older than the hook's age limit (30 seconds by default, or max_age). | Check how late TradingView sent it. If your entries can wait longer, raise the age limit or send max_age. |
unknown_symbol | The symbol isn't in the account's symbol map, and the account has no symbol of that exact name. | Map it on the dashboard's Symbols page. |
symbol_not_allowed | The symbol isn't one the target allows. | Add it to the target's allowed symbols. |
action_not_allowed | The action isn't one the target allows (kill_switch is off by default). | Allow it on the target. |
outside_hours | Outside the target's trading hours. | Change the trading hours, or expect it. |
market_closed | The symbol can't be traded now (its trade mode or session), with MT5's reason. The alert isn't kept to run later. | Send it when the market is open. |
below_min_lot | The size, rounded down to the lot step, is below the symbol's minimum. | Raise the size, the risk or the multiplier. |
above_max_lots | The size is above the target's maximum lots. | Raise the maximum, or allow clipping to it. |
max_positions | The target's maximum positions is reached. | Close positions, or raise the maximum. |
invalid_level | A level is on the wrong side of the price (a buy's stop loss above its entry, say), or not a valid price. | Fix the level; relative distances are always put on the protective side for you. |
stop_too_close | A level or pending price is within the symbol's stops level of the price. | Move it further away. |
frozen | Within the symbol's freeze level: the broker allows no change that close to the trigger price. | Wait, or move it further away. |
expiry_not_allowed | The symbol doesn't allow that expiry for pending orders. | Use another expires (the symbol's specification lists what it allows). |
risk_unavailable | MT5 couldn't work out the loss at the stop for risk sizing, or it wasn't a loss. | Check the stop loss is on the losing side; or size with lots. |
no_margin | MT5's margin check says the account can't afford it. | Lower the size, or add funds. |
pyramiding | The lane already holds that side, and the target's pyramiding doesn't allow another entry. | Close first, or raise pyramiding (hedging accounts only). |
opposite_open | The lane holds the other side, and the target refuses opposite opens. | Send a reverse, or set the target's opposite side to close first or hedge. |
symbol_shared | A netting account's symbol has a position or order that isn't the lane's, or another lane holds it. | Close the other position, or trade the symbol from one lane only. |
lane_in_strategy_mode | An open, reverse or pending entry in a lane that strategy mode uses. | Use another tag for these alerts. |
kill_switch | The account's kill switch is engaged: nothing may open or add. | Lift it in the dashboard or with the API when you're ready. |
billing_hold | The account is close-only because the workspace's payment is overdue: nothing may open or add. | Pay from the dashboard's Billing page (see the billing hold). |
account_busy | An earlier trade on the symbol still had no outcome, and the alert waited as long as it may (an entry its age limit, an exit 15 minutes). | Look at the earlier trade: an unknown one may need settling. |
account_unavailable | The account couldn't take the alert: for example, its terminal isn't running or logged in. | Check the account's status in the dashboard. |
account_changed | The account's login or server changed after the alert was received. | Resend it if you still want it on the new login. |
ownership_lost | On a netting account, something outside the lane traded the lane's symbol, so automation on that symbol is suspended. | In the dashboard, release the lane's ownership or close the position. |
filling_unavailable | The symbol allows no filling mode a market order can use. | Ask your broker, or trade the symbol with a pending entry. |
broker_rejected | The broker rejected the request; the detail has MT5's retcode and comment. | See MT5 retcodes. |
drift | Strategy mode: the lane doesn't hold what the strategy's previous position says it should. | Turn on the target's heal drift, so increases and flips open up to the strategy's position. Too much held is closed down on the strategy's next reduction or exit, or by a close alert with a portion in the same lane. Don't open the missing volume by hand or with the API: the lane doesn't own those trades (on a netting account they suspend it, ownership_lost). |
nothing_to_do | There was nothing for the alert to act on, such as a close when the lane holds no position. | Usually nothing: check the lane if you expected a position. |
Flags
Flags mark something worth knowing on an alert that didn't fail:
| Flag | Meaning |
|---|---|
ambiguous_order | Whether an entry came before this exit was decided by the order Pipsocket received them, as neither source_seq nor sent_at told them apart (sent in the same second, or no times given). If TradingView delivered them out of order, the exit may have acted on the newer entry. Send source_seq if your strategy can fire twice in a second. |
partial_fill_remainder_cancelled | A market order filled only in part, and Pipsocket asked the broker to cancel the rest. The cancel's own outcome is in the detail: while the rest may still be live (the cancel refused or not answered yet), the alert stays watched, and the rest may fill. See filling. |
late_fill_closed | On a hedging account, a full exit didn't wait for the lane's earlier entries still without an answer. One of them filled later, and Pipsocket closed exactly that position (or cancelled that order), recorded on the exit. Your manual trades and newer entries are left alone. Until each of those entries has settled with nothing left open, the exit's alert is still watched, and it is kept for 30 days after that. |
settled_by_operator | An owner or admin settled an unknown step by hand. |
Email digests
With a hook's notifications on, Pipsocket emails a digest at most every 15 minutes, listing the hook's alerts that ended refused, partial, unknown or undelivered, and strategy drift.