파이썬 버전에서 K-라인 합성 함수를 작성하는 법을 가르쳐

저자:리디아, 창작: 2022-12-26 09:28:58, 업데이트: 2023-09-20 09:48:46

img

파이썬 버전에서 K-라인 합성 함수를 작성하는 법을 가르쳐

전략을 작성하고 사용할 때, 우리는 종종 드물게 사용되는 K-라인 기간 데이터를 사용합니다. 그러나 교환 및 데이터 소스는 이러한 기간에 대한 데이터를 제공하지 않습니다. 기존 기간과 데이터를 사용하여만 합성 할 수 있습니다. 합성 알고리즘은 이미 자바스크립트 버전을 가지고 있습니다 (링크) 사실, 자바스크립트 코드를 파이썬으로 이식하는 것은 쉽습니다. 다음으로, K-라인 합성 알고리즘의 파이썬 버전을 작성해 보겠습니다.

자바스크립트 버전

  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 
  }

자바스크립트 알고리즘이 있다. 파이썬은 줄별로 번역되고 이식될 수 있다. 자바스크립트 내장 함수나 내재된 메소드를 만나면 해당 메소드를 찾기 위해 파이썬으로 이동할 수 있다. 따라서 마이그레이션은 쉽다. 알고리즘의 논리는 정확히 같지만 자바스크립트 함수 호출은var n=d.getTimezoneOffset()파이썬으로 마이그레이션할 때,n=time.altzone다른 차이점은 언어 문법 ( for for loop, boolean values, logical AND, logical NOT, logical OR 등) 에서만 나타난다.

마이그레이션된 파이썬 코드:

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)

테스트

Huobi 시장 차트

img

백테스트 합성의 4시간 차트

img

위의 코드는 참조 용도로만 사용됩니다. 특정 전략에서 사용되면 특정 요구 사항에 따라 수정하고 테스트하십시오. 버그 또는 개선 제안이 있다면 메시지를 남겨주세요. 감사합니다. o^_^ o


관련

더 많은