<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="iso-8859-1" %> <%@ Import Namespace="AutoTradingBot"%> <%@ Import Namespace="System.Configuration"%> <%@ Import Namespace="System.Data"%> .:: Automatización | sistemas automáticos | sistemas de trading | trading automatizado ::.
 :: Análisis en Prueba Externa ::. 

A todos aquellos que usan sistemas de trading la historia que actualmente les voy a contar les será bastante familiar. Cuando comenzamos a interesarnos por el mundo de los sistemas, comenzamos a programar nuestras primeras ideas, a probarlas, optimizarlas, analizarlas, .... empezamos a descubrir un mundo totalmente nuevo para nosotros y realmente, en un principio, nos encontramos como bebes en pañales, con un sinfín de cosas por aprender.

 :: Introducción ::.

Lo más común es comenzar a probar sistemas de libre distribución, del tipo de los que se ofrecen en la página de Visual Chart Group o de los que algunos amables traders ponen a nuestra disposición. Tras unas pocas horas de optimización hemos conseguido el sistema millonario que nos retirará de trabajar para el resto de la vida. Ya no tendremos que seguir soportando a ese plasta de jefe y podré llevar a los niños a Disneyworld. Las estadísticas de nuestra optimización lo dicen y ese sistema es una máquina de hacer dinero.

Tras convencer a nuestra familia para comenzar a operar con “la máquina de hacer dinero”, empezamos no sin miedo, a utilizar las señales de compra/venta que el sistema genera y al cabo del tiempo (normalmente poco tiempo), nos damos cuenta de que nuestros resultados no se parecen en nada a lo que había conseguido tras mi optimización, las rachas de pérdidas son extraordinariamente más grandes que las esperadas y nos envuelve un sentimiento de frustración que acaba por hacernos parar la operativa para recapacitar sobre lo que hemos hecho mal y buscar soluciones.

Esta historia tan típica y que todos hemos sufrido en nuestros comienzos tiene fácil explicación: simplemente habíamos comenzado a operar con un sistema sobreoptimizado, que se había ajustado a la curva de precios histórica, dando unos resultados muy buenos en el pasado, pero con poco valor predictivo futuro. Para evitar este tipo de sobreoptimizaciones, ahorrándonos así varios disgustos, lo más conveniente es aplicar el análisis en prueba externa a nuestros sistemas. Veamos en que consiste.

 :: El Concepto ::.

Supongamos que hoy es día 31 de diciembre de 2000 y tenemos un sistema muy bueno con el que queremos comenzar a operar al día siguiente. El proceso habitual es optimizar nuestro sistema en un conjunto de datos históricos y aplicar el conjunto de parámetros óptimo a la operativa en mercado real a partir del 1 de enero de 2001.
De esta manera podríamos saber como se hubiera comportado nuestro sistema en un conjunto de datos en los que el sistema no ha sido optimizado, o lo que es lo mismo, en un conjunto de datos externos a la optimización. Por lo tanto, en el análisis de prueba externa lo que hacemos es optimizar el sistema en un conjunto de datos históricos determinados y aplicar los parámetros optimizados a otros conjuntos de datos que no habían sido tenidos en cuenta en nuestra optimización inicial.

La idea es dividir nuestro conjunto de datos históricos en diversos “trozos” de datos, optimizando en cada uno de los trozos y aplicando los parámetros óptimos al trozo siguiente. Veámoslo con un ejemplo. Imaginemos que tenemos un conjunto de datos que va desde el 1/1/1998 al 15/5/2003 y queremos analizar la validez de un determinado sistema de trading. Para ello tenemos dos opciones:


1. Tomar el conjunto de datos entero, optimizarlo y comenzar a operar con los parámetros optimizados a partir del día 16/5/2003. Esta manera, que es la que habitualmente se suele utilizar, es totalmente errónea, ya que no nos informa de la bondad del sistema en ningún momento. Simplemente nos dice que ha sido posible obtener unos buenos resultados con nuestro sistema en dicho periodo, pero no sabemos nada acerca del carácter predictivo del sistema, ya que no hemos aplicado el sistema a datos externos.


2. Dividir el conjunto de datos en diversos periodos. Por ejemplo, de la siguiente manera:

Periodo Optimizado
Parámetros aplicados al periodo
1/1/1998 a 31/12/1998
1/1/1999 a 31/3/1999
1/4/1998 a 31/3/1999
1/4/1999 a 30/6/1999
1/7/1998 a 30/6/1999
1/7/1999 a 30/9/1999
...
...
1/4/2002 a 31/3/2003
1/4/2003 a 30/6/2003

En la tabla anterior hemos dividido nuestro conjunto de datos en periodos de 12 meses, aplicando los parámetros optimizados a los 3 meses siguientes, obteniendo de esta manera nuestra secuencia de operaciones en prueba externa. Es importante por lo tanto, seleccionar el periodo hacia atrás (el periodo que vamos a optimizar) y el periodo hacia delante (el periodo “futuro” al que vamos a aplicar los parámetros optimizados). De esta manera podemos saber que hubiera ocurrido en nuestra cuenta si hubiésemos comenzado a operar el 1/1/1999, por ejemplo, con los parámetros optimizados hasta el 31/12/1998.

De esta manera obtendremos una secuencia de operaciones fruto de nuestro análisis de prueba externa, siendo nuestras estadísticas mucho más reales que las obtenidas por la mera optimización del conjunto de datos global.

Además, con este tipo de prueba evitamos la sobreoptimización del sistema y el ajuste a la curva de precios, porque la secuencia de operaciones que hemos conseguido no es fruto de un conjunto de datos optimizado. Posteriormente, sería conveniente aplicar otro tipo de análisis a la secuencia de operaciones externas, para poder determinar nuestro capital necesario, etc... No obstante, esto será tratado en futuros boletines.


 :: Conclusión ::.

Si bien el hecho de que un sistema no haya superado los análisis de prueba externa no es motivo suficiente para decir que ese sistema no es bueno, si es cierto que con los análisis de prueba externa conseguimos una imagen más real de lo que podemos esperar de nuestro sistema, y sobre todo evitamos que nuestro sistema se haya simplemente ajustado a la curva de precios histórica como consecuencia de una sobreoptimización.
Aunque el proceso de realización de la prueba externa puede llegar a convertirse en algo bastante tedioso, es recomendable que realicemos este tipo de pruebas a nuestros sistemas antes de comenzar a operar con ellos y estimar posteriormente los capitales necesarios para comenzar en mercado real con nuestra operativa.

Espero que les haya servido de ayuda este artículo. Para cualquier duda pueden ponerse en contacto conmigo en chaptrader@yahoo.es

 

 :: Stop de Pérdidas y Objetivo ::.

Para explicar la siguiente rutina vamos a utilizar un sistema muy simple, de cruce de medias. Para ello, vemos inicialmente el código vba del sistema original.

Como sabemos, el sistema en vba se divide en 3 partes fundamentales:


1. La definición de parámetros y variables

2. La asignación de valores iniciales a las variables

3. Los cálculos que el sistema realizará en cada nueva barra de datos

 :: La definición de parámetros y variables ::.

Copiamos a continuación el código vba de nuestro sistema sin stops de pérdidas ni objetivos:

Código vba 1
'¡¡ Parameters
Dim PeriodoMedia1 As Long '30
Dim PeriodoMedia2 As Long '100
Dim FinDia As Integer '0

'Parameters !!

Dim MediaMovil1 As Long
Dim MediaMovil2 As Long
Dim HoraCierre As Long


Option Explicit
Public APP As SysUserApp
Implements System


Como podemos observar hemos definido tres parámetros:
- PeriodoMedia1, que será el número de barras o periodos que utilicemos para calcular la media móvil corta.

- PeriodoMedia2, que será el número de barras o periodos que utilicemos para calcular la media móvil larga.

- FinDia, que nos servirá para determinar si queremos hacer intradía o continuo el sistema. Si le asignamos el valor 0, el sistema será continuo, es decir, dejará las posiciones abiertas a fin de día, mientras que si es distinto de 0 el sistema será intradía.

Además, definimos dos variables a las que asignaremos posteriormente el valor de cada una de las dos medias móviles, cuyos cruces generarán nuestras señales de compra/venta. Y otra variable auxiliar (HoraCierre) que utilizamos para realizar cálculos intradía por si decidimos cerrar nuestras posiciones a fin de día

A continuación, pasamos a asignar los valores iniciales a las variables.

 :: La asignación de valores iniciales a las variables (OnInitCalculate) ::.

En esta parte del código tenemos que asignar los valores iniciales de las variables, o en caso de utilizar algún indicador, como es nuestro caso, especificar que indicador es. Así pues, nosotros asignaremos a las dos variables comentadas con anterioridad el cálculo de una media móvil. Veamos el código vba:

Código vba 2

'Public Sub System_OnInitCalculate()
With APP

MediaMovil1 = .GetIndicatorIdentifier(AvSimple, Data, PeriodoMedia1, PriceClose)
MediaMovil2 = .GetIndicatorIdentifier(AvSimple, Data, PeriodoMedia2, PriceClose)
HoraCierre = -1

.StartBar = PeriodoMedia2

End With
End Sub


Mediante el proceso .GetIndicatorIdentifier le decimos a nuestro sistema que a la variable MediaMovil1 le asigne el valor de un indicador, que en este caso será una media móvil simple (AvSimple), de nuestra fuente de datos principal (Data), utilizando para el cálculo de la misma un número determinado de barras o periodos (que viene expresado mediante el parámetro PeriodoMedia1) y tomando los precios de cierre (PriceClose) de cada barra para realizar el citado cálculo.
De la misma manera, asignamos el valor a la variable MediaMovil2.

Además, asignamos al proceso .StartBar el valor del parámetro PeriodoMedia2 (el número de barras para el cálculo de la media móvil larga). De esta manera, el sistema no podrá realizar ningún cálculo adicional hasta que no hayan transcurrido las barras suficientes para poder realizar correctamente el cálculo de nuestros indicadores.

A continuación pasamos a especificar los cálculos que se realizarán en cada barra, indicando las señales de compra/venta, etc...

 :: Cálculos que el sistema realizará en cada nueva barra de datos (OnCalculateBar) ::.

Una vez que hemos asignado los valores iniciales a nuestras variables es necesario que especifiquemos la lógica del sistema que determinará las entradas y salidas que realizamos. En nuestro caso, queremos desarrollar un sistema con cruce de medias, que seguirá la siguiente lógica:

- comprar cuando la media móvil corta cruce hacia arriba a la media móvil larga

- vender cuando la media móvil corta cruce hacia abajo a la media móvil larga
Esto se puede expresar de la siguiente manera, en el código vba:

Código vba 3

'If HoraCierre <> -1 Then
If .Time < HoraCierre Then
If .Date <> .Date(1) Then
HoraCierre = .Time(1)
End If

If .GetIndicatorValue(MediaMovil1) >= .GetIndicatorValue(MediaMovil2) And .GetIndicatorValue(MediaMovil1, 1, 1) < .GetIndicatorValue(MediaMovil2, 1, 1) Then
.Buy AtMarket
End If

If .GetIndicatorValue(MediaMovil1) <= .GetIndicatorValue(MediaMovil2) And .GetIndicatorValue(MediaMovil, 1, 1) > .GetIndicatorValue(MediaMovil2, 1, 1) Then
.Sell AtMarket
End If
Else
If FinDia <> 0 Then
.ExitLong AtMarket
.ExitShort AtMarket
End If

End If
Else
If .Date <> .Date(1) Then
HoraCierre = .Time(1)
End If

End If

Con esto tendríamos terminado nuestro sistema de cruce de medias, que operaría según la lógica comentada con anterioridad. Ahora bien, en ocasiones podemos estar interesados en analizar el efecto de incorporar un stop de pérdidas y un objetivo a nuestro sistema. Veamos como hacerlo.

Lo primero que necesitamos es definir dos nuevos parámetros o variables, según queramos que nuestros stop de pérdidas y objetivo sean fijos o variables. En este caso vamos a utilizar stops fijos, por lo que definiremos dos nuevos parámetros. Veamos el código completo al incorporarle los dos nuevos parámetros:

Código vba 4

''¡¡ Parameters
Dim PeriodoMedia1 As Long '30
Dim PeriodoMedia2 As Long '100
Dim FinDia As Integer '0

Dim StopPerdidas As Double '50
Dim Objetivo As Double '50

'Parameters !!
Dim MediaMovil1 As Long
Dim MediaMovil2 As Long
Dim HoraCierre As Long

Option Explicit
Public APP As SysUserApp
Implements System

El procedimiento OnInitCalculate lo dejamos tal cual está, ya que seguimos teniendo las mismas variables y por lo tanto no tenemos que asignar ningún nuevo valor inicial.
Pasamos por lo tanto a la parte del código que se repetirá en cada barra. Aquí, tendremos que incorporar nuevas líneas de códigos para que el sistema actúe teniendo en cuenta el stop de pérdidas y el objetivo utilizados.

Para ello, hemos de diferenciar entre posiciones largas o compradoras y posiciones cortas o vendedoras. Veamos, como lo hacemos en el código vba:

Código vba 5

Public Sub System_OnCalculateBar(ByVal Bar As Long)
With APP
If HoraCierre <> -1 Then
If .Time < HoraCierre Then

If .Date <> .Date(1) Then
HoraCierre = .Time(1)
End If

If .GetIndicatorValue(MediaMovil1) >= .GetIndicatorValue(MediaMovil2) And .GetIndicatorValue(MediaMovil1, 1, 1) < .GetIndicatorValue(MediaMovil2, 1, 1) Then
.Buy AtMarket
End If

If .GetIndicatorValue(MediaMovil1) <= .GetIndicatorValue(MediaMovil2) And .GetIndicatorValue(MediaMovil1, 1, 1) > .GetIndicatorValue(MediaMovil2, 1, 1) Then
.Sell AtMarket
End If

If .GetMarketPosition = 1 Then 'Cuando estamos largos o comprados
.ExitLong AtStop, 1, .GetEntryPrice - StopPerdidas 'Fijamos el stop de pérdidas
.ExitLong AtLimit, 1, .GetEntryPrice + Objetivo 'Fijamos el objetivo de ganancias
End If

If .GetMarketPosition = -1 Then 'Cuando estamos cortos o vendidos
.ExitShort AtStop, 1, .GetEntryPrice + StopPerdidas 'Fijamos el stop de pérdidas
.ExitShort AtLimit, 1, .GetEntryPrice - Objetivo 'Fijamos el objetivo de ganancias
End If

Else

If FinDia <> 0 Then
.ExitLong AtMarket
.ExitShort AtMarket
End If

End If

Else

If .Date <> .Date(1) Then
HoraCierre = .Time(1)
End If

End If


End With
End Sub

En rojo hemos resaltado la parte de código en la que incorporamos el stop de pérdidas y el objetivo. Para ello utilizamos la función .GetEntryPrice, que nos devuelve el precio de entrada del negocio en vigor, sumando o restándole el stop de pérdidas y el objetivo que definimos como parámetros, dependiendo de que la posición sea larga o corta.
Utilizamos una orden AtStop o AtLimit, dependiendo de la posición en la que se encuentre el precio actualmente respecto al stop de pérdidas o el objetivo. Así pues, tendremos:

- Si estamos comprados, estableceremos una orden en stop (AtStop) si el precio llega al stop de pérdidas. Como el precio actual es superior al precio de nuestro stop de pérdidas, utilizamos una orden en stop.

- Si estamos comprados, estableceremos una orden limitada (AtLimit) si el precio llega al objetivo. Como el precio actual es inferior al precio de nuestro objetivo, utilizamos una orden limitada.

En el caso de que nos encontráramos en posición vendedora, actuaríamos al contrario, es decir:

- Si estamos vendidos, estableceremos una orden en stop (AtStop) si el precio llega al stop de pérdidas. Como el precio actual es inferior al precio de nuestro stop de pérdidas, utilizamos una orden en stop.

- Si estamos vendidos, estableceremos una orden limitada (AtLimit) si el precio llega al objetivo. Como el precio actual es superior al precio de nuestro objetivo, utilizamos una orden limitada.


En esta lección simplemente hemos querido mostrarles como pueden incorporar a su sistema un stop de pérdidas y un objetivo, sin entrar en valoraciones de la bondad o no del sistema utilizado. Así mismo, es posible utilizar datos porcentuales en lugar de absolutos tanto para el stop de pérdidas como para el objetivo, aunque en este caso hemos preferido utilizar datos absolutos, dejando otras opciones posibles a su discreción, con la intención de que puedan practicar modificando el presente código y desarrollando el suyo propio.

Esperamos que esta lección les haya ayudado a aprender como incorporar stops de pérdidas y ganancias a nuestro sistema en Visual Chart, utilizando el lenguaje de programación VBA


Autor: Equipo de Desarrollo de Sistemas deAutoTrading[bot]



Privacidad de Datos
- Reserva Legal
AutotradingBot, Desarrollador y especialista en Sistemas Trading, Derivados Financieros y
Futuro Sistemas sobre Dax, Eurostoxx, Bund, Cac e Ibex, y Sistemas CFDs.
© 2004 - AutoTrading[bot] - Reservados todos los derechos