本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
//@version=4
// Volatility Stop MTF
// v1.0, 2020.01.27
// This code may be reused freely, without permission.
// It was written using the following standards:
// • PineCoders Coding Conventions for Pine: http://www.pinecoders.com/coding_conventions/
// • PineCoders MTF Selection Framework: https://www.tradingview.com/script/90mqACUV-MTF-Selection-Framework-PineCoders-FAQ/
study("Volatility Stop MTF", "VStop MTF", true, linktoseries = true)
// ———————————————————— Inputs
// {
vCS0 = "Lime/Red", vCS1 = "Aqua/Pink"
vST0 = "Line", vST1 = "Circles", vST2 = "Diamonds", vST3 = "Arrows"
vTF0 = "0. None.", vTF1 = "1. Discrete Steps (60min, 1D, 3D, 1W, 1M, 12M)", vTF2 = "2. Multiple Of Current TF", vTF3 = "3. Fixed TF"
vSrc = input(close, "Source")
vLength = input(20, "Length", minval = 2)
vFactorATR = input(2.0, "ATR Factor", minval = 0.25, step = 0.25)
vColScheme = input(vCS1, "Color Scheme", options = [vCS0, vCS1])
vStyle = input(vST0, "Style", options = [vST0, vST1, vST2, vST3])
vThickness = input(2, "Line Thickness", options = [0, 1, 2, 3])
vColorBars = input(false, "Color bars on trend state")
_2 = input(true, "═════════ HTF Seletion ══════════")
vHtfType = input(vTF2, "Higher Timeframe Selection", options=[vTF0, vTF1, vTF2, vTF3])
vHtfType2 = input(3., " 2. Multiple of Current TF", minval = 1)
vHtfType3 = input("D", " 3. Fixed TF", type = input.resolution)
vHtfStops = input(true, "Early Breaches by chart bars")
vHtfBreachesMrkr = input(true, " Show Early Breaches")
vHtfBreachedBars = input(false, " Color bars in limbo")
vHtfBreachedBg = input(false, " Highlight background in limbo")
vHtfRepaints = input(false, "Repainting HTF")
vHtfShow = input(false, "Show HTF Used")
vOffsetLabels = input(3, "Label Offset")
var vDefaultScheme = vColScheme == vCS0
var vShowCircles = vStyle == vST1
var vShowDiamonds = vStyle == vST2
var vShowArrows = vStyle == vST3
var vHtfOn = vHtfType != vTF0
// }
// ———————————————————— Functions
// {
// —————————— Volatility Stop Function
f_vStop(_src, _atrLength, _atrFactor) =>
var _max = _src
var _min = _src
var _trendUp = true
var _stop = 0.0
_atrM = nz(atr(_atrLength) * _atrFactor, tr)
_max := max(_max, _src)
_min := min(_min, _src)
_stop := nz(_trendUp ? max(_stop, _max - _atrM) : min(_stop, _min + _atrM), _src)
_trendUp := _src - _stop >= 0.0
if _trendUp != nz(_trendUp[1], true)
_max := _src
_min := _src
_stop := _trendUp ? _max - _atrM : _min + _atrM
[_stop, _trendUp]
// —————————— PineCoders MTF Selection Framework functions
// ————— Converts current "timeframe.multiplier" plus the TF into minutes of type float.
f_resInMinutes() =>
_resInMinutes = timeframe.multiplier * (
timeframe.isseconds ? 1. / 60. :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 1440. :
timeframe.isweekly ? 10080. :
timeframe.ismonthly ? 43800. : na)
// ————— Returns resolution of _resolution period in minutes.
f_tfResInMinutes(_resolution) =>
// _resolution: resolution of any TF (in "timeframe.period" string format).
security(syminfo.tickerid, _resolution, f_resInMinutes())
// ————— Given current resolution, returns next step of HTF.
f_resNextStep(_res) =>
// _res: current TF in fractional minutes.
_res <= 1 ? "60" :
_res <= 60 ? "1D" :
_res <= 360 ? "3D" :
_res <= 1440 ? "1W" :
_res <= 10080 ? "1M" : "12M"
// ————— Returns a multiple of current resolution as a string in "timeframe.period" format usable with "security()".
f_multipleOfRes(_res, _mult) =>
// _res: current resolution in minutes, in the fractional format supplied by f_resInMinutes() companion function.
// _mult: Multiple of current TF to be calculated.
// Convert current float TF in minutes to target string TF in "timeframe.period" format.
_targetResInMin = _res * max(_mult, 1)
// Find best string to express the resolution.
_targetResInMin <= 0.083 ? "5S" :
_targetResInMin <= 0.251 ? "15S" :
_targetResInMin <= 0.501 ? "30S" :
_targetResInMin <= 1440 ? tostring(round(_targetResInMin)) :
_targetResInMin <= 43800 ? tostring(round(min(_targetResInMin / 1440, 365))) + "D" :
tostring(round(min(_targetResInMin / 43800, 12))) + "M"
// ————— Print a label at end of chart.
f_htfLabel(_txt, _y, _color, _offsetLabels) =>
_t = int(time + (f_resInMinutes() * _offsetLabels * 60000))
// Create the label on the dataset's first bar.
var _lbl = label.new(_t, _y, _txt, xloc.bar_time, yloc.price, #00000000, label.style_none, color.gray, size.large)
if barstate.islast
// Rather than delete and recreate the label on every realtime bar update,
// simply update the label's information; it's more efficient.
label.set_xy(_lbl, _t, _y)
label.set_text(_lbl, _txt)
label.set_textcolor(_lbl, _color)
// }
// ———————————————————— Calcs
// {
// ————— HTF calcs
// Get current resolution in float minutes.
var vResInMinutes = f_resInMinutes()
// Get HTF from user-defined mode.
var vHtf = vHtfType == vTF1 ? f_resNextStep(vResInMinutes) : vHtfType == vTF2 ? f_multipleOfRes(vResInMinutes, vHtfType2) : vHtfType3
// If current res is not lower than HTF, print warning at right of chart.
if vHtfOn and vResInMinutes >= f_tfResInMinutes(vHtf)
f_htfLabel("Chart\nresolution\nmust be < " + vHtf, sma(high + 3 * tr, 10)[1], color.silver, vOffsetLabels)
else
// Show calculated HTF when needed.
if vHtfOn and vHtfShow
f_htfLabel(vHtf, sma(high + 3 * tr, 10)[1], color.silver, vOffsetLabels)
// ————— VStop calcs
[vStopChartTf, vTrendUpChartTf] = f_vStop(vSrc, vLength, vFactorATR)
vStop = not vHtfOn ? vStopChartTf : vHtfRepaints ? security(syminfo.tickerid, vHtf, vStopChartTf) : security(syminfo.tickerid, vHtf, vStopChartTf[1], lookahead = barmerge.lookahead_on)
vTrendUp = not vHtfOn ? vTrendUpChartTf : vHtfRepaints ? security(syminfo.tickerid, vHtf, vTrendUpChartTf) : security(syminfo.tickerid, vHtf, vTrendUpChartTf[1], lookahead = barmerge.lookahead_on)
var vInLimbo = false
vHtfBreach = vHtfOn and vHtfStops and not vInLimbo and cross(close, vStop)
vTrendReversal = vTrendUp != vTrendUp[1]
vInLimbo := (vInLimbo or vHtfBreach) and vTrendUp == vTrendUp[1]
// }
// ———————————————————— Plots
// {
// ————— Coloring
var cGreen = #00FF00ff, var cGreenDark = #00FF0080
var cRed = #FF0000ff, var cRedDark = #FF0000b0
var cAqua = #00C0FFff, var cAquaDark = #00C0FF80
var cPink = #FF0080ff, var cPinkDark = #FF008080
var cOrange = #FF8000ff, var cOrangeDark = #FF8000d0
vColorUp = vInLimbo ? vDefaultScheme ? cGreenDark : cAquaDark : vDefaultScheme ? cGreen : cAqua
vColorDown = vInLimbo ? vDefaultScheme ? cRedDark : cPinkDark : vDefaultScheme ? cRed : cPink
vColor = vInLimbo ? vDefaultScheme ? vTrendUp ? cGreenDark : cRedDark : vTrendUp ? cAquaDark : cPinkDark : vDefaultScheme ? vTrendUp ? cGreen : cRed : vTrendUp ? cAqua : cPink
vColorLine = vTrendReversal or vHtfBreach ? #00000000 : vColor
// ————— Plotting
// Diamonds and arrows
plotshape(vShowDiamonds or vShowCircles ? vStop : na, "Diamonds & Circles", vShowDiamonds ? shape.diamond : shape.circle, location.absolute, vColor)
plotchar(vShowArrows and vTrendUp ? vStop : na, "Arrows Up", "⮝", location.absolute, vColorUp)
plotchar(vShowArrows and not vTrendUp ? vStop : na, "Arrows Dn", "⮟", location.absolute, vColorDown)
// Line and beginning circles
plot(vThickness != 0 ? vStop : na, "V-Stop", vColorLine, vThickness)
plot(vTrendReversal ? vStop : na, "Beg. Circle", vColor, max(vThickness, 1) + 2, plot.style_circles)
plot(vTrendReversal ? vStop : na, "Beg. Small circle", #000000ff, max(vThickness, 1), plot.style_circles)
// Early breaches
vEarlyBreachUp = vHtfBreach and not vTrendReversal and vTrendUp
vEarlyBreachDn = vHtfBreach and not vTrendReversal and not vTrendUp
plotshape(vHtfBreachesMrkr and vEarlyBreachUp, "HTF Trend Up BReached", shape.triangledown, location.abovebar, cRed, size = size.tiny)
plotshape(vHtfBreachesMrkr and vEarlyBreachDn, "HTF Trend Down Breached", shape.triangleup, location.belowbar, cRed, size = size.tiny)
// Bars
vBarUp = close > open
barcolor(vHtfBreachedBars and vInLimbo ? vBarUp ? cOrange : cOrangeDark : not vColorBars ? na : vTrendUp ? vBarUp ? cGreen : cGreenDark : vBarUp ? cRed : cRedDark)
// Background
bgcolor(vHtfBreachedBg and vInLimbo ? color.silver : na, transp = 90)
// }
// ————— Alerts
alertcondition(vTrendReversal, "1. V-Stop Trend Reversal", "V-Stop Trend Reversal")
alertcondition(vTrendUp and not vTrendUp[1], "2. V-Stop Trend Up", "V-Stop In Up Trend")
alertcondition(not vTrendUp and vTrendUp[1], "3. V-Stop Trend Down", "V-Stop In Down Trend")
alertcondition(vEarlyBreachUp, "4. V-Stop HTF Trend Up Breach", "V-Stop HTF Up Trend Breached")
alertcondition(vEarlyBreachDn, "5. V-Stop HTF Trend Down Breach", "V-Stop HTF Dn Trend Breached")