Lo que recuerda el programa
Cuenta los cruces con una variable Persistent y distingue el estado del historial.
La marca de cruce muestra dónde ocurrió un evento. Para saber también cuántos han ocurrido desde el principio de los datos, el programa necesita recordar el valor de un contador.
¿Por qué no basta una variable normal?
Estas líneas reinician la cuenta en cada vela:
count = 0
count += 1La primera asigna cero cada vez que se ejecuta main(). La segunda suma uno, así que el resultado final es 1 en todas las velas.
+= es una asignación abreviada: count += 1 expresa lo mismo que count = count + 1. Primero lee el valor anterior, suma uno y guarda el resultado en la variable.
Para acumular eventos necesitamos otro inicio. Queremos asignar cero solo al crear el contador por primera vez.
La variable Persistent
count: Persistent[int] = 0Persistent indica que conservemos el valor entre velas. El cero inicial establece la variable una sola vez. En la siguiente vela continuamos con el valor conservado de la última vela cerrada.
int indica el tipo entero del contador. Importamos Persistent desde pynecore, igual que antes Series.
La anotación no guarda datos en el disco. Una nueva ejecución comienza otra vez al principio de los datos, con el contador a cero. Hablamos de conservarlo entre velas dentro del programa.
Cuenta los cruces ascendentes
Crea event_counter.py:
"""
@pyne edge
"""
from pynecore import Persistent
from pynecore.lib import close, color, plot, script, ta
@script.indicator("Crossing Counter", overlay=False)
def main():
fast_average = ta.sma(close, 5)
slow_average = ta.sma(close, 20)
crosses_up = ta.crossover(fast_average, slow_average)
count: Persistent[int] = 0
if crosses_up:
count += 1
plot(count, "Crossing count", color=color.blue, linewidth=2)Ejecútalo con los datos de demostración. El contador del panel separado empieza en cero. Sube uno en cada cruce ascendente y permanece igual entre ellos.

Si el último valor es 12, por ejemplo, significa que hubo doce cruces ascendentes en todos los datos procesados. El breve período visible en pantalla puede contener menos señales. Ampliar el gráfico no reinicia el contador.
Estado e historial
Las dos anotaciones cumplen tareas distintas:
| Anotación | ¿Qué le pedimos al entorno? |
|---|---|
Series[float] | Poder consultar los valores anteriores de cada vela |
Persistent[int] | Empezar la siguiente vela con el valor almacenado |
La asignación de una variable Series se ejecuta en cada vela y los valores resultantes forman un historial. La asignación inicial de Persistent ocurre una sola vez; después, las modificaciones del código hacen avanzar su estado.
Para consultar directamente un valor anterior de un contador, puedes poner su valor actual en otra variable Series. Conservar valores e indexar valores pasados son cuestiones distintas.
Dónde declarar la variable persistente
Declaramos el contador antes de la condición, donde está disponible en cada vela. Así tiene valor aunque no se cumpla la condición y plot puede representarlo siempre.
No crees un contador global mutable normal encima de main(). Describe el estado entre velas con la anotación, en el lugar donde se usa.
La ejecución histórica que estudiamos calcula una vez por vela. En un modo que evalúa varias veces una vela, Persistent vuelve a partir del estado de la vela cerrada anterior. Por eso no cuenta todas las ejecuciones técnicas. Usamos el contador para eventos de velas cerradas.
Una condición también puede reiniciar el valor
Al contar velas alcistas consecutivas, puedes poner el contador a cero en una bajista o en una con apertura y cierre iguales:
if close > open:
streak += 1
else:
streak = 0Antes debes crear streak con Persistent[int]. Aquí el reinicio es una operación condicional deliberada. No ocurre automáticamente al principio de cada vela.
Pruébalo por tu cuenta
Añade un segundo contador persistente. Debe contar los cruces descendentes y aparecer como una línea naranja. Ambos cálculos deben ejecutarse en cada vela.
Solución del ejercicio
Junto al cálculo del cruce ascendente:
crosses_down = ta.crossunder(fast_average, slow_average)
down_count: Persistent[int] = 0
if crosses_down:
down_count += 1
plot(down_count, "Downward count", color=color.orange, linewidth=2)Conserva count y su dibujo. Los contadores son independientes. Una nueva ejecución reconstruye ambos desde cero.
Compruébalo en una señal
Compara las marcas del capítulo sobre cruces con los cambios del contador sobre los mismos datos. En la vela del cruce ascendente debe subir exactamente uno. Solo puede volver a subir en la siguiente si ocurre otro cruce ascendente.