Categorías
Strategy Builder

Strategy Builder

Tutorial del Strategy Builder. Explicación de las propiedades y pasos a seguir para crear sistemas automáticos con el Strategy Builder.

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

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#, escribiendo el código desde el NinjaScript Editor. Pero si no sabemos programar podemos utilizar el asistente llamado Strategy Builder para construir estrategias sin escribir código. Este asistente se abre desde el menú New / Strategy Builder.

Abrir Strategy Builder

Microsoft.NET y NinjaScript

NinjaTrader está basado en el framework Microsoft .NET que es una librería de clases de Microsoft que permite a los programadores realizar cualquier tarea en el entorno Windows. NinjaTrader por su parte 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 NinjaScript 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 propias de NinjaTrader como el Market Analyzer, el 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. Es menos intensivo que On each tick.

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.

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 teórico se logrará en el precio Open de la siguiente barra B que se corresponde con el 2.789,50 en la imagen. Sin embargo, en real puede que no sea filled en el Open, ya que dependerá de la liquidez en el lado Ask del libro de órdenes cuando la orden llegue al Exchange.

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

Al cierre de la barra B las dos órdenes de salida habrían logrado 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 que 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 & 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.

En el artículo Variables en el Strategy Builder encontrará un ejemplo detallado para crear variables.


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 & 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 & 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

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.

111 respuestas a «Strategy Builder»

Hola gerardo, no necesitas añadir un campo específico para el número de contratos en el Strategy Builder. Ya viene implementado por defecto.
Si cargas la estrategia en el Strategy Analyzer o desde el Control Center/pestaña Strategies, y vas abajo a «Order Properties» y en el desplegable «Set order quantity» seleccionas «Default quantity», aparecerá un nuevo campo «Default Quantity» para que introduzcas el número de contratos para las órdenes.
Saludos

Hola gracias por responder, la pregunta puntual va dirigida a que no sé cómo colocar los valores al usar el trailing stop, en el strategy builder ya q no logro hacer que el stop siga al precio, gracias

Hola Gerardo, he ampliado el artículo con más explicaciones + video, sobre cómo configurar el trailing.

Buenas tardes:

Quisiera saber como programar el target profit para una estrategia en la que entro con dos contratos y quiero salir al llegar a los 4 y los 8 ticks.

Muchas gracias

Hola Felipe,
El modo más rápido sería tener dos órdenes de entrada con distinto nombre, una para trades con TP=4ticks y otra con TP=8ticks.
Por ejemplo: EntradaTP4 y EntradaTP8.
Desde el StrategyBuilder puedes hacerlo.
El parámetro Entries per direction tienes que ponerlo = 2.
Stops and Targets = Per entry execution
En el Actions, cada vez que se den las condiciones para entrar lo haces dos veces; una para EntradaTP4 y otra para EntradaTP8.
Al configurar los Profits y StopLoss lo haces para cada una de las órdenes por separado, rellenando correctamente la etiqueta ‘From Entry Signal’ para que cada salida esté vinculada a su entrada por el nombre.
Saludos

Las salidas sí me las vincula, pero solo me hace una entrada.
He puesto dos entradas en sets separados y he probado también en el mismo set, pero solo me coge una entrada.
Los parámetros por defecto también están como me has dicho: «El parámetro Entries per direction tienes que ponerlo = 2. Stops and Targets = Per entry execution»

Hola Gerardo, arriba en el artículo, en el apartado «Stops y Targets» se enumeran las diferentes opciones para configurar de manera estándar el target y el stop, y una de ellas es mediante un «Trailing stop». Sólo tienes que configurar los ticks que quieres para el trailing.
De todos modos, he ampliado el contenido de la sección Stops y Targets para incluir un ejemplo de cómo configurar un Trailing-Stop. Espero que te ayude. Saludos.

Muy buenas,

una pregunta, ¿sabes si con el strategy builder se puede ordenar a un sistema que compre o venda si un indicador pasa de color rojo a azul o viceversa.?

Y por otro lado, ¿se puede hacer un sistema de divergencias con el estrategy builder entre un indicador con una sola línea y el precio?

Muchas gracias de antemano

Hola Miguel,

sobre la primera pregunta, la respuesta es que sí. El único requisito es que el indicador no oculte esa información y se pueda preguntar desde fuera si para una barra determinada está rojo o azul.

Sobre la segunda pregunta, lamentablemente con el Strategy Builder no sería posible. Los sistemas de divergencias se basan en la geometría de las curvas (normalmente entre un precio y un indicador). Para determinar la geometría hay que calcular pívots y almacenarlos en colecciones especiales (Listas o Diccionarios); y este almacenamiento no se puede conseguir con el Strategy Builder.
Para construir un buen sistema de divergencias habría que programar a medida la estrategia.

Saludos

Muchas gracias por la respuesta.

Eso me imaginaba. El indicador que pasa de rojo a azul no sólo tiene oculta esa información, sino que ni siquiera aparece listado cuando abres el ninja script para crear un indicador.

Efectivamente tendré que empezar a pensar en meterme con el asunto de la programación.

Aprovecho para comentarte otra cuestión. Quiero crear estrategias usando order flow, concretamente con el delta acumulado. Como dijiste, si tienen la información oculta o no aparece en la lista de indicadores del ninja script, no puedo ordenar al strategy builder nada de eso. Por ejemplo el order flow cumulative delta que trae el ninja trader 8 en la versión lifetime es uno de esos que tienen todo oculto.
Mi pregunta es, ¿se puede programar desde el ninja script editor de ninja trader 8 asuntos sobre order flow, delta acumulado, bid ask…?.

Un ejemplo sería:

– compra o vende cuando el delta acumulado de la barra actual sea x veces más grande o más pequeño en porcentaje que el de la barra anterior.

Gracias de antemano, un saludo

Hola Miguel Ángel,

efectivamente, todos los indicadores protegidos ocultan su código y no se listan en el NinjaScript Editor.
Todos los Plots de un indicador son públicos y están en la colección Values, de modo que aunque no conozcas el nombre exacto del Plot siempre puedes obtener su valor en el código a través de la sintaxis Values[i]. Pero tendrías que programar un poco para conseguirlo. Comparando los valores extraídos con las lecturas que te da el DataBox en el chart, puedes identificar cada Plot con su Values[i] y entonces sí podrías incluirlo en tu estrategia.

Sobre el OrderFlow, sí pueden utilizarse los indicadores de ninja para el orderflow en estrategias. El problema del Strategy Builder es que está muy limitado para incluir personalizaciones, como la que comentas del porcentaje de
la barra anterior. Y la mejor opción es programar en el NinjaScript Editor, donde ya puedes hacer cualquier cosa. El sistema que propones sí puede progamarse sin problemas en el editor; en el builder sería más complicado aunque
también podría lograrse.

Saludos

Muy buenas,

acabo de leerme el articulo sobre sistemas semiautomáticos y e ha quedado más claro aquello que te preguntaba.

Mucha gracias y un saludo.

Buenos dias,

Antes que nada agradecerte por el material que publicas ya que me ha ayudado a iniciarme desde cero en este mundo.

Estoy tratando de realizar una estrategia usando las barras heikin ashi, comprando cuando esta por encima de una media y vender cuando este por debajo de la media, es decir, siempre estar en una direccion de mercado pero al momento de cierre de la orden creo que me toma el cierre de la vela con los parametros de las velas heikin ashi y no los reales del precio, como debo configurar la orden para que tome los datos del precio real.

Gracias a ti Eduardo por participar.

Efectivamente, todas las referencias al OHLC de la barra será a precios calculados, que pueden no coincidir con la realidad (p.ej. te puede dibujar un High al que nunca se llegó en el intervalo temporal de esa barra).

No es algo que haya verificado pero puedes intentar estas dos posibilidades. Aunque también depende de cómo esté programada la estrategia.

1.- En el Strategy Analyzer selecciona ‘Order fill resolution’ = «High» en el apartado ‘Historical fill processing’.
(Esto penaliza el rendimiento al tener que cargar el histórico de 1-tick)

2.- Si con lo anterior no consigues el filled correcto, prueba lo siguiente:
En ‘Tools/Options/Market data’ marca la opción [X] ‘Show Tick Replay’.
Después ve al Strategy Analyzer, en Data Series marca [X] ‘Tick Replay’ y ‘Order fill resolution’ = «High».
(Esto penaliza el rendimiento al tener que cargar el histórico del Time&Sales – y dependiendo del instrumento no todos los proveedores de datos lo tienen.)

En ambos casos tienes que estar conectado (al menos una vez, para poder descargar esos históricos).

Buenos días,

Muy buena la forma tan detallada como explicas cada función del Strategy Builder. Felicitaciones por compartir tus conocimientos a los nuevos traders.

Una consulta, te agradecería por favor si me puedes explicar como puedo configurar en el Strategy Builder para hacer que a cierta hora (ejemplo: 2:15pm) de cada dia de la semana (solo de lunes a viernes) se valide si el precio sube o baja X cantidad de Ticks. En el caso de que el valor llegase a subir a los X ticks ejecutar una orden de compra, y si llegase a bajar los X ticks, entonces ejecutar una orden de venta.

Quedo atento a tus comentarios.

Hola Edinson,

el StrategyBuilder es una herramienta generalista de introducción al desarrollo de sistemas. En el momento que se precisan de ajustes más particulares puede ser incapaz de resolver el problema.

Si el código necesita cálculos aritméticos, a fecha de hoy no puede resolverse desde el Strategy Builder, como es tu caso donde habría que calcular la diferencia entre el precio corriente y el precio de referencia donde se inició el seguimiento del movimiento.

Con el Strategy Builder podemos establecer mediante parámetros de entrada, la hora ‘Desde y la hora ‘Hasta’ de la ventana temporal para el seguimiento, así como obtener el precio de referencia en el instante ‘Desde’ y compararlo con el precio corriente.

Pero quedaría por resolver el cálculo de la diferencia entre los dos precios para saber si se alcanza el umbral requerido para disparar las órdenes. Para salvar este último escollo hay que editar el código que genera el Strategy Builder.

Cuando lo tenga listo compartiré un video con la solución completa.

Hola, buen día

Mil gracias, estaré muy atento a tu video para ver como se puede editar el Strategy Builder para cuando se requiere cálculos aritméticos. Espero ver pronto ese video, ya que me será de mucha ayuda para crear otras estrategias y que también le servirá a otros traders que visitan este magnifico blog.

En vez del video y para aprovechar y dotar de más contenido al blog, he añadido dos artículos más acerca del Strategy Builder. Uno sobre cómo crear intervalos horarios. Y otro para trabajar con variables y editar código. Espero que te resulten útiles Edinson, y en general a todos los lectores interesados. Saludos.

Hola, muchas gracias por todo lo que publicas en relación a Ninjatrader. Quisiera saber cómo se puede aumentar el numero de Condiciones y Acciones en Ninjatrader 7, por sobre los 10 «sets» que aparecen. Gracias

De nada Esteban. En NinjaTrader 7 parece que existe ese límite de 10 Sets. En el tema de la ayuda «Operations/Strategy Wizard/Wizard Screens», en el apartado «Understanding the Conditions and Actions screen» dicen lo siguiente:
«Via the wizard, you can have up to ten different condition sets with related actions. If you require more than ten condition sets, then you should self code your strategy via the NinjaScript Editor».
Por lo tanto, si se quieren añadir más condiciones y acciones habría que editar el código. Pero en tal caso, la estrategia ya no podría abrirse desde el asistente y todas las modificaciones posteriores tendrían que hacerse desde el NinjaScript Editor, escribiendo código.

hola como estas?

tengo un problema con mi estrategia automatica la cual pongo una orden limitada de compra por debajo del precio pero al activar la estrategia me dice que mi orden ha sido rechazada por que no ha podido ser llenada o algo así, pero no tiene sentido por que al querer hacer una compra es logico que la orden limitada de compra se ponga por abajo del precio, me puedes ayudar con eso por favor

Hola Johan,
hay muchas causas que pueden provocar el rechazo de órdenes. Lo primero es averiguar en qué barra ocurre el error para analizar el escenario concreto. Justo antes de cada envío de orden añade en el código un Print(CurrentBar) y así, en la ventana Output, quedará escrito en qué barra ha fallado. Y ya tendrás una pista para empezar a buscar la causa del error.
También en el método OnStateChange, dentro del bloque IF State.Defaults, añade TraceOrders = True. Esto activa el log de órdenes y vuelca más información en la ventana Output, que te puede ayudar a encontrar el motivo del error.
Ayuda del TraceOrders

Dependiendo del error que encuentres, a veces puede resultar útil analizar un único tipo de barras: o históricas, o en tiempo real. Para procesar sólo barras en tiempo real escribe como primeras líneas de código en el OnBarUpdate lo siguiente:
if(State==State.Historical)
return;
Y si no quieres procesar tiempo real, sólo histórico, sería:
if(State==State.Realtime)
return;
Ayuda del State

Hola buenos días. Tengo un problema con mi estrategia. La idea es que el precio una vez cruce una media en un tick compré o venda según el caso, pero está esperando que cierre la barra o compra mucho después del cruce. Cómo configurar para que esta condición se cumpla.

Hola Franklin, si quieres que la estrategia trabaje tick a tick, tienes que establecer la propiedad Calculate = OnEachTick. Para tu caso concreto también te serviría con Calculate = OnPriceChange. Consulta las opciones de la propiedad Calculate.

Franklin un gusto saludarte tengo la misma inquietud quisiera que abra una compra o una venta al superar por 1 tick o al tocar una media, haz logrado resolver esto? solo lo logro al cierre de cada barra pero a veces esto supera por mucho la media.

Hola que tal? agradecerte por tus respuestas, cuando uno analiza la estrategia en ninjaTrader y obtiene los diferentes resultados en la optimización, que es lo que tenemos que tomar en cuenta de esos resultados? o que resultado toma importancia para decir que el bot podría tener una buena expectativa.
Muchas gracias.

De entre todos, el Profit Factor es el más determinante.
Pero aparte, mejor que una optimización, hay que hacer un Walk Forward Optimization para tener una idea más aproximada de cómo se puede comportar el sistema en el futuro. Saludos

Hola, muy bueno tu articulo, quisiera saber si existe una forma de que se coloque una orden automática cuando el precio toque una media móvil? he tratado de hacerlo y no lo logro al toque solo al cierre de la barra.

Hola Gustavo, cuando ejecutes la estrategia en el Strategy Analyzer prueba lo siguiente:

  1. La propiedad Calculate hay que establecerla a On each tick.
  2. En el apartado Historical fill processing‘ asigna estos valores:
    • Order fill resolution = High. La explicación la puedes consultar aquí.
    • Fill limit orders on touch: marca esta casilla si quieres que las órdenes limitadas sean filled al tocarlas el precio, en caso contrario, el precio tendría que superarlas.

Espero que te sirva. Saludos.

GRACIAS POR ESTE ARTICULO DE VERDAD ME HA SACADO DE UNA DUDA, PERO TENGO OTRA PREGUNTA, EN EL VIDEO QUE HICISTE SOBRE EL TRAILING STOP NO PUSISTE TARGET ES ASI QUE SE USA O SOLO LO HICISTE A MODO DE PRUEBA.

El Trailing-Stop es un stoploss dinámico que se va moviendo a medida que el precio se mueve a favor de la entrada. En esencia es una orden de pérdidas aunque dará ganancias si se mueve más allá del precio de entrada, y el mercado se gira y lo toca. Si quieres un target de beneficio propiamente dicho, tendrías que enviar también una orden de take-profit.

si eso lo entiendo lo que pasa es que tengo una estrategia y le puse un trailing stop pero cada vez que se ejecuta una operacion me salta un mensaje de error y desactiva la estrategia por eso pregunto, porque quiero saber la forma correcta de programarlo o configurarlo para que no pase eso, mi ejecuta primero una orden limite y cuando el precio vuelve entra a mercado pero no se porque el trailing stop no me funciona.

Para identificar la causa del error establece el parámetro TraceOrders a True para que se vuelquen los mensajes a la ventana Output. Y cuando ejecutes la estrategia en el Analyzer ten siempre abierta la ventana Output. Si hay errores, se imprimirán en el Output, y te dará pistas para investigar.
Mi consejo es que crees un sistema muy simple por ejemplo un cruce de medias. Con un takeprofit muy lejano para que el trailing tengo espacio de sobra para moverse y puedas comprobar que funciona bien consultando el Output. Y lo pruebas con la conexión ‘Simulated Data Feed’ donde puedes dirigir el movimiento del precio y así comprobar que el trailing se mueve bien.

Saludos ¿Como configuro mis entradas al 61.8% del retrocso fibonacci?
¿Como determino que ya estoy en una tendencia? hay algún indicador?

Hola Dagnia,
sobre la tendencia puedes consultar este artículo del indicador PowerTrend. Pero por supuesto no es infalible y en períodos laterales entregará muchas señales falsas.
Para entrar a un % de retroceso, primero habría que delimitar el impulso previo. Necesitas dos «picos» A y B. Una vez conocida la «recta AB» puedes saber en qué precio se encuentra el x% de retroceso y colocar ahí tu orden limitada de entrada. Necesitarías un indicador que hiciera todo el trabajo: que calculara los impulsos (tramo entre A y B) y el precio para el % de fibo que quieres y que se introduciría en el indicador por parámetro. Así la estrategia sólo tiene que leer a qué precio está el retroceso esperado y colocar ahí la orden. No conozco ningún indicador que haga esta tarea y tendrías que programarlo tú. No sería sencillo.
Por otro lado, para trading discrecional puedes dibujar un fibo en un chart y ordenar una entrada en el porcentaje que quieras. Sin programar nada.
Saludos

Buenas quería saber si es posible hacer lo que dijo Dagnia. Mas menos

Lo que necesito es que el robot trace el fibo de una vela, a una hora determinada, en una temporalidad que yo le diga
Coja el máximo y el mínimo con las mechas de la vela y que pueda seleccionar con niveles de fibo para poder hacer entrada en largo o en corto segun sea la vela alcista o bajista.

Ejemplo:
Temporalidad 5min
En Dax
Duración de operación hasta las 00:00h de ese día
Vela de las 20:35h (máximo y mínimo con mechas)
Niveles fibo
Se deja operación (Buy Limit o sell limit) (depende de la vela 20:35h)
Y se pone un ATM de SL o TP

Hola Xabi, con el Strategy Builder no se puede construir ese sistema. Pero sí podrías hacerlo con programación a medida desde el NinjaScript Editor.

hola cordial saludo;

muchas gracias por cada aporte que realizan a la comunidad es muy grato aprendo un montón cada aporte, les escribo por que tengo una inquietud y es que realice una estrategia con el buldier pero no se como hacer para agregar 2 botones al panel de ninja una que diga activar largos y otro que diga activar cortos(click para activarlo y click para desactivarlo) he visto que algunas estrategias lo tienen y la verdad he buscado como hacerlo pero no logro encontrar como, si pudieran poner un correo para enviar imágenes estaría estupendo, mil gracias

Hola Freddy,

en NinjaTrader se pueden agregar botones a un elemento WPF, como el chart, la barra de menús del chart y en general cualquier otro elemento que pueda ser contenedor.
Si eres programador C# y conoces de WPF (Windows Presentation Fundation) no te costaría hacerlo. Pero si no, sería una tarea muy compleja y tendrías que recurrir a alguna plantilla de código. En el foro de soporte de NinjaTrader hay varios hilos que hablan de cómo añadir botones a un chart, y en los que se ha compartido el código fuente. Ese código podrías copiarlo y adaptarlo a tu estrategia.

Desde el Strategy Builder no se pueden añadir automáticamente botones ni ningún otro elemento WPF. Tendrías que editar el código generado por el Strategy Builder e incluir tú mismo el código para insertar los botones en el chart, y además modificar la lógica del programa para que reaccionara a la pulsación de los botones.

Para tu problema concreto de activar largos o cortos, un «apaño» muy rudimentario que quizás pudiera servirte sería construir dos estrategias independientes, una sólo para compras y otra sólo para ventas. Y activarlas/desactivarlas desde su checkbox en la pestaña Strategies.

Saludos

Mil gracias, de todos a los que he preguntado eres el único que me respondió muy amablemente, la verdad no soy programador C# por lo que me tocará recurrir a una plantilla de código en el foro de ninjatrader, seguiré con mi investigación enserio muchas muchas gracias si me pudieras recomendar algún otro sitio donde investigar te agradecería.

De nada Freddy. Realmente el mejor sitio es el foro de NinjaTrader. Busca por «Add Button Chart» o términos semejantes y encontrarás código para insertar botones en el chart. Después, para añadir la lógica ya tendrás que saber de programación C# + NinjaScript. Saludos

Hola que tal, he creado una estrategia interesante, buenos resultados y otros colegas les gustaría probarla, como puedo limitar los tiempos, por así decirlo… que solo puedan usar la estrategia por 10 días, como prueba, eso es posible? Como podría limitar ese tiempo?

Hola Jesús,
La respuesta a tu pregunta daría para escribir mucho sobre el tema y lamentablemente una respuesta de comentario no es lo más apropiado, pero intentaré ayudarte. Hay un gran cantidad de artículos, blogs, libros, etc donde se habla largo y tendido de las protecciones de código en .NET.

Simplificando al máximo tu problema, necesitas resolver dos escenarios:

  1. Proteger tu código fuente mediante algún tipo de «encriptación» (en .NET se llama «ofuscación»).

    Si el código de tu estrategia es visible, simplemente haciendo copy+paste cualquiera podría crear una estrategia idéntica a la tuya y utilizarla libremente sin ninguna restricción. A efectos prácticos sería como fotocopiar un libro.

    En .NET la manera de proteger el código es mediante la ofuscación. Hay ofuscadores de pago, y otros open source (uno de los más reconocidos es ConfuserEx). Para usar alguno open source hay que saber algo/mucho de programación. La opción más práctica sería usar el que viene con NinjaTrader que es de pago (100$/año). Aquí más información Ayuda oficial de NT8.

    Si no quieres gastar dinero puedes optar por no proteger el código y simplemente compilarlo como .dll. La estrategia en el fichero .dll no será visible, pero cualquier con algo de conocimiento la podrá decompilar fácilmente y acceder al código fuente. La compilación como .dll NO es una protección.

  2. Permitir la ejecución del código durante un período de tiempo autorizado.

    Esto se consigue con las licencias. NinjaTrader incluye un gestor de licencias pero es sólo para los partners. Tienes que ser un Vendor autorizado para poder crear licencias en los indicadores/estrategias que distribuyas. Obviamente, si tu código no está protegido (ofuscado) y es accesible, cualquiera podría eliminar el chequeo de la licencia y no serviría para nada. Para distribuir un código con licencia, tienes que haberlo ofuscado antes.

    Si no eres Vendor y para tu caso concreto, lo más sencillo sería añadir un bloque de código como el siguiente, al comienzo del OnBarUpdate (es algo muy simple y no es la mejor manera de codificarlo, pero cumpliría su función de no permitir la ejecución más allá del 31 de agosto de 2020, por ejemplo):
    DateTime expiracion = new DateTime(2020, 08, 31);
    if( DateTime.Now > expiracion )
    return;

    Ese chequeo se puede saltar cambiando la hora del pc. Para evitar la ejecución en tiempo real de la estrategia se puede usar este otro código que comprueba la fecha de la barra, no la del pc:
    DateTime expiracion = new DateTime(2020, 08, 31);
    if( Time[0] > expiracion )
    return;

    Después ofusca el código y ya lo puedes distribuir. Si no ofuscas el código y sólo lo compilas como dll y lo distribuyes, cualquier con un decompilador podrá ver el código fuente, hacer un copy+paste y quitar el chequeo de fecha.

Espero que te sirva.
Saludos

Hola de Nuevo, tengo dos curiosidades:
1.- Que opciones se pueden usar para permitir que el sistema automático opere con más de un contrato?
2.- Existe la forma de que si mueva de manera manual en el chart en plena operativa el target o stop loss definidos ya en el Strategy Builder no regrese al cambio de barra a su posición inicial?
Gracias, saludos a la distancia.

Hola Arturo,

  1. En el diálogo de carga de la estrategia, en el último apartado Order properties, hay un campo llamado Set order quantity. Abre el desplegable y elige Default quantity. Entonces aparece un nuevo campo llamado Default quantity donde podrás indicar el número de contratos para las órdenes.
  2. No es posible. Los métodos de envío de orden que utiliza el Strategy Builder son llamados con cada nueva barra. Por ejemplo si mueves una orden pendiente, al cerrar la barra se vuelve a ejecutar el OnBarUpdate así como los envíos de las órdenes al precio que estuvieran calculados en el código.

Saludos

Buen dia, saludos desde Honduras

Antes que nada quisiera agradecerte por el tiempo que dedicas a instruirnos.

Mi consulta es la siguiente;

Tengo una estrategia en NinjaScript que me genera conflicto.
Dicha estrategia tiene sus respectivos SL/PT pero también la tengo programada con órdenes de salida. El conflicto se me genera cuando el precio de SL/PT coincide con el precio en la condición de salida generando una DOBLE ORDEN la cual me provoca pérdidas, ya que la orden SL/PT se ejecuta pero también se ejecuta otra orden en la misma dirección.
Hay alguna manera de solventar este inconveniente o deberé elegir eliminar mis condiciones de salida?
Cabe mencionar que dichas condiciones de salida me ayudan a reducir las pérdidas significativamente.
En espera de tu pronta atención al respecto,

¡Gracias anticipadas!

Hola Mauricio,
sí, eso te va a dar problemas: el mezclar los SL/TP (puestos con llamadas a los métodos SetStopLoss/SetProfitTarget dentro del método OnStateChange) con llamadas a métodos Exit para salir, dentro del método OnBarUpdate.
Lo que puedes hacer es que cuando se dé la condición de salida dentro del OnBarUpdate, llamar nuevamente al método SetStopLoss/SetProfitTarget, pero con un nuevo precio de salida, para así mover la orden. De este modo no necesitarías llamar a ningún método Exit.
Saludos.

Buen dia,
Gracias por tu oportuna respuesta.
Creo haber entendido el mensaje, sin embargo no me queda claro como parametrizarlo en el Strategy Builder.
Podrias brindarme una instruccion mas detallada o quizas un ejemplo de como lo harias tu?

Muchas Gracias!

Pensé que habías programado la estrategia. Lo que te proponía sólo se puede hacer desde código. Tendrías que editar el código que genera el StrategyBuilder e introducir los cambios. Pero entonces ya no podrás volver a abrir la estrategia desde el Builder.
Aquí está la ayuda de los métodos Set: SetProfitTarget y SetStopLoss. Pero hay que saber programar, aunque sea poco. Dentro de los IF’s que tengas para las condiciones de salida, tendrás que incluir los Set’s correspondientes. Siento no poder ayudarte más, pero se sale de lo que es el StrategyBuilder y se entra en el campo de la programación a medida, que es otro mundo.
Saludos

Hola que tal? yo de nuevo por aquí, es posible programar entradas con respecto a la formación de una vela anterior en Strategy Builder, por ejemplo, si la vela tiene cuerpo completo entrar al 38% del retroceso de la vela o si la la mecha de la vela no supera el 23% de su cuerpo entrar al 61%, no sé si me explico 😀 … saludos gracias.

Hola Arturo,

para lograrlo tendrías que usar variables y editar el código para añadir los cálculos aritméticos.
En el artículo de Variables en el Strategy Builder hay un ejemplo que te puede servir como guía para emplear variables y editar el código para incluir cálculos.

Pero a medida que el sistema precisa de más cálculos o adquiere complejidad, el asistente te va a servir de poco y es mejor ir a la programación a medida.
Lo que buscas sería muy sencillo de resolver con programación a medida. Te pongo un ejemplo de código que también te serviría para incluirlo en el código del Strategy Builder al editarlo.

Ejemplo de entrada corta al 61% del retroceso en una barra bajista y siempre que la mecha no sea mayor que el 23% del cuerpo:

if( Close[0] < Open[0] ) // barra bajista
{
double cuerpo = Open[0] - Close[0];
double mecha = Close[0] - Low[0];

if( mecha <= 0.23 * cuerpo )
{
// Precio de entrada al 61% del retroceso del rango:
double precioteorico = Low[0] + ( High[0] - Low[0] ) * 0.61;
double precioreal = Instrument.MasterInstrument.RoundToTickSize( precioteorico );
EnterShortLimit( precioreal );
}
}

Hola, excelente día. En el Builder agregué una condición para hacer que espere 2 velas antes de volver a entrar. Quedó así: BarsSinceExitExecution(0,””,0) > 2 pero ahora no toma ninguna operación en el día. ¿Podrías orientarme como hacerlo y si es posible explicar un poco los parámetros de BarsSinceExitExecution() y como usarlo ?

Alberto, si no estás trabajando en multi-timeframe ni con diversos nombres para las órdenes de salida, prueba a usar la firma del método sin nada entre paréntesis, según la ayuda oficial BarsSinceExitExecution.
Usa Prints antes y después del IF con el que estés controlando el BarsSinceExitExecution, para enterarte de lo que está pasando, valores de alguna variable que te interese o afecte al IF, etc. Tendrás algún bug en el código.
Mira bien el ejemplo de la ayuda y asegúrate de entender esta expresión:
|| BarsSinceExitExecution() == -1
Es necesaria para entrar por primera vez. Si sólo usas BarsSinceExitExecution() > 2 no entrarás nunca por primera vez. Saludos

NT7 se basa en unas librerías de windows más antiguas (winforms) y NT8 en el más moderno framework .NET. Aunque el código usado en ambas es C# y las funciones son muy parecidas, los NinjaScripts generados son incompatibles.

Hola buen dia exelente blog.. Tengo una pregunta como se puede colocar un stop que este en un indicador como en una media movil? siendo que mi stop variable.

Saludos

Gracias Ricardo. Sobre tu pregunta, se resuelve incluyendo Condiciones y Acciones en la estrategia. En el artículo Sistema Cruce Medias se explica en detalle.
Para tu caso concreto podrías incluir un nuevo Set, añadir una nueva Condición y configurarla como el cruce entre el precio y la media móvil (puedes elegir cualquier indicador de la biblioteca). Después y en el mismo Set añadirías una nueva Acción – para responder a esa Condición – que consistiría en configurar la salida, por ejemplo con una orden de salida a mercado. Tendrías que configurar por separado las compras y las ventas. Saludos.

Muchas gracias por tu respuesta. si tienes razón.
Tengo otra duda porque cuando realizas el histórico de entradas de una estrategia muestra un resultado y cuando aplicas la estrategia en tiempo real para tomar las ordenes hay variaciones en el precio de la entrada. ¿Como puedo configurar para que la entrada en tiempo real sea igual a la toma de decisión de un histórico?
Te agradesco.

El deslizamiento depende de la liquidez en el momento de la entrada. Si no hay suficiente sí puedes sufrirlo y que el precio del filled no sea el esperado. Pero salvo que operes productos con poca liquidez, o en momentos con mucha volatilidad (noticias, apertura, cierre de sesión, etc), este problema tiene que ser infrecuente.
Caso aparte es que utilices para el backtesting series de barras ficticias o calculadas como Renko, Point&Figure, Three Line Break o Heiken-Ashi. En esos gráficos las entradas reales puede que no coincidan con las del backtesting porque sus barras se recalculan después de que el precio ya se haya movido. Pero es un problema originado por el tipo de chart elegido, no por la estrategia. Saludos.

Hola. Me pueden dar una idea de como puedo salir de un trade cuando mi TG la quiero con el indicador de Risk Reawar?.
Ya tengo configurado mi entrada y mi salida en una media móvil(stop) pero mi TG no lo quiero fijo lo quiero que mida desde mi entrada hasta donde coloco el stop (media móvil) por lo tanto mi TG será donde daría el indicador de Risk Reawar en la relacion 1-1. o como puedo medir la distancia de mi entrada hasta mi stop para multiplicarlo por 1, 2, 3 etc depende de la relación que quiera.. Les agradezco

Hola Ricardo, en el momento de la entrada tendrás que obtener el valor de la media móvil del stoploss, calcular la diferencia entre el precio de entrada y esa media móvil, multiplicar esa diferencia por el factor RiskReward y sumarlo al precio de entrada para establecer el takeprofit. El factor RiskReward será un input, y el cálculo del precio del takeprofit tendrás que hacerlo editando el código. Revisa el apartado de Inputs y Variables del artículo del Strategy Builder. Y sobre todo el artículo Variables en el Strategy Builder que muestra un ejemplo de cómo hacer cálculos aritméticos editando el código. Espero que te sirva como guía para hallar una solución. Saludos.

Hola, saludos:

Quisiera saber si existe para Ninja 8 algún indicador abierto que grafique divergencias en cualquier oscilador, especialmente divergencias ocultas.
Y si no es así, alguna idea o pista de cómo programarlo?

Hola, un indicador de divergencias universal no me suena, aunque puedes buscar en el foro de NinjaTrader por si hay algo.
Para programarlo en NinjaTrader tendrías que saber de POO (para el manejo de colecciones fundamentalmente) y NinjaScript.
Se trata de comparar los pívots (o «picos») de dos series de datos, p.ej. precio y RSI.
Lo primero es calcular los pivots o «picos» de cada serie. Una vez identificados los pivots de las dos series (con una tolerancia de alguna barra para el matcheo) tienes que determinar si convergen (comparten tendencia) o divergen (tendencias contrarias).
Los pívots se pueden calcular con los Highs o con los Lows. Si el precio está en tendencia alcista y usas los pívots Low para el matcheo, obtendrás las divergencias ocultas. Con los pívots High, las divergencias estándar.
Saludos

Buenas tardes. Estoy aprendiendo mucho con sus aportaciones, son de gran ayuda para todos asi que muchas gracias de antemano.

ojala pueda ayudarme con lo siguiente. Dos dudas independientes una de la otra:

-como puedo hacer para abrir una posicion larga cuando el minimo de una vela alcista este exactamente posicionada en una ema8, sin traspasarla.

-otra duda que soy incapaz de resolver es como abrir una posicion larga cuando se den las siguientes circunstancias. Que se de un patron de vela concreto y que el RSI a su vez, este por encima del valor 70.

Muchas gracias de verdad por tu ayuda.

Hola Gonzalo,
la primera pregunta creo que no la tienes bien planteada ya que es casi imposible que el Low de una barra coincida con su EMA8 y en general con cualquier EMA (salvo con la EMA1 calculada sobre los Lows). Carga la EMA sobre un chart y lo podrás ver. Puede que exista algún tipo de barra especial con más probabilidad de coincidencia pero en general será muy difícil que se cumplan esas condiciones que planteas.

Sobre la otra pregunta de los patrones, lo más práctico sería tener un indicador a medida para detectar patrones. P.ej. el Plot del indicador podría valer 0 si la barra no tiene patrón, 1 si la barra en un doji, 2 si es un hammer alcista, -2 si es un hammer bajista, etc. Es decir, se trata de emparejar cada patrón con un número. Después, en el Strategy Builder preguntarías por el valor de ese indicador en la barra corriente y si coincide con el patrón que quieres operar (y que podrías introducirlo como un parámetro de entrada en la ventana de carga y así poder optimizarlo) procederías a ejecutar la tarea que quisieras: abrir o cerrar posición, comprobar otros indicadores, etc. Saludos.

Disculpame, me refería a que el Low estuviera a 1 tick o 2 del precio EMA8. Se que es dificil que caiga con exactitud.
Muchas gracias por tu rapidez en la respuesta. Me encanta tu blog.
Gracias.

Hola que tal Comunidad.. Tengo una duda como puedo poner un dibujo que me aparezca en la parte de la zona del indicador.. coloco dibujos y trato de ponerlos en la Y con el indicador y siempre pe aparecen en la zona del precio y no en el panel del grafico.
Saludos

Hola muy buen dia.
Tengo una duda como puedo tener un criterio de entrada en la construccion de una estrategia que tome un dato en un grafico diferente. Es decir que una condicion sea de un grafico de 1 H pero que las entrada se de en el grafico de 1 Min.

Si me pueden ayudar a despejar esa duda.

Saludos y exelente comunidad.

Hola Ricardo,
puedes añadir todas las DataSeries (otros timeframes y/o otros instrumentos) que quieras, adicionalmente a la DataSerie principal en que se carga la estrategia.
Cuando configures las condiciones en el StrategyBuilder por ejemplo con indicadores, tendrás que especificar a qué DataSerie se refiere cada indicador (igual que harías en un chart multi-panel con varios instrumentos/timeframes). Nada más.
El parámetro de entrada no es exclusivo de una DataSerie, tú decides en las condiciones a qué DataSerie afecta el input parameter.
Sin embargo con las acciones, por ejemplo en el envío de órdenes, parece que no es posible elegir la DataSerie y todas las órdenes se enviarían a la DataSerie principal. Para enviar la orden a otra DataSerie diferente (realmente a otro instrumento, ya que lógicamente el timeframe no interviene aunque sea distinto al de la DataSerie principal) tendrías que abrir el código e incluir una mínima edición en la sentencia de envío de orden. Saludos.

Buenos días. enormes gracias por la labor que haceis.

Tengo una duda sobre como programar un SL que sea diferente cada entrada.

Es decir, quiero que mi SL se calcule por la diferencia del cierre de la vela que me da la entrada y el máximo o mínimo relativo, según se sea un short o long, más cercano (o por el low o high de la misma vela). Y que luego el profit sea 2 o 3 veces esta distancia.

Un saludo y gracias de antemano

Buenos días Carles,
a medida que la lógica de la estrategia se complique y surjan nuevos problemas, será más difícil encontrar una solución con el Strategy Builder y necesitaremos incluir código a medida. Y en ese punto ya no hay soluciones genéricas, sino que hay que analizar cada caso concreto.

Grosso modo, el código para solucionar lo que planteas sería como sigue:

// Primero vendría la lógica para entrar y que vamos a suponer que termina con una compra a mercado:
EnterLong();

// Después calculo el precio de SL y lo guardo en una variable. Por ejemplo a 12 ticks del cierre de la barra que da señal de entrada:
double sl = Instrument.MasterInstrument.RoundToTickSize( Close[0] - 12.0 * TickSize );

// Configuro la orden de stop-loss:
SetStopLoss(CalculationMode.Price, sl);

Es fundamental que la función SetStopLoss no se ejecute más hasta la siguiente entrada porque si no, modificaría con cada ejecución el precio de la orden actual de stop-loss.

// Para un Take-Profit de p.ej. el triple del SL, se actuaría de similar modo:
double tp = Instrument.MasterInstrument.RoundToTickSize( Close[0] + 12.0 * 3.0 * TickSize );
SetProfitTarget(CalculationMode.Price, tp);

E igualmente, el cálculo y configuración del Take-Profit sólo debe ejecutarse una vez tras cada entrada.

Tienes que encontrar el lugar idóneo para incluir este código dentro del que te haya generado el asistente.
Y como decía al principio, no hay una receta universal sino que hay que analizar cada sistema.

Saludos

Buenos días, muchas gracias por la contestación tan rápida.

He estado probando lo que dijiste, pero no me esta saliendo. Lo que hice fue crear esas variables con el builder (sl y tp) como tipo double defecto 0.

Después en la parte del código de condiciones y acciones las definí con la formula que indicas. (no se si a palabra double que pones delante tengo que ponerla o esto ya viene definido en el paso anterior)

Y en la parte del código de stops y targets configuré los stops loss y los profit como tu indicaste.

No se que estoy haciendo mal.

También tengo la duda de si en la formula done defines el valor de la variables puedo hacer esto: sl = Instrument.MasterInstrument.RoundToTickSize( Close[0] – low[0]); para que así el tamaño de mi sl y tp dependan de cada vela de entrada y no de una cantidad siempre igual.

Saludos y muchas gracias

Hola Carles,
no tienes que crear las variables desde el wizard, las indicaciones que te di son para escribir directamente el código. Tienes que abrir el código de la estrategia y después compilarla.
Ten en cuenta que la estrategia editada ya no podrá abrirse más desde el StrategyBuilder, sólo desde el NinjaScript Editor y las modificaciones futuras que necesites hacer tendrían que hacerse con programación manual.
En cuanto al dimensionamiento que comentas del stop-loss la respuesta es sí. De hecho es lo recomendable para adaptarte de algún modo al contexto del mercado. Y no tienes porque limitarte al OHLC de la barra corriente, sino que puedes usar indicadores a modo de envolvente (Keltner, Bollinger, ATR, …) o un MAX/Min de n-Lows o n-Highs, etc.

Hola, tengo una duda sobre el Strategy Analyzer… ¿Es posible hacer backtest,walk-Forward,etc con una Estrategia programada con ninjascrip que utilice parámetros de order flow? Tipo POC, deltas, imbalances,libro de órdenes etc,.? Gracias anticipadas

Hola Gustavo,
no se puede. Para trabajar con datos históricos de la cinta (time&sales) y poder calcular deltas, bid-ask, imbalances, etc en barras históricas, necesitas activar la propiedad ‘Tick Replay’. Pero esta característica no funciona con el backtesting de estrategias. Saludos.

Gracias x la respuesta..¿ Es posible hacer esto con alguna otra plataforma o de algún otro modo? Saludos

Veo tb en la guía NT8 lo de Tick Replay y ofrece como alternativa:»Para obtener una mayor resolución de ejecución de pedidos en las pruebas retrospectivas de estrategias, puede utilizar la Resolución de ejecución alta en el Analizador de estrategias.» La pregunta en este caso es. ¿Este modo de Alta ejecución como trabaja? ¿Entiendo q habria mucha diferencia con respecto a los datos Tick Replay.. Saludos

Hola Gustavo,
si ejecutas la estrategia en el MarketReplay te funcionará tu lógica de OrderFlow del código: eventos OnMarketData y OnMarketDepth. Y podrías hacer un backtesting «manual». Sería muy lento y laborioso pero sería también el backtest más preciso posible.

No conozco ninguna plataforma que te permita procesar eventos de OrderFlow en backtest, optimización, o walkforward. Primero tendría que proporcionarte histórico de la cinta y hay muy pocos softwares retail que lo tengan, aparte de NinjaTrader. Corrijo: NinjaTrader procesa eventos de OrderFlow para backtesting en el Strategy Analyzer.

El Order fill resolution High es un import de un segundo timeframe más granular, y que el usuario elige para aumentar la precisión en la simulación de los filled de las órdenes.
El OrderFlow se usa para triggers de E/S, pero no tiene que ver con el filled de las órdenes. Si p.ej. colocas una orden stop para salir al precio X, da igual que el backtest lo hagas con TickReplay (en caso de poderse) o no, porque no te va a influir, en los filled no importa si el precio que toca el stop es buy o sell, con que lo toque será filled, y si ya trabajas a 1-tick no conseguirás más precisión por trabajar con TickReplay. Saludos

Buenas tardes,
tengo una nueva duda, comentas que necesito activar la propiedad ‘Tick Replay’, para poder calcular en barras históricas, pero que no funciona en backtesting, mi duda es:
En el Strategy Analyzer en todos los tipos de Backtest: optimización, walk, multi, en el apartado Data Series hay una pestana que indica Tick Replay, ¿no seria esta la opción que permitiría hacer ese calculo?

Hola Gustavo, tengo que corregir mi respuesta anterior, porque el Strategy Analyzer sí procesa los eventos de la cinta. No sé en qué release se activó esta función, pero ahora mismo en la 8.1.1.6 funciona, ejecutándose el método OnMarketData con prints históricos de la cinta en el Strategy Analyzer. Sin embargo, esto no afecta a la precisión del filled de las órdenes en backtesting. En la ayuda de Ninja se puede leer:

Tick Replay was NOT designed to provide accuracy in backtesting concerning order fills and execution and should NOT be used to expect the exact sequence of executions as running a strategy on live data. For greater order-fill resolution and accuracy in strategy backtesting, you can use the High Fill Resolution in the Strategy Analyzer. Furthermore you cannot combine both Tick Replay and High Order Fill resolution.

Es decir, que Tick Replay está ideado para analizar el OrderFlow y tomar decisiones de E/S pero no para precisar el filled de las órdenes, esto último lo conseguirías con ‘Order fill resolution = High’. Además, las dos funciones no se pueden activar a la vez. Saludos

Buenas tardes, he hecho una simple estrategia de cierre automático por Importe en USD con dos variables. Es para otro robot que tengo que no tiene acceso a tp ni stop pero hace buenas entradas. Simplemente quería meter otra estrategia en otro gráfico que me vaya cerrando esos trades de esa otra estrategia con mis condiciones que son recorrridos más cortos.
El problema es que el robot funciona bien pero cada vez que hace un cierre parece que se desactiva y tengo que volver a habilitarlo para que vuelva a cerrar.
¿Hay alguna condición para que se ejecute siempre que exista un trade abierto?
Gracias

Hola Daniel,
a qué te refieres con que no tienes acceso a TP ni SL en la estrategia que hace buenas entradas ? Si quieres añadir un TP o SL general en moneda lo puedes hacer añadiendo una sola línea de código (mira en la ayuda las funciones
SetProfitTarget y SetStopLoss).

En cuanto a lo que te está sucediendo de desactivación de la estrategia seguramente se deba a una operación no permitida que provoque el error. Por ejemplo, si una estrategia en la cuenta A abre un largo y otra estrategia en la misma cuenta A intenta abrir un corto, se cerrará la posición en la cuenta A y se desactivarán las estrategias.
Consulta en la pestaña Log de la ventana principal de NinjaTrader, por si hay algún mensaje de error que explique por qué se ha desactivado la estrategia.
Para encontrar más pistas sobre el error también puedes consultar el fichero más reciente en la carpeta Documents\NinjaTrader 8\trace y en la carpeta Documents\NinjaTrader 8\log.
Saludos

Buenos días, gracias por contestar. Lo de no tener acceso a tp y stop me refiero a que la estrategia A que está en un gráfico 1 no tiene parámetros de configuración de tp y stop y los pone muy lejos automáticamente. La estrategia hace buenas entradas pero si le acortara los recorridos posiblemente tendría un buen resultado. Por eso quería meter otra estrategia en un gráfico 2 que me cerrase por Pnl no realizado. La he hecho desde el comparativo de Pnl y cerrar si supera o disminuye el pnl dicho importe parametrizado. Pero esta estrategia solo me funciona el primer cierre, a continuación se desactiva y tengo que volver a cargarla de nuevo para que funcione. Supongo habrá algún bot free que haga esta funcion como en mt4 pero no lo he encontrado y es que es una tontería pero… muchas gracias

Hola Daniel. Como te decía echa un vistazo a los mensajes del log. Seguramente encuentres pistas de por qué se cierra la estrategia.
Si sabes programar, esa función que buscas de cerrar por PnL sería muy fácil de implementar mediante código en la propia estrategia que hace las entradas. Saludos

Hola:
Opero con velas renko y quiero abrir posiciones cuando una vela verde suceda a una roja, pero en el punto exacto del valor de cierre de la verde.
Strategy builder, sin embargo, me abre al inicio de la siguiente vela, ya sea ascendente o descendente.
Podéis ayudarme?
Muchas gracias

Hola Felipe, como normal general en backtesting no se puede abrir posición en el Close de una barra. Cuando una barra cierra es cuando se ejecuta el método OnBarUpdate, se evalúan las condiciones del mercado y se decide qué hacer. Si decidimos enviar una orden de entrada p.ej. a mercado, el filled ocurrirá en el Open de la siguiente barra. Es decir, lo más pronto que conseguiremos el filled es en el Open de la siguiente; y en real si envías la orden a mercado podrías sufrir un deslizamiento adicional con lo que el precio filled sería aún peor que el Open.
Excepcionalmente sí es posible conseguir el filled en el Close de la barra pero sólo para algunos tipos de barra como las Range donde en todo momento se conocen los dos precios donde puede cerrar; pero habría que trabajar en el timeframe de 1-tick y con una gestión de órdenes compleja que no soporta el StrategyBuilder. Y habría que enviar órdenes de tipo StopLimit, con lo que se perderían muchos filleds.
Por otro lado las barras Renko no deben usarse para backtesting porque son barras ficticias que no reflejan el verdadero recorrido del precio, y en real los resultados siempre serán mucho peores.
Saludos

Hola de nuevo:
Estoy con una estrategia, con velas renko, en la que voy aumentando los contratos largos mientras las velas sean ascendentes.
¿Cómo puedo cerrar todas las posiciones en cuanto aparezca una vela roja?

Hola Felipe. En el modo Managed usa ExitLong() para cerrar toda la posición larga.
Si lo que quieres es hacer un reverse entonces usa EnterShort(), que al mismo tiempo que cierra toda la posición larga, abre un corto.

Gracias. Voy solucionando problemas.
El problema que tengo es que abro un largo en una vela verde después de una roja; y sumo otra posición en la segunda vela verde.
Quiero que me cierre la primera posición o las dos posiciones cuando aparece una roja, haciéndolo con un reverse, pero solo me cierra la primera posición cuando la primera verde es seguida de la roja. Si se me abren las dos posiciones largas, el reverse no se me activa si la vela roja sigue a la segunda verde, si no más adelante.
No sé si es porque tengo activas dos órdenes de reverse a la vez.

A ver si me explico mejor:
Si con 4 verdes meto un contrato con cada una de ellas y ordeno que en la primero roja me haga un reverse, solo se me ejecuta cuando la roja aparece tras la primera o la tercera, pero no tras la segunda o la cuarta. En estos dos casos el reverse se ejecuta más adelante con otras rojas

Hola Felipe. El código se ejecuta a cierra de barra, momento en que se evalúa el contexto y se decide enviar la orden de cierre a mercado que sería filled en el Open de la siguiente barra. P.ej. si estando alcista, con los contratos que sean, aparece una barra roja a su cierre se enviaría un ExitLong() – sin nada entre los paréntesis – que sería filled en el Open de la siguiente y cerraría toda la posición larga.
Partiendo de ese concepto tendrías que comprobar que el código de la estrategia está bien escrito: comprueba que entre los paréntesis de los Exits no haya un 1 o una variable, así como el orden en que se ejecuta todo el código dentro del OnBarUpdate (p.ej. no deben ejecutarse métodos incompatibles al mismo tiempo como un Enter y un Exit). Saludos

Pero, con velas renko, hasta que no se cierra la segunda vela, no sabemos dónde está su open. Si tras una verde ordeno cierre en una roja, pueden ocurrir dos cosas:
a) Que la tercera vela sea roja, por lo que el close de la segunda coincide con el open de la tercera.
b) Que la tercera sea verde, por lo que el open de la tercera coincidiría con el de la segunda.
¿Si yo ordeno el cierre en el close de la segunda (roja), el programa me lo coloca necesariamente en el open de la tercera, es decir, la posición de salida me la haría coincidir con la entrada?

Así es Felipe.
En backtest (histórico) las órdenes enviadas al cierre de barra (histórica), aparecerán en el Open de la siguiente barra (histórica). Con barras Renko en real, aparecerá en el siguiente Open real y que no coincide con el Open histórico, y de ahí que el backtesting de un sistema en Renko se aleje mucho de los resultados que se consiguen en real.
Las barra Renko no reflejan el verdadero movimiento del precio y muchos de sus Open son falsos.
Se puede comprobar de una manera muy sencilla: abre un chart Renko de p.ej. 8, conecta con el Simulador, sube la Trend hasta que dibuje una barra verde, y sigue manteniendo la Trend alcista; entonces empieza a dibujar una nueva barra con el Open correcto. Deja que suba un poco más para que se siga dibujando la nueva barra verde y antes de que termine gira la tendencia. La barra verde empezará a menguar hasta que pase a bajista y siga descendiendo. Pero hasta aquí su Open sigue bien dibujado. Sigue bajando hasta que la barra bajista cierre. En ese momento la barra roja se redibuja y su Open pasa a estar situado falsamente en el Open de la barra verde anterior. En resumen son barras fake y no deban usarse para backtesting.
Si la estrategia estuviera funcionando en real, la orden se habría enviado al cierre de la barra verde, y se habría ejecutado en el Open real de la barra roja y no en el fake que aparece en histórico.
Dicho esto advierto sobre el peligro de comprar cursos o sistemas basados en barras Renko porque seguramente se trate de una estafa.

A la hora de ordenar un open reverse en sentido contrario, ¿hay algún modo de que el número de contratos venga definido por el número de contratos que quiero cerrar?
Es decir, si tengo abiertos X largos (unas veces 2, otras 4…) en diferentes sets, ¿puedo abrir un corto con X contratos, dependiendo del valor de X en cada momento?

Si p.ej. tienes una posición larga de x contratos, puedes hacer un reverse a cortos con EnterShort(Position.Quantity), que te cerrará los x contratos largos y te los volverá a abrir en corto.
En el Strategy Builder tienes la opción de añadir para el tamaño de la orden esa propiedad Position.Quantity.

Hola de nuevo a todos:
¿Puedo poner varias órdenes de entrada en distintos niveles para que se me ejecuten todas?
Por ejemplo:
Si close>open
Longlimit at close-2ticks
Longlimit at close-4ticks
De modo que si después de cerrar la vela, el precio baja hasta -6ticks, se me abran dos posiciones largas

Hola Felipe, sí se puede. Establece la propiedad EntriesPerDirection a 2. Y para evitar problemas, usa un nombre diferente para cada orden de entrada. Saludos.

Muy buenas a todos. Yo tengo 2 dudas que no he sido capaz de resolver construyendo mis bots:
1. Si quiero que el bot interactúe con una sma de 100 en 5 minutos (grafico donde ópera el bot) con la misma sma de 100 en grafico de 1h, para según su relación hacer entradas. Como lo puedo hacer?

2. Si quiero que las entradas me las haga con la configuración de un ATM que ya tengo definido. Como lo hago?

Saludos t gracias anticipadas!

Hola Carles. sobre la primera duda, tienes que añadir una segunda DataSeries de 60min, en el apartado ‘Additional Data’. Después en el apartado ‘Conditions and Actions’, cuando añadas la segunda SMA en su propiedad DataSeries seleccionas la DataSeries de 60min que creaste antes.
La segunda duda no se puede resolver desde el StrategyBuilder. Se puede hacer con código a medida y mediante una programación bastante avanzada. Otra opción que podrías intentar es encajar los parámetros de la ATM en tu estrategia dentro del Strategy Builder, pero sólo podrás hacerlo si es una configuración de parámetros sencilla.

Buenos días.

Gracias por tu respuesta anterior!

Otra duda. Si quiero que el bot se cierre una vez detecte que una entrada ha sido profit, sin importar el valor del profit o del profit acumulado ese día, como se puede hacer?

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