Pine Script v5 User Manual (200-350)

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 151

Machine Translated by Google

Manual del usuario de Pine Script™ v5

Tenga en cuenta que el parámetro de color acepta argumentos de "color de serie", por lo que valores constantes como color.red,
color. lime, "#FF9090", así como las expresiones que calculan colores en tiempo de ejecución, como se hace aquí con la variable
colorpaleta, funcionarán.

Puede crear barras o velas utilizando valores distintos de los valores OHLC reales. Por ejemplo, podría calcular y trazar velas
suavizadas utilizando el siguiente código, que también colorea las mechas dependiendo de la posición del cierre en relación con el
cierre suavizado (c) de nuestro indicador:

1 //@versión=5
2 indicador("Velas suavizadas", superposición = verdadero) 3 lenInput = input.int(9) 4
smooth(fuente, longitud) => ta.sma(fuente,
longitud) 6 o = smooth(open, lenInput) 7 h = suave
5 (alto, lenInput) 8 l = suave (bajo,
lenInput) 9 c = suave (cerrado, lenInput) 10
ourWickColor = cerrar > c ? color.verde: color.rojo
11 plotcandle(o, h, l, c, wickcolor = ourWickColor)

190 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Puede resultarle útil trazar los valores OHLC tomados de un período de tiempo más alto. Puedes, por ejemplo, trazar barras diarias en un gráfico
intradiario:

1 // NOTA: Utilice este script en un gráfico intradiario. 2 //@version=5 3 indicador("Barras


diarias")

5 // Utilice espacios para devolver datos solo cuando se complete el período de tiempo 1D; en caso contrario, `na`.
6 [o, h, l, c] = request.security(syminfo.tickerid, "D", [abrir, alto, bajo, cerrar], gaps →= barmerge.gaps_on)

8 var color UP_COLOR = color.plata


9 var color DN_COLOR = color.blue 10 color wickColor = c
>= o ? UP_COLOR: DN_COLOR 11 colores bodyColor = c >= o ? color.nuevo(UP_COLOR,
70) : color.nuevo(DN_COLOR, 70)
12 // Solo traza velas en períodos de tiempo intradiarios, 13 // y cuando
`request.security()` devuelve valores que no son `na` porque un HTF tiene
→completado.
14 plotcandle(timeframe.isintraday ? o : na, h, l, c, color = bodyColor, wickcolor =
→color de mecha)

Tenga en cuenta que:

• Mostramos la trama del guión después de haber utilizado “Orden Visual/Traer al Frente” desde el menú “Más” del guión. Este
hace que las velas de nuestro script aparezcan encima de las velas del gráfico.

• El script solo mostrará velas cuando se cumplan dos condiciones:

– El gráfico utiliza un marco de tiempo intradiario (consulte la verificación en timeframe.isintraday en la llamada a plotcandle() ).
Hacemos esto porque no es útil mostrar un valor diario en períodos de tiempo superiores o iguales a 1D.

– La función request.security() devuelve valores que no son na (ver gaps = barmerge.gaps_on en la función
llamar).

• Usamos una tupla ([abrir, alto, bajo, cerrar]) con request.security() para recuperar cuatro valores en una llamada.

• Usamos var para declarar nuestras constantes de color UP_COLOR y DN_COLOR sólo en la barra cero. Usamos constantes porque esos
colores se usan en más de un lugar de nuestro código. De esta manera, si necesitamos cambiarlos, sólo tendremos que hacerlo en un
lugar.

4.4. Trazado de barras 191


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Creamos una transparencia más clara para el cuerpo de nuestras velas en la inicialización de la variable bodyColor, para que
no obstruyas las velas del gráfico.

4.4.3 Trazar barras con `plotbar()`


La firma de plotbar() es:

barra de trazado (abrir, alto, bajo, cerrar, título, color, editable, mostrar_último, mostrar) → anular

Tenga en cuenta que plotbar() no tiene parámetros para bordercolor o wickcolor, ya que no hay bordes ni mechas en las barras
convencionales.

Esto traza barras convencionales usando la misma lógica de coloración que en el segundo ejemplo de la sección anterior:

1 //@versión=5 2
indicador("Barras de dos colores") 3 paletaColor
= cerrar >= abrir? color.lime: color.red 4 barra gráfica (abrir, alto, bajo, cerrar, color =
paletaColor)

4.5 Estados de prohibición

• Introducción

• Variables integradas del estado de la barra

• Ejemplo

192 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.5.1 Introducción

Un conjunto de variables integradas en el espacio de nombres barstate permiten que su secuencia de comandos detecte diferentes propiedades de la barra en la que se
está ejecutando actualmente la secuencia de comandos.

Estos estados se pueden utilizar para restringir la ejecución o la lógica de su código a barras específicas.

Algunas funciones integradas devuelven información sobre la sesión de negociación a la que pertenece la barra actual. Se explican en la sección Estados de
sesión .

4.5.2 Variables integradas del estado de la barra

Tenga en cuenta que, si bien los indicadores y bibliotecas se ejecutan en todas las actualizaciones de precios o volúmenes en tiempo real, las estrategias que no
utilizan calc_on_every_tick no lo harán; solo se ejecutarán cuando se cierre la barra de tiempo real. Esto afectará la detección de estados de barras en ese tipo
de secuencia de comandos. En mercados abiertos, por ejemplo, este código no mostrará un fondo hasta que se cierre el tiempo real porque es entonces cuando
se ejecuta la estrategia:

1 //@versión=5 2
estrategia("S") 3
bgcolor(barstate.islast ? color.plata : na)

`barstate.isfirst`

barstate.isfirst solo es verdadero en la primera barra del conjunto de datos, es decir, cuando bar_index es cero.

Puede resultar útil inicializar variables solo en la primera barra, por ejemplo:

1 // Declara la matriz y establece sus valores solo en la primera barra.


2 FILL_COLOR = color.green 3 var fillColors =
array.new_color(0) 4 si barstate.isfirst

5 // Inicializa los elementos de la matriz con tonos progresivamente más claros del relleno →color.

6 array.push(fillColors, color.new(FILL_COLOR, 70)) array.push(fillColors,


7 color.new(FILL_COLOR, 75)) array.push(fillColors, color.new(FILL_COLOR,
8 80)) array.push(fillColors , color.new(FILL_COLOR, 85)) array.push(fillColors,
9 color.new(FILL_COLOR, 90))
10

`barstate.islast`

barstate.islast es verdadero si la barra actual es la última en el gráfico, ya sea que esa barra sea una barra en tiempo real o no.

Se puede utilizar para restringir la ejecución de código a la última barra del gráfico, lo que suele resultar útil al dibujar líneas, etiquetas o tablas. Aquí, lo usamos
para determinar cuándo actualizar una etiqueta que queremos que aparezca solo en la última barra. Creamos la etiqueta solo una vez y luego actualizamos sus
propiedades usando las funciones label.set_*() porque es más eficiente:

1 //@versión=5 2
indicador("", "", verdadero)
3 // Crea etiqueta solo en la primera barra. 4 var etiqueta hiLabel =
etiqueta.new(na, na, "")
5 // Actualiza la posición de la etiqueta y el texto en la última barra, 6 // incluidas todas las actualizaciones de
barras en tiempo real. 7 si barstate.islast

(continúa en la página siguiente)

4.5. Estados de la barra 193


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

8 label.set_xy(hiLabel, bar_index, alto) label.set_text(hiLabel,


9 str.tostring(alto, format.mintick))

`barstate.ishistory`

barstate.ishistory es cierto en todas las barras históricas. Nunca puede ser cierto en una barra cuando barstate.isrealtime también es verdadero, y no se
vuelve verdadero en la actualización de cierre de una barra en tiempo real, cuando barstate.isconfirmed se vuelve verdadero. En mercados cerrados, esto
puede ser cierto en la misma barra donde barstate.islast también lo es.

`barstate.isrealtime`

barstate.isrealtime es verdadero si la actualización de datos actual es una actualización de barra en tiempo real; en caso contrario, es falso (por lo tanto, es histórico).
Tenga en cuenta que barstate.islast también es válido en todas las barras en tiempo real.

`barstate.es nuevo`

barstate.isnew es verdadero en todas las barras históricas y en la primera actualización (de apertura) de la barra en tiempo real.

Todas las barras históricas se consideran barras nuevas porque el tiempo de ejecución de Pine Script™ ejecuta su secuencia de comandos en cada barra de forma secuencial,

desde la primera barra del gráfico en el tiempo hasta la última. De este modo , su secuencia de comandos descubre cada barra histórica a medida que se ejecuta, barra por barra.

barstate.isnew puede ser útil para restablecer las variables varip cuando aparece una nueva barra en tiempo real. El siguiente código restablecerá updateNo
a 1 en todas las barras históricas y al comienzo de cada barra en tiempo real. Calcula el número de actualizaciones en tiempo real durante cada barra en
tiempo real:

1 //@versión=5 2
indicador("") 3 updateNo()
=> varap int updateNo =
4 na if barstate.isnew
5

6 número de actualización:
7 = 1 más

8 actualizarNo += 1 9
trama(actualizarNo())

`barstate.está confirmado`

barstate.isconfirmed es verdadero en todas las barras históricas y en la última actualización (de cierre) de una barra en tiempo real.

Puede resultar útil evitar el repintado solicitando que se cierre la barra de tiempo real antes de que una condición pueda cumplirse. Lo usamos aquí para
mantener el trazado de nuestro RSI hasta que la barra de tiempo real se cierre y se convierta en una barra de tiempo real transcurrido. Se trazará en barras
históricas porque barstate.isconfirmed siempre es verdadero en ellas:

1 //@versión=5
2 indicadores("")
3 myRSI = ta.rsi(close, 20) 4
plot(barstate.isconfirmed? myRSI: na)

barstate.isconfirmed no funcionará cuando se use en una llamada request.security() .

194 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

`barstate.islastconfirmedhistory`

barstate.islastconfirmedhistory es verdadero si el script se ejecuta en la última barra del conjunto de datos cuando el mercado está cerrado, o en
la barra inmediatamente anterior a la barra en tiempo real si el mercado está abierto.

Se puede utilizar para detectar la primera barra en tiempo real con barstate.islastconfirmedhistory[1], o para posponer
cálculos intensivos en el servidor hasta la última barra histórica, que de otro modo serían indetectables en los mercados abiertos.

4.5.3 Ejemplo

A continuación se muestra un ejemplo de un script que utiliza variables barstate.*:

1 //@versión=5

2 indicadores ("Estados de la barra", superposición = verdadero, max_labels_count = 500)

4 texto de estado() =>


""
5 cadena txt = txt +=
6 barstate.isfirst ? "es primero\n" ? : ""
7 txt += barstate.islast "islat\n" : ""
""
8 txt += barstate.ishistory? "ishistory\n": txt += barstate.isrealtime? "isrealtime\n":
9 txt += barstate.isnew ""
10 ? "es nuevo\n" : ""
11 txt += barstate.isconfirmed? "no confirmado\n": ""
""
12 txt += barstate.islastconfirmedhistory? "islastconfirmedhistory\n":
13

14 color de etiqueta = cambiar

15 barstate.isfirst => color.fucsia


dieciséis
barstate.islastconfirmedhistory => color.gris
17 barstate.ishistoria barstate.está => color.plata
18 confirmado => color.naranja
19 barstate.isnew => color.rojo
20 => color.amarillo
21

22 etiqueta.new(bar_index, na, stateText(), yloc = yloc.abovebar, color = labelColor)

Tenga en cuenta que:

• El nombre de cada estado aparecerá en el texto de la etiqueta cuando sea verdadero.

• Hay cinco colores posibles para el fondo de la etiqueta:

– fucsia en la primera barra

– plata en lingotes históricos

– gris en la última barra histórica confirmada

– naranja cuando se confirma una barra de tiempo real (cuando se cierra y se convierte en una barra de tiempo real transcurrido)

– rojo en la primera ejecución de la barra de tiempo real

– amarillo para otras ejecuciones de la barra de tiempo real

Comenzamos agregando el indicador al gráfico de un mercado abierto, pero antes de recibir cualquier actualización en tiempo real. Tenga en cuenta cómo
la última barra del historial confirmada se identifica en el n.° 1, y cómo la última barra se identifica como la última, pero aún se considera una
barra histórica porque no se han recibido actualizaciones en tiempo real.

4.5. Estados de la barra 195


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Veamos lo que sucede cuando comienzan a llegar actualizaciones en tiempo real:

Tenga en cuenta que:

• La barra de tiempo real es roja porque es su primera ejecución, porque barstate.isnew es verdadero y barstate. ishistory ya no es cierto, por
lo que nuestra estructura de interruptor que determina nuestro color usa la rama barstate.isnew => color.red. Por lo general, esto no durará
mucho porque en la próxima actualización barstate.isnew ya no será verdadero, por lo que el color de la etiqueta se volverá amarillo.

• La etiqueta de las barras en tiempo real transcurrido es naranja porque esas barras no eran barras históricas cuando cerraron. En
consecuencia, la rama barstate.ishistory => color.silver en la estructura del switch no se ejecutó, pero la siguiente, barstate.isconfirmed =>
color.orange sí.

Este último ejemplo muestra cómo la etiqueta de la barra en tiempo real se volverá amarilla después de la primera ejecución en la barra. Así es como
suele aparecer la etiqueta en las barras en tiempo real:

196 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.6 Información del gráfico

• Introducción

• Precios y volumen

• Información de símbolos

• Periodo de tiempo del gráfico

• Información de la sesión

4.6.1 Introducción

La forma en que los scripts pueden obtener información sobre el gráfico y el símbolo que se están ejecutando actualmente es a través de un subconjunto de
variables integradas de Pine Script™. Los que cubrimos aquí permiten que los scripts accedan a información relacionada con:

• Los precios y el volumen del gráfico.

• El símbolo del gráfico.

• El marco temporal del gráfico

• La sesión (o período de tiempo) en la que se comercializa el símbolo

4.6. Información del gráfico 197


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.6.2 Precios y volumen

Las variables integradas para los valores OHLCV son:


open: el precio de apertura del bar.

• alto: el precio más alto de la barra, o el precio más alto alcanzado durante el tiempo transcurrido de la barra en tiempo real.

• bajo: el precio más bajo de la barra, o el precio más bajo alcanzado durante el tiempo transcurrido de la barra en tiempo real.

• cerrar: el precio de cierre de la barra, o el precio actual en la barra en tiempo real.

• volumen: el volumen negociado durante la barra, o el volumen negociado durante el tiempo transcurrido de la barra en tiempo real. La unidad de
información de volumen varía según el instrumento. Está en acciones para acciones, en lotes para forex, en contratos de futuros, en la moneda base
para criptomonedas, etc.

Otros valores están disponibles a través de:

• hl2: el promedio de los valores máximo y mínimo de la barra .

• hlc3: el promedio de los valores máximo, mínimo y de cierre de la barra .

• ohlc4: el promedio de los valores de apertura, máximo, mínimo y cierre de la barra .

En las barras históricas, los valores de las variables anteriores no varían durante la barra porque sobre ellas sólo está disponible información OHLCV. Cuando
se ejecutan en barras históricas, los scripts se ejecutan al cerrar la barra , cuando se conoce toda la información de la barra y no se puede cambiar durante la
ejecución del script en la barra.

Las barras en tiempo real son otra historia. Cuando los indicadores (o estrategias que usan calc_on_every_tick = true) se ejecutan en tiempo real, los valores
de las variables anteriores (excepto open) variarán entre iteraciones sucesivas del script en la barra de tiempo real, porque representan su valor actual en un
momento determinado durante el progreso de la barra de tiempo real.
Esto puede llevar a una forma de repintar. Consulte la página sobre el modelo de ejecución de Pine Script™ para obtener más detalles.

El operador de referencia histórica [] se puede utilizar para hacer referencia a valores pasados de las variables integradas, por ejemplo, cerrar[1] se refiere al
valor de cierre en la barra anterior, en relación con la barra particular en la que se está ejecutando el script.

4.6.3 Información de símbolos

Las variables integradas en el espacio de nombres syminfo proporcionan a los scripts información sobre el símbolo del gráfico en el que se ejecuta el script.
Esta información cambia cada vez que un usuario del script cambia el símbolo del gráfico. Luego, el script se vuelve a ejecutar en todas las barras del gráfico
utilizando los nuevos valores de las variables integradas:

• syminfo.basecurrency: la moneda base, por ejemplo, “BTC” en “BTCUSD” o “EUR” en “EURUSD”.

• syminfo.currency: la moneda de cotización, por ejemplo, “USD” en “BTCUSD” o “CAD” en “USDCAD”.

• syminfo.description: la descripción larga del símbolo.

• syminfo.mintick: el valor de tick del símbolo, o el precio de incremento mínimo, puede moverse. No debe confundirse con pips o puntos. En “ES1!” (“S&P
500 E­Mini”) el tamaño del tick es 0,25 porque ese es el incremento mínimo en el que se mueve el precio.

• syminfo.pointvalue: el valor en puntos es el múltiplo del activo subyacente que determina el valor de un contrato. En “ES1!” (“S&P 500 E­Mini”) el valor
en puntos es 50, por lo que un contrato vale 50 veces el precio del instrumento.

• syminfo.prefix: El prefijo es el identificador de la bolsa o corredor: “NASDAQ” o “BATS” para “AAPL”,


“CME_MINI_DL” para “ES1!”.

• syminfo.root: Es el prefijo del ticker para tickers estructurados como los de futuros. Es “ES” para “ES1!”, “ZW” para
“¡ZW1!”.

198 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• syminfo.session: Refleja la configuración de la sesión en el gráfico para ese símbolo. Si la opción “Configuración del gráfico/Símbolo/Sesión”
El campo está configurado en "Extendido", solo devolverá "extendido" si el símbolo y el feed del usuario permiten sesiones extendidas.
Rara vez se muestra y se utiliza principalmente como argumento para el parámetro de sesión en ticker.new().

• syminfo.ticker: Es el nombre del símbolo, sin la parte de intercambio (syminfo.prefix): “BTCUSD”, “AAPL”, “ES1!”,
“USDCAD”.

• syminfo.tickerid: esta cadena rara vez se muestra. Se utiliza principalmente como argumento para el símbolo de request.security()
parámetro. Incluye información de sesión, prefijo y teletipo.

• syminfo.timezone: la zona horaria en la que se intercambia el símbolo. La cadena es el nombre de la base de datos de la zona horaria de la IANA (por ejemplo,
“América/Nueva_York”).

• syminfo.type: El tipo de mercado al que pertenece el símbolo. Los valores son “acciones”, “futuros”, “índice”, “forex”,
“cripto”, “fondo”, “dr”, “cfd”, “bono”, “warrant”, “estructurado” y “derecho”.

Este script mostrará los valores de esas variables integradas en el gráfico:

1 //@versión=5

2 indicador("`syminfo.*` incorporados", "", verdadero)

3 imprimirTabla(txtIzquierda, txtDerecha) =>

4 var tabla t = tabla.nueva(posición.middle_right, 2, 1)


5 table.cell(t, 0, 0, txtLeft, bgcolor = color.amarillo, text_halign = text.align_
→derecha)
6 table.cell(t, 1, 0, txtRight, bgcolor = color.amarillo, text_halign = text.align_
→izquierda)
7

8nl = "\n"

quedan 9 =

10 "syminfo.basecurrency: " + nl +
11 "syminfo.currency: " + nl +
12 "syminfo.description: " + nl +
13 "syminfo.mintick: " + nl +
14 "syminfo.pointvalue: " + nl +
15 "syminfo.prefix: " + nl +
dieciséis
"syminfo.root: " + nl +
17 "syminfo.session: " + nl +
18 "syminfo .ticker: " + nl +
19 "syminfo.tickerid: " + nl +
20 "syminfo.timezone: " + nl +
21 "syminfo.type: "
22

23 derecha =

24 syminfo.basecurrency + nl +
25 syminfo.currency + nl +
26 syminfo.descripción + nl +
27 str.tostring(syminfo.mintick) + nl +
28 str.tostring(syminfo.pointvalue) + nl +
29 syminfo.prefijo + nl +
30 syminfo.root + nl +
31 syminfo.session + nl +
32 syminfo.ticker + nl +
33 syminfo.tickerid + nl +
34 syminfo.timezone + nl +
35 syminfo.type
36

37 imprimirTabla(izquierda, derecha)

4.6. Información del gráfico 199


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.6.4 Periodo de tiempo del gráfico

Un script puede obtener información sobre el tipo de período de tiempo utilizado en el gráfico utilizando estas funciones integradas, que devuelven un resultado
"simple bool":

• marco de tiempo.issegundos

• timeframe.isminutos

• timeframe.isintraday

• timeframe.isdaily

• timeframe.isweekly

• marco temporal.ismensual

• marco temporal.isdwm

Dos funciones integradas adicionales devuelven información sobre períodos de tiempo más específicos:

• timeframe.multiplier devuelve un “int simple” que contiene el multiplicador de la unidad del marco temporal. Un período de tiempo del gráfico de una hora
devolverá 60 porque los períodos de tiempo intradiarios se expresan en minutos. Un período de tiempo de 30 segundos arrojará 30 (segundos), un
gráfico diario arrojará 1 (día), un gráfico trimestral arrojará 3 (meses) y un gráfico anual arrojará 12 (meses). El valor de esta variable no se puede
utilizar como argumento para los parámetros de período de tiempo en funciones integradas, ya que esperan una cadena en formato de especificaciones
de período de tiempo.

• timeframe.period devuelve una cadena en el formato de especificación de período de tiempo de Pine Script™.

Consulte la página sobre Plazos para obtener más información.

4.6.5 Información de la sesión

La información de la sesión está disponible en diferentes formas:

• La variable incorporada syminfo.session devuelve un valor que es session.regular o session.extended. Refleja la configuración de la sesión en el gráfico
para ese símbolo. Si el campo "Configuración del gráfico/Símbolo/Sesión" está configurado en "Extendido", solo devolverá "extendido" si el símbolo y el
feed del usuario permiten sesiones extendidas. Se utiliza cuando se espera un tipo de sesión, por ejemplo, como argumento para el parámetro de
sesión en ticker.new().

• Las funciones integradas de estado de sesión proporcionan información sobre la sesión de negociación a la que pertenece una barra.

200 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.7 colores

• Introducción

• Colores constantes

• Coloración condicional

• Colores calculados

• Mezcla de transparencias

• Consejos

4.7.1 Introducción
Los elementos visuales del guión pueden desempeñar un papel fundamental en la usabilidad de los indicadores que escribimos en Pine Script™. Los diagramas
y dibujos bien diseñados hacen que los indicadores sean más fáciles de usar y comprender. Los buenos diseños visuales establecen una jerarquía visual que
permite que la información más importante se destaque y la menos importante no estorbe.

Usar colores en Pine puede ser tan simple como quieras o tan complicado como lo requiera tu concepto. Los 4.294.967.296 posibles conjuntos de color y
transparencia disponibles en Pine Script™ se pueden aplicar a:

• Cualquier elemento que pueda trazar o dibujar en el espacio visual de un indicador, ya sean líneas, rellenos, texto o velas.

• El fondo del espacio visual de un script, ya sea que el script se ejecute en su propio panel o en modo de superposición en el
cuadro.

• El color de las barras o del cuerpo de las velas que aparecen en un gráfico.

Un guión sólo puede colorear los elementos que coloca en su propio espacio visual. La única excepción a esta regla es que un indicador de panel puede
colorear barras o velas del gráfico.

Pine Script™ tiene colores integrados como color.green, así como funciones como color.rgb() que le permiten generar dinámicamente cualquier color en el
espacio de color RGBA.

Transparencia

Cada color en Pine Script™ está definido por cuatro valores:

• Sus componentes rojo, verde y azul (0­255), siguiendo el modelo de color RGB.

• Su transparencia (0­100), a menudo denominada canal Alfa fuera de Pine, tal como se define en el modelo de color RGBA.
Aunque la transparencia se expresa en el rango de 0 a 100, su valor puede ser "flotante" cuando se usa en funciones, lo que le da acceso a los 256
valores subyacentes del canal alfa.

La transparencia de un color define qué tan opaco es: cero es completamente opaco, 100 hace que el color (cualquiera que sea) sea invisible.
Modular la transparencia puede ser crucial en imágenes de color más complejas o cuando se utilizan fondos, para controlar qué colores dominan a los demás
y cómo se mezclan cuando se superponen.

4.7. Colores 201


Machine Translated by Google

Manual del usuario de Pine Script™ v5

índice Z

Cuando colocas elementos en el espacio visual de un guión, tienen una profundidad relativa en el eje z ; algunos aparecerán encima de otros. El
índice z es un valor que representa la posición de los elementos en el eje z . Los elementos con el índice z más alto aparecen en la parte superior.

Los elementos dibujados en Pine Script™ se dividen en grupos. Cada grupo tiene su propia posición en el espacio z y, dentro del mismo grupo,
los elementos creados en último lugar en la lógica del script aparecerán encima de otros elementos del mismo grupo. Un elemento de un grupo
no se puede colocar fuera de la región del espacio z atribuido a su grupo, por lo que un gráfico nunca puede aparecer encima de una tabla, por
ejemplo, porque las tablas tienen el índice z más alto.

Esta lista contiene los grupos de elementos visuales, ordenados por índice z creciente, por lo que los colores de fondo siempre están en la parte
inferior del espacio z y las tablas siempre aparecerán encima de todos los demás elementos:

• Colores de fondo

• Rellenos

• Parcelas

• Líneas H

• Rellenos de línea

• Líneas

• Cajas

• Etiquetas

• Mesas

Tenga en cuenta que al usar explicit_plot_zorder = true en indicador() o estrategia(), puede controlar el índice z relativo de los objetos visuales
plot*(), hline() y fill() usando su orden secuencial en el script.

4.7.2 Colores constantes

Hay 17 colores integrados en Pine Script™. Esta tabla enumera sus nombres, equivalente hexadecimal y valores RGB como argumentos para
color.rgb():

Nombre Maleficio Valores RGB

color.aqua #00BCD4 color.rgb(0, 188, 212) color.negro


#363A45 color.rgb(54, 58, 69) color.azul #2196F3 color.rgb(33,
150, 243) color.fucsia #E040FB color.rgb(224, 64, 251) color.gris
#787B86 color.rgb(120, 123, 134) color.verde #4CAF50
color.rgb(76, 175, 80) color.lima #00E676 color.rgb(0 , 230, 118)
color.granate #880E4F color.rgb(136, 14, 79) color.navy
#311B92 color.rgb(49, 27, 146) color.oliva #808000
color.rgb(128, 128, 0) color.naranja #FF9800 color.rgb(255,
152, 0) color.púrpura #9C27B0 color.rgb(156, 39, 176)
color.rojo #FF5252 color.rgb(255, 82, 82) color.plata #B2B5BE
color.rgb(178, 181, 190) color.verde azulado color.blanco
#FFFFFF color.rgb(255, 255, 255) color.amarillo #FFEB3B
color.rgb(255, 235, 59)

#00897B color.rgb(0, 137, 123)

202 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

En el siguiente guión, todos los gráficos utilizan el mismo color: color oliva con una transparencia de 40, pero expresado de diferentes maneras.
Los cinco métodos son funcionalmente equivalentes:

1 //@versión=5 2
indicador("", "", verdadero)
3 // ———— La transparencia (#99) está incluida en el valor hexadecimal. 4 trama (ta.sma (cerrar,
10), "10", #80800099)
5 // ———— La transparencia se incluye en los argumentos de la función generadora de color. 6 plot(ta.sma(close, 30), "30",
color.new(color.olive, 40)) 7 plot(ta.sma(close, 50), "50", color.rgb(128, 128 , 0, 40))

8 // ———— Usar el parámetro `transp` (obsoleto y desaconsejado) 9 plot(ta.sma(close, 70),


"70", color.olive, transp = 40) 10 plot(ta.sma(close, 90), "90", #808000, transp = 40)

Nota: Las dos últimas llamadas a plot() especifican la transparencia utilizando el parámetro transp. Este uso debe evitarse ya que la transp está obsoleta en
Pine Script™ v5. Usar el parámetro transp para definir la transparencia no es tan flexible porque requiere un argumento de tipo entero de entrada , lo que
implica que debe conocerse antes de ejecutar el script y, por lo tanto, no se puede calcular dinámicamente, ya que el script se ejecuta barra a barra. Además,
si utiliza un argumento de color que ya incluye información de transparencia, como se hace en las siguientes tres llamadas a plot() , cualquier argumento
utilizado para el parámetro transp no tendrá ningún efecto. Esto también es válido para otras funciones con un parámetro transp.

Los colores en el script anterior no varían a medida que el script se ejecuta barra a barra. A veces, sin embargo, es necesario crear colores a medida que el
script se ejecuta en cada barra porque dependen de condiciones que se desconocen en el momento de la compilación o cuando el script comienza a
ejecutarse en la barra cero. Para esos casos, los programadores tienen dos opciones:

1. Utilice declaraciones condicionales para seleccionar colores entre unos pocos colores base predeterminados.

2. Cree nuevos colores dinámicamente, calculándolos a medida que el script se ejecuta barra a barra, para implementar degradados de color.
Por ejemplo.

4.7.3 Coloración condicional

Digamos que desea colorear un promedio móvil en diferentes colores, dependiendo de algunas condiciones que defina. Para hacerlo, puede utilizar una
declaración condicional que seleccionará un color diferente para cada uno de sus estados. Comencemos coloreando una media móvil en un color alcista
cuando está subiendo y en un color bajista cuando no lo está:

4.7. Colores 203


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5 2
indicador("Colores condicionales", "", verdadero) 3 int lengthInput =
input.int(20, "Length", minval = 2) 4 colores maBullColorInput = input.color(color.green,
"Toro") 5 colores maBearColorInput = input.color(color.maroon, "Oso") 6 float ma =
ta.sma(close, lengthInput)

7 // Definir nuestros estados. 8 bool


maRising = ta.rising(ma, 1)
9 // Construye nuestro color. 10
colores c_ma = maRising ? maBullColorInput: maBearColorInput 11 trazado(ma, "MA", c_ma, 2)

Tenga en cuenta que:

• Proporcionamos a los usuarios de nuestro script una selección de colores para nuestros colores alcistas/osos.

• Definimos una variable booleana maRising que será verdadera cuando la media móvil sea más alta en la barra actual que en la última.

• Definimos una variable de color c_ma a la que se le asigna uno de nuestros dos colores, dependiendo del valor del booleano maRising.
Usamos el ? : operador ternario para escribir nuestra declaración condicional.

También puede utilizar colores condicionales para evitar el trazado en determinadas condiciones. Aquí, trazamos pivotes altos y bajos usando
una línea, pero no queremos trazar nada cuando entra un nuevo pivote, para evitar las uniones que de otro modo aparecerían en las transiciones
de pivotes. Para hacerlo, probamos los cambios de pivote y usamos na como valor de color cuando se detecta un cambio, de modo que no se
trace ninguna línea en esa barra:

1 //@versión=5 2
indicador("Colores condicionales", "", verdadero) 3 int piernasInput
= input.int(5, "Patas de pivote", minval = 1) 4 colores pHiColorInput = input.color(color.olive ,
"Pivotes altos")
(continúa en la página siguiente)

204 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

5 colores pLoColorInput = input.color(color.orange, "Pivotes bajos")


6 // Inicializa las variables de nivel de pivote. 7 var float pHi = na
8 var float pLo = na 9 // Cuando
se detecta un nuevo pivote,
guarda su valor. 10 pHi := nz(ta.pivothigh(entrada de piernas, entrada de
piernas), pHi) 11 pLo := nz(ta.pivotlow(entrada de piernas, entrada de piernas),
pLo)
12 // Cuando se detecta un nuevo pivote, no trazar un color. 13 plot(pHi, "Alto",
ta.change(pHi) ? na : pHiColorInput, 2, plot.style_line) 14 plot(pLo, "Bajo", ta.change(pLo) ? na : pLoColorInput, 2, plot.
línea_estilo)

Para entender cómo funciona este código, primero se debe saber que ta.pivothigh() y ta.pivotlow(), usados tal como están aquí sin un argumento
para el parámetro fuente, devolverán un valor cuando encuentren un pivote alto/bajo . de lo contrario regresan na.

Cuando probamos el valor devuelto por la función pivote para na usando la función nz() , permitimos que el valor devuelto se asigne a las
variables pHi o pLo solo cuando no es na; de lo contrario, el valor anterior de la variable simplemente se reasigna a éste, lo que no tiene ningún
impacto en su valor. Tenga en cuenta que los valores anteriores de pHi y pLo se conservan barra a barra porque usamos la palabra clave var al
inicializarlos, lo que hace que la inicialización solo ocurra en la primera barra.

Todo lo que queda por hacer a continuación es, cuando tracemos nuestras líneas, insertar una declaración condicional ternaria que producirá na
para el color cuando cambie el valor de pivote, o el color seleccionado en las entradas del script cuando el nivel de pivote no cambie.

4.7.4 Colores calculados

Usando funciones como color.new(), color.rgb() y color.from_gradient(), uno puede crear colores sobre la marcha, mientras el script se ejecuta
barra a barra.

color.new() es más útil cuando necesitas generar diferentes niveles de transparencia a partir de un color base.

color.rgb() es útil cuando necesitas crear colores dinámicamente a partir de componentes rojo, verde, azul o transparencia. Mientras color.rgb()
crea un color, sus funciones hermanas color.r(), color.g(), color.b() y color.t() se pueden utilizar para extraer los valores de rojo, verde, azul o
transparencia. a partir de un color, que a su vez puede utilizarse para generar una variante.

color.from_gradient() es útil para crear degradados lineales entre dos colores base. Determina qué color intermediario utilizar evaluando un valor
de origen frente a los valores mínimo y máximo.

4.7. Colores 205


Machine Translated by Google

Manual del usuario de Pine Script™ v5

color.nuevo()

Usemos color.new(color, transp) para crear diferentes transparencias para columnas de volumen usando uno de los dos colores base alcista/
bajista:

1 //@versión=5 2
indicador("Volumen")
3 // Nombramos nuestras constantes de color para hacerlas más legibles. 4 var color GOLD_COLOR
= #CCCC00ff 5 var color VIOLET_COLOR = #AA00FFff 6
colores bullColorInput = input.color(GOLD_COLOR, "Toro") 7
colores bearColorInput = input.color(VIOLET_COLOR, "Oso") 8 int nivelesInput = input.int( 10,
"Niveles de gradiente", minval = 1)

9 // Inicializamos solo una vez en la barra cero con `var`; de lo contrario, el recuento se restablecería a
→cero en cada barra.
10 var flotador riseFallCnt = 0
11 // Cuente las subidas/caídas, fijando el rango en: 1 a `i_levels`. 12 riseFallCnt := math.max(1,
math.min(levelsInput, riseFallCnt + math.sign(volumen ­ →nz(volumen[1]))))

13 // Vuelva a escalar el recuento en una escala de 80, inviértalo y limite la transparencia a <80 para que →los colores permanezcan visibles.

14 transparencia flotante = 80 ­ math.abs(80 * riseFallCnt/levelsInput)


15 // Construya la transparencia correcta del color alcista o bajista. 16 colores volumeColor = color.new(cerrar > abrir?
bullColorInput: bearColorInput,
→transparencia)
17 trazado(volumen, "Volumen", volumenColor, 1, plot.style_columns)

Tenga en cuenta que:

• En la penúltima línea de nuestro script, calculamos dinámicamente el color de la columna variando tanto el color base utilizado,
dependiendo de si la barra está arriba o abajo, como el nivel de transparencia, que se calcula a partir de las subidas o bajadas
acumuladas de volumen.

• Ofrecemos al usuario del script control no sólo sobre los colores base alcista/bajista utilizados, sino también sobre el número de niveles
de brillo que utilizamos. Usamos este valor para determinar el número máximo de subidas o bajadas que rastrearemos. Dar a los
usuarios la posibilidad de gestionar este valor les permite adaptar las imágenes del indicador al período de tiempo o al mercado que utilizan.

• Nos encargamos de controlar el nivel máximo de transparencia que utilizamos para que nunca supere 80. Esto garantiza
Nuestros colores siempre conservan algo de visibilidad.

• También fijamos el valor mínimo para el número de niveles en 1 en las entradas. Cuando el usuario selecciona 1, el volumen
las columnas estarán en color alcista o bajista de brillo máximo, o transparencia cero.

206 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

color.rgb()

En nuestro siguiente ejemplo usamos color.rgb(rojo, verde, azul, transp) para crear colores a partir de valores RGBA. Usamos el resultado como
regalo de Navidad para nuestros amigos, para que puedan llevar sus gráficos de TradingView a las fiestas:

1 //@version=5 2
indicador("Velas navideñas", "", verdadero) 3 float r =
math.random(0, 255) 4 float g = math.random(0,
255) 5 float b = math. aleatorio(0, 255) 6 float t =
math.random(0, 100) 7 color vacacionesColor =
color.rgb(r, g, b, t) 8 plotcandle(abierto, alto, bajo,
cerrado, color = c_holiday, wickcolor = color de vacaciones,

→bordercolor = c_holiday)

Tenga en cuenta que:

• Generamos valores en el rango de cero a 255 para los canales rojo, verde y azul, y en el rango de cero a 100 para la transparencia.
También tenga en cuenta que debido a que math.random() devuelve valores flotantes, el rango flotante 0.0­100.0 proporciona acceso a
los valores de transparencia completos 0­255 del canal alfa subyacente.

• Usamos la función math.random(min, max, seed) para generar valores pseudoaleatorios. No utilizamos un argumento para el tercer
parámetro de la función: semilla. Usarlo es útil cuando desea garantizar la repetibilidad de los resultados de la función. Llamado con la
misma semilla, producirá la misma secuencia de valores.

color.from_gradient()

Nuestros últimos ejemplos de cálculos de color utilizarán color.from_gradient(valor, valor_inferior, valor_superior, color_inferior, color_superior).
Primero usémoslo en su forma más simple, para colorear una señal CCI en una versión del indicador que por lo demás se parece al integrado:

1 //@versión=5 2
indicador(título="Gradiente de línea CCI", precisión=2, marco de tiempo="") 3 var color GOLD_COLOR
= #CCCC00 4 var color VIOLET_COLOR = #AA00FF

(continúa en la página siguiente)

4.7. Colores 207


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

5 var color BEIGE_COLOR = #9C6E1B 6 float srcInput =


input.source(close, title="Fuente") 7 int lenInput = input.int(20, "Longitud", minval = 5) 8 colores
bullColorInput = input.color(GOLD_COLOR , "Toro") 9 colores osoColorInput =
input.color(BEIGE_COLOR, "Oso") 10 señal flotante = ta.cci(srcInput, lenInput) 11 colores signalColor
= color.from_gradient(señal, ­200, 200, osoColorInput, → bullColorInput) 12 plot(señal, "CCI",
signalColor) 13 bandTopPlotID = hline(100, "Banda superior", color.silver,
hline.style_dasshed) 14 bandBotPlotID = hline(­100, "Banda inferior", color.silver, hline.style_dasshed) 15 relleno(bandTopPlotID,
bandBotPlotID,
color.new(BEIGE_COLOR, 90), "Fondo")

Tenga en cuenta que:

• Para calcular el gradiente, color.from_gradient() requiere valores mínimo y máximo con los que se comparará el argumento utilizado para
el parámetro de valor. El hecho de que queramos un gradiente para una señal ilimitada como CCI (es decir, sin límites fijos como RSI,
que siempre oscila entre 0 y 100), no implica que no podamos usar color.from_gradient(). Aquí resolvemos nuestro enigma
proporcionando valores de ­200 y 200 como argumentos.
No representan los valores mínimo y máximo reales para CCI, pero están en niveles a partir de los cuales no nos importa que los colores
ya no cambien, ya que siempre que la serie esté fuera de los límites de valor_inferior y valor_superior, los colores utilizados para
color_inferior y color_superior cambiarán. aplicar.

• La progresión de color calculada por color.from_gradient() es lineal. Si el valor de la serie está a medio camino entre los argumentos
valor_inferior y valor_superior, los componentes RGBA del color generado también estarán a medio camino entre los de color_inferior y
color_superior.

• Muchos cálculos de indicadores comunes están disponibles en Pine Script™ como funciones integradas. Aquí usamos ta.cci() en lugar
de calcularlo a lo largo.

El argumento utilizado para el valor en color.from_gradient() no necesariamente tiene que ser el valor de la línea que estamos calculando. Se
puede usar cualquier cosa que queramos, siempre que se puedan proporcionar argumentos para valor_inferior y valor_superior.
Aquí, mejoramos nuestro indicador CCI coloreando la banda usando el número de barras desde que la señal ha estado por encima/por debajo
de la línea central:

1 //@versión=5 2
indicador(título="Gradiente de línea CCI", precisión=2, marco de tiempo="") 3 var color GOLD_COLOR
= #CCCC00 4 var color VIOLET_COLOR = #AA00FF
5 var color GREEN_BG_COLOR =
color.new( color.green, 70) 6 var color RED_BG_COLOR = color.new(color.maroon,
70) 7 float srcInput 8 int lenInput 9 int pasosInput 10 color bullColorInput =
input.color(GOLD_COLOR, = input.source(close, "Fuente") = input.int(20,
"Line: Bull", inline = "11 ") "Longitud", minval = 5) = input.int(50, "Niveles de gradiente",
11 colores osoColorInput = minval = 1)
input.color(VIOLET_COLOR, "Oso", inline = "11") 12 colores bullBgColorInput = input.color(GREEN_BG_COLOR, "Fondo:
Toro", inline = "12

→")
13 colores bearBgColorInput = input.color(RED_BG_COLOR, "Bear", inline = "12") (continúa en la página siguiente)

208 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

14

15 // Traza la línea de señal coloreada. 16 señal


flotante = ta.cci(srcInput, lenInput) 17 color signalColor =
color.from_gradient(señal, ­200, 200, color.new(bearColorInput,
→0), color.new(bullColorInput, 0)) 18 plot(señal,
"CCI", signalColor, 2)
19

20 // Detectar cruces de la línea central. 21 bool señalX =


ta.cross(señal, 0)
22 // Cuenta el número de barras desde el cruce. Limitándolo al número de pasos desde las entradas. 23 int gradientStep =
math.min(stepsInput, nz(ta.barssince(signalX)))
24 // Elija el color final alcista/bajista para el degradado. 25 colores endColor = señal >
0? bullBgColorInput: bearBgColorInput 26 // Obtiene el color del degradado desde ningún color a `c_endColor` 27 color
bandColor = color.from_gradient(gradientStep, 0, stepInput, na, endColor) 28 bandTopPlotID = hline(100, "Upper
Band", color. plateado, hline.style_dashed) 29 bandBotPlotID = hline(­100, "Banda inferior", color.silver, hline.style_dasshed) 30 fill(bandTopPlotID,
bandBotPlotID, bandColor, título = "Banda")

Tenga en cuenta que:

• El gráfico de señal utiliza los mismos colores base y degradado que en nuestro ejemplo anterior. Sin embargo, hemos aumentado el ancho de la línea del valor
predeterminado 1 a 2. Es el componente más importante de nuestros elementos visuales; aumentar su ancho es una forma de darle más protagonismo y
garantizar que los usuarios no se distraigan con la banda, que se ha vuelto más ocupada que en su color beige plano original.

• El relleno debe permanecer discreto por dos razones. En primer lugar, es de importancia secundaria respecto de lo visual, ya que proporciona información
complementaria, es decir, el tiempo durante el cual la señal ha estado en territorio alcista/bajista. En segundo lugar, dado que los rellenos tienen un índice z
mayor que los trazados, el relleno cubrirá el trazado de la señal. Por estos motivos, hacemos que los colores base del relleno sean bastante transparentes, en
70, para que no enmascaren los trazados. El degradado utilizado para la banda comienza sin ningún color (consulte el na utilizado como argumento para
bottom_color en la llamada color.from_gradient() ) y va a los colores base alcista/bajista de las entradas, que son condicionales, c_endColor La variable de
color contiene.

• Proporcionamos a los usuarios distintas selecciones de colores alcistas/bajistas para la línea y la banda.

• Cuando calculamos la variable gradientStep, usamos nz() en ta.barssince() porque en las primeras barras del conjunto de datos, cuando la condición probada
aún no se ha producido, ta.barssince() devolverá na. Como usamos nz(), el valor devuelto se reemplaza por cero en esos casos.

4.7.5 Mezcla de transparencias

En este ejemplo llevamos nuestro indicador CCI en otra dirección. Construiremos zonas de amortiguamiento de extremos que se ajustan dinámicamente utilizando un
Canal Donchian (máximos/mínimos históricos) calculado a partir del CCI. Construimos las bandas superior/inferior haciéndolas 1/4 de la altura del DC. Usaremos una
retrospectiva de ajuste dinámico para calcular el DC. Para modular la retrospectiva, calcularemos una medida simple de volatilidad manteniendo una relación entre un
ATR de corto plazo y uno largo. Cuando ese ratio es superior a 50 de sus últimos 100 valores, consideramos que la volatilidad es alta. Cuando la volatilidad es alta/
baja, reducimos/aumentamos el lookback.

Nuestro objetivo es proporcionar a los usuarios de nuestro indicador:

• La línea CCI está coloreada usando un gradiente alcista/bajista, como ilustramos en nuestros ejemplos más recientes.

• Las bandas superior e inferior del Canal Donchian, rellenas de tal manera que su color se oscurece a medida que un máximo o mínimo histórico se vuelve cada
vez más antiguo.

• Una forma de apreciar el estado de nuestra medida de volatilidad, que haremos pintando el fondo con un color cuya intensidad aumenta cuando aumenta la
volatilidad.

4.7. Colores 209


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Así es como se ve nuestro indicador usando el tema claro:

Y con el tema oscuro:

1 //@versión=5 2
indicador("CCI DC", precisión = 6) 3 colores GOLD_COLOR =
#CCCC00ff 4 colores VIOLET_COLOR = #AA00FFff 5 int
lengthInput = input.int(20, "Longitud", minval = 5) 6 color
bullColorInput = input.color(GOLD_COLOR, "Toro") 7 colores osoColorInput =
input.color(VIOLET_COLOR, "Oso")

9 // ————— La función sujeta `val` entre `min` y `max`. 10 abrazadera (val, min, max) => math.max
(min, math.min (max, val))
11

12

13 // ————— Volatilidad expresada como valor 0­100. 14 float v = ta.atr(longitudInput /


5) / ta.atr(lengthInput * 5) 15 float vPct = ta.percentrank(v, lengthInput * 5)

dieciséis

17 // ————— Calcular la retrospectiva dinámica para DC. Aumenta/disminuye en bajo/alto


→volatilidad.
18 bool highVolatility = vPct > 50 19 var int lookBackMin =
lengthInput * 2 20 var int lookBackMax = lengthInput * 10 21 var float
lookBack = math.avg(lookBackMin, lookBackMax) 22 lookBack +=
highVolatility? ­2: 2 23 mirarAtrás: = abrazadera (mirarAtrás, mirarAtrásMin, mirarAtrásMax)

24

25 // ————— Longitud dinámica retrospectiva del canal de señal de Donchian. 26 señal flotante = ta.cci(close,
lengthInput) 27 // `lookBack` es un flotante; Es necesario convertirlo a int para
usarlo en una longitud. 28 float hiTop = ta.highest(señal, int(lookBack)) 29 float loBot = ta.lowest(señal, int(lookBack))

30 // Consigue un margen del 25% de la altura del DC para construir bandas altas y bajas. 31 float margin = (hiTop ­ loBot) / 4
32 float hiBot = hiTop ­ margen 33 float loTop = loBot + margen
34 // Centro de DC. 35 centro flotante = math.avg(hiTop,
loBot)

36

37 // ————— Crea colores. 38 colores


signalColor = color.from_gradient(señal, ­200, 200, bearColorInput, →bullColorInput)

39 // Bandas: Calcula las transparencias de modo que cuanto más tiempo haya transcurrido desde que el alto/bajo haya cambiado, 40 //
cuanto más oscuro se vuelve el color. Limite la transparencia más alta a 90. 41 float hiTransp
= abrazadera(100 ­ (100 * math.max(1, nz(ta.barssince(ta.change(hiTop)) +
→1)) / 255), 60, 90)
(continúa en la página siguiente)

210 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

42 float loTransp = abrazadera(100 ­ (100 * math.max(1, nz(ta.barssince(ta.change(loBot)) +


→1)) / 255), 60, 90) 43 colores
hiColor = color.new(bullColorInput, hiTransp) 44 colores loColor =
color.new(bearColorInput, loTransp)
45 // Antecedentes: Cambie la escala del rango 0­100 de `vPct` a 0­25 para crear 75­100 →transparencias.

46 colores bgColor = color.nuevo(color.gris, 100 ­ (vPct / 4))


47

48 // ————— Parcelas
49 // Líneas invisibles para rellenos de banda. 50 hiTopPlotID
= trama(hiTop, color = na) 51 hiBotPlotID = trama(hiBot, color = na)
52 loTopPlotID = trama(loTop, color = na) 53 loBotPlotID =
trama(loBot, color = na)

54 // Trazar señal y línea central. 55 p_signal = plot(señal,


"CCI", signalColor, 2) 56 plot(center, "Centerline", color.silver, 1)

57

58 // Llenar las bandas.


59 llenar(hiTopPlotID, hiBotPlotID, hiColor) 60 llenar(loTopPlotID,
loBotPlotID, loColor)
61

62 // ————— Antecedentes. 63
bgcolor(bgColor)

Tenga en cuenta que:

• Limitamos la transparencia del fondo a un rango de 100­75 para que no abrume. También utilizamos un color neutro que no distraiga
demasiado. Cuanto más oscuro es el fondo, mayor es nuestra medida de volatilidad.

• También fijamos los valores de transparencia para los rellenos de banda entre 60 y 90. Usamos 90 para que cuando se encuentre un
nuevo alto/bajo y el gradiente se restablezca, la transparencia inicial haga que el color sea algo visible. No utilizamos una
transparencia inferior a 60 porque no queremos que esas bandas oculten la línea de señal.

• Usamos la muy útil función ta.percentrank() para generar un valor de 0 a 100 a partir de nuestro índice ATR que mide la volatilidad.
Resulta útil convertir valores cuya escala se desconoce en valores conocidos que puedan utilizarse para producir transparencias.

• Debido a que debemos fijar valores tres veces en nuestro script, escribimos una función f_clamp(), en lugar de explícitamente
codificando la lógica tres veces.

4.7.6 Consejos

Diseñar esquemas de colores utilizables.

Si escribe scripts destinados a otros operadores, intente evitar colores que no funcionen bien en algunos entornos, ya sea para gráficos,
etiquetas, tablas o rellenos. Como mínimo, pruebe sus imágenes para asegurarse de que funcionen satisfactoriamente con los temas claros
y oscuros de TradingView; son los más utilizados. Se deben evitar colores como el blanco y el negro, por ejemplo.

Cree las entradas adecuadas para brindar a los usuarios de scripts la flexibilidad de adaptar las imágenes de su script a sus entornos
particulares.

Tenga cuidado de crear una jerarquía visual de los colores que utilice que coincida con la importancia relativa de los componentes visuales
de su guión. Los buenos diseñadores saben cómo lograr el equilibrio óptimo entre color y peso para que la atención se centre naturalmente
en los elementos más importantes del diseño. Cuando haces que todo destaque, nada lo hace. Deje espacio para que algunos elementos
se destaquen atenuando las imágenes que los rodean.

4.7. Colores 211


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Proporcionar una selección de ajustes preestablecidos de color en sus entradas, en lugar de un solo color que se pueda cambiar, puede ayudar a los
usuarios con problemas de color. Nuestras calificaciones técnicas demuestran una forma de lograrlo.

Traza líneas nítidas

Es mejor utilizar transparencia cero para trazar las líneas importantes en sus imágenes, para mantenerlas nítidas. De esta manera, se verán los rellenos
con mayor precisión. Tenga en cuenta que los rellenos tienen un índice z más alto que los trazados, por lo que se colocan encima de ellos.
Un ligero aumento del ancho de una línea también puede contribuir en gran medida a que se destaque.

Si desea que un gráfico especial se destaque, también puede darle más importancia utilizando varios gráficos para la misma línea.
Estos son ejemplos en los que modulamos el ancho y la transparencia sucesivos de los gráficos para lograr esto:

1 //@versión=5
2 indicadores("")
3 plot(alto, "", color.new(color.orange, 80), 8) 4 plot(high, "", color.new(color.orange,
60), 4) 5 plot(high, "", color.new(color.orange, 60), 4) 5 plot(high, "",
color.nuevo(color.naranja, 00), 1)
6

7 trama(hl2, "", color.new(color.orange, 60), 4) 8 trama(hl2, "", color.new(color.orange,


00), 1)
9

10 trazado(bajo, "", color.nuevo(color.naranja, 0), 1)

Personalizar degradados

Al crear degradados, adáptelos a los elementos visuales a los que se aplican. Si está utilizando un degradado para colorear velas, por ejemplo, normalmente
es mejor limitar el número de pasos del degradado a diez o menos, ya que es más difícil para el ojo percibir variaciones de intensidad de objetos discretos.
Como hicimos en nuestros ejemplos, limite los niveles de transparencia mínimo y máximo para que sus elementos visuales permanezcan visibles y no
abrumen cuando no sea necesario.

Selección de color a través de la configuración del script.

El tipo de color que utilice en sus guiones tiene un impacto en cómo los usuarios de su guión podrán cambiar los colores de las imágenes de su guión.
Siempre que no utilice colores cuyos componentes RGBA deban calcularse en tiempo de ejecución, los usuarios del script podrán modificar los colores que
utilice yendo a la pestaña "Configuración/Estilo" del script. Nuestro primer script de ejemplo en esta página cumple con ese criterio, y la siguiente captura de
pantalla muestra cómo usamos la pestaña "Configuración/Estilo" del script para cambiar el color de la primera media móvil:

212 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Si su secuencia de comandos usa un color calculado, es decir, un color donde al menos uno de sus componentes RGBA solo se puede conocer en
tiempo de ejecución, entonces la pestaña "Configuración/Estilo" NO ofrecerá a los usuarios los widgets de color habituales que pueden usar para
modificar su trama. colores. También se verán afectadas las tramas del mismo guión que no utilicen colores calculados. En este script, por ejemplo,
nuestra primera llamada a plot() usa un color calculado y la segunda no:

1 //@versión=5
2 indicador ("Colores calculados", "", verdadero) 3 float ma =
ta.sma(close, 20) 4 float maHeight =
ta.percentrank(ma, 100) 5 float transparencia = math.min(80, 100 ­
maHeight )
6 // Este gráfico utiliza un color calculado. 7 trama(ma, "MA1",
color.rgb(156, 39, 176, transparencia), 2)
8 // Este gráfico no utiliza un color calculado. 9 trama(cerrar, "Cerrar", color.azul)

El color utilizado en el primer trazado es un color calculado porque su transparencia solo se puede conocer en tiempo de ejecución. Se calcula
utilizando la posición relativa de la media móvil en relación con sus últimos 100 valores. Cuanto mayor sea el porcentaje de valores pasados que
estén por debajo del valor actual, mayor será el valor 0­100 de maHeight. Como queremos que el color sea el más oscuro cuando maHeight es 100,
le restamos 100 para obtener la transparencia cero. También limitamos el valor de transparencia calculado a un máximo de 80 para que siempre
permanezca visible.

Debido a que ese color calculado se usa en nuestro script, la pestaña "Configuración/Estilo" no mostrará ningún widget de color:

4.7. Colores 213


Machine Translated by Google

Manual del usuario de Pine Script™ v5

La solución para permitir a los usuarios de scripts controlar los colores utilizados es proporcionarles entradas personalizadas, como lo hacemos aquí:

1 //@versión=5
2 indicadores ("Colores calculados", "", verdadero) 3 colores maInput =
input.color(color.purple, "MA") 4 colores closeInput = input.color(color.blue, "Close")
5 float ma = ta .sma(close, 20) 6 float maHeight = ta.percentrank(ma, 100) 7 float
transparencia = math.min(80, 100 ­ maHeight)

8 // Este gráfico utiliza un color calculado. 9 trama(ma, "MA1",


color.new(maInput, transparencia), 2)
10 // Este gráfico no utiliza un color calculado. 11 trama(cerrar, "Cerrar",
cerrarEntrada)

Observe cómo la "Configuración" de nuestro script ahora muestra una pestaña "Entradas", donde hemos creado dos entradas de color. El primero usa
color.purple como valor predeterminado. Ya sea que el usuario del script cambie ese color o no, se usará en una llamada color.new() para generar una
transparencia calculada en la llamada plot() . La segunda entrada usa como valor predeterminado el color incorporado color.blue que usamos anteriormente
en la llamada a plot() , y simplemente úselo tal como está en la segunda llamada a plot() .

4.8 Rellenos

• Introducción

• Rellenos `plot()` y `hline()`

• Rellenos de línea

214 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.8.1 Introducción

Hay dos mecanismos diferentes dedicados a llenar el espacio entre los elementos visuales de Pine:

• La función fill() le permite colorear el fondo entre dos gráficos trazados usando plot() o dos líneas horizontales.
trazado usando hline().

• La función linefill.new() llena el espacio entre líneas creadas con line.new().

4.8.2 Rellenos `plot()` y `hline()`

La función fill() tiene dos firmas:

fill(plot1, plot2, color, título, editable, show_last, fillgaps) → void fill(hline1, hline2, color, título, editable, fillgaps)
→ void

Los argumentos utilizados para los parámetros plot1, plot2, hline1 y hline2 deben ser los ID devueltos por las llamadas plot() y hline() . La función
fill() es la única función integrada donde se utilizan estos ID.

Vea en este primer ejemplo cómo los ID devueltos por las llamadas plot() y hline() se capturan en las variables p1, p2, p3 y h1, h2, h3 y h4 para
reutilizarlos como argumentos fill() :

1 //@versión=5 2
indicador("Ejemplo 1") 3 p1 =
plot(math.sin(high)) 4 p2 =
plot(math.cos(low)) 5 p3 =
plot(math.sin(close) ) 6 llenar(p1, p3,
color.nuevo(color.rojo, 90)) 7 llenar(p2, p3, color.nuevo(color.azul,
90)) 8 h1 = líneah(0) 9 h2 = líneah(1.0 ) 10 h3 = líneah(0.5) 11
h4 = líneah(1.5) 12
relleno(h1, h2,
color.nuevo(color.amarillo,
90)) 13 relleno(h3, h4,
color.nuevo(color.lima, 90) )

4.8. Rellenos 215


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Debido a que fill() requiere dos ID de la misma función, a veces necesitamos usar una llamada a plot() donde de otro modo habríamos
usado una llamada a hline() , como en este ejemplo:

1 //@versión=5 2
indicador("Ejemplo 2") 3 src = cerrar

4 ma = ta.sma(src, 10) 5 osc = 100


* (ma ­ src) / ma 6 oscPlotID = plot(osc)

7 // Una `hline()` no funcionaría aquí porque se necesitan dos llamadas a `plot()`. 8 zeroPlotID = plot(0, "Zero", color.silver,
1, plot.style_circles) 9 fill(oscPlotID, zeroPlotID, color.new(color.blue, 90))

Debido a que se puede usar un “color de serie” como argumento para el parámetro de color en fill(), puedes usar constantes como
color. red o #FF001A, así como expresiones que calculan el color de cada barra, como en este ejemplo:

216 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5 2
indicador("Ejemplo 3", "", verdadero) 3 línea1 =
ta.sma(cerrar, 5) 4 línea2 = ta.sma(cerrar,
20) 5 p1PlotID = parcela(línea1) 6 p2PlotID
= plot(line2) 7 fill(p1PlotID, p2PlotID,
línea1 > línea2 ? color.new(color.green,
90) : color.new(color.
→rojo, 90))

4.8.3 Rellenos de línea

Los rellenos de línea son objetos que le permiten llenar el espacio entre dos dibujos lineales creados mediante la función line.new() . Se muestra un objeto de
relleno de línea en el gráfico cuando se llama a la función linefill.new() . La función tiene la siguiente firma:

linefill.new(línea1, línea2, color) → serie linefill

Los argumentos línea1 y línea2 son los ID de línea de las dos líneas que se van a completar. El argumento del color es el color del relleno. Cualquier par de dos
líneas solo puede tener un relleno de línea entre ellas, por lo que las llamadas sucesivas a linefill.new() en el mismo par de líneas reemplazarán el relleno de línea
anterior por uno nuevo. La función devuelve el ID del objeto de relleno de línea que creó, que se puede guardar en una variable para usar en la llamada
linefill.set_color() que cambiará el color de un relleno de línea existente.

El comportamiento de los rellenos de línea depende de las líneas a las que están adjuntos. Los rellenos de línea no se pueden mover directamente; sus
coordenadas siguen las de las líneas a las que están vinculados. Si ambas líneas se extienden en la misma dirección, el relleno de línea también se extenderá.

Tenga en cuenta que para que las extensiones de línea funcionen correctamente, la coordenada x1 de una línea debe ser menor que su coordenada x2. Si el
argumento x1 de una línea es mayor que su argumento x2 y se usa extend.left, la línea en realidad se extenderá hacia la derecha porque se supone que x2 es la
coordenada x más a la derecha .

En el siguiente ejemplo, nuestro indicador dibuja dos líneas que conectan los dos últimos puntos de pivote máximo y mínimo del gráfico. Extendemos las líneas
hacia la derecha para proyectar el movimiento a corto plazo del gráfico y llenamos el espacio entre ellas para mejorar la visibilidad del canal que crean las líneas:

4.8. Rellenos 217


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 indicador ("Canal", superposición = verdadero)
3

4 LARGO_IZQUIERDO = 15
5 LARGO_DERECHO = 5
6 pH = ta.pivothigh(LEN_LEFT, LEN_RIGHT)
7 pL = ta.pivotlow(LEN_LEFT, LEN_RIGHT)
8

9 // Índices de barra de puntos de pivote


10 pH_x1 = ta.valorcuando(pH, índice_barra, 1) ­ LEN_RIGHT
11 pH_x2 = ta.valorcuando(pH, índice_barra, 0) ­ LEN_RIGHT
12 pL_x1 = ta.valuewhen(pL, bar_index, 1) ­ LEN_RIGHT
13 pL_x2 = ta.valuewhen(pL, bar_index, 0) ­ LEN_RIGHT
14 // Valores de precio de los puntos de pivote
15 pH_y1 = ta.valorcuando(pH, pH, 1)
16 pH_y2 = ta.valorcuando(pH, pH, 0)
17 pL_y1 = ta.valorcuando(pL, pL, 1)
18 pL_y2 = ta.valorcuando(pL, pL, 0)
19

20 si barstate.islastconfirmedhistory
21 // Líneas
22 lH = línea.nueva(pH_x1, pH_y1, pH_x2, pH_y2, extender = extender.derecha)
23 lL = línea.nueva(pL_x1, pL_y1, pL_x2, pL_y2, extender = extender.derecha)
24 // Llenar
25 fillColor = cambiar
26 pH_y2 > pH_y1 y pL_y2 > pL_y1 => color.verde
27 pH_y2 < pH_y1 y pL_y2 < pL_y1 => color.rojo
28 => color.plata
29 linefill.new(lH, lL, color.new(fillColor, 90))

4.9 Entradas

• Introducción

• Funciones de entrada

• Parámetros de la función de entrada

• Tipos de entrada

• Otras características que afectan las entradas

• Consejos

218 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.9.1 Introducción
Las entradas permiten que los scripts reciban valores que los usuarios pueden cambiar. Usarlos para valores clave hará que sus scripts sean más
adaptables a las preferencias del usuario.

El siguiente script traza una media móvil simple (SMA) de 20 períodos utilizando ta.sma(close, 20). Si bien es simple de escribir, no es muy flexible porque
ese MA específico es todo lo que trazará:

1 //@versión=5 2
indicador("MA", "", verdadero) 3
plot(ta.sma(close, 20))

Si en cambio escribimos nuestro script de esta manera, se vuelve mucho más flexible porque sus usuarios podrán seleccionar: la fuente y la longitud que
quieren usar para el cálculo del MA.

1 //@versión=5 2
indicador("MA", "", verdadero) 3 fuenteInput
= entrada(cerrar, "Fuente") 4 longitudInput = entrada(20,
"Longitud") 5 plot(ta.sma(fuenteInput, longitudEntrada))

Solo se puede acceder a las entradas cuando se ejecuta un script en el gráfico. Los usuarios del script acceden a ellos a través del cuadro de diálogo
"Configuración" del script, al que se puede acceder mediante:

• Hacer doble clic en el nombre de un indicador en el gráfico

• Hacer clic derecho en el nombre del script y elegir el elemento "Configuración" en el menú desplegable.

• Elegir el elemento "Configuración" en el icono del menú "Más" (tres puntos) que aparece cuando uno pasa el cursor sobre el
nombre del indicador en el gráfico

• Hacer doble clic en el nombre del indicador en la ventana de datos (cuarto icono a la derecha del gráfico)

El cuadro de diálogo "Configuración" siempre contiene las pestañas "Estilo" y "Visibilidad", que permiten a los usuarios especificar sus preferencias sobre
las imágenes del script y los períodos de tiempo del gráfico donde debería estar visible.

Cuando un script contiene llamadas a funciones input.*(), aparece una pestaña "Entradas" en el cuadro de diálogo "Configuración".

En el flujo de ejecución de un script, las entradas se procesan cuando el script ya está en un gráfico y un usuario cambia los valores en la pestaña
"Entradas". Los cambios desencadenan una nueva ejecución del script en todas las barras del gráfico, de modo que cuando un usuario cambia un valor de
entrada, el script vuelve a calcular utilizando ese nuevo valor.

4.9. Entradas 219


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.9.2 Funciones de entrada

Están disponibles las siguientes funciones de entrada:

• aporte()

• entrada.int()

• entrada.float()

• entrada.bool()

• entrada.color()

• entrada.cadena()

• entrada.plazo()

• entrada.símbolo()

• entrada.precio()

• fuente de entrada()

• entrada.sesión()

• entrada.hora()

Se crea un widget de entrada específico en la pestaña "Entradas" para aceptar cada tipo de entrada. A menos que se especifique lo contrario en la llamada
input.*(), cada entrada aparece en una nueva línea de la pestaña "Entradas", en el orden en que aparecen las llamadas input.*() en el script.

Nuestra guía de estilo recomienda colocar llamadas input.*() al principio del script.

Las definiciones de funciones de entrada suelen contener muchos parámetros que le permiten controlar el valor predeterminado de las entradas, sus límites y
su organización en la pestaña "Entradas".

Una llamada input*.() es simplemente otra llamada a función en Pine Script™, su resultado se puede combinar con operadores aritméticos, de comparación,
lógicos o ternarios para formar una expresión que se asignará a la variable. Aquí, comparamos el resultado de nuestra llamada a input.string() con la cadena
"On". Luego, el resultado de la expresión se almacena en la variable plotDisplayInput.
Dado que esa variable tiene un valor verdadero o falso, es del tipo “input bool”:

1 //@version=5 2
indicador("Ingrese una expresión`", "", verdadero) 3 bool plotDisplayInput =
input.string("Activado", "Visualización de trazado", opciones = ["Activado", "Desactivado" ])
→== "Activado"
4 trama (plotDisplayInput? cerrar: na)

Todos los valores devueltos por las funciones input.*() excepto los de “fuente” son valores calificados de “entrada”. Consulte la sección de calificadores de tipo
de nuestro Manual de usuario para obtener más información.

4.9.3 Parámetros de la función de entrada

Los parámetros comunes a todas las funciones de entrada son: defval, título, información sobre herramientas, en línea y grupo. Algunos parámetros son
utilizados por otras funciones de entrada: opciones, minval, maxval, paso y confirmación.

Todos estos parámetros esperan argumentos "constantes" (excepto si es una entrada utilizada para una "fuente", que devuelve un resultado de "serie
flotante"). Esto significa que deben conocerse en el momento de la compilación y no pueden cambiar durante la ejecución del script. Debido a que el resultado
de una función input.*() siempre se califica como “entrada” o “serie”, se deduce que el resultado de una llamada a la función input.*() no se puede utilizar
como argumento en una entrada posterior.*( ) llama porque el calificador "entrada" es más fuerte que "const".

Repasemos cada parámetro:

220 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• defval es el primer parámetro de todas las funciones de entrada. Es el valor predeterminado que aparecerá en el widget de entrada. Él
requiere un argumento del tipo de valor de entrada para el que se utiliza la función.

• el título requiere un argumento de “cadena constante”. Es la etiqueta del campo.

• La información sobre herramientas requiere un argumento de “cadena constante”. Cuando se utiliza el parámetro, aparecerá un icono de signo de interrogación
a la derecha del campo. Cuando los usuarios pasan el cursor sobre él, aparecerá el texto de información sobre herramientas. Tenga en cuenta que si se
agrupan varios campos de entrada en una línea usando inline, la información sobre herramientas siempre aparecerá a la derecha del campo más a la derecha
y mostrará el texto del último argumento de información sobre herramientas utilizado en la línea. Las nuevas líneas (\n) se admiten en la cadena de argumento.

• inline requiere un argumento de “cadena constante”. Usar el mismo argumento para el parámetro en múltiples llamadas input.*() agrupará sus
widgets de entrada en la misma línea. Hay un límite en el ancho que se expandirá la pestaña "Entradas", por lo que se puede incluir una cantidad
limitada de campos de entrada en una línea. El uso de una llamada input.*() con un argumento único para inline tiene el efecto de llevar el campo
de entrada a la izquierda, inmediatamente después de la etiqueta, renunciando a la alineación izquierda predeterminada de todos los campos de
entrada utilizados cuando no se utiliza ningún argumento en línea.


El grupo requiere un argumento de "cadena constante". Solía agrupar cualquier número de entradas en la misma sección. La cadena utilizada como
argumento de grupo se convierte en el encabezado de la sección. Todas las llamadas input.*() que se agruparán deben usar la misma cadena para
su argumento de grupo.

• opciones requiere una lista de elementos separados por comas entre corchetes (por ejemplo, ["ON", "OFF"]. Se utiliza para crear un menú desplegable
que ofrece los elementos de la lista en forma de selecciones de menú. Solo un elemento de menú se puede seleccionar Cuando se utiliza una lista
de opciones, el valor defval debe ser uno de los elementos de la lista.
Cuando se usan opciones en funciones de entrada que permiten minval, maxval o step, esos parámetros no se pueden usar simultáneamente.

• minval requiere un argumento “const int/float”, dependiendo del tipo de valor defval. es el minimo
valor válido para el campo de entrada.

• maxval requiere un argumento “const int/float”, dependiendo del tipo de valor defval. es el maximo
valor válido para el campo de entrada.

• paso es el incremento por el cual se moverá el valor del campo cuando se utilicen las flechas arriba/abajo del widget.

• confirmar requiere un argumento “const bool” (verdadero o falso). Este parámetro afecta el comportamiento del script cuando se agrega a un gráfico.
Las llamadas input.*() usando confirm = true harán que aparezca la pestaña "Configuración/Entradas" cuando se agregue el script al gráfico.
confirmar es útil para garantizar que los usuarios configuren un campo en particular.

Los parámetros minval, maxval y step solo están presentes en la firma de las funciones input.int() y input.float() .

4.9.4 Tipos de entrada

Las siguientes secciones explican qué hace cada función de entrada. A medida que avancemos, exploraremos las diferentes formas en que puede utilizar
las funciones de entrada y organizar su visualización.

Entrada sencilla

input() es una función simple y genérica que admite los tipos fundamentales de Pine Script™: “int”, “float”, “bool”, “color” y “string”. También admite entradas
de "fuente", que son valores relacionados con el precio, como close, hl2, hlc3 y hlcc4, o que pueden usarse para recibir el valor de salida de otro script.

Su firma es:

entrada (defval, título, información sobre herramientas, en línea, grupo) → entrada int/float/bool/color/string |
→flotador de serie

4.9. Entradas 221


Machine Translated by Google

Manual del usuario de Pine Script™ v5

La función detecta automáticamente el tipo de entrada analizando el tipo de argumento defval utilizado en la llamada a la función. Este script
muestra todos los tipos admitidos y el tipo calificado devuelto por la función cuando se usa con argumentos defval de diferentes tipos:

1 //@versión=5 2
indicador("`input()`", "", verdadero) 3 a = input(1,
"input int") 4 b = input(1.0, "input float") 5 c
= entrada(verdadero, "entrada bool") 6 d =
entrada(color.orange, "color de entrada") 7 e =
entrada("1", "cadena de entrada") 8 f = entrada(cerrar, "serie
flotante") 9 trama (n.a.)

entrada de números enteros

Existen dos firmas para la función input.int() ; uno cuando no se usan opciones, el otro cuando sí:

input.int(defval, título, minval, maxval, paso, información sobre herramientas, en línea, grupo, confirmar) → →entrada int
input.int(defval,
título, opciones, información sobre herramientas, en línea, grupo, confirmar) → entrada int

Esta llamada utiliza el parámetro de opciones para proponer una lista predefinida de longitudes para el MA:

1 //@versión=5 2
indicador("MA", "", verdadero) 3
maLengthInput = input.int(10, opciones = [3, 5, 7, 10, 14, 20, 50, 100, 200]) 4 ma = ta.sma(cerrar, maLengthInput) 5
trama(ma)

Este usa el parámetro minval para limitar la longitud:

1 //@versión=5 2
indicador("MA", "", verdadero) 3
maLengthInput = input.int(10, minval = 2) 4 ma = ta.sma(close,
maLengthInput) 5 plot(ma)

La versión con la lista de opciones utiliza un menú desplegable para su widget. Cuando no se utiliza el parámetro de opciones, se utiliza un
widget de entrada simple para ingresar el valor.

222 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Entrada flotante

Existen dos firmas para la función input.float() ; uno cuando no se usan opciones, el otro cuando sí:

input.int(defval, título, minval, maxval, paso, información sobre herramientas, en línea, grupo, confirmar) →
→entrada interna
input.int(defval, título, opciones, información sobre herramientas, en línea, grupo, confirmar) → input int

Aquí utilizamos una entrada "flotante" para el factor utilizado para multiplicar la desviación estándar para calcular las Bandas de Bollinger:

1 //@version=5 2
indicador("MA", "", verdadero) 3
maLengthInput = input.int(10, minval = 1) 4 bbFactorInput =
input.float(1.5, minval = 0, paso = 0.5)
5 ma = ta.sma(cerrar, maLongitudEntrada)
6 bbWidth = ta.stdev(ma, maLengthInput) * bbFactorInput 7 bbHi = ma + bbWidth

8 bbLo = ma ­ bbAncho
9 trazado(ma)
10 trazado(bbHi, "BB Hi", color.gris) 11 trazado(bbLo,
"BB Lo", color.gris)

Los widgets de entrada para flotantes son similares a los utilizados para entradas de números enteros.

4.9. Entradas 223


Machine Translated by Google

Manual del usuario de Pine Script™ v5

entrada booleana

Sigamos desarrollando nuestro script aún más, esta vez agregando una entrada booleana para permitir a los usuarios alternar la visualización del
BB:

1 //@version=5 2
indicador("MA", "", verdadero) 3 maLengthInput
= input.int(10, 4 bbFactorInput = input.float(1.5, "Longitud MA", minval = 1)
"Factor BB", inline = "01", minval = 0, paso = 0,5) 5 showBBInput = input.bool(true, "Mostrar BB", en línea = "01")

6 ma = ta.sma(cerrar, maLongitudEntrada)
7 bbWidth = ta.stdev(ma, maLengthInput) * bbFactorInput 8 bbHi = ma + bbWidth

9 bbLo = ma ­ bbAncho
10 plot(ma, "MA", color.aqua) 11
plot(showBBInput? bbHi: na, "BB Hi", color.gray) 12 plot(showBBInput? bbLo: na, "BB
Lo", color.gray)

Tenga en cuenta que:

• Hemos agregado una entrada usando input.bool() para establecer el valor de showBBInput.

• Usamos el parámetro inline en esa entrada y en la de bbFactorInput para ponerlos en la misma línea.
Usamos "01" como argumento en ambos casos. Así es como el compilador Pine Script™ reconoce que pertenecen a la misma línea. La
cadena particular utilizada como argumento no es importante y no aparece en ninguna parte de la pestaña "Entradas"; solo se usa para
identificar qué entradas van en la misma línea.

• Hemos alineado verticalmente los argumentos del título de nuestras llamadas input.*() para que sean más fáciles de leer.

• Usamos la variable showBBInput en nuestras dos llamadas a plot() para trazar condicionalmente. Cuando el usuario desmarca la casilla de
verificación de la entrada showBBInput, el valor de la variable se vuelve falso. Cuando eso sucede, nuestras llamadas plot() trazan el valor
na , que no muestra nada. Usamos verdadero como valor predeterminado de la entrada, por lo que los BB se trazan de forma predeterminada.

• Debido a que utilizamos el parámetro en línea para la variable bbFactorInput, su campo de entrada en la pestaña "Entradas" no
no se alinea verticalmente con el de maLengthInput, que no usa en línea.

224 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Entrada de color

Como se explica en la sección Selección de color mediante configuración de script de la página “Colores”, las selecciones de color que normalmente
que aparecen en la pestaña “Configuración/Estilo” no siempre están disponibles. Cuando ese sea el caso, los usuarios del script no tendrán medios para cambiar
los colores que utiliza tu guión. Para esos casos, es esencial proporcionar entradas de color si desea que los colores de su guión sean
modificable a través de la “Configuración” del script. En lugar de utilizar la pestaña "Configuración/Estilo" para cambiar los colores, permitirá que
los usuarios de su script cambien los colores usando llamadas a input.color().

Supongamos que queremos trazar nuestras BB en un tono más claro cuando los valores alto y bajo son mayores/inferiores que las BB. Tú
Podría usar un código como este para crear tus colores:

bbHiColor = color.nuevo(color.gris, alto > bbHi ? 60 : 0)


bbLoColor = color.nuevo(color.gris, bajo < bbLo ? 60 : 0)

Cuando se utilizan componentes de color dinámicos (o "series") como la transparencia aquí, los widgets de color en "Configuración/Estilo"
ya no aparecerá. Creemos el nuestro propio, que aparecerá en nuestra pestaña “Entradas”:

1 //@versión=5
2 indicadores("MA", "", verdadero)
3 maLengthInput = input.int(10, 4 maColorInput = "Longitud MA", en línea = "01", minval = 1)
input.color(color.aqua, "", 5 bbFactorInput = input.float(1.5, →= 0.5) en línea = "01")
"Factor BB", en línea = "02", minval = 0, paso

6 bbColorInput = input.color(color.gray, "", 7 showBBInput = input.bool(true, en línea = "02")


= ta.sma(close, maLengthInput) "Mostrar BB", en línea = "02")
8 ma

9 bbWidth = ta.stdev(ma, maLengthInput) * bbFactorInput


10 bbHola = ma + bbAncho
11 bbLo = ma ­ bbAncho
12 bbHiColor = color.new(bbColorInput, alto > bbHi ? 60 : 0)
13 bbLoColor = color.new(bbColorInput, bajo < bbLo ? 60 : 0)
14 trama(ma, "MA", maColorInput)
15 trazado (showBBInput? bbHi: na, "BB Hi", bbHiColor, 2)
16 trama (showBBInput? bbLo: na, "BB Lo", bbLoColor, 2)

Tenga en cuenta que:

• Hemos agregado dos llamadas a input.color() para recopilar los valores de maColorInput y bbColorInput.
variables. Usamos maColorInput directamente en la llamada plot(ma, "MA", maColorInput) y usamos
bbColorInput para construir las variables bbHiColor y bbLoColor, que modulan la transparencia usando

4.9. Entradas 225


Machine Translated by Google

Manual del usuario de Pine Script™ v5

la posición del precio en relación con los BB. Usamos un valor condicional para el valor de transp con el que llamamos color.new() , para
generar diferentes transparencias del mismo color base.

• No utilizamos un argumento de título para nuestras nuevas entradas de color porque están en la misma línea que otras entradas, lo que
permite a los usuarios comprender a qué gráficos se aplican.

• Hemos reorganizado nuestros argumentos en línea para que reflejen el hecho de que tenemos entradas agrupadas en dos líneas distintas.

Entrada de plazo

Las entradas de período de tiempo pueden ser útiles cuando desea poder cambiar el período de tiempo utilizado para calcular los valores en sus secuencias de comandos.

Eliminemos nuestros BB de las secciones anteriores y agreguemos una entrada de marco de tiempo a un script MA simple:

1 //@version=5 2
indicador("MA", "", verdadero) 3 tfInput =
input.timeframe("D", "Timeframe") 4 ma = ta.sma(close, 20) 5
securityNoRepaint(sym, tf, src) =>
request.security(sym, tf, src[barstate.isrealtime? 1: 0])
6 [barstate.isrealtime ? →0: 1]

7 maHTF = seguridadNoRepaint(syminfo.tickerid, tfInput, ma) 8 plot(maHTF, "MA", color.aqua)

Tenga en cuenta que:

• Usamos la función input.timeframe() para recibir la entrada del marco temporal.

• La función crea un widget desplegable donde se proponen algunos plazos estándar. La lista de plazos
También incluye cualquiera que haya marcado como favorito en la interfaz de usuario de la carta.

• Usamos tfInput en nuestra llamada request.security() . También usamos gaps = barmerge.gaps_on en la llamada, por lo que la función
solo devuelve datos cuando se completa el período de tiempo superior.

226 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Entrada de símbolo

La función input.symbol() crea un widget que permite a los usuarios buscar y seleccionar símbolos como lo harían en la interfaz de usuario del gráfico.

Agreguemos una entrada de símbolo a nuestro script:

1 //@version=5 2
indicador("MA", "", verdadero) 3 tfInput =
input.timeframe("D", "Timeframe") 4 symbolInput = input.symbol("",
"Symbol") 5 ma = ta.sma(cerrar, 20) 6 seguridadNoRepaint(sym,
tf, src) => request.security(sym, tf,
src[barstate.isrealtime? 1: 0])[barstate.isrealtime ? →0:
7 1]

8 maHTF = seguridadNoRepaint(symbolInput, tfInput, ma) 9 plot(maHTF, "MA", color.aqua)

Tenga en cuenta que:

• El argumento defval que utilizamos es una cadena vacía. Esto hace que request.security(), donde usamos la variable symbolInput que contiene esa entrada, use
el símbolo del gráfico de forma predeterminada. Si el usuario selecciona otro símbolo y desea volver al valor predeterminado usando el símbolo del gráfico,
deberá usar la selección "Restablecer configuración" del menú "Valores predeterminados" de la pestaña "Entradas".

• Usamos la función definida por el usuario securityNoRepaint() para usar request.security() de tal manera que no se vuelva a pintar; solo devuelve valores cuando
se ha completado el período de tiempo más alto.

4.9. Entradas 227


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Entrada de sesión

Las entradas de sesión son útiles para recopilar valores de inicio y fin durante períodos de tiempo. La función incorporada input.session() crea un
widget de entrada que permite a los usuarios especificar la hora de inicio y finalización de una sesión. Las selecciones se pueden realizar usando un
menú desplegable o ingresando valores de tiempo en formato “hh:mm”.

El valor devuelto por input.session() es una cadena válida en formato de sesión. Consulte la página del manual sobre sesiones para obtener más
información.

La información de la sesión también puede contener información sobre los días en que la sesión es válida. Usamos una llamada a la función
input.string() aquí para ingresar la información de ese día:

1 //@versión=5 2
indicador("Entrada de sesión", "", verdadero) 3 cadenas
sessionInput = input.session("0600­1700", "Sesión") 4 cadenas daysInput = input.string("1234567",
información sobre herramientas = "1 = domingo, 7 = sábado") 5 sessionString = sessionInput + ":" + daysInput 6 inSession = not
na(time(timeframe.period, sessionString)) 7 bgcolor(inSession? color.silver :
na)

Tenga en cuenta que:

• Este script propone una sesión predeterminada de “0600­1700”.

• La llamada input.string() utiliza información sobre herramientas para proporcionar a los usuarios ayuda sobre el formato a utilizar para ingresar información del día.

• Se construye una cadena de sesión completa concatenando las dos cadenas que el script recibe como entradas.

• Declaramos explícitamente el tipo de nuestras dos entradas con la palabra clave string para dejar claro que esas variables contendrán
una cuerda.

• Detectamos si la barra del gráfico está en la sesión definida por el usuario llamando a time() con la cadena de sesión. Si el valor de tiempo de
la barra actual (el tiempo en el que se abrió la barra ) no está en la sesión, time() devuelve na, por lo que inSession será verdadero siempre
que time() devuelva un valor que no sea na.

228 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Entrada de fuente

Las entradas de fuentes son útiles para proporcionar una selección de dos tipos de fuentes:

• Valores de precios, a saber: apertura, máximo, mínimo, cierre, hl2, hlc3 y ohlc4.

• Los valores trazados por otros scripts en el gráfico. Esto puede resultar útil para "vincular" dos o más scripts enviando
la salida de uno como entrada a otro script.

Este script simplemente traza la selección de fuente por parte del usuario. Proponemos el máximo como valor predeterminado:

1 //@versión=5 2
indicador("Fuente de entrada", "", verdadero) 3 srcInput =
input.source(high, "Fuente") 4 plot(srcInput, "Src",
color.new(color.purple, 70), 6)

Esto muestra un gráfico donde, además de nuestro script, hemos cargado un indicador de “Promedio móvil de Arnaud Legoux”. Vea aquí cómo utilizamos el
widget de entrada de origen de nuestro script para seleccionar la salida del script de ALMA como entrada a nuestro script.
Debido a que nuestro script traza esa fuente en una línea gruesa de color violeta claro, verá que los gráficos de los dos scripts se superponen porque trazan el
mismo valor:

Entrada de tiempo

Las entradas de tiempo utilizan la función input.time() . La función devuelve una hora Unix en milisegundos (consulte la página Hora para obtener más
información). Este tipo de datos también contiene información de fecha, por lo que la función input.time() devuelve una hora y una fecha.
Es por eso que su widget permite la selección de ambos.

Aquí, probamos el tiempo de la barra con un valor de entrada y trazamos una flecha cuando es mayor:

1 //@version=5 2
indicador("Entrada de hora", "T", verdadero) 3
timeAndDateInput = input.time(timestamp("1 de agosto de 2021 00:00 +0300"), "Fecha y hora") 4 barIsLater = hora > timeAndDateInput
5 plotchar(barIsLater, "barIsLater", "", ubicación.arriba,
tamaño = tamaño.tiny)

Tenga en cuenta que el valor defval que utilizamos es una llamada a la función timestamp() .

4.9. Entradas 229


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.9.5 Otras características que afectan las entradas

Algunos parámetros de la función indicador(), cuando se utilizan, llenarán la pestaña "Entradas" del script con un campo. Los parámetros son timeframe y
timeframe_gaps. Un ejemplo:

1 //@version=5 2
indicador("MA", "", true, timeframe = "D", timeframe_gaps = false) 3 plot(ta.vwma(close, 10))

4.9.6 Consejos

El diseño de las entradas de su script tiene un impacto importante en la usabilidad de sus scripts. Las entradas bien diseñadas son más intuitivas y mejoran la
experiencia del usuario:

• Elija etiquetas claras y concisas (el argumento del título de su entrada).

• Elija sus valores predeterminados con cuidado.

• Proporcione valores minval y maxval que evitarán que su código produzca resultados inesperados; por ejemplo, limite el valor mínimo de longitudes a 1 o
2, según el tipo de MA que esté utilizando.

• Proporcione un valor de paso que sea congruente con el valor que está capturando. Los pasos de 5 pueden ser más útiles en un rango de 0 a 200, por
ejemplo, o pasos de 0,05 en una escala de 0,0 a 1,0.

• Agrupar entradas relacionadas en la misma línea usando inline; colores alcistas y bajistas, por ejemplo, o el ancho y color de
una línea.

• Cuando tenga muchas entradas, agrúpelas en secciones significativas usando grupo. Coloca las secciones más importantes.
en la cima.

• Haga lo mismo con las entradas individuales dentro de las secciones.

Puede resultar ventajoso alinear verticalmente diferentes argumentos de múltiples llamadas input.*() en su código. Cuando necesite realizar cambios globales,
esto le permitirá utilizar la función de cursor múltiple del Editor para operar en todas las líneas a la vez.

Porque a veces es necesario utilizar espacios Unicode para lograr una alineación óptima en las entradas. Esto es un ejemplo:

1 //@versión=5
2 indicadores ("Entradas alineadas", "", verdadero)
3

4 var GRP1 = "No alineado"


(continúa en la página siguiente)

230 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

5 ma1SourceInput = entrada(cerrar, "Fuente MA", en línea = "11", grupo = GRP1) 6 ma1LongitudInput = entrada(cerrar, "Longitud", en
línea = "11", grupo = GRP1) 7 long1SourceInput = entrada(cerrar, "Fuente de señal", en línea = "12", grupo = GRP1) 8 long1LengthInput
= entrada(cerrar, "Longitud", en línea = "12", grupo = GRP1)

10 var GRP2 = "Alineado"


11 // Los tres espacios después de "fuente MA" son espacios Unicode EN (U+2002). 12 ma2SourceInput = entrada(cerrar,
"Fuente MA", en línea = "21", grupo = GRP2) 13 ma2LengthInput = entrada(cerrar, "Longitud", en línea = "21", grupo = GRP2) 14
long2SourceInput = entrada(cerrar, "Fuente de señal", en línea = "22", grupo = GRP2) 15 long2LengthInput = entrada(cerrar, "Longitud",
en línea = "22", grupo = GRP2)

dieciséis

17 trama (ta.vwma (cerrar, 10))

Tenga en cuenta que:

• Usamos el parámetro de grupo para distinguir entre las dos secciones de entradas. Usamos una constante para contener el nombre
de los grupos. De esta forma, si decidimos cambiar el nombre del grupo, sólo necesitaremos cambiarlo en un lugar.

• Los widgets de entrada de las primeras secciones no se alinean verticalmente. Estamos usando en línea, que coloca los widgets de
entrada inmediatamente a la derecha de la etiqueta. Debido a que las etiquetas para las entradas ma1SourceInput y long1SourceInput
tienen diferentes longitudes, las etiquetas están en diferentes posiciones y .

• Para compensar la desalineación, rellenamos el argumento del título en la línea ma2SourceInput con tres espacios Unicode EN
(U+2002). Los espacios Unicode son necesarios porque los espacios normales se eliminarían de la etiqueta. Puede lograr una
alineación precisa combinando diferentes cantidades y tipos de espacios Unicode. Consulte aquí para obtener una lista de espacios
Unicode de diferentes anchos.

4.9. Entradas 231


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.10 niveles

• niveles `hline()`

• Rellenos entre niveles

4.10.1 niveles `hline()`

Los niveles son líneas trazadas usando la función hline() . Está diseñado para trazar niveles horizontales usando un solo color, es decir, no
cambia en diferentes barras. Consulte la sección Niveles de la página sobre plot() para conocer formas alternativas de trazar niveles cuando
hline() no hace lo que necesita.

La función tiene la siguiente firma:

hline(precio, título, color, estilo de línea, ancho de línea, editable) → hline

hline() tiene algunas limitaciones en comparación con plot():

• Dado que el objetivo de la función es trazar líneas horizontales, su parámetro de precio requiere un argumento “entrada int/float”.
lo que significa que no se pueden utilizar valores de “serie flotante”, como valores cercanos o calculados dinámicamente.

• Su parámetro de color requiere un argumento “input int”, lo que excluye el uso de colores dinámicos, es decir, colores
calculado en cada barra, o valores de “color de serie”.

• Se admiten tres estilos de línea diferentes a través del parámetro estilo de línea: hline.style_solid, hline. style_dotted y hline.style_dasshed.

Veamos hline() en acción en el indicador "Índice de fuerza real":

1 //@versión=5
2 indicador("TSI") 3 myTSI =
100 * ta.tsi(cerrar, 25, 13)
4

5 hline( 50, "+50", color.lima) 6 hline( 25, "+25",


color.verde) 7 hline( 0, "Cero", color.gris, estilo de línea
= hline.style_dotted) 8 hline( ­25, "­25", color.granate) 9 hline(­50, "­50", color.rojo)

10

11 parcela (miTSI)

232 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Tenga en cuenta que:

• Mostramos 5 niveles, cada uno de un color diferente.

• Usamos un estilo de línea diferente para la línea central cero.

• Elegimos colores que funcionarán bien tanto en temas claros como oscuros.

• El rango habitual para los valores del indicador es de +100 a ­100. Dado que el ta.tsi() incorporado devuelve valores en el rango de +1 a ­1
rango, hacemos el ajuste en nuestro código.

4.10.2 Rellenos entre niveles

El espacio entre dos niveles trazados con hline() se puede colorear usando fill(). Tenga en cuenta que ambos gráficos deben haberse trazado
con hline().

Pongamos algunos colores de fondo en nuestro indicador TSI:

1 //@versión=5
2 indicadores("TSI")
3 miTSI = 100 * ta.tsi(cerrar, 25, 13)
4

5 plus50Hline = hline( 50, "+50", color.lima) 6 plus25Hline = hline( 25, "+25", color.verde)
7 zeroHline = hline( 0, "Cero", color.gris, estilo de línea = hline .style_dotted)

8 menos25Hline = hline(­25, "­25", color.granate) 9 minus50Hline = hline(­50, "­50", color.rojo)

10

11 // ————— La función devuelve un color en un tono claro para usarlo como fondo. 12 fillColor(col color) => color.new(col, 90)

13

14

15 fill(plus50Hline, plus25Hline, fillColor(color.lime)) 16 fill(plus25Hline, zeroHline, fillColor(color.teal)) 17


fill(zeroHline, minus25Hline, fillColor(color.maroon)) 18 fill(minus25Hline, minus50Hline, fillColor (color rojo))

19

20 parcela (miTSI)

4.10. Niveles 233


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Tenga en cuenta que:

• Ahora hemos utilizado el valor de retorno de nuestras llamadas a la función hline() , que es del tipo especial hline . Usamos las variables plus50Hline,
plus25Hline, zeroHline, minus25Hline y minus50Hline para almacenar esos ID de "hline" porque los necesitaremos en nuestras llamadas fill() más
adelante.

• Para generar tonos de color más claros para los colores de fondo, declaramos una función fillColor() que acepta un color y devuelve su transparencia
90. Usamos llamadas a esa función para los argumentos de color en nuestras llamadas fill() .

• Hacemos nuestras llamadas fill() para cada uno de los cuatro rellenos diferentes que queremos, entre cuatro pares diferentes de niveles.

• Usamos color.teal en nuestro segundo relleno porque produce un verde que se adapta mejor al esquema de color que el
color.green usado para el nivel 25.

4.11 Bibliotecas

• Introducción

• Crear una biblioteca

• Publicar una biblioteca

• Usando una biblioteca

234 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.11.1 Introducción

Las bibliotecas Pine Script™ son publicaciones que contienen funciones que se pueden reutilizar en indicadores, estrategias o en otras bibliotecas. Son útiles para
definir funciones de uso frecuente, de modo que su código fuente no tenga que incluirse en cada script donde sean necesarios.

Una biblioteca debe publicarse (de forma privada o pública) antes de poder utilizarse en otro script. Todas las bibliotecas se publican en código abierto. Los scripts
públicos solo pueden utilizar bibliotecas públicas y deben ser de código abierto. Los scripts privados o los scripts personales guardados en Pine Script™ Editor
pueden utilizar bibliotecas públicas o privadas. Una biblioteca puede utilizar otras bibliotecas o incluso versiones anteriores de sí misma.

Los programadores de bibliotecas deben estar familiarizados con la nomenclatura de escritura, los alcances y las funciones definidas por el usuario de Pine Script™.
Si necesita repasar los tipos calificados, consulte la página del Manual del usuario en el sistema de tipos. Para obtener más información sobre funciones y alcances
definidos por el usuario, consulte la página Funciones definidas por el usuario .

Puede explorar los scripts de la biblioteca publicados públicamente por los miembros en los scripts de la comunidad de TradingView.

4.11.2 Crear una biblioteca


Una biblioteca es un tipo especial de script que comienza con la declaración de biblioteca() , en lugar de con indicador() o estrategia().
Una biblioteca contiene definiciones de funciones exportables, que constituyen la única parte visible de la biblioteca cuando la utiliza otro script. Las bibliotecas
también pueden utilizar otro código Pine Script™ en su ámbito global, como un indicador normal. Este código normalmente servirá para demostrar cómo utilizar las
funciones de la biblioteca.

Un script de biblioteca tiene la siguiente estructura, donde se deben definir una o más funciones exportables:

1 //@versión=5
2

3 // @description <biblioteca_descripción> 4 biblioteca(título, superposición)

6 <código_script>
7

8 // @function <descripción_función> 9 // @param <parámetro>


<descripción_parámetro> 10 // @returns <descripción_valor_retorno> 11 export
<nombre_función>([simple/serie] <tipo_parámetro> <nombre_parámetro> [=
<predeterminado_
→valor>] [, ...]) =>
12 <código_función>
13

14 <código_script>

Tenga en cuenta que:

• Las anotaciones del compilador // @description, // @function, // @param y // @returns son opcionales, pero le recomendamos encarecidamente que las
utilice. Tienen un doble propósito: documentar el código de la biblioteca y completar la descripción de la biblioteca predeterminada que los autores pueden
usar al publicar la biblioteca.

• La palabra clave exportar es obligatoria.

• <parameter_type> es obligatorio, al contrario de las definiciones de parámetros de funciones definidas por el usuario en indicadores o estrategias,
que no tienen tipo.

• <script_code> puede ser cualquier código que normalmente usaría en un indicador, incluidas entradas o gráficos.

Esta es una biblioteca de ejemplo:

4.11. Bibliotecas 235


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2

3 // @description Proporciona funciones que calculan los valores máximos/mínimos de todos los tiempos. 4 biblioteca ("AllTimeHighLow", verdadero)

6 // @function Calcula el máximo histórico de una serie. 7 // @param val Serie a usar (se usa `high` si no se
proporciona ningún argumento). 8 // @returns El máximo histórico de la serie. 9 exportar alto (valor flotante = alto) =>

10 var flotador ath = val


11 ath := matemáticas.max(ath, val)
12

13 // @function Calcula el mínimo histórico de una serie. 14 // @param val Serie a usar (se usa `low` si no se

proporciona ningún argumento). 15 // @returns El mínimo histórico de la serie. 16 exportar lo (val flotante = bajo) => var flotante atl = val

17

18 atl := matemáticas.min(atl, val)


19

20 trama(hola()) 21
trama(lo())

Funciones de biblioteca

Las definiciones de funciones en las bibliotecas son ligeramente diferentes a las de las funciones definidas por el usuario en indicadores y estrategias.
Existen limitaciones en cuanto a lo que se puede incluir en el cuerpo de funciones de la biblioteca.

En firmas de funciones de biblioteca (su primera línea):

• La palabra clave exportar es obligatoria.

• Se debe mencionar explícitamente el tipo de argumento esperado para cada parámetro.

• Una palabra clave simple o de serie puede restringir los tipos de argumentos calificados permitidos (la siguiente sección explica sus
usar).

Estas son las restricciones impuestas a las funciones de la biblioteca:

• No pueden utilizar variables del ámbito global de la biblioteca a menos que estén calificadas como “const”. Esto significa tu
No se pueden utilizar variables globales inicializadas a partir de entradas de script, por ejemplo, ni matrices declaradas globalmente.

• Las llamadas request.*() no están permitidas.

• Las llamadas input.*() no están permitidas.

• Las llamadas a plot*(), fill() y bgcolor() no están permitidas.

Las funciones de biblioteca siempre devuelven un resultado calificado como "simple" o "serie". No puede usarlos cuando se requieren valores calificados
“constantes” o “de entrada”, como es el caso de algunas funciones integradas. Por ejemplo, una función de biblioteca no se puede utilizar para calcular un
argumento para el parámetro show_last en una llamada a plot() porque requiere un valor de "entrada int".

236 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Control de tipo calificado

Los tipos calificados de argumentos proporcionados en llamadas a funciones de biblioteca se detectan automáticamente en función de cómo se usa cada
argumento dentro de la función. Si el argumento puede usarse como una “serie”, se califica como tal. Si no puede, se intenta con el calificador de tipo
“simple”. Esto explica por qué este código:

exportar miEma(int x) =>


ta.ema(cerca, x)

funcionará cuando se llame usando myCustomLibrary.myEma(20), aunque el parámetro de longitud de ta.ema() requiere un argumento “simple int”.
Cuando el compilador Pine Script™ detecta que no se puede utilizar una longitud de “serie” con ta.ema(), prueba el calificador “simple”, que en este caso
está permitido.

Si bien las funciones de la biblioteca no pueden devolver valores "constantes" o "de entrada", se pueden escribir para producir resultados "simples". Esto
los hace útiles en más contextos que las funciones que devuelven resultados en "series", ya que algunas funciones integradas no permiten argumentos
en "series". Por ejemplo, request.security() requiere una "cadena simple" para su parámetro de símbolo. Si escribiéramos una función de biblioteca para
ensamblar el argumento del símbolo de la siguiente manera, el resultado de la función no funcionaría porque es del tipo calificado "cadena de serie":

exportar makeTickerid(prefijo de cadena, ticker de cadena) =>


prefijo + ":" + teletipo

Sin embargo, al restringir los calificadores de parámetros a "simples", podemos forzar que la función produzca un resultado "simple". Podemos lograr esto
anteponiendo el tipo de parámetro con la palabra clave simple :

exportar makeTickerid (prefijo de cadena simple, ticker de cadena simple) =>


prefijo + ":" + teletipo

Tenga en cuenta que para que la función devuelva un valor "simple", no se pueden utilizar valores de "serie" en su cálculo; de lo contrario, el resultado
será un valor de "serie".

También se puede utilizar la palabra clave series para anteponer el tipo de parámetro de función de una biblioteca. Sin embargo, debido a que los argumentos se
califican como "series" de forma predeterminada, usar el modificador de serie es redundante.

Tipos y objetos definidos por el usuario

Puede exportar tipos definidos por el usuario (UDT) desde bibliotecas y las funciones de biblioteca pueden devolver objetos.

Para exportar un UDT, anteponga su definición con la palabra clave export tal como exportaría una función:

//@versión=5
biblioteca("Punto")

punto de tipo de
exportación int x
float y bool
es Hola
bool fue violado = falso

Un script que importe esa biblioteca y cree un objeto desde su punto UDT se vería así:

Tenga en cuenta que:

• Este código no se compilará porque no se publica ninguna biblioteca "Point" y el script no muestra nada.

• UserName debería sustituirse por el nombre de usuario de TradingView del editor de la biblioteca.

• Usamos el método incorporado new() para crear un objeto desde el punto UDT.

4.11. Bibliotecas 237


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Anteponemos la referencia al punto UDT de la biblioteca con el alias pt definido en la declaración de importación , tal como lo hicimos
lo haría al usar una función de una biblioteca importada.

Los UDT utilizados en una biblioteca deben exportarse si alguna de sus funciones exportadas usa un parámetro o devuelve un resultado de ese
tipo definido por el usuario.

Cuando una biblioteca solo usa un UDT internamente, no es necesario exportarlo. La siguiente biblioteca utiliza el punto UDT
internamente, pero sólo se exporta su función drawPivots(), que no utiliza un parámetro ni devuelve un resultado de
tipo de punto:

1 //@versión=5

2 biblioteca ("PivotLabels", verdadero)

4 // Usamos este UDT `punto` en la biblioteca, pero NO requiere exportación porque:

5 // 1. Los parámetros de la función exportada no utilizan el UDT.

6 // 2. La función exportada no devuelve un resultado UDT.

7 tipo punto

8 entero x
9 flotar y
10 bool es Hola
11 bool fue violado = falso
12

13

14 fillPivotsArray(qtyLabels, leftLegs, rightLegs) =>

15 // Crea una matriz de la cantidad especificada de pivotes para mantener.


dieciséis var pivotsArray = array.new<punto>(math.max(qtyLabels, 0))
17

18 // Detectar pivotes.
19 pivote flotanteHi = ta.pivothigh(piernasizquierda,piernasderecha)
20 float pivotLo = ta.pivotlow(piernasizquierdas, piernasderechas)
21

22 // Crea un nuevo objeto `punto` cuando se encuentra un pivote.


23 punto encontradoPunto = cambiar
24 pivotHola => punto.nuevo(tiempo[piernasderechas], pivotHola, verdadero)
25 pivotLo => punto.nuevo(tiempo[piernasderechas], pivotLo, falso)
26 => no
27

28 // Agrega nueva información de pivote a la matriz y elimina el pivote más antiguo.


29 si no es na (punto encontrado)
30 array.push(pivotsArray, foundPoint)
31 array.shift(pivotsArray)
32

33 matriz<punto> resultado = matrizpivotes


34

35

36 detectarBreaches(pivotsArray) =>

37 // Detectar infracciones.
38 para [i, cada punto] en pivotsArray
39 si no na(cadaPunto)
40 si no, cada punto.fue violado
41 bool hola fue violada = eachPoint.isHi y alto[1] <= eachPoint.y
→y alto > eachPoint.y
42 bool loWasBreached = no eachPoint.isHi y low[1] >= eachPoint.y
→y bajo < eachPoint.y
43 si se infringió alto o bajo
44 // Este pivote fue violado; cambie su campo `wasBreached`.
45 punto p = array.get(pivotsArray, i)
46 p.wasBreached: = verdadero
(continúa en la página siguiente)

238 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

47 array.set(pivotsArray, i, p)
48

49

50 drawLabels (matriz de pivotes) =>


51 para cada punto en pivotsArray
52 si no na(cadaPunto)
53 etiqueta.nueva(
54 cadapunto.x,
55 cadaPunto.y,
56 str.tostring(cadaPunto.y, formato.mintick),
57 xloc.bar_time,
58 color = eachPoint.wasBreached? color.gray: eachPoint.isHola? color.
→verde azulado : color.rojo,
59 estilo = eachPoint.isHola? etiqueta.style_label_down: etiqueta.style_label_up,
60 color de texto = eachPoint.wasBreached? color.plata : color.blanco)
61

62

63 // @función Muestra una etiqueta para cada uno de los últimos pivotes `qtyLabels`.
64 // Colorea los pivotes altos en verde, los pivotes bajos en rojo y violados
→pivotes en gris.
65 // @param qtyLabels (simple int) Cantidad de las últimas etiquetas a mostrar.
66 // @param leftLegs (simple int) Piernas de pivote izquierdas.
67 // @param rightLegs (simple int) Piernas de pivote derechas.
68 // @returns Nada.
69 exportar drawPivots(int qtyLabels, int leftLegs, int rightLegs) =>
70 // Reúna los pivotes a medida que se produzcan.
71 matriz de puntos = llenar matriz de pivotes (cantidad de etiquetas, piernas izquierdas, piernas derechas)
72

73 //Marca pivotes incumplidos.


74 detectar infracciones (matriz de puntos)
75

76 // Dibuja etiquetas una vez.


77 si barstate.islastconfirmedhistory
78 dibujarLabels(matriz de puntos)
79

80

81 // Ejemplo de uso de la función.


82 pivotes de sorteo (20, 10, 5)

Si el usuario de TradingView publicó la biblioteca anterior, podría usarse así:

4.11.3 Publicar una biblioteca

Antes de que usted u otros programadores de Pine Script™ puedan reutilizar cualquier biblioteca, debe publicarla. Si quieres compartir tu
biblioteca con todos los TradingViewers, publíquela públicamente. Para usarlo de forma privada, utilice una publicación privada. Al igual que con los indicadores
o estrategias, el gráfico activo cuando publique una biblioteca aparecerá tanto en su widget (el pequeño marcador de posición que indica
bibliotecas en la secuencia de scripts de TradingView) y la página de script (la página que los usuarios ven cuando hacen clic en el widget).

Las bibliotecas privadas se pueden utilizar en scripts públicos protegidos o solo por invitación.

Después de agregar nuestra biblioteca de ejemplo al gráfico y configurar un gráfico limpio que muestre los trazados de nuestra biblioteca como los queremos,
Usamos el botón “Publicar script” del editor Pine. Aparece la ventana "Publicar biblioteca":

4.11. Bibliotecas 239


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Tenga en cuenta que:

• Dejamos el título de la biblioteca como está (el argumento del título en nuestra declaración de biblioteca() se utiliza como valor predeterminado).
Si bien puede cambiar el título de la publicación, es preferible mantener su valor predeterminado porque el argumento del título se usa para hacer
referencia a bibliotecas importadas en la declaración de importación . Les facilita la vida a los usuarios de la biblioteca cuando el título de su publicación
coincide con el nombre real de la biblioteca.

• Se crea una descripción predeterminada a partir de las anotaciones del compilador que utilizamos en nuestra biblioteca. Publicaremos la biblioteca.
sin retocarlo.

• Elegimos publicar nuestra biblioteca públicamente, por lo que será visible para todos los TradingViewers.

• No tenemos la posibilidad de seleccionar un tipo de visibilidad que no sea “Abierto” porque las bibliotecas siempre están abiertas.
fuente.

• La lista de categorías para bibliotecas es diferente a la de indicadores y estrategias. Hemos seleccionado la opción “Estadísticas y
Categoría Métricas.

• Hemos agregado algunas etiquetas personalizadas: "todos los tiempos", "alto" y "bajo".

Los usuarios previstos de las bibliotecas públicas son otros programadores de Pine; cuanto mejor explique y documente las funciones de su biblioteca, más
posibilidades habrá de que otros las utilicen. También será útil proporcionar ejemplos que demuestren cómo utilizar las funciones de su biblioteca en el código
de su publicación.

240 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Reglas de casa

Las bibliotecas de Pine se consideran código de “dominio público” en nuestras Reglas internas sobre publicación de guiones, lo que implica que no se
requiere permiso de su autor si llama a sus funciones o reutiliza su código en sus scripts de código abierto. Sin embargo, si tiene la intención de
reutilizar el código de las funciones de una biblioteca de Pine Script™ en una publicación pública protegida o solo por invitación, se requiere permiso
explícito de su autor para reutilizarlo en esa forma.

Ya sea que utilices las funciones de una biblioteca o reutilices su código, debes acreditar al autor en la descripción de tu publicación. También es una
buena forma de dar crédito a los comentarios de código abierto.

4.11.4 Usando una biblioteca

El uso de una biblioteca de otro script (que puede ser un indicador, una estrategia u otra biblioteca), se realiza a través de la declaración import :

importar <nombre de usuario>/<nombre de biblioteca>/<versión de biblioteca> [como <alias>]

dónde:

• La ruta <username>/<libraryName>/<libraryVersion> identificará de forma única la biblioteca.

• La <libraryVersion> debe especificarse explícitamente. Para garantizar la confiabilidad de los scripts que usan bibliotecas, no hay forma de usar
automáticamente la última versión de una biblioteca. Cada vez que su autor publica una actualización de la biblioteca, el número de versión
de la biblioteca aumenta. Si tiene intención de utilizar la última versión de la biblioteca, será necesario actualizar el valor <libraryVersion> en
la declaración de importación .

• La parte as <alias> es opcional. Cuando se usa, define el espacio de nombres que hará referencia a las funciones de la biblioteca.
Por ejemplo, si importa una biblioteca usando el alias allTime como lo hacemos en el siguiente ejemplo, se referirá a las funciones de esa
biblioteca como allTime.<function_mame>(). Cuando no se define ningún alias, el nombre de la biblioteca se convierte en su espacio de
nombres.

Para utilizar la biblioteca que publicamos en la sección anterior, nuestro siguiente script requerirá una declaración de importación :

importar PineCoders/AllTimeHighLow/1 como allTime

A medida que escribe el nombre de usuario del autor de la biblioteca, puede usar el comando "Autocompletar" ctrl + espacio / cmd + espacio del
Editor para mostrar una ventana emergente que proporciona selecciones que coinciden con las bibliotecas disponibles:

Este es un indicador que reutiliza nuestra biblioteca:

1 //@version=5 2
indicador("Usando la biblioteca AllTimeHighLow", "", verdadero) 3 importar
PineCoders/AllTimeHighLow/1 como allTime
4

5 trazar(allTime.hi()) 6
trazar(allTime.lo()) 7
trazar(allTime.hi(cerrar))

Tenga en cuenta que:

4.11. Bibliotecas 241


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Hemos elegido utilizar el alias "allTime" para la instancia de la biblioteca en nuestro script. Al escribir ese alias en el Editor, aparecerá una ventana
emergente para ayudarlo a seleccionar la función particular que desea usar de la biblioteca.

• Usamos las funciones hi() y lo() de la biblioteca sin argumentos, por lo que las variables integradas altas y bajas predeterminadas
se utilizarán para sus series, respectivamente.

• Usamos una segunda llamada a allTime.hi(), pero esta vez usando close como argumento, para trazar el cierre más alto en el
Historia del gráfico.

4.12 Líneas y cuadros

• Introducción

• Líneas

• Cajas

• Polilíneas

• Comportamiento en tiempo real

• Limitaciones

4.12.1 Introducción
Pine Script™ facilita dibujar líneas, cuadros y otras formaciones geométricas a partir de código utilizando los tipos de línea, cuadro y polilínea . Estos tipos
brindan utilidad para dibujar mediante programación niveles de soporte y resistencia, líneas de tendencia, rangos de precios y otras formaciones
personalizadas en un gráfico.

A diferencia de los gráficos, la flexibilidad de estos tipos los hace particularmente adecuados para visualizar datos calculados actuales en prácticamente
cualquier punto disponible del gráfico, independientemente de la barra del gráfico en la que se ejecuta el script.

Las líneas, cuadros y polilíneas son objetos, como etiquetas, tablas y otros tipos especiales. Los scripts hacen referencia a objetos de estos tipos mediante
ID, que actúan como punteros. Al igual que con otros objetos, los ID de línea, cuadro y polilínea se califican como valores de "serie", y todas las funciones
que administran estos objetos aceptan argumentos de "serie".

Nota: El uso de los tipos que analizamos en esta página a menudo implica matrices, especialmente cuando se trabaja con polilíneas, que requieren una
matriz de instancias de chart.point . Por lo tanto, te recomendamos que te familiarices con los arrays para aprovechar al máximo estos tipos de dibujos en
tus scripts.

Las líneas dibujadas por un guión pueden ser verticales, horizontales o en ángulo. Las cajas son siempre rectangulares. Las polilíneas conectan
secuencialmente múltiples segmentos de línea verticales, horizontales, en ángulo o curvos. Aunque todos estos tipos de dibujos tienen características
diferentes, sí tienen algunas cosas en común:

242 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Las líneas, cuadros y polilíneas pueden tener coordenadas en cualquier ubicación disponible en el gráfico, incluidas aquellas en momentos futuros más
allá de la última barra del gráfico.

• Los objetos de estos tipos pueden utilizar instancias de chart.point para establecer sus coordenadas.

• Las coordenadas x de cada objeto pueden ser índices de barra o valores de tiempo, dependiendo de su propiedad xloc especificada.

• Cada objeto puede tener uno de varios estilos de línea predefinidos.

• Los scripts pueden llamar a las funciones que administran estos objetos desde dentro del alcance de los bucles y las estructuras condicionales.
permitiendo un control iterativo y condicional de sus dibujos.

• Hay límites en la cantidad de estos objetos a los que una secuencia de comandos puede hacer referencia y mostrar en el gráfico. Una única instancia
de script puede mostrar hasta 500 líneas, 500 cuadros y 100 polilíneas. Los usuarios pueden especificar el número máximo permitido para cada tipo a
través de los parámetros max_lines_count, max_boxes_count y max_polylines_count de la declaración de declaración de indicador() o estrategia() del
script . Si no se especifica, el valor predeterminado es ~50. Al igual que con los tipos de etiquetas y tablas , las líneas, cuadros y polilíneas utilizan un
mecanismo de recolección de basura que elimina los objetos más antiguos del gráfico cuando el número total de dibujos excede el límite del script.

Nota: En los gráficos de TradingView, un conjunto completo de herramientas de dibujo permite a los usuarios crear y modificar dibujos mediante acciones del
mouse. Si bien a veces pueden parecerse a objetos de dibujo creados con código Pine Script™, son entidades no relacionadas . Los scripts de Pine no pueden
interactuar con las herramientas de dibujo desde la interfaz de usuario del gráfico y las acciones del mouse no afectan directamente a los objetos de dibujo de
Pine.

4.12.2 Líneas

Las funciones integradas en el espacio de nombres line.* controlan la creación y gestión de objetos de línea :

• La función line.new() crea una nueva línea.

• Las funciones line.set_*() modifican las propiedades de la línea.

• Las funciones line.get_*() recuperan valores de una instancia de línea.

• La función line.copy() clona una instancia de línea.

• La función line.delete() elimina una instancia de línea existente.

• La variable line.all hace referencia a una matriz de sólo lectura que contiene los ID de todas las líneas mostradas por el script. El tamaño de la matriz
depende del max_lines_count de la declaración de declaración del indicador() o estrategia() y del número de líneas que ha dibujado el script.

Los scripts pueden llamar a los elementos integrados line.set_*(), line.get_*(), line.copy() y line.delete() como funciones o métodos.

Creando líneas

La función line.new() crea una nueva instancia de línea para mostrar en el gráfico. Tiene las siguientes firmas:

line.new(primer_punto, segundo_punto, xloc, extender, color, estilo, ancho) → línea de serie

line.new(x1, y1, x2, y2, xloc, extender, color, estilo, ancho) → línea de serie

La primera sobrecarga de esta función contiene los parámetros first_point y second_point. El primer punto es un punto del gráfico que representa el inicio de
la línea y el segundo punto es un punto del gráfico que representa el final de la línea. La función copia la información de estos puntos del gráfico para
determinar las coordenadas de la línea. Si utiliza los campos de índice o de tiempo del primer_punto y segundo_punto como coordenadas x depende del valor
xloc de la función.

4.12. Líneas y cajas 243


Machine Translated by Google

Manual del usuario de Pine Script™ v5

La segunda sobrecarga especifica los valores x1, y1, x2 e y2 de forma independiente, donde x1 y x2 son valores int que representan las
coordenadas x inicial y final de la línea, y y1 e y2 son valores flotantes que representan las coordenadas y. Si la línea considera los valores de x
como índices de barra o marcas de tiempo depende del valor xloc en la llamada a la función.

Ambas sobrecargas comparten los mismos parámetros adicionales:

xloc
Controla si las coordenadas x de la nueva línea utilizan índice de barra o valores de tiempo. Su valor predeterminado es xloc.bar_index.

Al llamar a la primera sobrecarga, usar un valor xloc de xloc.bar_index le dice a la función que use los campos de índice del primer_punto
y segundo_punto, y un valor de xloc.bar_time le dice a la función que use los campos de tiempo de los puntos.

Al llamar a la segunda sobrecarga, un valor xloc de xloc.bar_index solicita a la función que trate los argumentos x1 y x2 como valores
de índice de barra. Cuando se usa xloc.bar_time, la función tratará x1 y x2 como valores de tiempo.

Cuando las coordenadas x especificadas representan valores de índice de barra , es importante tener en cuenta que la coordenada x
mínima permitida es bar_index ­ 9999. Para compensaciones mayores, se puede usar xloc.bar_time.

extender
Determina si la línea dibujada se extenderá infinitamente más allá de sus coordenadas inicial y final definidas. Acepta uno de los
siguientes valores: extender.left, extender.right, extender.both o extender.none (predeterminado).

color
Especifica el color del dibujo lineal. El valor predeterminado es color.azul.

estilo
Especifica el estilo de la línea, que puede ser cualquiera de las opciones enumeradas en la sección Estilos de línea de esta página . El valor
predeterminado es line.style_solid.

ancho
Controla el ancho de la línea, en píxeles. El valor predeterminado es 1.

El siguiente ejemplo demuestra cómo se pueden dibujar líneas en su forma más simple. Este script dibuja una nueva línea vertical que conecta
los precios de apertura y cierre en el centro horizontal de cada barra del gráfico:

1 //@version=5 2
indicador("Demostración de creación de líneas", superposición = verdadero)
3

4 //@variable El `chart.point` para el inicio de la línea. Contiene `índice` y `hora`


→información.
5 primerPunto = gráfico.punto.ahora(abierto)
(continúa en la página siguiente)

244 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

6 //@variable El `chart.point` para el final de la línea. Contiene `índice` y `hora`


→información.
7 segundoPunto = chart.point.now(cerrar)
8

9 // Dibuja una línea básica con un `ancho` de 5 que conecte el `primerPunto` al


→`segundoPunto`.
10 // Esta línea usa el campo `index` de cada punto para sus coordenadas x. 11 línea.nuevo(primerPunto, segundoPunto, ancho = 5)

12

13 // Colorea el fondo de la barra no confirmada. 14 bgcolor(barstate.isconfirmed? na:


color.new(color.orange, 70), title = "Sin confirmar
→barra resaltada")

Tenga en cuenta que:

• Si el primerPunto y el segundoPunto hacen referencia a coordenadas idénticas, el script no mostrará una línea.
ya que no hay distancia entre ellos para dibujar. Sin embargo, la identificación de la línea seguirá existiendo.

• El script sólo mostrará aproximadamente las últimas 50 líneas del gráfico, ya que no tiene un max_lines_count especificado en la llamada
a la función indicador() . Los dibujos lineales persisten en el gráfico hasta que se eliminan mediante line.delete() o el recolector de basura
los elimina.

• El script vuelve a dibujar la línea en la barra del gráfico abierto (es decir, la barra con un fondo naranja resaltado) hasta que
cierra. Una vez que se cierre la barra, ya no se actualizará el dibujo.

Veamos un ejemplo más complicado. Este script utiliza el precio hl2 de la barra anterior y los precios máximo y mínimo de la barra actual para dibujar un
abanico con un número de líneas especificado por el usuario que proyecta un rango de valores de precios hipotéticos para la siguiente barra del gráfico.
Llama a line.new() dentro de un bucle for para crear líneaslinesPerBar en cada barra:

1 //@version=5 2
indicador("Demostración de creación de líneas", "Abanico de proyección simple", verdadero, max_lines_count = 500)
3

4 //@variable El número de líneas de abanico dibujadas en cada barra del gráfico.


5 int líneasPerBar = input.int(20, "Dibujos lineales por barra", 2, 100)
6

7 //@variable La distancia entre cada punto y en la barra actual. 8 paso flotante = (alto ­ bajo) / (linesPerBar ­ 1)

(continúa en la página siguiente)

4.12. Líneas y cajas 245


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

10 //@variable El `chart.point` para el inicio de cada línea. No contiene `tiempo`


→información.
11 firstPoint = chart.point.from_index(bar_index ­ 1, hl2[1]) 12 //@variable El `chart.point` para el final de cada línea. No
contiene `tiempo`
→información.
13 segundoPunto = chart.point.from_index(bar_index + 1, float(na))
14

15 //@variable El valor y escalonado en la barra actual para `segundopunto.precio`

→cálculo, empezando por el `bajo`. 16 valor de barra


flotante = bajo
17 // Bucle para dibujar el abanico. 18 para i = 1 a
líneas por barra
19
// Actualiza el `precio` del `segundoPunto` usando la diferencia entre
→`barValue` y `firstPoint.price`. secondPoint.price :=
20
2.0 * barValue ­ firstPoint.price //@variable Es `color.aqua` cuando la pendiente de
21
la línea es positiva, `color.fuchsia`
→de lo contrario.
22
color lineColor = segundoPunto.precio > primerPunto.precio? color.aqua: color.
→fucsia
23
// Dibuje una nueva línea `lineColor` que conecte las coordenadas `firstPoint` y ` secondPoint` →.

24
// Esta línea usa el campo `index` de cada punto para sus coordenadas x. línea.nuevo(primerPunto, segundoPunto,
25
color = líneaColor)
26
// Agrega el `paso` al `barValue`. valorbarra += paso
27

28

29 // Colorea el fondo de la barra no confirmada. 30 bgcolor(barstate.isconfirmed? na:


color.new(color.orange, 70), title = "Sin confirmar

→barra resaltada")

Tenga en cuenta que:

• Hemos incluido max_lines_count = 500 en la llamada a la función indicador() , lo que significa que el script conserva
hasta 500 líneas en el gráfico.

• Cada llamada a line.new() copia la información del chart.point al que hacen referencia las variables firstPoint y sec­ondPoint. Como tal, el script
puede cambiar el campo de precio del segundo punto en cada iteración del bucle sin afectar las coordenadas y en otras líneas.

Modificando líneas

El espacio de nombres line.* contiene múltiples funciones de establecimiento que modifican las propiedades de las instancias de línea :

• line.set_first_point() y line.set_first_point() actualizan respectivamente los puntos inicial y final de la línea de identificación usando
información desde el punto especificado.

• line.set_x1() y line.set_x2() establecen una de las coordenadas x de la línea id en un nuevo valor x, que puede representar un
índice de barra o valor de tiempo dependiendo de la propiedad xloc de la línea.

• line.set_y1() y line.set_y2() establecen una de las coordenadas y de la línea id en un nuevo valor y.

• line.set_xy1() y line.set_xy2() actualizan uno de los puntos de la línea de identificación con nuevos valores x e y.

• line.set_xloc() establece el xloc de la línea de identificación y actualiza ambas coordenadas x con nuevos valores x1 y x2.

• line.set_extend() establece la propiedad de extensión de la línea de identificación.

• line.set_color() actualiza el valor de color de la línea de identificación.

246 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• line.set_style() cambia el estilo de la línea de identificación.

• line.set_width() establece el ancho de la línea de identificación.

Todas las funciones de establecimiento modifican directamente la línea de identificación pasada en la llamada y no devuelven ningún valor. Cada función de
establecimiento acepta argumentos de "serie", ya que un script puede cambiar las propiedades de una línea durante su ejecución.

El siguiente ejemplo dibuja líneas que conectan el precio de apertura de un período de tiempo con su precio de cierre. El script utiliza la
palabra clave var para declarar periodLine y las variables que hacen referencia a los valores de chart.point (openPoint y closePoint) solo
en la primera barra del gráfico, y asigna nuevos valores a estas variables durante su ejecución. Después de detectar un cambio en el
período de tiempo, establece el color de la línea period existente usando line.set_color(), crea nuevos valores para openPoint y closePoint
usando chart.point.now(), luego asigna una nueva línea usando esos puntos. al períodoLínea.

En otras barras donde el valor periodLine no es na, el script asigna un nuevo chart.point al closePoint, luego usa line.set_first_point() y
line.set_color() como métodos para actualizar las propiedades de la línea:

1 //@version=5 2

indicador("Demostración de modificación de líneas", overlay = true)


3

4 //@variable El tamaño de cada período. Plazo de 5 cadenas =


input.timeframe("D", "Plazo")
6

7 //@variable Una línea que conecta los precios de apertura y cierre del período. 8 var línea periodLine = na

10 //@variable El primer punto de la línea. Contiene información de "tiempo" e "índice". 11 var chart.point openPoint = chart.point.now(open) 12 //@variable El punto de cierre
de la línea. Contiene información de "tiempo" e "índice". 13 var chart.point closePoint = chart.point.now(cerrar)

14

15 if timeframe.change(timeframe) //@variable El color final de


dieciséis
`periodLine`. color finalColor = cambiar
17

18 closePoint.price > openPoint.price => color.verde closePoint.price <


19 openPoint.price => color.rojo
20 => color gris
21

22 // Actualiza el color del `periodLine` actual al `finalColor`.


(continúa en la página siguiente)

4.12. Líneas y cajas 247


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

23 line.set_color(periodLine, finalColor)
24

25 // Asigna nuevos puntos a `openPoint` y `closePoint`.


26 openPoint := chart.point.now(abierto)
27 closePoint := chart.point.now(cerrar)
28 // Asigna una nueva línea a `periodLine`. Utiliza campos `time` del `openPoint`
→y `closePoint` como coordenadas x.
29 periodLine := line.new(openPoint, closePoint, xloc.bar_time, estilo = line.style_
→flecha_derecha, ancho = 3)
30

31 más si no na (periodLine)
32 // Asigna un nuevo punto al `closePoint`.
33 closePoint := chart.point.now(cerrar)
34

35 //@variable El color de la `periodLine` en desarrollo.


36 color en desarrolloColor = cambiar
37 closePoint.price > openPoint.price => color.aqua
38 closePoint.price < openPoint.price => color.fucsia
39 => color gris
40

41 // Actualiza las coordenadas del segundo punto de la línea usando el nuevo `closePoint`.
42 // Utiliza el campo `time` desde el punto para su nueva coordenada x.
43 periodLine.set_segundo_punto(closePoint)
44 // Actualiza el color de la línea usando `developingColor`.
45 periodLine.set_color(desarrollandoColor)

Tenga en cuenta que:

• Cada dibujo lineal en este ejemplo utiliza el estilo line.style_arrow_right . Consulte la sección Estilos de línea a continuación para
una descripción general de todas las configuraciones de estilo disponibles.

Estilos de línea

Los usuarios pueden controlar el estilo de los dibujos lineales de sus scripts pasando una de las siguientes variables como argumento de estilo.
en sus llamadas a funciones line.new() o line.set_style() :

248 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Argumento Línea Argumento Línea

línea. línea.
estilo_solido estilo_flecha_izquierda

línea. línea.
estilo_puntos estilo_arrow_right

línea. línea.
estilo_guiones estilo_flecha_ambos

Tenga en cuenta que:

• Las polilíneas también pueden usar cualquiera de estas variables como su valor de estilo de línea. Ver la sección Crear polilíneas.
de esta página.

Leer valores de línea

El espacio de nombres line.* incluye funciones getter , que permiten a un script recuperar valores de un objeto de línea para su posterior uso.
usar:

• line.get_x1() y line.get_x2() obtienen respectivamente la primera y segunda coordenada x de la línea de identificación. Si el


El valor devuelto representa un índice de barra o el valor de tiempo depende de la propiedad xloc de la línea.

• line.get_y1() y line.get_y2() obtienen respectivamente la primera y segunda coordenada y de la línea de identificación.

• line.get_price() recupera el precio (coordenada y) de una identificación de línea en un valor x específico, incluidos los índices de barra fuera
de los puntos inicial y final de la línea. Esta función solo es compatible con líneas que usan xloc.bar_index como valor xloc.

El siguiente script dibuja una nueva línea al inicio de un patrón de precio ascendente o descendente que se forma a lo largo de barras longitudinales.
Utiliza la palabra clave var para declarar la variable directionLine en la primera barra del gráfico. El ID asignado a DirectionLine persiste en las
barras siguientes hasta que se produce la condición newDirection, en cuyo caso el script asigna una nueva línea a la variable.

En cada barra, el script llama a los captadores line.get_y2(), line.get_y1(), line.get_x2() y line.get_x1() como métodos para recuperar valores de la
dirección actual y calcular su pendiente, que utiliza. para determinar el color de cada dibujo y trama. Recupera valores extendidos de directionLine
desde más allá de su segundo punto usando line.get_price() y los traza en el gráfico:

4.12. Líneas y cajas 249


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 indicadores ("Demostración de lectura de valores de línea", superposición = verdadero)
3

4 //@variable El número de barras para cálculos ascendentes y descendentes. 5 int longitud = input.int(2, "Longitud", 2)

7 //@variable Una línea que se dibuja cada vez que `hlc3` comienza a subir o bajar
→barras de longitud. 8
var línea direcciónLínea = na
9

10 //@variable Es "verdadero" cuando "hlc3" aumenta sobre las barras de "longitud", en caso contrario es "falso". 11 bool rise = ta.rising(hlc3, length)
12 //@variable Es "true" cuando "hlc3" cae sobre las barras de
"longitud", "false" en caso contrario. 13 bool cayendo = ta.falling(hlc3, longitud) 14 //@variable Es "verdadero" cuando comienza un patrón ascendente o
descendente, "falso" en caso contrario. 15 bool newDirection = (subiendo
y no subiendo[1]) o (bajando y no bajando[1])

dieciséis

17 // Actualice `directionLine` cuando `newDirection` sea `true`. La línea usa el


→predeterminado `xloc.bar_index`.
18 si nueva dirección
19 direcciónLínea := línea.new(bar_index ­ longitud, hlc3[longitud], bar_index, hlc3,
→ancho = 3)
20

21 //@variable La pendiente de `direcciónLine`. 22 pendiente flotante =


(directionLine.get_y2() ­ directionLine.get_y1()) / (directionLine.get_
→x2() ­ direcciónLine.get_x1())
23 //@variable El valor extrapolado de `directionLine` en `bar_index`. 24 valor de línea flotante = línea.get_price (direcciónLínea, índice de barra)

25

26 //@variable Es `color.green` cuando la `pendiente` es positiva, `color.red` en caso contrario. 27 colores pendienteColor = pendiente > 0 ?
color.verde : color.rojo
28

29 // Actualiza el color de `directionLine`. 30 direcciónLine.set_color(pendienteColor)

31 // Traza el `lineValue`. 32 plot(lineValue,


"Valor extrapolado", SlopeColor, 3, plot.style_circles)

Tenga en cuenta que:

250 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Este ejemplo llama a la segunda sobrecarga de la función line.new() , que utiliza los parámetros x1, y1, x2 e y2 para definir los puntos
inicial y final de la línea. El valor x1 son las barras de longitud detrás del bar_index actual, y el valor y1 es el valor hlc3 en ese índice. X2
e y2 en la llamada a la función usan los valores bar_index y hlc3 de la barra actual .

• La llamada a la función line.get_price() trata la línea de dirección como si se extendiera infinitamente, independientemente de
su propiedad extendida.

• La secuencia de comandos solo muestra aproximadamente las últimas 50 líneas del gráfico, pero el gráfico de valores extrapolados abarca
a lo largo de la historia del gráfico.

Líneas de clonación

Los scripts pueden clonar una identificación de línea y todas sus propiedades con la función line.copy() . Cualquier cambio en la instancia de línea
copiada no afecta el original.

Por ejemplo, este script crea una línea horizontal en el precio de apertura de la barra una vez cada longitud de barra, que asigna a una variable mainLine.
En todas las demás barras, crea una línea copiada usando line.copy() y llama a las funciones line.set_*() para modificar sus propiedades. Como vemos
a continuación, alterar la línea copiada no afecta la línea principal en ningún caso.
forma:

1 //@version=5 2
indicador("Demostración de clonación de líneas", superposición = verdadero, max_lines_count = 500)
3

4 //@variable El número de barras entre cada nueva asignación de mainLine. 5 int longitud = input.int(20, "Longitud", 2, 500)

7 //@variable El primer `chart.point` utilizado por `mainLine`. Contiene `índice` y


→ información `hora`.
8 firstPoint = chart.point.now(open) 9 //@variable El segundo
`chart.point` utilizado por `mainLine`. No contiene `tiempo`
→información.
10 segundosPunto = chart.point.from_index(bar_index + longitud, abierto)
11

12 //@variable Una línea horizontal dibujada en el precio de "apertura" una vez cada barra de "longitud". 13 var línea mainLine = na

14

15 si bar_index % longitud == 0
(continúa en la página siguiente)

4.12. Líneas y cajas 251


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

dieciséis // Asigna una nueva línea a la `línea principal` que conecta el `primerPunto` con el →`segundoPunto`.

17 // Esta línea usa los campos `index` de ambos puntos como coordenadas x. Línea principal := línea.nueva(primerPunto,
18 segundoPunto, color = color.púrpura, ancho = 2)
19

20 //@variable Una copia de `mainLine`. Los cambios en esta línea no afectan el original. 21 líneas copiadasLine = line.copy(mainLine)

22

23 // Actualiza el color, estilo y segundo punto de `copiedLine`. 24 line.set_color(copiedLine, color.orange) 25


line.set_style(copiedLine, line.style_dotted) 26 line.set_first_point(copiedLine,
chart.point.now(cerrar))

Tenga en cuenta que:

• El campo de índice del segundo Punto tiene barras de longitud más allá del índice_barra actual. Dado que la coordenada x
máxima permitida con xloc.bar_index es bar_index + 500, hemos establecido el valor máximo de la entrada de longitud en
500.

Eliminar líneas

Para eliminar una identificación de línea dibujada por un script, use la función line.delete() . Esta función elimina la instancia de línea del
script y su dibujo en el gráfico.

Eliminar instancias de líneas suele ser útil cuando se desea mantener solo un número específico de líneas en el gráfico en un momento
dado o eliminar dibujos condicionalmente a medida que avanza el gráfico.

Por ejemplo, este script dibuja una línea horizontal con la propiedad extend.right cada vez que un RSI cruza su EMA.

El script almacena todos los ID de línea en una matriz de líneas que utiliza como cola para mostrar solo el último número de líneas en el
gráfico. Cuando el tamaño de la matriz excede el número de líneas especificado, el script elimina la ID de línea más antigua de la matriz
usando array.shift() y la elimina con line.delete():

1 //@versión=5
2

3 //@variable El número máximo de líneas permitidas en el gráfico. 4 constante int MAX_LINES_COUNT =


500
(continúa en la página siguiente)

252 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

6 indicador ("Demostración de eliminación de líneas", "Niveles cruzados RSI", max_lines_count = MAX_LINES_


→CONTAR)
7

8 //@variable La longitud del RSI. 9 int rsiLength = input.int(14, "RSI length",


2) 10 //@variable La longitud de la EMA del RSI. 11 int emaLength = input.int(28, "longitud promedio
RSI", 2) 12 //@variable El número máximo de líneas que se deben mantener en el gráfico.
13 int numberOfLines = input.int(20, "Líneas en el gráfico", 0, MAX_LINES_COUNT)

14

15 //@variable Una matriz que contiene los ID de las líneas del gráfico. 16 var matriz<línea> líneas = array.new<línea>()

17

18 //@variable Un RSI `rsiLength` de `close`. 19 float rsi = ta.rsi(close, rsiLength) 20 //@variable


Un EMA `maLength` de `rsi`. 21 flotante rsiMA = ta.ema(rsi, emaLength)

22

23 si ta.cruz(rsi, rsiMA)
24 //@variable El color de la línea horizontal. línea de colorColor = rsi > rsiMA ?
25 color.green: color.red // Dibuja una nueva línea horizontal. Utiliza el `xloc.bar_index`
26 predeterminado. nuevaLínea = línea.nueva(bar_index, rsiMA, bar_index + 1, rsiMA, extender = extender.right,
27

→color = colorlínea, ancho = 2)


28 // Inserta `newLine` en la matriz `lines`. líneas.push(nuevaLínea)
29

30 // Elimina la línea más antigua cuando el tamaño de la matriz excede el especificado


→`númeroDeLíneas`.
31 si matriz.tamaño (líneas)> número de líneas
32 línea.eliminar(líneas.shift())
33

34 // Traza `rsi` y `rsiMA`. 35 plot(rsi, "RSI", color.new(color.blue, 40))

36 plot(rsiMA, "EMA de RSI", color.new(color.gray, 30))

Tenga en cuenta que:

• Declaramos una variable MAX_LINES_COUNT con el tipo calificado “const int”, que el script usa como max_lines_count en la función
indicador() y el maxval de input.int() asignado a la variable numberOfLines.

• Este ejemplo utiliza la segunda sobrecarga de la función line.new() , que especifica las coordenadas x1, y1, x2 e y2.
dina de forma independiente.

4.12.3 Cajas

Las funciones integradas en el espacio de nombres box.* crean y administran objetos de cuadro :

• La función box.new() crea un nuevo cuadro.

• Las funciones box.set_*() modifican las propiedades del cuadro.

• Las funciones box.get_*() recuperan valores de una instancia de cuadro.

• La función box.copy() clona una instancia de cuadro.

• La función box.delete() elimina una instancia de cuadro.

4.12. Líneas y cajas 253


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• La variable box.all hace referencia a una matriz de sólo lectura que contiene los ID de todos los cuadros mostrados por el script. El tamaño de
la matriz depende del max_boxes_count de la declaración de indicador() o estrategia() y del número de cuadros que ha dibujado el script.

Al igual que con las líneas, los usuarios pueden llamar a los elementos integrados box.set_*(), box.get_*(), box.copy() y box.delete() como funciones
o métodos.

Creando cajas

La función box.new() crea un nuevo objeto de cuadro para mostrar en el gráfico. Tiene las siguientes firmas:

box.new(arriba_izquierda, abajo_derecha, color_borde, ancho_borde, estilo_borde, extender,


→xloc, bgcolor, text, text_size, text_color, text_halign, text_valign, text_wrap, →text_font_family) → cuadro de serie

box.new(izquierda, arriba, derecha, abajo, border_color, border_width, border_style, extender, →xloc, bgcolor, text, text_size,
text_color, text_halign, text_valign, text_wrap, →text_font_family) → cuadro de serie

La primera sobrecarga de esta función incluye los parámetros top_left y bottom_right, que aceptan objetos chart.point que representan las esquinas
superior izquierda e inferior derecha del cuadro, respectivamente. La función copia la información de estos puntos del gráfico para establecer las
coordenadas de las esquinas del cuadro. Si utiliza los campos de índice o de tiempo de los puntos superior_izquierdo e inferior_derecho como
coordenadas x depende del valor xloc de la función.

La segunda sobrecarga especifica los bordes izquierdo, superior, derecho e inferior del cuadro. Los parámetros izquierdo y derecho aceptan valores
int que especifican las coordenadas x izquierda y derecha del cuadro, que pueden ser índices de barra o valores de tiempo dependiendo del valor
xloc en la llamada a la función. Los parámetros superior e inferior aceptan valores flotantes que representan las coordenadas y superior e inferior del
cuadro.

Los parámetros adicionales de la función son idénticos en ambas sobrecargas:

color del borde


Especifica el color de los cuatro bordes del cuadro. El valor predeterminado es color.azul.

ancho del borde


Especifica el ancho de los bordes, en píxeles. Su valor predeterminado es 1.

estilo de borde
Especifica el estilo de los bordes, que puede ser cualquiera de las opciones en la sección Estilos de cuadro de esta página.

extender
Determina si los bordes del cuadro se extienden infinitamente más allá de las coordenadas x izquierda o derecha. Acepta uno de los siguientes
valores: extender.left, extender.right, extender.both o extender.none (predeterminado).

xloc
Determina si los bordes izquierdo y derecho del cuadro utilizan índice de barra o valores de tiempo como coordenadas x. El valor
predeterminado es xloc.bar_index.

En la primera sobrecarga, un valor xloc de xloc.bar_index significa que la función usará los campos de índice de los puntos del gráfico
superior_izquierdo e inferior_derecho, y un valor xloc de xloc.bar_time significa que usará sus campos de tiempo.

En la segunda sobrecarga, usar un valor xloc de xloc.bar_index significa que la función trata los valores izquierdo y derecho como índices de
barra, y xloc.bar_time significa que los tratará como marcas de tiempo.

Cuando las coordenadas x especificadas representan valores de índice de barra , es importante tener en cuenta que la coordenada x mínima
permitida es bar_index ­ 9999. Para compensaciones mayores, se puede usar xloc.bar_time.

bgcolor
Especifica el color de fondo del espacio dentro del cuadro. El valor predeterminado es color.azul.

254 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

texto
El texto que se mostrará dentro del cuadro. Por defecto, su valor es una cadena vacía.

tamaño_texto
Especifica el tamaño del texto dentro del cuadro. Acepta uno de los siguientes valores: tamaño.diminuto, tamaño.pequeño, tamaño.normal,
tamaño.grande , tamaño.enorme o tamaño.auto (predeterminado).

text_color Controla
el color del texto. Su valor predeterminado es color.negro.

texto_halign
Especifica la alineación horizontal del texto dentro de los límites del cuadro. Acepta uno de los siguientes: text.align_left, text.align_right
o text.align_center (predeterminado).

texto_valign
Especifica la alineación vertical del texto dentro de los límites del cuadro. Acepta uno de los siguientes: text.align_top, text.align_bottom
o text.align_center (predeterminado).

text_wrap
Determina si el cuadro ajustará el texto que contiene. Si su valor es text.wrap_auto, el cuadro envuelve el texto para garantizar que no
sobrepase sus bordes verticales. También recorta el texto ajustado cuando se extiende más allá de la parte inferior.
Si el valor es text.wrap_none, el cuadro muestra el texto en una sola línea que puede extenderse más allá de sus bordes. El valor
predeterminado es text.wrap_none.

text_font_family Define la
familia de fuentes del texto del cuadro. El uso de font.family_default muestra el texto del cuadro con la fuente predeterminada del
sistema. font.family_monospace muestra el texto en formato monoespaciado. El valor predeterminado es font.family_default.

Escribamos un script simple para mostrar cuadros en un gráfico. El siguiente ejemplo dibuja un cuadro que proyecta los valores alto y bajo de
cada barra desde el centro horizontal de la barra actual hasta el centro de la siguiente barra disponible.

En cada barra, el script crea puntos superiorIzquierdo e InferiorDerecho mediante chart.point.now() y chart.point_from_index(), luego llama a
box.new() para construir un nuevo cuadro y mostrarlo en el gráfico. También resalta el fondo en la barra del gráfico no confirmado usando
bgcolor() para indicar que vuelve a dibujar ese cuadro hasta la última actualización de la barra:

1 //@versión=5
2 indicador ("Demostración de creación de cuadros", superposición = verdadero)
3

(continúa en la página siguiente)

4.12. Líneas y cajas 255


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

4 //@variable El `chart.point` para la esquina superior izquierda del cuadro. Contiene información de `índice` →y `hora`.

5 topLeft = chart.point.now(high) 6 //@variable El


`chart.point` para la esquina inferior derecha del cuadro. No
→contiene información de "tiempo".
7 abajoDerecha = chart.point.from_index(bar_index + 1, bajo)
8

9 // Dibuja un cuadro usando los puntos de las esquinas `topLeft` y `bottomRight`. Utiliza los campos `index` →como coordenadas x.

10 box.new(arriba a la izquierda, abajo a la derecha, color.púrpura, 2, bgcolor = color.new(color.gris, 70))


11

12 // Colorea el fondo de la barra no confirmada. 13 bgcolor(barstate.isconfirmed? na:


color.new(color.orange, 70), title = "Sin confirmar
→barra resaltada")

Tenga en cuenta que:

• El campo de índice del punto inferior derecho es una barra mayor que el índice del punto superior izquierdo. Si las coordenadas x de las esquinas fueran
iguales, el script dibujaría una línea vertical en el centro horizontal de cada barra, similar al ejemplo de la sección Creación de líneas de esta página .

• De manera similar a las líneas, si arriba a la izquierda y abajo a la derecha contuvieran coordenadas idénticas, el cuadro no se mostraría en el gráfico ya
que no habría espacio entre ellos para dibujar. Sin embargo, su identificación seguiría existiendo.

• Este script sólo muestra aproximadamente los últimos 50 cuadros en el gráfico, ya que no hemos especificado un max_boxes_count en la llamada a la
función indicador() .

Modificando cuadros

Existen múltiples funciones de configuración en el espacio de nombres box.*, lo que permite a los scripts modificar las propiedades de los objetos del cuadro :

• box.set_top_left_point() y box.set_bottom_right_point() actualizan respectivamente las coordenadas superior izquierda e inferior derecha.
dinates del cuadro de identificación utilizando información del punto especificado.

• box.set_left() y box.set_right() establecen la coordenada x izquierda o derecha del cuadro de identificación en un nuevo valor izquierdo/derecho,
que puede ser un índice de barra o un valor de tiempo dependiendo de la propiedad xloc del cuadro.

• box.set_top() y box.set_bottom() establecen la coordenada y superior o inferior del cuadro de identificación en una nueva parte superior/inferior
valor.

• box.set_lefttop() establece las coordenadas izquierda y superior del cuadro de identificación, y box.set_rightbottom() establece las coordenadas derecha y superior.
coordenadas inferiores.

• box.set_border_color(), box.set_border_width() y box.set_border_style() actualizan respectivamente el color,


ancho y estilo del borde del cuadro de identificación.

• box.set_extend() establece la propiedad de extensión horizontal del cuadro de identificación.

• box.set_bgcolor() establece el color del espacio dentro del cuadro de identificación en un nuevo color.

• cuadro.set_text(), box.set_text_size(), box.set_text_color(), box.set_text_halign(), box.set_text_valign(), box.set_text_wrap() y box.set_text_font_family()


actualizan las propiedades relacionadas con el texto del cuadro de identificación.

Al igual que con las funciones de establecimiento en el espacio de nombres line.*, todos los configuradores de cuadro modifican el cuadro de identificación directamente sin

devolver un valor, y cada función de establecimiento acepta argumentos de "serie".

Tenga en cuenta que, a diferencia de las líneas, el espacio de nombres box.* no contiene una función de configuración para modificar el xloc de un cuadro. Los usuarios
deben crear un nuevo cuadro con la configuración xloc deseada para tales casos.

256 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Este ejemplo utiliza cuadros para visualizar los rangos de barras ascendentes y descendentes con el mayor volumen durante un
período de tiempo definido por el usuario. Cuando el script detecta un cambio en el período de tiempo, asigna nuevos cuadros a
sus variables upBox y downBox, restablece sus valores upVolume y downVolume y resalta el fondo del gráfico.

Cuando el volumen de una barra hacia arriba o hacia abajo excede upVolume o downVolume, el script actualiza las variables de
seguimiento de volumen y llama a box.set_top_left_point() y box.set_bottom_right_point() para actualizar las coordenadas upBox o
downBox. Los configuradores usan la información de los puntos del gráfico creados con chart.point.now() y chart.point.from_time()
para proyectar los valores máximos y mínimos de esa barra desde la hora actual hasta la hora de cierre del marco temporal:

1 //@version=5 2
indicador("Modificación de cajas de demostración", "Cajas de gran volumen", verdadero, max_boxes_count = 100)
3

4 //@variable El período de tiempo del cálculo. Plazo de 5 cadenas = input.timeframe("D",


"Plazo")
6

7 //@variable Un cuadro que proyecta el rango de la barra ascendente con el `volumen` más alto
→durante el "plazo".

8 var box upBox = na 9 //@variable Un


cuadro que proyecta el rango de la barra descendente con el `volumen` más bajo
→durante el "plazo".
10 var cuadro abajoBox = na

11 //@variable El volumen más alto de barras ascendentes durante el "período de tiempo". 12 var float upVolume = na 13 //@variable El
volumen más alto de barras descendentes durante
el "período de tiempo". 14 var flotar hacia abajoVolumen = na

15

16 // Variables de color. 17 var color


upBorder = color.teal 18 var color upFill 19 var color downBorder =
color.maroon = color.nuevo(color.verde azulado, 90)

20 var color downFill = color.new(color.granate, 90)


21

22 //@variable La hora de cierre del `plazo`. 23 int closeTime = time_close(timeframe) 24 //@variable


Es "verdadero" cuando una nueva barra comienza en el "timeframe". 25 bool
changeTF = timeframe.change(timeframe)

26

(continúa en la página siguiente)

4.12. Líneas y cajas 257


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

27 //@variable El `chart.point` para la esquina superior izquierda de los cuadros. Contiene `índice`
→e información de "hora".
28 arriba a la izquierda = gráfico.punto.ahora (alto)
29 //@variable El `chart.point` para la esquina inferior derecha de los cuadros. No
→contiene información de "índice".
30 abajoDerecha = chart.point.from_time(closeTime, bajo)
31

32 si changeTF y no na(volumen)
33 si cierra > abre
34 // Actualiza los valores `upVolume` y `downVolume`.
35 subirVolumen := volumen
36 volumen abajo: = 0.0

37 // Dibuja un nuevo `upBox` usando la información de `tiempo` y `precio` de `topLeft` y


→puntos `inferiorDerecha`.
38 upBox := box.new(arriba a la izquierda, abajo a la derecha, borde arriba, 3, xloc = xloc.bar_time,
→bgcolor = rellenorelleno)
39 // Dibuja un nuevo `downBox` con coordenadas `na`.
40 downBox := box.new(na, na, na, na, downBorder, 3, xloc = xloc.bar_time,
→bgcolor = abajoRelleno)
41 demás
42 // Actualiza los valores `upVolume` y `downVolume`.
43 subirVolumen := 0.0
44 abajoVolumen := volumen

45 // Dibuja un nuevo `upBox` con coordenadas `na`.


46 upBox := box.new(na, na, na, na, upBorder, 3, xloc = xloc.bar_time, bgcolor =
→arribaRellenar)
47 // Dibuja un nuevo `downBox` usando la información `time` y `price` de `topLeft` y
→puntos `inferiorDerecha`.
48 downBox := box.new(arriba a la izquierda, abajo a la derecha, borde abajo, 3, xloc = xloc.bar_time,
→bgcolor = abajoRelleno)
49 // Actualiza ``upVolume`` y cambia las coordenadas de ``upBox`` cuando aumenta el volumen
→en una barra ascendente.
50 más si cierra > abre y volumen > subir volumen
51 subirVolumen := volumen
52 box.set_top_left_point(upBox, arriba a la izquierda)
53 box.set_bottom_right_point(arribaCuadro, abajoDerecha)
54 // Actualiza ``downVolume`` y cambia las coordenadas de ``downBox`` cuando el volumen
→aumenta en una barra descendente.
55 más si cierra <= abrir y volumen > bajarVolumen
56 abajoVolumen := volumen

57 box.set_top_left_point (cuadro abajo, arriba a la izquierda)


58 box.set_bottom_right_point(abajoCuadro, abajoDerecha)
59

60 // Resalte el fondo cuando comience una nueva barra de "período de tiempo".


61 bgcolor(changeTF? color.new(color.orange, 70): na, title = "Cambio de plazo
→resaltar")

Tenga en cuenta que:

• La llamada a la función indicador() contiene max_boxes_count = 100, lo que significa que el script preservará el
últimas 100 casillas del gráfico.

• Utilizamos ambas sobrecargas de box.new() en este ejemplo. En la primera barra del período de tiempo, el guión llama
la primera sobrecarga para el upBox cuando la barra está subiendo, y llama a esa sobrecarga para el downBox cuando la barra está subiendo.
la barra está cayendo. Utiliza la segunda sobrecarga para asignar un nuevo cuadro con valores na a la otra variable de cuadro en ese
bar.

258 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Estilos de caja

Los usuarios pueden incluir una de las siguientes variables line.style_* en sus llamadas a funciones box.new() o box.set_border_style() para
establecer los estilos de borde de los cuadros dibujados por sus scripts:

Argumento Caja

línea.style_solid

línea.style_dotted

línea.style_dasshed

Valores del cuadro de lectura

El espacio de nombres box.* presenta funciones getter que permiten a los scripts recuperar valores de coordenadas de una instancia de box:

• box.get_left() y box.get_right() obtienen respectivamente las coordenadas x de los bordes izquierdo y derecho del cuadro de identificación.
Si el valor devuelto representa un índice de barra o un valor de tiempo depende de la propiedad xloc del cuadro.

• box.get_top() y box.get_bottom() obtienen respectivamente las coordenadas y superior e inferior del cuadro de identificación.

El siguiente ejemplo dibuja cuadros para visualizar rangos de precios hipotéticos durante un período de barras de longitud. Al comienzo de cada
nuevo período, utiliza el rango de vela promedio multiplicado por la entrada del factor de escala para calcular los puntos de las esquinas de un
cuadro centrado en el precio hl2 con una altura de rango inicial. Después de dibujar el primer cuadro, crea numberOfBoxes: 1 cuadros nuevos
dentro de un bucle for .

Dentro de cada iteración del bucle, el script obtiene lastBoxDrawn recuperando el último elemento de la matriz box.all de solo lectura , luego llama
a box.get_top() y box.get_bottom() para obtener sus coordenadas y. Utiliza estos valores para calcular las coordenadas de una nueva caja que
es ScaleFactor veces más alta que la anterior:

4.12. Líneas y cajas 259


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 indicador ("Demostración de valores de cuadro de lectura", "Cuadros anidados", superposición = verdadero, max_boxes_count
→= 500)
3

4 //@variable El número de barras en el cálculo del rango.


5 int longitud = input.int(10, "Longitud", 2, 500)
6 //@variable El número de cuadros anidados dibujados en cada período.
7 int numberOfBoxes = input.int(5, "Recuento de cuadros anidados", 1)
8 //@variable El factor de escala aplicado a cada cuadro.
9 float scaleFactor = input.float(1.6, "Factor de escala", 1)
10

11 //@variable El rango del cuadro inicial.


12 float rango inicial = factor de escala * ta.sma (alto ­ bajo, longitud)
13

14 si bar_index % longitud == 0
15 //@variable El `chart.point` superior izquierdo para el cuadro inicial. No contiene
→ información `hora`.
dieciséis
arribaIzquierda = chart.point.from_index(bar_index, hl2 + rangoinicial / 2)
17 //@variable El `chart.point` de abajo a la derecha para el cuadro inicial. No contiene
→ información `hora`.
18 abajoDerecha = chart.point.from_index(bar_index + longitud, hl2 ­ rangoinicial / 2)
19

20 // Calcular los colores de borde y relleno de los cuadros.


21 borderColor = color.rgb(math.random(100, 255), math.random(0, 100), math.
→aleatorio(100, 255))
22 bgColor = color.new(borderColor, math.max(100 * (1 ­ 1/númeroDeCajas), 90))
23

24 // Dibuja un nuevo cuadro usando los puntos `topLeft` y `bottomRight`. Utiliza su


→`index` campos como coordenadas x.
25 box.new(arriba a la izquierda, abajo a la derecha, borderColor, 2, bgcolor = bgColor)
26

27 si númeroDeCajas > 1
28 // Bucle para crear cuadros adicionales.
29 para i = 1 a númeroDeCajas ­ 1
30 //@variable El último cuadro dibujado por el script.
31 cuadro últimocuadrodibujado = cuadro.todo.último()
32

(continúa en la página siguiente)

260 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

33 //@variable El precio máximo de la última caja.


34 parte superior flotante = box.get_top(lastBoxDrawn)
35 //@variable El precio mínimo de la última caja.
36 fondo flotante = box.get_bottom(lastBoxDrawn)
37

38 //@variable El rango escalado del nuevo cuadro.


39 float newRange = factor de escala * (arriba ­ abajo) * 0.5
40 //@variable El punto medio entre "abajo" y "arriba".
41 flotador medio = 0,5 * (arriba + abajo)
42

43 // Actualiza los campos `precio` de los puntos `topLeft` y `bottomRight`.


44 // Esto no afecta las coordenadas de las casillas anteriores.
45 topLeft.price: = hl2 + nuevo rango
46 precio.inferiorDerecho: = hl2 ­ nuevo rango
47

48 // Dibuja un nuevo cuadro usando los puntos `topLeft` y `bottomRight` actualizados.


49 box.new(arriba a la izquierda, abajo a la derecha, borderColor, 2, bgcolor = bgColor)

Tenga en cuenta que:

• La llamada a la función indicador() usa max_boxes_count = 500, lo que significa que el script puede mostrar hasta 500
casillas en el gráfico.

• Cada dibujo tiene un índice derecho con barras de longitud más allá del índice izquierdo. Dado que las coordenadas x de estos
Los dibujos pueden tener hasta 500 barras en el futuro, hemos establecido el valor máximo de la entrada de longitud en 500.

• En cada nuevo período, el script utiliza valores color.rgb() aleatorios para border_color y bgcolor
de las cajas.

• Cada llamada a box.new() copia las coordenadas de los objetos chart.point asignados a las posiciones superior izquierda e inferior.
variables tomRight, razón por la cual el script puede modificar sus campos de precio en cada iteración del bucle sin
afectando a las otras cajas.

Cajas de clonación

Para clonar una identificación de cuadro específica, use box.copy(). Esta función copia el cuadro y sus propiedades. Cualquier cambio en lo copiado.
La caja no afecta al original.

Por ejemplo, este script declara una variable originalBox en la primera barra y le asigna un nuevo cuadro una vez cada
barras de longitud. En otras barras, usa box.copy() para crear un CopyBox y llama a las funciones box.set_*() para modificar
sus propiedades. Como se muestra en el cuadro a continuación, estos cambios no modifican el cuadro original:

4.12. Líneas y cajas 261


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 indicadores ("Demostración de clonación de cuadros", superposición = verdadero, max_boxes_count = 500)
3

4 //@variable El número de barras entre cada nueva asignación de mainLine.


5 int longitud = input.int(20, "Longitud", 2)
6

7 //@variable El `chart.point` para la parte superior izquierda del `originalBox`. Contiene `tiempo`
→e información `índice`.
8 arriba a la izquierda = gráfico.punto.ahora (alto)
9 //@variable El `chart.point` para la parte inferior derecha del `originalBox`. No
→contiene información de "tiempo".
10 abajoDerecha = chart.point.from_index(bar_index + 1, bajo)
11

12 //@variable Un nuevo cuadro con esquinas `topLeft` y `bottomRight` en cada barra de `length`.
Caja de 13 var caja original = na
14

15 //@variable Es verde azulado cuando la barra sube y granate cuando baja.


16 colores originalColor = cerrar > abrir? color.verde azulado : color.granate
17

18 si bar_index % longitud == 0
19 // Asigna un nuevo cuadro usando la información `topLeft` y `bottomRight` al
→`Caja original`.
20 // Este cuadro utiliza los campos `index` de los puntos como coordenadas x.
21 originalBox := box.new(arriba a la izquierda, abajo a la derecha, color original, 2, bgcolor = color.
→nuevo(color original, 60))
22 más
23 //@variable Un clon de `originalBox`.
24 cuadro copiadoCuadro = cuadro.copiar(cuadro original)
25 // Modifica el `copiedBox`. Estos cambios no afectan al `originalBox`.
26 box.set_top(cuadrocopiado, alto)
27 box.set_bottom_right_point(cuadrocopiado, abajoDerecha)
28 box.set_border_color(cajacopiada, color.gris)
29 box.set_border_width(cajacopiada, 1)
30 box.set_bgcolor(copiedBox, na)

262 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Eliminar cuadros

Para eliminar cuadros dibujados por un script, use box.delete(). Al igual que con las funciones *.delete() en otros espacios de nombres de
dibujo, esta función es útil para eliminar cuadros condicionalmente o mantener un número específico de cuadros en el gráfico.

Este ejemplo muestra cuadros que representan valores de volumen acumulativo periódicos. El script crea una nueva ID de cuadro y la
almacena en una matriz de cuadros una vez por cada barra de longitud. Si el tamaño de la matriz excede el número de cajas especificado,
el script elimina el cuadro más antiguo de la matriz usando array.shift() y lo elimina usando box.delete().

En otras barras, acumula volumen durante cada período modificando la parte superior del último cuadro de la matriz de cuadros. Luego, el
script utiliza bucles for para encontrar el Top más alto de todos los cuadros de la matriz y establece el bgcolor de cada cuadro con un color
degradado basado en su valor box.get_top() relativo al Top más alto:

1 //@versión=5
2

3 //@variable El número máximo de cuadros que se mostrarán en el gráfico.


4 constante int MAX_BOXES_COUNT = 500
5

6 indicador("Demostración de eliminación de cuadros", "Cuadros de volumen acumulativo", formato = formato.volumen,


→max_boxes_count = MAX_BOXES_COUNT)
7

8 //@variable El número de barras en cada período. 9 int length = input.int(20, "Length", 1) 10 //


@variable El número máximo de cuadros de volumen en el cálculo. 11 int
numberOfBoxes = input.int(10, "Número de cajas", 1, MAX_BOXES_COUNT)

12

13 //@variable Una matriz que contiene el ID de cada cuadro mostrado por el script. 14 cajas var = array.new<caja>()

15

16 if bar_index % length == 0 // Inserta un nuevo


17 cuadro en la matriz `boxes`. El cuadro tiene la propiedad predeterminada `xloc.bar_ →index`. cajas.push(box.new(bar_index, 0,
bar_index + 1, 0, #000000,
18 2, text_color = →#000000))

19 // Mueve el cuadro más antiguo fuera de la matriz y elimínalo cuando el tamaño de la matriz
→ excede el `numberOfBoxes`.
20 si cajas.tamaño() > númeroDeCajas
21 cuadro.eliminar(cuadros.shift())
(continúa en la página siguiente)

4.12. Líneas y cajas 263


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

22

23 //@variable El último cuadro dibujado por el script a partir de la barra del gráfico actual. 24 cuadro últimocuadro = cuadros.último()

25 // Agrega el volumen de la barra actual a la parte superior del `lastBox` y actualiza el `right`
→índice.
26 lastBox.set_top(lastBox.get_top() + volumen) 27 lastBox.set_right(bar_index + 1)

28 // Muestra la parte superior del `lastBox` como texto con formato de volumen. 29 lastBox.set_text(str.tostring(lastBox.get_top(),
formato.volumen))
30

31 //@variable El `top` más alto de todos los cuadros en la matriz `boxes`. 32 flotante más altoTop = 0.0 33 para identificación en
cajas

34 Top más alto := math.max(id.get_top(), Top más alto)


35

36 // Establece el `bgcolor` de cada `id` en `boxes` con un gradiente basado en la proporción de


→su `top` al `highestTop`.
37 para identificación en cajas
38 id.set_bgcolor(color.from_gradient(id.get_top() / lowerTop, 0, 1, color.purple, →color.orange))

Tenga en cuenta que:

• En la parte superior del código, hemos declarado una variable MAX_BOXES_COUNT con el tipo calificado “const int”.
Usamos este valor como max_boxes_count en la función indicador() y el valor máximo posible de la entrada numberOfBoxes.

• Este script utiliza la segunda sobrecarga de la función box.new() , que especifica las posiciones izquierda, superior, derecha,
y las coordenadas inferiores por separado.

• Hemos incluido format.volume como argumento de formato en la llamada al indicador() , que le dice al script que el eje y del panel del
gráfico representa valores de volumen . Cada cuadro también muestra su valor superior como texto con formato de volumen .

4.12.4 Polilíneas
Las polilíneas de Pine Script™ son dibujos avanzados que conectan secuencialmente las coordenadas de una matriz de instancias de puntos del
gráfico utilizando segmentos de línea recta o curva .

Estos poderosos dibujos pueden conectar hasta 10,000 puntos en cualquier ubicación disponible en el gráfico, lo que permite que los scripts
dibujen series personalizadas, polígonos y otras formaciones geométricas complejas que de otro modo serían difíciles o imposibles de dibujar
usando objetos de línea o cuadro .

El espacio de nombres polilínea.* presenta las siguientes funciones integradas para crear y administrar objetos de polilínea :

• La función polyline.new() crea una nueva instancia de polilínea.

• La función polyline.delete() elimina una instancia de polilínea existente.

• La variable polyline.all hace referencia a una matriz de sólo lectura que contiene los ID de todas las polilíneas mostradas por el script. El
tamaño de la matriz depende del max_polylines_count de la declaración de declaración del indicador() o estrategia() y del número de
polilíneas dibujadas por el script.

A diferencia de las líneas o cuadros, las polilíneas no tienen funciones de modificación o lectura de sus propiedades. Para volver a dibujar una
polilínea en el gráfico, se puede eliminar la instancia existente y crear una nueva polilínea con los cambios deseados.

264 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Creando polilíneas

La función polyline.new() crea una nueva instancia de polilínea para mostrar en el gráfico. Tiene la siguiente firma:

polilínea.new(puntos, curvos, cerrados, xloc, color_línea, color_relleno, estilo_línea, ancho_línea) → polilínea serie

Los ocho parámetros siguientes afectan el comportamiento de un dibujo de polilínea:

puntos
Acepta una matriz de objetos chart.point que determinan las coordenadas de cada punto en la polilínea. El dibujo conecta las
coordenadas de cada elemento de la matriz secuencialmente, comenzando desde el primero. Si la polilínea usa el campo índice o
tiempo de cada punto del gráfico para sus coordenadas x depende del valor xloc en la llamada a la función.

curvo
Especifica si el dibujo utiliza segmentos de línea curvados para conectar cada punto del gráfico en la matriz de puntos. El valor
predeterminado es falso, lo que significa que utiliza segmentos de línea recta.

cerrado
Controla si la polilínea conectará el último punto del gráfico en la matriz de puntos con el primero, formando una polilínea cerrada.
El valor predeterminado es falso.

xloc
Especifica qué campo de cada punto del gráfico en la matriz de puntos utiliza la polilínea para sus coordenadas x. Cuando su valor
es xloc.bar_index, la función utiliza los campos de índice para crear la polilínea. Cuando su valor es xloc.bar_time, la función utiliza
los campos de hora. El valor predeterminado es xloc.bar_index.

line_color
Especifica el color de todos los segmentos de línea en el dibujo de polilínea. El valor predeterminado es color.azul.

fill_color Controla
el color del espacio cerrado rellenado por el dibujo de polilínea. Su valor predeterminado es na.

line_style
Especifica el estilo de la polilínea, que puede ser cualquiera de las opciones disponibles en la sección Estilos de línea de esta página.
El valor predeterminado es line.style_solid.

line_width
Especifica el ancho de la polilínea, en píxeles. El valor predeterminado es 1.

Este script muestra un ejemplo sencillo de cómo dibujar una polilínea en el gráfico. Inserta un nuevo chart.point con un valor de precio
alternativo en una matriz de puntos y colorea el fondo con bgcolor() una vez por cada barra de longitud.

En la última barra histórica confirmada, el script dibuja una nueva polilínea en el gráfico, conectando las coordenadas de cada punto del
gráfico en la matriz, comenzando desde el primero:

4.12. Líneas y cajas 265


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@version=5 2
indicador("Demostración de creación de polilíneas", "Polilínea oscilante")
3

4 //@variable El número de barras entre cada punto del dibujo. 5 int longitud = input.int(20, "Longitud entre puntos", 2)

7 //@variable Una matriz de objetos `chart.point` para conectarse secuencialmente con una polilínea. 8 puntos var = array.new<chart.point>()

10 //@variable La coordenada y de cada punto en los `puntos`. Alterna entre 1 y ­


→1 en cada `nuevoPunto`.
11 var int yValor = 1
12

13 //@variable Es "verdadero" una vez cada barra de "longitud", en caso contrario es "falso". 14 bool newPoint = bar_index % longitud
== 0
15

16 if newPoint //
17 Inserta un nuevo `chart.point` en los `points`. El nuevo punto contiene información de `tiempo` y →`índice`.

18 puntos.push(chart.point.now(yValue))
19 // Cambia el signo de `yValue`. Valor y *= ­1
20

21

22 // Dibuja una nueva `polilínea` en la última barra del gráfico histórico confirmado.
23 // La polilínea usa el campo `time` de cada `chart.point` en la matriz `points` →como coordenadas x.

24 si barstate.islastconfirmedhistory polilínea.new(puntos, xloc =


25 xloc.bar_time, line_color = #9151A6, line_width = 3)
26

27 // Resalte el fondo del gráfico en cada condición de `nuevoPunto`. 28 bgcolor(newPoint ? color.new(color.gray, 70): na, title =
"Nuevo punto resaltado")

Tenga en cuenta que:

• Este script utiliza sólo una polilínea para conectar cada punto del gráfico de la matriz con segmentos de línea recta, y este
dibujo abarca todos los datos del gráfico disponibles, comenzando desde la primera barra.

• Si bien se puede lograr un efecto similar usando líneas, hacerlo requeriría una nueva instancia de línea en cada aparición
de la condición newPoint, y dicho dibujo estaría limitado a un máximo de 500 segmentos de línea.
Este dibujo de polilínea única y abierta, por otro lado, puede contener hasta 9999 segmentos de línea.

266 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Dibujos curvos

Las polilíneas pueden dibujar curvas que de otro modo serían imposibles de producir con líneas o cuadros. Al habilitar el parámetro
curvo de la función polyline.new() , la polilínea resultante interpola valores no lineales entre las coordenadas de cada chart.point en
su conjunto de puntos para generar un efecto curvo.

Por ejemplo, el script "Polilínea oscilante" de nuestro ejemplo anterior utiliza segmentos de línea recta para producir un dibujo que
se asemeja a una onda triangular, es decir, una forma de onda que zigzaguea entre sus picos y valles. Si configuramos el parámetro
curvo en la llamada polyline.new() de ese ejemplo en verdadero, el dibujo resultante conectaría los puntos usando segmentos
curvos , produciendo una forma suave y no lineal similar a una onda sinusoidal:

1 //@version=5 2
indicador("Demostración de dibujos curvos", "Polilínea oscilante suave")
3

4 //@variable El número de barras entre cada punto del dibujo. 5 int longitud = input.int(20, "Longitud entre puntos", 2)

7 //@variable Una matriz de objetos `chart.point` para conectarse secuencialmente con una polilínea. 8 puntos var = array.new<chart.point>()

10 //@variable La coordenada y de cada punto en los `puntos`. Alterna entre 1 y ­


→1 en cada `nuevoPunto`.
11 var int yValor = 1
12

13 //@variable Es "verdadero" una vez cada barra de "longitud", en caso contrario es "falso". 14 bool newPoint = bar_index % longitud
== 0
15

16 si es nuevoPunto
17 // Inserta un nuevo `chart.point` en los `puntos`. El nuevo punto contiene información de `tiempo` y →`índice`.

18 puntos.push(chart.point.now(yValue))
19 // Cambia el signo de `yValue`. Valor y *= ­1
20

21

22 // Dibuje una nueva "polilínea" curva en la última barra del gráfico histórico confirmado.
23 // La polilínea usa el campo `time` de cada `chart.point` en la matriz `points` →como coordenadas x.

24 si barstate.islastconfirmedhistory
25 polyline.new(puntos, curvo = verdadero, xloc = xloc.bar_time, line_color = #9151A6,
(continúa en la página siguiente)

4.12. Líneas y cajas 267


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

→ancho_línea = 3)
26

27 // Resalte el fondo del gráfico en cada condición de `nuevoPunto`. 28 bgcolor(newPoint ? color.new(color.gray, 70): na, title
= "Nuevo punto resaltado")

Observe que en este ejemplo, las curvas suaves tienen un comportamiento relativamente consistente y ninguna parte del dibujo se extiende
más allá de sus coordenadas definidas, lo que no siempre es el caso cuando se dibujan polilíneas curvas. Los datos utilizados para
construir una polilínea afectan en gran medida la función suave y por partes que interpola entre sus puntos. En algunos casos, la curva
interpolada puede ir más allá de sus coordenadas reales.

Agreguemos alguna variación a los puntos del gráfico en la matriz de puntos de nuestro ejemplo para demostrar este comportamiento. En
la versión siguiente, el script multiplica yValue por un valor aleatorio en las llamadas a chart.point.now() .

Para visualizar el comportamiento, este script también crea una línea horizontal en el valor del precio de cada punto del gráfico en la matriz
de puntos y muestra otra polilínea que conecta los mismos puntos con segmentos de línea recta. Como vemos en el gráfico, ambas
polilíneas pasan por todas las coordenadas de la matriz de puntos. Sin embargo, la polilínea curva ocasionalmente llega más allá de los
límites verticales indicados por las líneas horizontales, mientras que la polilínea dibujada con segmentos rectos no
no:

1 //@version=5 2
indicador("Demostración de dibujos curvos", "Polilíneas oscilantes aleatorias")
3

4 //@variable El número de barras entre cada punto del dibujo. 5 int longitud = input.int(20, "Longitud entre puntos", 2)

7 //@variable Una matriz de objetos `chart.point` para conectarse secuencialmente con una polilínea. 8 puntos var = array.new<chart.point>()

10 //@variable El signo de cada `precio` en los `puntos`. Alterna entre 1 y ­1 en


→cada `nuevoPunto`.
11 var int yValor = 1
12

13 //@variable Es "verdadero" una vez cada barra de "longitud". 14 bool newPoint = bar_index
% longitud == 0
15

16 if newPoint // Inserta
17 un nuevo `chart.point` con un `price` aleatorio en los `points`.
18 // El nuevo punto contiene información de `hora` e `índice`.
(continúa en la página siguiente)

268 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

19 puntos.push(chart.point.now(yValue * math.random()))
20 // Cambia el signo de `yValue`.
21 Valor y *= ­1
22

23 //@variable El `chart.point` más nuevo.


24 últimoPunto = puntos.último()
25 // Dibuja una línea horizontal en `lastPoint.price`. Esta línea usa el valor predeterminado
→`xloc.bar_index`.
26 línea.nuevo(últimoPunto.índice ­ longitud, últimoPunto.precio, últimoPunto.índice + longitud,
→últimoPunto.precio, color = color.rojo)
27

28 // Dibuje dos instancias de `polilínea` en la última barra del gráfico confirmada.


29 // Ambas polilíneas usan el campo `time` de cada `chart.point` en la matriz `points`
→como coordenadas x.
30 si barstate.islastconfirmedhistory
31 polyline.new(puntos, curvo = false, xloc = xloc.bar_time, line_color = #EB8A3B,
→ancho_línea = 2)
32 polyline.new(puntos, curvo = verdadero, xloc = xloc.bar_time, line_color = #9151A6,
→ancho_línea = 3)
33

34 // Resalte el fondo del gráfico en cada condición de `nuevoPunto`.


35 bgcolor(newPoint ? color.new(color.gray, 70): na, title = "Nuevo punto resaltado")

formas cerradas

Dado que una sola polilínea puede contener numerosos segmentos de línea recta o curva, y el parámetro cerrado permite que
dibujando para conectar las coordenadas del primer y último gráfico. Punto en su conjunto de puntos, podemos usar polilíneas para
Dibuja muchos tipos diferentes de formas poligonales cerradas.

Dibujemos algunos polígonos en Pine. El siguiente script dibuja periódicamente polígonos aleatorios centrados en el precio hl2
valores.

Cada vez que ocurre la condición newPolygon, borra la matriz de puntos y calcula el número de lados.
y el desplazamiento de rotación del nuevo dibujo del polígono basado en los valores de math.random() , luego usa un bucle for para empujar
El nuevo gráfico numberOfSides apunta a la matriz que contiene coordenadas escalonadas de una ruta elíptica con xScale
y semiejes yScale. El script dibuja el polígono conectando cada punto del gráfico de la matriz de puntos usando un
Polilínea cerrada con segmentos de línea recta:

4.12. Líneas y cajas 269


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 indicadores ("Demostración de formas cerradas", "Polígonos de N lados", verdadero)


3

4 //@variable El tamaño del semieje horizontal.

5 flotante xScale = input.float(3.0, "escala X", 1.0)


6 //@variable El tamaño del semieje vertical.

7 float yScale = input.float(1.0, "escala Y") * ta.atr(2)


8

9 //@variable Una matriz de objetos `chart.point` que contienen coordenadas de vértice.


10 puntos var = array.new<chart.point>()
11

12 //@variable La condición que desencadena un nuevo dibujo de polígono. Basado en el


→eje horizontal para evitar superposiciones.
13 bool newPolygon = bar_index % int(math.round(2 * xScale)) == 0 y barstate.
→no confirmado
14

15 si es nuevopolígono
dieciséis
// Limpia la matriz de `puntos`.
17 puntos.clear()
18

19 //@variable El número de lados y vértices del nuevo polígono.


20 int númeroDeLados = int(math.random(3, 7))
21 //@variable Un desplazamiento de rotación aleatorio aplicado al nuevo polígono, en radianes.
22 rotación flotanteOffset = math.random(0.0, 2.0) * math.pi
23 //@variable El tamaño del ángulo entre cada vértice, en radianes.
24 paso flotante = 2 * math.pi / numberOfSides
25

26 //@variable El ángulo de rotación en sentido antihorario de cada vértice.


27 ángulo flotante = rotaciónOffset
28

29 para i = 1 a númeroDeLados
30 //@variable La coordenada x aproximada de una elipse en el `ángulo`,
→redondeado al número entero más cercano.
31 int xValue = int(math.round(xScale * math.cos(ángulo))) + bar_index
32 //@variable La coordenada y de una elipse en el "ángulo".
33 float yValue = yScale * math.sin(ángulo) + hl2
34

(continúa en la página siguiente)

270 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

35 // Inserta un nuevo `chart.point` que contiene `xValue` y `yValue` en el


→ matriz de puntos.
36 // El nuevo punto no contiene información de "tiempo".
37 puntos.push(chart.point.from_index(xValue, yValue))
38 // Agrega el `paso` al `ángulo`.
39 ángulo += paso
40

41 // Dibuja una polilínea cerrada que conecte los "puntos".


42 // La polilínea usa el campo `index` de cada `chart.point` en los `points`
→matriz.
43 polilínea.nueva(
44 puntos, cerrado = verdadero, color_linea = color.navy, color_relleno = color.new(color.
→naranja, 50), ancho_línea = 3
45 )

Tenga en cuenta que:

• Este ejemplo muestra las últimas ~50 polilíneas en el gráfico, ya que no hemos especificado un max_polylines_count
valor en la llamada a la función indicador() .

• El cálculo de yScale multiplica un input.float() por ta.atr(2) para adaptar la escala vertical de los dibujos a
rangos de precios recientes.

• Los polígonos resultantes tienen un ancho máximo del doble del semieje horizontal (2 * xScale), redondeados
al número entero más cercano. La condición newPolygon utiliza este valor para evitar que los dibujos poligonales
superposición.

• El script redondea el cálculo de xValue al entero más cercano porque el campo de índice de un chart.point
solo acepta un valor int , ya que el eje x del gráfico no incluye índices de barras fraccionarias.

Eliminar polilíneas

Para eliminar una identificación de polilínea específica, use polyline.delete(). Esta función elimina el objeto de polilínea del script y su
dibujando en el gráfico.

Al igual que con otros objetos de dibujo, podemos usar polyline.delete() para mantener un número específico de dibujos de polilíneas o eliminar dibujos
de un gráfico de forma condicional.

Por ejemplo, el siguiente script dibuja periódicamente espirales aritméticas aproximadas y almacena sus ID de polilínea en una matriz.
que utiliza como cola para gestionar el número de dibujos que muestra.

Cuando se produce la condición newSpiral, el script crea una matriz de puntos y agrega puntos al gráfico dentro de un bucle for. En
En cada iteración del bucle, llama a la función definida por el usuario espiralPoint() para crear un nuevo punto gráfico que contiene puntos escalonados.
valores de una trayectoria elíptica que crece con respecto al ángulo. Luego, el guión crea una curva de color aleatorio.
polilínea que conecta las coordenadas de los puntos e inserta su ID en la matriz de polilíneas.

Cuando el tamaño de la matriz excede el número de espirales especificado, el script elimina la polilínea más antigua usando ar­ray.shift() y elimina el
objeto usando polyline.delete():

4.12. Líneas y cajas 271


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2

3 //@variable El número máximo de polilíneas permitidas en el gráfico. 4 constante int MAX_POLYLINES_COUNT = 100

6 indicador ("Ejemplo de eliminación de polilíneas", "Espirales", verdadero, max_polylines_count = MAX_


→POLYLINES_COUNT)
7

8 //@variable El número de dibujos en espiral en el gráfico. 9 int numberOfSpirals = input.int(10, "Espirales


mostradas", 1, MAX_POLYLINES_COUNT) 10 //@variable El número de rotaciones de espiral completas que se dibujarán. 11 int rotaciones = input.int(5,
"Rotaciones", 1) 12 //@variable La escala del semieje horizontal. 13 float xScale = input.float(1.0, "X escala") 14 //
@variable La escala del semieje vertical. 15 float yScale = input.float(0.2, "Escala Y") * ta.atr(2)

dieciséis

17 //@función Calcula un punto aproximado a partir de una aritmética de escala elíptica


→espiral.
18 //@returns Un `chart.point` con información de `índice` y `precio`. 19 puntoespiral(ángulo flotante, int xOffset, flotante yOffset) =>
resultado = chart.point.from_index(
20

21 int(math.round(ángulo * xScale * math.cos(ángulo))) + xOffset, ángulo * yScale * math.sin(ángulo) +


22 yOffset
23 )
24

25 //@variable Una matriz de polilíneas. 26 var polilíneas =


array.new<polilínea>()
27

28 //@variable La condición para crear una nueva espiral. 29 bool newSpiral = bar_index %
int(math.round(4 * math.pi * rotaciones * xScale)) == 0
30

31 if newSpiral //@variable
32 Una matriz de objetos `chart.point` para el dibujo `espiral`. puntos = array.new<chart.point>() //@variable El ángulo en sentido antihorario entre
33 los puntos calculados, en radianes. paso flotante = math.pi / 2
34

35

(continúa en la página siguiente)

272 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

36 //@variable El ángulo de rotación de cada punto calculado en la espiral, en radianes.


37 theta flotante = 0,0
38 // Bucle para crear los puntos de la espiral. Crea 4 puntos por rotación completa.
39 para i = 0 a rotaciones * 4
40 //@variable Un nuevo punto en la espiral calculada.
41 chart.point nuevoPunto = puntoespiral(theta, bar_index, ohlc4)
42 // Agrega el `newPoint` a la matriz de `points`.
43 puntos.push(nuevoPunto)
44 // Agrega el `paso` al ángulo `theta`.
45 theta += paso
46

47 //@variable Un color aleatorio para el nuevo dibujo `espiral`.


48 color espiralColor = color.rgb(math.random(150, 255), math.random(0, 100), math.
→aleatorio(150, 255))
49 //@variable Una nueva polilínea que conecta los puntos de la espiral. Utiliza el campo `index`
→desde cada punto como coordenadas x.
50 polilínea espiral = polilínea.new(puntos, verdadero, color_línea = colorespiral, ancho_línea
→= 3)
51

52 // Inserta la nueva `espiral` en la matriz `polylines`.


53 polilíneas.push(espiral)
54 // Saca la primera polilínea de la matriz y la elimina cuando el tamaño de la matriz
→ excede el `númeroDeEspirales`.
55 si polilíneas.tamaño() > númeroDeEspirales
56 polilínea.eliminar(polilíneas.shift())
57

58 // Resalte el fondo cuando `newSpiral` sea `true`.


59 bgcolor(newSpiral ? color.new(color.blue, 70): na, title = "Nuevo dibujo resaltado")

Tenga en cuenta que:

• Declaramos una variable global MAX_POLYLINES_COUNT con un valor constante de 100. El script utiliza
esta constante como el valor max_polylines_count en la función indicador() y el valor máximo del
entrada númeroDeEspirales.

• Al igual que con nuestro ejemplo de “polígonos de N lados” en la sección anterior, redondeamos el cálculo de las coordenadas x a
el número entero más cercano ya que el campo de índice de un chart.point solo puede aceptar un valor int .

• A pesar de la apariencia suave de los dibujos, la matriz de puntos de cada polilínea solo contiene cuatro chart.point
objetos por rotación en espiral. Dado que la llamada a polyline.new() incluye curvado = verdadero, cada polilínea usa
curvas suaves para conectar sus puntos, produciendo una aproximación visual de la curvatura real de la espiral.

• El ancho de cada espiral es de aproximadamente 4 * math.pi * rotaciones * xScale, redondeado al


entero más cercano. Usamos este valor en la condición newSpiral para espaciar cada dibujo y evitar superposiciones.

Redibujar polilíneas

En algunos casos, puede ser conveniente cambiar un dibujo de polilínea durante la ejecución de un script. Mientras que la polilínea.*
El espacio de nombres no contiene funciones de configuración integradas, podemos volver a dibujar polilíneas a las que hacen referencia variables o colecciones mediante
eliminando las polilíneas existentes y asignando nuevas instancias con los cambios deseados.

El siguiente ejemplo utiliza llamadas a polyline.delete() y polyline.new() para actualizar el valor de una variable de polilínea.

Este script dibuja polilíneas cerradas que conectan los puntos abiertos, altos, bajos y cerrados de períodos que contienen barras de longitud.
Crea una variable currentDrawing en la primera barra y le asigna una ID de polilínea en cada barra del gráfico. Utiliza el
Variables openPoint, highPoint, lowPoint y closePoint para hacer referencia a puntos del gráfico que rastrean el período.
desarrollar valores OHLC. A medida que surgen nuevos valores, el script asigna nuevos objetos chart.point a las variables, los recopila

4.12. Líneas y cajas 273


Machine Translated by Google

Manual del usuario de Pine Script™ v5

en una matriz usando array.from, luego crea una nueva polilínea que conecta las coordenadas de los puntos de la matriz y la asigna
al Dibujo actual.

Cuando la condición newPeriod es falsa (es decir, el período actual no está completo), el script elimina la polilínea a la que hace
referencia el Dibujo actual antes de crear una nueva, lo que da como resultado un dibujo dinámico que cambia durante el período
de desarrollo:

1 //@version=5 2
indicador("Demostración de redibujado de polilíneas", "Polígonos OHLC", verdadero, max_polylines_count =
→100)
3

4 //@variable La duración del período. 5 int longitud = input.int(100, "Longitud", 1)

7 //@variable Un `chart.point` que representa el inicio de cada período. 8 var chart.point openPoint = na 9 //@variable Un `chart.point` que
representa el punto más alto de cada período. 10 var chart.point
highPoint = na 11 //@variable Un `chart.point` que representa el punto más bajo de cada período. 12 var chart.point lowPoint = na 13 //@variable Un
`chart.point` que representa el punto de cierre de la barra actual. 14
closePoint = chart.point.now(cerrar)

15

16 //@variable Dibujo de polilínea del período actual. 17 var polilínea dibujo actual = na

18

19 //@variable Es "verdadero" una vez cada barra de "longitud". 20 bool nuevoPeriodo = bar_index %
longitud == 0
21

22 si es nuevoPeríodo
23 // Asigna nuevos puntos del gráfico a `openPoint`, `highPoint` y `closePoint`. openPoint := chart.point.now(abierto) highPoint :=
24 chart.point.now(alto) lowPoint := chart.point.now(bajo)
25

26

27 más
28 // Asigna un nuevo `chart.point` al `highPoint` cuando el `high` es mayor que →su `price`. si es alto > punto alto.precio punto alto :=
chart.point.now(alto)
29

30

(continúa en la página siguiente)

274 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

31 // Asigna un nuevo `chart.point` al `lowPoint` cuando el `low` es menor que su


→`precio`.
32 si es bajo <puntobajo.precio
33 puntobajo := chart.point.now(bajo)
34

35 //@variable Es verde azulado cuando `closePoint.price` es mayor que `openPoint.price`,


→ granate en caso contrario.

Dibujo de 36 coloresColor = closePoint.price > openPoint.price? color.verde azulado : color.granate


37

38 // Elimina la polilínea asignada al `currentDrawing` si no es un `newPeriod`.


39 si no es nuevoPeriodo
40 polilínea.eliminar (dibujo actual)
41 // Asigna una nueva polilínea al `dibujo actual`.
42 // Utiliza el campo `index` de cada `chart.point` en su matriz como coordenadas x.
43 Dibujo actual := polilínea.nuevo(
44 array.from(openPoint, highPoint, closePoint, lowPoint), cerrado = verdadero,
45 color_linea = Colordibujo, color_relleno = color.new(Colordibujo, 60)
46 )

4.12.5 Comportamiento en tiempo real

Las líneas, cuadros y polilíneas están sujetos a acciones de confirmación y reversión , que afectan el comportamiento de un script cuando
se ejecuta en una barra de tiempo real. Consulte la página sobre el modelo de ejecución de Pine Script™ .

Este script demuestra el efecto de la reversión cuando se ejecuta en la barra del gráfico no confirmado en tiempo real:

La llamada line.new() en este ejemplo crea una nueva ID de línea en cada iteración cuando los valores cambian en la barra no confirmada. El
El script elimina automáticamente los objetos creados en cada cambio en esa barra debido a la reversión antes de cada iteración.
Solo confirma la última línea creada antes de que se cierre la barra, y esa instancia de línea es la que persiste en la barra confirmada.
bar.

4.12. Líneas y cajas 275


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.12.6 Limitaciones

Número total de objetos

Las líneas, cuadros y polilíneas consumen recursos del servidor, por lo que existen límites en la cantidad total de dibujos por script.
Cuando un script crea más objetos de dibujo que el límite permitido, el tiempo de ejecución de Pine Script™ elimina automáticamente
los más antiguos en un proceso denominado recolección de basura.

Un único script puede contener hasta 500 líneas, 500 cuadros y 100 polilíneas. Los usuarios pueden controlar los límites de
recolección de basura especificando los valores max_lines_count, max_boxes_count y max_polylines_count en la declaración de
declaración de indicador() o estrategia() de su script.

Este script demuestra cómo funciona la recolección de basura en Pine. Crea una nueva línea, cuadro y polilínea en cada barra del
gráfico. No hemos especificado valores para los parámetros max_lines_count, max_boxes_count o max_polylines_count en la
llamada a la función indicador() , por lo que el script mantendrá las ~50 líneas, cuadros y polilíneas más recientes en el gráfico, ya
que esta es la configuración predeterminada para cada parámetro:

1 //@versión=5 2
indicador("Demostración de recolección de basura", superposición = verdadero)
3

4 //@variable Un nuevo `chart.point` en el `bar_index` y `high` actuales. 5 firstPoint = chart.point.now(high) 6 //@variable


Un nuevo `chart.point` una barra hacia el futuro en el `low`
actual. 7 secondPoint = chart.point.from_index(bar_index + 1, low) 8 //@variable Un nuevo `chart.point` una barra hacia el futuro en
el `high` actual. 9 tercerPunto = chart.point.from_index(bar_index + 1, alto)

10

11 // Dibuje una nueva `línea` que conecte el `primerPunto` con el `segundoPunto`. 12 líneas.nuevo(primerPunto,
segundoPunto, color = color.rojo, ancho = 2)
13 // Dibuja un nuevo `cuadro` con la esquina superior izquierda `primerPunto` y la esquina inferior `segundoPunto`
→esquina derecha.
14 box.new(primerPunto, segundoPunto, color.púrpura, 2, bgcolor = na)
15 // Dibuja una nueva `polilínea` que conecte el `primerPunto`, el `segundoPunto` y el `tercerPunto`
→secuencialmente.
16 polilínea.nueva(array.from(primerPunto, segundoPunto, tercerPunto), verdadero, ancho_línea = 2)

Tenga en cuenta que:

276 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Hemos utilizado la herramienta de dibujo “Medir” de TradingView para medir el número de barras cubiertas por el script.
dibujar objetos.

Referencias futuras con `xloc.bar_index`

Los objetos colocados usando xloc.bar_index pueden contener coordenadas x no más allá de 500 barras en el futuro.

Otros contextos

Los scripts no pueden utilizar líneas, cuadros o polilíneas en las funciones request.*(). Las instancias de estos tipos pueden usar los valores
de las llamadas request.*(), pero los scripts solo pueden crearlos y dibujarlos en el contexto del gráfico.

Esta limitación también es la razón por la que dibujar objetos no funcionará cuando se use el parámetro de marco de tiempo en la declaración
de indicador() .

Búfer histórico y `max_bars_back`

El uso de barstate.isrealtime en combinación con dibujos a veces puede producir resultados inesperados. Por ejemplo, la intención de este
script es ignorar todas las barras históricas y dibujar líneas horizontales que abarquen 300 barras en barras en tiempo real :

1 //@versión=5
2 indicador ("Demostración de búfer histórico", superposición = verdadero)
3

4 //@variable Un `chart.point` en el `bar_index` de hace 300 barras y el `cierre` actual. 5 firstPoint = chart.point.from_index(bar_index[300], close) 6 //@variable El
`chart.point` de la barra actual que contiene el `close` actual. 7 segundoPunto = chart.point.now(cerrar)

9 // Dibuja una nueva línea en las barras de tiempo real.


10 si barstate.isrealtime
11 line.new(primerPunto, segundoPunto)

Sin embargo, fallará en tiempo de ejecución y generará un error. El script falla porque no puede determinar el tamaño del búfer para los
valores históricos de la serie temporal subyacente . Aunque el código no contiene la variable de tiempo incorporada, el bar_index incorporado
utiliza la serie de tiempo en su funcionamiento interno. Por lo tanto, acceder al valor de bar_index desde 300 barras atrás requiere que el
búfer histórico de la serie temporal sea de al menos 300 barras.

Pine Script™ incluye un mecanismo que detecta automáticamente el tamaño del búfer histórico requerido en la mayoría de los casos.
Funciona permitiendo que el script acceda a valores históricos cualquier número de barras hacia atrás durante un tiempo limitado. En el caso
de este script, el uso de barstate.isrealtime para controlar el dibujo de líneas le impide acceder a la serie histórica, por lo que no puede inferir
el tamaño del búfer histórico requerido y el script falla.

La solución simple a este problema es usar la función max_bars_back() para definir explícitamente el búfer histórico de la serie temporal
antes de evaluar la estructura condicional:

Estos problemas pueden resultar confusos, pero son bastante raros. El equipo de Pine Script™ espera eliminarlos con el tiempo.

4.12. Líneas y cajas 277


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.13 Datos de gráficos no estándar

• Introducción

• `ticker.heikinashi()`

• `ticker.renko()`

• `ticker.linebreak()`

• `ticker.kagi()`

• `ticker.pointfigure()`

4.13.1 Introducción

Estas funciones permiten que los scripts obtengan información de barras o tipos de gráficos no estándar, independientemente del tipo de gráfico
en el que se esté ejecutando el script. Son: ticker.heikinashi(), ticker.renko(), ticker.linebreak(), ticker.kagi() y ticker.pointfigure().
Todos ellos funcionan de la misma manera; crean un identificador de teletipo especial que se utilizará como primer argumento en una llamada a
la función re­quest.security() .

4.13.2 `ticker.heikinashi()`

Heikin­Ashi significa barra promedio en japonés. Los valores de apertura/máximo/mínimo/cierre de las velas Heikin­Ashi son sintéticos; no son
precios reales de mercado. Se calculan promediando combinaciones de valores OHLC reales de la barra actual y anterior. Los cálculos utilizados
hacen que las barras Heikin­Ashi sean menos ruidosas que las velas normales. Pueden ser útiles para realizar evaluaciones visuales, pero no
son adecuados para realizar pruebas retrospectivas o operaciones automatizadas, ya que las órdenes se ejecutan según los precios del mercado,
no sobre los precios Heikin­Ashi.

La función ticker.heikinashi() crea un identificador de teletipo especial para solicitar datos de Heikin­Ashi con la función re­quest.security() .

Este script solicita el valor de cierre de las barras Heikin­Ashi y las traza sobre las velas normales:

278 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@version=5 2
indicador("HA Close", "", true) 3 haTicker =
ticker.heikinashi(syminfo.tickerid) 4 haClose = request.security(haTicker,
timeframe.period, close) 5 plot(haClose , "HA Cerrar", color.negro, 3)

Tenga en cuenta que:

• Los valores de cierre de las barras Heikin­Ashi representados como la línea negra son muy diferentes de los de las velas reales que
utilizan precios de mercado. Actúan más como una media móvil.

• La línea negra aparece sobre las barras del gráfico porque hemos seleccionado "Orden visual/Traer al frente" en el menú del script.
Menú “Más”.

Si desea omitir valores para el horario extendido en el último ejemplo, primero deberá crear un ticker intermediario sin información de sesión
extendida:

4.13. Datos de gráficos no estándar 279


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@version=5 2
indicador("HA Close", "", true) 3 regularSessionTicker =
ticker.new(syminfo.prefix, syminfo.ticker, session.regular) 4 haTicker = ticker.heikinashi(regularSessionTicker) 5 haClose =
request.security(haTicker, timeframe.period, close, gaps = barmerge.gaps_on) 6
plot(haClose, "HA Close", color.black, 3, plot.style_linebr)

Tenga en cuenta que:

• Primero usamos la función ticker.new() para crear un ticker sin información de sesión extendida.

• Usamos ese ticker en lugar de syminfo.tickerid en nuestra llamada ticker.heikinashi() .

• En nuestra llamada request.security() , configuramos el valor del parámetro gaps en barmerge.gaps_on. Esto indica a la función que no utilice valores
anteriores para llenar los espacios donde faltan datos. Esto hace posible que devuelva valores na fuera de las sesiones regulares.

• Para poder ver esto en el gráfico, también necesitamos usar un estilo especial plot.style_linebr, que rompe el
gráficos sobre valores de na .

Este script traza velas Heikin­Ashi debajo del gráfico:

1 //@versión=5
2 indicador("velas Heikin­Ashi")
3 VELA_VERDE = #26A69A
4 VELAS_ROJAS = #EF5350
5

6 haTicker = ticker.heikinashi(syminfo.tickerid) 7 [haO, haH, haL, haC] =


request.security(haTicker, timeframe.period, [abierto, alto, bajo,
→cerrar])
8 color de vela = haC >= haO ? CANDLE_GREEN : CANDLE_RED 9 tramacandela(haO,
haH, haL, haC, color = colorvela)

Tenga en cuenta que:

• Usamos una tupla con request.security() para recuperar cuatro valores con la misma llamada.

• Usamos plotcandle() para trazar nuestras velas. Consulte la página de trazado de barras para obtener más información.

280 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.13.3 `ticker.renko()`

Las barras Renko solo trazan los movimientos de precios, sin tener en cuenta el tiempo ni el volumen. Parecen ladrillos apilados en columnas
.
adyacentes1. Un nuevo ladrillo solo se extrae después de que el precio supera la parte superior o inferior en una cantidad predeterminada.
La función ticker.renko() crea una identificación de teletipo que se puede usar con request.security() para recuperar valores de Renko, pero no
existe una función de Pine Script™ para dibujar barras de Renko en el gráfico:

1 //@version=5 2
indicador("", "", verdadero) 3 renkoTicker
= ticker.renko(syminfo.tickerid, "ATR", 10) 4 renkoLow = request.security(renkoTicker,
timeframe.period, low) 5 trama (renkoBajo)

4.13.4 `ticker.linebreak()`

El tipo de gráfico Salto de línea muestra una serie de cuadros verticales que se basan en cambios de precios1 . La función ticker.linebreak()
crea una identificación de teletipo que se puede usar con request.security() para recuperar valores de “salto de línea”, pero no existe una función
de Pine Script™ para dibujar dichas barras en el gráfico:

1 //@version=5 2
indicador("", "", verdadero) 3
lineBreakTicker = ticker.linebreak(syminfo.tickerid, 3) 4 lineBreakClose =
request.security(lineBreakTicker, timeframe.period, close) 5 plot(lineBreakClose )

4.13.5 `ticker.kagi()`

Los gráficos Kagi están formados por una línea continua que cambia de dirección. La dirección cambia cuando el precio cambia1 más allá de una
cantidad predeterminada. La función ticker.kagi() crea una identificación de teletipo que se puede usar con request.security() para recuperar
valores "Kagi", pero no existe una función Pine Script™ para dibujar dichas barras en el gráfico:

1 //@version=5 2
indicador("", "", verdadero) 3
kagiBreakTicker = ticker.linebreak(syminfo.tickerid, 3) 4 kagiBreakClose =
request.security(kagiBreakTicker, timeframe.period, close) 5 plot(kagiBreakClose )

4.13.6 `ticker.pointfigure()`

,
Los gráficos de puntos y figuras (PnF) solo trazan los movimientos de precios1 sin tener en cuenta el tiempo. Se traza una columna de X cuando
el precio aumenta y de O cuando el precio baja. La función ticker.pointfigure() crea una identificación de teletipo que se puede usar con
request.security() para recuperar valores "PnF", pero no existe una función Pine Script™ para dibujar dichas barras en el gráfico. Cada columna
de X u O está representada con cuatro números. Puede considerarlos como valores sintéticos de OHLC PnF:

1 //@versión=5 2
indicador("", "", verdadero) 3 pnfTicker
= ticker.pointfigure(syminfo.tickerid, "hl", "ATR", 14, 3)
(continúa en la página siguiente)

1 En TradingView, los tipos de gráficos Renko, Line Break, Kagi y PnF se generan a partir de valores OHLC de un período de tiempo inferior. Por lo tanto, estos tipos de gráficos

representan sólo una aproximación de cómo serían si se generaran a partir de datos de ticks.

4.13. Datos de gráficos no estándar 281


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

4 [pnfO, pnfC] = request.security(pnfTicker, timeframe.period, [abrir, cerrar], barmerge.


→gaps_on)
5 plot(pnfO, "PnF Open", color.green, 4, plot.style_linebr) 6 plot(pnfC, "PnF Close", color.red,
4, plot.style_linebr)

4.14 Parcelas

• Introducción

• Parámetros `plot()`

• Trazar condicionalmente

• Niveles

• Compensaciones

• Límite de recuento de parcelas

• Escala

4.14.1 Introducción

La función plot() es la función más utilizada para mostrar información calculada utilizando scripts de Pine. Es versátil y puede trazar diferentes
estilos de líneas, histogramas, áreas, columnas (como columnas de volumen), rellenos, círculos o cruces.

El uso de plot() para crear rellenos se explica en la página sobre Rellenos.

Este script muestra algunos usos diferentes de plot() en un script superpuesto:

282 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@version=5 2
indicador("`plot()`", "", true) 3 plot(high, "Línea azul
`high`") 4 plot(math.avg(cerrar, abrir), "Cruces en
el centro del cuerpo", cerrar > abrir? color.lime : →color.purple, 6, plot.style_cross) 5 plot(math.min(abrir, cerrar), "Línea de paso
azul marino en el punto bajo del cuerpo", color.navy ,
3, trama.
→style_stepline)
6 plot(low, "Punto gris en `low`", color.gray, 3, plot.style_circles)
7

8 colores VIOLETA = #AA00FF


9 colores ORO = #CCCC00
10 ma = ta.alma(hl2, 40, 0.85, 6) 11 var almaColor =
color.plata
12 almaColor := ma > ma[2] ? ORO: ma < ma[2] ? VIOLETA : trama almaColor 13 (ma, "ALMA bicolor", almaColor,
2)

Tenga en cuenta que:

• La primera llamada a plot() traza una línea azul de 1 píxel a través de los máximos de la barra.

• La segunda trama se cruza en el punto medio de los cuerpos. Las cruces son de color lima cuando la barra está arriba y violeta cuando está abajo. El argumento
utilizado para el ancho de línea es 6 pero no es un valor de píxel; sólo un tamaño relativo.

• La tercera llamada traza una línea de paso de 3 píxeles de ancho siguiendo el punto más bajo de los cuerpos.

• La cuarta llamada traza un círculo gris en el mínimo de las barras .

• La última trama requiere cierta preparación. Primero definimos nuestros colores alcistas/osos, calculamos una media móvil de Arnaud Legoux y luego hacemos
nuestros cálculos de colores. Inicializamos nuestra variable de color solo en la barra cero, usando var. Lo inicializamos en color.silver, por lo que en las primeras
barras del conjunto de datos, hasta que una de nuestras condiciones haga que el color cambie, la línea será plateada. Las condiciones que cambian el color de la
línea requieren que sea mayor/menor que su valor hace dos barras.
Esto hace que las transiciones de color sean menos ruidosas que si simplemente buscáramos un valor superior/inferior al anterior.

Este script muestra otros usos de plot() en un panel:

4.14. Parcelas 283


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5 2
indicador("Cambio de volumen", formato = formato.volumen)
3

4 colores VERDE = #008000


5 colores VERDE_LUZ = color.nuevo(VERDE, 50) 6 colores VERDE_LUZ =
color.nuevo(VERDE, 85)
colores ROSA = #FF0080 7
8 colores PINK_LIGHT = color.nuevo(ROSA, 50)
9 colores PINK_LIGHTER = color.nuevo(PINK, 90)
10

11 bool barUp = ta.rising(cerrar, 1) 12 bool barDn = ta.falling(cerrar,


1) 13 float volumeChange = ta.change(volumen)

14

15 ColorVolumen = barArriba ? GREEN_LIGHTER: barDn? PINK_LIGHTER: color.gray 16 plot(volumen, "Columnas de volumen",


colorvolumen, estilo = plot.style_columns)
17

18 cambio de volumenColor = barra arriba? ¿Cambio de volumen > 0? VERDE: GREEN_LIGHT: cambio de volumen> 0
→? ROSA: ROSA_LUZ
19 plot(volumeChange, "Columnas de cambio de volumen", volumeChangeColor, 12, plot.style_
→histograma)
20

21 trazado(0, "Línea cero", color.gris)

Tenga en cuenta que:

• Estamos trazando valores de volumen normales como columnas anchas sobre la línea cero (consulte el estilo = gráfico.
style_columns en nuestra llamada plot() ).

• Antes de trazar las columnas calculamos nuestro color de volumen utilizando los valores de las variables booleanas barUp y barDn. Se vuelven
respectivamente verdaderos cuando el cierre de la barra actual es más alto/más bajo que el anterior. Tenga en cuenta que el "Volumen"
integrado no utiliza la misma condición; identifica una barra superior con cerrar > abrir.
Usamos los colores GREEN_LIGHTER y PINK_LIGHTER para las columnas de volumen.

• Debido a que el primer gráfico traza columnas, no utilizamos el parámetro de ancho de línea, ya que no tiene ningún efecto en las columnas.

• El segundo gráfico de nuestro script es el cambio en el volumen, que hemos calculado anteriormente usando ta.change(volumen).
Este valor se traza como un histograma, para el cual el parámetro de ancho de línea controla el ancho de la columna. Hacemos que este
ancho sea 12 para que los elementos del histograma sean más delgados que las columnas del primer gráfico. Positivo negativo

284 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Los valores de cambio de volumen se trazan por encima/debajo de la línea cero; no se requiere ninguna manipulación para lograr este efecto.

• Antes de trazar el histograma de valores de cambio de volumen, calculamos su valor de color, que puede ser uno de cuatro colores diferentes.
Usamos los colores VERDE o ROSA brillante cuando la barra está arriba/abajo Y el volumen ha aumentado desde la última barra (cambio de
volumen > 0). Debido a que el cambio de volumen es positivo en este caso, el elemento del histograma se trazará encima de la línea cero. Usamos
los colores brillantes GREEN_LIGHT o PINK_LIGHT cuando la barra está arriba/abajo Y el volumen NO ha aumentado desde la última barra.
Debido a que el cambio de volumen es negativo en este caso, el elemento del histograma se trazará debajo de la línea cero.

• Finalmente, trazamos una línea cero. También podríamos haber usado hline(0) allí.

• Usamos formato = formato.volumen en nuestra llamada a indicador() para que los valores grandes mostrados para este script sean
abreviados como los del indicador “Volumen” incorporado.

Las llamadas a plot() siempre deben colocarse en la primera posición de una línea, lo que implica que siempre están en el alcance global del script. No se
pueden colocar en funciones o estructuras definidas por el usuario como if, for, etc. Sin embargo, las llamadas a plot() pueden diseñarse para trazar
condicionalmente de dos maneras, que cubrimos en la sección Trazados condicionales de esta página.

Un script sólo puede trazar en su propio espacio visual, ya sea en un panel o en el gráfico como una superposición. Los scripts que se ejecutan en un panel
solo pueden colorear las barras en el área del gráfico.

4.14.2 Parámetros `plot()`


La función plot() tiene la siguiente firma:

trama (serie, título, color, ancho de línea, estilo, precio de seguimiento, histbase, desplazamiento, unión, →editable,
show_last, display) → trama

Los parámetros de plot() son:

series Es

el único parámetro obligatorio. Su argumento debe ser del tipo “series int/float”. Tenga en cuenta que debido a que las reglas de conversión
automática en Pine Script™ convierten en la dirección int 2/7 float 2/7 bool, una variable de tipo “bool” no se puede utilizar tal cual; debe convertirse
en “int” o “float” para usarlo como argumento. Por ejemplo, si newDay es de tipo “bool”, ¿newDay? 1: 0 se puede utilizar para representar 1 cuando
la variable es verdadera y cero cuando es falsa.

título

Requiere un argumento de "cadena constante", por lo que debe conocerse en el momento de la compilación. Aparece la cadena:

• En la escala del script cuando el campo “Configuración del gráfico/Escalas/Etiqueta de nombre del indicador” está marcado.

• En la ventana de datos.

• En la pestaña “Configuración/Estilo”.

• En el menú desplegable de campos input.source() .

• En el campo “Condición” del cuadro de diálogo “Crear alerta”, cuando se selecciona el script.

• Como encabezado de columna al exportar datos del gráfico a un archivo CSV.

color

Acepta “color de serie”, por lo que se puede calcular sobre la marcha, barra por barra. Trazar con na como color, o cualquier color con una
transparencia de 100, es una forma de ocultar trazados cuando no son necesarios.

ancho de línea

Es el tamaño del elemento trazado, pero no se aplica a todos los estilos. Cuando se traza una línea, la unidad son píxeles. No tiene ningún impacto
cuando se usa plot.style_columns .

estilo
Los argumentos disponibles son:

4.14. Parcelas 285


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• plot.style_line (el valor predeterminado): traza una línea continua usando el argumento ancho de línea en píxeles para su ancho.
Los valores na no se trazarán como una línea, pero se unirán cuando entre un valor que no sea na . Los valores que no sean na
solo se unirán si son visibles en el gráfico.

• plot.style_linebr: permite trazar líneas discontinuas al no trazar en valores na y no unir espacios.


es decir, superar los valores na .

• plot.style_stepline: Gráficos que utilizan un efecto de escalera. Las transiciones entre cambios de valores se realizan utilizando una
línea vertical dibujada en medio de las barras, en lugar de una diagonal punto a punto que une los puntos medios de las barras.
También se puede utilizar para lograr un efecto similar al de plot.style_linebr, pero solo si se tiene cuidado de no trazar ningún
color en los valores na .

• plot.style_area: traza una línea de ancho de línea, llenando el área entre la línea y la base histórica.
El argumento color se utiliza tanto para la línea como para el relleno. Puedes hacer que la línea tenga un color diferente usando
otra llamada a plot() . Los valores positivos se trazan encima de la base histórica y los valores negativos debajo.

• plot.style_areabr: Esto es similar a plot.style_area pero no une los valores na . Otra diferencia es cómo se calcula la escala del
indicador. Sólo los valores trazados sirven para calcular el rango y del espacio visual del guión. Si solo se trazan valores altos
situados lejos de la base histórica, por ejemplo, esos valores se usarán para calcular la escala y del espacio visual del script. Los
valores positivos se trazan encima de la base histórica y los valores negativos debajo.

• plot.style_columns: Traza columnas similares a las del indicador incorporado “Volumen”. El valor del ancho de línea no afecta el
ancho de las columnas. Los valores positivos se trazan encima de la base histórica y los valores negativos debajo. Siempre incluye
el valor de histbase en la escala y del espacio visual del script.

• plot.style_histogram: traza columnas similares a las del indicador incorporado “Volumen”, excepto que el valor del ancho de línea
se utiliza para determinar el ancho de las barras del histograma en píxeles. Tenga en cuenta que dado que el ancho de línea
requiere un valor de “entrada int”, el ancho de las barras del histograma no puede variar de una barra a otra. Los valores positivos
se trazan encima de la base histórica y los valores negativos debajo. Siempre incluye el valor de histbase en la escala y del
espacio visual del script.

• plot.style_circles y plot.style_cross: trazan una forma que no está unida entre barras a menos que también se use join = true. Para
estos estilos, el argumento del ancho de línea se convierte en una medida de tamaño relativa: sus unidades no son píxeles.

trackprice El valor
predeterminado de esto es falso. Cuando sea cierto, se trazará una línea de puntos formada por pequeños cuadrados en todo el ancho
del espacio visual del guión. A menudo se usa junto con show_last = 1, offset = ­99999 para ocultar el gráfico real y dejar solo la línea de
puntos residual.

base histórica
Es el punto de referencia utilizado con plot.style_area, plot.style_columns y plot.style_histogram. Determina el nivel que separa los
valores positivos y negativos del argumento de la serie. No se puede calcular dinámicamente, ya que se requiere una "entrada int/float".

desplazamiento Esto permite cambiar la gráfica en el pasado/futuro usando un desplazamiento negativo/positivo en barras. El valor no puede
cambiar durante la ejecución del script.

unirse
Esto solo afecta a los estilos plot.style_circles o plot.style_cross. Cuando es verdadero, las formas están unidas por una línea de un píxel.

editable Este
parámetro booleano controla si las propiedades del gráfico se pueden editar o no en la pestaña “Configuración/Estilo”. Su valor
predeterminado es verdadero.

show_last
Permite controlar cuántas de las últimas barras son visibles los valores trazados. Se requiere un argumento "input int", por lo que no se
puede calcular dinámicamente.

286 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

mostrar
El valor predeterminado es mostrar.todo. Cuando se establece en display.none, los valores trazados no afectarán la escala del espacio
visual del guión. El gráfico será invisible y no aparecerá en los valores del indicador ni en la ventana de datos. Puede ser útil en
gráficos destinados a usarse como entradas externas para otros scripts, o para gráficos utilizados con el marcador de posición
{{plot("[plot_title]")}} en llamadas alertcondition() , por ejemplo:

1 //@versión=5
2 indicadores("")
3 r = ta.rsi(close, 14) 4 xUp =
ta.crossover(r, 50) 5 plot(r, "RSI", display =
display.none) 6 alertcondition(xUp, "alerta xUp", mensaje = ' El RSI
es alcista en: {{plot("RSI")}}')

4.14.3 Trazar condicionalmente

Las llamadas a plot() no se pueden usar en estructuras condicionales como if, pero se pueden controlar variando sus valores trazados o su
color. Cuando no se requiere ningún trazado, puede trazar valores na o trazar valores usando un color o cualquier color con 100 de
transparencia (lo que también lo hace invisible).

Control de valor

Una forma de controlar la visualización de gráficos es trazar valores na cuando no se necesita ningún gráfico. A veces, los valores devueltos
por funciones como request.security() devolverán valores na , cuando se usa gaps = barmerge.gaps_on, por ejemplo. En ambos casos, a
veces resulta útil trazar líneas discontinuas. Este script muestra algunas formas de hacerlo:

1 //@versión=5
2 indicador("Gráficos discontinuos", "", verdadero) 3 bool plotValues =
bar_index % 3 == 0 4 plot(plotValues ? alto: na, color =
color.fucsia, ancho de línea = 6, estilo = plot.style_
→linebr) 5
plot(plotValues? alto: na) 6 plot(plotValues?
math.max(abrir, cerrar): na, color = color.navy, ancho de línea = 6,
→estilo = trama.style_cross)
7 plot(plotValues? math.min(abrir, cerrar): na, color = color.navy, ancho de línea = 6,
(continúa en la página siguiente)

4.14. Parcelas 287


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

→estilo = trama.style_circles)
8 plot(plotValues? bajo: na, color = plotValues? color.green: na, ancho de línea = 6,
→estilo = trama.style_stepline)

Tenga en cuenta que:

• Definimos la condición determinante cuando graficamos usando bar_index % 3 == 0, que se vuelve verdadera cuando
el resto de la división del índice de la barra por 3 es cero. Esto sucederá cada tres compases.

• En el primer gráfico utilizamos plot.style_linebr, que traza la línea fucsia en los máximos. Está centrado en la horizontal de la barra.
punto medio.

• El segundo gráfico muestra el resultado de trazar los mismos valores, pero sin tener especial cuidado al romper la línea. Lo que sucede aquí es que la
delgada línea azul de la llamada simple a plot() se une automáticamente sobre los valores na (o espacios), por lo que la trama no se interrumpe.

• Luego trazamos cruces y círculos de color azul marino en la parte superior e inferior del cuerpo. Los estilos plot.style_circles y plot.style_cross son una
forma sencilla de trazar valores discontinuos, por ejemplo, niveles de parada o toma de ganancias, o niveles de soporte y resistencia.

• El último gráfico en verde en los mínimos de la barra se realiza usando plot.style_stepline. Observe cómo sus segmentos son más anchos que los
segmentos de línea fucsia trazados con plot.style_linebr. También observe cómo en la última barra, solo se traza hasta la mitad hasta que llega la
siguiente barra.

• El orden de trazado de cada trama está controlado por su orden de aparición en el guión. Ver

Este script muestra cómo puede restringir el trazado a barras después de una fecha definida por el usuario. Usamos la función input.time() para crear un widget
de entrada que permite a los usuarios del script seleccionar una fecha y hora, usando el 1 de enero de 2021 como valor predeterminado:

1 //@versión=5
2 indicador("", "", verdadero) 3 startInput =
input.time(timestamp("2021­01­01")) 4 plot(time > startInput? cerrar: na)

Control de colores

La sección Coloración condicional de la página sobre colores analiza el control de color para los gráficos. Aquí veremos algunos ejemplos.

El valor del parámetro de color en plot() puede ser una constante, como uno de los colores constantes integrados o un literal de color.
En Pine Script™, el tipo calificado de dichos colores se denomina “color constante” (consulte la página del sistema Tipo ). Se conocen en tiempo de compilación.

1 //@versión=5 2
indicador("", "", verdadero) 3 trazado(cerrar,
color = color.gray)

El color de un gráfico también se puede determinar utilizando información que sólo se conoce cuando el script comienza a ejecutarse en la primera barra histórica
de un gráfico (barra cero, es decir, bar_index == 0 o barstate.isfirst == true), como será el caso en el que la información necesaria para determinar un color
depende del gráfico en el que se ejecuta el script. Aquí, calculamos el color del gráfico utilizando la variable incorporada syminfo.type , que devuelve el tipo de
símbolo del gráfico. El tipo calificado de plotColor en este caso será “color simple”:

//@version=5
indicador("", "", true) plotColor =
switch syminfo.type "stock" => color.purple
"futures" => color.red

"índice" => color.gris


(continúa en la página siguiente)

288 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)


"divisas" => color.fucsia
"cripto" => color.lima
"fondo" => color.naranja =>
"dr" color.aqua =>
"cfd" color.azul
plot(close, color = plotColor) printTable(txt) => var
table t = table.new(position.middle_right, 1, 1), table.cell(t, → 0, 0, txt, bgcolor = color.amarillo) imprimirTabla(syminfo.type)

Los colores de la trama también se pueden elegir mediante las entradas del guión. En este caso, la variable lineColorInput es del tipo “color de
entrada” :

1 //@versión=5
2 indicadores ("", "", verdadero) 3 colores
lineColorInput = input(#1848CC, "Color de línea") 4 trazados (cerrar, color = lineColorInput)

Finalmente, los colores del trazado también pueden ser valores dinámicos , es decir, valores calculados que pueden cambiar en cada barra. Estos
valores son del tipo “color serie” :

1 //@version=5 2
indicador("", "", verdadero) 3 plotColor =
cerrar >= abrir? color.lime: color.red 4 plot(cerrar, color = plotColor)

Al trazar niveles de pivote, un requisito común es evitar trazar transiciones de nivel. Usar líneas es una alternativa, pero también puedes usar plot()
de esta manera:

1 //@version=5 2
indicador("Gráficos de pivote", "", verdadero) 3 pivotHigh =
fixnan(ta.pivothigh(3,3)) 4 plot(pivotHigh, "PivotHigh",
ta.change(pivotHigh) ? na : color.olive, 3) 5 plotchar(ta.change(pivotHigh), "ta.change(pivotHigh)", "•", ubicación.top, tamaño =
tamaño.
→pequeño)

Tenga en cuenta que:

4.14. Parcelas 289


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Usamos pivotHigh = fixnan(ta.pivothigh(3,3)) para mantener nuestros valores de pivote. Debido a que ta.pivothigh() solo devuelve un
valor cuando se encuentra un nuevo pivote, usamos fixnan() para llenar los espacios con el último valor de pivote devuelto.
Los espacios aquí se refieren a los valores na que devuelve ta.pivothigh() cuando no se encuentra ningún nuevo pivote.

• Nuestros pivotes se detectan tres barras después de que ocurren porque usamos el argumento 3 para los parámetros leftbars y
rightbars en nuestra llamada ta.pivothigh() .

• El último gráfico traza un valor continuo, pero establece el color del gráfico en na cuando cambia el valor del pivote, por lo que el
gráfico no es visible en ese momento. Debido a esto, un gráfico visible solo aparecerá en la barra que sigue a aquel en el que
trazamos usando un color.

• El punto azul indica cuando se detecta un nuevo pivote alto y no se dibuja ningún gráfico entre la barra anterior y esa. Observe cómo
el pivote en la barra indicada por la flecha acaba de ser detectado en la barra de tiempo real, tres barras después, y cómo no se
dibuja ningún gráfico. El gráfico solo aparecerá en la siguiente barra, lo que lo hará visible cuatro barras después del pivote real.

4.14.4 Niveles

Pine Script™ tiene una función hline() para trazar líneas horizontales (consulte la página sobre Niveles). hline() es útil porque tiene algunos
estilos de línea que no están disponibles con plot(), pero también tiene algunas limitaciones, a saber, que no acepta "color de serie" y que
su parámetro de precio requiere una "entrada int/float", por lo que no puede variar durante la ejecución del script.

Puedes trazar niveles con plot() de diferentes maneras. Esto muestra un indicador CCI con niveles trazados usando plot():

1 //@version=5 2
indicador("Niveles de CCI con `plot()`") 3 plot(ta.cci(close,
20)) 4 plot(0, "Zero", color.gray, 1, plot.
style_circles) 5 plot(bar_index % 2 == 0? 100: na, "100", color.lime, 1,
plot.style_linebr) 6 plot(bar_index % 2 == 0? ­100: na, "­100", color.fucsia, 1, plot.style_linebr) 7 plot( 200, "200", color.green,
2, trackprice = true, show_last = 1, offset = ­99999) 8 plot(­200, "­200", color .red, 2, trackprice = true, show_last = 1, offset =
­99999) 9 plot( 300, "300", color.new(color.green, 50), 1) 10 plot(­300, "­300" , color.nuevo(color.rojo, 50), 1)

Tenga en cuenta que:

• El nivel cero se traza usando plot.style_circles.

290 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Los 100 niveles se trazan utilizando un valor condicional que solo traza cada segunda barra. Para prevenir la na
Para evitar que los valores se puenteen, utilizamos el estilo de línea plot.style_linebr .

• Los 200 niveles se trazan usando trackprice = true para trazar un patrón distintivo de pequeños cuadrados que se extiende a todo el ancho del espacio visual
del guión. El show_last = 1 allí muestra solo el último valor trazado, que aparecería como una línea recta de una barra si no se usara también el siguiente
truco: el desplazamiento = ­99999 empuja ese segmento de una barra muy lejos en el pasado, por lo que que nunca es visible.

• Los 300 niveles se trazan utilizando una línea continua, pero se utiliza una transparencia más clara para hacerlos menos prominentes.

4.14.5 Compensaciones

El parámetro de desplazamiento especifica el desplazamiento utilizado cuando se traza la línea (los valores negativos se desplazan en el pasado, los valores
positivos se desplazan hacia el futuro). Por ejemplo:

1 //@versión=5 2
indicador("", "", verdadero) 3
trazado(cerrar, color = color.rojo, desplazamiento = ­5) 4 trazado(cerrar,
color = color.lima, desplazamiento = 5)

Como se puede ver en la captura de pantalla, la serie roja se ha desplazado hacia la izquierda (ya que el valor del argumento es negativo), mientras que la serie
verde se ha desplazado hacia la derecha (su valor es positivo).

4.14.6 Límite de recuento de parcelas

Cada guión está limitado a un recuento máximo de tramas de 64. Todas las llamadas a plot*() y alertcondition() cuentan en el recuento de tramas de un guión.
Algunos tipos de llamadas cuentan por más de una en el recuento total de la trama.

Las llamadas a plot() cuentan para uno en el recuento total de trazados si usan un argumento de “color constante” para el parámetro de color, lo que significa que se
conoce en el momento de la compilación, por ejemplo:

trama(cerrar, color = color.verde)

Cuando utilicen otro tipo calificado, como cualquiera de estos, contarán por dos en el recuento total de parcelas:

plot(close, color = syminfo.mintick > 0.0001 ? color.green : color.red) // "simple


→color"
plot(close, color = input.color(color.purple)) // "color de entrada" plot(close, color = close > open ?
color.green : color.red) // "color de serie" plot(close, color = color.new(color.plata, cerrar > abrir? 40: 0)) // "color de serie"

4.14. Parcelas 291


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.14.7 Escala

No todos los valores se pueden trazar en todas partes. El espacio visual de su guión siempre está limitado por límites superior e inferior que
se ajustan dinámicamente con los valores trazados. Un indicador RSI trazará valores entre 0 y 100, por lo que generalmente se muestra en un
panel (o área) distinto encima o debajo del gráfico. Si los valores del RSI se trazaran como una superposición en el gráfico, el efecto sería
distorsionar la escala de precios normal del símbolo, a menos que estuviera cerca del rango de 0 a 100 del RSI. Esto muestra una línea de
señal RSI y una línea central en el nivel 50, con el script ejecutándose en un panel separado:

1 //@versión=5
2 indicador("RSI") 3 myRSI =
ta.rsi(close, 20) 4 bullColor =
color.from_gradient(myRSI, 50, 80, color.new(color.lime, 70), color.
→nuevo(color.lima, 0))
5 osoColor = color.from_gradient(myRSI, 20, 50, color.new(color.red, 0), color.
→nuevo(color.rojo, 70))
6 miRSIColor = miRSI > 50 ? bullColor : bearColor 7 plot(myRSI, "RSI", myRSIColor,
3) 8 hline(50)

Tenga en cuenta que el tamaño del eje y del espacio visual de nuestro script se ajusta automáticamente utilizando el rango de valores trazados, es decir, los
valores de RSI. Consulte la página sobre Colores para obtener más información sobre la función color.from_gradient() utilizada en el script.

Si intentamos trazar los valores cercanos del símbolo en el mismo espacio agregando la siguiente línea a nuestro script:

trama (cerrar)

Esto es lo que pasa:

El gráfico muestra el símbolo BTCUSD, cuyos precios de cierre rondan los 40.000 durante este período. Trazar valores en el rango de 40000
hace que nuestros gráficos de RSI en el rango de 0 a 100 sean indiscernibles. Los mismos gráficos distorsionados ocurrirían si colocáramos
el indicador RSI en el gráfico como una superposición.

292 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Fusionando dos indicadores

Si planea fusionar dos señales en un guión, primero considere la escala de cada una. Es imposible, por ejemplo, trazar correctamente un
RSI y un MACD en el mismo espacio visual del script porque el RSI tiene un rango fijo (0 a 100) mientras que el MACD no, ya que traza
promedios móviles calculados sobre el precio.

Si ambos indicadores utilizaron rangos fijos, puede cambiar los valores de uno de ellos para que no se superpongan. Podríamos, por
ejemplo, trazar tanto el RSI (0 a 100) como el Indicador de Fuerza Verdadera (TSI) (­100 a +100) desplazando uno de ellos. Nuestra
estrategia aquí será comprimir y cambiar los valores de TSI para que se representen sobre el RSI:

1 //@version=5 2
indicador("RSI y TSI") 3 myRSI =
ta.rsi(close, 20) 4 bullColor =
color.from_gradient(myRSI, 50, 80, color.new(color.lime, 70) , color.
→nuevo(color.lima, 0))
5 osoColor = color.from_gradient(myRSI, 20, 50, color.new(color.red, 0), color.
→nuevo(color.rojo, 70))
6 miRSIColor = miRSI > 50 ? bullColor : bearColor 7 plot(myRSI, "RSI",
myRSIColor, 3) 8 hline(100) 9 hline(50) 10 hline(0)

11

12 // 1. Comprimir el rango de TSI de ­100/100 a ­50/50.


13 // 2. Muévalo hacia arriba en 150, de modo que su valor de ­50 min se convierta en 100. 14 myTSI = 150
+ (100 * ta.tsi(close, 13, 25) / 2) 15 plot(myTSI, "TSI", color.azul, 2) 16
trama(ta.ema(myTSI, 13), "TSI EMA", #FF006E) 17
hline(200) 18 hline(150)

Tenga en cuenta que:

• Hemos agregado niveles usando hline para situar ambas señales.

• Para que ambas líneas de señal oscilen en el mismo rango de 100, dividimos el valor TSI por 2 porque tiene un rango de 200 (­100
a +100). Luego aumentamos este valor en 150 para que oscile entre 100 y 200, haciendo de 150 su línea central.

• Las manipulaciones que hacemos aquí son típicas de los compromisos necesarios para poner dos indicadores con escalas diferentes
en el mismo espacio visual, incluso cuando sus valores, a diferencia del MACD, están limitados en un rango fijo.

4.14. Parcelas 293


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.15 Repintado

• Introducción

• Cálculos históricos versus en tiempo real

• Conspirar en el pasado

• Variaciones del conjunto de datos

4.15.1 Introducción

Definimos repintar como: comportamiento del script que hace que los cálculos o gráficos históricos versus en tiempo real se comporten de manera diferente.

El comportamiento de repintado está muy extendido y puede deberse a muchos factores. Siguiendo nuestra definición, nuestra estimación es que más del 95%
de los indicadores existentes se repintan. Los indicadores ampliamente utilizados como MACD y RSI, por ejemplo, exhiben una forma de repintado porque
muestran un valor en barras históricas, pero cuando se ejecutan en tiempo real producirán resultados que fluctúan constantemente hasta que se cierra la barra
en tiempo real. Por tanto, se comportan de manera diferente en las barras históricas y en tiempo real. Esto no necesariamente los hace menos útiles en todos
los contextos, ni impide que los operadores expertos los utilicen. ¿A quién se le ocurriría desacreditar un indicador de perfil de volumen, por ejemplo porque se
actualiza en tiempo real y, por tanto, se repinta?

Los diferentes tipos de repintado que analizamos en esta página se pueden dividir de esta manera:

• Generalizado y a menudo aceptable: recálculo durante la barra en tiempo real (la mayoría de los indicadores clásicos como MACD, RSI y la gran mayoría
de indicadores en los Community Scripts, scripts que utilizan llamadas de repintado request.security() , etc.). A menudo no hay nada de malo en utilizar
estos scripts, siempre que comprenda cómo funcionan. Sin embargo, si elige utilizar estos scripts para emitir alertas u órdenes comerciales, debe saber
si se generan utilizando valores confirmados o en tiempo real y decidir por sí mismo si el comportamiento del script cumple con sus requisitos.

• Engañoso: trazar en el pasado, calcular resultados en tiempo real que no se pueden replicar en barras históricas, reubicar eventos pasados (Ichimoku,
la mayoría de los scripts dinámicos, la mayoría de las estrategias que usan calc_on_evey_tick = true, scripts que usan repintar llamadas de
request.security() cuando los valores se trazan en barras históricas, ya que su comportamiento no será el mismo en tiempo real, la mayoría de los
scripts usan varap, la mayoría de los scripts usan timenow, algunos scripts usan variables barstate.*).

• Inaceptable: scripts que utilizan información futura, estrategias que se ejecutan en gráficos no estándar, scripts que utilizan tiempo real.
plazos intrabar para generar alertas u órdenes.

• Inevitable: revisión de los feeds históricos por parte de los proveedores de datos, variando la barra de inicio de las barras históricas.

Los dos primeros tipos de repintado pueden ser perfectamente aceptables si:

1. Eres consciente del comportamiento.

2. Puedes vivir con ello, o

3. Puedes evitarlo.

294 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Ahora debería quedarle claro que no todos los comportamientos de repintado son intrínsecamente incorrectos y deben evitarse a toda costa. En muchas
situaciones, repintar los indicadores es exactamente lo que se necesita. Lo importante es saber cuándo el comportamiento de repintado no es aceptable para
usted. Para evitar este tipo de situaciones, debe comprender exactamente cómo funcionan las herramientas que utiliza o cómo debe diseñar las que construye.
Si publica scripts, cualquier comportamiento de repintado potencialmente engañoso debe mencionarse junto con las demás limitaciones de su script.

Nota: No discutiremos los peligros de usar estrategias en gráficos no estándar, ya que este problema no está relacionado con el repintado.
Consulte el Backtesting en gráficos no estándar: ¡Precaución! Guión para una discusión sobre el tema.

Para usuarios de scripts

Es muy posible que decida utilizar indicadores de repintado si comprende cómo se comportan y ese comportamiento cumple con los requisitos de su metodología
comercial. No sea uno de esos recién llegados al comercio que ponen frases de “repintar” en guiones publicados como si eso los desacreditara. Hacerlo sólo
revela su incomprensión del tema.

La pregunta "¿Se vuelve a pintar?" no significa nada. En consecuencia, no se puede responder de manera significativa. ¿Por qué? Porque hay que calificarlo. En
cambio, uno podría preguntar:

• ¿Espera a que se cierre la barra de tiempo real antes de mostrar sus marcadores de entrada/salida?

• ¿Las alertas esperan hasta el final de la barra de tiempo real antes de activarse?

• ¿Se vuelven a pintar los gráficos de marcos de tiempo más altos (lo que significa que no se trazarán de la misma manera en las barras de tiempo real que en las barras de tiempo real)?

bares históricos)?

• ¿Su guión se traza en el pasado (como lo hacen la mayoría de los guiones pivotantes o en zigzag)?

• ¿Su estrategia utiliza calc_on_every_tick = true?

• ¿Su indicador se mostrará en tiempo real de la misma manera que lo hace en las barras históricas?

• ¿Está obteniendo información futura con sus llamadas request.security() ?

Lo importante es que comprendas cómo funcionan las herramientas que utilizas y si su comportamiento es compatible con tus objetivos, repintando o no. Como
aprenderá si lee esta página, repintar es un asunto complejo. Tiene muchas caras y muchas causas. Incluso si no programa en Pine Script™, esta página lo
ayudará a comprender la variedad de causas que pueden llevar a repintar y, con suerte, permitirá discusiones más significativas con los autores de scripts.

Para programadores de Pine Script™

Como comentamos en la sección anterior, no es necesario evitar a toda costa todos los tipos de comportamiento de repintado y, como veremos en el siguiente
texto, algunos no pueden. Esperamos que esta página le ayude a comprender mejor la dinámica en juego, para que pueda tomar mejores decisiones de diseño
con respecto a sus herramientas comerciales. El contenido de esta página debería ayudarle a evitar cometer los errores de codificación más comunes que
provocan repintado o trazados engañosos.

Cualesquiera que sean sus decisiones de diseño, si publica su guión, debe explicárselas a los comerciantes para que puedan entender cómo se comporta su
guión.

Examinaremos tres categorías amplias de causas de repintado:

• Cálculos históricos versus en tiempo real

• Conspirar en el pasado

• Variaciones del conjunto de datos

4.15. Repintar 295


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.15.2 Cálculos históricos versus en tiempo real

Valores de datos de fluidos

Los datos históricos no incluyen registros de movimientos de precios intermediarios en barras; sólo valores de apertura, máximo, mínimo y cierre (OHLC).

Sin embargo, en las barras en tiempo real (barras que funcionan cuando el mercado del instrumento está abierto), los valores máximo, mínimo y de cierre no
son fijos; pueden cambiar los valores muchas veces antes de que se cierre la barra en tiempo real y se arreglen sus valores HLC. Son fluidos.
Esto lleva a que un script a veces funcione de manera diferente con datos históricos y en tiempo real, donde solo el precio de apertura no cambiará durante la
barra.

Cualquier secuencia de comandos que utilice valores como máximo, mínimo y cierre en tiempo real está sujeta a producir cálculos que pueden no ser
repetibles en barras históricas; por lo tanto, repintar.

Veamos este sencillo script. Detecta cruces del valor de cierre (en la barra en tiempo real, esto corresponde al precio actual del instrumento) por encima y por
debajo de una EMA .

1 //@version=5 2
indicador("Repintar", "", verdadero) 3 ma = ta.ema(close,
5) 4 xUp = ta.crossover(close, ma)
5 xDn = ta.crossunder(close, ma) 6 plot(ma,
"MA", color.negro, 2) 7 bgcolor(xUp ?
color.new(color.lime, 80) : xDn ?
color.new(color.fucsia, 80): na)

Tenga en cuenta que:

• El script utiliza bgcolor() para colorear el fondo de verde cuando el cierre cruza sobre la EMA y de rojo cuando se cruza debajo.
la EMA.

• La captura de pantalla muestra el script en tiempo real en un gráfico de 30 segundos. Se ha detectado un cruce sobre la EMA, por lo que
el fondo de la barra de tiempo real es verde.

• El problema aquí es que nada garantiza que esta condición se mantendrá hasta el final de la barra de tiempo real. La flecha apunta al cronómetro y
muestra que quedan 21 segundos en la barra de tiempo real, y hasta entonces puede pasar cualquier cosa.

• Asistimos a un guión repintado.

Para evitar este repintado, debemos reescribir nuestro script para que no utilice valores que fluctúen durante la barra de tiempo real.
Esto requerirá utilizar valores de una barra que ha transcurrido (normalmente la barra anterior), o el precio de apertura , que no varía en tiempo real.

296 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Podemos lograr esto de muchas maneras. Este método agrega una condición y barstate.isconfirmed a nuestras detecciones cruzadas, lo
que requiere que el script se ejecute en la última iteración de la barra, cuando se cierra y se confirman los precios. Es una forma sencilla
de evitar repintar:

1 //@version=5 2
indicador("Repintar", "", verdadero) 3 ma = ta.ema(close,
5) 4 xUp = ta.crossover(close, ma)
y barstate.isconfirmed 5 xDn = ta. crossunder(close, ma) y barstate.isconfirmed 6 plot(ma,
"MA", color.black, 2) 7 bgcolor(xUp ? color.new(color.lime, 80) : xDn ? color.new(color.fucsia ,
80): no)

Esto utiliza los cruces detectados en la barra anterior:

1 //@version=5 2
indicador("Repintar", "", verdadero) 3 ma = ta.ema(close,
5) 4 xUp = ta.crossover(close, ma)
[1] 5 xDn = ta.crossunder (cerrar, ma)[1] 6 plot(ma,
"MA", color.negro, 2) 7 bgcolor(xUp ? color.new(color.lime,
80) : xDn ? color.new(color.fucsia, 80 ) : n / A)

Esto utiliza solo valores de cierre confirmados y EMA para sus cálculos:

1 //@versión=5 2
indicador("Repintar", "", verdadero) 3 ma =
ta.ema(close[1], 5) 4 xUp =
ta.crossover(close[1], ma) 5 xDn =
ta.crossunder(close[1], ma) 6 plot(ma, "MA", color.black,
2) 7 bgcolor(xUp ? color.new(color.lime, 80) :
xDn ? color.new(color. fucsia, 80) : na)

Esto detecta cruces entre la apertura de la barra en tiempo real y el valor de la EMA de las barras anteriores. Observe que la EMA se
calcula usando close, por lo que se repinta. Debemos asegurarnos de usar un valor confirmado para detectar cruces, por lo tanto ma[1] en
la lógica de detección de cruces:

1 //@version=5 2
indicador("Repintar", "", verdadero) 3 ma = ta.ema(close,
5) 4 xUp = ta.crossover(open, ma[1])
5 xDn = ta.crossunder (abierto, ma[1]) 6 plot(ma,
"MA", color.negro, 2) 7 bgcolor(xUp ?
color.new(color.lima, 80) : xDn ?
color.new(color.fucsia, 80 ) : n / A)

Tenga en cuenta que todos estos métodos tienen una cosa en común: si bien evitan el repintado, también activarán señales más tarde
que el repintado de los scripts. Este es un compromiso inevitable si se quiere evitar repintar. Simplemente no puedes quedarte con tu
pastel y comértelo también.

4.15. Repintar 297


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Repintar llamadas `request.security()`

Los datos obtenidos con request.security() diferirán en las barras históricas y en tiempo real si la función no se usa de la manera correcta.
Repintar las llamadas a request.security() producirá datos históricos y gráficos que no se pueden replicar en tiempo real.
Veamos un script que muestra la diferencia entre llamadas request.security() repintadas y sin repintar:

1 //@version=5 2
indicador("Repintar vs no repintar `request.security()`", "", true) 3 var BLACK_MEDIUM = color.new(color.black, 50) 4 var ORANGE_LIGHT
= color. nuevo(color.naranja, 80)

6 tfInput = entrada.plazo("1")
7

8 repintarClose = request.security(syminfo.tickerid, tfInput, cerrar) 9 plot(repintarClose, "Repintar cerrar", BLACK_MEDIUM, 8)

10

11 indexHighTF = barstate.isrealtime? 1: 0 12 indexCurrTF = barstate.isrealtime?


0: 1
13 noRepintarClose = request.security(syminfo.tickerid, tfInput,
→cerrar[índiceAltoTF])[índiceCurrTF]
14 trama(nonRepaintingClose, "Cerrar sin repintar", color.fucsia, 3)
15

16 if ta.change(time(tfInput)) label.new(bar_index, na,


17 " ", yloc = yloc.abovebar, style = label.style_none,
→textcolor = color.negro, tamaño = tamaño.grande) 18
bgcolor(barstate.isrealtime ? ORANGE_LIGHT : na)

Así es como se ve su resultado en un gráfico de 5 segundos que ha estado ejecutando el script durante unos minutos:

Tenga en cuenta que:

• El fondo naranja identifica la barra de tiempo real y las barras de tiempo real transcurrido.

• Una flecha curva negra indica cuándo llega un nuevo período de tiempo más alto.

• La línea gris gruesa muestra la llamada de repintado request.security() utilizada para inicializar repaintingClose.

• La línea fucsia muestra la llamada request.security() sin repintado utilizada para inicializar nonRepaintingClose.

298 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• El comportamiento de la línea de repintado es completamente diferente en barras históricas y en tiempo real. En barras históricas, muestra el
nuevo valor de un período de tiempo completo al cierre de la barra donde se completa. Luego permanece estable hasta que se complete otro
período de tiempo. El problema es que en tiempo real sigue el precio de cierre actual , por lo que se mueve todo el tiempo y cambia en cada
barra.

• El comportamiento de la línea fucsia que no se repinta, por el contrario, se comporta exactamente igual en las barras históricas y en tiempo real.
Se actualiza en la barra después de completar el período de tiempo superior y no se mueve hasta que se completa la barra después de que
se completa otro período de tiempo superior. Es más confiable y no engaña a los usuarios del script. Tenga en cuenta que, si bien los nuevos
datos de períodos de tiempo más altos llegan al cierre de las barras históricas, estarán disponibles al abrir la misma barra en tiempo real.

Este script muestra una función nonRepaintingSecurity() que se puede usar para hacer lo mismo que nuestro código sin repintado en el ejemplo
anterior:

1 //@version=5 2
indicador("No repintar `nonRepaintingSecurity()`", "", verdadero)
3

4 tfInput = entrada.plazo("1")
5

6 seguridad sin repintado (sym, tf, src) =>


7 request.security(sym, tf, src[barstate.isrealtime? 1: 0])[barstate.isrealtime ? →0: 1]

9 nonRepaintingClose = nonRepaintingSecurity(syminfo.tickerid, "1", cerrar) 10 plot(nonRepaintingClose, "Cierre sin repintar", color.fuchsia, 3)

Otra forma de producir datos de períodos de tiempo más altos que no se vuelven a pintar es esta, que utiliza un desplazamiento de [1] en la serie y
mira hacia adelante:

nonRepaintingSecurityAlternate(sym, tf, src) =>


request.security(sym, tf, src[1], lookahead = barmerge.lookahead_on)

Producirá el mismo comportamiento de no repintar que nonRepaintingSecurity(). Tenga en cuenta que el desplazamiento [1] de la serie y el uso de
lookahead = barmerge.lookahead_on son interdependientes. No se puede eliminar uno sin comprometer la funcionalidad de la función. También tenga
en cuenta que se esperan variaciones ocasionales de una barra entre el momento en que los valores nonRepaintingSecurity() y
nonRepaintingSecurityAlternate() aparecen en las barras históricas.

Usando `request.security()` en plazos más bajos

Algunas secuencias de comandos utilizan request.security() para solicitar datos de un período de tiempo inferior al del gráfico. Esto puede resultar útil
cuando las funciones diseñadas específicamente para manejar intrabars en períodos de tiempo más bajos se envían a lo largo del período. Cuando
este tipo de función definida por el usuario requiere la detección de la primera barra de intrabarras, como lo hace la mayoría, la técnica solo funcionará
en barras históricas. Esto se debe al hecho de que las intrabarras en tiempo real aún no están ordenadas. El impacto de esto es que dichos scripts no
pueden reproducir en tiempo real su comportamiento en barras históricas. Cualquier lógica que genere alertas, por ejemplo, será defectuosa y será
necesaria una actualización constante para volver a calcular las barras transcurridas en tiempo real como barras históricas.

Cuando se usa en períodos de tiempo más bajos que los del gráfico sin funciones especializadas capaces de distinguir entre intrabarras, re­
quest.security() solo devolverá el valor de la última intrabarra en la dilatación de la barra del gráfico, lo cual generalmente no es útil, y también No se
reproduce en tiempo real, por lo que lleva a repintar.

Por todas estas razones, a menos que comprenda las sutilezas del uso de request.security() en períodos de tiempo más bajos que los del gráfico, es
mejor evitar usar la función en esos períodos de tiempo. Los scripts de mayor calidad tendrán una lógica para detectar tales anomalías y evitar la
visualización de resultados que no serían válidos si se utilizara un período de tiempo más bajo.

4.15. Repintar 299


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Fuga futura con `request.security()`

Cuando se usa request.security() con lookahead = barmerge.lookahead_on para obtener precios sin compensar la serie en [1], devolverá
datos del futuro en barras históricas, lo cual es peligrosamente engañoso.

Si bien las barras históricas mostrarán mágicamente los precios futuros antes de que se conozcan, no es posible realizar una anticipación en tiempo
real porque el futuro es desconocido, como debería, por lo que no existen barras futuras.

Esto es un ejemplo:

1 // ¡FUTURA FUTURA! ¡NO UTILICE! 2 //


@versión=5 3
indicador("Fuga futura", "", verdadero) 4 futuroAlto =
request.security(syminfo.tickerid, "D", alto, anticipación = barmerge.
→lookahead_on) 5
trama (futuroAlto)

Observe cómo la línea del período de tiempo superior muestra el valor alto del período de tiempo antes de que ocurra. La solución es usar
la función como lo hacemos en nuestro nonRepaintingSecurity() mostrado anteriormente.

Se moderarán los guiones públicos que utilicen esta técnica engañosa.

`varip`

Los scripts que utilizan el modo de declaración varip para variables (consulte nuestra sección sobre varip para obtener más información)
guardan información en actualizaciones en tiempo real, que no se pueden reproducir en barras históricas donde solo está disponible
información OHLC. Dichos scripts pueden ser útiles en tiempo real, incluso para generar alertas, pero su lógica no se puede probar, ni sus
gráficos en barras históricas pueden reflejar cálculos que se realizarán en tiempo real.

300 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Incorporaciones de estado de barra

Los scripts que utilizan estados de barra pueden volver a pintarse o no. Como hemos visto en la sección anterior, usar barstate.isconfirmed es en realidad
una forma de evitar repintar que se reproducirá en barras históricas, que siempre están "confirmadas". Sin embargo , el uso de otros estados de barra,
como barstate.isnew, dará lugar a que se vuelva a pintar. La razón es que en las barras históricas, barstate.isnew es verdadero en el cierre de la barra ,
pero en tiempo real, es verdadero en la apertura de la barra. El uso de otras variables de estado de la barra generalmente causará algún tipo de
discrepancia de comportamiento entre las barras históricas y en tiempo real.

`tiempo ahora`

El timenow incorporado devuelve la hora actual. Los scripts que utilizan esta variable no pueden mostrar un comportamiento histórico y en tiempo real
consistente, por lo que necesariamente se repintan.

Estrategias

Las estrategias que usan calc_on_every_tick = true se ejecutan en cada actualización en tiempo real, mientras que las estrategias se ejecutan al cierre de
las barras históricas. Lo más probable es que no generen las mismas ejecuciones de órdenes y, por lo tanto, vuelvan a pintar. Tenga en cuenta que
cuando esto sucede, también invalida los resultados del backtesting, ya que no son representativos del comportamiento de la estrategia en tiempo real.

4.15.3 Trazar en el pasado


Los scripts que detectan pivotes después de que hayan transcurrido 5 barras a menudo se remontan al pasado para trazar niveles o valores de pivote en
el pivote real, 5 barras en el pasado. Esto a menudo hará que los operadores desprevenidos que miran gráficos en barras históricas infieran que cuando
el pivote ocurre en tiempo real, los mismos gráficos aparecerán en el pivote cuando ocurra, a diferencia de cuando se detecte.

Veamos un script que muestra el precio de los pivotes altos colocando el precio en el pasado, 5 barras después de que se detectó el pivote:

1 //@versión=5 2
indicador("Trazando en el pasado", "", verdadero) 3 pHi = ta.pivothigh(5, 5) 4 si no
na(pHi)

5 label.new(bar_index[5], na, str.tostring(pHi, format.mintick) + "\n", yloc =


→yloc.abovebar, estilo = etiqueta.style_none, textcolor = color.negro, tamaño = tamaño. →normal)

Tenga en cuenta que:

4.15. Repintar 301


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Este script se vuelve a pintar porque a una barra en tiempo real transcurrido que no muestra ningún precio se le puede asignar un precio si se identifica.
como pivote, 5 barras después de que se produzca el pivote real.

• La pantalla se ve muy bien, pero puede resultar engañosa.

La mejor solución a este problema cuando se desarrolla un script para otros es trazar sin un desplazamiento de forma predeterminada, pero dar la opción a los
usuarios del script de activar el trazado en el pasado a través de entradas, de modo que necesariamente estén al tanto de lo que está haciendo el script, por
ejemplo. :

1 //@version=5 2
indicador("Trama en el pasado", "", verdadero) 3 plotInThePast = input(false, "Trama en
el pasado") 4 pHi = ta.pivothigh(5, 5) 5 si no na(pHi)

6 label.new(bar_index[plotInThePast? 5: 0], na, str.tostring(pHi, format.mintick)


→+ "\n", yloc = yloc.abovebar, estilo = etiqueta.style_none, textcolor = color.negro, →tamaño = tamaño.normal)

4.15.4 Variaciones del conjunto de datos

Puntos de partida

Los scripts comienzan a ejecutarse en la primera barra histórica del gráfico y luego se ejecutan en cada barra de forma secuencial, como se explica en la página
de este manual sobre el modelo de ejecución de Pine Script™. Si la primera barra cambia, entonces el script a menudo no calculará de la misma manera que lo
hizo cuando el conjunto de datos comenzó en un momento diferente.

Los siguientes factores influyen en la cantidad de barras que ve en sus gráficos y en su punto de partida:

• El tipo de cuenta que tiene

• Los datos históricos disponibles del proveedor de datos.

• Los requisitos de alineación del conjunto de datos, que determinan su punto de partida.

Estos son los límites de barra específicos de la cuenta:

• 20000 barras históricas para el plan Premium.

• 10000 barras históricas para planes Pro y Pro+.

• 5000 bares históricos para otros planes.

Los puntos de partida se determinan utilizando las siguientes reglas, que dependen del período de tiempo del gráfico:

• 1, 5, 10, 15, 30 segundos: se alinea con el comienzo de un día.

• 1 ­ 14 minutos: se alinea con el comienzo de una semana.

• 15 ­ 29 minutos: se alinea con el comienzo de un mes.

• 30 ­ 1439 minutos: se alinea con el comienzo de un año.

• 1440 minutos y más: se alinea con el primer punto de datos históricos disponible.

A medida que pasa el tiempo, estos factores hacen que el historial de su gráfico comience en diferentes momentos. Esto a menudo tiene un impacto en los
cálculos de sus scripts, porque los cambios en los resultados de los cálculos en las primeras barras pueden afectar a todas las demás barras del conjunto de
datos. El uso de funciones como ta.valuewhen(), ta.barssince() o ta.ema(), por ejemplo, producirá resultados que varían según la historia temprana.

302 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Revisión de datos históricos.

Las barras históricas y en tiempo real se crean utilizando dos fuentes de datos diferentes proporcionadas por las bolsas/corredores: datos históricos y
datos en tiempo real. Cuando transcurren las barras en tiempo real, las bolsas/corredores a veces realizan lo que normalmente son pequeños ajustes a los
precios de las barras, que luego se escriben en sus datos históricos. Cuando se actualiza el gráfico o se vuelve a ejecutar el script en esas barras
transcurridas en tiempo real, se crearán y calcularán utilizando los datos históricos, que contendrán esas revisiones de precios generalmente pequeñas, si
se han realizado.

Los datos históricos también pueden revisarse por otros motivos, por ejemplo, para divisiones de acciones.

4.16 Sesiones

• Introducción

• Cadenas de sesión

• Estados de sesión

• Usando sesiones con `request.security()`

4.16.1 Introducción

La información de la sesión se puede utilizar de tres maneras diferentes en Pine Script™:

1. Cadenas de sesión que contienen horas de inicio hasta información del día que se pueden usar en funciones como time() y time_close() para
detectar cuándo las barras están en un período de tiempo particular, con la opción de limitar sesiones válidas a días específicos. La función
input.session() proporciona una manera de permitir a los usuarios de scripts definir valores de sesión a través de la pestaña "Entradas" de un script
(consulte la sección Entrada de sesión para obtener más información).

2. Las variables integradas de los estados de sesión , como session.ismarket, pueden identificar a qué sesión pertenece una barra.

3. Al recuperar datos con request.security() , también puede optar por devolver datos solo de sesiones regulares o de sesiones extendidas . En este
caso, la definición de sesiones ordinarias y ampliadas es la del intercambio. Es parte de las propiedades del instrumento, no está definido por el
usuario, como en el punto 1. Esta noción de sesiones regulares y extendidas es la misma que se utiliza en la interfaz del gráfico, en el campo
“Configuración del gráfico/Símbolo/Sesión”, por ejemplo.

Las siguientes secciones cubren ambos métodos de uso de la información de sesión en Pine Script™.

Tenga en cuenta que:

• No todas las cuentas de usuario de TradingView tienen acceso a información ampliada de la sesión.

• No hay ningún tipo de “sesión” especial en Pine Script™. En cambio, las cadenas de sesión son del tipo "cadena" pero deben ajustarse a la sintaxis
de la cadena de sesión.

4.16. Sesiones 303


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.16.2 Cadenas de sesión

Especificaciones de cadena de sesión

Las cadenas de sesión utilizadas con time() y time_close() deben tener un formato específico. Su sintaxis es:

<período_tiempo>:<días>

Dónde:

• <time_period> utiliza horas en formato “hhmm”, con “hh” en formato de 24 horas, por lo que 1700 son las 5 p.m. Los períodos de
tiempo están en el formato “hhmm­hhmm” y una coma puede separar varios períodos de tiempo para especificar combinaciones de
períodos discretos.

Por ejemplo, ­ <días> es un conjunto de dígitos del 1 al 7 que especifica en qué días la sesión es válida. 1 es domingo, 7
es sábado.

Nota: Los días predeterminados son: 1234567, que es diferente en Pine Script™ v5 que en versiones anteriores donde se usa 23456 (días
laborables). Para que el código v5 reproduzca el comportamiento de versiones anteriores, debe mencionar explícitamente los días
laborables, como en "0930­1700:23456".

Estos son ejemplos de cadenas de sesión:

"24x7"
Una sesión de 7 días y 24 horas que comienza a medianoche.

"0000­0000:1234567"
Equivalente al ejemplo anterior.

"0000­0000"
Equivalente a los dos ejemplos anteriores porque los días predeterminados son 1234567.

"0000­0000:23456"
Igual que el ejemplo anterior, pero sólo de lunes a viernes.

"2000­1630:1234567"
Una sesión nocturna que comienza a las 20:00 horas y finaliza a las 16:30 horas del día siguiente. Es válido todos los días de la semana.

"09.30­17.00:146"
Una sesión que comienza a las 9:30 y finaliza a las 17:00 los domingos (1), miércoles (4) y viernes (6).

"1700­1700:23456"
Una sesión nocturna. La sesión del lunes comienza el domingo a las 17:00 y finaliza el lunes a las 17:00. Es válido de lunes a
viernes.

"1000­1001:26"
Una sesión rara que dura sólo un minuto los lunes (2) y viernes (6).

"0900­1600,1700­2000"
Una sesión que comienza a las 9:00, tiene un descanso de 16:00 a 17:00 y continúa hasta las 20:00. Aplica para todos los días de la
semana.

304 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Usando cadenas de sesión

Las propiedades de sesión definidas con cadenas de sesión son independientes de las sesiones definidas por el intercambio que determinan
cuándo se puede negociar un instrumento. Los programadores tienen total libertad para crear cualquier definición de sesión que se adapte a su
propósito, que suele ser detectar cuándo las barras pertenecen a períodos de tiempo específicos. Esto se logra en Pine Script™ utilizando una
de las dos firmas siguientes de la función time() :

tiempo (plazo, sesión, zona horaria) → serie int tiempo (plazo, sesión) →
serie int

Aquí usamos time() con un argumento de sesión para mostrar los valores máximos y mínimos de apertura del mercado en un gráfico intradiario:

1 //@versión=5 2
indicador("Apertura alta/baja", superposición = verdadero)
3

4 entrada de sesión = entrada.sesión ("0930­0935")


5

6 sessionBegins(sess) => t = time("",


7 sess) timeframe.isintraday y
8 (no barstate.isfirst) y na(t[1]) y no na(t)
9

10 var flotador alto = na


11 var flotante lo = na
12 si la sesión comienza (entrada de sesión) hola: =
13 alta baja: = baja
14

15

16 plot(lo, "lo", color.fucsia, 2, plot.style_circles) 17 plot(hola, "hola", color.lime, 2,


plot.style_circles)

Tenga en cuenta que:

• Usamos una entrada de sesión para permitir a los usuarios especificar el tiempo que desean detectar. Solo buscamos la hora de inicio de
la sesión en barras, por lo que utilizamos un espacio de cinco minutos entre la hora de inicio y finalización de nuestro valor predeterminado
"0930­0935".

• Creamos una función sessionBegins() para detectar el inicio de una sesión. Su llamada time("", sess) usa una cadena vacía para el
parámetro de marco temporal de la función, lo que significa que usa el marco temporal del gráfico, sea cual sea. La función devuelve
verdadero cuando:

– El gráfico utiliza un marco de tiempo intradiario (segundos o minutos).

– El script no está en la primera barra del gráfico, lo cual aseguramos con (no con barstate.isfirst). este cheque

4.16. Sesiones 305


Machine Translated by Google

Manual del usuario de Pine Script™ v5

evita que el código siempre detecte una sesión que comienza en la primera barra porque na(t[1]) y no na(t) siempre es verdadero allí.

– La llamada time() devolvió na en la barra anterior porque no estaba en el período de tiempo de la sesión y devolvió un valor que no es na en la
barra actual, lo que significa que la barra está en el período de tiempo de la sesión.

4.16.3 Estados de sesión

Tres variables integradas le permiten distinguir el tipo de sesión a la que pertenece la barra actual. Sólo son útiles en plazos intradiarios:

• session.ismarket devuelve verdadero cuando la barra pertenece al horario comercial habitual.

• session.ispremarket devuelve verdadero cuando la barra pertenece a la sesión extendida anterior al horario comercial habitual.

• session.ispostmarket devuelve verdadero cuando la barra pertenece a la sesión extendida después del horario comercial habitual.

4.16.4 Usando sesiones con `request.security()`

Cuando su cuenta de TradingView brinda acceso a sesiones extendidas, puede elegir ver sus barras con el campo "Configuración/Símbolo/Sesión". Hay dos
tipos de sesiones:

• regular (que no incluye datos previos y posteriores a la comercialización), y

• ampliado (que incluye datos previos y posteriores a la comercialización).

Los scripts que utilizan la función request.security() para acceder a los datos pueden devolver datos de sesión extendidos o no. Este es un ejemplo en el que
solo se obtienen datos de la sesión normal:

1 //@versión=5
2 indicador("Ejemplo 1: Datos de sesión regular") 3 regularSessionData =
request.security("NASDAQ:AAPL", timeframe.period, close,
→barmerge.gaps_on)
4 trama (regularSessionData, estilo = trama.style_linebr)

Si desea que la llamada request.security() devuelva datos de sesión extendida, primero debe usar la función ticker.new() para crear el primer argumento de la
llamada request.security() :

306 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5 2
indicador("Ejemplo 2: Datos de sesión extendida") 3 t =
ticker.new("NASDAQ", "AAPL", sesión.extendida) 4 extendSessionData =
request.security(t, timeframe.period , cerrar, barmerge.gaps_on) 5 plot(extendedSessionData, estilo = plot.style_linebr)

Tenga en cuenta que los vacíos del gráfico anterior en la trama del guión ahora están llenos. Además, tenga en cuenta que nuestros scripts de
ejemplo no producen el color de fondo del gráfico; se debe a que la configuración del gráfico muestra horarios extendidos.

La función ticker.new() tiene la siguiente firma:

ticker.new(prefijo, ticker, sesión, ajuste) → cadena simple

Dónde:

• prefijo es el prefijo del intercambio, por ejemplo, "NASDAQ"

• el ticker es el nombre de un símbolo, por ejemplo, "AAPL"

• la sesión puede ser sesión.extendida o sesión.regular. Tenga en cuenta que esta no es una cadena de sesión.

• ajuste ajusta los precios utilizando diferentes criterios: ajuste.ninguno, ajuste.divisiones,


ajuste.dividendos.

Nuestro primer ejemplo podría reescribirse como:

1 //@versión=5 2
indicador("Ejemplo 1: Datos de sesión regular") 3 t = ticker.new("NASDAQ",
"AAPL", session.regular) 4 regularSessionData = request.security(t,
timeframe.period , cerrar, barmerge.gaps_on) 5 plot(regularSessionData, style = plot.style_linebr)

Si desea utilizar las mismas especificaciones de sesión utilizadas para el símbolo principal del gráfico, omita el tercer argumento en
ticker.new(); es opcional. Si desea que su código declare explícitamente su intención, utilice la variable incorporada syminfo.session .
Contiene el tipo de sesión del símbolo principal del gráfico:

1 //@versión=5 2
indicador("Ejemplo 1: Datos de sesión regular") 3 t = ticker.new("NASDAQ",
"AAPL", syminfo.session) 4 regularSessionData = request.security(t,
timeframe.period , cerrar, barmerge.gaps_on) 5 plot(regularSessionData, style = plot.style_linebr)

4.16. Sesiones 307


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.17 Estrategias

• Introducción

• Un ejemplo de estrategia simple

• Aplicar una estrategia a un gráfico

• Probador de estrategias

• Emulador de corredor

• Pedidos y entradas

• Dimensionamiento de la posición

• Cerrar una posición en el mercado

• Grupos OCA

• Divisa

• Alterar el comportamiento de cálculo

• Simulación de costos comerciales

• Gestión de riesgos

• Margen

• Alertas de estrategia

• Notas sobre estrategias de prueba

4.17.1 Introducción
Las estrategias de Pine Script™ simulan la ejecución de operaciones con datos históricos y en tiempo real para facilitar las pruebas retrospectivas y futuras de los
sistemas comerciales. Incluyen muchas de las mismas capacidades que los indicadores Pine Script™ y al mismo tiempo brindan la capacidad de realizar, modificar
y cancelar pedidos hipotéticos y analizar los resultados.

Cuando un script utiliza la función estrategia() para su declaración, obtiene acceso al espacio de nombres estrategia.*, donde puede llamar funciones y variables para
simular órdenes y acceder a información estratégica esencial. Además, el script mostrará información y resultados simulados externamente en la pestaña "Probador
de estrategias".

308 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

4.17.2 Un ejemplo de estrategia simple

El siguiente script es una estrategia simple que simula la entrada de posiciones largas o cortas al cruzar dos medias móviles:

1 //@versión=5 2
estrategia("prueba", superposición = verdadero)
3

4 // Calcula dos medias móviles con diferentes longitudes. 5 flotar rápidoMA = ta.sma(cerrar, 14) 6 flotar lentoMA
= ta.sma(cerrar, 28)

8 // Ingrese una posición larga cuando `fastMA` cruce a `slowMA`. 9 si ta.crossover(fastMA, slowMA)
estrategia.entrada("comprar", estrategia.long)
10

11

12 // Ingrese una posición corta cuando `fastMA` cruce por debajo de `slowMA`. 13 si ta.crossunder(fastMA, slowMA)
estrategia.entrada("vender", estrategia.short)
14

15

16 // Traza las medias móviles. 17 trazado(fastMA, "Fast


MA", color.aqua) 18 trazado(slowMA, "Slow MA", color.orange)

Tenga en cuenta que:

• La línea de estrategia("test" overlay = true) declara que el script es una estrategia denominada "prueba" con resultados visuales
superpuestos en el panel del gráfico principal.

• estrategia.entry() es el comando que utiliza el script para simular órdenes de “compra” y “venta”. cuando el guión
realiza un pedido, también traza la identificación del pedido en el gráfico y una flecha para indicar la dirección.

• Dos funciones plot() trazan las medias móviles con dos colores diferentes como referencia visual.

4.17.3 Aplicar una estrategia a un gráfico

Para probar una estrategia, aplíquela al gráfico. Puede utilizar una estrategia integrada desde el cuadro de diálogo "Indicadores y estrategias" o escribir
la suya propia en el Editor Pine. Haga clic en "Agregar al gráfico" en la pestaña "Editor Pine" para aplicar una secuencia de comandos al gráfico:

Después de compilar y aplicar un script de estrategia a un gráfico, trazará marcas de orden en el panel principal del gráfico y mostrará resultados de
rendimiento simulados en la pestaña "Probador de estrategias" a continuación:

4.17. Estrategias 309


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Nota: Los resultados de una estrategia aplicada a gráficos no estándar (Heikin Ashi, Renko, Line Break, Kagi, Point & Figure y Range) no reflejan
las condiciones reales del mercado de forma predeterminada. Los guiones de estrategia utilizarán los valores de precios sintéticos de estos gráficos
durante la simulación, que a menudo no se alinean con los precios reales del mercado y, por lo tanto, producirán resultados de backtest poco
realistas. Por lo tanto, recomendamos encarecidamente utilizar tipos de gráficos estándar para las estrategias de backtesting. Alternativamente, en
los gráficos Heikin Ashi, los usuarios pueden simular órdenes usando precios reales habilitando la opción "Completar órdenes usando OHLC
estándar" en las propiedades de la Estrategia.

4.17.4 Probador de estrategias

El módulo Strategy Tester está disponible para todos los scripts declarados con la función Strategy() . Los usuarios pueden acceder a este módulo
desde la pestaña "Probador de estrategias" debajo de sus gráficos, donde pueden visualizar cómodamente sus estrategias y analizar resultados de
rendimiento hipotéticos.

310 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Descripción general

La pestaña Descripción general del Probador de estrategias presenta métricas de rendimiento esenciales y curvas de equidad y reducción sobre una secuencia
simulada de operaciones, lo que proporciona una visión rápida del rendimiento de la estrategia sin profundizar en detalles granulares. El gráfico de esta
sección muestra la curva de acciones de la estrategia como un gráfico de referencia centrado en el valor inicial, la curva de compra y retención de acciones
como un gráfico de líneas y la curva de reducción como un gráfico de histograma. Los usuarios pueden alternar estos gráficos y escalarlos como valores
absolutos o porcentajes usando las opciones debajo del gráfico.

Tenga en cuenta que:

• El cuadro general utiliza dos escalas; la izquierda es para las curvas de acciones y la derecha es para la curva de reducción.

• Cuando un usuario hace clic en un punto de estos gráficos, esto dirigirá la vista del gráfico principal al punto donde se realizó la operación.
cerrado.

Resumen de Desempeño

La pestaña Resumen de desempeño del módulo presenta una descripción general completa de las métricas de desempeño de una estrategia. Muestra tres
columnas: una para todas las operaciones, una para todas las posiciones largas y otra para todas las posiciones cortas, para proporcionar a los operadores
información más detallada sobre el rendimiento comercial simulado general, largo y corto de una estrategia.

4.17. Estrategias 311


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Lista de oficios

La pestaña Lista de operaciones proporciona una visión granular de las operaciones simuladas por una estrategia con información esencial,
incluida la fecha y hora de ejecución, el tipo de orden utilizada (entrada o salida), la cantidad de contratos/acciones/lotes/unidades negociadas.
y el precio, así como algunas métricas clave de desempeño comercial.

Tenga en cuenta que:

312 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

• Los usuarios pueden navegar por los tiempos de operaciones específicas en sus gráficos haciendo clic en ellas en esta lista.

• Al hacer clic en el campo “Trade #” encima de la lista, los usuarios pueden organizar las operaciones en orden ascendente comenzando desde el
primero o en orden descendente comenzando desde el último.

Propiedades

La pestaña Propiedades proporciona información detallada sobre la configuración de una estrategia y el conjunto de datos al que se aplica. Incluye el rango de
fechas de la estrategia, información de símbolos, configuración del script y propiedades de la estrategia.

• Rango de fechas : incluye el rango de fechas con operaciones simuladas y el rango total de backtesting disponible.

• Información del símbolo : contiene el nombre del símbolo y el corredor/bolsa, el período y el tipo del gráfico, el tamaño del tick, el
valor en puntos para el gráfico y la moneda base.

• Entradas de estrategia : describe los diversos parámetros y variables utilizados en el script de estrategia disponible en las "Entradas".
pestaña de la configuración del script.

• Propiedades de la estrategia : proporciona una descripción general de la configuración de la estrategia comercial. Incluye detalles esenciales como el
capital inicial, la moneda base, el tamaño del pedido, el margen, la pirámide, la comisión y el deslizamiento. Además, esta sección destaca cualquier
modificación realizada en el comportamiento de cálculo de estrategias.

4.17.5 Emulador de corredor

TradingView utiliza un emulador de corredor para simular el desempeño de las estrategias comerciales. A diferencia del comercio en la vida real, el emulador
utiliza estrictamente los precios de los gráficos disponibles para la simulación de órdenes. En consecuencia, la simulación sólo puede realizar operaciones
históricas después del cierre de una barra, y sólo puede realizar operaciones en tiempo real en un nuevo tick de precio. Para obtener más información sobre
este comportamiento, consulte el modelo de ejecución de Pine Script™.

Dado que el emulador sólo puede utilizar datos del gráfico, hace suposiciones sobre el movimiento del precio dentro de la barra. Utiliza los precios de apertura,
máximo y mínimo de una barra para inferir la actividad intrabar mientras calcula el cumplimiento de órdenes con la siguiente lógica:

• Si el precio máximo está más cerca del precio de apertura que del precio mínimo, se supone que el precio se movió en este orden en la barra: apertura
→ máximo → mínimo → cierre.

• Si el precio mínimo está más cerca del precio de apertura que del precio máximo, se supone que el precio se movió en este orden en la barra: apertura
→ mínimo → máximo → cierre.

• El emulador del corredor supone que no existen brechas entre los precios dentro de las barras; en los “ojos” del emulador, toda la gama
de precios intrabar está disponible para la ejecución de órdenes.

4.17. Estrategias 313


Machine Translated by Google

Manual del usuario de Pine Script™ v5

lupa de barra

Los titulares de cuentas Premium pueden anular las suposiciones intrabar del emulador de broker a través del parámetro use_bar_magnifier
de la función Strategy() o la entrada "Usar lupa de barra" en la pestaña "Propiedades" de la configuración del script. Bar Magnifier inspecciona
datos en períodos de tiempo más pequeños que los del gráfico para obtener información más granular sobre la acción del precio dentro de
una barra, permitiendo así ejecutar órdenes más precisas durante la simulación.

Para demostrarlo, el siguiente script coloca una orden límite de "Compra" en el Precio de entrada y una orden límite de "Salida" en el Precio
de salida cuando el valor del tiempo cruza el Tiempo del pedido, y dibuja dos líneas horizontales para visualizar los precios de la orden.
El script también resalta el fondo usando orderColor para indicar cuándo la estrategia realizó las órdenes:

1 //@versión=5 2
estrategia("Demostración de lupa de barra", superposición = verdadero, use_bar_magnifier = falso)
3

4 //@variable La marca de tiempo UNIX para realizar el pedido. 5 int ordenHora = marca de
tiempo("UTC", 2023, 3, 22, 18)
(continúa en la página siguiente)

314 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

7 //@variable Devuelve `color.orange` cuando `time` cruza `orderTime`, false


→de lo contrario.
Orden de 8 coloresColor = na
9

10 // Precios de entrada y salida.


11 entrada flotantePrecio = hl2 ­ (alto ­ bajo)
12 precio de salida flotante = precio de entrada + (alto ­ bajo) * 0,25
13

14 // Líneas de entrada y salida.


15 var línea entradaLínea = na
16 var línea exitLine = na
17

18 si ta.cross(hora,ordenHora)
19 // Dibujar nuevas líneas de entrada y salida.
20 líneadeentrada := línea.nueva(índice_barra,Precio_entrada, índice_barra + 1,Precio_entrada, color =
→color.verde, ancho = 2)
21 línea de salida := línea.nueva(índice_barra, Precio_salida, índice_barra + 1, Precio_salida, color =
→color.rojo, ancho = 2)
22

23 // Actualizar el color de resaltado del pedido.


24 orderColor := color.nuevo(color.naranja, 80)
25

26 // Colocar órdenes limitadas en `entryPrice` y `exitPrice`.


27 estrategia.entrada("Comprar", estrategia.long, límite = entradaPrecio)
28 estrategia.exit("Salir", "Comprar", límite = precio de salida)
29

30 // Actualizar líneas mientras la posición esté abierta.


31 más si estrategia.position_size > 0.0
32 entradaLine.set_x2(bar_index + 1)
33 exitLine.set_x2(índice_barra + 1)
34

35 bgcolor(orderColor)

Como vemos en el gráfico anterior, el emulador del corredor asumió que los precios intrabar se movieron de abierto a alto, luego de alto a
bajo, luego bajo para cerrar en la barra que se completó la orden de "Compra", lo que significa que el emulador asumió que la orden de "Salida" no podía
rellenar la misma barra. Sin embargo, después de incluir use_bar_magnifier = true en la declaración, vemos
una historia diferente:

4.17. Estrategias 315


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Nota: La cantidad máxima de intrabars que puede solicitar un script es 100.000. Es posible que algunos símbolos con un historial más largo no tengan
una cobertura intrabar completa para las barras iniciales del gráfico con esta limitación, lo que significa que las operaciones simuladas en esas barras
no se verán afectadas por la lupa de barras.

4.17.6 Órdenes y entradas

Al igual que en el trading de la vida real, las estrategias de Pine utilizan órdenes para gestionar las posiciones. En este contexto, una orden es un comando para
simular una acción del mercado y una operación es el resultado después de que se ejecuta la orden. Por lo tanto, para ingresar o salir de posiciones usando Pine,
los usuarios deben crear órdenes con parámetros que especifiquen cómo se comportarán.

Para ver más de cerca cómo funcionan las órdenes y cómo se convierten en operaciones, escribamos un guión de estrategia simple:

1 //@versión=5 2 estrategia("Mi

estrategia", superposición = verdadero, margen_largo = 100, margen_corto = 100)


3

4 //@función Muestra el texto pasado a `txt` cuando se llama. 5 etiqueta de depuración (txt) =>

7 etiqueta.nuevo( bar_index, alto, texto = txt, color = color.lima, estilo = etiqueta.estilo_label_


→inferior_derecha,
8 color de texto = color.negro, tamaño = tamaño.grande
9 )
10

11 longCondition = bar_index % 20 == 0 // verdadero en cada vigésima barra 12 if (longCondition)

13 debugLabel("Orden de entrada larga creada")


14 estrategia.entry("Mi ID de entrada larga", estrategia.long)
15 estrategia.close_all()

En este script, hemos definido una condición larga que es verdadera siempre que bar_index sea divisible por 20, es decir, cada vigésima barra. La
estrategia utiliza esta condición dentro de una estructura if para simular una orden de entrada con estrategia.entry() y dibuja una etiqueta al precio de
entrada con la función debugLabel() definida por el usuario. El script llama a Strategy.close_all() desde el

316 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

alcance global para simular una orden de mercado que cierra cualquier posición abierta. Veamos qué sucede una vez que agregamos el script a nuestro
gráfico:

Las flechas azules en el gráfico indican ubicaciones de entrada y las violetas marcan los puntos donde la estrategia cerró posiciones. Observe que las
etiquetas preceden al punto de entrada real en lugar de aparecer en la misma barra; esto son órdenes en acción. De forma predeterminada, las estrategias
de Pine esperan el siguiente tick de precio disponible antes de completar las órdenes, ya que completar una orden en el mismo tick no es realista. Además,
recalculan el cierre de cada barra histórica, lo que significa que el siguiente tick disponible para ejecutar una orden es la apertura de la siguiente barra en
este caso. Como resultado, de forma predeterminada, todas las órdenes se retrasan una barra del gráfico.

Es importante tener en cuenta que aunque el script llama a Strategy.close_all() desde el alcance global, forzando la ejecución en cada barra, la llamada a
la función no hace nada si la estrategia no simula una posición abierta. Si hay una posición abierta, el comando emite una orden de mercado para cerrarla,
que se ejecuta en el siguiente tick disponible. Por ejemplo, cuando la condición larga es verdadera en la barra 20, la estrategia coloca una orden de entrada
para ejecutar en el siguiente tick, que es en la apertura de la barra 21. Una vez que el script recalcula sus valores en el cierre de esa barra, la función coloca
una orden para cerrar la posición, que se ejecuta al abrir la barra 22.

Tipos de orden

Las estrategias de Pine Script™ permiten a los usuarios simular diferentes tipos de pedidos para sus necesidades particulares. Los principales tipos notables
son mercado, límite, parada y límite de parada.

Órdenes de mercado

Las órdenes de mercado son el tipo más básico de órdenes. Dirigen una estrategia para comprar o vender un valor lo antes posible, independientemente del
precio. En consecuencia, siempre se ejecutan en el siguiente tick de precio disponible. Por defecto, toda estrategia. *() funciones que generan órdenes
producen específicamente órdenes de mercado.

El siguiente script simula una orden de mercado larga cuando bar_index es divisible por 2 * CycleLength. De lo contrario, simula una orden de mercado
corta cuando bar_index es divisible por CycleLength, lo que da como resultado una estrategia que alterna operaciones largas y cortas una vez por cada barra
CycleLength:

4.17. Estrategias 317


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 estrategia ("Demostración de orden de mercado", superposición = verdadero, margen_largo = 100, margen_corto = 100)
3

4 //@variable Número de barras entre entradas largas y cortas.


5 cicloLongitud = input.int(10, "Duración del ciclo")
6

7 //@función Muestra el texto pasado a `txt` cuando se llama.


8 debugLabel(txt, lblColor) => etiqueta.new(
9 bar_index, alto, texto = txt, color = lblColor, textcolor = color.blanco,
10 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
11 )
12

13 //@variable Devuelve `true` cada barra de `2 * CycleLength`.


14 condición larga = índice_barra % (2 * longitud del ciclo) == 0
15 //@variable Devuelve `true` cada barra de `cycleLength`.
16 condición corta = bar_index % longitud del ciclo == 0
17

18 // Genera una orden de mercado larga con una etiqueta `color.green` en `longCondition`.
19 si es largoCondición
20 debugLabel("Orden de mercado larga creada", color.verde)
21 estrategia.entry("Mi ID de entrada larga", estrategia.long)
22 // De lo contrario, genere una orden de mercado corta con una etiqueta `color.red` en
→`condicióncorta`.
23 más si es cortaCondición
24 debugLabel("Orden de mercado corta creada", color.rojo)
25 estrategia.entry("Mi ID de entrada corta", estrategia.short)

318 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Limitar órdenes

Las órdenes limitadas ordenan una estrategia para ingresar a una posición a un precio específico o mejor (inferior al especificado para órdenes largas y
más alto para los cortos). Cuando el precio de mercado actual es mejor que el parámetro límite del comando de orden, la orden
se llenará sin esperar a que el precio de mercado alcance el nivel límite.

Para simular órdenes de límite en un script, pase un valor de precio a un comando de colocación de orden con un parámetro de límite. El
El siguiente ejemplo coloca una orden límite 800 ticks debajo de la barra y cierra 100 barras antes del last_bar_index:

1 //@versión=5

2 estrategia ("Demostración de orden limitada", superposición = verdadero, margen_largo = 100, margen_corto = 100)
3

4 //@función Muestra el texto pasado a `txt` y una línea horizontal en `price` cuando
→llamado.
5 debugLabel(precio, txt) =>
6 etiqueta.nueva(
7 bar_index, precio, texto = txt, color = color.verde azulado, textcolor = color.blanco,
8 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
9 )
10 línea.nueva(
11 bar_index, precio, bar_index + 1, precio, color = color.teal, extender = extender.
→correcto,
12 estilo = línea.style_dasshed
13 )
14

15 // Genera una orden de límite largo con una etiqueta y una línea de 100 barras antes de `last_bar_
→índice`.
16 si último_índice_barra ­ índice_barra == 100
17 límitePrecio = cerrar ­ syminfo.mintick * 800
18 debugLabel(limitPrice, "Orden de límite largo creada")
19 estrategia.entrada("Largo", estrategia.largo, límite = límitePrecio)

Observe cómo el script colocó la etiqueta y comenzó la línea varias barras antes de la operación. Mientras el precio se mantenga
por encima del valor límite de Precio, el pedido no se pudo completar. Una vez que el precio de mercado alcanzó el límite, la estrategia se ejecutó.
la barra intermedia comercial. Si hubiéramos establecido el precio límite en 800 ticks por encima del cierre de la barra en lugar de por debajo, la orden sería
Llénelo inmediatamente ya que el precio ya tiene un mejor valor:

4.17. Estrategias 319


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia ("Demostración de orden limitada", superposición = verdadero, margen_largo = 100, margen_corto = 100)
3

4 //@función Muestra el texto pasado a `txt` y una línea horizontal en `price` cuando
→llamado.
5 debugLabel(precio, txt) =>
6 etiqueta.nueva(
7 bar_index, precio, texto = txt, color = color.verde azulado, textcolor = color.blanco,
8 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
9 )
10 línea.nueva(
11 bar_index, precio, bar_index + 1, precio, color = color.teal, extender = extender.
→correcto,
12 estilo = línea.style_dasshed
13 )
14

15 // Genera una orden de límite largo con una etiqueta y una línea de 100 barras antes de `last_bar_
→índice`.
16 si último_índice_barra ­ índice_barra == 100
17 límitePrecio = cerrar + syminfo.mintick * 800
18 debugLabel(limitPrice, "Orden de límite largo creada")
19 estrategia.entrada("Largo", estrategia.largo, límite = límitePrecio)

Órdenes stop y stop­limit

Las órdenes stop ordenan una estrategia para simular otra orden después de que el precio alcanza el precio stop especificado o un valor peor.
(mayor que lo especificado para pedidos largos y menor para pedidos cortos). Son esencialmente lo opuesto a las órdenes limitadas. Cuando
el precio de mercado actual es peor que el parámetro de parada, la estrategia activará la orden posterior sin esperar
para que el precio actual alcance el nivel de stop. Si el comando de colocación de la orden incluye un argumento de límite, el siguiente
La orden será una orden limitada al valor especificado. De lo contrario, será una orden de mercado.

El siguiente script coloca una orden de parada 800 ticks por encima del cierre de hace 100 barras. En este ejemplo, la estrategia entró en un
posición larga cuando el precio de mercado cruzó el precio de parada algunas barras después de realizar la orden. Observe que la inicial
El precio en el momento de la orden era mejor que el pasado para detener. Una orden límite equivalente se habría ejecutado en el

320 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

siguiente barra de gráfico:

1 //@versión=5

2 estrategia ("Detener demostración de orden", superposición = verdadero, margen_largo = 100, margen_corto = 100)
3

4 //@función Muestra el texto pasado a `txt` cuando se llama y muestra el nivel de `precio` en
→el gráfico.

5 debugLabel(precio, txt) =>


6 etiqueta.nueva(
7 bar_index, alto, texto = txt, color = color.verde azulado, textcolor = color.blanco,
8 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
9 )
10 line.new(bar_index, alto, bar_index, precio, estilo = line.style_dotted, color =
→color.verde azulado)
11 línea.nueva(
12 bar_index, precio, bar_index + 1, precio, color = color.teal, extender = extender.
→correcto,
13 estilo = línea.style_dasshed
14 )
15

16 // Genera una orden stop larga con una etiqueta y líneas 100 barras antes de la última barra.
17 si último_índice_barra ­ índice_barra == 100
18 stopPrice = cerrar + syminfo.mintick * 800
19 debugLabel(stopPrice, "Orden de parada larga creada")
20 estrategia.entrada("Larga", estrategia.larga, detener = detenerPrecio)

Los comandos de colocación de órdenes que utilizan argumentos de límite y de parada producen órdenes de límite de parada. Este tipo de orden espera
para que el precio cruce el nivel stop, luego coloca una orden limitada al precio límite especificado.

Modifiquemos nuestro script anterior para simular y visualizar una orden stop­limit. En este ejemplo, utilizamos el valor bajo
desde hace 100 barras como precio límite en el comando de entrada. Este script también muestra una etiqueta y un nivel de precio para indicar
cuando la estrategia cruza el stopPrice, es decir, cuando la estrategia activa la orden límite. Observe cómo el precio de mercado
inicialmente alcanza el nivel límite, pero la estrategia no simula una operación porque el precio debe cruzar el stopPrice para
coloque la orden límite pendiente al precio límite:

4.17. Estrategias 321


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia("Demostración de orden Stop­Limit", overlay = true, margin_long = 100, margin_short =


→100)
3

4 //@función Muestra el texto pasado a `txt` cuando se llama y muestra el nivel de `precio` en
→el gráfico.

5 debugLabel(precio, txt, lblColor, lineWidth = 1) =>


6 etiqueta.nueva(
7 bar_index, alto, texto = txt, color = lblColor, textcolor = color.blanco,
8 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
9 )
10 line.new(bar_index, close, bar_index, precio, estilo = line.style_dotted, color =
→lblColor, ancho = ancho de línea)
11 línea.nueva(
12 bar_index, precio, bar_index + 1, precio, color = lblColor, extender = extender.
→correcto,
13 estilo = línea.style_dasshed, ancho = ancho de línea
14 )
15

Parada flotante 16 varPrecio = na


Límite flotante de 17 varPrecio = na
18

19 // Genera una orden stop­limit larga con una etiqueta y líneas 100 barras antes de la última
→barra.
20 si último_índice_barra ­ índice_barra == 100
21 stopPrice: = cerrar + syminfo.mintick * 800
22 Precio límite: = bajo
23 debugLabel(preciolímite, "", color.gris)
24 debugLabel(stopPrice, "Orden de límite de parada larga creada", color.verde azulado)
25 estrategia.entrada("Largo", estrategia.largo, detener = detenerPrecio, límite = limitarPrecio)
26

27 // Dibuja una línea y etiqueta una vez que la estrategia activa la orden límite.
28 si es alto >= stopPrice
29 debugLabel(limitPrice, "Orden limitada activada", color.green, 2)
30 detenerPrecio := na

322 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Comandos de colocación de pedidos

Las estrategias de Pine Script™ cuentan con varias funciones para simular la colocación de órdenes, conocidas como comandos de colocación de
órdenes. Cada comando tiene un propósito único y se comporta de manera diferente a los demás.

`estrategia.entrada()`

Este comando simula órdenes de entrada. De forma predeterminada, las estrategias colocan órdenes de mercado al llamar a esta función, pero
también pueden crear órdenes stop, limit y stop­limit cuando utilizan los parámetros stop y limit.

Para simplificar las posiciones de apertura, Strategy.entry() presenta varios comportamientos únicos. Uno de esos comportamientos es que este
comando puede revertir una posición de mercado abierto sin llamadas a funciones adicionales. Cuando se completa una orden realizada usando
Strategy.entry() , la función calculará automáticamente la cantidad que la estrategia necesita para cerrar la posición de mercado abierta y negociar
cantidades de contratos/acciones/lotes/unidades en la dirección opuesta de forma predeterminada. Por ejemplo, si una estrategia tiene una posición
abierta de 15 acciones en la dirección estrategia.larga y llama a estrategia.entry() para colocar una orden de mercado en la dirección estrategia.corta ,
la cantidad que la estrategia negociará para colocar la orden es 15 acciones más la cantidad de la nueva orden corta.

El siguiente ejemplo demuestra una estrategia que utiliza solo llamadas a Strategy.entry() para realizar órdenes de entrada. Crea una orden de
mercado larga con un valor de cantidad de 15 acciones una vez cada 100 barras y una orden de mercado corta con una cantidad de 5 acciones una
vez cada 25 barras. El script resalta el fondo azul y rojo para las apariciones de las respectivas condiciones de compra y venta:

1 //@versión=5 2
estrategia("Demostración de entrada", "prueba", superposición = verdadero)
3

4 //@variable Es "verdadero" en cada barra número 100. 5 buyCondition = bar_index


% 100 == 0 6 //@variable Es "verdadero" cada 25 barras excepto aquellas
que son divisibles por 100. 7 sellCondition = bar_index % 25 == 0 y no buyCondition

9 si condición de compra
10 estrategia.entrada("comprar", estrategia.long, cantidad = 15) 11 si condición de venta

12 estrategia.entrada("vender", estrategia.corto, cantidad = 5)


(continúa en la página siguiente)

4.17. Estrategias 323


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

13

14 bgcolor(condición de compra? color.nuevo(color.azul, 90): na) 15 bgcolor(condición de venta?


color.nuevo(color.rojo, 90): na)

Como vemos en el gráfico anterior, las marcas de orden muestran que la estrategia negoció 20 acciones en cada orden ejecutada en lugar de 15 y 5.
Dado que Strategy.entry() invierte automáticamente las posiciones, a menos que se especifique lo contrario a través de Strategy.risk.allow_entry_in()
función, agrega el tamaño de la posición abierta (15 para entradas largas) al tamaño de la nueva orden (5 para entradas cortas) cuando cambia la
dirección, lo que resulta en una cantidad negociada de 20 acciones.

Observe que en el ejemplo anterior, aunque la condición de venta ocurre tres veces antes de otra condición de compra, la estrategia solo coloca una
orden de "venta" en la primera aparición. Otro comportamiento único del comando Strategy.entry() es que se ve afectado por la configuración piramidal
de un script . La pirámide especifica el número de órdenes consecutivas que la estrategia puede completar en la misma dirección. Su valor es 1 por
defecto, lo que significa que la estrategia solo permite que se complete una orden consecutiva en cualquier dirección. Los usuarios pueden configurar
los valores de pirámide de la estrategia a través del parámetro de pirámide de la llamada a la función estrategia() o la entrada "Pirámide" en la pestaña
"Propiedades" de la configuración del script.

Si agregamos piramidismo = 3 a la declaración de nuestro script anterior, la estrategia permitirá hasta tres operaciones consecutivas en la misma
dirección, lo que significa que puede simular nuevas órdenes de mercado en cada aparición de sellCondition:

`estrategia.orden()`

Este comando simula un orden básico. A diferencia de la mayoría de los comandos de colocación de pedidos, que contienen lógica interna para
simplificar la interfaz con las estrategias, Strategy.order() utiliza los parámetros especificados sin tener en cuenta la mayoría de las configuraciones de
estrategias adicionales. Las órdenes realizadas por Strategy.order() pueden abrir nuevas posiciones y modificar o cerrar las existentes.

El siguiente script utiliza solo llamadas a Strategy.order() para crear y modificar entradas. La estrategia simula una orden de mercado larga de 15
unidades cada 100 barras, luego tres órdenes cortas de cinco unidades cada 25 barras. El script resalta el fondo azul y rojo para indicar cuándo la
estrategia simula órdenes de "compra" y "venta":

324 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 estrategia ("Solicitar demostración", "prueba", superposición = verdadero)
3

4 //@variable Es "verdadero" en cada barra número 100. 5 buyCond = bar_index


% 100 == 0 6 //@variable Es `true` en cada 25 barras excepto
aquellas que son divisibles por 100. 7 sellCond = bar_index % 25 == 0 y no buyCond

9 if buyCond
10 estrategia.order("comprar", estrategia.long, qty = 15) // Ingrese una posición larga de 15
→unidades.
11 si venderCond
12 estrategia.order("sell", estrategia.short, qty = 5) // Sale 5 unidades de la posición larga →.

13

14 bgcolor(comprarCond ? color.new(color.azul, 90) : na) 15 bgcolor(venderCond ?


color.new(color.rojo, 90): na)

Esta estrategia en particular nunca simulará una posición corta, ya que a diferencia de Strategy.entry(), Strategy.order() no invierte
posiciones automáticamente. Cuando se utiliza este comando, la posición de mercado resultante es la suma neta de la posición de mercado
actual y la cantidad de la orden ejecutada. Después de que la estrategia completa la orden de "compra" de 15 unidades, ejecuta tres
órdenes de "venta" que reducen la posición abierta en cinco unidades cada una, y 15 ­ 5 * 3 = 0. El mismo script se comportaría de manera
diferente usando estrategia.entry( ), según el ejemplo mostrado en la sección anterior.

4.17. Estrategias 325


Machine Translated by Google

Manual del usuario de Pine Script™ v5

`estrategia.salida()`

Este comando simula órdenes de salida. Es único porque permite que una estrategia salga de una posición de mercado o forme múltiples
salidas en forma de órdenes de stop­loss, take­profit y trailing stop a través de los parámetros de pérdida, stop, beneficio, límite y trail_*.

El uso más básico del comando Strategy.exit() es la creación de niveles en los que la estrategia saldrá de una posición debido a perder
demasiado dinero (stop­loss), ganar suficiente dinero (take­profit) o ambas cosas (corchete). .

Las funcionalidades stop­loss y take­profit de este comando están asociadas a dos parámetros. Los parámetros de pérdida y ganancia de la
función especifican valores de parada de pérdidas y toma de ganancias como un número definido de ticks lejos del precio de la orden de
entrada, mientras que sus parámetros de parada y límite proporcionan valores específicos de precio de parada de pérdidas y toma de
ganancias. Los parámetros absolutos en la llamada a la función reemplazan a los relativos. Si una llamada a Strategy.exit() contiene
argumentos de beneficio y límite, el comando priorizará el valor límite e ignorará el valor de beneficio. Asimismo, solo considerará el valor de
parada cuando la llamada a la función contenga argumentos de parada y pérdida.

Nota: A pesar de compartir los mismos nombres con los parámetros de los comandos estrategia.entry() y estrategia.order() , los parámetros
de límite y detención funcionan de manera diferente en estrategia.exit(). En el primer caso, usar límite y stop en el comando creará una única
orden stop­limit que abre una orden límite después de cruzar el precio stop. En el segundo caso, el comando creará una orden de límite y
parada separada para salir de una posición abierta.

Todas las órdenes de salida de Strategy.exit() con un argumento from_entry están vinculadas al ID de una orden de entrada correspondiente;
Las estrategias no pueden simular órdenes de salida cuando no hay una posición de mercado abierta ni una orden de entrada activa asociada
con un ID from_entry.

La siguiente estrategia coloca una orden de entrada de "compra" a través de Strategy.entry() y una orden de stop­loss y Take­Profit a través
del comando strat­egy.exit() cada 100 barras. Observe que el script llama a Strategy.exit() dos veces. El comando "exit1" hace referencia a
una orden de entrada "buy1" y "exit2" hace referencia a la orden de "compra". La estrategia solo simulará órdenes de salida de "exit2" porque
"exit1" hace referencia a un ID de orden que no existe:

1 //@versión=5 2
estrategia("Salir de la demostración", "prueba", superposición = verdadero)
3

(continúa en la página siguiente)

326 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

4 //@variable Es "verdadero" en cada barra número 100. 5 condición de compra =


índice_barra % 100 == 0
6

7 //@variable Precio Stop­loss para comandos de salida. 8 var float stopLoss = na 9 //@variable Precio
de obtención de beneficios para los comandos de salida.
10 var float takeProfit = na

11

12 // Realizar pedidos en `buyCondition`. 13 si compraCondición

14 si estrategia.position_size == 0.0 stopLoss :=


15 cerrar * 0.99 takeProfit := cerrar * 1.01
dieciséis

17 estrategia.entry("comprar", estrategia.long)
18 estrategia.exit("salir1", "comprar1", stop = stopLoss, limit = takeProfit) // Hace
→nada. La orden "comprar1" no existe.
19 estrategia.exit("salir2", "comprar", detener = detenerLoss, límite = tomar ganancias)
20

21 // Establece `stopLoss` y `takeProfit` en `na` cuando el precio toque cualquiera de los dos, es decir, cuando
→la estrategia simula una salida. 22 si es
bajo <= stopLoss o alto >= takeProfit stopLoss := na TakeProfit :=
23 na
24

25

26 plot(stopLoss, "SL", color.red, estilo = plot.style_circles) 27 plot(takeProfit, "TP", color.green, estilo = plot.style_circles)

Tenga en cuenta que:

• Las órdenes de límite y stop de cada comando de salida no necesariamente se ejecutan a los precios especificados. Las estrategias
pueden ejecutar órdenes limitadas a mejores precios y detener órdenes a peores precios, dependiendo del rango de valores disponibles
para el emulador del corredor.

Si un usuario no proporciona un argumento from_entry en la llamada a Strategy.exit() , la función creará órdenes de salida para cada entrada abierta.

En este ejemplo, la estrategia crea órdenes de entrada "compra1" y "compra2" y llama a estrategia.exit() sin un argumento from_entry cada 100 barras.
Como podemos ver en las marcas de orden en el gráfico, una vez que el precio de mercado alcanza los valores de stopLoss o takeProfit, la estrategia
completa una orden de salida para las entradas de "compra1" y "compra2":

4.17. Estrategias 327


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia ("Salir de toda la demostración", "prueba", superposición = verdadero, piramidal = 2)


3

4 //@variable Es "verdadero" en cada barra número 100. 5 condición de compra =


índice_barra % 100 == 0
6

7 //@variable Precio Stop­loss para comandos de salida. 8 var float stopLoss = na 9 //@variable
Precio de obtención de beneficios para los comandos
de salida.
10 var float takeProfit = na
11

12 // Realizar pedidos en `buyCondition`. 13 si compraCondición

14 si estrategia.position_size == 0.0 stopLoss := cerrar


15 * 0.99 takeProfit := cerrar * 1.01
dieciséis

17 estrategia.entry("buy1", estrategia.long)
18 estrategia.entry("compra2", estrategia.long)
19 estrategia.exit("salida", stop = stopLoss, limit = takeProfit) // Coloca órdenes para →salir todo abierto entradas.

20

21 // Establece `stopLoss` y `takeProfit` en `na` cuando el precio toque cualquiera de los dos, es decir, cuando
→la estrategia simula una salida. 22 si es bajo
<= stopLoss o alto >= takeProfit
23 stopLoss := na takeProfit :=
24 na
25

26 plot(stopLoss, "SL", color.red, estilo = plot.style_circles) 27 plot(takeProfit, "TP", color.green, estilo = plot.style_circles)

Es posible que una estrategia salga del mismo ID de entrada más de una vez, lo que facilita la formación de estrategias de salida
multinivel. Al ejecutar múltiples comandos de salida, la cantidad de cada orden debe ser una parte de la cantidad negociada y su
suma no debe exceder la posición abierta. Si la cantidad de la función es menor que el tamaño de la posición actual del mercado,
la estrategia simulará una salida parcial. Si el valor de la cantidad excede la cantidad de la posición abierta, reducirá la orden ya
que no puede completar más contratos/acciones/lotes/unidades que la posición abierta.

328 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

En el siguiente ejemplo, hemos modificado nuestro script anterior de "Salir de la demostración" para simular dos órdenes de stop­loss y take­profit por
entrada. La estrategia coloca una orden de "compra" con una cantidad de dos acciones, órdenes de stop­loss y toma de ganancias de "salida1" con una cantidad de
una acción y órdenes de stop­loss y toma de ganancias “exit2” con una cantidad de tres acciones:

1 //@versión=5
2 estrategia ("Demostración de salida múltiple", "prueba", superposición = verdadero)
3

4 //@variable Es "verdadero" en cada barra número 100.


5 condición de compra = índice_barra % 100 == 0
6

7 //@variable Precio Stop­loss para comandos "exit1".


8 var flotador stopLoss1 = na
9 //@variable Precio Stop­loss para comandos "exit2".
10 var flotador stopLoss2 = na
11 //@variable Precio de toma de ganancias para los comandos "exit1".
12 var flotante takeProfit1 = na
13 //@variable Precio de toma de ganancias para los comandos "exit2".
14 var flotante takeProfit2 = na
15

16 // Realizar pedidos en `buyCondition`.


17 si compraCondición
18 si estrategia.position_size == 0.0
19 stopLoss1: = cerrar * 0,99
20 stopLoss2: = cerrar * 0,98
21 takeProfit1 := cerrar * 1.01
22 takeProfit2 := cerrar * 1.02
23 estrategia.entrada("comprar", estrategia.largo, cantidad = 2)
24 estrategia.exit("salir1", "comprar", detener = detenerLoss1, límite = tomarProfit1, cantidad = 1)
25 estrategia.exit("salir2", "comprar", detener = detenerLoss2, límite = tomarProfit2, cantidad = 3)
26

27 // Establece `stopLoss1` y `takeProfit1` en `na` cuando el precio toque cualquiera de los dos.
28 si es bajo <= stopLoss1 o alto >= takeProfit1
29 detenerLoss1 := na
30 tomar beneficio1 := na
31 // Establece `stopLoss2` y `takeProfit2` en `na` cuando el precio toque cualquiera de los dos.
(continúa en la página siguiente)

4.17. Estrategias 329


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

32 si es bajo <= stopLoss2 o alto >= takeProfit2 stopLoss2 := na TakeProfit2 := na


33

34

35

36 plot(stopLoss1, "SL1", color.red, estilo = plot.style_circles) 37 plot(stopLoss2, "SL2", color.red, estilo = plot.style_circles)
38 plot(takeProfit1, "TP1", color.verde , estilo = plot.style_circles) 39 plot(takeProfit2, "TP2", color.verde, estilo =
plot.style_circles)

Como podemos ver en las marcas de orden en el gráfico, la estrategia completó las órdenes de "salida2" a pesar de que el valor de cantidad especificado excedía
la cantidad negociada. En lugar de utilizar esta cantidad, el script redujo el tamaño de los pedidos para que coincidieran con la posición restante.

Tenga en cuenta que:

• Todas las órdenes generadas a partir de una llamada a Strategy.exit() pertenecen al mismo grupo Strategy.oca.reduce , lo que significa que
cuando cualquiera de las órdenes se ejecuta, la estrategia reduce todas las demás para igualar la posición abierta.

Es importante tener en cuenta que las órdenes producidas por este comando reservan una parte de la posición de mercado abierto para salir. strat­egy.exit() no
puede realizar una orden para salir de una parte de la posición ya reservada para salir mediante otro comando de salida.

El siguiente script simula una orden de mercado de "compra" para 20 acciones hace 100 barras con órdenes de "límite" y "parada" de 19 y 20 acciones
respectivamente. Como vemos en el gráfico, la estrategia ejecutó primero la orden "stop". Sin embargo, la cantidad negociada fue sólo una acción. Dado que el
script colocó primero la orden "límite", la estrategia reservó su cantidad (19 acciones) para cerrar la posición abierta, dejando solo una acción para cerrar con la
orden "stop":

1 //@versión=5 2
estrategia("Demostración de salida reservada", "prueba", superposición = verdadero)
3

4 //@precio variable de la orden de salida "stop". 5 var float stop = na


6 //@variable precio de orden de salida
"límite" 7 var float limit = na

8 //@variable Es "verdadero" 100 barras antes del "último_índice_barra". 9 condición larga = last_bar_index ­
bar_index == 100
(continúa en la página siguiente)

330 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

10

11 si es largaCondición
12 detener := cerrar * 0,99 límite :=
13 cerrar * 1,01
14 estrategia.entry("comprar", estrategia.long, 20)
15 estrategia.exit("límite", límite = límite, cantidad = 19) estrategia.exit("parar",
dieciséis detener = detener, cantidad = 20)
17

18 bool showPlot = estrategia.position_size != 0 19 plot(showPlot ? stop : na, "Stop", color.red, 2,


plot.style_linebr) 20 plot(showPlot ? límite : na, "Límite 1", color.green , 2, trama.style_linebr)

Otra característica clave de la función Strategy.exit() es que puede crear trailingstops, es decir, órdenes de stop­loss que van por detrás del
precio de mercado en una cantidad específica siempre que el precio se mueve hacia un mejor valor en la dirección favorable. Estas órdenes
tienen dos componentes: el nivel de activación y el desplazamiento del rastro. El nivel de activación es el valor que debe cruzar el precio de
mercado para activar el cálculo del trailing stop, expresado en ticks mediante el parámetro trail_points o como valor de precio mediante el
parámetro trail_price. Si una llamada de salida contiene ambos argumentos, el argumento trail_price tiene prioridad.
El desplazamiento del recorrido es la distancia que seguirá la parada detrás del precio de mercado, expresada en ticks mediante el parámetro
trail_offset. Para que Strategy.exit() cree y active paradas finales, la llamada a la función debe contener los argumentos trail_offset y trail_price
o trail_points.

El siguiente ejemplo muestra un trailing stop en acción y visualiza su comportamiento. La estrategia simula una orden de entrada larga en la
barra 100 barras antes de la última barra del gráfico, luego un trailing stop en la siguiente barra. El script tiene dos entradas: una controla el
desplazamiento del nivel de activación (es decir, la cantidad más allá del precio de entrada necesaria para activar el stop) y la otra controla el
desplazamiento del recorrido (es decir, la distancia a seguir detrás del precio de mercado cuando se mueve a un mejor valor en la dirección deseada).

La línea discontinua verde en el gráfico muestra el nivel que debe cruzar el precio de mercado para activar la orden de trailing stop. Después
de que el precio cruza este nivel, el script traza una línea azul para indicar el trailing stop. Cuando el precio sube a un nuevo valor máximo, lo
cual es favorable para la estrategia porque significa que el valor de la posición está aumentando, el stop también sube para mantener una
distancia de ticks trailingStopOffset detrás del precio actual. Cuando el precio disminuye o no alcanza un nuevo punto máximo, el valor stop
permanece igual. Finalmente, el precio cruza por debajo del stop, lo que provoca la salida:

1 //@version=5 2

estrategia("Demostración de orden trailing stop", overlay = true, margin_long = 100, margin_short


(continúa en la página siguiente)

4.17. Estrategias 331


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

→= 100)
3

4 //@variable Compensación utilizada para determinar qué tan por encima del precio de entrada (en ticks) el
→Se localizará el nivel de activación.
5 activaciónLevelOffset = input(1000, "Compensación del nivel de activación (en ticks)")
6 //@variable Compensación utilizada para determinar qué tan por debajo del precio alto (en ticks) está el
→el trailing stop seguirá el gráfico.
7 trailingStopOffset = input(2000, "Trailing Stop Offset (en ticks)")
8

9 //@función Muestra el texto pasado a `txt` cuando se llama y muestra el nivel de `precio` en
→el gráfico.

10 debugLabel(precio, txt, lblColor, hasLine = false) =>


11 etiqueta.nueva(
12 bar_index, precio, texto = txt, color = lblColor, textcolor = color.blanco,
13 estilo = etiqueta.style_label_lower_right, tamaño = tamaño.grande
14 )
15 si tiene línea
dieciséis
línea.nueva(
17 bar_index, precio, bar_index + 1, precio, color = lblColor, extender =
→extender.derecha,
18 estilo = línea.style_dasshed
19 )
20

21 //@variable El precio al que se encuentra el nivel de activación del trailing stop.


22 var float trailPriceActivationLevel = na

23 //@variable El precio al que se encuentra el trailing stop.


24 var float trailingStop = na
25 //@variable Calcula el valor que tendría el Trailing Stop si estuviera activo en
→el momento.
26 teóricoStopPrice = alto ­ trailingStopOffset * syminfo.mintick
27

28 // Genera una orden de mercado larga para ingresar 100 barras antes de la última barra.
29 si último_índice_barra ­ índice_barra == 100
30 estrategia.entrada("Larga", estrategia.larga)
31

32 // Genera un trailing stop 99 barras antes de la última barra.


33 si último_índice_barra ­ índice_barra == 99
34 trailPriceActivationLevel: = abrir + syminfo.mintick * activaciónLevelOffset
35 estrategia.salir(
36 "Parada de seguimiento", from_entry = "Largo", trail_price =
→nivel de activación de precio de ruta,
37 trail_offset = trailingStopOffset
38 )
39 debugLabel(trailPriceActivationLevel, "Nivel de activación de Trailing Stop", color.
→verde, verdadero)
40

41 // Visualice la mecánica del trailing stop en acción.


42 // Si hay una operación abierta, verifique si se ha alcanzado el nivel de activación.
43 // Si se ha logrado, realice un seguimiento del trailing stop asignando su valor a a
→variable.
44 si estrategia.opentrades == 1
45 si na(trailingStop) y alto > trailPriceActivationLevel
46 debugLabel(trailPriceActivationLevel, "Nivel de activación cruzado", color.verde)
47 trailingStop: = precio de parada teórico
48 debugLabel(trailingStop, "Trailing Stop activado", color.azul)
49

50 de lo contrario, si el precio de parada teórico > la parada final


(continúa en la página siguiente)

332 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

(Continuación de la página anterior)

51 trailingStop: = precio de parada teórico


52

53 // Visualiza el movimiento del trailing stop. 54 trama(trailingStop, "Trailing


Stop")

`estrategia.close()` y `estrategia.close_all()`

Estos comandos simulan posiciones de salida utilizando órdenes de mercado. Las funciones cierran operaciones al ser llamadas en lugar de a
un precio específico.

El siguiente ejemplo demuestra una estrategia simple que coloca una orden de "compra" a través de Strategy.entry() una vez cada 50 barras y
cierra con una orden de mercado usando Strategy.close() 25 barras después:

1 //@versión=5 2
estrategia("Cerrar demostración", "prueba", superposición = verdadero)
3

4 //@variable Es "verdadero" cada 50 barras. 5 buyCond = bar_index


% 50 == 0 6 //@variable Es `true` en cada 25
barras excepto aquellas que son divisibles por 50. 7 sellCond = bar_index % 25 == 0 y no buyCond

9 si comprarCond
10 estrategia.entrada("comprar", estrategia.largo) 11 si
venderCond
12 estrategia.cerrar("comprar")
13

14 bgcolor(comprarCond ? color.new(color.azul, 90) : na) 15 bgcolor(venderCond ?


color.new(color.rojo, 90): na)

A diferencia de la mayoría de los otros comandos de colocación de pedidos, el parámetro id de Strategy.close() hace referencia a un ID de
entrada existente para cerrar. Si la identificación especificada no existe, el comando no ejecutará una orden. Si una posición se formó a partir de
varias entradas con el mismo ID, el comando saldrá de todas las entradas simultáneamente.

4.17. Estrategias 333


Machine Translated by Google

Manual del usuario de Pine Script™ v5

Para demostrarlo, el siguiente script coloca una orden de "compra" una vez cada 25 barras. El script cierra todas las entradas de "compra"
una vez cada 100 barras. Hemos incluido piramidal = 3 en la declaración de estrategia() para permitir que la estrategia simule hasta tres
órdenes en la misma dirección:

1 //@versión=5
2 estrategia ("Demostración de cierre múltiple", "prueba", superposición = verdadero, piramidal = 3)
3

4 //@variable Es "verdadero" en cada barra número 100. 5 sellCond = bar_index


% 100 == 0 6 //@variable Es "verdadero" cada 25 barras
excepto aquellas que son divisibles por 100. 7 buyCond = bar_index % 25 == 0 y no sellCond

9 si comprarCond
10 estrategia.entrada("comprar", estrategia.largo)
11 si venderCond
12 estrategia.cerrar("comprar")
13

14 bgcolor(comprarCond ? color.new(color.azul, 90) : na) 15 bgcolor(venderCond ? color.new(color.rojo,


90): na)

Para los casos en los que un script tiene varias entradas con diferentes ID, el comando estrategia.close_all() puede resultar útil ya que cierra
todas las entradas, independientemente de sus ID.

El siguiente script coloca las órdenes de entrada "A", "B" y "C" secuencialmente según el número de operaciones abiertas y luego las cierra
todas con una única orden de mercado:

334 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia ("Cerrar demostración de ID múltiple", "prueba", superposición = verdadero, piramidación = 3)


3

4 estrategia de cambio.opentrades
5 0 => estrategia.entrada("A", estrategia.long)
6 1 => estrategia.entrada("B", estrategia.long)
7 2 => estrategia.entrada("C", estrategia.long)
8 3 => estrategia.close_all()

`estrategia.cancel()` y `estrategia.cancel_all()`

Estos comandos permiten que una estrategia cancele órdenes pendientes, es decir, aquellas generadas por estrategia.exit() o por estrategia.order()
o estrategia.entry() cuando usan argumentos de límite o parada.

La siguiente estrategia simula una orden límite de "compra" 500 ticks por debajo del precio de cierre hace 100 barras y luego cancela la orden.
en la siguiente barra. El script dibuja una línea horizontal en el precio límite y colorea el fondo de verde y naranja para
indicar cuándo se realiza y cancela la orden limitada respectivamente. Como podemos ver, no pasó nada una vez que el precio de mercado
cruzó el precio límite porque la estrategia ya canceló la orden:

4.17. Estrategias 335


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia ("Cancelar demostración", "prueba", superposición = verdadero)


3

4 //@variable Dibuja una línea horizontal en el precio "límite" de la orden de "compra". 5 var línea limitLine = na

7 //@variable Devuelve `color.green` cuando la estrategia coloca la orden de "compra", `color. →naranja` cuando cancela el pedido.
8 colores bgColor = na

10 si último_índice_barra ­ índice_barra == 100


11 float limitPrice = close ­ syminfo.mintick * 500 estrategia.entry("comprar",
12 estrategia.long, limit = limitPrice) limitLine := line.new(bar_index, limitPrice, bar_index
13 + 1, limitPrice, extender = →extend.right ) bgColor := color.nuevo(color.verde, 50)

14

15

16 if last_bar_index ­ bar_index == 99 estrategia.cancel("comprar") bgColor :=


17 color.new(color.orange, 50)
18

19

20 bgcolor(bgColor)

Al igual que con Strategy.close(), el parámetro id de Strategy.cancel() se refiere al ID de una entrada existente. Este comando no hará
nada si el parámetro id hace referencia a una ID que no existe. Cuando hay varias órdenes pendientes con el mismo ID, este comando
las cancelará todas a la vez.

En este ejemplo, hemos modificado el script anterior para colocar una orden límite de "compra" en tres barras consecutivas a partir
de hace 100 barras. La estrategia los cancela todos después de que bar_index esté a 97 barras de la barra más reciente, lo que hace
que no haga nada cuando el precio cruza cualquiera de las líneas:

336 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5

2 estrategia ("Demostración de cancelación múltiple", "prueba", superposición = verdadero, piramidal = 3)


3

4 //@variable Dibuja una línea horizontal en el precio "límite" de la orden de "compra". 5 var línea limitLine = na

7 //@variable Devuelve `color.green` cuando la estrategia coloca la orden de "compra", `color. →naranja` cuando cancela el pedido.
8 colores bgColor = na

10 si last_bar_index ­ bar_index <= 100 y last_bar_index ­ bar_index >= 98


11 float limitPrice = close ­ syminfo.mintick * 500 estrategia.entry("comprar",
12 estrategia.long, limit = limitPrice) limitLine := line.new(bar_index, limitPrice, bar_index
13 + 1, limitPrice, extender = →extend.right ) bgColor := color.nuevo(color.verde, 50)

14

15

16 if last_bar_index ­ bar_index == 97 estrategia.cancel("comprar") bgColor :=


17 color.new(color.orange, 50)
18

19

20 bgcolor(bgColor)

Tenga en cuenta que:

• Agregamos Pyramiding = 3 a la declaración del script para permitir que se completen tres órdenes de Strategy.entry() . Alternativamente,
el script lograría el mismo resultado usando estrategia.order() ya que no es sensible a la configuración piramidal.

Es importante tener en cuenta que ni estrategia.cancel() ni estrategia.cancel_all() pueden cancelar órdenes de mercado , ya que la estrategia las
ejecuta inmediatamente en el siguiente tick. Las estrategias no pueden cancelar pedidos una vez que se han completado. Para cerrar una posición
abierta, utilice estrategia.close() o estrategia.close_all().

Este ejemplo simula una orden de mercado de "compra" hace 100 barras y luego intenta cancelar todas las órdenes pendientes en la siguiente barra.
Dado que la estrategia ya completó la orden de "compra", el comando Strategy.cancel_all() no hace nada en este caso, ya que no hay órdenes
pendientes para cancelar:

4.17. Estrategias 337


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@version=5 2

estrategia("Cancelar demostración de mercado", "prueba", superposición = verdadero)


3

4 //@variable Devuelve `color.green` cuando la estrategia coloca la orden de "compra", `color.


→naranja` cuando intenta cancelar.
5 colores bgColor = na
6

7 si último_índice_barra ­ índice_barra == 100


8 estrategia.entry("comprar", estrategia.long) bgColor :=
9 color.new(color.verde, 50)
10

11 si último_índice_barra ­ índice_barra == 99
12 estrategia.cancel_all() bgColor :=
13 color.new(color.naranja, 50)
14

15 bgcolor(bgColor)

4.17.7 Dimensionamiento de la posición

Las estrategias de Pine Script™ presentan dos formas de controlar el tamaño de las operaciones simuladas:

• Establezca un tipo y valor de cantidad fijo predeterminado para todos los pedidos utilizando los argumentos default_qty_type y de­fault_qty_value en
la función estrategia() , que también establece los valores predeterminados en la pestaña "Propiedades" de la configuración del script.

• Especifique el argumento cantidad al llamar a Strategy.entry(). Cuando un usuario proporciona este argumento a la función, el
El script ignora el valor y el tipo de cantidad predeterminados de la estrategia.

El siguiente ejemplo simula órdenes de "Compra" de tamaño longAmount siempre que el precio bajo sea igual al valor más bajo, y órdenes de "Venta" de
tamaño shortAmount cuando el precio alto sea igual al valor más alto:

338 Capítulo 4. Conceptos


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 estrategia ("Comprar barato, vender caro", superposición = verdadero, default_qty_type = estrategia.cash,
→valor_cantidad_predeterminado = 5000)
3

4 int longitud = input.int(20, "Longitud") 5 float longAmount = input.float(4.0, "Cantidad


larga") 6 float shortAmount = input.float(2.0, "Cantidad corta")

8 flotador más alto = ta.highest(longitud) 9 float más bajo =


ta.lowest(longitud)
10

11 interruptor
12 bajo == más bajo => estrategia.entry("Comprar", estrategia.largo, monto largo) alto == más alto =>
13 estrategia.entry("Vender", estrategia.corto, monto corto)

Observe que en el ejemplo anterior, aunque hemos especificado los argumentos default_qty_type y default_qty_value en la
declaración de declaración, el script no utiliza estos valores predeterminados para las órdenes simuladas. En lugar de ello, los
dimensiona como una cantidad larga y una cantidad corta de unidades. Si queremos que el script use el tipo y valor predeterminados,
debemos eliminar la especificación de cantidad de las llamadas a Strategy.entry() :

4.17. Estrategias 339


Machine Translated by Google

Manual del usuario de Pine Script™ v5

1 //@versión=5
2 estrategia ("Comprar barato, vender caro", superposición = verdadero, default_qty_type = estrategia.cash,
→valor_cantidad_predeterminado = 5000)
3

4 int longitud = input.int(20, "Longitud")


5

6 flotador más alto = ta.más alto (longitud) 7 flotador más bajo = ta.más
bajo (longitud)
8

9 interruptor
10 bajo == más bajo => estrategia.entry("Comprar", estrategia.long) alto == más alto =>
11 estrategia.entry("Vender", estrategia.corto)

4.17.8 Cerrar una posición de mercado

Aunque es posible simular una salida de una orden de entrada específica que se muestra en la pestaña Lista de operaciones del módulo Probador
de estrategias , todas las órdenes están vinculadas según las reglas FIFO (primero en entrar, primero en salir). Si el usuario no especifica el
parámetro from_entry de una llamada a Strategy.exit() , la estrategia saldrá de la posición de mercado abierta a partir de la primera orden de
entrada que la abrió.

El siguiente ejemplo simula dos órdenes secuencialmente: "Comprar1" al precio de mercado para las últimas 100 barras y "Comprar2" una vez
que el tamaño de la posición coincide con el tamaño de "Comprar1". La estrategia solo coloca una orden de salida cuando el tamaño de la
posición es de 15 unidades. El script no proporciona un argumento from_entry al comando estrategia.exit() , por lo que la estrategia coloca
órdenes de salida para todas las posiciones abiertas cada vez que llama a la función, comenzando por la primera. Traza el tamaño de la posición
en un panel separado para referencia visual:

340 Capítulo 4. Conceptos

También podría gustarte