Strategy Builder

Asistente para crear sistemas automáticos sin programar código

Introducción

En NinjaTrader los sistemas automáticos de trading se llaman estrategias. El modo más versátil y potente de crear estrategias es mediante programación a medida en lenguaje C# con el editor de código NinjaScript Editor. Pero si no sabemos programar podemos utilizar el asistente llamado Strategy Builder para construir estrategias. Este asistente se abre desde el menú New / Strategy Builder.

Abrir Strategy Builder

Avanzado. NinjaTrader está basado en el framework Microsoft .NET. Además ofrece una librería de clases especializada en trading con muchos tipos públicos y accesibles a los programadores, conocida como NinjaScript. Las clases de .NET y de NinjaTrader se pueden combinar mediante programación en lenguaje C# para dotar a la aplicación de cualquier funcionalidad imaginable: tipos de barra a medida, estilos de chart personalizados, nuevas herramientas de dibujo, comunicación con redes sociales, servicios web, bases de datos propias, Add-Ons, etc. Un Add-On es una aplicación Windows embebida en NinjaTrader. Cualquier herramienta que se pueda programar en Windows con el framework .NET – independientemente de su aspecto y funcionalidad – se puede incluir en NinjaTrader. También podemos personalizar el aspecto y comportamiento de la parte pública de algunas herramientas como el Market Analyzer, DOM o el Strategy Analyzer.

A continuación explico los apartados del Strategy Builder. Algunos pueden resultar complejos o contener mucha información técnica, y refiero al link de la ayuda oficial para encontrar todos los datos al respecto.

Tras abrir el asistente, en la lista de la izquierda aparecen todos los pasos. Para ir a cualquiera de ellos sólo hay que pulsar sobre él. Pulsando en el botón Next se pasaría al siguiente paso de la lista.

Welcome

El primer paso del asistente del Strategy Builder es la bienvenida. En el campo Strategy se muestra una lista desplegable con todas las estrategias que hayamos creado con anterioridad desde el asistente. Si es la primera vez que usamos el asistente el desplegable estará vacío. Por defecto aparece la opción de New strategy … para crear una estrategia nueva.

Strategy Builder. Welcome

Todas las estrategias de la lista desplegable pueden editarse en cualquier momento. Pero si alguna de ellas se modificara desde el NinjaScript Editor – para incluir código personalizado por ejemplo – ya no podría abrirse desde el Strategy Builder y desaparecería de esa lista. En este tutorial no vamos a ver el NinjaScript Editor ya que es un editor para escribir en lenguaje de programación C#.

Pulsando el botón Next pasamos al siguiente apartado General.

General

En el campo Name introduciremos un nombre para la estrategia, que debe comenzar por una letra mayúscula y no puede contener caracteres especiales. En el campo Description podemos incluir una descripción breve del sistema. Pulsamos en Next para ir al siguiente apartado Default Properties.

Strategy Builder. General

Default Properties

En este apartado estableceremos el funcionamiento por defecto de la estrategia. Sin embargo, todos estos valores son configurables por el usuario cuando ejecute la estrategia. Si el subapartado More properties no está desplegado, haz click en el triángulo a su izquierda. En la imagen se muestran los valores por defecto. A continuación explico cada una de las propiedades del Strategy Builder, pero si no quiere entrar en detalles puede ir al siguiente paso Additional Data.

Strategy Builder. Default Properties

Calculate

Es un desplegable para elegir la frecuencia con la que se ejecuta el método OnBarUpdate. Hay tres modos posibles.

  1. On bar close: hasta que la barra corriente no cierra, el código funcional de la estrategia no se ejecuta. Si estuviéramos trabajando en timeframe de 1 hora, el código del método OnBarUpdate sólo se ejecutaría una vez por cada hora.
  2. On each tick: es el modo más intensivo ya que el código se ejecutaría con cada 1-tick entrante. En productos muy negociados y en determinados momentos de la sesión se pueden recibir cientos de ticks por segundo y cada uno de ellos provocaría la ejecución del código. Con el hardware actual esto no debe preocuparnos, incluso si tuviéramos varios sistemas On each tick corriendo simultáneamente.
  3. On price change: el código funcional de la estrategia se ejecuta sólo si se recibe un precio diferente del anterior.

Entries per direction

Informa sobre el número máximo de órdenes permitido por posición abierta. Si por ejemplo vale 2, puedo entrar largo y más adelante volver a comprar con otra orden nueva antes de cerrar la primera. Pero ya no podría enviar una tercera orden de compra. Se refiere a las veces que se entra en la misma dirección, no al tamaño o volumen de esas entradas que puede ser cualquiera. A esta técnica de ir aumentando progresivamente la posición también se le llama scale-in.

Entry Handling

Admite dos valores: AllEntries y UniqueEntries.

  • AllEntries: el número máximo de órdenes de entrada que se pueden enviar para aumentar la posición viene dado por EntriesPerDirection. No importa el nombre de las órdenes.
  • UniqueEntries: la restricción se aplica por nombre de orden. Si por ejemplo EntriesPerDirection vale 1 y he entrado largo con una orden a la que he llamado ComprarSoporte, mientras no cierre esta orden no podré comprar con otra llamada igual, pero sí podré abrir un nuevo largo con otra orden de compra de diferente nombre, como por ejemplo ComprarSoporte99. De hecho podré abrir todos los largos que quiera siempre que el nombre de la orden de entrada sea único. Sin embargo si EntryHandling se hubiera establecido a AllEntries, sólo podría tener un largo abierto sin importar su nombre.

Exit on session close

Si al llegar al fin de la sesión estamos abiertos, la posición se cierra automáticamente y se cancelan las órdenes pendientes.

Exit on session close seconds

Informa de los segundos que deben faltar antes del cierre de sesión, para cerrar automáticamente la posición abierta. Sólo es útil si se marca la opción Exit on session close. Su utilidad es establecer un margen temporal de seguridad para no esperar al cierre del mercado para cerrar la posición abierta.

Fill limit orders on touch

Si se marca, las órdenes limitadas serán filled cuando el precio las toque. Esto sólo afecta al backtesting; en tiempo y cuenta reales las órdenes limitadas serán filled cuando les llegue su turno en la cola del libro de órdenes.

Maximum bars look back

Afecta a la cantidad de datos que se guardan en memoria y eventualmente al rendimiento. Si la estrategia no necesita preguntar por valores de barras pasadas más allá de 256 barras previas, es conveniente establecer el valor del parámetro a 256, y si no, a Infinite.

Minimum bars required

Número de barras históricas que deben existir antes de que la estrategia comience a funcionar.

Order Fill Resolution

Modo en que se produce el filled histórico de las órdenes intrabarra. Sólo afecta al backtesting y por extensión al procesamiento de barras pasadas, no reales.

Strategy Builder. Order Fill Resolution

Supongamos que una estrategia envía una orden de compra a mercado al cierre de la barra A; en histórico el filled se logrará en el precio Open de la siguiente barra B que se corresponde con el 2.789,50 en la imagen – en real puede que no sea filled en el Open, ya que dependerá de la liquidez en el lado Ask del libro de órdenes y de lo rápido que llegue la orden al Exchange-.

Inmediatamente después del filled se envía una bracket de salida compuesta por una orden de take-profit a 4 puntos por encima de la entrada, en el 2.790,50, y una orden de stop-loss a 2 puntos por debajo en el 2.788,50.

Durante el desarrollo de la barra B las dos órdenes de salida logran el filled, pero la cuestión es saber cuál de las dos lo hace en primer lugar. En tiempo real será la primera que haya sido alcanzada por el precio. Pero para averiguar en histórico qué orden de salida logró el filled en primer lugar hay analizar cada tick de esa barra hasta encontrar el primer tick que toca el precio de alguna de las dos órdenes de salida.

Para analizar en detalle los ticks intrabarra hay que elegir la opción Order fill resolution = High. Esta opción obliga a cargar el histórico de 1-tick lo que repercutirá en el rendimiento del backtest. La otra opción Order fill resolution = Standard (Fastest) interpreta el filled en función de los precios OHLC de la barra; es menos precisa que la otra, pero a cambio mucho más rápida ya que no precisa de cargar todo el histórico de 1-tick. Puede encontrar más información en la ayuda oficial del programa: Understanding Historical Fill Processing

Realtime Error Handling

Establece cómo debe comportarse la estrategia cuando una orden es rechazada. Puedes encontrar más información en la siguiente página de la ayuda oficial: Real-time Error Handling.

Slippage

Deslizamiento expresado en ticks que sufrirán las órdenes históricas en su filled. Su finalidad es penalizar los resultados del backtesting para aproximarlos a la realidad.

Start Behavior

Establece el comportamiento de la estrategia en el arranque, basado en el estado de la cuenta. Puede encontrar más información de las distintas opciones en la página oficial Syncing Account Positions.

Stops and Targets

En el mismo instante en que se consigue un filled de una orden de entrada, se puede enviar automáticamente una bracket de salida compuesta por una orden de take-profit más otra de stop-loss. No es necesario que se ejecute el método OnBarUpdate (el filled de una orden de entrada no depende de cuándo se ejecute el código. Desde código – ya sea generado por el Strategy Builder o escrito a medida por nosotros – sólo se pueden enviar órdenes pero no decidir cuándo serán filled).

Las dos opciones de gestión de estas órdenes bracket de salida son:

  • ByStrategyPosition: sólo hay una orden bracket por todo el tamaño de la posición. Si por ejemplo una orden de entrada de 10 contratos termina teniendo tres filleds parciales de 3, 5 y 2 contratos, sólo habrá una orden de take-profit de 10 contratos y otra orden de stop-loss de 10 contratos.
  • PerEntryExecution: en este caso, cada filled parcial tendrá su correspondiente bracket.

Time in force

Establece qué hacer con las órdenes en espera al llegar al fin de la sesión. Una orden en espera puede ser por ejemplo una orden limitada de compra para entrar largo.

  • Day: las órdenes en espera se cancelarán al cerrar la sesión.
  • GTC: las órdenes no se cancelan nunca, salvo por petición expresa del usuario.
  • GTD: las órdenes se cancelan cuando se llega a la fecha determinada.

Trace orders

Si se marca, la estrategia escribirá en la ventana Output – a la que se accede desde New / NinjaScript Output – mensajes de log referentes al envío y gestión de órdenes.

Additional Data

En este paso podemos añadir series de barras adicionales a aquélla para la que se ejecutará la estrategia. Así conseguimos construir estrategias multi-timeframe (cuando todas las series son del mismo instrumento pero con diferente timeframe) o multi-instrumento (las series pueden ser de varios instrumentos y con iguales o diferentes timeframes). Pulsando en add se abre una pequeña ventana para seleccionar el instrumento y timeframe de la nueva serie de barras a añadir.

Strategy Builder. Additional Data

En el subapartado Custom Series podemos añadir series personalizadas para que cada barra guarde un dato calculado. Sobre esas series personalizadas podríamos aplicar indicadores para extraer información operativa.

Inputs y Variables

Aquí creamos los parámetros de entrada para el sistema que podrá personalizar el usuario cuando cargue la estrategia. Por ejemplo los períodos para las medias, los ticks de beneficio y pérdida, los intervalos de tiempo prohibidos para operar, etc.

Si lo necesitáramos para nuestros cálculos, también podríamos añadir variables.

Strategy Builder. Inputs y Variables

En el artículo Sistema Cruce Medias encontrará un ejemplo de cómo crear parámetros de entrada para el período de unas medias.

Condiciones y Acciones

Este apartado es fundamental ya que es donde se proporciona la lógica funcional a la estrategia. En el bloque superior es donde se indican las condiciones que deben cumplirse para ejecutar las acciones correspondiente que se configuran en el bloque inferior. Por ejemplo una condición podría ser “… cuando se crucen dos medias al alza …” y su acción podría ser “… comprar a mercado …”.

Strategy Builder. Conditions y Actions

En el artículo Sistema Cruce Medias encontrará un ejemplo de cómo crear condiciones y acciones para detectar los cruces de dos medias y actuar en consecuencia.

Stops y Targets

Pulsando en add se abre un diálogo para establecer las órdenes de take-profit y de stop-loss. Hay diferentes modalidades para elegir. Las más elementales son Profit target para establecer un beneficio a un número fijo de ticks con respecto a la entrada, Stop loss para establecer una pérdida máxima en ticks con respecto a la entrada, y Trailing stop para establecer un stop loss de tipo trailing que se va ajustando con respecto al movimiento del precio.

Strategy Builder. Stops y Targets

Trailing Stop. Ejemplo y configuración.

A continuación detallo un ejemplo de configuración de un trailing-stop.

Vamos a suponer que nuestro sistema trabaja a cierre de barra, en cuyo caso el precio de la orden de stop-loss se recalculará al cierre de barra. Y si el nuevo precio calculado resulta más ventajoso que el existente, entonces se actualizará el precio de la orden de stop-loss.

Para recalcular el precio del stop-loss se usa como precio de referencia el High o el Low de la barra recién cerrada, dependiendo de si la entrada es compra o venta.

Por ejemplo si se ha comprado un contrato de un instrumento cuyo TickSize es la unidad y con un trail stop-loss fijado en 10 ticks. Y tras el cierre de la barra corriente el High queda en 2.710, se recalcularía el stop-loss a 2.700. Si el stop-loss actual está por debajo de 2.700 se subiría automáticamente a 2.700. Si no, se dejaría sin modificar la orden de stop-loss al precio que estuviera.

En cambio, si el sistema funciona al Tick, el precio de la orden de stop-loss se recalcula con cada tick entrante. Si el nuevo precio calculado es más ventajoso que el existente, se actualiza la orden de stop-loss. Para recalcular el precio del stop-loss se usa como precio de referencia el Close del tick entrante. Siguiendo con el ejemplo anterior, si se ha comprado un contrato en 2710 con un trail stop-loss fijado en 10 ticks; el stop-loss quedaría en 2.700. Si el siguiente tick entra con un precio de 2.711 el stop-loss se subiría automáticamente a 2.701.

En el video siguiente comparto los pasos para configurar un trailing-stop como el que acabo de explicar.

Finish

Pulsando en el botón Finish se concluye la asistencia del Strategy Builder. Acto seguido la estrategia se compilará automáticamente, y en unos segundos estará disponible para utilizarse.

Strategy Builder. Finish