Scale out of a position with multiple take-profit levels¶
Scaling out turns a single exit into a ladder. You open the position at full size, take a partial profit at the first target, trail the stop behind the price, take another partial at the second target (up to 5 targets) and close the remainder at the final target. This guide chains every step into a single watcher script that polls the market and runs each step the moment price reaches the matching level.
Tip
Define your credentials in shell variables once. Every interactive command below reuses them, so the steps stay short and the script stays portable.
export CTID=1234567
export ACC=7654321
export PWD_FILE=$HOME/.ctrader/pwd
1. Identify the take-profit levels from recent price action¶
Before you open anything, scan the candles for the resistance levels above your planned entry. candles returns the last N candles in JSON for the symbol and period you want to trade.
ctrader-cli candles --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--symbol=EURUSD --period=h1 --count=48
For this example, assume you are opening a buy at 1.1200 and you want to take profit at three levels: 1.1250 (TP1, one third), 1.1300 (TP2, another third) and 1.1400 (TP3, the remainder). Your initial stop loss sits at 1.1150.
2. Open the full-size position with a stop loss only¶
order place-market fills at the next available price. Pass --sl for protection but omit --tp so the position stays open through every level until you decide to close it.
ctrader-cli order place-market --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--symbol=EURUSD --side=buy --volume=1000 --sl=1.1150
The CLI prints the new position identifier in JSON. The watcher script in step 7 captures it automatically; if you are running the commands by hand, copy it for every later step.
3. Verify the position is open and protected¶
positions confirms the position is live with the stop loss in place. A single position with no take profit is the starting point for the ladder.
ctrader-cli positions --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q
4. Take the first partial at TP1 and move the stop to breakeven¶
When the market reaches 1.1250, take one third of the position with position close-partial, then move the stop to your entry price with position modify.
ctrader-cli position close-partial --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--position=11223344 --volume=333
ctrader-cli position modify --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--position=11223344 --sl=1.1200
The remaining two thirds stay open and the trade is now a free runner from breakeven.
5. Take the second partial at TP2 and trail the stop up¶
When the market reaches 1.1300, take another third and trail the stop up to TP1.
ctrader-cli position close-partial --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--position=11223344 --volume=333
ctrader-cli position modify --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--position=11223344 --sl=1.1250
The final third now sits in a tight corridor between 1.1250 and 1.1400.
6. Close the remainder at TP3¶
When the market reaches 1.1400, exit the rest with position close.
ctrader-cli position close --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
--position=11223344
Confirm the account is flat for the symbol with positions.
ctrader-cli positions --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q
7. Automate the ladder with a watcher script¶
Save the ladder as scale-out.sh and run it once you are ready to enter the trade. The script opens the position, captures its identifier, polls price and runs each step the moment the market reaches the matching TP level. No further input is needed.
The script uses jq to extract the new position identifier from the JSON output and awk for the floating-point comparison against the TP level. Both are preinstalled on most Linux distributions and on macOS. On Windows, install them through winget or run the script inside WSL.
#!/usr/bin/env bash
set -euo pipefail
CTID=1234567
ACC=7654321
PWD_FILE=$HOME/.ctrader/pwd
SYMBOL=EURUSD
SIDE=buy
VOLUME=1000
SL=1.1150
ENTRY=1.1200
TP1=1.1250
TP2=1.1300
TP3=1.1400
POLL_SECONDS=5
# Run any cTrader CLI call with the shared auth flags. The command name
# comes first, then --ctid, --pwd-file and --account, then -q, then the
# command-specific options.
cli() {
ctrader-cli "$1" --ctid=$CTID --pwd-file=$PWD_FILE --account=$ACC -q \
"${@:2}"
}
# Print the current bid for the symbol.
current_bid() {
cli price --symbol=$SYMBOL | jq -r '.bid'
}
# Block until the bid reaches or exceeds the target. Used for buy positions.
wait_for_bid_at_least() {
local target=$1
echo "Watching $SYMBOL bid for $target every ${POLL_SECONDS}s..."
while true; do
local price
price=$(current_bid)
if [ -n "$price" ] && awk -v p="$price" -v t="$target" 'BEGIN { exit !(p + 0 >= t + 0) }'; then
echo "Bid $price reached $target."
return 0
fi
sleep $POLL_SECONDS
done
}
# Open the position at full size with only a stop-loss and capture its identifier.
POS_ID=$(cli order place-market \
--symbol=$SYMBOL --side=$SIDE --volume=$VOLUME --sl=$SL | jq -r '.positionId')
echo "Opened position $POS_ID on $SYMBOL."
# TP1: take one third of the volume and move the stop to breakeven.
wait_for_bid_at_least $TP1
cli position close-partial --position=$POS_ID --volume=$(( VOLUME / 3 ))
cli position modify --position=$POS_ID --sl=$ENTRY
# TP2: take another third and trail the stop up to TP1.
wait_for_bid_at_least $TP2
cli position close-partial --position=$POS_ID --volume=$(( VOLUME / 3 ))
cli position modify --position=$POS_ID --sl=$TP1
# TP3: close the remainder at the final target.
wait_for_bid_at_least $TP3
cli position close --position=$POS_ID
echo "Closed position $POS_ID at TP3."
Run it with bash scale-out.sh after the broker session is online. The script logs each step to stdout, so you can watch progress in the terminal or pipe it to a log file with bash scale-out.sh | tee -a scale-out.log. Every close-partial locks in part of the move and every modify tightens the stop behind it.
If the stop loss hits before a TP level, the next close-partial call returns an error and the script exits under set -e. Re-run the script after reviewing the position state with positions or close the position by hand with cli position close --position=$POS_ID.
Note
The .positionId field assumes the JSON key cTrader uses for the new position identifier. If your CLI build names the key differently, replace .positionId with the matching key from the order place-market output. For a sell position, replace current_bid and wait_for_bid_at_least with the equivalent ask helpers and compare against ask <= TP instead of bid >= TP.
The CLI references lists all available options for the commands used in this workflow.
Warning
cTrader CLI is a tool for trading and automation. It does not provide financial, investment, legal or tax advice. Commands that place or change orders can trigger real trades and result in losses. Verify every command before you run it, test on a demo account first and protect your credentials.