OPEN-SOURCE SCRIPT
Swing Stockpicking Dashboard

//version=5
indicator("Swing Stockpicking Dashboard (Mansfield RS + Trend Template)", overlay=true, max_labels_count=500)
// ---------- Inputs ----------
bench = input.symbol("SPY", "Benchmark (para RS)")
rsLen = input.int(252, "52w lookback (barras)", minval=20)
rsMaLen = input.int(252, "RS base MA (barras)", minval=20)
ma50Len = input.int(50, "SMA rápida", minval=1)
ma150Len = input.int(150, "SMA media", minval=1)
ma200Len = input.int(200, "SMA lenta", minval=1)
slopeLookback = input.int(22, "Pendiente MA200 (barras)", minval=1)
scoreThreshold = input.int(5, "Umbral score (0–7)", minval=0, maxval=7)
showMAs = input.bool(true, "Dibujar medias")
showTable = input.bool(true, "Mostrar tabla dashboard")
// ---------- Benchmark & Mansfield RS ----------
benchClose = request.security(bench, timeframe.period, close)
ratio = (benchClose > 0) ? (close / benchClose) : na
rsBase = ta.sma(ratio, rsMaLen)
mansfield = (rsBase != 0 and not na(rsBase)) ? ((ratio / rsBase - 1) * 100) : na
// ---------- Price MAs ----------
ma50 = ta.sma(close, ma50Len)
ma150 = ta.sma(close, ma150Len)
ma200 = ta.sma(close, ma200Len)
// ---------- 52w High/Low ----------
hi52 = ta.highest(high, rsLen)
lo52 = ta.lowest(low, rsLen)
// ---------- Minervini-style checks ----------
c1 = close > ma150 and close > ma200
c2 = ma150 > ma200
c3 = ma200 > ma200[slopeLookback] // MA200 subiendo vs hace ~1 mes (en D)
c4 = ma50 > ma150 and ma50 > ma200
c5 = close >= lo52 * 1.25 // ≥ +25% desde mínimo 52w
c6 = close >= hi52 * 0.75 // dentro del 25% de máximos 52w
c7 = (mansfield > 0) and (mansfield > mansfield[1]) // RS > 0 y mejorando
score = (c1 ? 1 : 0) + (c2 ? 1 : 0) + (c3 ? 1 : 0) + (c4 ? 1 : 0) + (c5 ? 1 : 0) + (c6 ? 1 : 0) + (c7 ? 1 : 0)
qualified = score >= scoreThreshold
// ---------- Plots ----------
if showMAs
plot(ma50, "SMA 50", linewidth=1)
plot(ma150, "SMA 150", linewidth=1)
plot(ma200, "SMA 200", linewidth=2)
plotshape(qualified, title="PICK", style=shape.triangleup, location=location.belowbar, size=size.tiny, text="PICK")
// ---------- Dashboard table ----------
var table t = table.new(position.top_right, 2, 9, frame_width=1)
f_row(_r, _name, _ok) =>
table.cell(t, 0, _r, _name)
table.cell(t, 1, _r, _ok ? "OK" : "—")
if showTable and barstate.islast
table.cell(t, 0, 0, "Check")
table.cell(t, 1, 0, "Pass")
f_row(1, "Price > SMA150 & SMA200", c1)
f_row(2, "SMA150 > SMA200", c2)
f_row(3, "SMA200 rising (" + str.tostring(slopeLookback) + ")", c3)
f_row(4, "SMA50 > SMA150 & SMA200", c4)
f_row(5, "≥ +25% from 52w low", c5)
f_row(6, "Within 25% of 52w high", c6)
f_row(7, "Mansfield RS > 0 & rising", c7)
table.cell(t, 0, 8, "Score")
table.cell(t, 1, 8, str.tostring(score) + "/7")
// ---------- Alerts ----------
alertcondition(qualified, "Qualified stock (PICK)", "El activo supera el score mínimo para stock-picking swing.")
indicator("Swing Stockpicking Dashboard (Mansfield RS + Trend Template)", overlay=true, max_labels_count=500)
// ---------- Inputs ----------
bench = input.symbol("SPY", "Benchmark (para RS)")
rsLen = input.int(252, "52w lookback (barras)", minval=20)
rsMaLen = input.int(252, "RS base MA (barras)", minval=20)
ma50Len = input.int(50, "SMA rápida", minval=1)
ma150Len = input.int(150, "SMA media", minval=1)
ma200Len = input.int(200, "SMA lenta", minval=1)
slopeLookback = input.int(22, "Pendiente MA200 (barras)", minval=1)
scoreThreshold = input.int(5, "Umbral score (0–7)", minval=0, maxval=7)
showMAs = input.bool(true, "Dibujar medias")
showTable = input.bool(true, "Mostrar tabla dashboard")
// ---------- Benchmark & Mansfield RS ----------
benchClose = request.security(bench, timeframe.period, close)
ratio = (benchClose > 0) ? (close / benchClose) : na
rsBase = ta.sma(ratio, rsMaLen)
mansfield = (rsBase != 0 and not na(rsBase)) ? ((ratio / rsBase - 1) * 100) : na
// ---------- Price MAs ----------
ma50 = ta.sma(close, ma50Len)
ma150 = ta.sma(close, ma150Len)
ma200 = ta.sma(close, ma200Len)
// ---------- 52w High/Low ----------
hi52 = ta.highest(high, rsLen)
lo52 = ta.lowest(low, rsLen)
// ---------- Minervini-style checks ----------
c1 = close > ma150 and close > ma200
c2 = ma150 > ma200
c3 = ma200 > ma200[slopeLookback] // MA200 subiendo vs hace ~1 mes (en D)
c4 = ma50 > ma150 and ma50 > ma200
c5 = close >= lo52 * 1.25 // ≥ +25% desde mínimo 52w
c6 = close >= hi52 * 0.75 // dentro del 25% de máximos 52w
c7 = (mansfield > 0) and (mansfield > mansfield[1]) // RS > 0 y mejorando
score = (c1 ? 1 : 0) + (c2 ? 1 : 0) + (c3 ? 1 : 0) + (c4 ? 1 : 0) + (c5 ? 1 : 0) + (c6 ? 1 : 0) + (c7 ? 1 : 0)
qualified = score >= scoreThreshold
// ---------- Plots ----------
if showMAs
plot(ma50, "SMA 50", linewidth=1)
plot(ma150, "SMA 150", linewidth=1)
plot(ma200, "SMA 200", linewidth=2)
plotshape(qualified, title="PICK", style=shape.triangleup, location=location.belowbar, size=size.tiny, text="PICK")
// ---------- Dashboard table ----------
var table t = table.new(position.top_right, 2, 9, frame_width=1)
f_row(_r, _name, _ok) =>
table.cell(t, 0, _r, _name)
table.cell(t, 1, _r, _ok ? "OK" : "—")
if showTable and barstate.islast
table.cell(t, 0, 0, "Check")
table.cell(t, 1, 0, "Pass")
f_row(1, "Price > SMA150 & SMA200", c1)
f_row(2, "SMA150 > SMA200", c2)
f_row(3, "SMA200 rising (" + str.tostring(slopeLookback) + ")", c3)
f_row(4, "SMA50 > SMA150 & SMA200", c4)
f_row(5, "≥ +25% from 52w low", c5)
f_row(6, "Within 25% of 52w high", c6)
f_row(7, "Mansfield RS > 0 & rising", c7)
table.cell(t, 0, 8, "Score")
table.cell(t, 1, 8, str.tostring(score) + "/7")
// ---------- Alerts ----------
alertcondition(qualified, "Qualified stock (PICK)", "El activo supera el score mínimo para stock-picking swing.")
オープンソーススクリプト
TradingViewの精神に則り、このスクリプトの作者はコードをオープンソースとして公開してくれました。トレーダーが内容を確認・検証できるようにという配慮です。作者に拍手を送りましょう!無料で利用できますが、コードの再公開はハウスルールに従う必要があります。
免責事項
この情報および投稿は、TradingViewが提供または推奨する金融、投資、トレード、その他のアドバイスや推奨を意図するものではなく、それらを構成するものでもありません。詳細は利用規約をご覧ください。
オープンソーススクリプト
TradingViewの精神に則り、このスクリプトの作者はコードをオープンソースとして公開してくれました。トレーダーが内容を確認・検証できるようにという配慮です。作者に拍手を送りましょう!無料で利用できますが、コードの再公開はハウスルールに従う必要があります。
免責事項
この情報および投稿は、TradingViewが提供または推奨する金融、投資、トレード、その他のアドバイスや推奨を意図するものではなく、それらを構成するものでもありません。詳細は利用規約をご覧ください。