Si el precio permanece diez velas por encima de la media, close > average puede ser verdadero diez veces. Para marcar solo el evento en que pasa de abajo a arriba, necesitas también la relación de la vela anterior.

Una situación y su comienzo

Supongamos que la media es 100 tanto ahora como en la vela anterior. El cierre anterior era 99 y el actual es 101. En la vela actual, el precio está por encima de la media y además la ha cruzado respecto a la vela anterior.

Si el siguiente cierre es 102, sigue por encima. Pero no hay un nuevo cruce ascendente porque en la vela anterior ya estaba arriba.

ta.crossover(first, second) es verdadero si el primer valor es ahora mayor que el segundo y en la ejecución anterior era menor o igual. ta.crossunder es su equivalente descendente.

La igualdad actual aún no es un cruce. Si el primer valor solo alcanza al segundo, > no es verdadero. La igualdad en la vela anterior, en cambio, sí permite que el paso actual por encima cuente como cruce.

El cruce de dos medias móviles

Seguiremos con las dos medias del capítulo Medias móviles. La más corta y rápida será azul; la larga y lenta, naranja. Un triángulo verde marca el cruce ascendente de la rápida y uno rojo el descendente.

Crea cross_signals.py:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, location, plot, plotshape, script, shape, ta


@script.indicator("Average Crossings", overlay=True)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)
    plotshape(crosses_up, "Cross up", style=shape.triangleup,
              location=location.belowbar, color=color.green)
    plotshape(crosses_down, "Cross down", style=shape.triangledown,
              location=location.abovebar, color=color.red)

Ejecútalo con los datos de demostración y los valores predeterminados 5 y 20. Las marcas aparecen solo en las velas con cruce. En un tramo largo donde la línea azul permanezca sobre la naranja, no habrá una nueva señal verde en cada vela.

El gráfico de cross_signals.py muestra medias rápida y lenta con marcas de cruce verdes y rojas.
Los cruces de las dos medias móviles aparecen como eventos individuales.

¿Por qué calculamos el cruce en líneas separadas?

ta.crossover y ta.crossunder se ejecutan en cada vela. Así su ejecución anterior corresponde a la vela procesada anterior.

Si llamaras al cruce solo cuando se cumple otra condición, su estado anterior no vendría necesariamente de la vela anterior. La línea dibujada y la marca podrían estar examinando series temporales diferentes.

Por eso seguimos la regla del capítulo anterior: calculamos los resultados con estado en cada vela y después decidimos con los valores obtenidos.

Aquí también se nota el calentamiento

La SMA de veinte solo es válida desde la vigésima vela. En su primer valor válido aún falta la SMA anterior, por lo que no hay dos velas completas con las que decidir un cruce.

La condición necesita los valores de ambas medias tanto en la vela actual como en la anterior.

No conviene sustituir na por cero para obtener una señal. Una media cero podría generar un cruce artificial donde todavía no se puede calcular la media real.

Cuándo se conocen los datos

En el libro ejecutamos los programas sobre velas históricas cerradas. Una señal calculada con el cierre diario utiliza información conocida al cerrar esa vela.

El cierre de una vela que aún se está formando puede cambiar. Un cruce observado durante ella puede desaparecer al terminar. No lo confundas con comprobar velas cerradas.

Una señal en un gráfico histórico no implica automáticamente una operación ejecutada en esa misma vela. El indicador dibuja una señal; definiremos las órdenes y el momento de ejecución al estudiar estrategias.

Pruébalo por tu cuenta

Crea una copia llamada price_crossings.py. En vez de marcar el cruce de las medias, marca cuándo el cierre cruza por encima o por debajo de la media lenta. Conserva esa media en el gráfico.

Solución del ejercicio
crosses_up = ta.crossover(close, slow_average)
crosses_down = ta.crossunder(close, slow_average)

Las marcas usan las dos variables lógicas, así que no necesitas modificar las líneas plotshape. Conviene cambiar los títulos a Price cross up y Price cross down.

Si ya no utilizas la media rápida, elimina su cálculo, su dibujo y su input. Así la interfaz ofrece solo el ajuste que se usa realmente.

Sigue un cruce paso a paso

Selecciona una vela con marca verde. Observa los valores de ambas líneas en ella y en la anterior. Expresa las dos comparaciones que hicieron verdadera la señal. Esta comprobación también sirve para revisar una estrategia.