Dos líneas temporales en Ninja Trader
Publicado: 09 Jun 2008 17:26
He estado echándole un ojo a la forma de hacer que las optimizaciones en Ninja Trader tengan en cuenta la "intra-barra", y no den por buenas las operaciones que se puedan cerrar en la misma barra. He encontrado la instrucción "BarsInProgress", que permite jugar con dos líneas temporales (o más). Estoy haciendo las primeras pruebas, pero básicamente esto es lo que entiendo:
Para resumir el funcionamiento, pongo el ejemplo que viene en la ayuda, e intentaré explicarlo. Puede que me pierda algo, por eso invito a los que programen en NT a que me corrijan o complementen la información.
Según esto entiendo que la forma de que un backtest o un WFO compruebe los movimientos dentro de las barras es dejando la línea principal del gráfico en la escala en la que queremos ejecutar el sistema, y añadiendo otra más pequeña, que el sistema también comprobará, aunque no realicemos ninguna orden sobre ella, sólo la utilizaremos para ejecutar la órdenes lanzadas delsde la línea temporal principal. En este enlace que me dejó Wave el otro día lo explican:
http://www.ninjatrader-support.com/vb/s ... rid&t=6652
Este es el ejemplo que ponen:
Este es el ejemplo que ponen... si alguien tiene experiencia y ve algún error, o quiere comentar algo, seré el primer agradecido. Por mi parte estoy haciendo las primeras pruebas de backtest para ver als diferencias (la primera diferencia es el tiempo que tarda... buffff).
La clave para lanzar la orden sobre la segunda línea de tiempo es la instrucción:
EnterLong(1, 1, "Long: 1min");
Si fuera "0" la lanzaría sobre la linea de tiempo principal. Para órdenes limitadas se utiliza la nomenclatura:
EnterLongLimit(int barsInProgressIndex, bool liveUntilCancelled, int quantity, double limitPrice, string signalName)
de forma que para comprar un contrato limitado al mínimo de la barra, a ejecutar sobre la segunda línea temporal, sería:
EnterLongLimit(1, true, 1, Low[0], "Venta Limitada");
.................
A ver si mejoramos de esta forma los backtests.
Saludos!
Edito: Gracias por el enlace, Wave!
Para resumir el funcionamiento, pongo el ejemplo que viene en la ayuda, e intentaré explicarlo. Puede que me pierda algo, por eso invito a los que programen en NT a que me corrijan o complementen la información.
Código: Seleccionar todo
// Asumimos que esta estrategia se ejecutará sobre un gráfico ES 12-06 con barras de 1 minuto
protected override void Initialize()
{
// Añadimos una segunda línea temporal de 5 minutos: Cuyo índice "BarsInProgress" será "1". La línea principal es la del gráfico (1 minuto), será Barsinprogress=0
Add(PeriodType.Minute, 5);
}
protected override void OnBarUpdate()
{
// Comprobamos a qué línea temporal está llamando el método "OnBarUpdate()"
if (BarsInProgress == 0)
{
// Un valor de cero representa la línea principal del gráfico ES 12-06, en este caso 1 minuto
// Aquí pondríamos las intrucciones a ejecutar sobre las barras de 1 minuto
}
else if (BarsInProgress == 1)
{
// Un valor de uno representa la línea secundaria, en este caso 5 minutos
// Aquí pondríamos las intrucciones a ejecutar sobre las barras de 5 minutos
}
}
http://www.ninjatrader-support.com/vb/s ... rid&t=6652
Este es el ejemplo que ponen:
Código: Seleccionar todo
protected override void Initialize()
{
/* Añadimos una segunda línea temporal al sistema.
MUY IMPORTANTE: debe ser menor que la principal
Nota: En este ejemplo partiremos de que el gráfico principal es de 5 minutos, y ahora añadiremos una línea temporal de 1 minuto */
Add(PeriodType.Minute, 1);
// Añadimos dos indicadores EMA
Add(EMA(Fast));
Add(EMA(Slow));
/* Ajustamos el color de los indicadores */
EMA(Fast).Plots[0].Pen.Color = Color.Blue;
EMA(Slow).Plots[0].Pen.Color = Color.Green;
CalculateOnBarClose = true;
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
/* Cuando se llama a "OnBarUpdate()" siempre se llamará primero a la primera línea temporal, la principal, seguida de las otras series secundarias.
En este caso el orden sería el siguiente:
12:00PM 5min
12:00PM 1min
12:01PM 1min
12:02PM 1min
12:03PM 1min
12:04PM 1min
12:05PM 5min
12:05PM 1min
Cuando OnBarUpdate() sea llamado por la línea de tiempo principal (5min en este ejemplo), haz lo siguiente:*/
if (BarsInProgress == 0)
{
// Cuando la media rápida cruce al alza a la lenta... lanza la orden para ser ejecutada en la línea de tiempo secundaria:
if (CrossAbove(EMA(Fast), EMA(Slow), 1))
{
/* La condición de entrada es lanzada en la línea de tiempo primaria, pero es enviada y ejecutada en la secundaria (1 minuto)
La forma de determinar sobre que serie se lanzará la orden es por el primer parámetro: 0 = línea primaria, 1 = secundaria, 2 = terciaria, etc. */
EnterLong(1, 1, "Long: 1min");
}
// Si se cruza a la baja, entra en corto en la segunda línea de tiempo (1 minuto)
else if (CrossBelow(EMA(Fast), EMA(Slow), 1))
{
/* Exáctamente lo mismo de antes */
EnterShort(1, 1, "Short: 1min");
}
}
// Cuando OnBarUpdate() sea llamado por la línea de tiempo secundaria, no hagas nada.
else
{
return;
}
}
La clave para lanzar la orden sobre la segunda línea de tiempo es la instrucción:
EnterLong(1, 1, "Long: 1min");
Si fuera "0" la lanzaría sobre la linea de tiempo principal. Para órdenes limitadas se utiliza la nomenclatura:
EnterLongLimit(int barsInProgressIndex, bool liveUntilCancelled, int quantity, double limitPrice, string signalName)
de forma que para comprar un contrato limitado al mínimo de la barra, a ejecutar sobre la segunda línea temporal, sería:
EnterLongLimit(1, true, 1, Low[0], "Venta Limitada");
.................
A ver si mejoramos de esta forma los backtests.
Saludos!
Edito: Gracias por el enlace, Wave!