Categorías
Programación Strategy Builder

Variables en el Strategy Builder

Creación de Variables en el Strategy Builder y edición del código para incluir cálculos aritméticos y lógicos con las variables.

Para ver cómo cómo crear y configurar Variables en el Strategy Builder usaré el siguiente caso práctico.

Se vigilará el precio entre una HoraDesde y una HoraHasta, y si el precio alcanza a recorrer una cantidad X a partir de la HoraDesde, se realizará una acción determinada; que puede ser una compra/venta, cerrar una posición abierta, etc.

Desplazamiento del precio

En la imagen anterior se representa un intervalo horario HoraDesde y HoraHasta, el precio P al inicio del intervalo, y el precio Q que se espera alcanzar para desencadenar la acción.

Para este ejemplo, la acción que tomaremos será simplemente la de imprimir un aviso en la ventana Output.

Se usará una variable para guardar el precio en el instante HoraDesde. Finalmente se editará el código para calcular la diferencia entre el precio corriente y la variable.

Para poder seguir adecuadamente el presente artículo, el lector debe estar familiarizado con la creación de estrategias automáticas mediante el Strategy Builder. En el artículo sobre el Strategy Builder encontrará más detalles sobre el funcionamiento de este asistente.

También puede consultar el artículo sobre cómo crear y configurar intervalos horarios en el Strategy Builder.

Y aquí encontrará la documentación oficial de NinjaTrader 8 sobre el Strategy Builder.


Inputs y Variables

Abrimos el asistente desde el menú New / Strategy Builder. Y vamos recorriendo los diferentes pasos hasta llegar al apartado de Inputs y Variables.

Strategy Builder Inputs & Variables

Creación de los Inputs

Hay que crear inputs para el intervalo horario y para el umbral de movimiento.

Para crear el intervalo horario el lector puede seguir las explicaciones del artículo de creación y configuración de intervalos horarios en el Strategy Builder. Tenemos que llegar al estado que se observa en la siguiente imagen.

Strategy Builder. Añadir Inputs

Entonces pulsamos en la etiqueta add en el bloque de Inputs para crear un nuevo parámetro para el umbral del movimiento. El umbral de movimiento es lo que queremos que se mueva el precio desde la HoraDesde, para provocar la acción. Como va a medirse en puntos, el Type tiene que ser double. Por ejemplo asignamos un 2 por defecto.

Strategy Builder. Configurar Inputs

Creación de la Variable

A continuación pulsamos en la etiqueta add en el bloque de Variables, para crear la variable que guardará el precio en el instante HoraDesde. La llamamos PrecioDesde y de tipo double.

Strategy Builder. Añadir Variables

Una vez configurados los parámetros de entrada y las variables en el Strategy Builder, pulsamos en Next para ir al siguiente paso de Conditions and Actions.

Strategy Builder. Inputs y Variables

Condiciones y Acciones

En este paso de Conditions & Actions recreamos las mismas condiciones y acciones que en el artículo de creación y configuración de intervalos horarios en el Strategy Builder. El resultado de la configuración debe quedar como se muestra en la imagen siguiente.

Strategy Builder. Conditions & Actions

Si la barra corriente se encuentra dentro del intervalo horario configurado, simplemente se imprimirá un mensaje en la ventana Ouput.

Asignación de valor a la variable

Ahora tenemos que añadir la condición para asignar el precio a la variable PrecioDesde. Es decir, cuando el Time de la barra corriente coincida con la HoraDesde, se asignará el precio Close de la barra corriente a la variable. Esta condición es independiente de las anteriores relativas al intervalo horario, así que se creará en otro grupo. Para crear un nuevo grupo se pulsa en el botón + a la derecha de la pestaña Set 1

Dentro del nuevo grupo Set 2, procedemos a crear la condición pulsando en la etiqueta add del bloque de Condiciones.

Strategy Builder. Añadir Conditions

La condición es que el Time de la barra corriente sea igual que el valor del parámetro HoraDesde. Y pulsamos OK para cerrar el diálogo.

Strategy Builder. Configurar condición

La condición quedaría como se muestra en la imagen siguiente. Ahora configuramos la acción, que consistirá en asignar el valor a la variable. Pulsamos en la etiqueta add para abrir el diálogo de acciones.

Strategy Builder. Añadir Actions

Abrimos la carpeta Misc y seleccionamos el elemento Set PrecioDesde. En la sección inferior pulsamos en la etiqueta set para elegir qué dato asignamos a la variable PrecioDesde.

Strategy Builder. Action Set

Queremos asignar a la variable el valor del precio de la barra en ese instante, así que abrimos la carpeta Price y seleccionamos Close. Salimos con OK.

Asignar de valor a la variable

De nuevo pulsamos en el botón OK.

Asignación de valor a la variable

Reordenar los Sets

Llegados a este punto, hay dos bloques de condiciones:

  • Set 1: para decidir si la barra corriente se encuentra dentro del intervalo horario [Desde,Hasta].
  • Set 2: para decidir si el Time de la barra corriente coincide con el parámetro HoraDesde y en tal caso asignar su precio de cierre a la variable PrecioDesde.

Pero el orden en que deben ejecutarse es al revés, primero debe decidirse si la barra está en la HoraDesde para guardar el PrecioDesde. Y después se irá comprobando el intervalo horario de cada barra. Para intercambiar los Set hay que hacer click en una cualquiera de las dos etiquetas, Set 1 ó Set 2, y sin soltar el botón del mouse arrastrar hacia la otra etiqueta para intercambiar su posición. 

Reordenar Sets

Configuración del umbral de movimiento

Ahora queda por añadir la condición del umbral de movimiento. Tras el intercambio de las pestañas Set, pulsamos en la etiqueta add del bloque de condiciones del Set 2.

Añadir Condition Set 2

Quiero calcular la diferencia entre el precio Close de la barra corriente, y el precio guardado en la variable PrecioDesde, y si esa diferencia es mayor que el parámetro UmbralMovimiento, realizar una acción. El problema es que el Strategy Builder no permite realizar cálculos aritméticos con las variables, sólo permite comparaciones, así que crearé una comparación y luego editaré el código para calcular la resta.

La condición que voy a crear va a ser, por ejemplo, que el precio de cierre sea mayor que la variable PrecioDesde. 

Configurar Condition 2

En cuanto a la acción, voy a cambiar el mensaje de aviso. Selecciono la acción y pulso en la etiqueta edit para cambiar el texto del mensaje. Para consultar cómo personalizar mensajes puede leer este artículo.

Strategy Builder. Edit Action

Ahora se escribirá un mensaje si el Close es mayor que PrecioDesde. Pero lo que pretendo no es eso, sino calcular la diferencia entre el Close y el PrecioDesde y compararla con el parámetro UmbralMovimiento para escribir el mensaje sólo si cumple la condición. A día de hoy, el StrategyBuilder no soporta este tipo de operaciones aritméticas, así que hay que editar el código generado por el asistente.

Pulsamos en el botón View Code para ver el código generado.

Strategy Builder. View Code

Edición del código

Al pulsar en View Code se abre el NinjaScript Editor mostrando el código generado. La línea de código que hay que modificar es la que está resaltada. Ahora no podemos editar nada, porque estamos en modo View. Así que cerramos el NinjaScript Editor.

NinjaScript Editor. View code

Tras cerrar el NinjaScript Editor, regresamos automáticamente al Stratey Builder, y esta vez pulsamos en el botón Unlock Code. Aparece un mensaje de advertencia ya que si desbloqueamos la estrategia no se podrá volver a abrir desde el Strategy Builder; y por lo tanto, cualquier modificación futura deberá realizarse mediante programación desde el NinjaScript Editor.

Strategy Builder. Unlock Code

Aceptamos, y se vuelve a abrir el editor y esta vez ya nos deja escribir. 

Primero comentamos la línea de código que queremos editar añadiendo dos barras inclinadas al inicio de la línea. El comentario hace que esa línea no se ejecute, y así no la borramos para tenerla a mano por si necesitamos restaurarla en el futuro.

A continuación añadimos la nueva línea de código en sustitución de la anterior, para calcular la resta entre el precio corriente, Close[0], y el PrecioDesde. Y si esa resta es mayor o igual que el parámetro UmbralMovimiento, se ejecutará la acción que en este caso es el Print.

Por último pulsamos en el botón Compile para compilar el código y activar la edición realizada. 

NinjaScript Editor. Edit code

Añadir más condiciones y acciones mediante código

El mensaje sólo se mostrará si ha habido un desplazamiento alcista. Si quisiéramos también incluir los desplazamientos bajistas tendríamos que crear un nuevo Set de Condiciones y Acciones desde el Strategy Builder y editarlo del mismo modo que hemos visto.

Pero ya no podemos hacerlo porque hemos desbloqueado la estrategia y no puede abrirse desde el Strategy Builder. Así que o prevemos la situación y creamos un Set 3 antes de desbloquear la estrategia, o bien hacemos un copy+paste del código del Set 2 para crear el Set 3 desde código, y realizamos las modificaciones necesarias, como se demuestra en la siguiente imagen.

También he aprovechado para cambiar el texto de los mensajes. Por último hay que pulsar en el botón Compile para activar los cambios y tener la estrategia disponible para ejecutarla, por ejemplo, desde el Strategy Analyzer y poder comprobar el uso correcto de variables en el Strategy Builder.

NinjaScript Editor. Add new code

Aviso de riesgo !

Este artículo tiene una finalidad didáctica y divulgativa acerca de sus contenidos. En ningún caso se pretende ofrecer al lector un vehículo de inversión o especulación mediante las pautas que aquí se explican, y se desaconseja encarecidamente usar los ejemplos propuestos en un entorno productivo con cuenta real. Observe la claúsula de riesgo a pie de página y el Aviso Legal.

9 respuestas a «Variables en el Strategy Builder»

Hola, muchas gracias por tus artículos, son muy útiles. Una pregunta: Si quiero hacer un contador de operaciones, algo muy simple, solo que incremente en 1 cada vez que tome una operación (Contador = Contador +1). ¿Es posible hacerlo directamente desde el Constructor? (sin tener que desbloquear el código)?

Muchas gracias por la respuesta. Pusé una variable Contador de tipo entero. Desbloqué el código y al cumplirse el Set 1 (donde toma una entrada), puse un Contador++; (junto con algunos mensajes de print, entre ellos el valor del Contador). Extrañamente parece que varias veces entrara al Set 1 porque me puso varios mensajes del valor del contador y lo incremento varias veces (aunque realmente solo tomó una entrada). ¿Cómo puedo hacer que solo se incremente una vez en el set1 ?

Saludos

Sin ver el código es difícil dar una respuesta exacta. Depende de dónde estés incrementando la variable contador.

¿Cómo estableces la variable Calculate? Si trabajas con OnEachTick o con OnPriceChange, el código se ejecutará varias veces durante la formación de la barra.

En cualquier caso, el código siguiente debería solucionarlo, donde después de incrementar la variable Contador se utiliza una variable Boolean para no repetir el incremento.

Por ejemplo:

// Esta declaración hay que hacerla al comienzo
// del código. Por ejemplo justo encima del
// método OnStateChange, antes de la siguiente
// línea de código estándar:
// protected override void OnStateChange()

private bool done_increment = false;

// Antes de incrementar el contador comprueba
// si ya lo has hecho con el siguiente IF:

if(done_increment == false)
{
contador++
done_increment = true;
}

Espero que te sirva. Saludos

PD: Ten en cuenta que ya no se volverá a incrementar la variable. Si no quieres eso, en algún lugar tendrías que reiniciar a false el booleano. Por ejemplo cuando vuelvas a estar FLAT, en la siguiente barra, etc. Depende del programa.

hola muchas gracias por el articulo me a ayudado muchísimo, quisiera saber al construir una estrategia puedo agregarle dentro de esta un atm para que lo ejecute cuando cumpla los parámetros. gracias

De nada David, me alegro de que el artículo te haya resultado útil. En principio sí es posible, en la siguiente página de la ayuda oficial se enumeran todos los métodos disponibles: ATM Strategy Methods. Pero tendrías que hacerlo escribiendo a medida el código dentro de la estrategia, no desde el Strategy Builder.

hola muchas gracias por la ayuda espero poder ponerla con mi estrategia RSi y macd estoy leyendo mucho para aprender mas ya que quiero mejorar en esto gracias nuevamente

Muy buenas! Me encantan vuestros artículos. Ojala hubiera más.

Similar al compañero, yo tengo el problema en que quiero contar, pero lo que quiero contar son velas.

Es decir un indicador me da señal, pues a partir de ese momento el segundo indicador tiene N velas para aparecer, sino la entrada se pierde. Me podrían dar alguna indicación de como realizarlo por favor?

Un saludo, que tengáis un gran día.

Hola Carlos,
lamentablemente con el wizard no podemos incluir operaciones aritméticas. Lo más adecuado cuando nuestros sistemas reclaman más complejidad es programarlos manualmente.

Pero aún así te expongo una solución que aprovecha todo el código generado por el wizard y sólo al final requiere de una pequeña edición de código.

Lo primero es crear una variable en el apartado Inputs & Variables del StrategyBuilder. Por ejemplo la llamo MyVar01, de tipo int y por defecto un valor de -1. Esta variable guardará el valor de la CurrentBar cuando el primer indicador dé la señal.

También creamos un parámetro de entrada llamado Param01 para que el usuario informe el máximo número de barras permitido entre las señales de los dos indicadores.

Voy a suponer que tienes un primer Set-1 en el apartado Conditions & Actions donde se decide si un primer indicador A da señal. En ese caso crearás una Action (o aprovecharás la que ya tengas) y asignarás a la variable MyVar01 el valor de la CurrentBar actual. Todo esto lo puedes hacer desde el asistente. En la carpeta Misc de Actions verás una entrada Set Myvar01 para asignar el valor a la variable, que como digo será el de la CurrentBar (que a su vez la encontrarás dentro de otra carpeta Misc).

Sigo suponiendo que tienes un segundo Set-2 en el apartado Conditions & Actions donde se decide si un segundo indicador B da señal y en ese caso evaluar la diferencia entre MyVar01 y la CurrentBar corriente, y si es menor que el valor introducido por el usuario en el parámetro Param01, se produciría el envío de la orden.

Lo más sencillo sería incluir una condición fake para que el asistente cree el código que luego editaremos. Así pues crearíamos en el wizard una condición compuesta, por un lado para evaluar la señal del indicador B y por otro que el valor de MyVar01 sea mayor que CurrentBar (esta última condición es fake porque no es lo que pretendemos, pero a continuación la corregiremos editando el código).

Después abrimos el código y donde aparezca la condición de MyVar01 > CurrentBars[Default input], la cambiamos por el siguiente código:

if( MyVar01 != -1 && (CurrentBar - MyVar01) < Param01 )
{
// Actions ...
}

Dentro de las llaves del IF irían las acciones que ya habría creado el wizard y simplemente podríamos hacer un copy+paste.
Luego, cada vez que el sistema cierre la posición y quede Flat tendrías que inicializar el valor de MyVar01 a -1.

Espero que te sirva. Saludos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

  Acepto la política de privacidad