Cuando tenemos una estrategia de trading ya desarrollada pero que no alcanza unos resultados óptimos, en ocasiones puede resultar adecuado optimizar sus parámetros con el fin de refinar un poco la estrategia buscando aquellos conjuntos de parámetros que han funcionado mejor en el histórico. Posteriormente habrá que analizar la robustez de los parámetros obtenidos, algo que ya vimos en Cómo Medir la Robustez de tu Sistema de la mano de Sergi Sánchez de Sersan Sistemas.

Bien, pongámonos manos a la obra. En TradeStation tenemos los dos métodos de optimización habituales en este tipo de plataformas:

  • Exhaustive, con el que se calculan todas las combinaciones de parámetros dentro del rango que especifiquemos. Con ello nos aseguraremos de encontrar los mejores conjuntos de parámetros pero a cambio el proceso será muy lento al tener que realizar todas las combinaciones.
  • Genetic, mediante el que se utiliza un algoritmo evolutivo para realizar la optimización. Debemos tener en cuenta que con este método no se analizan todas las combinaciones, sino que mediante selección natural se van seleccionando conjuntos de parámetros cuyos resultados sean estadísticamente significativos. Este método será apropiado sobre todo en aquellos casos en los que el tiempo de optimización mediante el método Exhaustive sea excesivamente largo.    

Para iniciar una optimización, previamente debemos insertar una estrategia. Para ello hacemos click con el botón derecho sobre el gráfico que deseemos y seleccionamos Insert Strategy…

Seleccionamos la estrategia que deseemos del listado. En nuestro caso vamos a aplicar las estrategias Keltner Channels LE y SE a un gráfico diario del mini SP:

Le damos a Ok y en la siguiente ventana hacemos click en Format…

 

Y en la nueva ventana seleccionamos el parámetro que deseemos optimizar pulsando en el botón Optimize:

Al hacer eso nos aparecerá un menú donde establecer el rango de optimización del parámetro. En nuestro ejemplo hemos cogido, tanto para la pata larga como para la pata corta, el rango 10-40 con incrementos de 1 para el período de los canales y el rango 0.75-2.25 con incrementos de 0.15 para el multiplicador del ATR. Si ahora le damos a Ok veremos que el menú de la ventana anterior nos cambia y ya tenemos las opciones de optimización:

En Type elegiremos si queremos hacer una optimización estándar o un análisis walk-forward. Si seleccionáramos la segunda opción pinchando en Advanced Settings podremos especificar qué porcentaje de la muestra o qué fechas queremos excluir de la optimización. Por su parte, en el apartado Method tendremos la posibilidad de elegir la optimización exhaustiva o la basada en algoritmos genéticos. En todo momento se nos mostrará el número de combinaciones/pruebas que se realizarán (recuadro naranja). En caso de coger algoritmos genéticos podremos modificar en Advanced Settings diferentes opciones relacionadas con el algoritmo tales como generaciones, tamaño de la población, tasa de mutación, etc.

Una vez hemos configurado la optimización como deseemos le damos a Optimize y se inicia el proceso:

Debo reconocer que el módulo de optimización de TradeStation me ha sorprendido gratamente: se ha ventilado más de 100.000 combinaciones de parámetros sobre un histórico de 5 años en diario en poco más de 7 minutos, sin duda bastante aceptable.

Lo malo es que una vez que termina la optimización la ventana que muestra el estado de la misma desaparece y no nos sale nada. ¿Dónde están ahora nuestros resultados? No os asustéis, están en el menú View -> Strategy Optimization Report (alternativamente también podéis teclear Alt+Mays+O) y ¡bingo! Aquí tenemos todos los resultados, incluyendo información detallada sobre win/loss ratio, máximo drawdown, tamaño de cuenta recomendado para operar con esa combinación de parámetros, etc.:

Aquí un pequeño truco: si vamos haciendo doble click en cada fila de resultados se nos irá cargando la combinación de parámetros directamente en el gráfico, algo bastante cómodo para realizar un primer examen visual de los mejores candidatos.

Por supuesto, al hacer eso también se irá actualizando automáticamente el Strategy Performance Report que podéis encontrar también dentro del menú View.

Asimismo, podemos ordenar los resultados en base a los diferentes criterios de las columnas sin más que hacer doble click en los encabezados correspondientes.

Dentro de esas columnas me ha llamado la atención lo que TradeStation denomina TS Index. Para los que no sepan lo que es, se trata de un índice de calidad para estrategias que se calcula como:


Net Profit * NumWinTrades / AbsValue (Max. Intraday Drawdown)


Otra cuestión interesante sobre los resultados de las optimizaciones es que podemos configurar cómo se muestran en el report. Para ello simplemente debemos ir al menú View->Chart Analysis Preferences… y seleccionar la pestaña Strategy:

En dicha ventana podemos especificar cuántos resultados queremos que se muestren en función de uno de los criterios que aparecen en el desplegable Fitness Function. Por defecto nos muestra las 200 estrategias con el mayor Net Profit pero quizás nos interese más sacar las 1.000 estrategias de nuestra optimización con el menor Max Drawdown. En todo caso, estas opciones debemos configurarlas antes de realizar la optimización.

Rizando el Rizo: Optimización mediante Código
Muchas veces los lectores me preguntan si es posible realizar optimizaciones programadas mediante código en las plataformas de diseño de sistemas de tal forma que podamos dejar el PC toda la noche haciéndolas de forma secuencial.

Por fortuna, en el caso de TradeStation la respuesta es afirmativa. Desde la versión 9.5, TradeStation incluye una excelente API con la que vamos a poder realizar optimizaciones programadas sobre múltiples símbolos e intervalos. Os explico brevemente las funciones de EasyLanguage más relevantes para ello usando un sencillo ejemplo, aunque podéis encontrar la referencia completa en
https://community.tradestation.com/Discussions/DATA/20140911125726EasyLanguage_Optimization_API.pdf

Para empezar debemos ir al editor de EasyLanguage desde las Trading Apps y crear allí una nueva aplicación desde el menú New -> TradingApp.

Ahora ya podemos empezar a escribir código. Lo primero es declarar algunos métodos y establecer el símbolo y timeframe sobre el que trabajaremos, así como la fecha final, el tamaño del histórico a utilizar y el valor inicial del parámetro que vamos a optimizar, así como algunas variables internas:

using elsystem;
using elsystem.windows.forms;
using elsystem.drawing;

inputs:
Sym("@ES"),
int MinuteInterval(60),
LastDate("05/31/2017"),
int DaysBack(200),
NumDevsStep(0.1);

vars:
Form form1(null),
tsopt.Optimizer optimizer(null);

A continuación, con el siguiente código, creamos un formulario que nos permitirá iniciar la optimización con un simple click:

method void InitApp_Initialized( elsystem.Object sender, elsystem.InitializedEventArgs args ) 
vars: Button startButton;

begin
form1 = Form.Create("OptTest", 500, 500);
form1.BackColor = Color.LightGray;
form1.Dock = DockStyle.Right;
startButton = Button.Create("Start Optimization", 120, 30);
startButton.Location(20, 20);
startButton.Click += OnStartButtonClick;
form1.AddControl(startButton);
form1.Show();
end;

 

Y con este breve código, indicamos qué debe hacer el botón cuando le pulsemos, que no será  otra cosa que iniciar la optimización llamando al método StartOptimization ;)

method void OnStartButtonClick(elsystem.Object sender, elsystem.EventArgs args)
begin
StartOptimization();
end;

A partir de aquí empezamos a aprovechar la API de optimización de TradeStation. Si analizáis el código que viene a continuación, veréis que vamos a usar la estrategia de bandas de Bollinger sobre el símbolo, timeframe e histórico que hemos elegido en los inputs, optimizando los parámetros NumDevsDn y NumDevsUp entre 1 y 3 con el paso definido en la variable NumDevsStep:

method tsopt.Job DefineJob()
vars: tsopt.Job job, tsopt.Security security, tsopt.Strategy strategy;

begin
job = new tsopt.Job;
security = job.Securities.AddSecurity();
security.Symbol = Sym;
security.Interval.SetMinuteChart(MinuteInterval);
security.History.LastDateString = LastDate;
security.History.DaysBack = DaysBack;
strategy = job.Strategies.AddStrategy("Bollinger Bands LE");
strategy.ELInputs.OptRange("NumDevsDn", 1, 3, NumDevsStep);
strategy = job.Strategies.AddStrategy("Bollinger Bands SE");
strategy.ELInputs.OptRange("NumDevsUp", 1, 3, NumDevsStep);
return job;
end;

Con los siguientes métodos inicializamos la optimización y la supervisamos por si se produjera algún error:

method void StartOptimization()
vars:
tsopt.Job job;

begin
ClearPrintLog;
Print("Starting optimization...");
job = DefineJob();
optimizer = new tsopt.Optimizer;
optimizer.JobDone += OptDone;
optimizer.JobFailed += OptError;
optimizer.ProgressChanged += OptProgress;
optimizer.StartJob(job);
end;

method void OptProgress(Object sender, tsopt.ProgressChangedEventArgs args)
begin
Print("Test ", args.Progress.TestNum.ToString(), " of ", args.Progress.TestCount.ToString());
Print("   ", args.BestValues.FitnessName, " = ", args.BestValues.FitnessValue.ToString());
end;

method void OptDone(object sender, tsopt.JobDoneEventArgs args)

begin
Print("Optimization done");
Print("Net Profit = ", args.Results.NetProfit());
end;

method void OptError(Object sender, tsopt.JobFailedEventArgs args)
begin
Print("Optimization Error: ", args.Error.Message);
end;

Compilamos el código (menú Build->Verify o tecleamos F3) y si todo está correcto debería aparecer un nuevo botón en las Trading Apps como el siguiente:

Si todo ha funcionado correctamente nos aparecerá esta espartana pero funcional ventanita:


Al hacer click en el botón se iniciará la optimización que hayamos programado (en nuestro ejemplo, la del sistema de bandas de Bollinger que hemos comentado sobre el futuro continuo del S&P 500 en barras de 60 minutos) pero por supuesto podemos replicar el código para varios activos y/o timeframes y realizar múltiples optimizaciones simultáneamente (además por defecto TradeStation aprovecha todos los núcleos del procesador).

Por cierto, si queréis ver cómo evoluciona la optimización de la app que hemos creado y ver los mejores resultados podéis acceder al log de Easy Language:

 

Y allí veréis cómo se almacenan los mejores resultados en base al Net Profit (por supuesto podéis cambiarlo dentro del método OptProgress para usar otros criterios):


Conclusión
En este artículo habéis podido ver cómo se realiza la optimización de una estrategia en TradeStation de la manera tradicional, algo que resulta similar a otras plataformas de sistemas, pero también cómo podemos programar todo el proceso usando la potente API de optimización de TradeStation lo cual nos abre nuevos mundos a la hora de agilizar nuestras optimizaciones. Y ya de paso, hemos aprendido a crear nuestra primera App en TradeStation, ¿quién da más en un solo artículo :P?

Saludos,
X-Trader


¿Te gustaría aprender a programar en Easy Language y crear tus propios sistemas en TradeStation? Pues estás de enhorabuena porque ahora puedes apuntarte al curso Mastering EasyLanguage para Sistemas de la mano de Sersan Sistemas, un curso recomendado para aquellos usuarios que ya conocen EasyLanguage y quieren profundizar en el desarrollo e implementación de estrategias de trading automático con TradeStation.