4 votos

Detectar patrón a partir de datos OHLC en Python

Estoy tratando de crear un script que, a partir de datos estándar de OHLC, encuentre patrones. El patrón específico que estoy buscando en este momento es un movimiento lateral después de un movimiento hacia arriba, aquí tienes un ejemplo:

Así que básicamente mi código debería detectar cuando el precio está dentro de una caja como las de arriba.

Sé que esto no es fácil de hacer y no estoy buscando que alguien dé su código, solo necesito ayuda para encontrar una dirección general o algunas fuentes/biblioteca sobre este tema, si las hay.

Mi idea era la siguiente: detectar cuándo el precio está subiendo y, si el precio, después de subir, comienza a moverse entre un intervalo X e Y (sin subir o bajar demasiado), etiquetarlo como un rango (que es lo que estoy buscando). Creo que esto debería funcionar, pero no tengo idea de cómo ponerlo en código.

Esto es lo que tengo:

import copy
import urllib
import numpy as np
import pandas as pd
import cfscrape
import json
import datetime
from datetime import datetime as dt

BU = cfscrape.create_scraper()
URL = "https://api.binance.com/api/v1/klines?&symbol=ADABTC&interval=1h&limit=250"

ResultRaw = BU.get(URL, timeout=(10, 15)).content
Result = json.loads(ResultRaw)

for x in Result:
    TimeUnix = float(x[0]) / float(1000)
    K = datetime.datetime.fromtimestamp(TimeUnix)
    x[0] = K

    Variation = Result.index(x)

    Previous = Variation-1

    Variation = ((float(x[4])-float(x[1]))/float(x[1]))*100

    print(Variation)

df = pd.DataFrame([x[:6] for x in Result], 
                  columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'])

format = '%Y-%m-%d %H:%M:%S'
df['Date'] = pd.to_datetime(df['Date'], format=format)
df = df.set_index(pd.DatetimeIndex(df['Date']))
df["Open"] = pd.to_numeric(df["Open"],errors='coerce')
df["High"] = pd.to_numeric(df["High"],errors='coerce')
df["Low"] = pd.to_numeric(df["Low"],errors='coerce')
df["Close"] = pd.to_numeric(df["Close"],errors='coerce')
df["Volume"] = pd.to_numeric(df["Volume"],errors='coerce')

Esto es lo que estoy haciendo:

  1. Recuperar datos
  2. Convertirlos en datos JSON
  3. Para cada fila, determinar cuánto cambió el precio en términos de porcentaje, esto es lo que hace Variation
  4. Convertirlo en un dataframe de Pandas

¡Cualquier tipo de ayuda es apreciada!

0 votos

Gracias por tu respuesta @noob2. Mi propósito inicial era encontrar una forma de detectar triángulos/las cunas/pennantes alcistas, pero al ver que encontrar dicho patrón específico desde el código podría ser demasiado difícil de hacer, decidí hacer lo siguiente: si el precio se dispara y luego no vuelve a bajar, sino que comienza a moverse en un rango, detectar ese rango

1 votos

Tl;dr lo que estoy tratando de hacer es detectar cuándo el precio comienza a consolidarse después de una ola alcista

1 votos

Puede querer considerar la agregación de datos OHLC en barras de precios , y echar un vistazo al método de Triple Barrera y escaneo de tendencias . El paquete de Python mlfinlab implementa estos (de Prado 2018 Avances en el aprendizaje automático financiero)

8voto

John Rennie Puntos 6821

Hasta donde yo sé, no hay ninguna biblioteca. Junto con otros investigadores, implementamos esto hace 20 años en scheme (sí, fue hace mucho tiempo, cuando Lisp, y no Python, era el lenguaje de la IA).

Nuestra metodología (que fue realmente rápida), fue la siguiente

  1. necesitas una escala de tiempo, una semana por ejemplo
  2. marcar todos los mínimos locales y máximos locales en la escala de tiempo
  3. ahora necesitas formar líneas que pasen por dos de ellos y no crucen la "línea de precio", si piensas un poco al respecto; para ser eficiente
    • solo puedes unir mínimos locales juntos o máximos locales juntos, por lo tanto necesitas un código que puedas ejecutar dos veces, una vez que "invertiste" el precio (es decir, $\times (-1)$).
    • una vez que detectes que la línea que une $m_i$ a $m_j$ cruza la "línea de precio", puedes eliminar de tu lista muchos $m_k$ donde $k>j$ si están por encima de la línea $[m_i,m_j)$
  4. ahora tienes una colección de líneas que unen dos mínimos locales (no necesariamente consecutivos) $(m_i,m_j)$ juntos, "solo" tienes que
    • tener el ángulo con el eje horizontal de cada línea
    • verificar que las líneas que tienen un mínimo local en común tengan el "mismo ángulo" (necesitas un umbral para diferenciar dos ángulos; si quieres ser realista, calcular el umbral correcto es complicado)
    • ahora tienes una lista de líneas que contienen 3 mínimos locales
    • puedes iterar
  5. en esta etapa tienes una gran colección de líneas, caracterizadas por
    • un punto de inicio y un punto de parada (donde cruzan la línea de precio o un extremo local)
    • su ángulo con el eje $x$
    • su número de "puntos de apoyo" (nota que si tienes 3 "puntos alineados", tienes 3 líneas diferentes: 2 con 2 puntos y una con 3 puntos)
  6. necesitas escribir un lenguaje "regex" para crear combinaciones de esas líneas, como
    • un triángulo abierto es: una línea superior y una línea inferior, con un ángulo abierto positivo, abarcando al menos 3 fechas en común
    • un hombro-cabeza-hombro está compuesto por tres líneas: dos líneas superiores (o inferiores) con ángulos "casi simétricos" y una línea inferior (o superior) "casi horizontal", abarcando al menos 5 fechas en común

Si lo implementas, por favor envíame una copia de tu código ;{)}

[EDIT] Parece que hay una publicación en medium, que señala un código de quantopian, que es muy similar a mi descripción. Sin embargo, el código parece ser muy pobre.

Por ejemplo, aquí hay una línea de código para encontrar máximos locales (60 días) en pandas:

prices.iloc[np.where((prices.rolling(60,center=True).max()==prices).values)[0],:]

Mientras que en el código de quantopian tienen 20 líneas complejas de código (deberían ser 2 ya que hacen mínimos y máximos). Mi consejo es reimplementar, francamente no es tan complejo.

0 votos

¡Muchas gracias por tu respuesta! Fue realmente muy útil. Me gustaría enviarte el código para que lo revises, pero la dura verdad es que todavía no tengo ninguno. Estoy en una etapa en la que tengo muchos conceptos en mente, pero no tengo idea de cómo plasmar ninguno de ellos en código. Aquí tienes algunas de las aproximaciones (muy teóricas) que tenía en mente (mensaje siguiente):

0 votos

1) Creando una red neuronal, alimentándola con imágenes de patrones que me gustan y dejándola recorrer gráficos para ver si puede encontrar los patrones que elegí 2) Un enfoque más matemático que implicaría usar mínimos y máximos, tal como sugeriste 3) Encontrar una forma de convertir datos ohlc en una serie de valores que pueda usar para "cuantificar" ese patrón, luego puedo recorrer otros gráficos y ver si hay nuevos patrones que tengan valores similares al que "cuantifiqué"

0 votos

@Jack022 no estoy seguro de que una red neuronal sea eficiente en esto, el enfoque geométrico sería mi preferencia (en general me gustan las redes neuronales: arxiv.org/abs/2006.09611 pero no para esto)

2voto

Simon Puntos 106

¿Podrías utilizar la técnica de etiquetado de banderas de matriz? A continuación se proporciona documentación y siempre puedes diseñar tus propias banderas personalizadas.

Creo que será una buena herramienta para investigar: https://mlfinlab.readthedocs.io/en/latest/labeling/labeling_matrix_flags.html

0 votos

Gracias un montón. Este es un buen recurso. Estoy echando un vistazo.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X