Price Change Trigger

The price_change trigger fires when the market price has moved by a specified percentage over a lookback window. It compares the current candle's close to a candle from N minutes ago. This trigger is global — it does not require an open position.

Use it for momentum entries ("buy after a 5% dip in the last 4 hours") or breakout detection ("price is up 3% over the last day").

Note

For price changes relative to your position's entry price, see Position Price Change instead. price_change watches the market; pos_price_change watches your P&L.

TOML Syntax

[[actions.triggers]]
type = "price_change"
value = "-5%"           # Required: ±N% threshold
timeframe = "1h"        # Optional: candle size (default: 1m)
lookback = 24           # Optional: number of candles to look back (default: 1)
max_value = "-15%"      # Optional: maximum allowed change (range cap)
max_count = 1           # Optional: max fires per position

Parameters

ParameterTypeRequiredDefaultDescription
typestringYesMust be "price_change"
valuestringYesPercentage threshold in "±N%" format
timeframestringNo"1m"Candle size for the lookback window
lookbackintegerNo1Number of timeframe-sized candles to look back
max_valuestringNoMaximum change in "±N%" format (caps the range)
max_countintegerNounlimitedMaximum times this trigger can fire per position

How It Works

The engine computes a total lookback in 1-minute candles:

total_lookback = lookback × timeframe_in_minutes
timeframelookbackTotal 1m candlesReal window
"1h"1 (default)601 hour
"1h"42404 hours
"1h"24144024 hours
"4h"6144024 hours
"1d"1 (default)14401 day
"5m"12601 hour

When lookback is omitted, it defaults to 1 — meaning the window equals exactly one timeframe period. This is backwards-compatible with the original behavior.

The engine then calculates:

change_pct = (current_close - close_N_candles_ago) / close_N_candles_ago × 100
  • Negative value (e.g., "-5%"): trigger fires when change_pct <= -5.0
  • Positive value (e.g., "+3%"): trigger fires when change_pct >= 3.0
graph TD
    A["Current candle close"] --> C{"Calculate % change<br/>over lookback window"}
    B["Close from N candles ago<br/>(N = lookback × timeframe)"] --> C
    C --> D{"change meets<br/>threshold?"}
    D -->|Yes| E{"Within max_value<br/>range?"}
    D -->|No| F["No action"]
    E -->|Yes or no max_value| G["Trigger fires"]
    E -->|No — too extreme| F

The value Format

The value field uses a "±N%" string format:

ValueMeaning
"-5%"Price dropped at least 5%
"-2.0%"Price dropped at least 2%
"+3%"Price rose at least 3%
"+1.5%"Price rose at least 1.5%
"3%"Same as "+3%" (positive assumed)

Tip

The + sign is optional for positive values. "3%" and "+3%" are equivalent.

The lookback Parameter

The lookback parameter controls how many timeframe-sized candles to look back. Without it, the engine looks back exactly one timeframe period.

# Without lookback: compares to 1 hour ago
type = "price_change"
value = "-5%"
timeframe = "1h"

# With lookback: compares to 24 hours ago (24 × 1h)
type = "price_change"
value = "-5%"
timeframe = "1h"
lookback = 24

This is useful when you want a long lookback window but the timeframe options don't cover it directly. For example, "did the price drop 10% over the last 3 days?" can be expressed as:

type = "price_change"
value = "-10%"
timeframe = "1d"
lookback = 3

The max_value Parameter (Range Capping)

max_value caps how extreme the price change can be for the trigger to fire. It creates a range instead of a simple threshold — useful for avoiding "falling knife" entries.

# Fire when price drops between 5% and 15%
# (skip if it dropped MORE than 15% — that's a falling knife)
type = "price_change"
value = "-5%"
max_value = "-15%"
timeframe = "4h"

How it works:

  • For negative thresholds: value is the minimum drop, max_value is the maximum drop
  • For positive thresholds: value is the minimum rise, max_value is the maximum rise
valuemax_valueFires when change is...
"-5%""-15%"Between -5% and -15%
"-5%"(none)-5% or worse (no cap)
"+3%""+10%"Between +3% and +10%
"+3%"(none)+3% or better (no cap)

Tip

max_value works with all price-change family triggers: price_change, price_change_from_high, and price_change_from_low.

Valid Timeframes

The timeframe field accepts: 1m, 5m, 15m, 1h, 4h, 1d.

When omitted, the trigger uses 1m — meaning it compares the current close to the close 1 minute ago. This is rarely useful on its own. In practice, you almost always want a larger timeframe.

Examples

Buy After a 5% Dip Over 4 Hours

[[actions]]
type = "open_long"
amount = "100 USDC"

[[actions.triggers]]
type = "price_change"
value = "-5%"
timeframe = "4h"

Buy After a 10% Dip Over 24 Hours (With Lookback)

[[actions]]
type = "open_long"
amount = "200 USDC"

[[actions.triggers]]
type = "price_change"
value = "-10%"
timeframe = "1h"
lookback = 24

Sell After a 3% Rise Over 1 Hour

[[actions]]
type = "sell"
amount = "100%"

[[actions.triggers]]
type = "price_change"
value = "+3%"
timeframe = "1h"

DCA Entry on Hourly Dip (Fire Once)

[[actions]]
type = "buy"
amount = "100 USDC"
average_price = true

[[actions.triggers]]
type = "price_change"
value = "-3%"
timeframe = "1h"
max_count = 1

Buy the Dip — But Not the Crash (Range Cap)

# Enter on 5-15% dips over 4 hours, skip if it's a free fall
[[actions]]
type = "open_long"
amount = "100 USDC"

[[actions.triggers]]
type = "price_change"
value = "-5%"
max_value = "-15%"
timeframe = "4h"

Combine with Technical Indicator

# Buy when price dropped 3% in the last hour AND RSI is oversold
[[actions]]
type = "open_long"
amount = "100 USDC"

[[actions.triggers]]
type = "price_change"
value = "-3%"
timeframe = "1h"

[[actions.triggers]]
indicator = "rsi_14"
operator = "<"
target = "30"
timeframe = "1h"

Tips

Tip

price_change is a global market signal. It works whether or not you have an open position. This makes it ideal for entry triggers that watch for market-wide dips or rallies.

Tip

Use lookback when standard timeframes don't cover the window you need. timeframe = "1h" with lookback = 24 gives you a 24-hour window calculated from hourly candle boundaries.

Tip

max_value is your safety net. In volatile markets, a 5% dip might be normal — but a 30% crash could signal something fundamentally wrong. Use max_value to filter out extreme moves.

Warning

Without a timeframe, price_change compares to just 1 minute ago, which is extremely noisy. Always set a timeframe for meaningful signals.

TriggerWhat It Measures
Price Change from High% drop from the highest price in a lookback window
Price Change from Low% rise from the lowest price in a lookback window
Position Price Change% change from your entry price
Trailing Stop% drop from position's peak price
Consecutive CandlesStreaks of red or green candles