Procesamiento de datos K-line en transacciones programáticas

El autor:Un sueño pequeño., Creado: 2019-08-13 11:11:38, Actualizado: 2023-10-20 20:06:13

img

Procesamiento de datos K-line en transacciones programáticas

Cuando se escribe una estrategia de negociación programada, a menudo hay una necesidad de usar datos de línea K de ciclos no estandarizados, por ejemplo, datos de línea K de ciclos de 12 minutos o de ciclos de línea K de 4 horas, que normalmente no se pueden obtener directamente. ¿Cómo podemos abordar esta necesidad? La respuesta es que hay una solución. Los ciclos no estándares pueden ser obtenidos mediante la combinación de datos de ciclos más pequeños, se puede imaginar que el precio más alto de varios ciclos, calculado como el precio más alto después de la síntesis, el precio más bajo calculado como el precio más bajo después de la síntesis, el precio de apertura no cambia, se utiliza el primer precio de apertura de la síntesis de los datos de la línea K, el precio de cierre corresponde al último precio de cierre de los datos de la línea K, el tiempo es el tiempo que se tarda en el precio de apertura, el volumen de transacción se calcula y se obtiene con los datos de la línea K. En la foto siguiente:

  • ¿Qué es eso?

    Tomemos como ejemplo el mercado de activos de la cadena de bloques BTC_USDT, que se convierte en 4 horas en 1 hora.

    img

    img

    img

    img

    El tiempo Lo más alto Se abrió. Bajo El tiempo
    2019.8.12 00:00 11447.07 11382.57 11367.2 11406.92
    2019.8.12 01:00 11420 11405.65 11366.6 11373.83
    2019.8.12 02:00 11419.24 11374.68 11365.51 11398.19
    2019.8.12 03:00 11407.88 11398.59 11369.7 11384.71

    Estos cuatro ciclos de una hora, combinados con una raíz de cuatro ciclos de cuatro horas, el precio de apertura es el precio de apertura de la primera línea 00:00:11382.57. El precio de cierre es el último, el precio de cierre a las 03:00:11384.71. El precio más alto para encontrar el precio más alto aquí: 11447.07 El precio más bajo para encontrar el precio más bajo aquí: 11365.51 El ciclo de 4 horas comienza a las 00:00 de la línea K de 1 hora, es 2019.8.12 00:00 La suma de los pedidos de transacciones por hora (la observación principal de cómo se sintetizan los precios, no se muestra en los datos de transacciones), no se hace aquí.

    La línea K de cuatro horas que se compone es: Alturas: 11447.07 ¿Qué es lo que está pasando? Bajo: 113.65.51 Recolección: 11384.71 El tiempo: 08.12.2019 00:00

    img

    Se puede ver que los datos son consistentes.

  • Implementación de código

    Una vez que la idea inicial ha sido validada, se puede escribir un código manual para implementar esta necesidad inicialmente.

    El código es de referencia para aprender:

      function GetNewCycleRecords (sourceRecords, targetCycle) {    // K线合成函数
          var ret = []
          
          // 首先获取源K线数据的周期
          if (!sourceRecords || sourceRecords.length < 2) {
              return null
          }
          var sourceLen = sourceRecords.length
          var sourceCycle = sourceRecords[sourceLen - 1].Time - sourceRecords[sourceLen - 2].Time
    
          if (targetCycle % sourceCycle != 0) {
              Log("targetCycle:", targetCycle)
              Log("sourceCycle:", sourceCycle)
              throw "targetCycle is not an integral multiple of sourceCycle."
          }
    
          if ((1000 * 60 * 60) % targetCycle != 0 && (1000 * 60 * 60 * 24) % targetCycle != 0) {
              Log("targetCycle:", targetCycle)
              Log("sourceCycle:", sourceCycle)
              Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle)
              throw "targetCycle cannot complete the cycle."
          }
    
          var multiple = targetCycle / sourceCycle
    
    
          var isBegin = false 
          var count = 0
          var high = 0 
          var low = 0 
          var open = 0
          var close = 0 
          var time = 0
          var vol = 0
          for (var i = 0 ; i < sourceLen ; i++) {
              // 获取 时区偏移数值
              var d = new Date()
              var n = d.getTimezoneOffset()
    
              if (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) {
                  isBegin = true
              }
    
              if (isBegin) {
                  if (count == 0) {
                      high = sourceRecords[i].High
                      low = sourceRecords[i].Low
                      open = sourceRecords[i].Open
                      close = sourceRecords[i].Close
                      time = sourceRecords[i].Time
                      vol = sourceRecords[i].Volume
    
                      count++
                  } else if (count < multiple) {
                      high = Math.max(high, sourceRecords[i].High)
                      low = Math.min(low, sourceRecords[i].Low)
                      close = sourceRecords[i].Close
                      vol += sourceRecords[i].Volume
    
                      count++
                  }
    
                  if (count == multiple || i == sourceLen - 1) {
                      ret.push({
                          High : high,
                          Low : low,
                          Open : open,
                          Close : close,
                          Time : time,
                          Volume : vol,
                      })
                      count = 0
                  }
              }
          }
    
          return ret 
      }
    
      // 测试
      function main () {
          while (true) {
              var r = exchange.GetRecords()                           // 原始数据,作为合成K线的基础K线数据,例如要合成4小时K线,可以用1小时K线作为原始数据。
              var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)      // 通过 GetNewCycleRecords 函数 传入 原始K线数据 r , 和目标周期, 1000 * 60 * 60 * 4 即 目标合成的周期 是4小时K线数据。
    
              $.PlotRecords(r2, "r2")                                 // 策略类库栏 可以勾选画线类库,调用 $.PlotRecords 画线类库 导出函数 画图。
              Sleep(1000)                                             // 每次循环间隔 1000 毫秒,防止访问K线接口获取数据过于频繁,导致交易所限制。
          }
      }
    

    En realidad, para sintetizar líneas K, se necesitan dos cosas: primero, se necesitan datos de las materias primas, es decir, datos de las líneas K de ciclos pequeños, en el ejemplo anterior.var r = exchange.GetRecords()Se obtienen datos de línea K de ciclos pequeños. En segundo lugar, se necesita definir qué ciclo es el mayor, es decir, el ciclo objetivo para la síntesis de datos de línea K. Luego, con el algoritmo de la función GetNewCycleRecords, se puede devolver finalmente los datos de una estructura de arquetipos de K líneas sintetizadas. En este sentido, el gobierno de los Estados Unidos ha tomado una decisión en este sentido.

    • 1, el ciclo objetivo no puede ser menor que el ciclo de la línea K de la función GetNewCycleRecords como material de datos. Los datos de los ciclos más pequeños no se pueden sintetizar con ciclos más pequeños.

    • 2, el ciclo objetivo que se establece debe ser cerrado. ¿Qué es el cierre del ciclo? En pocas palabras, es un rango de tiempo de los ciclos de objetivos que se combinan en una hora o en un día para formar un ciclo cerrado. Por ejemplo: Por ejemplo, la línea K de un ciclo de 12 minutos, que comienza a partir de 0 minutos 0 segundos de cada hora (por ejemplo, a 0 horas), el primer ciclo es00:00:00 ~ 00:12:00El segundo ciclo es00:12:00 ~ 00:24:00El tercer ciclo es00:24:00 ~ 00:36:00El cuarto ciclo es00:36:00 ~ 00:48:00El quinto ciclo es el siguiente.00:48:00 ~ 01:00:00En el caso de los niños, la hora es la misma que la hora.

      Si es un ciclo de 13 minutos, es decir, un ciclo no cerrado, los datos calculados en este ciclo no son únicos, ya que los datos sintetizados difieren según el punto de inicio de los datos sintetizados.

    El disco está funcionando:img

    Comparación de los gráficos de los mercadosimg

  • La estructura de datos que se necesita para construir datos de línea K

    A menudo mis amigos me preguntan, ¿cómo puedo calcular la línea media del precio más alto de cada K?

    Normalmente, las medias son las medias de los precios de cierre calculados, que constituyen las medias, pero también hay veces que se necesita calcular el precio más alto, el precio más bajo, el precio de apertura, etc. No se puede decir directamente en este momento.exchange.GetRecords()Los datos de la línea K devueltos por la función se transmiten directamente a la función de cálculo de indicadores.

    Por ejemplo:talib.MALa función de cálculo de indicadores homogéneos tiene dos parámetros, el primero es el parámetro de datos a transmitir, y el segundo es el parámetro de ciclo del indicador. Por ejemplo, vamos a calcular el indicador del siguiente gráfico.img

    La línea K tiene un ciclo de 4 horas. En el gráfico de la bolsa, se ha establecido una línea recta con un parámetro de ciclo de la línea recta de 9. La fuente de datos que se ha configurado para calcular es el precio más alto por barra.imgEs decir, esta línea media es el promedio calculado de los precios más altos de los 9 ciclos de 4 horas de la línea KBar, que consta de una línea media de indicadores.

    En el caso de los gráficos de las bolsas de valores, los datos de las bolsas de valores son los mismos que los de las bolsas de valores.

    var highs = []
    for (var i = 0 ; i < r2.length ; i++) {
        highs.push(r2[i].High)
    }
    

    Como se calcula el valor medio del precio más alto de cada Bar, se obtiene un indicador de línea recta. Entonces, primero se necesita construir una matriz en la que cada elemento de datos sea el valor máximo correspondiente a cada barra. Se puede ver que las variables highs comienzan como una matriz vacía, y luego vamos a recorrer esta variable de datos de la línea K r2 (¿no recuerdan r2? Se lee el valor máximo de r2 por Bar (es decir, r2[i].High, i toma el rango de valor de 0 a r2.length - 1) y se empuja a los altos.

    En este momento, los máximos se pueden transmitir a talib. La función MA calcula la línea media.

    Un ejemplo completo:

    function main () {
        while (true) {
            var r = exchange.GetRecords()
            var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
            if (!r2) {
                continue
            }
            
            $.PlotRecords(r2, "r2")                                               // 画出K线
            
            var highs = []
            for (var i = 0 ; i < r2.length ; i++) {
                highs.push(r2[i].High)
            }
            
            var ma = talib.MA(highs, 9)                                           // 用均线指标函数 talib.MA 计算 均线指标
            $.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time)     // 使用画线类库把均线指标画在图表上
            
            Sleep(1000)
        }
    }
    

    La prueba está en marcha:

    img

    Se puede ver que los valores de los indicadores de línea media de la posición del ratón en el gráfico son:11466.9289

    El código puede ser copiado para ejecutar pruebas en la política, ¡recuerda guardar después de seleccionar la librería de líneas de dibujo!

  • Cómo obtener datos de la línea K del mercado de la moneda digital

    Los inventores de la plataforma de intercambio cuantitativo ya tienen una interfaz envuelta, la función exchange.GetRecords, para obtener datos de K-line. A continuación se explica el acceso directo a la interfaz de datos de línea K de la bolsa para obtener datos, ya que a veces se necesita especificar parámetros para obtener más líneas K, envuelto en la interfaz GetRecords. Por lo general, se devuelven 100 bits. Si se encuentra con una estrategia que inicialmente requiere más de 100 bits, se requiere recopilar una espera. Para hacer que la política funcione lo más rápido posible, puede envasar una función por sí mismo, acceder directamente a la interfaz de línea K de la bolsa y especificar parámetros para obtener más datos de línea K.

    En el caso de BTC_USDT, la transacción de bitcoins es un ejemplo de lo que se necesita:

    Para encontrar la documentación de la API de la bolsa, consulte la descripción de la interfaz de línea K:img

    https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
    

    Parámetros:

    Nombre del parámetro Tipo de trabajo ¿Es necesario? Descripción Valoración
    el símbolo la cuerda Es cierto El trato está bien. ¿Qué es eso?
    el período la cuerda Es cierto Devuelve el tiempo de grabación de los datos, es decir, el intervalo de tiempo de cada pieza. 1 minuto, 5 minutos, 15 minutos, 30 minutos, 60 minutos, 1 día, 1 mes, 1 semana, 1 año
    tamaño número entero - No es cierto. Devuelve el número de líneas de datos de K [1, 2000]

    El código de prueba:

    function GetRecords_Huobi (period, size, symbol) {
        var url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
        var ret = HttpQuery(url)
        
        try {
            var jsonData = JSON.parse(ret)
            var records = []
            for (var i = jsonData.data.length - 1; i >= 0 ; i--) {
                records.push({
                    Time : jsonData.data[i].id * 1000,
                    High : jsonData.data[i].high,
                    Open : jsonData.data[i].open,
                    Low : jsonData.data[i].low,
                    Close : jsonData.data[i].close,
                    Volume : jsonData.data[i].vol,
                })
            }
            return records
        } catch (e) {
            Log(e)
        }
    }  
    
    
    function main() {
        var records = GetRecords_Huobi("1day", "300", "btcusdt")
        Log(records.length)
        $.PlotRecords(records, "K")
    }
    

    La versión de Python, ejemplo de cómo acceder a la interfaz de un intercambio de tokens:

#!python3
import json
import urllib2

def GetRecords_Huobi(period, size, symbol):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
    request = urllib2.Request(url)  
    request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')  
    opener = urllib2.build_opener()  
    f= opener.open(request)  
    ret = f.read().decode('utf-8')  
    
    try :
        jsonData = json.loads(ret)
        
        records = []
        for i in range(len(jsonData["data"]) - 1, -1, -1):
            records.append({
                "Time" : jsonData["data"][i]["id"] * 1000, 
                "High" : jsonData["data"][i]["high"], 
                "Open" : jsonData["data"][i]["open"], 
                "Low" : jsonData["data"][i]["low"], 
                "Close" : jsonData["data"][i]["close"], 
                "Volume" : jsonData["data"][i]["vol"], 
            })
        return records
    except Exception as e:
        Log(e)
        
def main():
    r = GetRecords_Huobi("1day", "300", "btcusdt")
    Log(len(r))
    ext.PlotRecords(r, "K")   # 需要引用Python画线类库


La versión de Python, un ejemplo de la interfaz de línea K para acceder al Bitcoin Exchange:

#!python3
import json
import urllib2

def GetRecords_Huobi(period, size, symbol):
    headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    url = "https://api.binance.com/api/v3/klines?symbol=" + symbol + "&interval=" + period
    request = urllib2.Request(url)  
    request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')  
    opener = urllib2.build_opener()  
    f= opener.open(request)  
    ret = f.read().decode('utf-8')  
    try :
        jsonData = json.loads(ret)
        
        records = []
        for i in range(len(jsonData)):
            records.append({
                "Time" : float(jsonData[i][0]),
                "High" : float(jsonData[i][2]), 
                "Open" : float(jsonData[i][1]), 
                "Low" : float(jsonData[i][3]), 
                "Close" : float(jsonData[i][4]), 
                "Volume" : float(jsonData[i][5]), 
            })
        return records
    except Exception as e:
        Log(e)
        
def main():
    r = GetRecords_Huobi("1m", "300", "BTCUSDT")
    Log(len(r))
    ext.PlotRecords(r, "K")   # 需要引用Python画线类库


img

img

Como se puede ver en el registro, imprimir records.length es 300, es decir, registros K línea de datos de la barra tiene un número de 300.img


Relacionados

Más.

los guardias de seguridad¿Puede el editor arreglar el problema? No se puede hacer k días de 3 horas o 6 horas.

los guardias de seguridadif (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) { isBegin = verdad ¿Qué quieres decir? Esta frase tiene un problema, no se puede sintetizar k días con 3 horas o 6 horas, sólo se puede sintetizar k días con 1 hora, 2 horas, 4 horas de línea k.

El año 2004¿Puedes escalar toda la información histórica de una especie?

¿Qué quieres?Gracias por la respuesta.

¿Qué quieres?Por favor, ¿cómo se maneja mejor si se quiere más de 300 bits? por ejemplo, 1000 bits de datos de K-line.

Un sueño pequeño.Bueno, tomé el tiempo para cambiarlo.

Un sueño pequeño.Esto es para acceder a los datos de la interfaz de un intercambio, y la cantidad de datos que el intercambio te da es la cantidad.

Un sueño pequeño.Si se excede el número máximo de retornos soportados por la interfaz de intercambio, solo se puede recopilar suficiente cantidad de datos de la línea K.