K-Liniendatenverarbeitung im quantitativen Handel

Schriftsteller:Gutes, Erstellt: 2019-09-03 11:15:30, Aktualisiert: 2023-11-07 20:43:41

img

Wie verarbeitet die K-Linie Daten im quantitativen Handel?

Bei der Erstellung einer quantitativen Handelsstrategie mit den K-Liniendaten gibt es oft Fälle, in denen nicht-standardmäßige Zyklus-K-Liniendaten erforderlich sind. Zum Beispiel sind 12-minütige Zyklus-K-Liniendaten und 4-stündige K-Linienzyklus-Daten erforderlich. Normalerweise sind solche nicht-standardmäßigen Zyklen nicht direkt verfügbar. Wie befassen wir uns mit solchen Bedürfnissen?

Die Daten der nicht standardisierten Zyklus-K-Linie können durch die Kombination der Daten des kleineren Zyklus erhalten werden. Hierbei wird der höchste Preis in mehreren Zyklen als der höchste Preis nach der Synthese der mehreren Zyklus-K-Linie gezählt, und der niedrigste Preis wird als der niedrigste Preis nach der Synthese berechnet, und der Eröffnungspreis ändert sich nicht. Der erste Eröffnungspreis der Rohstoffdaten der K-Linie wird synthetisiert. Der Schlusskurs entspricht dem Schlusskurs der letzten Rohstoffdaten der K-Linie. Die Zeit verwendet die Zeit der Eröffnungspreislinie k. Das Transaktionsvolumen verwendet die Rohstoffdaten, die summiert und berechnet wurden.

Wie in der Abbildung gezeigt:

  • Denken

Nehmen wir das Blockchain-Asset BTC_USDT als Beispiel und synthetisieren wir 1 Stunde in 4 Stunden.

img img img img

Zeit Höchste Geöffnet Niedrigste Schließen
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

Die Daten von vier 1-Stunden-Zyklen werden zu einer einzigen 4-Stunden-Zyklusdaten zusammengefasst.

Der Eröffnungspreis ist der Eröffnungspreis der ersten K-Linie um 00:00 Uhr: 11382.57 Der Schlusskurs ist der Schlusskurs der letzten K-Linie um 03:00 Uhr: 11384.71 Der höchste Preis ist der höchste Preis unter ihnen zu finden: 11447,07 Der niedrigste Preis ist der niedrigste Preis unter ihnen zu finden: 11365,51

Anmerkung: China Commodity Futures Market schließt an einem normalen Handelstag um 15:00 Uhr

Die 4-Stunden-Zyklusstartzeit ist die Startzeit der ersten 1-stündigen K-Linie, d. h. 2019.8.12 00:00

Die Summe des Volumens aller 1-Stunden-K-Linien wird als dieses 4-Stunden-K-Linienvolumen verwendet.

Eine 4-stündige K-Linie wird synthetisiert:

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

img

Sie können sehen, dass die Daten konsistent sind.

  • Umsetzung des Codes

Nachdem Sie die ersten Ideen verstanden haben, können Sie den Code manuell schreiben, um die Anforderungen zu erfüllen.

Diese Codes dienen nur als Referenz:

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.
      }
  }

Um die K-Linie zu synthetisieren, braucht man zwei Dinge. Das erste sind die Rohstoffdaten, also die K-Linie-Daten eines kleineren Zyklus.var r = exchange.GetRecords()Um die kleineren Daten der Zyklus-K-Linie zu erhalten.

Die zweite ist, um die Größe des Synthese-Zyklus zu ermitteln, verwenden wir den GetNewCycleRecords-Funktionsalgorithmus, um dies zu tun, dann können Sie endlich die Daten einer synthetisierten K-Linien-Array-Struktur zurückgeben.

Bitte beachten Sie:

  1. Der Zielzyklus kann nicht kleiner sein als der Zyklus der K-Linie, die Sie in der Funktion GetNewCycleRecords als Rohstoff für die Daten übergeben haben.

  2. Der Zielzyklus muss auf Zyklus geschlossen eingestellt werden. Was ist ein Zyklus geschlossen? Einfach gesagt, innerhalb einer Stunde oder innerhalb eines Tages werden die Zielzykluszeitbereiche zu einem geschlossenen Kreislauf zusammengefasst.

Zum Beispiel:

Die K-Linie des 12-minütigen Zyklus beginnt jede Stunde von 0:0, der erste Zyklus ist 00:00:00 ~ 00:12:00, und der zweite Zyklus ist 00:12: 00 ~ 00: 24:00, der dritte Zyklus ist 00:24:00 ~ 00:36:00, der vierte Zyklus ist 00:36:00 ~ 00:48:00, der fünfte Zyklus ist 00:48 :00 ~ 01:00:00, die genau eine vollendete Stunde sind.

Wenn es sich um einen Zyklus von 13 Minuten handelt, handelt es sich um einen Zyklus, der nicht geschlossen ist. Die durch einen solchen Zyklus berechneten Daten sind nicht einzigartig, da sich die synthetisierten Daten je nach Ausgangspunkt der synthetisierten Daten unterscheiden.

Führe es auf den echten Markt:

img

Kontrastwechselkarte

img

  • Konstruieren Sie die erforderliche Datenstruktur mit K-Liniendaten

Ich möchte den gleitenden Durchschnitt des höchsten Preises für alle K-Linien berechnen.

Normalerweise berechnen wir die gleitenden Durchschnitte mit dem Durchschnitt der Schlusskurs, aber manchmal gibt es Nachfrage, um den höchsten Preis, den niedrigsten Preis, den Eröffnungspreis und so weiter zu verwenden.

für diese zusätzlichen Anforderungen können die von der Exchange.GetRecords() Funktion zurückgegebenen K-Zeilendaten nicht direkt an die Indikatorberechnungsfunktion übergeben werden.

Zum Beispiel: Dietalib.MADie Funktion zur Berechnung des gleitenden Durchschnittsindikators hat zwei Parameter, der erste ist die Daten, die eingegeben werden müssen, und der zweite ist der Indikatorzyklusparameter.

Wir müssen beispielsweise die Indikatoren wie unten dargestellt berechnen.

img

Der K-Linienzyklus dauert 4 Stunden.

Auf dem Kursdiagramm wurde eine Durchschnittslinie mit dem Zyklusparameter 9 festgelegt.

Die berechnete Datenquelle verwendet den höchsten Preis pro Bar.

img

Das heißt, diese gleitende Durchschnittslinie besteht aus dem Durchschnitt des höchsten Durchschnittspreises von neun 4-Stunden-Zyklus K-Line Bar.

Lassen Sie uns selbst eine Datenbank erstellen, um zu sehen, ob sie mit den Daten der Börse identisch ist.

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

Da wir den höchsten Preis für jeden Bar berechnen müssen, um den Wert des gleitenden Durchschnittsindikators zu erhalten, müssen wir ein Array erstellen, in dem jedes Datenelement den höchsten Preis für jeden Bar hat.

Sie können sehen, dass diehighsDie Variable ist zunächst ein leeres Array, dann durchqueren wir die Datenvariable r2 k-Linien (erinnern Sie sich nicht an die r2? Schauen Sie sich den Code in der Hauptfunktion an, der die 4-Stunden-K-Linie oben synthetisiert).

Lesen Sie den höchsten Preis von jedem Bar von r2 (d. h. r2[i].High, i reicht von 0 bis r2.länge - 1), dann drücken Sie inhighsAuf diese Weise konstruieren wir einfach eine Datenstruktur, die eins zu eins mit der K-Linien-Datenleiste korrespondiert.

In diesem Moment,highskann dietalib.MAFunktion zur Berechnung des gleitenden Durchschnitts.

Vollständiges Beispiel:

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

Rücktest:

img

Sie können sehen, dass der durchschnittliche Indikatorwert der Mauspunktposition in der Abbildung ist 11466.9289

Der obige Code kann in die Strategie kopiert werden, um den Test auszuführen, denken Sie daran, die Draw Line Library zu überprüfen und speichern!

  • K-Line-Datenerfassungsmethode für den Kryptowährungsmarkt

Die FMZ Quant-Plattform verfügt bereits über eine verpackte Schnittstelle, nämlich dieexchange.GetRecordsFunktion, um K-Liniendaten zu erhalten.

Das Folgende konzentriert sich auf den direkten Zugriff auf den Austauschs K-Linie Datenoberfläche Daten zu erhalten, denn manchmal müssen Sie Parameter spezifizieren, um mehr K-Linien zu erhalten, das PaketGetRecordsWenn Sie auf eine Strategie stoßen, die zunächst mehr als 100 K-Zeilen erfordert, müssen Sie auf den Sammelvorgang warten.

Um die Strategie so schnell wie möglich funktionieren zu lassen, können Sie eine Funktion einkapseln, direkt auf die K-Linie-Schnittstelle der Börse zugreifen und Parameter angeben, um mehr K-Linie-Daten zu erhalten.

Mit dem BTC_USDT-Handelspaar auf der Huobi-Börse als Beispiel implementieren wir diese Anforderung:

Finden Sie die API-Dokumentation der Exchange und lesen Sie die Beschreibung der K-Line-Schnittstelle:

img

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

Parameter:

Name Typ Ist das notwendig? Beschreibung Wert
Symbol String - Das stimmt. Handelspaar Ich will nicht, dass du mich verarschst.
Periode String - Das stimmt. Gibt die zeitliche Granularität der Daten zurück, d. h. das Zeitintervall jeder k-Zeile 1 Minute, 5 Minuten, 15 Minuten, 30 Minuten, 60 Minuten, 1 Tag, 1 Monat, 1 Woche, 1 Jahr
Größe ganzzahl falsche Gibt die Anzahl der Datenzeilen zurück [1, 2000]

Prüfcode:

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

Sie können das auf dem Protokoll sehen, Druckrecords.lengthist 300, d. h. die Anzahl derrecordsDie Datenleiste ist 300.img


Verwandt

Mehr