Traitement des données de ligne K dans le commerce quantitatif

Auteur:La bonté, Créé: 2019-09-03 11:15:30, Mis à jour: 2023-11-07 20:43:41

img

Comment le traitement des données K Line dans le commerce quantitatif?

Lors de l'écriture d'une stratégie de trading quantitative, en utilisant les données K-line, il y a souvent des cas où des données K-line de cycle non standard sont requises. par exemple, des données K-line de cycle de 12 minutes et des données de cycle de K-line de 4 heures sont requises. Habituellement, ces cycles non standard ne sont pas directement disponibles. Alors, comment gérer de tels besoins?

Les données de la ligne K du cycle non standard peuvent être obtenues en combinant les données du cycle plus petit. Imaginez ceci, le prix le plus élevé dans plusieurs cycles est compté comme le prix le plus élevé après la synthèse de la ligne K du cycle multiple, et le prix le plus bas est calculé comme le prix le plus bas après la synthèse, et le prix d'ouverture ne change pas. Le premier prix d'ouverture des données de matières premières de la ligne K est synthétisé. Le prix de clôture correspond au prix de clôture des dernières données de matières premières de la ligne K. Le temps utilise le temps de la ligne de prix d'ouverture k. Le volume de transaction utilise les données de matières premières qui ont été additionnées et calculées.

Comme indiqué sur la figure:

  • Je pense

Prenons l'actif blockchain BTC_USDT comme exemple et synthétisons 1 heure en 4 heures.

img img img img

Le temps Le plus élevé Il est ouvert. Le plus bas Je suis proche.
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

Les données de quatre cycles d'une heure sont combinées en une seule donnée de cycle de quatre heures.

Le prix d' ouverture est le prix d' ouverture de la première ligne K à 00h00 heure: 11382,57 Le prix de clôture est le prix de clôture de la dernière ligne k à 03:00: 11384.71 Le prix le plus élevé est de trouver le prix le plus élevé parmi eux: 11447,07 Le prix le plus bas est de trouver le prix le plus bas parmi eux: 11365,51

Note: le marché des contrats à terme sur matières premières chinois est fermé à 15 h par jour de négociation normal.

L'heure de début du cycle de 4 heures est l'heure de début de la première ligne K d'une heure, c'est-à-dire 2019.8.12 00:00

La somme du volume de toutes les lignes k de 1 heure est utilisée comme ce volume de lignes k de 4 heures.

Une ligne K de 4 heures est synthétisée:

High: 11447.07
Open: 11382.57
Low: 11365.51
Close: 11384.71
Time: 209.8.12 00:00

img

Vous pouvez voir que les données sont cohérentes.

  • Mise en œuvre du code

Après avoir compris les idées initiales, vous pouvez écrire manuellement le code pour réaliser les exigences.

Ces codes sont uniquement à titre de référence:

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

  // test
  function main () {
      while (true) {
          var r = exchange.GetRecords() // Raw data, as the basic K-line data of the synthesize K line. for example, to synthesize a 4-hour K-line, you can use the 1-hour K-line as the raw data.
          var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) // Pass the original K-line data r through the GetNewCycleRecords function, and the target cycles, 1000 * 60 * 60 * 4, ie the target synthesis cycle is 4 hours K-line data .

          $.PlotRecords(r2, "r2") // The strategy class library bar can be selected by check the line class library, and calling the $.PlotRecords line drawing class library to export the function drawing.
          Sleep(1000) // Each cycle is separated by 1000 milliseconds, preventing access to the K-line interface too much, resulting in transaction restrictions.
      }
  }

En fait, pour synthétiser la ligne K, vous avez besoin de deux choses. La première est les données de matières premières, c'est-à-dire les données de la ligne K d'un cycle plus petit.var r = exchange.GetRecords()pour obtenir les données de la ligne K du cycle plus petit.

La seconde est de déterminer la taille du cycle de synthèse, nous utilisons l'algorithme de fonction GetNewCycleRecords pour le faire, puis vous pouvez finalement retourner les données d'une structure de matrice de ligne K synthétisée.

Veuillez noter:

  1. Le cycle cible ne peut pas être inférieur au cycle de la ligne K que vous avez passé dans la fonction GetNewCycleRecords comme matière première pour les données.

  2. Le cycle cible doit être réglé sur cycle closed. Qu'est-ce qu'un cycle closed?

par exemple:

La ligne K du cycle de 12 minutes commence à partir de 0h00 toutes les heures, le premier cycle est de 00h00 à 00h12 et le deuxième cycle est de 00h12 à 00h24 et le troisième cycle est de 00h24 à 00h36 et le quatrième cycle est de 00h36 à 00h48 et le cinquième cycle est de 00h48 à 00h00 à 00h00 ce qui correspond exactement à une heure complète.

si c'est un cycle de 13 minutes, il s'agira d'un cycle non fermé. Les données calculées par un tel cycle ne sont pas uniques car les données synthétisées diffèrent selon le point de départ des données synthétisées.

Faites-le sur le marché réel:

img

Graphique des échanges de contraste

img

  • Construire la structure de données requise à l'aide de données de ligne K

Je veux calculer la moyenne mobile du prix le plus élevé pour toutes les lignes K. Que dois-je faire?

Habituellement, nous calculons les moyennes mobiles en utilisant la moyenne des prix de clôture, mais parfois il y a une demande pour utiliser le prix le plus élevé, le prix le plus bas, le prix d'ouverture et ainsi de suite.

pour ces demandes supplémentaires, les données de ligne K renvoyées par la fonction exchange.GetRecords (()) ne peuvent pas être transmises directement à la fonction de calcul de l'indicateur.

Par exemple: Letalib.MALa fonction de calcul de l'indicateur de moyenne mobile comporte deux paramètres, le premier étant les données à transmettre et le second le paramètre du cycle de l'indicateur.

Par exemple, nous devons calculer les indicateurs comme indiqué ci-dessous.

img

Le cycle de la ligne K est de 4 heures.

Sur le graphique des cotations boursières, une ligne moyenne a été fixée avec le paramètre de cycle de 9.

La source de données calculée utilise le prix le plus élevé par bar.

img

C'est-à-dire que cette ligne moyenne mobile est constituée de la moyenne du prix moyen le plus élevé de neuf barres de K-line de cycle de 4 heures.

Construisons nous-mêmes des données pour voir si c'est la même chose avec les données de l'échange.

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

Puisque nous devons calculer le prix le plus élevé de chaque barre pour obtenir la valeur de l'indicateur de moyenne mobile, nous devons construire un tableau dans lequel chaque élément de données a le prix le plus élevé pour chaque barre.

Vous pouvez voir que lehighsla variable est initialement un tableau vide, puis nous traversons la variable de données de ligne r2 k (ne vous souvenez pas de la r2? Regardez le code dans la fonction principale qui synthétise la ligne K de 4 heures ci-dessus).

Lisez le prix le plus élevé de chaque barre de r2 (c'est-à-dire r2 [i].High, i varie de 0 à r2.longueur - 1), puis appuyez surhighsDe cette façon, nous construisons simplement une structure de données qui correspond un à un avec la barre de données de la ligne K.

En ce moment,highspeut passer letalib.MAfonction de calcul de la moyenne mobile.

Exemple complet:

function main () {
     while (true) {
         var r = exchange.GetRecords()
         var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
         if (!r2) {
             Continue
         }
        
         $.PlotRecords(r2, "r2") // Draw the K line
        
         var highs = []
         for (var i = 0 ; i < r2.length ; i++) {
             Highs.push(r2[i].High)
         }
        
         var ma = talib.MA(highs, 9) // use the moving average function "talib.MA" to calculate the moving average indicator
         $.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time) // Use the line drawing library to draw the moving average indicator on the chart
        
         Sleep(1000)
     }
}

Test de retour:

img

Vous pouvez voir que la valeur moyenne de l'indicateur de la position du point de la souris dans la figure est 11466.9289

Le code ci-dessus peut être copié dans la stratégie pour exécuter le test, n'oubliez pas de vérifier la bibliothèque de lignes de dessin et de l'enregistrer!

  • Méthode d'acquisition de données K-line pour le marché des crypto-monnaies

La plateforme FMZ Quant dispose déjà d'une interface intégrée, à savoir leexchange.GetRecordsfonction, pour obtenir des données de ligne K.

Ce qui suit se concentre sur l'accès direct à l'interface de données de ligne K de l'échange pour obtenir des données, car parfois vous devez spécifier des paramètres pour obtenir plus de lignes K, le paquetGetRecordsl'interface renvoie généralement 100 k lignes. si vous rencontrez une stratégie qui nécessite initialement plus de 100 K-lignes, vous devez attendre le processus de collecte.

Afin de faire fonctionner la stratégie le plus rapidement possible, vous pouvez encapsuler une fonction, accéder directement à l'interface de ligne K de l'échange, et spécifier des paramètres pour obtenir plus de données de ligne K.

En utilisant la paire de trading BTC_USDT sur Huobi comme exemple, nous mettons en œuvre cette exigence:

Trouvez la documentation de l'API de l'échange et consultez la description de l'interface K-line:

img

https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles

Paramètres:

Nom Le type Est-ce que c' est nécessaire? Définition Valeur
le symbole une chaîne vrai Paire de négociation Je ne sais pas.
période une chaîne vrai Renvoie la granularité temporelle des données, qui est l'intervalle de temps de chaque ligne k 1 minute, 5 minutes, 15 minutes, 30 minutes, 60 minutes, 1 jour, 1 mois, 1 semaine, 1 année
taille nombre entier faux Renvoie le nombre de lignes de données K [1, 2000]

Code de test:

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

img img

Vous pouvez le voir sur le journal, imprimerrecords.lengthest de 300, c'est-à-dire le nombre derecordsLa barre de données de la ligne K est 300.img


Relationnée

Plus de