avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

Bringen Sie Ihnen Schritt für Schritt bei, eine Python-Version der K-Line-Synthesefunktion zu schreiben

Erstellt in: 2019-12-21 09:38:26, aktualisiert am: 2024-12-15 15:59:54
comments   4
hits   2836

Bringen Sie Ihnen Schritt für Schritt bei, eine Python-Version der K-Line-Synthesefunktion zu schreiben

Bringen Sie Ihnen Schritt für Schritt bei, eine Python-Version der K-Line-Synthesefunktion zu schreiben

Beim Schreiben und Verwenden von Strategien werden häufig einige ungewöhnliche K-Linien-Zyklusdaten verwendet. Börsen und Datenquellen stellen für diese Zeiträume jedoch keine Daten zur Verfügung. Eine Synthese ist nur unter Verwendung von Daten aus bestehenden Zyklen möglich. Der Synthesealgorithmus hat bereits eine JavaScript-Version (Link), tatsächlich ist es sehr einfach, einen JavaScript-Code auf eine Python-Version zu portieren. Als Nächstes schreiben wir eine Python-Version des K-Line-Synthese-Algorithmus.

JavaScript-Version

  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 
  }

Wenn es einen JavaScript-Algorithmus gibt, kann dieser zeilenweise übersetzt und in Python übertragen werden. Wenn Sie auf integrierte Funktionen oder inhärente Methoden von JavaScript stoßen, suchen Sie einfach nach den entsprechenden Methoden in Python, sodass die Übertragung relativ einfach ist. Die Algorithmuslogik ist genau dieselbe, nur der JavaScript-Funktionsaufrufvar n = d.getTimezoneOffset()Bei der Portierung auf Python verwenden Sie die Zeitbibliothek von Pythonn = time.altzoneersetzen. Weitere Unterschiede bestehen lediglich in der Sprachsyntax (wie etwa die Verwendung von For-Schleifen, Unterschiede bei Booleschen Werten, Unterschiede bei der Verwendung von logischem „und“, logischem „nicht“, logischem „oder“ usw.).

Der transplantierte Python-Code:

import time

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

    # 首先获取源K线数据的周期
    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) : 
        # 获取时区偏移数值
        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 

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

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

prüfen

Huobi-Marktdiagramm Bringen Sie Ihnen Schritt für Schritt bei, eine Python-Version der K-Line-Synthesefunktion zu schreiben

Backtesting des synthetischen 4-Stunden-Charts Bringen Sie Ihnen Schritt für Schritt bei, eine Python-Version der K-Line-Synthesefunktion zu schreiben

Der obige Code dient nur als Lernreferenz. Wenn Sie ihn in einer bestimmten Strategie verwenden, ändern und testen Sie ihn bitte entsprechend Ihren Anforderungen. Wenn Sie Fehler oder Verbesserungsvorschläge haben, hinterlassen Sie bitte eine Nachricht, vielen Dank o^_^o