K-Line-Datenverarbeitung in programmatisierten Transaktionen

Schriftsteller:Kleine Träume, Erstellt: 2019-08-13 11:11:38, Aktualisiert: 2023-10-20 20:06:13

img

K-Line-Datenverarbeitung in programmatisierten Transaktionen

Bei der Erstellung von programmatisierten Handelsstrategien mit K-Linien-Daten gibt es häufig die Notwendigkeit, einige nicht-standardmäßige Perioden-K-Linien-Daten zu verwenden, z. B. 12-minütige Perioden-K-Linien-Daten oder 4-Stunden-K-Linien-Perioden-Daten, die normalerweise nicht direkt verfügbar sind. Wie gehen wir mit solchen Bedürfnissen um? Die Antwort ist, dass es eine Lösung gibt. Nicht-standard-Zyklen können durch Daten aus kleineren Zyklen zusammengefasst werden. Man kann sich vorstellen, dass der höchste Preis in mehreren Zyklen als der höchste Preis nach der Synthese, der niedrigste Preis als der niedrigste Preis nach der Synthese berechnet wird, der Eröffnungspreis bleibt unverändert. Sie sehen die folgenden Bilder:

  • Ich denke

    Wir nehmen den Beispiel des Blockchain-Assets BTC_USDT als Beispiel, wo eine Stunde zu vier Stunden wird.

    img

    img

    img

    img

    Zeit Hoch Aufmachen Niedrig Abgeschieden
    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

    Diese vier 1-Stunden-Zyklen, zusammengefasst mit einer 4-Stunden-Zyklen-Wurzel, der Preis ist der Preis für den ersten Tag 00:00: 11382.57. Der Schlusskurs ist der letzte, also der Schlusskurs um 03:00 Uhr: 11384.71 Die höchsten Preise finden Sie hier: 11447.07 Die niedrigsten Preise finden Sie hier: 11365.51 Der 4-Stunden-Zyklus beginnt um 00:00 Uhr und die 1-Stunden-K-Linie beginnt um 00:00 Uhr. Die Summe der Transaktionen pro Stunde (wie die Hauptpreise zusammengesetzt werden, die in den Transaktionsdaten nicht angezeigt werden) wird hier nicht beschrieben.

    Das Ergebnis ist eine 4-stündige K-String, die lautet: Höhe: 11447 Off: 11382.57 Niedrig: 11365.51 Sammlung: 11384.71 Zeit: 19.8.12 00:00

    img

    Die Daten sind einheitlich.

  • Schreiben von Code-Implementierungen

    Wenn die Idee erst einmal verifiziert ist, kann man mit der Hand einen Code schreiben, der den ersten Schritt zur Erfüllung dieses Bedarfs macht.

    Der Code ist nur für Referenznutzung:

      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线接口获取数据过于频繁,导致交易所限制。
          }
      }
    

    Um die K-Linien zu synthetisieren, brauchen wir zwei Dinge: Erstens, wir brauchen die Rohdaten, also die Daten der K-Linien in kleinen Zyklen.var r = exchange.GetRecords()Zweitens ist es notwendig, klar zu definieren, wie groß die Periode ist, d.h. der Ziel-Periode, für die die K-Liniendaten zusammengesetzt werden. Die Algorithmen der Funktion GetNewCycleRecords können dann die Daten einer synthetischen K-Strang-Arraystruktur zurückgeben. Es ist wichtig zu beachten:

    • 1. Die Zieldurchlaufzeit darf nicht kleiner sein als die Dauer der K-Zeile, für die Sie die GetNewCycleRecords-Funktion als Datenrohstoff übergeben. Das ist nicht möglich, wenn man Daten aus kleineren Perioden zusammensetzt.

    • 2. Die gesetzten Zielzyklen müssen zyklusgeschlossen sein. Was ist Zyklusschließung? Einfach ausgedrückt: In einer Stunde oder in einem Tag werden die Zeiträume der Zielzyklen zusammengefasst, um einen geschlossenen Kreislauf zu bilden. Ein Beispiel: Die K-Linie mit einem 12-minütigen Zyklus beginnt z. B. bei 0 Minuten und 0 Sekunden pro Stunde (zum Beispiel bei 0 Uhr).00:00:00 ~ 00:12:00Der zweite Zyklus ist00:12:00 ~ 00:24:00Der dritte Zyklus ist00:24:00 ~ 00:36:00Der vierte Zyklus ist00:36:00 ~ 00:48:00Der fünfte Zyklus ist00:48:00 ~ 01:00:00Das ist eine gute Idee, um eine volle Stunde zusammenzustellen.

      Wenn es sich um eine 13-minütige Periode handelt, also eine nicht geschlossene Periode, sind die Daten, die für diese Periode berechnet werden, nicht einzigartig, da die Daten, die zusammengesetzt werden, je nach Startpunkt unterschiedlich sind.

    Die Live-Disc läuft:img

    Vergleichs-Börsen-Chartsimg

  • Datenstrukturen, die mit K-Daten aufgebaut werden müssen

    Ich möchte die höchste durchschnittliche Preis für jede K-Linie berechnen.

    Normalerweise berechnen wir die Durchschnittslinie als den Durchschnittswert des berechneten Schlusskurses, der die Durchschnittslinie bildet, aber manchmal ist es auch notwendig, den Höchstpreis, den Mindestpreis, den Eröffnungspreis usw. zu berechnen. Wir können es nicht direkt anpassen.exchange.GetRecords()Die zurückgegebenen K-Liniendaten werden direkt in die Indikatorenberechnung übertragen.

    Zum Beispiel:talib.MADie Gleichlinien-Indikator-Rechenfunktion hat zwei Parameter, wobei der erste Parameter die Daten ist, die eingegeben werden müssen, und der zweite Parameter die Indikator-Zyklus-Parameter ist. Also, zum Beispiel, wenn wir die folgenden Indikatoren anstellen.img

    Die K-Linie hat einen 4-stündigen Zyklus. Auf dem Börsenchart ist eine Durchschnittslinie mit einem Durchschnittszyklus von 9 eingestellt. Und die Datenquelle, die berechnet wird, ist der höchste Preis pro Bar.imgDiese Durchschnittslinie ist die durchschnittlich berechnete Durchschnittswerte der höchsten Preise der 9 4-Stunden-Zyklen der K-Linie Bar.

    Wir bauten selbst eine Datenrechnung auf, um zu sehen, ob sie die gleiche ist wie die Berechnungen auf den Charts der Börsen.

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

    Da man den Mittelwert des höchsten Preises für jede Bar berechnen muss, erhält man einen Mittelwert. Dann muss man zunächst eine Array erstellen, in der jedes Datenelement den höchsten Wert für jede Bar entspricht. Man kann sehen, dass die Variable highs anfänglich eine leere Array ist, und dann gehen wir durch die Variable der K-Linien-Daten, r2 (vergessen Sie r2? Schauen Sie sich den Code in der Main-Funktion an, die oben die 4 Stunden K-Linien zusammengesetzt hat). Lesen Sie den höchsten Wert von r2 pro Bar (d.h. r2[i].High, i nimmt den Wertbereich von 0 bis r2.length-1), und schieben Sie in die Highs. Dies erzeugt eine Datenstruktur, die den K-Liniendaten Bar-zu-Bar entspricht.

    Dabei können die Highs in talib übertragen werden.

    Ein 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")                                               // 画出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)
        }
    }
    

    Die Wiederholung läuft:

    img

    Sie können sehen, dass die durchschnittlichen Indikatoren für die Haltestelle der Maus in der Grafik11466.9289

    Der oben genannte Code kann kopiert werden, um einen Test in der Strategie auszuführen. Denken Sie daran, nach dem Klicken auf "Draw Line Library" zu speichern!

  • Wie man K-Line-Daten für den Kryptowährungsmarkt erhält

    Die Erfinder der quantitativen Handelsplattform verfügen bereits über eine verpackte Schnittstelle, die Exchange.GetRecords-Funktion, die K-Leiste-Daten abruft. Der Schwerpunkt liegt hierbei auf dem direkten Zugriff auf die Exchange-K-Datenlinie-Schnittstelle, um Daten zu erhalten, da manchmal Parameter angegeben werden müssen, um mehr K-Datenlinien zu erhalten, die in GetRecords-Schnittstellen verpackt sind. Normalerweise werden 100 Wörter zurückgegeben. Wenn eine Strategie auf mehr als 100 Wörter angewiesen ist, muss sie warten, bis sie gesammelt wird. Um die Strategie so schnell wie möglich in die Tat umzusetzen, kann man eine Funktion selbst einpacken, direkt auf die K-Lein-Schnittstelle der Börse zugreifen und Parameter angeben, um mehr K-Lein-Daten zu erhalten.

    Mit dem BTC_USDT-Trading-Paar, dem Beispiel für den Bitcoin-Trading, haben wir dieses Bedürfnis erfüllt:

    Finden Sie die API-Dokumentation der Börse und sehen Sie sich die Beschreibung der K-Line-Schnittstelle an:img

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

    Parameter:

    Name der Parameter Typ Ist es notwendig? Beschreibung Wertschöpfung
    Symbol String - Das stimmt. Die Transaktion stimmt Ich will nicht, dass du mich verarschst.
    Periode String - Das stimmt. Die Zeitgröße der Daten, also die Zeitspanne für jede Schleife, wird zurückgegeben. 1 Minute, 5 Minuten, 15 Minuten, 30 Minuten, 60 Minuten, 1 Tag, 1 Monat, 1 Woche, 1 Jahr
    Größe ganzzahl falsche Rückgabe von K-Linien-Daten [1, 2000]

    Test-Code: Das ist das erste Mal, dass ich einen Test habe.

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

    Eine Python-Version, ein Beispiel für den Zugriff auf die Token Exchange-Schnittstelle:

#!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画线类库


Python-Version, ein Beispiel für die K-Line-Interface für den Zugriff auf die Binance-Börse:

#!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

Sie können sehen, dass im Log die Aufzeichnung records.length 300 ist, d.h. die Anzahl der Datenbalken in den K-Linien von records 300 ist.img


Verwandt

Mehr

BamsmenKann der Postmaster das Problem lösen?

Bamsmenif (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) { istBegin = wahr Wir sind hier. Es gibt ein Problem mit diesem Satz, man kann nicht einen Tag k mit 3 Stunden oder 6 Stunden zusammenstellen, man kann nur einen Tag k mit 1 Stunde, 2 Stunden und 4 Stunden zusammenstellen.

xis2004Wenn man alle historischen Daten einer Sorte durchkreuzen will, kann man sie dann auch durchkreuzen?

WillzhangDanke für die Antwort.

WillzhangBitte, wie kann ich besser damit umgehen, wenn ich mehr als 300 Bits will? Zum Beispiel 1000 K-Linien Daten.

Kleine TräumeDas ist eine gute Idee, um Zeit zu nehmen.

Kleine TräumeDas ist der Zugriff auf die Daten der Interface der Börse, und wie viele Daten die Börse Ihnen gibt, ist wie viel.

Kleine TräumeWenn die maximale Anzahl von Rückkehren überschritten wird, die von der Austauschoberfläche unterstützt wird, können nur Daten gesammelt werden, so dass genügend K-Line-Daten gespeichert werden.