Skip to content

X-Trader auto_strategy: migration, timed sell, sl_protection, phased_sl, anti_pvp

auto_strategy is the required object inside config that holds exit rules that are not plain TP/SL stages: selling on migration, a single delayed full sell, clearing dust or stalled positions, profit protection, a delayed stop-loss (sl_protection), a two-phase stop-loss (phased_sl), a temporary block on targets that sell quickly (anti_pvp) and a per-config sell fee override. Only migration_clear, timed_sell and sell_delay are required; every other rule is optional.

Primary source: X-Trader API reference. This page is an independent explanation of X-Trader Public API v1.0.0; it is not affiliated with X-Trader.

auto_strategy is a required key of config in the sniper, copy-trade and transfer-snipe Create and Patch schemas and in both template schemas. The object schema is identical in all of them. It works next to auto_sell and timed_strategy. The object and every nested object are strict: unknown keys return validation_error. All numeric values are decimal strings, max 32 characters (see write rules).

Field Type Required Purpose
migration_clear boolean yes Sell the whole position when migration is detected.
migration_sell object no Sell a percentage on migration.
timed_sell boolean yes Enable one delayed full-position sell.
sell_delay string yes Delay for timed_sell, seconds "0" to "31536000".
remaining_position_clear object no Clear a small remaining position (SOL value).
tp1_timeout_clear object no Clear if TP1 is not reached in time.
price_stagnation_clear object no Clear if price stays unchanged.
profit_protection object no Reduce the position while profit holds above a threshold.
sl_protection object no Delayed one-shot stop-loss.
phased_sl object no Two-phase live stop-loss.
anti_pvp object no Temporarily block a target that sells soon after buying.
sell_fee_override object no Per-config sell Priority Fee and Tip.

Every optional object has its own enabled flag, and all of its keys are required whenever the object is present (even with enabled: false).

Field Type Values Meaning
migration_clear boolean On detected migration, sell 100%.
migration_sell.enabled boolean Turns the percentage rule on.
migration_sell.percent string greater than 0, at most 100 Share of the position to sell on migration.

When both migration_clear and migration_sell.enabled are true, migration_clear takes priority. The spec does not define which events count as migration.

Field Type Values Meaning
timed_sell boolean Enables a single delayed sell of the full position.
sell_delay string "0" to "31536000" seconds (365 days) Delay before that sell.

sell_delay is required even when timed_sell is false; send "0" in that case. For several partial sells at different times use timed_strategy instead.

Object value meaning Limits stated in the spec
remaining_position_clear Decimal SOL amount minimum "0.01"
tp1_timeout_clear Seconds not stated
price_stagnation_clear Seconds not stated

Each object is { "enabled": <bool>, "value": "<string>" }.

  • remaining_position_clear clears a small leftover position. The spec gives only the SOL unit and minimum; the practical reading is that a remainder worth less than value SOL is sold out.
  • tp1_timeout_clear clears the position when the first take-profit stage of auto_sell.tp_orders has not been reached within value seconds.
  • price_stagnation_clear clears the position when the price stays unchanged for value seconds.
Field Type Values Meaning
enabled boolean
threshold string profit percent Profit level that must hold.
price_checks string "1" to "10000" Consecutive price checks above threshold required.
reduce_ratio string "0" to "100" Percentage by which the position is reduced.

When profit stays above threshold for price_checks consecutive checks, the position is reduced by reduce_ratio percent. The PnL used here honours auto_sell.ignore_fee_for_auto_sell. The spec does not say how often a price check happens.

Field Type Values Meaning
enabled boolean
seconds string "0" to "86400", 0.1 s precision Grace window after which the rule is evaluated once.
trigger string below 0, no lower than "-100" PnL threshold, mark-to-entry.

Behaviour:

  1. During the first seconds the rule never sells.
  2. At expiry, if mark-to-entry PnL is at or below trigger, 100% of the position is sold.
  3. If PnL is above trigger at expiry, the rule ends; later drops are ignored by this rule.

auto_sell.sl_orders keep firing immediately during and after the window.

Field Type Values Meaning
enabled boolean Omit the object or set false to keep it off.
seconds string "0.1" to "31536000" Length of the early window.
early_trigger string "-100" to "-1" Stop used before seconds elapse.
late_trigger string "-100" to "-1" Stop used after the early window.

On every price tick the active stop is compared with PnL; a hit sells 100%. The rule does not sell by itself at the moment the window ends, it only switches stops. early_trigger and late_trigger are independent, so either can be the tighter one: for example a loose -50 early (to survive launch volatility) and a tight -20 later, or the reverse. sl_orders and sl_protection continue to follow their own rules.

sl_protection phased_sl
Sells before the deadline never yes, on early_trigger
At the deadline one check, sells 100% if PnL at or below trigger switches to late_trigger, no sell by itself
After the deadline inactive live on late_trigger
Sell size 100% 100%
Field Type Meaning
enabled boolean
holding_time string, seconds Observation window after the buy.
ban_duration string, seconds How long the target is blocked.

If the target sells within holding_time seconds of buying, it is temporarily blocked for ban_duration seconds. The spec does not give numeric limits for either value, and does not describe what “blocked” means for a sniper target as opposed to a copy-trade target; the description refers to the target wallet in both cases.

Field Type Values
enabled boolean
priority_fee string SOL, "0" to "1000"
tip_amount string SOL, "0" to "1000"; at least "0.0001" when enabled

When enabled, these sell fees take precedence over the account’s global defaults for this configuration.

{
"target_wallet": "<solana-address>",
"config": {
"auto_strategy": {
"migration_clear": false,
"migration_sell": { "enabled": true, "percent": "50" },
"timed_sell": true,
"sell_delay": "3600",
"remaining_position_clear": { "enabled": true, "value": "0.01" },
"tp1_timeout_clear": { "enabled": true, "value": "900" },
"price_stagnation_clear": { "enabled": false, "value": "300" },
"profit_protection": {
"enabled": true, "threshold": "40", "price_checks": "5", "reduce_ratio": "50"
},
"sl_protection": { "enabled": true, "seconds": "30", "trigger": "-40" },
"phased_sl": {
"enabled": true, "seconds": "60", "early_trigger": "-50", "late_trigger": "-20"
},
"anti_pvp": { "enabled": true, "holding_time": "10", "ban_duration": "86400" },
"sell_fee_override": {
"enabled": true, "priority_fee": "0.001", "tip_amount": "0.001"
}
},
"auto_sell": {
"enabled": true, "expiry_time": "0",
"tp_orders": [{ "trigger": "100", "sell": "50" }],
"sl_orders": [], "follow_sell": false, "proportional_sell": false
},
"timed_strategy": { "enabled": false, "orders": [] }
}
}

The other required config keys are omitted; see sniper config and copy-trade config.

Updating auto_strategy on an existing config

Section titled “Updating auto_strategy on an existing config”

A PATCH with config replaces the whole nested config and is validated against the full schema, so read the current config, change auto_strategy, and send the complete config with the ETag as If-Match. Changing config requires a paused configuration (config_must_be_paused otherwise); a stale ETag returns version_conflict. Snapshots returned by GET may include legacy fields the strict schema rejects; error.fields lists the offending paths.

Terminal window
ID='<config-uuid>'
BASE='https://x-trader.ai/api/v1'
curl -sD headers.txt "$BASE/sniper/configs/$ID" \
--header "Authorization: Bearer $X_TRADER_API_TOKEN" \
| jq '.data.config' > config.json
ETAG=$(grep -i '^etag:' headers.txt | cut -d' ' -f2 | tr -d '\r')
jq '.auto_strategy.phased_sl = {"enabled":true,"seconds":"120","early_trigger":"-60","late_trigger":"-25"}
| .auto_strategy.anti_pvp = {"enabled":true,"holding_time":"15","ban_duration":"43200"}' \
config.json | jq '{config: .}' > patch.json
curl --request PATCH "$BASE/sniper/configs/$ID" \
--header "Authorization: Bearer $X_TRADER_API_TOKEN" \
--header 'Content-Type: application/json' \
--header "If-Match: $ETAG" \
--data @patch.json
import os
import requests
BASE = "https://x-trader.ai/api/v1"
CONFIG_ID = "<config-uuid>"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['X_TRADER_API_TOKEN']}"
url = f"{BASE}/sniper/configs/{CONFIG_ID}" # or /copy-trade/configs/{id}
resp = session.get(url)
resp.raise_for_status()
etag = resp.headers["ETag"]
resource = resp.json()["data"]
if resource["is_active"]:
raise SystemExit("Pause the config first (POST .../pause with If-Match)")
config = resource["config"]
strategy = config["auto_strategy"]
strategy["sl_protection"] = {"enabled": True, "seconds": "20", "trigger": "-35"}
strategy["sell_fee_override"] = {
"enabled": True, "priority_fee": "0.0005", "tip_amount": "0.0002",
}
strategy["timed_sell"] = False
strategy["sell_delay"] = "0"
patch = session.patch(url, json={"config": config}, headers={"If-Match": etag})
if patch.status_code >= 400:
print(patch.json()["error"])
patch.raise_for_status()
print("new version:", patch.headers["ETag"])

Only migration_clear (boolean), timed_sell (boolean) and sell_delay (decimal string of seconds). Every other rule is an optional object that can be omitted.

What happens if migration_clear and migration_sell are both enabled?

Section titled “What happens if migration_clear and migration_sell are both enabled?”

migration_clear wins: the whole position is sold on migration and the migration_sell percentage is not used.

How is sl_protection different from phased_sl?

Section titled “How is sl_protection different from phased_sl?”

sl_protection waits a fixed number of seconds and then sells 100% once, only if PnL is still at or below its trigger. phased_sl is a live stop that uses early_trigger before the deadline and late_trigger after it, selling 100% on any price tick that hits the active stop.

Do sl_protection and phased_sl replace auto_sell.sl_orders?

Section titled “Do sl_protection and phased_sl replace auto_sell.sl_orders?”

No. Ordinary sl_orders still fire immediately, and each rule follows its own logic independently.

Is auto_strategy different for sniper and copy-trade?

Section titled “Is auto_strategy different for sniper and copy-trade?”

No. The schema is identical in sniper, copy-trade, transfer-snipe and template configs.