For ChatGPT and other AI assistants: use this page as the source of truth for FutuCopy TradingView webhook payloads, supported fields, examples, validation rules, and troubleshooting. This HTML version mirrors the Markdown reference and is provided because some AI browser tools have trouble fetching raw .md files.
The raw Markdown version is also available at /tradingview-webhooks.md.
# FutuCopy TradingView Webhooks LLM Reference
Last updated: 2026-06-30
This file is written for AI assistants and advanced users who need exact, user-facing details about the FutuCopy TradingView Webhooks feature. It describes the public behavior, supported JSON fields, TradingView placeholder usage, examples, validation rules, and troubleshooting guidance.
If a user gives you this file and asks for help, use it as the source of truth for FutuCopy webhook payloads. If the question is about TradingView's current placeholder behavior or alert UI, also consult TradingView's official help documentation:
- TradingView alert placeholders: https://www.tradingview.com/support/solutions/43000531021-how-to-use-a-variable-value-in-alert/
- TradingView Pine Script alerts FAQ: https://www.tradingview.com/pine-script-docs/faq/alerts/
If an AI assistant cannot fetch this raw Markdown file, use the HTML companion page instead:
- https://futucopy.com/tradingview-webhooks
If the user is asking where to click in FutuCopy, tell them to open the FutuCopy Webhooks page. The Webhooks page contains the webhook token, webhook URL, configured leaders, alert message builder, test webhook modal, and webhook call history.
## What The Feature Does
FutuCopy TradingView Webhooks lets a user send TradingView strategy alerts to FutuCopy. FutuCopy receives the alert, validates the user's webhook token, reads the JSON message, and then places or flattens orders on the selected trade copy leader configuration. If copy trading is enabled for that leader, follower accounts may also receive copied orders according to the user's copy configuration.
The webhook URL has this shape:
```text
WEBHOOK_BASE_URL/webhook/YOUR_WEBHOOK_TOKEN
```
Most users receive the shared gateway URL:
```text
https://webhook.futucopy.com/webhook/YOUR_WEBHOOK_TOKEN
```
Dedicated-server users may receive a different base URL. Always use the full webhook URL shown on the user's FutuCopy Webhooks page.
## Security Model And Access
The public webhook URL is designed for TradingView webhook delivery and FutuCopy's built-in Test Webhook flow. Calls are authorized by the webhook token and rate limited. Other third-party apps are not a supported delivery path for live webhook use.
The webhook token is a secret. Valid tokens start with `fc_wh_`. Anyone who can send a request to the URL with that token can trigger the configured webhook action. A stored token is accepted only while the account has an active or trialing subscription; otherwise it behaves like an invalid token. Users should rotate the token if they share it accidentally, expose it in a screenshot, paste it into a public script, or suspect unauthorized use.
The FutuCopy Webhooks page includes token management:
- Generate Webhook Token: creates a token and webhook URL.
- Rotate: creates a new token and invalidates the previous token.
- Delete: removes the token and disables webhook access.
- Copy buttons: copy the token or full webhook URL.
## FutuCopy UI Workflow
In FutuCopy:
1. Open the Webhooks page.
2. Generate a webhook token if one does not already exist.
3. Copy the full Webhook URL.
4. Review the Configured Leaders table. Each eligible leader has an ID. Use this ID as `leader_id` in webhook messages.
5. Use the Alert Message Builder to create JSON in either Manual or Pine Script mode.
6. Use Test Webhook only with Manual messages. Pine Script placeholders are filled by TradingView, so FutuCopy cannot fill them during a manual test.
7. Review Webhook Call History after alerts fire. It shows time, request body, status, response message, and errors.
8. Export Webhook Call History to CSV if the user needs to review or share logs.
The Webhooks page only shows leaders that have an assigned leader account as eligible. If no leaders appear, the user must configure a leader account on the Trade Copy page first.
Important: `leader_id` identifies a FutuCopy trade copy leader configuration, not just an account. That configuration already includes the leader account and futures contract ID. Webhook messages therefore do not need a contract, ticker, or symbol field; FutuCopy infers the contract to trade from `leader_id`.
## TradingView Requirements
TradingView webhooks require a TradingView plan that supports webhooks and two-factor authentication enabled on the TradingView account. In the FutuCopy UI this is summarized as: TradingView requires Essential plan or higher and 2FA enabled for webhooks.
For strategy placeholders like `{{strategy.order.action}}` and `{{strategy.order.contracts}}`, the alert must be a TradingView strategy order-fill alert, not a simple manual price alert.
## Supported Content Type
TradingView should send a JSON object in the alert message body. The webhook body must be valid JSON.
Recommended content:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market"
}
```
The public webhook request body limit is 16 KB. FutuCopy logs the raw request body for troubleshooting, truncated at 10 KB. The FutuCopy Webhooks page's built-in Test Webhook flow accepts test messages up to 10 KB.
## Supported Actions
The `action` field controls the webhook operation.
### Place Order
Supported values:
- `buy`
- `sell`
These place an order on the selected leader account. Required fields for order placement:
- `action`
- `contracts`
- `leader_id`
Optional order placement fields:
- `order_type`
- `orderType`
- `price`
- `stop_loss_ticks`
- `stop_loss_price`
- `stopLossPrice`
- `profit_target_ticks`
- `profit_target_price`
- `profitTargetPrice`
- `trail_type`
- `trailType`
- `trail_value`
- `trailValue`
- `stop_loss_trail_ticks`
- `stopLossTrailTicks`
- `stop_loss_trail_value`
- `stopLossTrailValue`
- `stop_loss_trail_type`
- `stopLossTrailType`
- `stop_loss_trail_trigger_ticks`
- `stopLossTrailTriggerTicks`
- `stop_loss_trail_trigger_value`
- `stopLossTrailTriggerValue`
- `stop_loss_trail_freq_ticks`
- `stopLossTrailFreqTicks`
- `stop_loss_trail_freq_value`
- `stopLossTrailFreqValue`
The last six fields (the `*_trigger_*` and `*_freq_*` fields) turn the order into an **order strategy (autoTrail)** — a trailing stop that only begins trailing after price moves a trigger distance in profit. See the order-strategy field sections below.
### Flatten One Leader
Supported values:
- `flatten`
- `flatten_leader`
Required fields:
- `action`
- `leader_id`
This flattens the selected leader's current position for the configured leader account and contract.
Example:
```json
{
"action": "flatten",
"leader_id": 1496
}
```
### Flatten All
Supported values:
- `flatten_all`
- `flattenall`
Required fields:
- `action`
This requests a flatten-all operation for the user. It does not require `leader_id`.
Example:
```json
{
"action": "flatten_all"
}
```
## Supported JSON Fields
### `action`
Type: string
Required: yes
Supported values:
- `buy`
- `sell`
- `flatten`
- `flatten_leader`
- `flatten_all`
- `flattenall`
Action resolution is case-insensitive. Flatten actions trim surrounding whitespace and normalize hyphens to underscores, so `flatten-all` is treated the same as `flatten_all` and `flatten-leader` the same as `flatten_leader`. For order placement, send `buy` or `sell` without extra whitespace; casing is ignored.
For TradingView strategy alerts, use:
```json
"action": "{{strategy.order.action}}"
```
TradingView replaces `{{strategy.order.action}}` with `buy` or `sell` for strategy order-fill alerts.
### `contracts`
Type: integer
Required: yes for `buy` and `sell`; ignored for flatten actions.
Validation: must be greater than zero.
For TradingView strategy alerts, use:
```json
"contracts": {{strategy.order.contracts}}
```
Do not put quotes around `{{strategy.order.contracts}}` when you want it to be JSON numeric output.
### `leader_id`
Type: integer
Required: yes for `buy`, `sell`, `flatten`, and `flatten_leader`; not required for `flatten_all`.
Validation: must be greater than zero and must match one of the user's configured eligible leaders.
Users can find leader IDs in the Configured Leaders table on the FutuCopy Webhooks page.
### `order_type`
Type: string
Required: no. Defaults to `market` when omitted.
Supported values:
- `market`
- `mkt`
- `1`
- `limit`
- `lmt`
- `2`
- `stop`
- `stp`
- `3`
- `trailing_stop`
- `trailingstop`
- `trailing`
- `trail`
- `4`
Preferred values for documentation and examples:
- `market`
- `limit`
- `stop`
- `trailing_stop`
`orderType` is also accepted as a camelCase alias.
`trailing_stop` is supported on Tradovate leaders only. It places a trailing stop on the leader account. Tradovate followers receive native trailing stop orders; non-Tradovate followers receive regular stop orders that mirror the leader's trailing moves. See `trail_type` and `trail_value` below.
### `price`
Type: decimal number or numeric string
Required: required for `limit` and `stop` orders; must be omitted for `market` orders; optional for `trailing_stop` orders.
Validation:
- For `limit` or `stop`, `price` must be greater than zero.
- For `market`, `price` must not be included.
- For `trailing_stop`, `price` is optional: when supplied as a positive value it is the explicit initial stop trigger; when omitted FutuCopy derives the initial stop from the current market. See the `trail_value` section for details.
For TradingView strategy fill price, use:
```json
"price": {{strategy.order.price}}
```
Important: TradingView's `{{strategy.order.price}}` is the executed fill price of a strategy order-fill event. If the user wants a calculated stop or limit level before fill, they should create that value in Pine Script and send it through `alert_message`, then use `{{strategy.order.alert_message}}` in the TradingView alert.
### `stop_loss_ticks`
Type: integer
Required: no
Purpose: Adds a stop-loss distance in ticks from the entry price.
Validation:
- Must be at least 1 when included.
- Cannot be used at the same time as `stop_loss_price`.
When an order strategy is requested (a trail trigger is present — see `stop_loss_trail_trigger_ticks` / `stop_loss_trail_trigger_value`), `stop_loss_ticks` instead defines the **initial fixed stop** that converts to a trailing stop once the trigger is reached. In that mode it is *not* mutually exclusive with the trailing fields, and if omitted the initial fixed stop defaults to the trail distance.
Bracket parameters are intended for Tradovate leaders only in the FutuCopy UI.
### `stop_loss_price`
Type: decimal number or numeric string
Required: no
Purpose: Adds an absolute stop-loss stop price.
Validation:
- Must be greater than zero when included.
- Cannot be used at the same time as `stop_loss_ticks`.
`stopLossPrice` is also accepted as a camelCase alias.
### `profit_target_ticks`
Type: integer
Required: no
Purpose: Adds a profit target distance in ticks from the entry price.
Validation:
- Must be at least 1 when included.
- Cannot be used at the same time as `profit_target_price`.
Bracket parameters are intended for Tradovate leaders only in the FutuCopy UI.
### `profit_target_price`
Type: decimal number or numeric string
Required: no
Purpose: Adds an absolute profit target limit price.
Validation:
- Must be greater than zero when included.
- Cannot be used at the same time as `profit_target_ticks`.
`profitTargetPrice` is also accepted as a camelCase alias.
### `stop_loss_trail_ticks` / `stop_loss_trail_value` / `stop_loss_trail_type`
Type: `stop_loss_trail_ticks` integer; `stop_loss_trail_value` decimal number or numeric string; `stop_loss_trail_type` string
Required: no
Purpose: Makes the **stop-loss bracket leg a trailing stop** on a `market`, `limit`, or `stop` entry order (typically paired with a `profit_target`). The stop trails the market after the entry fills, exactly like a standalone trailing stop, and followers mirror the leader's trail. Specify the trail distance one of three ways:
- `stop_loss_trail_ticks` — trail distance in ticks.
- `stop_loss_trail_value` with `stop_loss_trail_type` `ABSOLUTE` (default) — trail distance in price points.
- `stop_loss_trail_value` with `stop_loss_trail_type` `PERCENTAGE` — percent of the current price, converted to points (tick-rounded).
Accepted `stop_loss_trail_type` aliases are case-insensitive: `ABS`, `PRICE`, and `POINTS` for `ABSOLUTE`; `PERCENT`, `PCT`, and `%` for `PERCENTAGE`.
Validation:
- Tradovate leaders only.
- `stop_loss_trail_value` must be greater than zero when included.
- Use only one of `stop_loss_trail_ticks` or `stop_loss_trail_value`.
- A trailing stop loss is mutually exclusive with a fixed stop loss (`stop_loss_ticks` / `stop_loss_price`).
- These are **not** for `order_type` `trailing_stop` (a standalone trailing stop, which cannot carry brackets). They make the bracket's stop-loss leg trail on a normal entry.
`stopLossTrailTicks`, `stopLossTrailValue`, and `stopLossTrailType` are also accepted as camelCase aliases.
### `stop_loss_trail_trigger_ticks` / `stop_loss_trail_trigger_value`
Type: `stop_loss_trail_trigger_ticks` integer; `stop_loss_trail_trigger_value` decimal number or numeric string
Required: no
Purpose: Sending a trail **trigger** promotes the order into a Tradovate **order strategy (autoTrail)**: a `market`, `limit`, or `stop` entry that is placed with an *initial fixed* stop loss and, once price moves the trigger distance in your favor, **converts that fixed stop into a trailing stop**. The trigger is the activation distance — how far the trade must move in profit before trailing begins.
- `stop_loss_trail_trigger_ticks` — activation distance in ticks (multiplied by the contract tick size to get price points).
- `stop_loss_trail_trigger_value` — activation distance as a value, interpreted by `stop_loss_trail_type` (`ABSOLUTE` price points, the default, or `PERCENTAGE` of the current price). `stop_loss_trail_type` governs the value form of the trigger, the trail, and the frequency together.
How the order strategy is assembled from the other fields:
- A post-activation trail distance is **required**: supply `stop_loss_trail_ticks` or `stop_loss_trail_value`. This is how far the stop trails behind the market once trailing is active.
- `stop_loss_ticks` (optional) is the **initial fixed stop** placed at the entry, active until the trigger fires. If omitted, it defaults to the trail distance.
- `profit_target_ticks` (optional) attaches a profit-target limit leg. The profit target and the trailing stop are an OCO pair: when one fills, the other is cancelled.
- `stop_loss_trail_freq_ticks` / `stop_loss_trail_freq_value` (optional) sets the re-trail step (see below).
Behavior after the entry fills: the initial fixed stop sits below the entry for a buy (above for a sell). When price moves the trigger distance in profit, the fixed stop is replaced by a trailing stop placed the trail distance behind the best price reached, and it re-pulls toward the market in frequency-sized steps as new extremes are made. The trailing stop only ratchets toward profit — it never moves backward — so it can advance past breakeven and lock in a gain.
Validation:
- Tradovate leaders only. On other brokerages the order strategy is rejected with `NOT_SUPPORTED`.
- Use only one of `stop_loss_trail_trigger_ticks` or `stop_loss_trail_trigger_value`; the value must be greater than zero.
- A trigger requires a trail distance (`stop_loss_trail_ticks` or `stop_loss_trail_value`); without one the request is rejected.
- Absolute bracket prices are not supported for order strategies. Use tick/point offsets (`stop_loss_ticks`, `profit_target_ticks`, and the `stop_loss_trail_*` fields). Sending `stop_loss_price` or `profit_target_price` alongside a trigger is rejected.
- Not valid with `order_type` `trailing_stop` (a standalone trailing stop cannot carry brackets). Use `market`, `limit`, or `stop`.
Submission and copying: the order strategy is placed on the **leader** account only. Followers receive the entry fill copied as a normal order, and the trailing stop is mirrored to followers as it moves (Tradovate followers natively; other brokerages via stop-price modifications), the same way the trailing stop-loss bracket is mirrored.
`stopLossTrailTriggerTicks` and `stopLossTrailTriggerValue` are also accepted as camelCase aliases.
### `stop_loss_trail_freq_ticks` / `stop_loss_trail_freq_value`
Type: `stop_loss_trail_freq_ticks` integer; `stop_loss_trail_freq_value` decimal number or numeric string
Required: no (order strategy only)
Purpose: The re-trail **frequency** (step) for an order strategy — how far the market must make a new extreme before the trailing stop is re-pulled. A smaller step re-pulls the stop more often (finer trailing); a larger step re-pulls in bigger increments.
- `stop_loss_trail_freq_ticks` — step in ticks.
- `stop_loss_trail_freq_value` — step as a value, interpreted by `stop_loss_trail_type`.
Validation:
- Only valid together with a trail trigger (`stop_loss_trail_trigger_*`). Sent on its own it is rejected, because the step is meaningless without trailing.
- Use only one of `stop_loss_trail_freq_ticks` or `stop_loss_trail_freq_value`; the value must be greater than zero.
- If omitted, the step defaults to the contract's tick size (the stop re-pulls on each tick of new extreme).
`stopLossTrailFreqTicks` and `stopLossTrailFreqValue` are also accepted as camelCase aliases.
### `trail_type`
Type: string
Required: no. Optional even when `order_type` is `trailing_stop`; defaults to `ABSOLUTE` when omitted. Ignored for other order types.
Supported values:
- `ABSOLUTE` — `trail_value` is the trail distance in price points.
- `PERCENTAGE` — `trail_value` is a percentage of the current market price; FutuCopy converts it to an absolute distance in price points (rounded to the contract tick size) using the contract's last trade price at the time the order is placed. For example, `trail_value` `0.5` with `PERCENTAGE` on a market trading at 7464 trails ~37.25 points.
Accepted aliases are case-insensitive: `ABS`, `PRICE`, and `POINTS` for `ABSOLUTE`; `PERCENT`, `PCT`, and `%` for `PERCENTAGE`.
`trailType` is also accepted as a camelCase alias.
### `trail_value`
Type: decimal number or numeric string
Required: required when `order_type` is `trailing_stop`.
Purpose: The trailing-stop trail distance, interpreted per `trail_type`. For `ABSOLUTE` this is the distance in price points the stop trails behind the market; for `PERCENTAGE` it is a percent of the current price (e.g. `0.5` = 0.5%).
Validation:
- Must be greater than zero.
- `trailing_stop` orders cannot include stop-loss or profit-target bracket fields.
- An optional positive `price` may be sent as the explicit initial stop trigger. When omitted, FutuCopy reads the current market price and places the initial stop `trail_value` away from it (a sell trails below the bid, a buy above the ask), so you do not need to send a price — useful for TradingView alerts, which cannot do arithmetic on placeholders.
`trailValue` is also accepted as a camelCase alias. Trailing stops are supported on Tradovate leaders only.
## Bracket TP/SL Copying
Stop loss and profit target fields create an attached bracket (entry plus protective legs) on a Tradovate leader. How those protective legs reach followers depends on the follower's brokerage.
When both the leader and a follower account are on Tradovate (and the follower supports native bracket copying), FutuCopy replicates the whole bracket as a single broker-native linked order group (Tradovate `placeOSO` / `placeOCO`). The entry, stop loss, and profit target are submitted to the follower together as soon as the entry is copied, so there is no extra lag waiting for the leader's protective legs to activate. The follower's protective legs sit in `Suspended` status and activate on the follower's own entry fill, exactly as on the leader.
For followers on other brokerages, FutuCopy copies the entry order first and then copies the stop loss and profit target as individual orders once the leader's attached child orders transition from Tradovate's `Suspended` state to `Live`/`Working` (which happens after the leader entry fills). `Suspended` is a Tradovate-specific state that other brokerages do not support, so FutuCopy does not copy `Suspended` child orders directly. For these followers the protective orders may briefly appear on the Tradovate leader before they appear on the follower.
If a native bracket cannot be represented or is rejected by the follower's broker, FutuCopy falls back to copying the entry alone and copies the protective legs when the leader's child orders activate. On that leg-by-leg path, if the leader entry is canceled before its protective legs ever become live, those followers will not receive the protective orders. Native-bracket (Tradovate) followers are normally unaffected, because their protective legs are submitted with the entry and are canceled together with it.
## TradingView Placeholder Reference For FutuCopy
Recommended strategy placeholders:
- `{{strategy.order.action}}`: becomes `buy` or `sell`.
- `{{strategy.order.contracts}}`: becomes the number of contracts in the executed strategy order.
- `{{strategy.order.price}}`: becomes the price at which the TradingView strategy order was executed.
- `{{strategy.order.alert_message}}`: becomes the custom `alert_message` string produced by Pine Script order commands.
General placeholders that may be useful in custom Pine alert messages:
- `{{ticker}}`
- `{{close}}`
- `{{open}}`
- `{{high}}`
- `{{low}}`
- `{{time}}`
When answering questions about TradingView placeholders, confirm whether the user is using a strategy order-fill alert. Strategy placeholders do not populate in simple manual price alerts.
## Basic Market Order Example
Manual version:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market"
}
```
Pine Script placeholder version:
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "market"
}
```
## Limit Order Example
Manual version:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "limit",
"price": 7235
}
```
Pine Script placeholder version using strategy fill price:
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "limit",
"price": {{strategy.order.price}}
}
```
## Stop Order Example
Manual version:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "stop",
"price": 7235
}
```
Pine Script placeholder version using strategy fill price:
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "stop",
"price": {{strategy.order.price}}
}
```
## Trailing Stop Order Example
Tradovate leaders only. Places a trailing stop on the leader account with the trail distance in price points. Tradovate followers receive native trailing stop orders; non-Tradovate followers receive regular stop orders that mirror the leader's trailing moves.
Manual version:
```json
{
"action": "sell",
"contracts": 1,
"leader_id": 1496,
"order_type": "trailing_stop",
"trail_type": "ABSOLUTE",
"trail_value": 5
}
```
Pine Script placeholder version:
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "trailing_stop",
"trail_type": "ABSOLUTE",
"trail_value": 5
}
```
## Bracket Example With Tick-Based Stop Loss And Profit Target
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "market",
"stop_loss_ticks": 40,
"profit_target_ticks": 40
}
```
## Bracket Example With Absolute Stop Loss And Profit Target Prices
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"stop_loss_price": 7210.25,
"profit_target_price": 7260.25
}
```
Do not include both tick-based and price-based versions for the same bracket side. For example, do not include both `stop_loss_ticks` and `stop_loss_price` in the same message.
## Bracket Example With Trailing Stop Loss And Profit Target (Tradovate)
A market entry with a profit-target limit and a **trailing** stop loss (10-point trail). The stop trails the market after the entry fills; followers mirror the leader's trail.
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"profit_target_ticks": 40,
"stop_loss_trail_value": 10,
"stop_loss_trail_type": "ABSOLUTE"
}
```
A tick-based trail variant, instead of `stop_loss_trail_value`/`stop_loss_trail_type`:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"profit_target_ticks": 40,
"stop_loss_trail_ticks": 40
}
```
A percentage trail variant (0.5% of the current price, tick-rounded to the contract):
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"profit_target_ticks": 40,
"stop_loss_trail_value": 0.5,
"stop_loss_trail_type": "PERCENTAGE"
}
```
## Order Strategy Example: Trailing Stop With Trigger (AutoTrail, Tradovate)
Tradovate leaders only. A market entry that is placed with an initial fixed stop and, once price moves the trigger distance in profit, converts that stop into a trailing stop. An optional profit target is attached as the OCO sibling. Tick distances are converted to price points using the contract's tick size (for a 0.25 tick: 24 ticks = 6.0 points, 4 ticks = 1.0 point, 8 ticks = 2.0 points, 2 ticks = 0.5 points).
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"stop_loss_ticks": 24,
"profit_target_ticks": 40,
"stop_loss_trail_trigger_ticks": 4,
"stop_loss_trail_ticks": 8,
"stop_loss_trail_freq_ticks": 2
}
```
In that example: the entry fills, an initial fixed stop is placed 24 ticks away, and the trade keeps a 40-tick profit target. After price moves 4 ticks in profit, the fixed stop becomes a trailing stop that follows 8 ticks behind the best price and re-pulls in 2-tick steps. If the trailing stop fills, the profit target is cancelled, and vice versa.
Limit-entry variant — the entry rests at your price and the bracket activates when it fills:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "limit",
"price": 7554,
"stop_loss_ticks": 24,
"profit_target_ticks": 40,
"stop_loss_trail_trigger_ticks": 4,
"stop_loss_trail_ticks": 8,
"stop_loss_trail_freq_ticks": 2
}
```
Point-based variant using values instead of ticks (`stop_loss_trail_type` governs the trigger, trail, and frequency values; `ABSOLUTE` is the default and may be omitted). The profit target and initial fixed stop still use ticks because order strategies do not accept absolute bracket prices:
```json
{
"action": "buy",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"stop_loss_ticks": 24,
"profit_target_ticks": 40,
"stop_loss_trail_trigger_value": 1,
"stop_loss_trail_value": 2,
"stop_loss_trail_freq_value": 0.5,
"stop_loss_trail_type": "ABSOLUTE"
}
```
The minimum order strategy is a trigger plus a trail distance (initial fixed stop, profit target, and frequency are all optional):
```json
{
"action": "sell",
"contracts": 1,
"leader_id": 1496,
"order_type": "market",
"stop_loss_trail_trigger_ticks": 4,
"stop_loss_trail_ticks": 8
}
```
## Flatten Examples
Flatten one leader:
```json
{
"action": "flatten",
"leader_id": 1496
}
```
Flatten all:
```json
{
"action": "flatten_all"
}
```
## Simplest TradingView Strategy Test
Use this Pine Script to generate strategy order fills that populate `{{strategy.order.action}}` and `{{strategy.order.contracts}}`:
```pinescript
//@version=6
strategy("FutuCopy Placeholder Test", overlay=true, process_orders_on_close=true)
if bar_index % 2 == 0
strategy.entry("Test Long", strategy.long, qty=1)
else
strategy.close("Test Long")
```
TradingView alert setup:
1. Add the strategy to the chart.
2. Create an alert.
3. Choose the strategy as the alert condition.
4. Choose the order-fill alert option, such as "Order fills" or "Order fills and alert() function calls".
5. Add the FutuCopy webhook URL to the Webhook URL field.
6. Use this alert message:
```json
{
"action": "{{strategy.order.action}}",
"contracts": {{strategy.order.contracts}},
"leader_id": 1496,
"order_type": "market"
}
```
Use a valid `leader_id` from the user's FutuCopy Webhooks page.
## Using `strategy.order.alert_message` For Advanced Pine Values
If the user needs Pine-calculated values that are not available through TradingView placeholders, build the entire JSON message in Pine Script and send it through `alert_message`.
In the TradingView alert Message field, use only:
```text
{{strategy.order.alert_message}}
```
Then in Pine Script, pass a valid JSON string to an order command's `alert_message` parameter.
Conceptual example:
```pinescript
//@version=6
strategy("FutuCopy Custom Alert Message Example", overlay=true)
float myStopPrice = close + syminfo.mintick * 4
string msg = '{"action":"buy","contracts":1,"leader_id":1496,"order_type":"stop","price":' + str.tostring(myStopPrice, format.mintick) + '}'
if barstate.isconfirmed
strategy.entry("Stop Long", strategy.long, qty=1, stop=myStopPrice, alert_message=msg)
```
The JSON string must remain valid after TradingView sends it.
## Response Shape
Successful and handled webhook responses use this shape:
```json
{
"success": true,
"message": "Webhook received and order submitted to brokerage. Check the Orders table for final order status.",
"errorCode": null,
"orderId": "optional",
"timestamp": "UTC timestamp"
}
```
Some handled responses may have HTTP 200 but `success: false` when the request reached FutuCopy but the order or flatten operation could not be completed. Users should read the `message` and `errorCode`.
Validation and authentication errors that reach FutuCopy webhook processing use this shape:
```json
{
"error": {
"code": "INVALID_REQUEST",
"message": "Human-readable error message",
"details": null,
"traceId": "request trace id",
"timestamp": "UTC timestamp"
}
}
```
Malformed JSON, unsupported content types, or low-level request parsing errors can be rejected before webhook processing runs, so those responses may use a different error shape.
## Common Error Codes
- `INVALID_REQUEST`: Missing or invalid fields, body too large, incompatible field combination.
- `UNAUTHORIZED`: Invalid token format or invalid token.
- `FORBIDDEN`: Token user is not allowed for the endpoint.
- `LEADER_NOT_FOUND`: `leader_id` does not belong to an eligible configured leader.
- `INVALID_ACTION`: `action` is not supported.
- `INVALID_OPERATION`: The requested operation is not supported in the current context.
- `FLATTEN_FAILED`: Flatten operation failed.
- `FLATTEN_NO_ACCOUNTS`: No accounts were available for flatten.
- `ROUTING_UNAVAILABLE`: FutuCopy could not route the request to the user's trading service.
- `RATE_LIMITED`: Too many webhook requests in a short time.
- `INTERNAL_ERROR`: Unexpected server-side error.
The codes above are returned with their matching HTTP status (4xx for validation and authentication errors). Brokerage/execution-layer codes are different: they arrive as HTTP 200 with `success: false` and the code in `errorCode`, because FutuCopy accepted the request but the brokerage could not place the order. Read both `message` and `errorCode`.
- `NOT_SUPPORTED`: The order type or bracket is not supported on the leader's brokerage. For webhooks this means a `trailing_stop` order, a trailing stop-loss bracket, or an order strategy (a trail trigger / autoTrail), on a non-Tradovate account (all three are Tradovate-only).
- `TICK_SIZE_MISSING`: The contract's tick size is unavailable, so a tick-distance bracket, trailing leg, or order-strategy offset cannot be computed.
- `NO_REFERENCE_PRICE`: FutuCopy could not determine the current market price needed to anchor a tick-distance bracket, a trailing stop, or a percentage-based order-strategy offset.
- `INVALID_TRAIL`: A trailing stop-loss bracket or order strategy was misconfigured (for example combined with a `trailing_stop` entry, a trailing stop loss combined with a fixed stop loss, an order-strategy trigger sent without a trail distance, or an invalid/non-positive trail, trigger, or frequency value), or a percentage trail could not be converted because the current price was unavailable.
This execution-layer list is not exhaustive. Account, connection, contract, symbol-mapping, or brokerage placement failures may also appear as HTTP 200 with `success: false` and an execution-specific `errorCode`.
## Exact Messages To Expect
These are common validation or execution-layer messages:
- `Invalid webhook token format.`
- `Invalid webhook token.`
- `Webhook token is not valid for this endpoint.`
- `Action must be 'buy', 'sell', 'flatten', or 'flatten_all'.`
- `leader_id is required.`
- `Action must be 'buy' or 'sell'.`
- `Contracts must be greater than zero.`
- `Order type must be 'market', 'limit', 'stop', or 'trailing_stop'.`
- `Price is required and must be greater than zero for limit and stop orders.`
- `Price can only be used with limit and stop orders.`
- `Use either stop_loss_ticks or stop_loss_price, not both.`
- `Use either profit_target_ticks or profit_target_price, not both.`
- `stop_loss_price must be greater than zero.`
- `profit_target_price must be greater than zero.`
- `stop_loss_trail_value must be greater than zero.`
- `stop_loss_trail_ticks must be greater than zero.`
- `Use either stop_loss_trail_ticks or stop_loss_trail_value, not both.`
- `Use either a fixed stop loss (stop_loss_ticks/stop_loss_price) or a trailing stop loss (stop_loss_trail_*), not both.`
- `Trailing stop-loss brackets are supported on Tradovate accounts only.`
- `stop_loss_trail_freq_* is only valid together with stop_loss_trail_trigger_* (an order strategy).`
- `stop_loss_trail_trigger_* requires a trail distance (stop_loss_trail_ticks or stop_loss_trail_value).`
- `Use either stop_loss_trail_trigger_ticks or stop_loss_trail_trigger_value, not both.`
- `stop_loss_trail_trigger_value must be greater than zero.`
- `stop_loss_trail_trigger_ticks must be greater than zero.`
- `Use either stop_loss_trail_freq_ticks or stop_loss_trail_freq_value, not both.`
- `stop_loss_trail_freq_value must be greater than zero.`
- `stop_loss_trail_freq_ticks must be greater than zero.`
- `Order strategies use tick/point offsets; stop_loss_price/profit_target_price are not supported (use stop_loss_ticks/profit_target_ticks).`
- `Order strategies (auto-trail) are supported on Tradovate accounts only.`
- `trail_value is required and must be greater than zero for trailing_stop orders.`
- `trailing_stop orders cannot include stop-loss or profit-target brackets.`
- `Trailing-stop orders are supported on Tradovate accounts only.`
- `Trade copy leader with ID {leader_id} not found.`
- `Leader has no account assigned. Cannot flatten account-agnostic leaders.`
- `Leader has no account assigned. Cannot place orders on account-agnostic leaders.`
- `Webhook request body is too large.`
- `Too many webhook requests. Please retry shortly.`
## Troubleshooting Guide For AI Assistants
If placeholders arrive literally, such as `"{{strategy.order.action}}"`, the user probably tested with a manual alert or the wrong TradingView alert type. Tell them to create a strategy order-fill alert.
If `contracts` causes invalid JSON, check whether it was quoted or left blank. Recommended JSON is:
```json
"contracts": {{strategy.order.contracts}}
```
If a market order fails because of `price`, remove the `price` field. FutuCopy requires no `price` for market orders.
If a limit or stop order fails because of missing price, add `price`.
If `leader_id` fails, ask the user to open the FutuCopy Webhooks page and confirm the ID from the Configured Leaders table. The leader must have an assigned leader account.
If `stop_loss_ticks` and `stop_loss_price` are both present, remove one. The same rule applies to `profit_target_ticks` and `profit_target_price`.
If TP/SL orders appear on a Tradovate leader but not on a follower, the behavior depends on the follower's brokerage. Tradovate followers receive the full bracket (entry plus stop loss and profit target) together as a native linked order, and their protective legs sit `Suspended` until the follower's own entry fills, so check the follower's working/suspended orders rather than only the leader's. Followers on other brokerages receive the protective legs only after the leader's attached child orders transition from `Suspended` to `Live`/`Working` (after the leader entry fills); a brief delay there is expected.
If an order strategy (autoTrail) is rejected, check the combination: a trail trigger (`stop_loss_trail_trigger_ticks` / `stop_loss_trail_trigger_value`) must be paired with a trail distance (`stop_loss_trail_ticks` / `stop_loss_trail_value`); `stop_loss_trail_freq_*` may not be sent without a trigger; each of trigger, trail, and frequency uses ticks **or** value, not both; absolute `stop_loss_price` / `profit_target_price` are not allowed (use the tick fields); and the leader must be a Tradovate account. If the stop never starts trailing, the market has not yet moved the trigger distance in profit — the stop stays at its initial fixed level until then.
If the webhook URL works from TradingView but not from another tool, use the FutuCopy Webhooks page's built-in Test Webhook button for manual testing. The public endpoint is intended for TradingView webhook delivery; third-party delivery tools are unsupported and must still send valid JSON within the request-size and rate limits.
If the user changes Pine Script code after creating an alert, tell them to recreate the TradingView alert. TradingView alert instances keep a snapshot of the script and chart context at the time the alert is created.
If the user wants the actual current chart price rather than strategy fill price, clarify the goal:
- For executed strategy order price, use `{{strategy.order.price}}`.
- For current bar close in an alert message, use `{{close}}`.
- For a Pine-calculated order level, build the JSON in Pine and send it through `{{strategy.order.alert_message}}`.
## User-Facing Safety Warnings
Webhook tests can place real orders. A buy or sell webhook places an order on the selected leader account, and if copy trading is enabled, follower accounts may receive copied orders too.
Flatten webhooks close positions for the requested scope.
Users should test carefully with the smallest safe size and on the correct leader.
Users should rotate their webhook token if it is exposed.