Allow User to Customize the Number of Recent Pivot to Determine Trend: //@version=5
indicator("Higher Time Frame Trend Detector", overlay=true)

// User Inputs
higher_tf = input.timeframe("D", "Higher Time Frame")
pivot_left = input.int(5, "Pivot Left Bars", minval=1)
pivot_right = input.int(5, "Pivot Right Bars", minval=1)
ma_length = input.int(21, "MA Length")

// Get Higher Time Frame Data
htf_high = request.security(syminfo.tickerid, higher_tf, high)
htf_low = request.security(syminfo.tickerid, higher_tf, low)
htf_close = request.security(syminfo.tickerid, higher_tf, close)
htf_bar_index = request.security(syminfo.tickerid, higher_tf, bar_index)

// Detect Pivots in Higher Time Frame
pivot_high = ta.pivothigh(htf_high, pivot_left, pivot_right)
pivot_low = ta.pivotlow(htf_low, pivot_left, pivot_right)

// Shift pivots by pivot_right bars to align them properly
pivot_high_shifted = pivot_high[pivot_right]
pivot_low_shifted = pivot_low[pivot_right]

// Initialize arrays to store pivots
var string[] pivot_types = array.new_string()
var int[] pivot_bars = array.new_int()
var float[] pivot_values = array.new_float()

// Initialize series variables for pivot highs and lows
var float pivot_high_plot = na
var float pivot_low_plot = na

// Add pivot highs to arrays
if not na(pivot_high_shifted)
    array.unshift(pivot_types, "H")
    array.unshift(pivot_bars, htf_bar_index[pivot_right])
    array.unshift(pivot_values, pivot_high_shifted)
    // Assign pivot_high_shifted to pivot_high_plot for plotting
    pivot_high_plot := pivot_high_shifted
else
    pivot_high_plot := na

// Add pivot lows to arrays
if not na(pivot_low_shifted)
    array.unshift(pivot_types, "L")
    array.unshift(pivot_bars, htf_bar_index[pivot_right])
    array.unshift(pivot_values, pivot_low_shifted)
    // Assign pivot_low_shifted to pivot_low_plot for plotting
    pivot_low_plot := pivot_low_shifted
else
    pivot_low_plot := na

// Limit the size of the arrays to the last 10 pivots to conserve memory
if array.size(pivot_types) > 10
    array.pop(pivot_types)
    array.pop(pivot_bars)
    array.pop(pivot_values)

// Initialize Trend Variable
var string trend = na

// Check if we have at least four pivots to analyze
if array.size(pivot_types) >= 4
    // Extract the last four pivots
    string pivot1_type = array.get(pivot_types, 0)
    float pivot1_value = array.get(pivot_values, 0)
    string pivot2_type = array.get(pivot_types, 1)
    float pivot2_value = array.get(pivot_values, 1)
    string pivot3_type = array.get(pivot_types, 2)
    float pivot3_value = array.get(pivot_values, 2)
    string pivot4_type = array.get(pivot_types, 3)
    float pivot4_value = array.get(pivot_values, 3)
    
    // Define sequences for uptrend and downtrend
    bool is_downtrend_sequence = pivot1_type == "H" and pivot2_type == "L" and pivot3_type == "H" and pivot4_type == "L"
    bool is_uptrend_sequence = pivot1_type == "L" and pivot2_type == "H" and pivot3_type == "L" and pivot4_type == "H"
    
    // Check for Lower Highs and Lower Lows
    bool lower_highs = pivot1_value < pivot3_value
    bool lower_lows = pivot2_value < pivot4_value
    // Check for Higher Highs and Higher Lows
    bool higher_highs = pivot2_value > pivot4_value
    bool higher_lows = pivot1_value > pivot3_value
    
    // Confirm trend with price action crossing pivot levels
    bool price_crossed_below_pivot_low = htf_close < pivot2_value  // For downtrend, price crosses below the recent low
    bool price_crossed_above_pivot_high = htf_close > pivot2_value // For uptrend, price crosses above the recent high
    
    // Determine the trend
    if is_downtrend_sequence and lower_highs and lower_lows and price_crossed_below_pivot_low
        trend := "Downtrend"
    else if is_uptrend_sequence and higher_highs and higher_lows and price_crossed_above_pivot_high
        trend := "Uptrend"
    else
        trend := "Sideways"
else
    trend := "Sideways"

// Display Trend Condition using Table
var table trend_table = table.new(position.top_right, 1, 1)

bgcolor = trend == "Uptrend" ? color.new(color.green, 70) : trend == "Downtrend" ? color.new(color.red, 70) : color.new(color.orange, 70)

// Update the table cell on every bar
table.cell(trend_table, 0, 0, "Trend: " + trend, text_color=color.white, bgcolor=bgcolor)

// Plot the pivot highs and lows outside of any local scope
plot(pivot_high_plot, "Pivot High", color=color.red, style=plot.style_circles, linewidth=2)
plot(pivot_low_plot, "Pivot Low", color=color.lime, style=plot.style_circles, linewidth=2)

// Plot the Moving Average (if you wish to include it)
htf_ma = ta.sma(htf_close, ma_length)
plot(htf_ma, "Higher TF MA", color=color.blue)