PROTECTED SOURCE SCRIPT
tp 11 (TP11FE.)

//version=6
indicator("อินดี้ tp 11 (TP11FE)", overlay=true, scale=scale.right, max_lines_count=500, max_labels_count=500)
//================ Inputs ================
group200 = "EMA200 / 5up-5down"
emaLen200 = input.int(200, "EMA length (ฐาน EMA200)", minval=1, group=group200)
show200Mid = input.bool(true, "แสดง EMA200 (midline)", group=group200)
show200_5u = input.bool(true, "แสดง 5up (จาก EMA200)", group=group200)
show200_5d = input.bool(true, "แสดง 5down (จาก EMA200)", group=group200)
group85 = "EMA85 (เฉพาะ 4 up / 4 down)"
emaLen85 = input.int(85, "EMA length สำหรับเส้น 4up/4down", minval=1, group=group85)
show85_4u = input.bool(true, "แสดง EMA85 — 4 up", group=group85)
show85_4d = input.bool(true, "แสดง EMA85 — 4 down", group=group85)
group35 = "EMA35"
emaLen35 = input.int(35, "EMA35 length", minval=1, group=group35)
showEMA35 = input.bool(true, "แสดง EMA35", group=group35)
groupPNR = "PNR (Percentile Nearest Rank)"
pnrLen = input.int(15, "PNR length (จำนวนแท่งในหน้าต่าง)", minval=1, group=groupPNR)
pnrPerc = input.int(50, "PNR Percentile (0–100)", minval=0, maxval=100, group=groupPNR)
pnrSrc = input.source(close, "PNR Source", group=groupPNR)
showPNR = input.bool(true, "แสดงเส้น PNR", group=groupPNR)
groupDSI = "Dynamic Structure Indicator (DSI)"
showDSI = input.bool(true, "แสดง DSI (โซน S/R ไดนามิก)", group=groupDSI)
atrMovement = input.float(1.0, "ATR Movement Required", step=0.5, group=groupDSI)
lookback = input.int(25, "High/Low Lookback", step=5, group=groupDSI)
maxZoneSize = input.float(2.5, "Max Zone Size (เทียบกับ ATR)", step=0.5, group=groupDSI)
newStructureReset = input.int(25, "Zone Update Count Before Reset", step=5, group=groupDSI)
drawPreviousStructure = input.bool(true, "Draw Previous Structure (RS/SR)", group=groupDSI)
groupFE = "FE Settings"
feLenBars = input.int(35, "FE length (bars) จาก P3", minval=5, group=groupFE)
feLife = input.int(500, "อายุเส้น FE (bars) ก่อนลบ", minval=50, group=groupFE)
showFE = input.bool(true, "แสดงเส้น FE", group=groupFE)
colBand = input.color(color.teal, "สีเส้น 95/105", group=groupFE)
colBandFill = input.color(color.new(color.teal, 85), "สีแถบ 95–105", group=groupFE)
col1618 = input.color(color.orange, "สีเส้น 161.8", group=groupFE)
col2618 = input.color(color.fuchsia, "สีเส้น 261.8", group=groupFE)
groupP1P2P3 = "Options for P1/P2/P3"
p1Lookback = input.int(200, "กรอบย้อนซ้ายสูงสุดสำหรับหา P1", minval=20, group=groupP1P2P3)
useCloseForEMA35 = input.bool(false, "EMA35 ใช้ close (แทน effClose)", group=groupP1P2P3)
groupPerf = "Performance / Safety"
p3MaxWindowBars = input.int(600, "จำกัดจำนวนแท่งสูงสุดที่สแกนหา P3", minval=100, maxval=2000, step=50, group=groupPerf)
//================ Colors ================
colMid200 = color.rgb(100, 50, 0)
col5band = color.rgb(200,170, 0)
col85_4 = color.rgb(90, 140, 230)
col35 = color.new(color.blue, 0)
colPNR = color.rgb(255, 17, 0)
//================ Core helpers ================
float effClose = close >= open ? math.max(open, close) : math.min(open, close)
f_bodyTop(_o, _c) => math.max(_o, _c)
f_bodyBot(_o, _c) => math.min(_o, _c)
f_midBody_at(_i) =>
float bt = f_bodyTop(open[_i], close[_i])
float bb = f_bodyBot(open[_i], close[_i])
(bt + bb) / 2.0
f_core(_len) =>
float mid = ta.ema(effClose, _len)
float _dev = ta.stdev(effClose, _len)
float devS = _dev == 0.0 ? na : _dev
float plus = na(mid) or na(devS) ? na : (close > mid ? (close - mid) / devS : 0.0)
float minus = na(mid) or na(devS) ? na : (close < mid ? (mid - close) / devS : 0.0)
float mmax = na(plus) or na(minus) ? na : math.max(plus, minus)
float lm = ta.ema(mmax, _len)
[mid, devS, lm]
//================ EMA200 + 5up/5down ================
[mid200, dev200, lm200] = f_core(emaLen200)
phi_adj = 1.38196601
float fiveUp_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 + (lm200 * phi_adj) * dev200
float fiveDown_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 - (lm200 * phi_adj) * dev200
plot(show200_5d ? fiveDown_200 : na, title="5down (EMA200)", color=col5band, linewidth=3)
plot(show200Mid ? mid200 : na, title="EMA200 (midline)", color=colMid200, linewidth=3)
plot(show200_5u ? fiveUp_200 : na, title="5up (EMA200)", color=col5band, linewidth=3)
//================ EMA85 — เฉพาะ 4up/4down ================
[mid85, dev85, lm85] = f_core(emaLen85)
float up4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 + lm85 * dev85
float down4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 - lm85 * dev85
plot(show85_4u ? up4_85 : na, title="EMA85 — 4 up", color=col85_4, linewidth=2)
plot(show85_4d ? down4_85 : na, title="EMA85 — 4 down", color=col85_4, linewidth=2)
//================ EMA35 ========================
float ema35 = useCloseForEMA35 ? ta.ema(close, emaLen35) : ta.ema(effClose, emaLen35)
plot(showEMA35 ? ema35 : na, title="EMA35", color=col35, linewidth=2)
//================ PNR ==========================
float pnr = na
if bar_index >= pnrLen - 1
float[] win = array.new_float()
for i = 0 to pnrLen - 1
array.push(win, pnrSrc)
array.sort(win)
int idx = int(math.round(pnrPerc / 100.0 * pnrLen)) - 1
idx := idx < 0 ? 0 : (idx > pnrLen - 1 ? pnrLen - 1 : idx)
pnr := array.get(win, idx)
plot(showPNR ? pnr : na, title="PNR", color=colPNR, linewidth=2)
//==================== P1 / P2 / P3 + FE ====================//
// ---------- Utilities ----------
isGreen_at(i) => close > open
isRed_at(i) => close < open
bodyTop_at(i) => f_bodyTop(open, close)
bodyBot_at(i) => f_bodyBot(open, close)
aboveEMA75_at(i) =>
float bt = bodyTop_at(i), bb = bodyBot_at(i), midv = mid200
float body = bt - bb
body <= 0 ? (bt >= midv) : ((bt - math.max(bb, midv)) / body >= 0.75)
belowEMA75_at(i) =>
float bt = bodyTop_at(i), bb = bodyBot_at(i), midv = mid200
float body = bt - bb
body <= 0 ? (bb <= midv) : ((math.min(bt, midv) - bb) / body >= 0.75)
// ------- ตรวจ P2 (Long) ที่ offset i -------
isP2Long_at(i) =>
bool hasRoom = (bar_index >= 4) and (i >= 2)
bool green = isGreen_at(i)
float fu = fiveUp_200
float bb = bodyBot_at(i)
bool bodyAbove5 = not na(fu) and bb >= fu
float M2 = f_midBody_at(i)
bool leftOK = close[i+1] <= M2 and close[i+2] <= M2
bool rightOK = close[i-1] <= M2 and close[i-2] <= M2
hasRoom and green and bodyAbove5 and leftOK and rightOK
// ------- ตรวจ P2 (Short) ที่ offset i -------
isP2Short_at(i) =>
bool hasRoom = (bar_index >= 4) and (i >= 2)
bool red = isRed_at(i)
float fd = fiveDown_200
float bt = bodyTop_at(i)
bool bodyBelow5 = not na(fd) and bt <= fd
float M2s = f_midBody_at(i)
bool leftOK = close[i+1] >= M2s and close[i+2] >= M2s
bool rightOK = close[i-1] >= M2s and close[i-2] >= M2s
hasRoom and red and bodyBelow5 and leftOK and rightOK
// ------- หา P1 จากสตรีค (Long) โดยใช้ offset ของ P2 -------
f_findP1_long_rel(p2Off) =>
int maxOff = math.min(p2Off + p1Lookback, 5000)
int foundRight = na
for i = p2Off to maxOff
if isGreen_at(i) and aboveEMA75_at(i)
foundRight := i
break
if na(foundRight)
int loBar = p2Off
float loVal = bodyBot_at(p2Off)
for i = p2Off to maxOff
float v = bodyBot_at(i)
if v < loVal
loVal := v
loBar := i
[open[loBar], loBar]
else
int j = foundRight
while j < 5000 and isGreen_at(j+1) and aboveEMA75_at(j+1)
j += 1
[open[j], j]
// ------- หา P1 (Short) โดยใช้ offset ของ P2 -------
f_findP1_short_rel(p2Off) =>
int maxOff = math.min(p2Off + p1Lookback, 5000)
int foundRight = na
for i = p2Off to maxOff
if isRed_at(i) and belowEMA75_at(i)
foundRight := i
break
if na(foundRight)
int hiBar = p2Off
float hiVal = bodyTop_at(p2Off)
for i = p2Off to maxOff
float v = bodyTop_at(i)
if v > hiVal
hiVal := v
hiBar := i
[open[hiBar], hiBar]
else
int j = foundRight
while j < 5000 and isRed_at(j+1) and belowEMA75_at(j+1)
j += 1
[open[j], j]
// ------- เลือก P3 ภายในหน้าต่าง (offset ช่วง start..end; step บวกเสมอ) -------
f_bin(v) => math.round(v / syminfo.mintick) * syminfo.mintick
f_pickP3_window(winStartOff, winEndOff, isLong) =>
// --- Normalize window ---
int s0 = math.min(winStartOff, winEndOff)
int e0 = math.max(winStartOff, winEndOff)
// --- Clamp to Pine's history limit (0..10000) และไม่เกินจำนวนแท่งที่มีอยู่ ---
int eCap = math.min(e0, math.min(10000, bar_index))
int sMin = math.max(0, s0)
// --- จำกัดความกว้างหน้าต่างตาม p3MaxWindowBars ---
int sTmp = math.max(eCap - p3MaxWindowBars + 1, sMin)
int s = math.max(0, math.min(sTmp, eCap))
int e = eCap
// ถ้า window กลายเป็นว่าง ให้คืนค่า na
if e < 0 or s > e
[na, na]
else
float[] levels = array.new_float()
int[] counts = array.new_int()
int[] firstI = array.new_int()
int[] maxRun = array.new_int()
float minOpen = open
int minIdx = s
float maxOpen = open
int maxIdx = s
float prevBin = na
int curRun = 0
for t = s to e
float bin = f_bin(open[t])
int idx = array.indexof(levels, bin)
if idx == -1
array.push(levels, bin)
array.push(counts, 1)
array.push(firstI, t)
array.push(maxRun, 1)
curRun := 1
else
array.set(counts, idx, array.get(counts, idx) + 1)
if not na(prevBin) and bin == prevBin
curRun += 1
else
curRun := 1
int prevMax = array.get(maxRun, idx)
if curRun > prevMax
array.set(maxRun, idx, curRun)
if open[t] < minOpen
minOpen := open[t]
minIdx := t
if open[t] > maxOpen
maxOpen := open[t]
maxIdx := t
prevBin := bin
// หา cluster ≥ 3
int best = na
int bestCnt = 0
int bestRun = 0
int bestFirst = na
int L = array.size(levels)
if L > 0
for m = 0 to L - 1
int c = array.get(counts, m)
if c >= 3
int r = array.get(maxRun, m)
int f = array.get(firstI, m)
if c > bestCnt or (c == bestCnt and (r > bestRun or (r == bestRun and f < bestFirst)))
best := m
bestCnt := c
bestRun := r
bestFirst := f
if not na(best)
int pickOff = array.get(firstI, best)
[open[pickOff], pickOff]
else
if isLong
[open[minIdx], minIdx]
else
[open[maxIdx], maxIdx]
// --------- สถานะ / ค่าที่ต้องจำ ---------
var int L_stage = 0
var int L_P2Abs = na
var float L_P2Close = na
var float L_M2 = na
var float L_P1Open = na
var int S_stage = 0
var int S_P2Abs = na
var float S_P2Close = na
var float S_M2 = na
var float S_P1Open = na
// --------- FE storage ---------
var line[] FE_l95 = array.new_line()
var line[] FE_l105 = array.new_line()
var line[] FE_l161 = array.new_line()
var line[] FE_l261 = array.new_line()
var linefill[] FE_fill = array.new_linefill()
var int[] FE_born = array.new_int()
f_add_fe_set(p3Abs, y95, y105, y161, y261) =>
int x1 = p3Abs, x2 = p3Abs + feLenBars
line l95 = line.new(x1, y95, x2, y95, xloc=xloc.bar_index, extend=extend.none, color=colBand, width=3)
line l105 = line.new(x1, y105, x2, y105, xloc=xloc.bar_index, extend=extend.none, color=colBand, width=3)
line l161 = line.new(x1, y161, x2, y161, xloc=xloc.bar_index, extend=extend.none, color=col1618, width=2)
line l261 = line.new(x1, y261, x2, y261, xloc=xloc.bar_index, extend=extend.none, color=col2618, width=2)
linefill lf = linefill.new(l95, l105, color=colBandFill)
array.push(FE_l95, l95)
array.push(FE_l105, l105)
array.push(FE_l161, l161)
array.push(FE_l261, l261)
array.push(FE_fill, lf)
array.push(FE_born, p3Abs)
f_delete_fe_index(idx) =>
linefill.delete(array.get(FE_fill, idx))
line.delete(array.get(FE_l95, idx))
line.delete(array.get(FE_l105, idx))
line.delete(array.get(FE_l161, idx))
line.delete(array.get(FE_l261, idx))
array.remove(FE_l95, idx)
array.remove(FE_l105, idx)
array.remove(FE_l161, idx)
array.remove(FE_l261, idx)
array.remove(FE_fill, idx)
array.remove(FE_born, idx)
// ลบตามอายุ (เดินหน้าแล้วอ้างย้อนกลับ เพื่อเลี่ยง step ติดลบ)
if array.size(FE_born) > 0
int n = array.size(FE_born)
for k = 0 to n - 1
int i = n - 1 - k
int born = array.get(FE_born, i)
if bar_index >= born + feLife
f_delete_fe_index(i)
// --------- เครื่องจักรสถานะ: Long ---------
int candL = 2
if bar_index >= 4 and L_stage == 0
if isP2Long_at(candL)
L_P2Abs := bar_index - candL
L_P2Close := close[candL]
L_M2 := f_midBody_at(candL)
[__p1OpenTmp, __p1BarTmp] = f_findP1_long_rel(candL)
L_P1Open := __p1OpenTmp
L_stage := 1
if L_stage == 1
int p2Ago = bar_index - L_P2Abs
if p2Ago >= 1 and close <= L_M2
L_stage := 2
if L_stage == 2
if isGreen_at(0) and close >= L_M2
int p2Ago = bar_index - L_P2Abs
int wStart = 0
int wEnd = math.max(p2Ago - 1, 0) // ไม่รวมแท่ง P2 เอง
[p3Open, p3Off] = f_pickP3_window(wStart, wEnd, true)
int p3Abs = bar_index - p3Off
float wave = L_P2Close - L_P1Open
if showFE and wave > 0 and not na(p3Open)
float y95 = p3Open + 0.95 * wave
float y105 = p3Open + 1.05 * wave
float y1618 = p3Open + 1.618 * wave
float y2618 = p3Open + 2.618 * wave
f_add_fe_set(p3Abs, y95, y105, y1618, y2618)
L_stage := 0
L_P2Abs := na, L_P2Close := na, L_M2 := na, L_P1Open := na
// --------- เครื่องจักรสถานะ: Short ---------
int candS = 2
if bar_index >= 4 and S_stage == 0
if isP2Short_at(candS)
S_P2Abs := bar_index - candS
S_P2Close := close[candS]
S_M2 := f_midBody_at(candS)
[__p1OpenTmpS, __p1BarTmpS] = f_findP1_short_rel(candS)
S_P1Open := __p1OpenTmpS
S_stage := 1
if S_stage == 1
int p2SAgo = bar_index - S_P2Abs
if p2SAgo >= 1 and close >= S_M2
S_stage := 2
if S_stage == 2
if isRed_at(0) and close <= S_M2
int p2SAgo = bar_index - S_P2Abs
int wStartS = 0
int wEndS = math.max(p2SAgo - 1, 0)
[p3OpenS, p3OffS] = f_pickP3_window(wStartS, wEndS, false)
int p3AbsS = bar_index - p3OffS
float waveS = S_P1Open - S_P2Close
if showFE and waveS > 0 and not na(p3OpenS)
float y95s = p3OpenS - 0.95 * waveS
float y105s = p3OpenS - 1.05 * waveS
float y1618s = p3OpenS - 1.618 * waveS
float y2618s = p3OpenS - 2.618 * waveS
f_add_fe_set(p3AbsS, y95s, y105s, y1618s, y2618s)
S_stage := 0
S_P2Abs := na, S_P2Close := na, S_M2 := na, S_P1Open := na
//==================== DSI (Dynamic Structure Indicator) ====================
float dsi_atr = ta.atr(14)
float dsi_highestBody = open > close ? open : close
float dsi_lowestBody = open > close ? close : open
// ระบุชนิดชัดเจนเพื่อหลีกเลี่ยง NA-type
var float dsi_res1 = na
var float dsi_res2 = na
var float dsi_sup1 = na
var float dsi_sup2 = na
var bool dsi_lookForNewResistance = true
var bool dsi_lookForNewSupport = true
var float dsi_prevRes1 = na
var float dsi_prevRes2 = na
var float dsi_prevSup1 = na
var float dsi_prevSup2 = na
var float dsi_atrSaved = na
var float dsi_potR1 = na
var float dsi_potR2 = na
var float dsi_potS1 = na
var float dsi_potS2 = na
if high[1] == ta.highest(high, lookback) and high < high[1] and dsi_lookForNewResistance
float r1 = high[1]
float hb2 = (open[2] > close[2] ? open[2] : close[2])
float hb1 = (open[1] > close[1] ? open[1] : close[1])
float hb0 = (open > close ? open : close)
float r2 = hb2 > hb1 ? hb2 : (hb0 > hb1 ? hb0 : hb1)
if (r1 - r2) / dsi_atr <= maxZoneSize
dsi_lookForNewResistance := false
dsi_potR1 := r1
dsi_potR2 := r2
dsi_atrSaved := dsi_atr
if low[1] == ta.lowest(low, lookback) and low > low[1] and dsi_lookForNewSupport
float s1 = low[1]
float lb2 = (open[2] > close[2] ? close[2] : open[2])
float lb1 = (open[1] > close[1] ? close[1] : open[1])
float lb0 = (open > close ? close : open)
float s2 = lb2 < lb1 ? lb2 : (lb0 < lb1 ? lb0 : lb1)
if (s2 - s1) / dsi_atr <= maxZoneSize
dsi_lookForNewSupport := false
dsi_potS1 := s1
dsi_potS2 := s2
dsi_atrSaved := dsi_atr
if close > dsi_potR1 and barstate.isconfirmed
dsi_potR1 := na, dsi_potR2 := na
if close < dsi_potS1 and barstate.isconfirmed
dsi_potS1 := na, dsi_potS2 := na
// ยืนยัน RS/SR เมื่อราคาวิ่งผ่านระยะ ATR ตามที่กำหนด
if not na(dsi_potR1) and dsi_potR1 - low >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevRes1 := na(dsi_prevRes1) ? dsi_potR1 : dsi_prevRes1
dsi_prevRes2 := na(dsi_prevRes2) ? dsi_potR2 : dsi_prevRes2
dsi_res1 := dsi_potR1
dsi_res2 := dsi_potR2
dsi_potR1 := na
dsi_potR2 := na
if not na(dsi_potS1) and high - dsi_potS1 >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevSup1 := na(dsi_prevSup1) ? dsi_potS1 : dsi_prevSup1
dsi_prevSup2 := na(dsi_prevSup2) ? dsi_potS2 : dsi_prevSup2
dsi_sup1 := dsi_potS1
dsi_sup2 := dsi_potS2
dsi_potS1 := na
dsi_potS2 := na
var int dsi_supCount = 0
var int dsi_resCount = 0
if close >= dsi_res1 and barstate.isconfirmed
dsi_lookForNewResistance := true
dsi_lookForNewSupport := true
dsi_resCount += 1
if close <= dsi_sup1 and barstate.isconfirmed
dsi_lookForNewSupport := true
dsi_lookForNewResistance := true
dsi_supCount += 1
if (close > dsi_res1 and na(dsi_prevRes1) and barstate.isconfirmed) or na(dsi_prevRes1) or dsi_supCount >= newStructureReset
dsi_prevRes1 := dsi_res1
dsi_prevRes2 := dsi_res2
dsi_supCount := 0
if (close < dsi_sup1 and na(dsi_prevSup1) and barstate.isconfirmed) or na(dsi_prevSup1) or dsi_resCount >= newStructureReset
dsi_prevSup1 := dsi_sup1
dsi_prevSup2 := dsi_sup2
dsi_resCount := 0
if close < dsi_prevRes2 and barstate.isconfirmed
dsi_prevRes1 := na
dsi_prevRes2 := na
if close > dsi_prevSup2 and barstate.isconfirmed
dsi_prevSup1 := na
dsi_prevSup2 := na
dsi_r1plot = plot(showDSI and (dsi_res1 == dsi_res1[1]) ? dsi_res1 : na, color=close >= dsi_res1 ? color.green : color.red, style=plot.style_linebr, title="DSI R1")
dsi_r2plot = plot(showDSI and (dsi_res1 == dsi_res1[1]) ? dsi_res2 : na, color=close >= dsi_res1 ? color.green : color.red, style=plot.style_linebr, title="DSI R2")
fill(dsi_r1plot, dsi_r2plot, color=showDSI ? (close > dsi_res1 ? color.green : color.new(color.red, 50)) : color.new(color.black, 100), title="DSI Resistance Zone")
dsi_s1plot = plot(showDSI and (dsi_sup1 == dsi_sup1[1]) ? dsi_sup1 : na, color=close < dsi_sup1 ? color.red : color.green, style=plot.style_linebr, title="DSI S1")
dsi_s2plot = plot(showDSI and (dsi_sup1 == dsi_sup1[1]) ? dsi_sup2 : na, color=close < dsi_sup1 ? color.red : color.green, style=plot.style_linebr, title="DSI S2")
fill(dsi_s1plot, dsi_s2plot, color=showDSI ? (close < dsi_sup1 ? color.red : color.new(color.green, 50)) : color.new(color.black, 100), title="DSI Support Zone")
dsi_ps1plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1[1]) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup1 : na, color=color.red, style=plot.style_linebr, title="DSI PS1")
dsi_ps2plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1[1]) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup2 : na, color=color.red, style=plot.style_linebr, title="DSI PS2")
fill(dsi_ps1plot, dsi_ps2plot, color=showDSI and drawPreviousStructure ? color.new(color.red, 10) : color.new(color.black, 100), title="DSI Previous Support Zone")
dsi_pr1plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1[1]) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes1 : na, color=color.green, style=plot.style_linebr, title="DSI PR1")
dsi_pr2plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1[1]) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes2 : na, color=color.green, style=plot.style_linebr, title="DSI PR2")
fill(dsi_pr1plot, dsi_pr2plot, color=showDSI and drawPreviousStructure ? color.new(color.green, 10) : color.new(color.black, 100), title="DSI Previous Resistance Zone")
indicator("อินดี้ tp 11 (TP11FE)", overlay=true, scale=scale.right, max_lines_count=500, max_labels_count=500)
//================ Inputs ================
group200 = "EMA200 / 5up-5down"
emaLen200 = input.int(200, "EMA length (ฐาน EMA200)", minval=1, group=group200)
show200Mid = input.bool(true, "แสดง EMA200 (midline)", group=group200)
show200_5u = input.bool(true, "แสดง 5up (จาก EMA200)", group=group200)
show200_5d = input.bool(true, "แสดง 5down (จาก EMA200)", group=group200)
group85 = "EMA85 (เฉพาะ 4 up / 4 down)"
emaLen85 = input.int(85, "EMA length สำหรับเส้น 4up/4down", minval=1, group=group85)
show85_4u = input.bool(true, "แสดง EMA85 — 4 up", group=group85)
show85_4d = input.bool(true, "แสดง EMA85 — 4 down", group=group85)
group35 = "EMA35"
emaLen35 = input.int(35, "EMA35 length", minval=1, group=group35)
showEMA35 = input.bool(true, "แสดง EMA35", group=group35)
groupPNR = "PNR (Percentile Nearest Rank)"
pnrLen = input.int(15, "PNR length (จำนวนแท่งในหน้าต่าง)", minval=1, group=groupPNR)
pnrPerc = input.int(50, "PNR Percentile (0–100)", minval=0, maxval=100, group=groupPNR)
pnrSrc = input.source(close, "PNR Source", group=groupPNR)
showPNR = input.bool(true, "แสดงเส้น PNR", group=groupPNR)
groupDSI = "Dynamic Structure Indicator (DSI)"
showDSI = input.bool(true, "แสดง DSI (โซน S/R ไดนามิก)", group=groupDSI)
atrMovement = input.float(1.0, "ATR Movement Required", step=0.5, group=groupDSI)
lookback = input.int(25, "High/Low Lookback", step=5, group=groupDSI)
maxZoneSize = input.float(2.5, "Max Zone Size (เทียบกับ ATR)", step=0.5, group=groupDSI)
newStructureReset = input.int(25, "Zone Update Count Before Reset", step=5, group=groupDSI)
drawPreviousStructure = input.bool(true, "Draw Previous Structure (RS/SR)", group=groupDSI)
groupFE = "FE Settings"
feLenBars = input.int(35, "FE length (bars) จาก P3", minval=5, group=groupFE)
feLife = input.int(500, "อายุเส้น FE (bars) ก่อนลบ", minval=50, group=groupFE)
showFE = input.bool(true, "แสดงเส้น FE", group=groupFE)
colBand = input.color(color.teal, "สีเส้น 95/105", group=groupFE)
colBandFill = input.color(color.new(color.teal, 85), "สีแถบ 95–105", group=groupFE)
col1618 = input.color(color.orange, "สีเส้น 161.8", group=groupFE)
col2618 = input.color(color.fuchsia, "สีเส้น 261.8", group=groupFE)
groupP1P2P3 = "Options for P1/P2/P3"
p1Lookback = input.int(200, "กรอบย้อนซ้ายสูงสุดสำหรับหา P1", minval=20, group=groupP1P2P3)
useCloseForEMA35 = input.bool(false, "EMA35 ใช้ close (แทน effClose)", group=groupP1P2P3)
groupPerf = "Performance / Safety"
p3MaxWindowBars = input.int(600, "จำกัดจำนวนแท่งสูงสุดที่สแกนหา P3", minval=100, maxval=2000, step=50, group=groupPerf)
//================ Colors ================
colMid200 = color.rgb(100, 50, 0)
col5band = color.rgb(200,170, 0)
col85_4 = color.rgb(90, 140, 230)
col35 = color.new(color.blue, 0)
colPNR = color.rgb(255, 17, 0)
//================ Core helpers ================
float effClose = close >= open ? math.max(open, close) : math.min(open, close)
f_bodyTop(_o, _c) => math.max(_o, _c)
f_bodyBot(_o, _c) => math.min(_o, _c)
f_midBody_at(_i) =>
float bt = f_bodyTop(open[_i], close[_i])
float bb = f_bodyBot(open[_i], close[_i])
(bt + bb) / 2.0
f_core(_len) =>
float mid = ta.ema(effClose, _len)
float _dev = ta.stdev(effClose, _len)
float devS = _dev == 0.0 ? na : _dev
float plus = na(mid) or na(devS) ? na : (close > mid ? (close - mid) / devS : 0.0)
float minus = na(mid) or na(devS) ? na : (close < mid ? (mid - close) / devS : 0.0)
float mmax = na(plus) or na(minus) ? na : math.max(plus, minus)
float lm = ta.ema(mmax, _len)
[mid, devS, lm]
//================ EMA200 + 5up/5down ================
[mid200, dev200, lm200] = f_core(emaLen200)
phi_adj = 1.38196601
float fiveUp_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 + (lm200 * phi_adj) * dev200
float fiveDown_200 = na(mid200) or na(dev200) or na(lm200) ? na : mid200 - (lm200 * phi_adj) * dev200
plot(show200_5d ? fiveDown_200 : na, title="5down (EMA200)", color=col5band, linewidth=3)
plot(show200Mid ? mid200 : na, title="EMA200 (midline)", color=colMid200, linewidth=3)
plot(show200_5u ? fiveUp_200 : na, title="5up (EMA200)", color=col5band, linewidth=3)
//================ EMA85 — เฉพาะ 4up/4down ================
[mid85, dev85, lm85] = f_core(emaLen85)
float up4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 + lm85 * dev85
float down4_85 = na(mid85) or na(dev85) or na(lm85) ? na : mid85 - lm85 * dev85
plot(show85_4u ? up4_85 : na, title="EMA85 — 4 up", color=col85_4, linewidth=2)
plot(show85_4d ? down4_85 : na, title="EMA85 — 4 down", color=col85_4, linewidth=2)
//================ EMA35 ========================
float ema35 = useCloseForEMA35 ? ta.ema(close, emaLen35) : ta.ema(effClose, emaLen35)
plot(showEMA35 ? ema35 : na, title="EMA35", color=col35, linewidth=2)
//================ PNR ==========================
float pnr = na
if bar_index >= pnrLen - 1
float[] win = array.new_float()
for i = 0 to pnrLen - 1
array.push(win, pnrSrc)
array.sort(win)
int idx = int(math.round(pnrPerc / 100.0 * pnrLen)) - 1
idx := idx < 0 ? 0 : (idx > pnrLen - 1 ? pnrLen - 1 : idx)
pnr := array.get(win, idx)
plot(showPNR ? pnr : na, title="PNR", color=colPNR, linewidth=2)
//==================== P1 / P2 / P3 + FE ====================//
// ---------- Utilities ----------
isGreen_at(i) => close > open
isRed_at(i) => close < open
bodyTop_at(i) => f_bodyTop(open, close)
bodyBot_at(i) => f_bodyBot(open, close)
aboveEMA75_at(i) =>
float bt = bodyTop_at(i), bb = bodyBot_at(i), midv = mid200
float body = bt - bb
body <= 0 ? (bt >= midv) : ((bt - math.max(bb, midv)) / body >= 0.75)
belowEMA75_at(i) =>
float bt = bodyTop_at(i), bb = bodyBot_at(i), midv = mid200
float body = bt - bb
body <= 0 ? (bb <= midv) : ((math.min(bt, midv) - bb) / body >= 0.75)
// ------- ตรวจ P2 (Long) ที่ offset i -------
isP2Long_at(i) =>
bool hasRoom = (bar_index >= 4) and (i >= 2)
bool green = isGreen_at(i)
float fu = fiveUp_200
float bb = bodyBot_at(i)
bool bodyAbove5 = not na(fu) and bb >= fu
float M2 = f_midBody_at(i)
bool leftOK = close[i+1] <= M2 and close[i+2] <= M2
bool rightOK = close[i-1] <= M2 and close[i-2] <= M2
hasRoom and green and bodyAbove5 and leftOK and rightOK
// ------- ตรวจ P2 (Short) ที่ offset i -------
isP2Short_at(i) =>
bool hasRoom = (bar_index >= 4) and (i >= 2)
bool red = isRed_at(i)
float fd = fiveDown_200
float bt = bodyTop_at(i)
bool bodyBelow5 = not na(fd) and bt <= fd
float M2s = f_midBody_at(i)
bool leftOK = close[i+1] >= M2s and close[i+2] >= M2s
bool rightOK = close[i-1] >= M2s and close[i-2] >= M2s
hasRoom and red and bodyBelow5 and leftOK and rightOK
// ------- หา P1 จากสตรีค (Long) โดยใช้ offset ของ P2 -------
f_findP1_long_rel(p2Off) =>
int maxOff = math.min(p2Off + p1Lookback, 5000)
int foundRight = na
for i = p2Off to maxOff
if isGreen_at(i) and aboveEMA75_at(i)
foundRight := i
break
if na(foundRight)
int loBar = p2Off
float loVal = bodyBot_at(p2Off)
for i = p2Off to maxOff
float v = bodyBot_at(i)
if v < loVal
loVal := v
loBar := i
[open[loBar], loBar]
else
int j = foundRight
while j < 5000 and isGreen_at(j+1) and aboveEMA75_at(j+1)
j += 1
[open[j], j]
// ------- หา P1 (Short) โดยใช้ offset ของ P2 -------
f_findP1_short_rel(p2Off) =>
int maxOff = math.min(p2Off + p1Lookback, 5000)
int foundRight = na
for i = p2Off to maxOff
if isRed_at(i) and belowEMA75_at(i)
foundRight := i
break
if na(foundRight)
int hiBar = p2Off
float hiVal = bodyTop_at(p2Off)
for i = p2Off to maxOff
float v = bodyTop_at(i)
if v > hiVal
hiVal := v
hiBar := i
[open[hiBar], hiBar]
else
int j = foundRight
while j < 5000 and isRed_at(j+1) and belowEMA75_at(j+1)
j += 1
[open[j], j]
// ------- เลือก P3 ภายในหน้าต่าง (offset ช่วง start..end; step บวกเสมอ) -------
f_bin(v) => math.round(v / syminfo.mintick) * syminfo.mintick
f_pickP3_window(winStartOff, winEndOff, isLong) =>
// --- Normalize window ---
int s0 = math.min(winStartOff, winEndOff)
int e0 = math.max(winStartOff, winEndOff)
// --- Clamp to Pine's history limit (0..10000) และไม่เกินจำนวนแท่งที่มีอยู่ ---
int eCap = math.min(e0, math.min(10000, bar_index))
int sMin = math.max(0, s0)
// --- จำกัดความกว้างหน้าต่างตาม p3MaxWindowBars ---
int sTmp = math.max(eCap - p3MaxWindowBars + 1, sMin)
int s = math.max(0, math.min(sTmp, eCap))
int e = eCap
// ถ้า window กลายเป็นว่าง ให้คืนค่า na
if e < 0 or s > e
[na, na]
else
float[] levels = array.new_float()
int[] counts = array.new_int()
int[] firstI = array.new_int()
int[] maxRun = array.new_int()
float minOpen = open
int minIdx = s
float maxOpen = open
int maxIdx = s
float prevBin = na
int curRun = 0
for t = s to e
float bin = f_bin(open[t])
int idx = array.indexof(levels, bin)
if idx == -1
array.push(levels, bin)
array.push(counts, 1)
array.push(firstI, t)
array.push(maxRun, 1)
curRun := 1
else
array.set(counts, idx, array.get(counts, idx) + 1)
if not na(prevBin) and bin == prevBin
curRun += 1
else
curRun := 1
int prevMax = array.get(maxRun, idx)
if curRun > prevMax
array.set(maxRun, idx, curRun)
if open[t] < minOpen
minOpen := open[t]
minIdx := t
if open[t] > maxOpen
maxOpen := open[t]
maxIdx := t
prevBin := bin
// หา cluster ≥ 3
int best = na
int bestCnt = 0
int bestRun = 0
int bestFirst = na
int L = array.size(levels)
if L > 0
for m = 0 to L - 1
int c = array.get(counts, m)
if c >= 3
int r = array.get(maxRun, m)
int f = array.get(firstI, m)
if c > bestCnt or (c == bestCnt and (r > bestRun or (r == bestRun and f < bestFirst)))
best := m
bestCnt := c
bestRun := r
bestFirst := f
if not na(best)
int pickOff = array.get(firstI, best)
[open[pickOff], pickOff]
else
if isLong
[open[minIdx], minIdx]
else
[open[maxIdx], maxIdx]
// --------- สถานะ / ค่าที่ต้องจำ ---------
var int L_stage = 0
var int L_P2Abs = na
var float L_P2Close = na
var float L_M2 = na
var float L_P1Open = na
var int S_stage = 0
var int S_P2Abs = na
var float S_P2Close = na
var float S_M2 = na
var float S_P1Open = na
// --------- FE storage ---------
var line[] FE_l95 = array.new_line()
var line[] FE_l105 = array.new_line()
var line[] FE_l161 = array.new_line()
var line[] FE_l261 = array.new_line()
var linefill[] FE_fill = array.new_linefill()
var int[] FE_born = array.new_int()
f_add_fe_set(p3Abs, y95, y105, y161, y261) =>
int x1 = p3Abs, x2 = p3Abs + feLenBars
line l95 = line.new(x1, y95, x2, y95, xloc=xloc.bar_index, extend=extend.none, color=colBand, width=3)
line l105 = line.new(x1, y105, x2, y105, xloc=xloc.bar_index, extend=extend.none, color=colBand, width=3)
line l161 = line.new(x1, y161, x2, y161, xloc=xloc.bar_index, extend=extend.none, color=col1618, width=2)
line l261 = line.new(x1, y261, x2, y261, xloc=xloc.bar_index, extend=extend.none, color=col2618, width=2)
linefill lf = linefill.new(l95, l105, color=colBandFill)
array.push(FE_l95, l95)
array.push(FE_l105, l105)
array.push(FE_l161, l161)
array.push(FE_l261, l261)
array.push(FE_fill, lf)
array.push(FE_born, p3Abs)
f_delete_fe_index(idx) =>
linefill.delete(array.get(FE_fill, idx))
line.delete(array.get(FE_l95, idx))
line.delete(array.get(FE_l105, idx))
line.delete(array.get(FE_l161, idx))
line.delete(array.get(FE_l261, idx))
array.remove(FE_l95, idx)
array.remove(FE_l105, idx)
array.remove(FE_l161, idx)
array.remove(FE_l261, idx)
array.remove(FE_fill, idx)
array.remove(FE_born, idx)
// ลบตามอายุ (เดินหน้าแล้วอ้างย้อนกลับ เพื่อเลี่ยง step ติดลบ)
if array.size(FE_born) > 0
int n = array.size(FE_born)
for k = 0 to n - 1
int i = n - 1 - k
int born = array.get(FE_born, i)
if bar_index >= born + feLife
f_delete_fe_index(i)
// --------- เครื่องจักรสถานะ: Long ---------
int candL = 2
if bar_index >= 4 and L_stage == 0
if isP2Long_at(candL)
L_P2Abs := bar_index - candL
L_P2Close := close[candL]
L_M2 := f_midBody_at(candL)
[__p1OpenTmp, __p1BarTmp] = f_findP1_long_rel(candL)
L_P1Open := __p1OpenTmp
L_stage := 1
if L_stage == 1
int p2Ago = bar_index - L_P2Abs
if p2Ago >= 1 and close <= L_M2
L_stage := 2
if L_stage == 2
if isGreen_at(0) and close >= L_M2
int p2Ago = bar_index - L_P2Abs
int wStart = 0
int wEnd = math.max(p2Ago - 1, 0) // ไม่รวมแท่ง P2 เอง
[p3Open, p3Off] = f_pickP3_window(wStart, wEnd, true)
int p3Abs = bar_index - p3Off
float wave = L_P2Close - L_P1Open
if showFE and wave > 0 and not na(p3Open)
float y95 = p3Open + 0.95 * wave
float y105 = p3Open + 1.05 * wave
float y1618 = p3Open + 1.618 * wave
float y2618 = p3Open + 2.618 * wave
f_add_fe_set(p3Abs, y95, y105, y1618, y2618)
L_stage := 0
L_P2Abs := na, L_P2Close := na, L_M2 := na, L_P1Open := na
// --------- เครื่องจักรสถานะ: Short ---------
int candS = 2
if bar_index >= 4 and S_stage == 0
if isP2Short_at(candS)
S_P2Abs := bar_index - candS
S_P2Close := close[candS]
S_M2 := f_midBody_at(candS)
[__p1OpenTmpS, __p1BarTmpS] = f_findP1_short_rel(candS)
S_P1Open := __p1OpenTmpS
S_stage := 1
if S_stage == 1
int p2SAgo = bar_index - S_P2Abs
if p2SAgo >= 1 and close >= S_M2
S_stage := 2
if S_stage == 2
if isRed_at(0) and close <= S_M2
int p2SAgo = bar_index - S_P2Abs
int wStartS = 0
int wEndS = math.max(p2SAgo - 1, 0)
[p3OpenS, p3OffS] = f_pickP3_window(wStartS, wEndS, false)
int p3AbsS = bar_index - p3OffS
float waveS = S_P1Open - S_P2Close
if showFE and waveS > 0 and not na(p3OpenS)
float y95s = p3OpenS - 0.95 * waveS
float y105s = p3OpenS - 1.05 * waveS
float y1618s = p3OpenS - 1.618 * waveS
float y2618s = p3OpenS - 2.618 * waveS
f_add_fe_set(p3AbsS, y95s, y105s, y1618s, y2618s)
S_stage := 0
S_P2Abs := na, S_P2Close := na, S_M2 := na, S_P1Open := na
//==================== DSI (Dynamic Structure Indicator) ====================
float dsi_atr = ta.atr(14)
float dsi_highestBody = open > close ? open : close
float dsi_lowestBody = open > close ? close : open
// ระบุชนิดชัดเจนเพื่อหลีกเลี่ยง NA-type
var float dsi_res1 = na
var float dsi_res2 = na
var float dsi_sup1 = na
var float dsi_sup2 = na
var bool dsi_lookForNewResistance = true
var bool dsi_lookForNewSupport = true
var float dsi_prevRes1 = na
var float dsi_prevRes2 = na
var float dsi_prevSup1 = na
var float dsi_prevSup2 = na
var float dsi_atrSaved = na
var float dsi_potR1 = na
var float dsi_potR2 = na
var float dsi_potS1 = na
var float dsi_potS2 = na
if high[1] == ta.highest(high, lookback) and high < high[1] and dsi_lookForNewResistance
float r1 = high[1]
float hb2 = (open[2] > close[2] ? open[2] : close[2])
float hb1 = (open[1] > close[1] ? open[1] : close[1])
float hb0 = (open > close ? open : close)
float r2 = hb2 > hb1 ? hb2 : (hb0 > hb1 ? hb0 : hb1)
if (r1 - r2) / dsi_atr <= maxZoneSize
dsi_lookForNewResistance := false
dsi_potR1 := r1
dsi_potR2 := r2
dsi_atrSaved := dsi_atr
if low[1] == ta.lowest(low, lookback) and low > low[1] and dsi_lookForNewSupport
float s1 = low[1]
float lb2 = (open[2] > close[2] ? close[2] : open[2])
float lb1 = (open[1] > close[1] ? close[1] : open[1])
float lb0 = (open > close ? close : open)
float s2 = lb2 < lb1 ? lb2 : (lb0 < lb1 ? lb0 : lb1)
if (s2 - s1) / dsi_atr <= maxZoneSize
dsi_lookForNewSupport := false
dsi_potS1 := s1
dsi_potS2 := s2
dsi_atrSaved := dsi_atr
if close > dsi_potR1 and barstate.isconfirmed
dsi_potR1 := na, dsi_potR2 := na
if close < dsi_potS1 and barstate.isconfirmed
dsi_potS1 := na, dsi_potS2 := na
// ยืนยัน RS/SR เมื่อราคาวิ่งผ่านระยะ ATR ตามที่กำหนด
if not na(dsi_potR1) and dsi_potR1 - low >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevRes1 := na(dsi_prevRes1) ? dsi_potR1 : dsi_prevRes1
dsi_prevRes2 := na(dsi_prevRes2) ? dsi_potR2 : dsi_prevRes2
dsi_res1 := dsi_potR1
dsi_res2 := dsi_potR2
dsi_potR1 := na
dsi_potR2 := na
if not na(dsi_potS1) and high - dsi_potS1 >= (nz(dsi_atrSaved, dsi_atr) * atrMovement)
dsi_prevSup1 := na(dsi_prevSup1) ? dsi_potS1 : dsi_prevSup1
dsi_prevSup2 := na(dsi_prevSup2) ? dsi_potS2 : dsi_prevSup2
dsi_sup1 := dsi_potS1
dsi_sup2 := dsi_potS2
dsi_potS1 := na
dsi_potS2 := na
var int dsi_supCount = 0
var int dsi_resCount = 0
if close >= dsi_res1 and barstate.isconfirmed
dsi_lookForNewResistance := true
dsi_lookForNewSupport := true
dsi_resCount += 1
if close <= dsi_sup1 and barstate.isconfirmed
dsi_lookForNewSupport := true
dsi_lookForNewResistance := true
dsi_supCount += 1
if (close > dsi_res1 and na(dsi_prevRes1) and barstate.isconfirmed) or na(dsi_prevRes1) or dsi_supCount >= newStructureReset
dsi_prevRes1 := dsi_res1
dsi_prevRes2 := dsi_res2
dsi_supCount := 0
if (close < dsi_sup1 and na(dsi_prevSup1) and barstate.isconfirmed) or na(dsi_prevSup1) or dsi_resCount >= newStructureReset
dsi_prevSup1 := dsi_sup1
dsi_prevSup2 := dsi_sup2
dsi_resCount := 0
if close < dsi_prevRes2 and barstate.isconfirmed
dsi_prevRes1 := na
dsi_prevRes2 := na
if close > dsi_prevSup2 and barstate.isconfirmed
dsi_prevSup1 := na
dsi_prevSup2 := na
dsi_r1plot = plot(showDSI and (dsi_res1 == dsi_res1[1]) ? dsi_res1 : na, color=close >= dsi_res1 ? color.green : color.red, style=plot.style_linebr, title="DSI R1")
dsi_r2plot = plot(showDSI and (dsi_res1 == dsi_res1[1]) ? dsi_res2 : na, color=close >= dsi_res1 ? color.green : color.red, style=plot.style_linebr, title="DSI R2")
fill(dsi_r1plot, dsi_r2plot, color=showDSI ? (close > dsi_res1 ? color.green : color.new(color.red, 50)) : color.new(color.black, 100), title="DSI Resistance Zone")
dsi_s1plot = plot(showDSI and (dsi_sup1 == dsi_sup1[1]) ? dsi_sup1 : na, color=close < dsi_sup1 ? color.red : color.green, style=plot.style_linebr, title="DSI S1")
dsi_s2plot = plot(showDSI and (dsi_sup1 == dsi_sup1[1]) ? dsi_sup2 : na, color=close < dsi_sup1 ? color.red : color.green, style=plot.style_linebr, title="DSI S2")
fill(dsi_s1plot, dsi_s2plot, color=showDSI ? (close < dsi_sup1 ? color.red : color.new(color.green, 50)) : color.new(color.black, 100), title="DSI Support Zone")
dsi_ps1plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1[1]) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup1 : na, color=color.red, style=plot.style_linebr, title="DSI PS1")
dsi_ps2plot = plot(showDSI and drawPreviousStructure and (dsi_prevSup1 == dsi_prevSup1[1]) and (dsi_prevSup1 != dsi_sup1) ? dsi_prevSup2 : na, color=color.red, style=plot.style_linebr, title="DSI PS2")
fill(dsi_ps1plot, dsi_ps2plot, color=showDSI and drawPreviousStructure ? color.new(color.red, 10) : color.new(color.black, 100), title="DSI Previous Support Zone")
dsi_pr1plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1[1]) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes1 : na, color=color.green, style=plot.style_linebr, title="DSI PR1")
dsi_pr2plot = plot(showDSI and drawPreviousStructure and (dsi_prevRes1 == dsi_prevRes1[1]) and (dsi_prevRes1 != dsi_res1) ? dsi_prevRes2 : na, color=color.green, style=plot.style_linebr, title="DSI PR2")
fill(dsi_pr1plot, dsi_pr2plot, color=showDSI and drawPreviousStructure ? color.new(color.green, 10) : color.new(color.black, 100), title="DSI Previous Resistance Zone")
Korumalı komut dosyası
Bu komut dosyası kapalı kaynak olarak yayınlanmaktadır. Ancak, özgürce ve herhangi bir sınırlama olmaksızın kullanabilirsiniz – daha fazla bilgi burada.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, işlem veya diğer türden tavsiye veya tavsiyeler anlamına gelmez ve teşkil etmez. Kullanım Şartları'nda daha fazlasını okuyun.
Korumalı komut dosyası
Bu komut dosyası kapalı kaynak olarak yayınlanmaktadır. Ancak, özgürce ve herhangi bir sınırlama olmaksızın kullanabilirsiniz – daha fazla bilgi burada.
Feragatname
Bilgiler ve yayınlar, TradingView tarafından sağlanan veya onaylanan finansal, yatırım, işlem veya diğer türden tavsiye veya tavsiyeler anlamına gelmez ve teşkil etmez. Kullanım Şartları'nda daha fazlasını okuyun.