//@version=5
// Stochastic (K & D) — Signals Only (no lines)
indicator("Stochastic (K & D) — Signals Only", shorttitle="Stoch KD Signals Only", overlay=true, format=format.price, precision=2)

// ==== Inputs ====
srcOpt      = input.string("close", "Source", options=["close", "hl2", "hlc3", "ohlc4"])
length      = input.int(14, "Length (%K)", minval=1)
smoothK     = input.int(3, "Smooth %K", minval=1)
smoothD     = input.int(3, "Smooth %D", minval=1)
overbought  = input.float(80.0, "Overbought", minval=0, maxval=100)
oversold    = input.float(20.0, "Oversold", minval=0, maxval=100)

useHTF      = input.bool(false, "HTFを使用（上位足で計算）")
htfTF       = input.timeframe("60", "HTFタイムフレーム", confirm=true)

showBuy     = input.bool(true,  "買い候補（%Kが%Dを下から上へ＆%K<oversold）を表示")
showSell    = input.bool(true,  "売り候補（%Kが%Dを上から下へ＆%K>overbought）を表示")
showExit    = input.bool(false, "エグジット候補（%Kが20上抜け／80下抜け）を表示")

// ★ サイズは const 必須のため、選択に応じて分岐描画します
arrowSizeOpt = input.string("small", "矢印サイズ", options=["tiny", "small", "normal", "large", "huge"])
isTiny   = arrowSizeOpt == "tiny"
isSmall  = arrowSizeOpt == "small"
isNormal = arrowSizeOpt == "normal"
isLarge  = arrowSizeOpt == "large"
isHuge   = arrowSizeOpt == "huge"

buyColor    = input.color(color.new(color.lime, 0), "買い矢印の色")
sellColor   = input.color(color.new(color.red,  0), "売り矢印の色")
exitColor   = input.color(color.new(color.gray, 0), "エグジット矢印の色")

// ==== Resolve source ====
float src = switch srcOpt
    "close"  => close
    "hl2"    => (high + low) / 2.0
    "hlc3"   => (high + low + close) / 3.0
    "ohlc4"  => (open + high + low + close) / 4.0
    => close

// ==== HTF handling ====
float baseHigh = useHTF ? request.security(syminfo.tickerid, htfTF, high) : high
float baseLow  = useHTF ? request.security(syminfo.tickerid, htfTF, low)  : low
float baseSrc  = useHTF ? request.security(syminfo.tickerid, htfTF, src)  : src

// ==== Stochastic core（ラインは描画しない）====
ll    = ta.lowest(baseLow,  length)
hh    = ta.highest(baseHigh, length)
denom = math.max(hh - ll, 1e-10)
kRaw  = 100.0 * (baseSrc - ll) / denom
k     = ta.sma(kRaw, smoothK)
d     = ta.sma(k,    smoothD)

// ==== Signals ====
bullCross   = ta.crossover(k, d)
bearCross   = ta.crossunder(k, d)
buySignal   = bullCross and k < oversold
sellSignal  = bearCross and k > overbought

exitLong    = showExit ? ta.crossover(k, 20) : false
exitShort   = showExit ? ta.crossunder(k, 80) : false

// ==== Plot shapes on price chart（ライン類は一切描画しない）====
// Buy
plotshape(showBuy  and buySignal and isTiny,   title="Buy tiny",  style=shape.triangleup,   location=location.belowbar, color=buyColor,  size=size.tiny,   text="Buy")
plotshape(showBuy  and buySignal and isSmall,  title="Buy small", style=shape.triangleup,   location=location.belowbar, color=buyColor,  size=size.small,  text="Buy")
plotshape(showBuy  and buySignal and isNormal, title="Buy normal",style=shape.triangleup,   location=location.belowbar, color=buyColor,  size=size.normal, text="Buy")
plotshape(showBuy  and buySignal and isLarge,  title="Buy large", style=shape.triangleup,   location=location.belowbar, color=buyColor,  size=size.large,  text="Buy")
plotshape(showBuy  and buySignal and isHuge,   title="Buy huge",  style=shape.triangleup,   location=location.belowbar, color=buyColor,  size=size.huge,   text="Buy")

// Sell
plotshape(showSell and sellSignal and isTiny,   title="Sell tiny",  style=shape.triangledown, location=location.abovebar, color=sellColor, size=size.tiny,   text="Sell")
plotshape(showSell and sellSignal and isSmall,  title="Sell small", style=shape.triangledown, location=location.abovebar, color=sellColor, size=size.small,  text="Sell")
plotshape(showSell and sellSignal and isNormal, title="Sell normal",style=shape.triangledown, location=location.abovebar, color=sellColor, size=size.normal, text="Sell")
plotshape(showSell and sellSignal and isLarge,  title="Sell large", style=shape.triangledown, location=location.abovebar, color=sellColor, size=size.large,  text="Sell")
plotshape(showSell and sellSignal and isHuge,   title="Sell huge",  style=shape.triangledown, location=location.abovebar, color=sellColor, size=size.huge,   text="Sell")

// Exit
plotshape(exitLong  and isTiny,   title="Exit L tiny",  style=shape.circle, location=location.abovebar, color=exitColor, size=size.tiny,   text="Exit L")
plotshape(exitLong  and isSmall,  title="Exit L small", style=shape.circle, location=location.abovebar, color=exitColor, size=size.small,  text="Exit L")
plotshape(exitLong  and isNormal, title="Exit L normal",style=shape.circle, location=location.abovebar, color=exitColor, size=size.normal, text="Exit L")
plotshape(exitLong  and isLarge,  title="Exit L large", style=shape.circle, location=location.abovebar, color=exitColor, size=size.large,  text="Exit L")
plotshape(exitLong  and isHuge,   title="Exit L huge",  style=shape.circle, location=location.abovebar, color=exitColor, size=size.huge,   text="Exit L")

plotshape(exitShort and isTiny,   title="Exit S tiny",  style=shape.circle, location=location.belowbar, color=exitColor, size=size.tiny,   text="Exit S")
plotshape(exitShort and isSmall,  title="Exit S small", style=shape.circle, location=location.belowbar, color=exitColor, size=size.small,  text="Exit S")
plotshape(exitShort and isNormal, title="Exit S normal",style=shape.circle, location=location.belowbar, color=exitColor, size=size.normal, text="Exit S")
plotshape(exitShort and isLarge,  title="Exit S large", style=shape.circle, location=location.belowbar, color=exitColor, size=size.large,  text="Exit S")
plotshape(exitShort and isHuge,   title="Exit S huge",  style=shape.circle, location=location.belowbar, color=exitColor, size=size.huge,   text="Exit S")

// ==== Alerts ====
alertcondition(bullCross,    title="Bullish %K cross above %D",  message="Stoch: %K crossed above %D (Bullish)")