Almacenando la amplitud en tickers composite
Calcular cualquier cosa relacionada con la amplitud en cualquier mercado ha sido uno de los mayores pasos que hemos dado. Automatizar los cálculos ha sido, para mí, la culminación. Comienzo aquí una serie de artículos en los que explicaré cómo lo hago con Amibroker.
Probablemente si me estáis leyendo también creéis que la amplitud de un grupo de subyacentes es la que define la dirección más probable que tomará el mercado en los próximos días. A fin de cuentas, no deja de ser un indicador de «sentimiento». Si todo sube, es más probable que aquello en lo que estamos invertidos suba porque «todo está conectado». Y lo más fuerte subirá más.
Este mantra aunque no siempre se cumple (el pasado jamás predecirá el futuro) sí ha demostrado tener una alta fiabilidad a la hora de verlo funcionar en sistemas probablemente por su impresionante lógica y los pocos parámetros que pueden ser optimizados. El problema radica en… ¿de dónde obtengo los datos?.
Si me hubierais preguntado hace 3 años: Stockcharts, pero sólo del NYSE. Hace 2 años: de Unicorn, de la web de Yahoo Finance, de la tabla de Excel del Foro de Market Timming… pero seguían siendo «datos concretos que otra persona me suministraba». Todo cambió cuando hace aproximadamente 1 año vi en el Foro fórmulas para calcular amplitudes de watchlists con amibroker. KChis había obrado lo que para mí era un milagro. ¡¡Podía tener la amplitud que quisiese!!. Sin embargo, el proceso de cálculo en mi PC era tedioso porque se basaba en variables dinámicas almacenadas en memoria temporal en función de un ticker seleccionado… Con mi tecnología no era práctico. Y ahí fue donde me puse a investigar otra forma de hacerlo. Mi proceso actual consta de 5 pasos:
1) Crear la fórmula (sólo se hace 1 vez).
2) Llevar a cabo un scan con esa fórmula sobre el watchlist deseado en filter y que en range ponga «All quotes» (importante, si la conexión es a un servidor de datos tenéis que tener activa la opción en settings de «Wait for backfill». De lo contrario se os calculará sin esperar a que estén descargados todos los datos y puede ser un problema). Es importante que antes de darle a scan tuvieseis seleccionado un contrato de futuros que cotice «los mismos días» que los componentes del watchlist. Al final del scan se creará un ticker composite.
3) Seleccionar el ticker composite para ver los indicadores de amplitud y usar un «foreign» predeterminado para ver un gráfico de precio. De esta forma evitamos el típico error del «último día de cotización» basado en que mientras el día no haya cerrado definitivamente amibroker no toma ese valor para calcular la amplitud (por eso si abrís el AMI en real con un servidor de datos podéis ver cómo muchos indicadores diarios cambian a los pocos segundos de estar conectados en función de vuestra tasa de refresco de datos).
Todo este proceso es difícil y falta el paso final: automatizarlo todo. Pero para llegar a eso aún faltan muchas entradas. Hoy mi intención es explicar la fórmula que creé en el Amibroker a un nivel «comprensible» para crear un ticker composite.
Lo primero en la fórmula es crear la variable watchlist y asignarle el nombre del watchlist seleccionado a la variable nombre:
Watchlist = GetOption ("FilterIncludewatchlist"); if( watchlist >= 0 ) { nombre = CategoryGetName(categoryWatchlist,watchlist); }
Luego definimos las típicas variables de amplitud, los valores que suben en un día, los que bajan, el volumen de los que suben, de los que bajan… todo lo que queráis vendría aquí:
Day_suben = C > Ref(C,-1); Day_bajan = C < Ref(C,-1); Day_igual = C == Ref(C,-1); Day_AD = day_suben - day_bajan; Day_totalAD = Day_suben + Day_bajan + Day_igual; Day_vol = V; Day_suben_vol = IIf(Day_suben, V, 0); Day_bajan_vol = IIf(Day_bajan, V, 0);
Ahora añadimos las variables calculadas a un ticker composite que funciona como si fuese un ticker externo, que no requiere calcularlo cada vez que se enciende el ami, sino solo cuando quieras actualizarlo. Para poder tener un ticker composite por cada watchlist tenemos que usar la variable «nombre» creada antes. Para poder usar estas variables de forma normalizada en los gráficos de amplitud todas deben terminar de la misma forma que la fórmula en la que se basan:
AddToComposite( Day_AD , "~"+ nombre + "DayAD", "X", atcFlagDefaults ); AddToComposite( Day_vol , "~"+ nombre + "Dayvol", "X", atcFlagDefaults ); AddToComposite( Day_suben_vol , "~"+ nombre + "Daysubenvol", "X", atcFlagDefaults ); AddToComposite( Day_bajan_vol , "~"+ nombre + "Daybajanvol", "X", atcFlagDefaults );
Como soy un desconfiado por naturaleza me gusta ver cuál es el último día que se ha actualizado un subyacente de un watchlist para detectar rápidamente si existe algún problema. Eso lo he logrado ordenando los subyacentes por «el último día del rango explorado que cotizó».
Filter = 0; Buy = Status("lastbarinrange"); SetSortColumns( 3 );
Y con eso ya tenemos los datos de amplitud calculados en un ticker composite. El código entero seguido sería:
Watchlist = GetOption ("FilterIncludewatchlist"); if( watchlist >= 0 ) { nombre = CategoryGetName(categoryWatchlist,watchlist); } Day_suben = C > Ref(C,-1); Day_bajan = C < Ref(C,-1); Day_igual = C == Ref(C,-1); Day_AD = day_suben - day_bajan; Day_totalAD = Day_suben + Day_bajan + Day_igual; Day_vol = V; Day_suben_vol = IIf(Day_suben, V, 0); Day_bajan_vol = IIf(Day_bajan, V, 0); AddToComposite( Day_AD , "~"+ nombre + "DayAD", "X", atcFlagDefaults ); AddToComposite( Day_vol , "~"+ nombre + "Dayvol", "X", atcFlagDefaults ); AddToComposite( Day_suben_vol , "~"+ nombre + "Daysubenvol", "X", atcFlagDefaults ); AddToComposite( Day_bajan_vol , "~"+ nombre + "Daybajanvol", "X", atcFlagDefaults ); Filter = 0; Buy = Status("lastbarinrange"); SetSortColumns( 3 );
NOTA A LOS LECTORES: Este código es muy muy simple pero es el que considero que debía publicar con fines didácticos. A partir de aquí podéis crear tickers de amplitud para nuevos máximos, nuevos mínimos, ratios, valores por encima de media de Hull, valores alcistas, valores cercas de máximos y mínimos e incluso modificar periodos temporales. Es decir, la imaginación es libre. Os animo a que intentéis calcular/programar lo que necesitéis y si necesitáis ayuda no dudéis en preguntarnos por el foro.
¡¡Buen trading!!
A mi haciendo el proceso me crea los composite, pero el dayAD me sale todo valores 0, el daybajanvol y el daysubenvol me sale el mismo valor, y el dayvol me sale un valor diferente a los anteriores.
Comprueba que los datos se hayan descargado previamente. Para eso tienes que pulsar en el triangulito pequeño que hay al lado de la llave inglesa (entre este icono y el panel de mandos de “parameters”) y seleccionar la opción “Wait for backfill (slow, RT sources only”)”. De esta forma el Ami se esperará a que se descarguen los datos antes de calcular la amplitud.
La segunda cosa a valorar es el archivo «symbolformat» del plugin. Está en «Mis documentos\AndersonWilson\QUANDL». El mío tiene estas líneas:
/ CHRIS dataset
CHRIS/ODE_OR5=s,s,s,C,s,s,s,s,V,I
CHRIS/=O,H,L,C,S,S,V,I
// WIKI dataset
WIKI/AAPL=S,S,S,S,S,S,S,O,H,L,C,V
WIKI/=S,S,S,S,S,S,S,O,H,L,C,V
// YAHOO dataset
YAHOO/INDEX_GSPC=O,H,L,C,V,1
//COT dataset
CFTC/=H,O,C,s,1,2,s,s,V,I
USTREASURY/YIELD=s,s,s,s,s,s,L,s,O,C,H
P.D: Este documento tenía pensado explicároslo en otro post 😀
Muchas gracias Alberto, sois muy grandes.
Deciros que la fórmula completa está mal escrita, era el problema que tenía a la hora de crear los composite.
Gracias por vuestros post
Buenas Miguel he creado la formula en Ami pero me da un error de sintaxis pone que la variable nombre no ha sido iniciada. ¿Como lo resuelvo?
Gracias
Si no me das más datos… En algún sitio has puesto «nombre» y el programa espera encontrar un definición de lo que es esa variable. Yo estoy como tú, tratando de aprender de Alberto y todavía no me he atrevido a ponerlo en marcha…
El código incluye la variable «nombre» y la asocia a las Watchlists que tengas creadas. Si no tienes creada ninguna, no las asocia y no crea la variable. Creo que puede ser eso después de mucho mirarlo, pero no lo he probado
Gracias Miguel.
El problema es que tengo conectado la base de datos a Quandl y me calcula el composite ticket pero sin haber descargado previamente los datos de todos los valores de la watchlist.
Un Saludo.
Buenas 😉
Tal como te ha comentado Miguel, para que el código funcione tienes que correr esta fórmula poniendo en el filtro algún watchlist. Si no pones ninguna watchlist e intentas aplicar la fórmula a toda la base de datos o cualquier otra cosa (sectores, mercados, grupos, GICS o ICB) no te va a funcionar.
Y para que eso no te pase tienes que pulsar en el triangulito pequeño que hay al lado de la llave inglesa (entre este icono y el panel de mandos de «parameters») y seleccionar la opción «Wait for backfill (slow, RT sources only»)». De esta forma el Ami se esperará a que se descarguen los datos antes de calcular la amplitud.
Os prometo que Alberto ha conseguido que los indicadores de amplitud se le carguen a diario automáticamente en su graficador. Yo no he llegado tan lejos y espero ir siguiendo los pasos de sus explicaciones para conseguirlo…