avatar of 发明者量化-小小梦 发明者量化-小小梦
Suivre Messages privés
4
Suivre
1271
Abonnés

Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Créé le: 2019-12-21 09:38:26, Mis à jour le: 2024-12-15 15:59:54
comments   4
hits   2839

Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Lors de la rédaction et de l’utilisation de stratégies, certaines données de cycle K-line peu courantes sont souvent utilisées. Cependant, les échanges et les sources de données ne fournissent pas de données pour ces périodes. Elle ne peut être synthétisée qu’en utilisant des données provenant de cycles existants. L’algorithme de synthèse possède déjà une version JavaScript (Lien), en fait, il est très simple de porter un code JavaScript vers la version Python. Ensuite, écrivons une version Python de l’algorithme de synthèse K-line.

Version JavaScript

  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 
  }

S’il existe un algorithme JavaScript, il peut être traduit et transplanté en Python ligne par ligne. Lorsque vous rencontrez des fonctions intégrées ou des méthodes inhérentes à JavaScript, recherchez simplement les méthodes correspondantes dans Python, la transplantation est donc relativement facile. La logique de l’algorithme est exactement la même, juste l’appel de fonction JavaScriptvar n = d.getTimezoneOffset()Lors du portage vers Python, utilisez la bibliothèque temporelle de Pythonn = time.altzoneremplacer. D’autres différences résident uniquement dans la syntaxe du langage (comme l’utilisation de boucles for, les différences dans les valeurs booléennes, les différences dans l’utilisation de “et” logique, “non” logique, “ou” logique, etc.).

Le code Python transplanté :

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)                                             

test

Graphique du marché Huobi Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Backtesting du graphique synthétique sur 4 heures Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Le code ci-dessus n’est utilisé qu’à titre de référence d’apprentissage. S’il est utilisé dans une stratégie spécifique, veuillez le modifier et le tester en fonction de vos besoins. Si vous avez des BUG ou des suggestions d’amélioration, veuillez laisser un message, merci beaucoup o^_^o