Lehren Sie, eine K-Linie Synthese-Funktion in der Python-Version zu schreiben

Schriftsteller:Lydia., Erstellt: 2022-12-26 09:28:58, Aktualisiert: 2023-09-20 09:48:46

img

Lehren Sie, eine K-Linie Synthese-Funktion in der Python-Version zu schreiben

Bei der Erstellung und Verwendung von Strategien verwenden wir oft einige selten verwendete K-Linien-Periodendaten. Allerdings liefern Austausch und Datenquellen keine Daten zu diesen Perioden. Es kann nur durch die Verwendung von Daten mit einer vorhandenen Periode synthetisiert werden. Der synthetisierte Algorithmus hat bereits eine JavaScript-Version (VerbindungEs ist einfach, ein Stück JavaScript-Code in Python zu transplantieren. Als nächstes schreiben wir eine Python-Version des K-Line-Synthese-Algorithmus.

JavaScript-Version

  function GetNewCycleRecords (sourceRecords, targetCycle) {    // K-line synthesis function
      var ret = []
      
      // Obtain the period of the source K-line data first
      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 
  }

Es gibt JavaScript-Algorithmen. Python kann Zeile für Zeile übersetzt und transplantiert werden. Wenn Sie auf JavaScript-Eingebettete Funktionen oder inhärente Methoden stoßen, können Sie zu Python gehen, um die entsprechenden Methoden zu finden. Daher ist die Migration einfach. Die Algorithmuslogik ist genau die gleiche, außer dass JavaScript Funktion Anrufevar n=d.getTimezoneOffset(). Wenn Sie auf Python migrieren,n=time.altzonein Python wird stattdessen die Zeitbibliothek verwendet. Andere Unterschiede sind nur in Bezug auf die Sprachgrammatik (wie die Verwendung von für Schleifen, Boolean-Werte, logische AND, logische NOT, logische OR usw.).

Migrationscode für Python:

import time

def GetNewCycleRecords(sourceRecords, targetCycle):
    ret = []

    # Obtain the period of the source K-line data first
    if not sourceRecords or len(sourceRecords) < 2 : 
        return None

    sourceLen = len(sourceRecords)
    sourceCycle = sourceRecords[-1]["Time"] - sourceRecords[-2]["Time"]

    if targetCycle % sourceCycle != 0 :
        Log("targetCycle:", targetCycle)
        Log("sourceCycle:", sourceCycle)
        raise "targetCycle is not an integral multiple of sourceCycle."

    if (1000 * 60 * 60) % targetCycle != 0 and (1000 * 60 * 60 * 24) % targetCycle != 0 : 
        Log("targetCycle:", targetCycle)
        Log("sourceCycle:", sourceCycle)
        Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle)
        raise "targetCycle cannot complete the cycle."
    
    multiple = targetCycle / sourceCycle

    isBegin = False
    count = 0 
    barHigh = 0 
    barLow = 0 
    barOpen = 0
    barClose = 0 
    barTime = 0 
    barVol = 0 

    for i in range(sourceLen) : 
        # Get the time zone offset value
        n = time.altzone        

        if ((1000 * 60 * 60 * 24) - (sourceRecords[i]["Time"] * 1000) % (1000 * 60 * 60 * 24) + (n * 1000)) % targetCycle == 0 :
            isBegin = True

        if isBegin : 
            if count == 0 : 
                barHigh = sourceRecords[i]["High"]
                barLow = sourceRecords[i]["Low"]
                barOpen = sourceRecords[i]["Open"]
                barClose = sourceRecords[i]["Close"]
                barTime = sourceRecords[i]["Time"]
                barVol = sourceRecords[i]["Volume"]
                count += 1
            elif count < multiple : 
                barHigh = max(barHigh, sourceRecords[i]["High"])
                barLow = min(barLow, sourceRecords[i]["Low"])
                barClose = sourceRecords[i]["Close"]
                barVol += sourceRecords[i]["Volume"]
                count += 1

            if count == multiple or i == sourceLen - 1 :
                ret.append({
                    "High" : barHigh,
                    "Low" : barLow,
                    "Open" : barOpen,
                    "Close" : barClose,
                    "Time" : barTime,
                    "Volume" : barVol,
                })
                count = 0
    
    return ret 

# Test
def main():
    while True:
        r = exchange.GetRecords()
        r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)      

        ext.PlotRecords(r2, "r2")                                 
        Sleep(1000)

Prüfung

Marktdiagramm von Huobi

img

4-Stunden-Diagramm der Backtest-Synthese

img

Der oben genannte Code dient nur als Referenz; wenn er in spezifischen Strategien verwendet wird, wird er entsprechend den spezifischen Anforderungen geändert und getestet. Wenn es einen Fehler oder Verbesserungsvorschlag gibt, hinterlassen Sie bitte eine Nachricht. Vielen Dank. o^_^ o


Verwandt

Mehr