Cualquiera que haya estado interesado en acciones o criptomonedas ha visto estas líneas adicionales en los gráficos. Es posible que haya escuchado las opiniones de que no funcionan. Pero mejoran enormemente mi capacidad de negociación, al tiempo que muestran muchos datos importantes. Pero, ¿cómo funcionan realmente? ¿Y a quién puede ser útil?
Definitivamente deberías leer esto si:
- Los usas en el comercio diario
- Estás planeando escribir un bot comercial
- Si desea implementar una estrategia comercial o indicadores usted mismo

Los
indicadores técnicos más a menudo son una función de ventana, una función recursiva o una función ponderada de precios / volúmenes que se extrae de la bolsa de valores en formato UOHLCV (tiempo unix, abierto, alto, bajo, cerrado, volumen). No es raro que los indicadores utilicen diferentes filtros, mínimos y máximos u otros indicadores como base para los cálculos posteriores.
Media móvil simple (SMA)
Al codificar indicadores, es muy conveniente utilizar un enfoque funcional. Por ejemplo, el promedio móvil es solo el promedio de cada valor de la ventana móvil.
function sma($close, window) { return rolling(x => mean(x), window, $close); }
donde
mean es la operación que calcula el promedio de la matriz y el
balanceo es la combinación de la función de ventana que para cada elemento existente en la matriz produce una matriz de los últimos n elementos y la
operación que pliega esta ventana en un número.
function rolling(operation, window, array) { let result = []; for (let i = 0; i < array.length; i++) { if (i + 1 < window) { result.push(NaN); } else { result.push(operation(array.slice(i + 1 - window, i + 1))); } } return result; }
El
SMA es un indicador rezagado y ayuda a determinar la tendencia. Se dibuja como superposición en el gráfico y los primeros valores generalmente se descartan. Se pueden usar dos promedios móviles juntos para generar señales cruzadas.

Un crossover alcista ocurre cuando un promedio móvil relativamente corto se rompe con un promedio móvil largo. El promedio móvil ponderado exponencialmente se usa con mayor frecuencia en la práctica, porque una función de ventana ponderada reduce el efecto de retraso.
Desviación estándar (STDEV)
Si reemplazamos la función
media en SMA con la desviación estándar, obtendremos una desviación estándar deslizante
function stdev($close, window) { return rolling(x => sd(x), window, $close); }
Donde se considera que
sd es la raíz cuadrada de la varianza y comúnmente sin la corrección de Bessel. Asumiremos que todos entienden cómo implementar
SD
La raíz cuadrada de la varianza se utiliza porque la varianza misma se mide en dólares suqare en términos de teoría de la dimensión y no porque alguien haya registrado una marca comercial o lo que sea.
Bandas de Bollinger (BBAND)
Por lo tanto, ya hemos implementado dos indicadores básicos que podemos combinar y obtener otros nuevos. Por ejemplo, si consideramos la suma puntual de la media móvil y la desviación estándar multiplicada por 2, obtendremos la parte superior de la banda de Bollinger y la parte inferior que obtendremos si restamos.
function bb($close, window, mult) { let middle = sma($close, window); let upper = pointwise((a, b) => a + b * mult, middle, stdev($close, window)); let lower = pointwise((a, b) => a - b * mult, middle, stdev($close, window)); return { lower : lower, upper : upper}; }
donde la función
pointwise es otra función útil
export function pointwise(operation, ...arrays) { let result = []; for (let i = 0, len = arrays[0].length; i < len; i++) { let iarr = (i) => arrays.map(x => x[i]); result[i] = operation(...iarr(i)); } return result; }
y solo realiza
operaciones con varias matrices

Las bandas de Bollinger ayudan a determinar la calma antes del gran movimiento del precio, y se usan como una herramienta para desplazar la volatilidad directamente en el gráfico, la desviación estándar se resta / agrega del promedio móvil para mostrarse como una superposición en un gráfico con el precio.
Promedio móvil exponencial (EMA)
¿Cómo podemos reducir el retraso del promedio móvil simple? Como calcula la media de los últimos n precios de cierre, podemos entender que podemos realizar la suma con cierta ponderación y reducir la contribución de los precios anteriores.
Por ejemplo si elegimos
y una constante
eso es menos de uno, entonces obtenemos un peso infinitamente decreciente, si agregaremos los precios comenzando por el más nuevo.

También es posible aproximar los cálculos y obtener una ecuación recursiva si ampliamos la ventana a la longitud total y suponemos que la contribución de las colas es pequeña.
Finalmente, necesitamos algún valor α = 1 - q como constante de suavizado. Es posible
probar que cuando elegimos
el centro de masa de las tablas de peso EMA y SMA anteriores se vuelven iguales. En código esto parece mucho más simple.
function ema($close, window, weight = null) { weight = weight ? weight : 2 / (window + 1); let ema = [ mean($close.slice(0, window)) ]; for (let i = 1; i < $close.length; i++) { ema.push($close[i] * weight + ema[i - 1] * (1 - weight)); }; return ema; }
En general, este es el mismo promedio móvil pero más sensible.

La efectividad del uso depende de su experiencia y de la configuración utilizada. Por ejemplo, en
este sitio, los parámetros se eligen bastante bien.
Media móvil convergencia divergencia (MACD)
Gerald Appel en 1979 presentó uno de los indicadores más simples y efectivos disponibles. Convierte dos indicadores EMA de tendencia en un oscilador de impulso y ofrece lo mejor de ambos mundos: seguimiento de tendencia e impulso. En términos generales, el histograma MACD es un derivado del precio. Se dibuja en un nuevo sistema de coordenadas en lugar de una superposición y se representa con dos líneas y un histograma.

Para calcular la línea MACD necesitamos restar la EMA larga de la corta, eso es todo. Otra EMA de esta línea con una pequeña ventana producirá la línea de señal. El histograma se obtiene por diferencia entre los dos resultados anteriores.
function macd($close, wshort, wlong, wsig) { let line = pointwise((a, b) => a - b, ema($close, wshort), ema($close, wlong)); let signal = ema(line, wsig); let hist = pointwise((a, b) => a - b, line, signal); return { line : line, signal : signal, hist : hist }; }
Matriz de correlación
Si le interesa la inversión a largo plazo y el análisis de cartera, encontrará útil la matriz de correlación.
function cor(f, g) { let Ef = mean(f), Eg = mean(g); let Ef2 = mean(pointwise((a) => a * a, f)); let Eg2 = mean(pointwise((a) => a * a, g)); let Efg = mean(pointwise((a, b) => a * b, f, g)); return (Efg - Ef * Eg) / Math.sqrt((Ef2 - Ef * Ef) * (Eg2 - Eg * Eg)); }
Aquí matriz de correlación de diferentes criptoactivos en 2 meses.

Prueba de unidad indicadora
Si tenemos tablas precisas de valores de indicadores, podemos probar con precisión nuestro cálculo. Hay varias formas de determinar la medida de error entre las dos funciones, pero en este caso el error cuadrático medio normalizado se ajusta mejor porque es una cantidad adimensional en contraste con RMSE y es relativo.
Por ejemplo, bitcoin puede costar $ 20,000 y una diferencia en $ 10 es pequeña, mientras que cuando el altcoin completo puede costar $ 1 y la diferencia en $ 10 es enorme.
function nrmse(f, g) { let sqrDiff = pointwise((a, b) => (a - b) * (a - b), f, g); return Math.sqrt(mean(sqrDiff)) / (Math.max(...f) - Math.min(...f)); }
También podemos usar MAPE pero no es conmutativo y tiene un problema cercano a cero.
Conclusión
Entonces eso es todo. En unas pocas líneas de código podemos expresar los indicadores técnicos básicos, si te gusta esta explotación revisa mi biblioteca en github. Allí puedes encontrar mucho más. Si desea utilizar algunos algoritmos de aprendizaje automático para su bot, verifique el indicador Zig-Zag como puntos de entrada.
Referencias
1.
StockCharts : una lista de algoritmos con datos de prueba en las tablas.
2.
Cryptowatch : parámetros de indicadores bien ajustados.
3.
Github : mi código fuente.
PD: si encuentra algún error en el texto, dígamelo directamente.