Acceder

La función Easylanguage: una belleza


El concepto de alcance cuando se trata de un lenguaje de programación puede resultar muy confuso muy rápidamente. Si eres nuevo en la programación y crees que Scope es un enjuague bucal, no te preocupes. Daré una explicación completa de Scope en términos de programación con la ayuda de ChatGPT. Su respuesta está en cursiva.
Recientemente conversé con ChatGPT sobre Scope en términos del lenguaje de programación Python.
En Python, el alcance de una variable se refiere a la región del programa donde se puede acceder o hacer referencia a esa variable. Hay dos tipos de ámbitos en Python: ámbito global y ámbito local.
Aquí hay un ejemplo que demuestra el concepto de alcance en Python:
# global variable
x = 10

def my_func():
    # local variable
    y = 5
    print("x inside my_func:", x)  # x is accessed from the global scope
    print("y inside my_func:", y)  # y is accessed from the local scope

my_func()

print("x outside my_func:", x)  # x is accessed from the global scope
print("y outside my_func:")  # y is not defined in the global scope, so this will raise a NameError
Ejemplo de alcance demostrado por Chat-GPT
En este ejemplo, definimos una variable global x con un valor de 10.
Luego definimos una función my_func que tiene una variable local y con un valor de 5. Dentro de la función, imprimimos los valores de xey. Se accede a la variable x desde el ámbito global, lo que significa que se puede hacer referencia a ella desde cualquier parte del programa.
La variable y, por otro lado, solo es accesible dentro de la función, que es el ámbito local. Fuera de la función, imprimimos nuevamente el valor de x, al que aún se puede acceder desde el ámbito global. Sin embargo, cuando intentamos imprimir el valor de y, obtenemos un NameError porque y no está definido en el ámbito global.
Bueno, eso fue bastante formal. En términos más simples, una variable declarada dentro de una función sólo puede verse dentro de esa función, a menos que esté declarada globalmente. Otra cosa de Scope, es que las variables tienen amnesia. Una vez que sales de la función, la variable olvida cuál era y no puedes hacer referencia a su valor anterior al regresar a la función.
A menos que sea una función de EasyLanguage. El alcance todavía está limitado por una función EasyLanguage, porque es una pieza de código separada que se encuentra dentro de la biblioteca de Técnicas de análisis. La mayoría de las veces no puedes ver lo que hay en la función a menos que la abras con ELEditor. Sin embargo, las variables que se definen dentro de la función no sufren de amnesia. Si necesita hacer referencia a un valor anterior de una variable declarada localmente, puede hacerlo. Este tipo de función es lo que EasyLanguage llama función serie. El único inconveniente de esta función es que ralentiza bastante el procesamiento.
Bueno. Para abreviar la historia, quería mostrar la magia de la función EasyLanguage con la que he estado trabajando en un proyecto. Este proyecto incluye algunas de las funciones de análisis de ciclos de Ehlers. La que voy a discutir hoy es la función HighRoof; no te preocupes, no voy a entrar en detalles sobre lo que hace esta función. Si quieres saberlo, búscalo en GOOGLE o pregúntale a ChatGPT. Desarrollé una estrategia que utilizó la función en los últimos 25 días de datos de precios de cierre. Luego me di la vuelta y envié la salida de la primera pasada de la función HighRoof directamente a la función HighRoof. Algo similar a incrustar funciones.
doubleSmooth = promedio(promedio(c,20),20);
Algo así como una media móvil doblemente suavizada. Después de hacer esto, comencé a pensar: ¿la función recuerda los datos de su respectiva llamada? La primera pasada utilizó datos de precios de cierre, por lo que sus variables y su historial deberían estar en términos de datos de precios. El segundo paso utilizó los datos de movimientos cíclicos generados por la llamada inicial a la función HighRoof. Todo salió bien, la función recordó los datos correctos. O parecía que así era. Así es como aprendes sobre cualquier lenguaje de programación: saca tu SandBox y haz algunas pruebas. En primer lugar, aquí está mi conversión de la función HighRoof de Ehlers en EasyLanguage.
//Ehlers HiRoof
 Inputs: dataSeries(numericseries),cutPeriod(Numeric);
 
 Vars:   a1(0), b1(0), c1(0), c2(0), c3(0), Filt(0), Filt2(0),
         alpha1(0),oneMinusAlpha1(0), highPass(0),myhp(0),degrees(0);
 Vars: numTimesCalled(0);   

//Highpass filter cyclic components whose periods are shorter than 48 bars

numTimesCalled = numTimesCalled + 1;

print(d," numTimesCalled ",numTimesCalled," highPass[1] ",highPass[1]," highPass[2] ",highPass[2]," highPass[3] ",highPass[3]);
degrees = .707*360 / CutPeriod;

alpha1 = (Cosine(degrees) + Sine(degrees) - 1) / Cosine(degrees);

oneMinusAlpha1 = 1-alpha1;
 
highPass = square(oneMinusAlpha1/2)*(dataSeries-2*dataSeries[1]+dataSeries[2]) +
  2*(oneMinusAlpha1)*highPass[1]-square(oneMinusAlpha1)*highPass[2];
 
 
 
EhlersHighRoof=highPass;
Función de techo alto de Ehlers
Esta función requiere sólo dos entradas: los datos (con un historial) y una longitud simple o un período de corte. La primera entrada es de tipo numericSeries y la segunda entrada es de tipo numericSimple. Verás la siguiente línea de código.
 print(d," numTimesCalled ",numTimesCalled," highPass[1] ",highPass[1]," highPass[2] ",highPass[2]," highPass[3] ",highPass[3]);
This code prints out the last three historic values of the HighPass variable for each function call. I am calling the function twice for each bar of data in the Crude Oil futures continuous contract.
1230206.00 numTimesCalled  494.00 highPass[1]   -0.78 highPass[2]   -0.51 highPass[3]   -0.60
1230206.00 numTimesCalled  494.00 highPass[1]   -0.05 highPass[2]   -0.02 highPass[3]   -0.06
1230207.00 numTimesCalled  495.00 highPass[1]   -0.38 highPass[2]   -0.78 highPass[3]   -0.51
1230207.00 numTimesCalled  495.00 highPass[1]    0.04 highPass[2]   -0.05 highPass[3]   -0.02
1230208.00 numTimesCalled  496.00 highPass[1]    0.31 highPass[2]   -0.38 highPass[3]   -0.78
1230208.00 numTimesCalled  496.00 highPass[1]    0.16 highPass[2]    0.04 highPass[3]   -0.05
1230209.00 numTimesCalled  497.00 highPass[1]    0.49 highPass[2]    0.31 highPass[3]   -0.38
1230209.00 numTimesCalled  497.00 highPass[1]    0.15 highPass[2]    0.16 highPass[3]    0.04
1230210.00 numTimesCalled  498.00 highPass[1]    0.30 highPass[2]    0.49 highPass[3]    0.31
1230210.00 numTimesCalled  498.00 highPass[1]    0.07 highPass[2]    0.15 highPass[3]    0.16
1230213.00 numTimesCalled  499.00 highPass[1]    0.52 highPass[2]    0.30 highPass[3]    0.49
1230213.00 numTimesCalled  499.00 highPass[1]    0.08 highPass[2]    0.07 highPass[3]    0.15
1230214.00 numTimesCalled  500.00 highPass[1]    0.44 highPass[2]    0.52 highPass[3]    0.30
1230214.00 numTimesCalled  500.00 highPass[1]    0.04 highPass[2]    0.08 highPass[3]    0.07
Resultado de llamar a HighRoof dos veces por barra
Comenzando en la parte superior del resultado, verá que en 1230206 la función se llamó dos veces con dos conjuntos de datos diferentes. Como puede ver, la salida de las dos primeras líneas es de diferente magnitud. La primera línea es aproximadamente un orden o magnitud de 10 de la segunda línea. Si va a las líneas 3 y 4, verá que HighPass[1] de las líneas 1 y 2 se mueve a HighPass[2] y luego a HighPass[3]. Creo que lo que sucede internamente es que para cada llamada por barra, las variables para cada llamada a función se colocan en una cola en la memoria. La cola continúa creciendo durante la longitud que sea necesaria y luego se mantiene o se trunca en algún momento posterior.
¿Por qué es esto tan genial?
En muchos lenguajes, la encapsulación de datos con la función requiere programación adicional. La función EasyLanguage podría verse como un "objeto" como en la programación orientada a objetos. Simplemente no sabes que lo estás haciendo. EasyLanguage se encarga de gran parte de la gestión de datos entre bastidores. Para hacer lo mismo en Python, necesitaría crear una clase de Ehlers Roof que mantenga datos históricos en los miembros de la clase y los cálculos se realizarían mediante un método de clase. En el caso de llamar a la función dos veces, crearía instancias de dos clases a partir de la plantilla y cada clase actuaría independientemente una de otra.
Aquí está mi SandBox para indicador
Value1 = EhlersHighRoof(close,25);
plot1(Value1,"EhlersHiRoof");
Value2 = EhlersHighRoof(value1,25);
plot2(Value2,"EhlersHiRoof2");
Zona de juegos Sandbox para la función Ehlers
 
Un último dato. Si va a trabajar con funciones trigonométricas como coseno, seno o tangente, asegúrese de que sus argumentos estén en grados y no en radianes. En Python, debes usar radianes.

Escrito por Quantified Models
t.me/quantifiedmodelstrading
2
¿Te ha gustado mi artículo?
Si quieres saber más y estar al día de mis reflexiones, suscríbete a mi blog y sé el primero en recibir las nuevas publicaciones en tu correo electrónico
  1. en respuesta a Microlector
    -
    #2
    07/09/23 12:50
    Conocimiento de trading.
  2. #1
    07/09/23 10:17
    Que tiene que ver esto con Rankia?
Proveedor de soluciones innovadoras de trading algorítmico e inteligencia artificial. Aportamos toda nuestra experiencia en el diseño, desarrollo e implantación de soluciones algorítmicas y de inteligencia artificial para inversores de todo tipo. TELEGRAM: t.me/quantifiedmodelstrading CONTACTO: [email protected]