Pine Script v5 User Manual (200-350)
Pine Script v5 User Manual (200-350)
Pine Script v5 User Manual (200-350)
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)
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:
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)
• 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 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.
• 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.
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)
• Introducción
• Ejemplo
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 .
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:
5 // Inicializa los elementos de la matriz con tonos progresivamente más claros del relleno →color.
`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
`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.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
1 //@versión=5
– naranja cuando se confirma una barra de tiempo real (cuando se cierra y se convierte en una barra de tiempo real transcurrido)
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.
• 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:
• Introducción
• Precios y volumen
• Información de símbolos
• 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:
•
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.
• 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.
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.
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.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 EMini”) 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 EMini”) el valor
en puntos es 50, por lo que un contrato vale 50 veces el precio del instrumento.
• syminfo.root: Es el prefijo del ticker para tickers estructurados como los de futuros. Es “ES” para “ES1!”, “ZW” para
“¡ZW1!”.
• 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”.
1 //@versión=5
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)
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™.
• 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.
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
• Sus componentes rojo, verde y azul (0255), siguiendo el modelo de color RGB.
• Su transparencia (0100), 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.
í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.
Hay 17 colores integrados en Pine Script™. Esta tabla enumera sus nombres, equivalente hexadecimal y valores RGB como argumentos para
color.rgb():
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))
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.
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á:
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)
• 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)
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.
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.
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.
• 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.
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)
• 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.0100.0 proporciona acceso a
los valores de transparencia completos 0255 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
• 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)
14
• 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.
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.
• 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.
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
dieciséis
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
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)
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)
57
62 // ————— Antecedentes. 63
bgcolor(bgColor)
• Limitamos la transparencia del fondo a un rango de 10075 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
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.
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.
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
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.
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:
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 0100 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:
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)
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 de línea
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().
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) )
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
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:
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))
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:
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:
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
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
• Tipos de entrada
• Consejos
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 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.
• 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.
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".
• 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.
• 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() .
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
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.)
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)
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.
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.
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)
• 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.
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:
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
• 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
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]
• 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.
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.
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]
• 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.
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("06001700", "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)
• 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.
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() .
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:
• 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.
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
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)
dieciséis
• 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.10 niveles
• 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.
• 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.
1 //@versión=5
2 indicador("TSI") 3 myTSI =
100 * ta.tsi(cerrar, 25, 13)
4
10
11 parcela (miTSI)
• 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.
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().
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)
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
19
20 parcela (miTSI)
• 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
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.
Un script de biblioteca tiene la siguiente estructura, donde se deben definir una o más funciones exportables:
1 //@versión=5
2
6 <código_script>
7
14 <código_script>
• 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.
• <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.
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) =>
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
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.
• Una palabra clave simple o de serie puede restringir los tipos de argumentos calificados permitidos (la siguiente sección explica sus
usar).
• 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 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".
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:
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":
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 :
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.
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í:
• 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.
• 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
7 tipo punto
8 entero x
9 flotar y
10 bool es Hola
11 bool fue violado = falso
12
13
18 // Detectar pivotes.
19 pivote flotanteHi = ta.pivothigh(piernasizquierda,piernasderecha)
20 float pivotLo = ta.pivotlow(piernasizquierdas, piernasderechas)
21
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)
47 array.set(pivotsArray, i, p)
48
49
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
80
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":
• 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.
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.
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 :
dónde:
• 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 :
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:
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))
• 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.
• Introducción
• Líneas
• Cajas
• Polilíneas
• 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:
• 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.
• 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 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(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.
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.
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
12
• 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
7 //@variable La distancia entre cada punto y en la barra actual. 8 paso flotante = (alto bajo) / (linesPerBar 1)
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
→barra resaltada")
• 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 secondPoint. 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_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.
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
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
23 line.set_color(periodLine, finalColor)
24
31 más si no na (periodLine)
32 // Asigna un nuevo punto al `closePoint`.
33 closePoint := chart.point.now(cerrar)
34
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)
• 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() :
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
• 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.
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_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:
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
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
• 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)
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)
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
• 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
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
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
• 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 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(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.
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.
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
4 //@variable El `chart.point` para la esquina superior izquierda del cuadro. Contiene información de `índice` →y `hora`.
9 // Dibuja un cuadro usando los puntos de las esquinas `topLeft` y `bottomRight`. Utiliza los campos `index` →como coordenadas x.
• 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_bgcolor() establece el color del espacio dentro del cuadro de identificación en un nuevo color.
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
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.
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
7 //@variable Un cuadro que proyecta el rango de la barra ascendente con el `volumen` más alto
→durante el "plazo".
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
26
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
• 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.
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
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:
1 //@versión=5
2 indicador ("Demostración de valores de cuadro de lectura", "Cuadros anidados", superposición = verdadero, max_boxes_count
→= 500)
3
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
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
• 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:
1 //@versión=5
2 indicadores ("Demostración de clonación de cuadros", superposición = verdadero, max_boxes_count = 500)
3
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
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)
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
12
13 //@variable Una matriz que contiene el ID de cada cuadro mostrado por el script. 14 cajas var = array.new<caja>()
15
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)
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
• 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 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.
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
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:
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>()
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.
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")
• 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.
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>()
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)
→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>()
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)
19 puntos.push(chart.point.now(yValue * math.random()))
20 // Cambia el signo de `yValue`.
21 Valor y *= 1
22
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:
1 //@versión=5
15 si es nuevopolígono
dieciséis
// Limpia la matriz de `puntos`.
17 puntos.clear()
18
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
• 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 array.shift() y elimina el
objeto usando polyline.delete():
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
dieciséis
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
• 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.
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
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
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
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.6 Limitaciones
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
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)
• Hemos utilizado la herramienta de dibujo “Medir” de TradingView para medir el número de barras cubiertas por el script.
dibujar objetos.
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() .
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)
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.
• 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 request.security() .
4.13.2 `ticker.heikinashi()`
HeikinAshi significa barra promedio en japonés. Los valores de apertura/máximo/mínimo/cierre de las velas HeikinAshi 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 HeikinAshi 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 HeikinAshi.
La función ticker.heikinashi() crea un identificador de teletipo especial para solicitar datos de HeikinAshi con la función request.security() .
Este script solicita el valor de cierre de las barras HeikinAshi y las traza sobre las velas normales:
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)
• Los valores de cierre de las barras HeikinAshi 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:
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)
• Primero usamos la función ticker.new() para crear un ticker sin información de sesión extendida.
• 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 .
1 //@versión=5
2 indicador("velas HeikinAshi")
3 VELA_VERDE = #26A69A
4 VELAS_ROJAS = #EF5350
5
• 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.
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.14 Parcelas
• Introducción
• Parámetros `plot()`
• Trazar condicionalmente
• Niveles
• Compensaciones
• 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.
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
• 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 ú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.
1 //@versión=5 2
indicador("Cambio de volumen", formato = formato.volumen)
3
14
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
• 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
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.
trama (serie, título, color, ancho de línea, estilo, precio de seguimiento, histbase, desplazamiento, unión, →editable,
show_last, display) → trama
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 campo “Condición” del cuadro de diálogo “Crear alerta”, cuando se selecciona el script.
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:
• 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_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.
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")}}')
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)
→estilo = trama.style_circles)
8 plot(plotValues? bajo: na, color = plotValues? color.green: na, ancho de línea = 6,
→estilo = trama.style_stepline)
• 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("20210101")) 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
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)
• 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)
• 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).
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:
Cuando utilicen otro tipo calificado, como cualquiera de estos, contarán por dos en el recuento total de parcelas:
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)
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.
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
• 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.15 Repintado
• Introducción
• Conspirar en el pasado
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:
3. Puedes evitarlo.
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.
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 indicador se mostrará en tiempo real de la misma manera que lo hace en las barras históricas?
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.
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.
• Conspirar en el pasado
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)
• 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.
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.
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)
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.
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
10
Así es como se ve su resultado en un gráfico de 5 segundos que ha estado ejecutando el script durante unos minutos:
• 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.
• 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
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:
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.
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.
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:
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.
`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.
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.
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)
• 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 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)
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:
• Los requisitos de alineación del conjunto de datos, que determinan su punto de partida.
Los puntos de partida se determinan utilizando las siguientes reglas, que dependen del período de tiempo del gráfico:
• 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.
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
4.16.1 Introducción
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™.
• 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.
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 “hhmmhhmm” 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 "09301700:23456".
"24x7"
Una sesión de 7 días y 24 horas que comienza a medianoche.
"00000000:1234567"
Equivalente al ejemplo anterior.
"00000000"
Equivalente a los dos ejemplos anteriores porque los días predeterminados son 1234567.
"00000000:23456"
Igual que el ejemplo anterior, pero sólo de lunes a viernes.
"20001630: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.3017.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).
"17001700: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.
"10001001:26"
Una sesión rara que dura sólo un minuto los lunes (2) y viernes (6).
"09001600,17002000"
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.
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
15
• 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
"09300935".
• 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 script no está en la primera barra del gráfico, lo cual aseguramos con (no con barstate.isfirst). este cheque
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.
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.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.
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:
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() :
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.
Dónde:
• la sesión puede ser sesión.extendida o sesión.regular. Tenga en cuenta que esta no es una cadena de sesión.
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.17 Estrategias
• Introducción
• Probador de estrategias
• Emulador de corredor
• Pedidos y entradas
• Dimensionamiento de la posición
• Grupos OCA
• Divisa
• Gestión de riesgos
• Margen
• Alertas de estrategia
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".
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
• 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.
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:
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.
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.
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.
• 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.
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.
• 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.
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.
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)
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
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:
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.
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
4 //@función Muestra el texto pasado a `txt` cuando se llama. 5 etiqueta de depuración (txt) =>
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
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:
1 //@versión=5
2 estrategia ("Demostración de orden de mercado", superposición = verdadero, margen_largo = 100, margen_corto = 100)
3
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)
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:
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)
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
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.
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 stoplimit. 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:
1 //@versión=5
4 //@función Muestra el texto pasado a `txt` cuando se llama y muestra el nivel de `precio` en
→el gráfico.
19 // Genera una orden stoplimit 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
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 stoplimit 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
9 si condición de compra
10 estrategia.entrada("comprar", estrategia.long, cantidad = 15) 11 si condición de venta
13
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":
1 //@versión=5
2 estrategia ("Solicitar demostración", "prueba", superposición = verdadero)
3
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
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.
`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 stoploss, takeprofit 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 (stoploss), ganar suficiente dinero (takeprofit) o ambas cosas (corchete). .
Las funcionalidades stoploss y takeprofit 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 stoplimit 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 stoploss y TakeProfit a través
del comando strategy.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
7 //@variable Precio Stoploss 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
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)
• 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":
1 //@versión=5
7 //@variable Precio Stoploss 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
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.
En el siguiente ejemplo, hemos modificado nuestro script anterior de "Salir de la demostración" para simular dos órdenes de stoploss y takeprofit por
entrada. La estrategia coloca una orden de "compra" con una cantidad de dos acciones, órdenes de stoploss y toma de ganancias de "salida1" con una cantidad de
una acción y órdenes de stoploss 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
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)
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.
• 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. strategy.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
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)
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
Otra característica clave de la función Strategy.exit() es que puede crear trailingstops, es decir, órdenes de stoploss 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
→= 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.
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
`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
9 si comprarCond
10 estrategia.entrada("comprar", estrategia.largo) 11 si
venderCond
12 estrategia.cerrar("comprar")
13
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.
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
9 si comprarCond
10 estrategia.entrada("comprar", estrategia.largo)
11 si venderCond
12 estrategia.cerrar("comprar")
13
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:
1 //@versión=5
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:
1 //@versión=5
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
14
15
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:
1 //@versión=5
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
14
15
19
20 bgcolor(bgColor)
• 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:
1 //@version=5 2
11 si último_índice_barra índice_barra == 99
12 estrategia.cancel_all() bgColor :=
13 color.new(color.naranja, 50)
14
15 bgcolor(bgColor)
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 default_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:
1 //@versión=5
2 estrategia ("Comprar barato, vender caro", superposición = verdadero, default_qty_type = estrategia.cash,
→valor_cantidad_predeterminado = 5000)
3
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() :
1 //@versión=5
2 estrategia ("Comprar barato, vender caro", superposición = verdadero, default_qty_type = estrategia.cash,
→valor_cantidad_predeterminado = 5000)
3
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)
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: