Curso Gratuito - Trading IA

Tradestation - Proyecto Scalping

Manuel
Manuel 109 puntos
editado septiembre 2023 en Plataformas

Hola, os comparto cómo estructuré mi proyecto de estrategia para scalping en Tradestation.

https://drive.google.com/file/d/11xTRwjzBK7CeEnJm9qkyyc2Kp9ELqJtY/view?usp=sharing

Veréis so aficionado a hacer funciones para separar código por organizarme mejor.

¿Queréis comentar alguno de estas funciones?

Saludos.

Comentarios

  • Impresionante Manuel, todas estas funciones son las que nos enseña Luis en el apartado de scalping o has implementado alguna que tú has visto destacable?

  • Luismi
    Luismi 224 puntos
    editado septiembre 2023

    Ponnos un ejemplo,lo que tiene la función,lo que se consigue con ella,que supongo es una parte de código,a la que luego poder llamar sin repetir el código

    Y como se le llama a la función en el código,que siempre dais por supuestas cosas que luego no sabemos 🤗

  • Manuel
    Manuel 109 puntos

    Ok, doy una visión general y después ya podemos ir desgranando un poco más el código.

    Que sepáis quen no lo hago solo para que podáis verlo, también para que lo comentéis y veamos qué cosas podemos mejorar. Quizás en código no podáis pero seguro que hay cosas que mejorar en el algoritmo.

    Otra cosa, esta visión general la voy a hacer en público, pero creo que el detalle lo haré en categorías privadas.

    El código que se ve en la imagen incluye tres indicadores:

    1. Giros: muestra sobre el precio si se ha identificado un giro pintando las velas.
    2. Intention: pinta las velas de intención.
    3. Ind_VolumeStudy: muestra en un subgráfico el volumen y los niveles de estudio.

    La estrategia está implementada sobre "Strategy.AllSignals", que como el nombre indica es una aplicación de tipo Strategy. Esto permite lanzar órdenes a mercado desde ella.

    El flujo principal del progama es el siguiente:

    1. Define entradas (Inputs).
    2. Define métodos.
    3. Inicializa variables
    4. La primera ejecución inicializa arrays de parámetros de los setups y carga los parámetros de la red neuronal.
    5. Calcula el estudio del volumen con la función _VolumeStudy.
    6. Calcula rango de precio con PriceRangeStudy.
    7. Comprueba si estamos dentro del horario de operativa llamando a la función InSession.
    8. Si estamos en horario:
      1. Calcula los parámetros del contexto con la función SessionContext.
      2. Comprueba los posibles giros con CheckTurn
      3. Comprueba intención con IntentionStudy
      4. Ejecuta las funciones de los distintos setups: SetupPOCBreak, SetupStopVolume, SetupStructure_v2, SetupRangeTurn, SetupPrePocTurn.
      5. Una vez ejecutados todos los setups la función TradeAdmin recoge todos los parámetros calculados y comprueba si hay una señal de entrada.
      6. Pasamos los parámetros a la red neuronal con NNETPredictParams.
      7. Realizamos la predicción con Init_NNet.
      8. Con los datos de TradeAdmin y Init_NNet, se ejecuta la función TradeConfirm que comprueba posibles parámetros de confirmación y ajusta takeprofit y stoploss devolviendo los datos necesarios para lanzar una operación.
      9. Si hay operación se lanza.
    9. Comprobamos si hay una operación abierta
      1. ajustamos profit y stoploss
      2. cerramos si hemos llegado al final del horario de operativa.

    El algoritmo funciona, detecta los setups y ejecuta correctamente las entradas. Faltaría una gestión activa de operaciones (si se quiere así).

  • Luismi
    Luismi 224 puntos

    Ni me habia fijado si estabamos en publico o no, como siempre escribimos los mismos, pero pe parece bien guardar un poco de privacidad,es logico

    Luego me pongo con lo que has puesto, pero te adelanto que me saldran preguntas sobre ello🤣

  • Luismi
    Luismi 224 puntos
    editado septiembre 2023

    Bueno , a ver si he entendido algo:

    Has creado un proyecto "Scalping", yo esto no lo habia hecho, no se que me aportara pero parece facil, supongo para tener todo lo relacionado con el codigo ordenado

    El codigo luego lo has dividido en funciones, que parece interesante, porque aporta 2 cosas si creo es asi:
    1-Tienes el codigo ordenado en trozos y cuando vas a ver algo no te pasas bueceando por las lineas(como hago yo)
    2- Si hay cosas que se repiten se podra llamar a la funcion con sus parametros(aqui ni idea todavia de como), como si fuese un RSi o algo asi

    El "StrategyAllSignals" es el strategy que manda las señales,( yo estoy haciendo un strategy con tooodo el codigo,y algun showme para ver graficamente mas cosas)

    Me gustaria ver un ejempo de como hacer lo de las funciones y como poder implementarlo

    La parte:
    2.Define metodos y
    4. La primera ejecucion inicializa arrays de parametros de los setups y carga los parametros de la red neuronal


    me suenan a chino, supongo es la parte donde se meten los parametros que da la red neuronal(que supongo se hara cada 3 o 4 semanas o cuando sea)
    Esto creo que tranquilamente lo podemos dejar para mas adelante

    Si quieres pasamos estas cosas a un post distinto, privado

    *Por cierto como os gustan a los programadores poner las cosas en ingles, ni una variable en español tiene el tio😂

  • Manuel
    Manuel 109 puntos
    editado septiembre 2023

    Hola, respuesta rápida:

    Cuando creas un proyecto puedes exportarlo en un único fichero y hacer una copia de seguridad. Al exportar se guardan todas las funciones del proyecto y todas de las que dependa esto es super interesante.

    Sobre todo si tienes 15 o 20 funciones en el proyecto más las propias de easylanguage.

    Las plabras en inglés (pocas veces uso español) es por compatibilidad con los lenguajes de programación :).


    El resto te lo respondo en otro Post.

    Saludos.

  • Manuel
    Manuel 109 puntos

    Hola, "Define métodos" es la parte en la que se definen porciones de código que se repiten o simplifican la lectura del código.

    Realmente lo que en Easylanguage llamamos Funciones son clases en las que podemos definir métodos. Por ejemplo, en tu estrategia "Strategy" probablemente tengas bloques de código que se repiten o que te gustaría sustituir por una sola palabra para simplificar.

    La definición de métodos facilita también el mantenimiento y depuración del código, porque si tienes bloques de código que se repiten probablemente tendrás que hacer un mismo cambio en varias partes del programa y seguro que alguna vez se olvidará alguna.

    Hay una restricción en easylanguage para definir métodos y es que deben definirse antes que cualquier otra sentencia de ejecución (es decir muy al principio).

    Cómo organices tu código es cosa personal, pero hay "códigos de buenas prácticas" que recomiendan usar métodos, funciones, clases, estructuras y todo tipo de declaraciones que faciliten el mantenimiento y legibilidad.

    Esta sería una estructructura de funció con métodos:

    { Declaramos las clases del entorno que vamos a necesitar }
    Using elsystem;
    Using ****
    
    { La directiva region nos ayuda a organizar el código, podrás ver estas regiones después en la ventana 
      "Outline" 
      Comenzamos las declaraciones }
    #region Declarations
    Const:
    String LOG ("….");
    Vars:
    int n (0);
    Array:
    double Inputs [] (0);
    #endregion
    
    { Ahora declaramos los métodos. Pueden devolver un valor o ser de tipo void. Son muy similares a las
      funciones. Algo particular es que hay que declarar las variables antes del bloque "Begin .. End" }
    #region Methods
    Method bool inSession()
    Vars: bool result;
    Begin
    result = "…..";
    Return result;
    End;
    #endregion
    
    { Este bloque se ejecutará solo en la primera ejecución, solo una vez. Es muy útil para la inicialización
      de variables y la carga de datos desde ficheros. }
    #region FirstExecutionCode
    Once Begin
    "…."
    End;
    #endregion
    
    { Ahora ya comienza el programa principal, en el que podemos hacer uso de las variables y métodos
      declarados. Fíjate cómo hacemos uso del método inSession() que nos devolverá true en caso de
      estar dentro del horario de operativa. }
    #region MainProgram
    If inSession() Then
    Begin
    "….."
    End;
    #endregion
    
    

    Fíjate cómo el código bien organizado puede ser múcho más fácil de entender y mantener.

    Espero sea de ayuda.

    Saludos.

  • Luismi
    Luismi 224 puntos
    editado septiembre 2023

    Conmigo tienes que empezar mas sencillo, he intentado hacer una funcion sencilla, Sesion si estamos en sesion o no , y me dan errores por todos los lados

    Veo que al estar en funcion hay que declarar los tipos de valores en las inputs, en las variables parecidos, pero me da error con casi cualquier cosa y y no me queda claro como llamas a la funcion desde el codigo.

    Si puedes poner un ejemplo con sus letritas para ver algo del funcionamiento y poder intentarlo…

    Lo de los metodos y tal no se si sale de mi entendimiento, alomejor es facil pero no se ni por donde empezar. A mi con poder hacer funciones o lo que sea que me coloquen trozos de codigo y luego en el codigo si se hacen referencias a ello , eso es lo que me parece muy interesante

    Si no acabamos antes con tu paciencia claro😂

  • Manuel
    Manuel 109 puntos

    Hola,

    una función tiene unos parámetros de entrada y un valor de salida.

    La declaración de los parámetros de entrada es:

    Inputs:
    RegularSessionStartTime(Numeric),
    RegularSessionEndTime(Numeric);

    Aquí declaras dos parámetros de entrada de tipo "Numérico" (en la ayuda podrá ver los tipos que puedes declarar).

    Esto quiere decir que cuando llames a esta función deberás pasar estos dos parámetros.

    El varlo de salía debes establecerlo en las propiedades de la función con un click derecho sobre el nombre de la fución.

    Esta podría ser una función que determine si estás dentro del horario de sesión:

    Inputs:
    RegularSessionStartTime(Numeric),
    RegularSessionEndTime(Numeric);

    InSession = (Time >= RegularSessionStartTime) and (Time <= RegularSessionEndTime);

    Le pasas las horas de inicio y de fin y te devolverá verdadero o false según la vela actual esté o no dentro de esas horas. Por ejemplo: InSession(1531,2130);

    La función debe llamarse InSession, para que sea correcto el código.

    Los métodos te los explico en otro post.

    Saludos.

  • Manuel
    Manuel 109 puntos
    editado octubre 2023

    Hola, continúo con los Métodos.

    Las funciones son útiles para organizar el código y que puedas utilizarlas en diferentes estrategias, indicadores, etc. Si no creas funciones tendrás que escribir el código cada vez que necesites una funcionalidad.

    Pues bien, los métodos son útiles para organizar el código dentro de una función. En el ejemplo que te puse del horar o de la sesión "InSession" no tiene sentido, pero tengo funciones con más 600 líneas de código. En este tipo de funciones es muy común que tengas pequeñas porciones de código que necesites en distintos puntos de la función. Una muy común es para imprimir en el Log.

    Por ejemplo, en varios puntos del código de la función del setup de estructrura me gusta imprimir ciertos datos. Puedes escribir esta sentencia:

    PrintLog(
    " SetupStructure_v2",
    " " + message +" "+
    " Giros: " + NumToStr(Structure.Count,0) +
    " Start: " + Numtostr(Time[CurrBar-(Structure[0] Astype double)],0) +
    " Giro 1: " + Numtostr(Time[CurrBar-(Structure[1] Astype double)],0) +
    " Giro 2: " + Numtostr(Time[CurrBar-(Structure[Structure.Count-1] Astype double)],0) +
    " Ctrl Price: " + Numtostr(StructureControlPrice,2) +
    " TP Price: " + Numtostr(StructureTakeProfitPrice,2) +
    " SL Price: " + Numtostr(StructureStopLossPrice,2) +
    " i1Len: " + NumToStr(i1Len,0) +
    " i2Len: " + NumToStr(i2Len,0) +
    " ptLen: " + NumToStr(ptLen,0) +
    " ptRatio: " + NumToStr(PTRatio,2) +
    " ptLenRatio: " + NumToStr(PTRLenRatio,2) +
    " Crl Violts.:" + Numtostr(ControlPriceViolations,0)
    );

    Seguramente lo hagas con copia y pega, pero como quieras añadir algo te va a tocar ir por cada línea cambiándolo.

    Si escribes un método:

    Method void PrintStructure(string message)
    Begin
    If debug And Structure.Count>1 Then
    Value99 = PrintLog(
    " SetupStructure_v2",
    " " + message +" "+
    " Giros: " + NumToStr(Structure.Count,0) +
    " Start: " + Numtostr(Time[CurrBar-(Structure[0] Astype double)],0) +
    " Giro 1: " + Numtostr(Time[CurrBar-(Structure[1] Astype double)],0) +
    " Giro 2: " + Numtostr(Time[CurrBar-(Structure[Structure.Count-1] Astype double)],0) +
    " Ctrl Price: " + Numtostr(StructureControlPrice,2) +
    " TP Price: " + Numtostr(StructureTakeProfitPrice,2) +
    " SL Price: " + Numtostr(StructureStopLossPrice,2) +
    " i1Len: " + NumToStr(i1Len,0) +
    " i2Len: " + NumToStr(i2Len,0) +
    " ptLen: " + NumToStr(ptLen,0) +
    " ptRatio: " + NumToStr(PTRatio,2) +
    " ptLenRatio: " + NumToStr(PTRLenRatio,2) +
    " Crl Violts.:" + Numtostr(ControlPriceViolations,0)
    );
    End;

    Puedes añadir en cada parte de tu código que quieras mostrar esta información una llamda a este método: PrintStructure("Texto explicativo");

    Los métodos son muy útiles para tener un código bien organizado, totalmente recomendado utilizarlos.

    Saludos.

  • Luismi
    Luismi 224 puntos

    Bueno, lo seguire intentano, ya te contare

    Muchas gracias, es muy interesante,porque a poco que organice el codigo a la larga me servira para cualquier codigo.

  • Luismi
    Luismi 224 puntos

    Para el que como yo se pelea con los códigos un artículo que habla de la programación de objetos

  • Manuel
    Manuel 109 puntos

    Es una pena que Easylanguage no permita usar la mayoría de las características de la programación orientada a objetos.

  • enormi
    enormi 183 puntos

    Pues el caso es que he encontrado una información que dice que hay dos tipos de Easylanguage.

    • EasyLanguage convencional: Este es el EasyLanguage de siempre, un clásico, una referencia. Es al que nos hemos referido en esta Review. Está basado en C# pero su orientación al trading es tal que tiene ya resueltos muchos problemas que nos solemos encontrar al programar sistemas con otros lenguajes. Es un lenguaje sencillo y apto para no programadores.
    • EasyLanguage Objects: Se lanzó en 2010 para extender las posibilidades de EasyLanguage con la programación orientada a objetos. Es muy parecido a Visual Basic .NET y con él se puede acceder a cualquier símbolo o dato mediante el código, aunque no esté en el chart, colocar órdenes desde indicadores, acceder a datos reales de la cuenta o posiciones, etc.

    Así que es posible que lo que querías, sí que esté disponible.

    Espero que te sirva esta información y que nos cuentes qué tal. Si alguien tiene información al respecto, que por favor nos lo comparta.

  • Manuel
    Manuel 109 puntos

    Easylanguage convencional dice que está basado en C#, que es un lenguaje orientado a objetos.
    Creo que la versión de Easylanguage que he usado es la orientada a objetos. Es verdad que está estructurado en torno a clases y métodos, pero no he encontrado la forma de crear clases nuevas, usar la herencia, el polimorfirsmo y otras características de la orientación a objetos.

    Buscaré información sobre esto a ver si encuentro algo.