// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=6
indicator("Blues v0.1.0", overlay=true, max_lines_count=500, max_labels_count=500)

// Chart-Signale
blauer_punkt_long  = input.source(title="Blauer Punkt Long",  defval=close, group="Chart-Signale")
blauer_punkt_short = input.source(title="Blauer Punkt Short", defval=close, group="Chart-Signale")

// Wolkenstatus
wolke_g = input.source(title="Wolke (1) Grün", defval=close, group="Lochstreifen")
wolke_r = input.source(title="Wolke (3) Rot",  defval=close, group="Lochstreifen")

// Anzeige
label_offset_mult = input.float(3.0, title="Label-Abstand (ATR x)", minval=0.1, step=0.1, group="Darstellung")

// ========= Basics =========
atr      = ta.atr(16)
g_active = (wolke_g > 0)
r_active = (wolke_r > 0)

// ========= Helper: steigende Flanke (series float/bool robust) =========
f_rise(sig) =>
    // true, wenn das Signal JETZT neu > 0 ist, vorher aber nicht
    cond_now  = (not na(sig)) and (sig > 0)
    cond_prev = na(sig[1]) or (sig[1] <= 0)
    cond_now and cond_prev

// ========= Zonen-Tracking =========
var int   g_zoneStart   = na
var float g_zoneHigh    = na
g_switch = barstate.isfirst ? true : (g_active != g_active[1])
if bar_index == 0 or g_switch
    g_zoneStart := bar_index
    g_zoneHigh  := na
g_inZone        = g_active and bar_index >= g_zoneStart
g_zoneHigh_prev = g_zoneHigh
if g_inZone
    if na(g_zoneHigh) or high > g_zoneHigh
        g_zoneHigh := high

var int   r_zoneStart = na
var float r_zoneLow   = na
r_switch = barstate.isfirst ? true : (r_active != r_active[1])
if bar_index == 0 or r_switch
    r_zoneStart := bar_index
    r_zoneLow   := na
r_inZone       = r_active and bar_index >= r_zoneStart
r_zoneLow_prev = r_zoneLow
if r_inZone
    if na(r_zoneLow) or low < r_zoneLow
        r_zoneLow := low

// ========= Blue-Trigger & Startbedingungen =========
long_blue_now  = g_inZone and f_rise(blauer_punkt_short)
short_blue_now = r_inZone and f_rise(blauer_punkt_long)
long_start_ok  = long_blue_now  and not na(g_zoneHigh_prev)
short_start_ok = short_blue_now and not na(r_zoneLow_prev)

// ========= States, Referenzen, Objekte =========
var bool  long_pending_active   = false
var float long_refHigh          = na
var label startLblLong          = na
var line  longPendingLine       = na

var bool  short_pending_active  = false
var float short_refLow          = na
var label startLblShort         = na
var line  shortPendingLine      = na

// ========= Start (Label + Linie) =========
if long_start_ok and not long_pending_active
    long_pending_active := true
    long_refHigh        := g_zoneHigh_prev
    if high < long_refHigh
        if not na(startLblLong)
            label.delete(startLblLong)
        startLblLong := label.new(bar_index, high + atr * label_offset_mult, "Ein Hoch kommt noch",
                                  xloc=xloc.bar_index, yloc=yloc.price,
                                  style=label.style_label_down, color=color.blue, textcolor=color.white, size=size.normal)
    if not na(longPendingLine)
        line.delete(longPendingLine)
    longPendingLine := line.new(bar_index, long_refHigh, bar_index + 1, long_refHigh, xloc=xloc.bar_index, extend=extend.right, color=color.blue, width=2)

if short_start_ok and not short_pending_active
    short_pending_active := true
    short_refLow         := r_zoneLow_prev
    if low > short_refLow
        if not na(startLblShort)
            label.delete(startLblShort)
        startLblShort := label.new(bar_index, low - atr * label_offset_mult, "Ein Tief kommt noch",
                                   xloc=xloc.bar_index, yloc=yloc.price,
                                   style=label.style_label_up, color=color.blue, textcolor=color.white, size=size.normal)
    if not na(shortPendingLine)
        line.delete(shortPendingLine)
    shortPendingLine := line.new(bar_index, short_refLow, bar_index + 1, short_refLow,
                                 xloc=xloc.bar_index, extend=extend.right, color=color.blue, width=2)

// ========= Erfüllung & Wolkenbruch =========
long_fulfilled_now  = long_pending_active  and high >= long_refHigh
short_fulfilled_now = short_pending_active and low  <= short_refLow
long_cloud_break    = long_pending_active  and not g_active
short_cloud_break   = short_pending_active and not r_active

// ========= Ende & Aufräumen =========
end_long  = long_pending_active  and (long_fulfilled_now  or long_cloud_break)
end_short = short_pending_active and (short_fulfilled_now or short_cloud_break)

if end_long
    if not na(startLblLong)
        label.delete(startLblLong)
        startLblLong := na
    if not na(longPendingLine)
        line.delete(longPendingLine)
        longPendingLine := na
    long_pending_active := false
    long_refHigh := na

if end_short
    if not na(startLblShort)
        label.delete(startLblShort)
        startLblShort := na
    if not na(shortPendingLine)
        line.delete(shortPendingLine)
        shortPendingLine := na
    short_pending_active := false
    short_refLow := na
