CROSSES UNDER
CROSSES UNDER in ProBuilder returns true on the bar where one series moves from above to below another, the standard trigger for bearish crossover signals.
Syntax
a CROSSES UNDER bParameters
| Name | Type | Default | Description |
|---|---|---|---|
| a | numeric series | required | The series being tested for a downward crossing. |
| b | numeric series or constant | required | The series or fixed level that a must cross below. |
Formula
a CROSSES UNDER b is true when both conditions hold on the same bar:
a[1] >= b[1] and a < bOn the previous bar a was at or above b, and on the current bar a is strictly below b.
How it works
CROSSES UNDER compares two values across consecutive bars and returns a boolean. The expression is true only on the single bar where the relationship flips from above to below. On later bars where a merely stays below b, it returns false. It therefore detects the crossing event itself, unlike the state comparison a < b, which stays true for as long as the condition holds.
Either operand can be a numeric expression of any kind: indicator output, a price constant such as close, a variable, or a plain number. Crossing fixed levels is a frequent pattern, for example Stochastic[14,3](close) CROSSES UNDER 80.
Since the current bar participates in the test, a downward cross detected on a live bar can vanish if prices recover before the bar closes. Testing shifted values, such as a[1] CROSSES UNDER b[1], restricts the check to completed bars and produces stable signals one bar later.
Examples
Example 1, EMA cross to the downside (Indicator)
a = ExponentialAverage[20](close)
b = ExponentialAverage[50](close)
signal = 0
// Evaluate the crossing on completed bars only
IF a[1] CROSSES UNDER b[1] THEN
signal = -1
ELSE
signal = 0
ENDIF
RETURN signal AS "Bearish Signal"The indicator prints -1 on the bar after the 20-period EMA drops below the 50-period EMA, and 0 otherwise. Both operands are shifted one bar so the test uses closed data.
Example 2, Closing a long position (ProOrder)
fast = Average[20](close)
slow = Average[50](close)
// Enter on the upward cross, exit on the downward cross
IF fast CROSSES OVER slow AND NOT LONGONMARKET THEN
BUY 1 CONTRACT AT MARKET
ENDIF
IF fast CROSSES UNDER slow AND LONGONMARKET THEN
SELL AT MARKET
ENDIFCROSSES UNDER acts as the exit trigger: the long position opened on the bullish cross is closed on the bar where the fast average falls back below the slow one.
Example 3, Stochastic leaving overbought territory (ProScreener)
myStoch = Stochastic[14, 3](close)
// Match instruments where %K has just dropped below 80
cond = myStoch CROSSES UNDER 80
SCREENER[cond] (myStoch AS "Stochastic")The screener returns instruments whose stochastic %K crossed below the 80 level on the current bar, a common overbought exit pattern.
Common errors and gotchas
- One-bar event, not a state. The expression is true only on the crossing bar. Logic that needs "is still below" must test
a < bseparately, or the signal will silently disappear on the next bar. - Live-bar instability. On a forming bar the cross can trigger and then untrigger before the close. Use
a[1] CROSSES UNDER b[1]when only confirmed crossings should count. - Strict inequality required. A series that declines to exactly the level of
bwithout moving below it does not fire the condition, because the current-bar comparison is strict. - Reversed operand order.
a CROSSES UNDER bandb CROSSES UNDER adescribe opposite events. Swapping the operands by accident inverts the signal without any compiler warning.
Related instructions
CROSSES OVER, the mirror operator for upward crossings.IF, conditional block that usually wraps a crossover test.THEN, required between the condition and the block body.ExponentialAverage, EMA series commonly paired in crossover systems.Average, simple moving average, another frequent crossover input.AND, combines the crossing with position or filter conditions.NOT, negates a boolean, useful for position checks alongside crossings.BarsSince, counts bars elapsed since a condition such as a crossover was true.
