Calculation and confirmation guide

Trend direction: define bullish, bearish and neutral states

A trend direction indicator assigns a state using a chosen price rule. It can describe price relative to an average, average ordering or swing structure. Different definitions can disagree on the same bar. A bullish label is not a probability of profit, evidence of institutional buying or an instruction to enter.

Explore custom indicator coding

Choose a definition you can inspect

These methods classify different features of the same history. None is universally best for a particular asset class.

DefinitionBullish exampleImportant distinction
Price locationClose above a chosen EMACan be true while the EMA slopes downward
Average orderingFast EMA above slow EMACan remain true after the latest close falls
SlopeCurrent EMA above its previous valueRequires a separate comparison; ordering does not measure slope
Swing structureConfirmed higher high and higher lowPivot confirmation occurs after the pivot bar; record the detection time

A three-state rule on one chart timeframe

This example calls a completed bar bullish only when close > baseline EMA and fast EMA > slow EMA. It calls it bearish only when both inequalities reverse. Every other available case is neutral. It uses no ATR, slope test or higher-timeframe request.

Close / baselineFast / slowState
105 / 100103 / 101Bullish: both comparisons pass
99 / 100103 / 101Neutral: the comparisons disagree
95 / 10098 / 101Bearish: both comparisons reverse
100 / 100103 / 101Neutral: equality does not pass either strict rule

Pine Script v6: display only completed-bar states

The code enforces fast < slow < baseline lengths and waits at least baselineLength chart bars. That gate is a display policy, not proof that initialization effects have disappeared. The developing bar is blank, and the Data Window shows 1, -1 or 0 only for an available confirmed state.

One-timeframe EMA direction filterpinescript
//@version=6
indicator("Confirmed EMA Direction [Pineify]", overlay=true)
int fastLength = input.int(20, "Fast EMA length", minval=1)
int slowLength = input.int(50, "Slow EMA length", minval=2)
int baselineLength = input.int(200, "Baseline EMA length", minval=3)
if fastLength >= slowLength or slowLength >= baselineLength
    runtime.error("Require fast < slow < baseline lengths.")
float fastEma = ta.ema(close, fastLength)
float slowEma = ta.ema(close, slowLength)
float baseline = ta.ema(close, baselineLength)
bool ready = bar_index >= baselineLength - 1 and not na(baseline) and not na(fastEma) and not na(slowEma)
bool confirmed = ready and barstate.isconfirmed
int state = close > baseline and fastEma > slowEma ? 1 : close < baseline and fastEma < slowEma ? -1 : 0
color stateColor = state == 1 ? color.teal : state == -1 ? color.orange : color.gray
pFast = plot(confirmed ? fastEma : na, "Fast EMA", color=color.teal, style=plot.style_linebr)
pSlow = plot(confirmed ? slowEma : na, "Slow EMA", color=color.orange, style=plot.style_linebr)
plot(confirmed ? baseline : na, "Baseline EMA", color=color.blue, linewidth=2, style=plot.style_linebr)
fill(pFast, pSlow, color=confirmed ? color.new(stateColor, 80) : na, fillgaps=false)
plot(confirmed ? state : na, "State: 1 bullish, -1 bearish, 0 neutral", display=display.data_window)
bgcolor(confirmed ? color.new(stateColor, 93) : na)

Separate a direction filter from a trade

A filter can restrict another setup, but it does not define an order. For example, a study could require the bullish state before evaluating a breakout. Specify the breakout, entry fill, invalidation, quantity and costs before measuring results.

  • A neutral state is not a short signal. A blank developing or insufficient-history bar is not neutral evidence.
  • Check reversals after a long trend and repeated switches in a range. Slower lengths can reduce switching while increasing reaction delay; the trade-off needs measurement.
  • The same 200-bar length spans different elapsed time on daily and five-minute charts. Keep symbol, session and adjustment settings fixed.
  • If extending this to weekly data on daily bars, define completed-week timing separately. Three EMA lengths on a daily chart do not establish multi-timeframe agreement.

Verify the calculation before comparing results

Compare the three EMA values and Data Window state with the rule table on selected historical bars, then observe a developing bar through its close. This page supplies a specification and indicator code; it does not report a backtest.

  • Test strict equality and conflicting comparisons as neutral cases.
  • Use one frozen definition when comparing a strategy with and without the filter. Do not change the definition to remove losses after seeing them.
  • A volume spike or a green cloud does not identify the buyer. Keep claims about participants separate from price-derived indicators.
Where Pineify fits

Pine Script AI Coding Agent

Adapt the stated calculation, inputs and confirmation rule into a Pine Script draft, then inspect the result on your chart.

Explore custom indicator coding

Frequently asked questions

Educational examples, not investment advice or tested trading strategies. Indicators describe supplied historical and developing prices. Syntax validation does not establish profitability or live execution.

Sources and verification