EMAの乖離率を表示するインジケーター

TradingView用のメモ

//@version=6
indicator("Multi EMA 乖離率|数値+乖離バンド", overlay=true, precision=4)

// ====== 基本設定 ======
src       = input.source(close, "計算に使う価格")
len9      = input.int(9,   "EMA 9",   minval=1)
len20     = input.int(20,  "EMA 20",  minval=1)
len75     = input.int(75,  "EMA 75",  minval=1)
len200    = input.int(200, "EMA 200", minval=1)
smoothLen = input.int(1, "平滑化(乖離率にEMA適用)", minval=1)

// ====== 表示設定(メインチャート) ======
grpShow   = "表示オプション"
showEMA9      = input.bool(false, "EMA9 を描画",  group=grpShow)
showEMA20     = input.bool(false, "EMA20 を描画", group=grpShow)
showEMA75     = input.bool(false, "EMA75 を描画", group=grpShow)
showEMA200    = input.bool(false, "EMA200 を描画", group=grpShow)

showBand9     = input.bool(true, "9EMA ±閾値バンド",   group=grpShow)
showBand20    = input.bool(true, "20EMA ±閾値バンド",  group=grpShow)
showBand75    = input.bool(false,"75EMA ±閾値バンド",  group=grpShow)
showBand200   = input.bool(false,"200EMA ±閾値バンド", group=grpShow)

fillBand      = input.bool(true, "バンド間に塗りつぶし", group=grpShow)

showActual9   = input.bool(false,"実際の乖離ライン(9EMAに沿う)",  group=grpShow, tooltip="価格とEMA9の現在乖離をEMA上に重ねる")
showActual20  = input.bool(false,"実際の乖離ライン(20EMAに沿う)", group=grpShow)
showActual75  = input.bool(false,"実際の乖離ライン(75EMAに沿う)", group=grpShow)
showActual200 = input.bool(false,"実際の乖離ライン(200EMAに沿う)",group=grpShow)

// ====== 時間足グループ判定 ======
var string tfGroup = ""
if timeframe.isminutes
    if timeframe.multiplier <= 1
        tfGroup := "M1"
    else if timeframe.multiplier <= 5
        tfGroup := "M5"
    else if timeframe.multiplier <= 15
        tfGroup := "M15"
    else if timeframe.multiplier <= 60
        tfGroup := "H1"
    else if timeframe.multiplier <= 240
        tfGroup := "H4"
    else
        tfGroup := "D1"
else if timeframe.isdaily
    tfGroup := "D1"
else if timeframe.isweekly
    tfGroup := "D1"
else
    tfGroup := "D1"

// ====== 閾値入力(+側のみ、−側は自動反転) ======
group9   = "9EMA しきい値(+%)"
tp9_M1   = input.float(1.0000, "M1",  step=0.0001, group=group9)
tp9_M5   = input.float(0.0500, "M5",  step=0.0001, group=group9)
tp9_M15  = input.float(2.0000, "M15", step=0.0001, group=group9)
tp9_H1   = input.float(2.5000, "H1",  step=0.0001, group=group9)
tp9_H4   = input.float(3.0000, "H4",  step=0.0001, group=group9)
tp9_D1   = input.float(3.5000, "D1",  step=0.0001, group=group9)

group20  = "20EMA しきい値(+%)"
tp20_M1  = input.float(1.0000, "M1",  step=0.0001, group=group20)
tp20_M5  = input.float(0.0500, "M5",  step=0.0001, group=group20)
tp20_M15 = input.float(2.0000, "M15", step=0.0001, group=group20)
tp20_H1  = input.float(2.5000, "H1",  step=0.0001, group=group20)
tp20_H4  = input.float(3.0000, "H4",  step=0.0001, group=group20)
tp20_D1  = input.float(3.5000, "D1",  step=0.0001, group=group20)

group75  = "75EMA しきい値(+%)"
tp75_M1  = input.float(1.0000, "M1",  step=0.0001, group=group75)
tp75_M5  = input.float(0.1000, "M5",  step=0.0001, group=group75)
tp75_M15 = input.float(2.0000, "M15", step=0.0001, group=group75)
tp75_H1  = input.float(2.5000, "H1",  step=0.0001, group=group75)
tp75_H4  = input.float(3.0000, "H4",  step=0.0001, group=group75)
tp75_D1  = input.float(3.5000, "D1",  step=0.0001, group=group75)

group200 = "200EMA しきい値(+%)"
tp200_M1  = input.float(1.0000, "M1",  step=0.0001, group=group200)
tp200_M5  = input.float(0.2000, "M5",  step=0.0001, group=group200)
tp200_M15 = input.float(2.0000, "M15", step=0.0001, group=group200)
tp200_H1  = input.float(2.5000, "H1",  step=0.0001, group=group200)
tp200_H4  = input.float(3.0000, "H4",  step=0.0001, group=group200)
tp200_D1  = input.float(3.5000, "D1",  step=0.0001, group=group200)

// ====== 閾値選択(現在の時間足に応じて) ======
f_pick(pos_M1, pos_M5, pos_M15, pos_H1, pos_H4, pos_D1) =>
    float r = na
    if tfGroup == "M1"
        r := pos_M1
    else if tfGroup == "M5"
        r := pos_M5
    else if tfGroup == "M15"
        r := pos_M15
    else if tfGroup == "H1"
        r := pos_H1
    else if tfGroup == "H4"
        r := pos_H4
    else
        r := pos_D1
    r

tp9   = f_pick(tp9_M1,   tp9_M5,   tp9_M15,   tp9_H1,   tp9_H4,   tp9_D1)
tp20  = f_pick(tp20_M1,  tp20_M5,  tp20_M15,  tp20_H1,  tp20_H4,  tp20_D1)
tp75  = f_pick(tp75_M1,  tp75_M5,  tp75_M15,  tp75_H1,  tp75_H4,  tp75_D1)
tp200 = f_pick(tp200_M1, tp200_M5, tp200_M15, tp200_H1, tp200_H4, tp200_D1)

tn9   = -tp9
tn20  = -tp20
tn75  = -tp75
tn200 = -tp200

// ====== EMA計算 ======
ema9   = ta.ema(src, len9)
ema20  = ta.ema(src, len20)
ema75  = ta.ema(src, len75)
ema200 = ta.ema(src, len200)

// ====== 乖離率(%)計算(必要なら平滑化) ======
f_smooth(val, len) =>
    float out = val
    if (len > 1)
        out := ta.ema(val, len)
    out

k9   = (src / ema9   - 1) * 100.0
k20  = (src / ema20  - 1) * 100.0
k75  = (src / ema75  - 1) * 100.0
k200 = (src / ema200 - 1) * 100.0

k9s   = f_smooth(k9,   smoothLen)
k20s  = f_smooth(k20,  smoothLen)
k75s  = f_smooth(k75,  smoothLen)
k200s = f_smooth(k200, smoothLen)

// ====== 色分け(過熱は濃色、順行は薄色) ======
f_color(val, pos, neg) =>
    color c = na
    if (val >= pos)
        c := color.new(color.red, 0)
    else if (val <= neg)
        c := color.new(color.blue, 0)
    else if (val >= 0)
        c := color.new(color.red, 40)
    else
        c := color.new(color.blue, 40)
    c

col9   = f_color(k9s,   tp9,   tn9)
col20  = f_color(k20s,  tp20,  tn20)
col75  = f_color(k75s,  tp75,  tn75)
col200 = f_color(k200s, tp200, tn200)

// ====== バンド(EMA × (1 ± 閾値/100))と実乖離ライン ======
upper9  = ema9   * (1 + tp9/100.0)
lower9  = ema9   * (1 + tn9/100.0)
upper20 = ema20  * (1 + tp20/100.0)
lower20 = ema20  * (1 + tn20/100.0)
upper75 = ema75  * (1 + tp75/100.0)
lower75 = ema75  * (1 + tn75/100.0)
upper200= ema200 * (1 + tp200/100.0)
lower200= ema200 * (1 + tn200/100.0)

// 実際の乖離ライン(EMAに現在の乖離率を乗せた線)
act9    = ema9   * (1 + k9s  /100.0)
act20   = ema20  * (1 + k20s /100.0)
act75   = ema75  * (1 + k75s /100.0)
act200  = ema200 * (1 + k200s/100.0)

// ====== 描画 ======
// EMA本体
plot(showEMA9   ? ema9   : na, "EMA9",   color=color.new(color.purple,  0), linewidth=2)
plot(showEMA20  ? ema20  : na, "EMA20",  color=color.new(color.blue,    0), linewidth=2)
plot(showEMA75  ? ema75  : na, "EMA75",  color=color.new(color.red,     0), linewidth=2)
plot(showEMA200 ? ema200 : na, "EMA200", color=color.new(color.green,   0), linewidth=2)

// ±閾値バンド(ライン)
p9u  = plot(showBand9  ? upper9  : na, "9 +Th",  color=color.new(color.red,  0))
p9l  = plot(showBand9  ? lower9  : na, "9 -Th",  color=color.new(color.blue, 0))
p20u = plot(showBand20 ? upper20 : na, "20 +Th", color=color.new(color.red,  0))
p20l = plot(showBand20 ? lower20 : na, "20 -Th", color=color.new(color.blue, 0))
p75u = plot(showBand75 ? upper75 : na, "75 +Th", color=color.new(color.red,  0))
p75l = plot(showBand75 ? lower75 : na, "75 -Th", color=color.new(color.blue, 0))
p200u= plot(showBand200? upper200: na, "200 +Th",color=color.new(color.red,  0))
p200l= plot(showBand200? lower200: na, "200 -Th",color=color.new(color.blue, 0))

// ===== バンド塗りつぶし(fillはグローバルで呼ぶ。色でON/OFF) =====
color bandFillCol = na
if fillBand
    bandFillCol := color.new(color.gray, 92)

// 9/20/75/200 の各バンドを常にfill呼び出し(色がnaなら描かれない)
fill(p9u,   p9l,   color=bandFillCol)
fill(p20u,  p20l,  color=bandFillCol)
fill(p75u,  p75l,  color=bandFillCol)
fill(p200u, p200l, color=bandFillCol)

// 実際の乖離ライン
plot(showActual9   ? act9   : na, "9 実乖離",   color=color.new(color.aqua,  0))
plot(showActual20  ? act20  : na, "20 実乖離",  color=color.new(color.aqua,  0))
plot(showActual75  ? act75  : na, "75 実乖離",  color=color.new(color.aqua,  0))
plot(showActual200 ? act200 : na, "200 実乖離", color=color.new(color.aqua,  0))

// ====== テーブル(右上:数値&閾値 4桁表示) ======
var table tbl = table.new(position.top_right, 5, 3, border_width=1)
if barstate.islast
    table.cell(tbl, 0, 0, "EMA",  text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 1, 0, "9",    text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 2, 0, "20",   text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 3, 0, "75",   text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 4, 0, "200",  text_color=color.white, bgcolor=color.black)

    table.cell(tbl, 0, 1, "乖離%", text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 1, 1, str.tostring(k9s,   "#.####") + "%",  bgcolor=col9)
    table.cell(tbl, 2, 1, str.tostring(k20s,  "#.####") + "%",  bgcolor=col20)
    table.cell(tbl, 3, 1, str.tostring(k75s,  "#.####") + "%",  bgcolor=col75)
    table.cell(tbl, 4, 1, str.tostring(k200s, "#.####") + "%",  bgcolor=col200)

    table.cell(tbl, 0, 2, "Th±%", text_color=color.white, bgcolor=color.black)
    table.cell(tbl, 1, 2, "+" + str.tostring(tp9,   "#.####") + "% / " + str.tostring(tn9,   "#.####") + "%")
    table.cell(tbl, 2, 2, "+" + str.tostring(tp20,  "#.####") + "% / " + str.tostring(tn20,  "#.####") + "%")
    table.cell(tbl, 3, 2, "+" + str.tostring(tp75,  "#.####") + "% / " + str.tostring(tn75,  "#.####") + "%")
    table.cell(tbl, 4, 2, "+" + str.tostring(tp200, "#.####") + "% / " + str.tostring(tn200, "#.####") + "%")

コメント

タイトルとURLをコピーしました