Procesamiento de datos de línea K en el comercio cuantitativo

El autor:La bondad, Creado: 2019-09-03 11:15:30, Actualizado: 2023-11-07 20:43:41

img

¿Cómo el procesamiento de datos de la línea K en el comercio cuantitativo?

Cuando se escribe una estrategia comercial cuantitativa, utilizando los datos de la línea K, a menudo hay casos en los que se requieren datos de la línea K de ciclo no estándar. por ejemplo, se requieren datos de la línea K de ciclo de 12 minutos y datos de ciclo de línea K de 4 horas. Por lo general, tales ciclos no estándar no están directamente disponibles. Entonces, ¿cómo lidiar con tales necesidades?

Los datos de la línea K del ciclo no estándar se pueden obtener combinando los datos del ciclo más pequeño. Imagínese esto, el precio más alto en múltiples ciclos se cuenta como el precio más alto después de la síntesis de la línea K del ciclo múltiple, y el precio más bajo se calcula como el precio más bajo después de la síntesis, y el precio de apertura no cambia. Se sintetiza el primer precio de apertura de los datos de materia prima de la línea K. El precio de cierre corresponde al precio de cierre de los últimos datos de materia prima de la línea K. El tiempo utiliza el tiempo de la línea de precio de apertura k. El volumen de transacción utiliza los datos de materia prima que se suman y calculan.

Como se muestra en la figura:

  • El pensamiento

Tomemos el activo blockchain BTC_USDT como ejemplo y sintetizemos 1 hora en 4 horas.

img img img img

El tiempo El más alto Abierto. El más bajo Muy cerca.
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

Los datos de cuatro ciclos de una hora se combinan en un solo ciclo de cuatro horas.

El precio de apertura es el precio de apertura de la primera línea K a las 00:00 hora: 11382.57 El precio de cierre es el precio de cierre de la última línea k a las 03:00: 11384.71 El precio más alto es encontrar el precio más alto entre ellos: 11447.07 El precio más bajo es encontrar el precio más bajo entre ellos: 11365.51

Nota: El mercado de futuros de materias primas de China cerró a las 15:00 horas en un día de negociación normal

La hora de inicio del ciclo de 4 horas es la hora de inicio de la primera línea K de 1 hora, es decir, 2019.8.12 00:00

La suma del volumen de todas las líneas k de 1 hora se utiliza como este volumen de líneas k de 4 horas.

Se sintetiza una línea K de 4 horas:

High: 11447.07
Open: 11382.57
Low: 11365.51
Close: 11384.71
Time: 209.8.12 00:00

img

Se puede ver que los datos son consistentes.

  • Implementación del código

Después de entender las ideas iniciales, se puede escribir manualmente el código para realizar los requisitos.

Estos códigos son únicamente de referencia:

function GetNewCycleRecords (sourceRecords, targetCycle) { // K line synthesis function
      var ret = []
      
      // First get the source K line data cycle
      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++) {
          // Get the time zone offset value
          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
  }

  // test
  function main () {
      while (true) {
          var r = exchange.GetRecords() // Raw data, as the basic K-line data of the synthesize K line. for example, to synthesize a 4-hour K-line, you can use the 1-hour K-line as the raw data.
          var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) // Pass the original K-line data r through the GetNewCycleRecords function, and the target cycles, 1000 * 60 * 60 * 4, ie the target synthesis cycle is 4 hours K-line data .

          $.PlotRecords(r2, "r2") // The strategy class library bar can be selected by check the line class library, and calling the $.PlotRecords line drawing class library to export the function drawing.
          Sleep(1000) // Each cycle is separated by 1000 milliseconds, preventing access to the K-line interface too much, resulting in transaction restrictions.
      }
  }

En realidad, para sintetizar la línea K, se necesitan dos cosas. El primero son los datos de la materia prima, es decir, los datos de la línea K de un ciclo más pequeño.var r = exchange.GetRecords()para obtener los datos de la línea K del ciclo más pequeño.

La segunda es calcular el tamaño del ciclo de síntesis, usamos el algoritmo de función GetNewCycleRecords para hacer esto, entonces finalmente se puede devolver los datos de una estructura de matriz de K-línea sintetizada.

Tenga en cuenta:

  1. El ciclo objetivo no puede ser menor que el ciclo de la línea K que pasó en la función GetNewCycleRecords como materia prima para los datos.

  2. El ciclo objetivo debe ser establecido en ciclo cerrado. ¿Qué es un ciclo cerrado?

Por ejemplo:

La línea K del ciclo de 12 minutos comienza a partir de 0:0 cada hora, el primer ciclo es 00:00:00 ~ 00:12:00, y el segundo ciclo es 00:12: 00 ~ 00: 24:00, el tercer ciclo es 00:24: 00 ~ 00:36:00, el cuarto ciclo es 00:36:00 ~ 00:48:00, el quinto ciclo es 00:48 :00 ~ 01:00:00, que son exactamente una hora completa.

Si se trata de un ciclo de 13 minutos, será un ciclo que no está cerrado. Los datos calculados por dicho ciclo no son únicos porque los datos sintetizados difieren según el punto de partida de los datos sintetizados.

Lo ejecutamos en el mercado real:

img

Gráfico de cambio de contraste

img

  • Construir la estructura de datos requerida utilizando datos de línea K

Quiero calcular la media móvil del precio más alto para todas las líneas K. ¿Qué debo hacer?

Por lo general, calculamos los promedios móviles utilizando el promedio de los precios de cierre, pero a veces hay demanda para utilizar el precio más alto, el precio más bajo, el precio de apertura y así sucesivamente.

para estas demandas adicionales, los datos de línea K devueltos por la función exchange.GetRecords() no se pueden pasar directamente a la función de cálculo del indicador.

Por ejemplo: Eltalib.MALa función de cálculo del indicador de media móvil tiene dos parámetros, el primero es el de los datos que se deben transmitir y el segundo es el parámetro del ciclo del indicador.

Por ejemplo, debemos calcular los indicadores que se muestran a continuación.

img

El ciclo de la línea K es de 4 horas.

En el gráfico de cotizaciones del mercado de divisas, se ha establecido una línea media con el parámetro del ciclo de 9.

La fuente de datos calculada utiliza el precio más alto por barra.

img

Es decir, esta línea media móvil consiste en el promedio del precio promedio más alto de nueve ciclos de 4 horas K-line Bar.

Vamos a construir un dato nosotros mismos para ver si es lo mismo con los datos del intercambio.

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

Dado que necesitamos calcular el precio más alto de cada barra para obtener el valor del indicador de la media móvil, necesitamos construir una matriz en la que cada elemento de datos tiene el precio más alto para cada barra.

Se puede ver que elhighsLa variable es inicialmente una matriz vacía, luego atravesamos la variable de datos de línea k r2 (no recuerden la r2?

Leer el precio más alto de cada Bar de r2 (es decir, r2 [i].Alto, i oscila entre 0 y r2. longitud - 1), luego presionar enhighsDe esta manera sólo construimos una estructura de datos que corresponde uno a uno con la K-línea de datos Bar.

En este momento,highs¿Puede pasar eltalib.MAfunción para calcular la media móvil.

Ejemplo completo:

function main () {
     while (true) {
         var r = exchange.GetRecords()
         var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
         if (!r2) {
             Continue
         }
        
         $.PlotRecords(r2, "r2") // Draw the K line
        
         var highs = []
         for (var i = 0 ; i < r2.length ; i++) {
             Highs.push(r2[i].High)
         }
        
         var ma = talib.MA(highs, 9) // use the moving average function "talib.MA" to calculate the moving average indicator
         $.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time) // Use the line drawing library to draw the moving average indicator on the chart
        
         Sleep(1000)
     }
}

Prueba posterior:

img

Puede ver que el valor promedio del indicador de la posición del punto del ratón en la figura es 11466.9289

El código anterior se puede copiar a la estrategia para ejecutar la prueba, recuerde revisar la Draw Line Library y guardarlo!

  • Método de adquisición de datos en línea K para el mercado de criptomonedas

La plataforma FMZ Quant cuenta ya con una interfaz empaquetada, a saber, elexchange.GetRecordsFunción, para obtener datos de línea K.

Lo siguiente se centra en el acceso directo a la interfaz de datos de línea K del intercambio para obtener datos, porque a veces se necesitan especificar parámetros para obtener más líneas K, el paqueteGetRecordsLa interfaz generalmente devuelve 100 k líneas. si te encuentras con una estrategia que inicialmente requiere más de 100 K-líneas, necesitas esperar el proceso de recopilación.

Para hacer que la estrategia funcione lo antes posible, puede encapsular una función, acceder directamente a la interfaz de línea K del intercambio y especificar parámetros para obtener más datos de línea K.

Utilizando el par de operaciones BTC_USDT en el exchange Huobi como ejemplo, implementamos este requisito:

Encuentra la documentación de la API del exchange y ve la descripción de la interfaz de la línea K:

img

https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles

Parámetros:

Nombre Tipo de producto ¿Es necesario? Descripción Valor
el símbolo la cuerda Es cierto Pares de negociación ¿Qué es eso?
el período la cuerda Es cierto Devuelve la granularidad de tiempo de los datos, que es el intervalo de tiempo de cada línea k 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 K líneas de datos [1, 2000]

Código de ensayo:

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")
}

img img

Se puede ver que en el registro, impresiónrecords.lengthes 300, es decir, el número derecordsLa barra de datos de la línea K es 300.img


Relacionados

Más.