Página 1 de 1

Colorear en pine script

Publicado: 05 Nov 2023 20:12
por Gerber
Muy buen día estimados Traders, Soy novato y humildemente pido de su ayuda respecto a un indicador que estoy modificando, este dibuja 5 lineas en forma de canales de regresión, y quiero que el área entre las dos lineas inferiores se coloreen de verde, y el área entre las dos linas superiores se coloreen de rojo; aquí el codigo:

Código: Seleccionar todo

//@version=5

indicator("BETA", shorttitle="BT", overlay=true)


////////////////////////////////Canal Ancho/////////////////////////////////////

src = input(close)

lengthInput = input.int(100, title="Length", minval = 1, maxval = 5000)
sourceInput = input.source(close, title="Source")

group1 = "Channel Settings"
useUpperDevInput = input.bool(true, title="Upper Deviation", inline = "Upper Deviation", group = group1)
upperMultInput = input.float(2, title="", inline = "Upper Deviation", group = group1)
useLowerDevInput = input.bool(true, title="Lower Deviation", inline = "Lower Deviation", group = group1)
lowerMultInput = input.float(2, title="", inline = "Lower Deviation", group = group1)

calcSlope(source, length) =>
    max_bars_back(source, 5000)
    if not barstate.islast or length <= 1
        [float(na), float(na), float(na)]
    else
        sumX = 0.0
        sumY = 0.0
        sumXSqr = 0.0
        sumXY = 0.0
        for i = 0 to length - 1 by 1
            val = source[i]
            per = i + 1.0
            sumX += per
            sumY += val
            sumXSqr += per * per
            sumXY += val * per
        slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
        average = sumY / length
        intercept = average - slope * sumX / length + slope
        [slope, average, intercept]
        
[s, a, i] = calcSlope(sourceInput, lengthInput)
startPrice = i + s * (lengthInput - 1)
endPrice = i
var line baseLine = na
if na(baseLine) and not na(startPrice)
    baseLine := line.new(bar_index - lengthInput + 1, startPrice, bar_index, endPrice, width=1)
else
    line.set_xy1(baseLine, bar_index - lengthInput + 1, startPrice)
    line.set_xy2(baseLine, bar_index, endPrice)
    na
    
calcDev(source, length, slope, average, intercept) =>
    upDev = 0.0
    dnDev = 0.0
    stdDevAcc = 0.0
    dsxx = 0.0
    dsyy = 0.0
    dsxy = 0.0
    periods = length - 1
    daY = intercept + slope * periods / 2
    val = intercept
    for j = 0 to periods by 1
        price = high[j] - val
        if price > upDev
            upDev := price
        price := val - low[j]
        if price > dnDev
            dnDev := price
        price := source[j]
        dxt = price - average
        dyt = val - daY
        price -= val
        stdDevAcc += price * price
        dsxx += dxt * dxt
        dsyy += dyt * dyt
        dsxy += dxt * dyt
        val += slope
    stdDev = math.sqrt(stdDevAcc / (periods == 0 ? 1 : periods))
    pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
    [stdDev, pearsonR, upDev, dnDev]
    
[stdDev, pearsonR, upDev, dnDev] = calcDev(sourceInput, lengthInput, s, a, i)
upperStartPrice = startPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
upperEndPrice = endPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
var line upper = na
lowerStartPrice = startPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
lowerEndPrice = endPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
var line lower = na
if na(upper) and not na(upperStartPrice)
    upper := line.new(bar_index - lengthInput + 1, upperStartPrice, bar_index, upperEndPrice, width=1)
else
    line.set_xy1(upper, bar_index - lengthInput + 1, upperStartPrice)
    line.set_xy2(upper, bar_index, upperEndPrice)
    na
if na(lower) and not na(lowerStartPrice)
    lower := line.new(bar_index - lengthInput + 1, lowerStartPrice, bar_index, lowerEndPrice, width=1)
else
    line.set_xy1(lower, bar_index - lengthInput + 1, lowerStartPrice)
    line.set_xy2(lower, bar_index, lowerEndPrice)
    na


//////////////////////////////////////////Canal Angosto//////////////////////////////////////////////

lengthInput_ = input.int(100, title="Length", minval = 1, maxval = 5000)
sourceInput_ = input.source(close, title="Source")

group2 = "Channel Settings"
useUpperDevInput2 = input.bool(true, title="Upper Deviation", inline = "Upper Deviation", group = group2)
upperMultInput2 = input.float(1, title="", inline = "Upper Deviation", group = group2)
useLowerDevInput2 = input.bool(true, title="Lower Deviation", inline = "Lower Deviation", group = group2)
lowerMultInput2 = input.float(1, title="", inline = "Lower Deviation", group = group2)

calcSlope_(source, length) =>
    max_bars_back(source, 5000)
    if not barstate.islast or length <= 1
        [float(na), float(na), float(na)]
    else
        sumX = 0.0
        sumY = 0.0
        sumXSqr = 0.0
        sumXY = 0.0
        for i = 0 to length - 1 by 1
            val = source[i]
            per = i + 1.0
            sumX += per
            sumY += val
            sumXSqr += per * per
            sumXY += val * per
        slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
        average = sumY / length
        intercept = average - slope * sumX / length + slope
        [slope, average, intercept]
        
[ss, aa, ii] = calcSlope_(sourceInput_, lengthInput_)
startPrice_ = ii + ss * (lengthInput_ - 1)
endPrice_ = ii
var line baseLine_ = na
if na(baseLine_) and not na(startPrice_)
    baseLine_ := line.new(bar_index - lengthInput_ + 1, startPrice_, bar_index, endPrice_, width=1)
else
    line.set_xy1(baseLine_, bar_index - lengthInput_ + 1, startPrice_)
    line.set_xy2(baseLine_, bar_index, endPrice_)
    na
    
calcDev_(source, length, slope, average, intercept) =>
    upDev2 = 0.0
    dnDev2 = 0.0
    stdDevAcc_ = 0.0
    dsxx = 0.0
    dsyy = 0.0
    dsxy = 0.0
    periods = length - 1
    daY = intercept + slope * periods / 2
    val = intercept
    for j = 0 to periods by 1
        price = high[j] - val
        if price > upDev
            upDev2 := price
        price := val - low[j]
        if price > dnDev
            dnDev2 := price
        price := source[j]
        dxt = price - average
        dyt = val - daY
        price -= val
        stdDevAcc_ += price * price
        dsxx += dxt * dxt
        dsyy += dyt * dyt
        dsxy += dxt * dyt
        val += slope
    stdDev2 = math.sqrt(stdDevAcc_ / (periods == 0 ? 1 : periods))
    pearsonR_ = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
    [stdDev2, pearsonR, upDev, dnDev]
    
[stdDev2, pearsonR_, upDev2, dnDev2] = calcDev_(sourceInput_, lengthInput_, ss, aa, ii)
upperStartPrice_ = startPrice_ + (useUpperDevInput2 ? upperMultInput2 * stdDev2 : upDev)
upperEndPrice_ = endPrice_ + (useUpperDevInput2 ? upperMultInput2 * stdDev2 : upDev)
var line upper_ = na
lowerStartPrice_ = startPrice_ + (useLowerDevInput2 ? -lowerMultInput2 * stdDev2 : -dnDev)
lowerEndPrice_ = endPrice_ + (useLowerDevInput2 ? -lowerMultInput2 * stdDev2 : -dnDev)
var line lower_ = na
if na(upper_) and not na(upperStartPrice_)
    upper_ := line.new(bar_index - lengthInput_ + 1, upperStartPrice_, bar_index, upperEndPrice_, width=1)
else
    line.set_xy1(upper_, bar_index - lengthInput_ + 1, upperStartPrice_)
    line.set_xy2(upper_, bar_index, upperEndPrice_)
    na
if na(lower_) and not na(lowerStartPrice_)
    lower_ := line.new(bar_index - lengthInput_ + 1, lowerStartPrice_, bar_index, lowerEndPrice_, width=1)
else
    line.set_xy1(lower_, bar_index - lengthInput_ + 1, lowerStartPrice_)
    line.set_xy2(lower_, bar_index, lowerEndPrice_)
    na
    

Re: Colorear en pine script

Publicado: 06 Nov 2023 13:22
por gu5tavo71
buen día

el codigo está mal posteado, y esto genera multiples errores de indexado
podrias arreglarlo y así podemos analizar tu pregunta?

Re: Colorear en pine script

Publicado: 08 Nov 2023 03:49
por Gerber
Ya esta reparado, imprime solamente cinco lineas por el momento.

Re: Colorear en pine script

Publicado: 08 Nov 2023 12:50
por gu5tavo71
Tu codigo sigue mal posteado

Prueba el editor completo, y "Mostrar codigo"
Imagen

Re: Colorear en pine script

Publicado: 08 Nov 2023 19:04
por Gerber
Perdón por el error, me podrian decir si ya está bien posteado?

Re: Colorear en pine script

Publicado: 09 Nov 2023 13:48
por gu5tavo71
Hola

Para que dos líneas se coloreen, tenes que usar linefill.new()
https://es.tradingview.com/pine-script- ... nefill.new

Ambos objetos (las lineas), deben ser locales. Pero tu código tiene una cadena de if por cada línea, y linefill.new() no funciona así
Hay que agrupar las líneas en un mismo if
algo así:

Código: Seleccionar todo

if na(baseLine) and not na(startPrice)
    baseLine := line.new(bar_index - lengthInput + 1, startPrice, bar_index, endPrice, width=1)
    upper := line.new(bar_index - lengthInput + 1, upperStartPrice, bar_index, upperEndPrice, width=1)
    lower := line.new(bar_index - lengthInput + 1, lowerStartPrice, bar_index, lowerEndPrice, width=1)
    upper_ := line.new(bar_index - lengthInput + 1, upperStartPrice_, bar_index, upperEndPrice_, width=1)
    lower_ := line.new(bar_index - lengthInput + 1, lowerStartPrice_, bar_index, lowerEndPrice_, width=1)
    linefill.new(upper_, upper, color.new(color.green, 50))
    linefill.new(lower, lower_, color.new(color.red, 50))
else
    line.set_xy1(baseLine, bar_index - lengthInput + 1, startPrice)
    line.set_xy2(baseLine, bar_index, endPrice)
    line.set_xy1(upper, bar_index - lengthInput + 1, upperStartPrice)
    line.set_xy2(upper, bar_index, upperEndPrice)
    line.set_xy1(lower, bar_index - lengthInput + 1, lowerStartPrice)
    line.set_xy2(lower, bar_index, lowerEndPrice)
    line.set_xy1(upper_, bar_index - lengthInput + 1, upperStartPrice_)
    line.set_xy2(upper_, bar_index, upperEndPrice_)
    line.set_xy1(lower_, bar_index - lengthInput + 1, lowerStartPrice_)
    line.set_xy2(lower_, bar_index, lowerEndPrice_)
    na

Re: Colorear en pine script

Publicado: 09 Nov 2023 13:51
por gu5tavo71
Por otro lado, va un consejo

DRY significa “Don't repeat yourself”. Es uno de los principios del buen desarrollo de software que nos recomienda no repetir código. Es un fundamento básico, que se aplica a cualquier lenguaje de programación.
En Pine Script, creamos nuestras propias funciones, para no repetir código.
Entonces, si ya tenemos la función calcSlope()calcDev(), no tiene sentido repetirla
Con una sola función, podemos hacer una línea, o tres líneas, o cinco líneas modificando un solo parámetro. En este caso, el multiplicador.

El código limpio, sin repetir codigo es este:

Código: Seleccionar todo

//@version=5
indicator("BETA", shorttitle="BT", overlay=true)


src = input(close)

lengthInput = input.int(100, title="Length", minval = 1, maxval = 5000)
sourceInput = input.source(close, title="Source")

group1 = "Channel Settings"
useUpperDevInput = input.bool(true, title="Upper Deviation", inline = "Upper Deviation", group = group1)
upperMultInput = input.float(2, title="", inline = "Upper Deviation", group = group1)
useLowerDevInput = input.bool(true, title="Lower Deviation", inline = "Lower Deviation", group = group1)
lowerMultInput = input.float(2, title="", inline = "Lower Deviation", group = group1)

calcSlope(source, length) =>
    max_bars_back(source, 5000)
    if not barstate.islast or length <= 1
        [float(na), float(na), float(na)]
    else
        sumX = 0.0
        sumY = 0.0
        sumXSqr = 0.0
        sumXY = 0.0
        for i = 0 to length - 1 by 1
            val = source[i]
            per = i + 1.0
            sumX += per
            sumY += val
            sumXSqr += per * per
            sumXY += val * per
        slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
        average = sumY / length
        intercept = average - slope * sumX / length + slope
        [slope, average, intercept]

calcDev(source, length, slope, average, intercept) =>
    upDev = 0.0
    dnDev = 0.0
    stdDevAcc = 0.0
    dsxx = 0.0
    dsyy = 0.0
    dsxy = 0.0
    periods = length - 1
    daY = intercept + slope * periods / 2
    val = intercept
    for j = 0 to periods by 1
        price = high[j] - val
        if price > upDev
            upDev := price
        price := val - low[j]
        if price > dnDev
            dnDev := price
        price := source[j]
        dxt = price - average
        dyt = val - daY
        price -= val
        stdDevAcc += price * price
        dsxx += dxt * dxt
        dsyy += dyt * dyt
        dsxy += dxt * dyt
        val += slope
    stdDev = math.sqrt(stdDevAcc / (periods == 0 ? 1 : periods))
    pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
    [stdDev, pearsonR, upDev, dnDev]

[s, a, i] = calcSlope(sourceInput, lengthInput)
[stdDev, pearsonR, upDev, dnDev] = calcDev(sourceInput, lengthInput, s, a, i)

startPrice = i + s * (lengthInput - 1)
endPrice = i
var line baseLine = na
upperStartPrice = startPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
upperEndPrice = endPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
var line upper = na
lowerStartPrice = startPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
lowerEndPrice = endPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
var line lower = na

group2 = "Channel Settings"
useUpperDevInput2 = input.bool(true, title="Upper Deviation", inline = "Upper Deviation", group = group2)
upperMultInput2 = input.float(1, title="", inline = "Upper Deviation", group = group2)
useLowerDevInput2 = input.bool(true, title="Lower Deviation", inline = "Lower Deviation", group = group2)
lowerMultInput2 = input.float(1, title="", inline = "Lower Deviation", group = group2)

upperStartPrice_ = startPrice + (useUpperDevInput2 ? upperMultInput2 * stdDev : upDev)
upperEndPrice_ = endPrice + (useUpperDevInput2 ? upperMultInput2 * stdDev : upDev)
var line upper_ = na

lowerStartPrice_ = startPrice + (useLowerDevInput2 ? -lowerMultInput2 * stdDev : -dnDev)
lowerEndPrice_ = endPrice + (useLowerDevInput2 ? -lowerMultInput2 * stdDev : -dnDev)
var line lower_ = na

if na(baseLine) and not na(startPrice)
    baseLine := line.new(bar_index - lengthInput + 1, startPrice, bar_index, endPrice, width=1)
    upper := line.new(bar_index - lengthInput + 1, upperStartPrice, bar_index, upperEndPrice, width=1)
    lower := line.new(bar_index - lengthInput + 1, lowerStartPrice, bar_index, lowerEndPrice, width=1)
    upper_ := line.new(bar_index - lengthInput + 1, upperStartPrice_, bar_index, upperEndPrice_, width=1)
    lower_ := line.new(bar_index - lengthInput + 1, lowerStartPrice_, bar_index, lowerEndPrice_, width=1)
    linefill.new(upper_, upper, color.new(color.green, 50))
    linefill.new(lower, lower_, color.new(color.red, 50))
else
    line.set_xy1(baseLine, bar_index - lengthInput + 1, startPrice)
    line.set_xy2(baseLine, bar_index, endPrice)
    line.set_xy1(upper, bar_index - lengthInput + 1, upperStartPrice)
    line.set_xy2(upper, bar_index, upperEndPrice)
    line.set_xy1(lower, bar_index - lengthInput + 1, lowerStartPrice)
    line.set_xy2(lower, bar_index, lowerEndPrice)
    line.set_xy1(upper_, bar_index - lengthInput + 1, upperStartPrice_)
    line.set_xy2(upper_, bar_index, upperEndPrice_)
    line.set_xy1(lower_, bar_index - lengthInput + 1, lowerStartPrice_)
    line.set_xy2(lower_, bar_index, lowerEndPrice_)
    na

Re: Colorear en pine script

Publicado: 09 Nov 2023 17:59
por Gerber
Que exelente quedó el indicador, felicitaciones; tambien gracias por el consejo, fuerte abrazo @gu5tavo71.