Inventeur d'un didacticiel d'introduction à la langue PINE

Auteur:Le petit rêve, Créé à: 2022-05-30 16:23:43, Mis à jour à: 2022-09-28 17:10:21

[TOC] Je vous en prie.

Inventeur d'un didacticiel d'introduction à la langue PINE

Les vidéos accompagnent le tutoriel:Qu'est-ce qui est trop difficile pour vous d'entrer dans le commerce quantitatif?

La plate-forme de trading quantitative des inventeurs prend en charge les stratégies de rédaction de la langue Pine, la prise en charge de la retouche, l'exécution de la stratégie de la langue Pine sur le disque dur et la compatibilité avec les versions inférieures de la langue Pine.FMZ.COMJe ne sais pas.La place des stratégiesIl y a beaucoup de stratégies de recherche et de portage (scripts) de Pine.

FMZ prend en charge non seulement le langage Pine, mais aussi les puissantes fonctions graphiques du langage Pine. Les fonctionnalités de la plate-forme FMZ, la richesse des outils utiles, l'administration efficace et facile, améliorent encore l'utilité des stratégies (scripts) de Pine. FMZ est basé sur la compatibilité avec le langage Pine, mais il y a aussi un certain nombre d'extensions, d'optimisations et de coupes dans le langage Pine.

Les différences les plus évidentes sont résumées en quelques mots:

  • 1, la politique Pine sur FMZ, le code à l'origine de l'icône de version//@versionLe code commence parstrategyindicatorLes phrases ne sont pas obligatoires et FMZ ne les prend pas en charge pour le moment.importImporterlibraryLes fonctionnalités de l'appareil.

    Vous pouvez voir certaines stratégies écrites comme ceci:

    //@version=5
    indicator("My Script", overlay = true)
    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue)
    plot(b, color = color.black)
    plotshape(c, color = color.red)
    

    Il y a aussi une autre version qui dit:

    //@version=5
    strategy("My Strategy", overlay=true)
    
    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    

    Sur FMZ, cela peut être simplifié:

    src = close
    a = ta.sma(src, 5)
    b = ta.sma(src, 50)
    c = ta.cross(a, b)
    plot(a, color = color.blue, overlay=true)
    plot(b, color = color.black, overlay=true)
    plotshape(c, color = color.red, overlay=true)
    

    Ou alors:

    longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
    if (longCondition)
        strategy.entry("My Long Entry Id", strategy.long)
    
    shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
    if (shortCondition)
        strategy.entry("My Short Entry Id", strategy.short)
    
  • Les paramètres relatifs à certaines transactions sont définis par le paramètre "Pine Language Transaction Library" dans l'interface de la politique FMZ.

    • Modèle de prix de clôture et modèle de prix en temps réel Dans la vue de trading, nous pouvons passer parstrategyLa fonctioncalc_on_every_tickParamètres pour définir un script de stratégie pour exécuter la stratégie logique en temps réel chaque fois que le prix change.calc_on_every_tickLe paramètre doit êtretruePar défaut.calc_on_every_tickLe paramètre estfalseLa logique de la stratégie n'est exécutée que lorsque la ligne K BAR actuelle de la stratégie est complètement terminée. Sur FMZ, les paramètres sont définis par le modèle "Pine Language Exchange Library".

      img

    • Le contrôle de la précision numérique, comme le prix, la quantité de sous-traitance et d'autres, lors de l'exécution de la stratégie est nécessaire sur FMZ. Dans la vue de trading, il n'y a pas de problème de précision en temps réel, car il ne peut être testé que par simulations. Sur FMZ, la stratégie Pine peut être exécutée en temps réel. La stratégie peut alors spécifier de manière flexible la précision des prix des variétés de transactions, la précision du nombre de commandes.

    • Code du contrat à terme Les variétés de transactions sur FMZ ont deux propriétés si elles sont des contrats. Elles sont respectivement des "paires de transactions" et des "codes de contrats", qui, en plus de la nécessité de définir clairement les paires de transactions sur le disque dur et lors de la réévaluation, nécessitent également de définir des codes de contrats spécifiques dans le paramètre "code de variété" du modèle de la bibliothèque de classes de transactions de la langue Pine. Par exemple, les contrats permanents sont remplis.swapLe code du contrat est spécifique à l'exposition de ce type de contrat par l'échange sur lequel l'opération est effectuée. Par exemple, il existe des contrats pour tous les trimestres.quarterLe code de ces contrats est identique au code des contrats à terme défini dans la documentation de l'API JavaScript/python/c++ de FMZ.

    Pour d'autres paramètres, par exemple, la taille minimale, la taille par défaut, vous pouvez consulter la documentation de la langue Pine sur la taille minimale.Une bibliothèque d'échanges linguistiques PineL'introduction des paramètres.

  • 3、runtime.debugruntime.logruntime.errorFonction étendue FMZ, utilisée pour le débogage.

    Trois fonctions de débogage ont été ajoutées à la plateforme FMZ.

    • runtime.debugLa fonction: n'est généralement pas utilisée pour imprimer des informations sur les variables sur la console.

    • runtime.log: Exporter le contenu dans le journal ⇒ FMZ PINE a une fonction spécifique ⇒

      runtime.log(1, 2, 3, close, high, ...),可以传多个参数。
      
    • runtime.error: lors de l'appel, provoque une erreur d'exécution et contient un message d'erreur spécifié dans les paramètres de message.

      runtime.error(message)
      
  • 4 est partiellement étendu dans la fonction graphique.overlayParamètres

    Langue Pine sur FMZ, fonction graphiqueplotplotshapeplotcharet ainsi de suite.overlayParamètres de support permettant de spécifier une image dans un schéma principal ou sous-schéma.overlayParamètrestrueLe dessin est dans le thème et est réglé surfalseDessiner en sous-graphique. Permettre à la stratégie Pine sur FMZ de dessiner en même temps que le thème et le sous-graphique.

  • 5、syminfo.mintickPrise de valeur de la variable par défaut

    syminfo.mintickLa variable par défaut est définie comme la valeur minimale de la variété actuelle.Disque réel/RéécritureDans l'interface "Pine Language Trading Library", le paramètre de modèle de la précision de la devise de prix peut contrôler cette valeur. La précision de la devise de prix est réglée sur 2 pour que le prix soit précis jusqu'à la seconde place des décimales lors de la transaction, lorsque le prix a une unité minimale de variation de 0.01 [4].syminfo.mintickLa valeur est 0.01 ∞.

  • Les prix moyens dans FMZ PINE Script sont ceux qui incluent les frais de service

    Par exemple: le prix de la commande est de 8000, la direction de vente, la quantité d'une main, le prix moyen après la transaction n'est pas de 8000, moins de 8000, les frais de traitement sont inclus dans le coût.

Base de la langue pine

Lorsque vous commencez à apprendre les bases de la langue Pine, vous ne connaissez peut-être pas les instructions et la syntaxe du code dans certains exemples. Ce n'est pas grave, vous pouvez d'abord vous familiariser avec les concepts, comprendre le but du test, ou consulter la documentation de la langue Pine de FMZ pour voir les instructions.

Exécution du modèle

Il est très important d'avoir une bonne compréhension des concepts connexes tels que le processus d'exécution des scripts de la langue Pine. Les stratégies de la langue Pine sont basées sur des graphiques, comprises comme une série de calculs et d'opérations qui sont exécutées sur un graphique dans l'ordre chronologique suivant les données les plus anciennes déjà chargées.bar_indexRéférencement à la valeur d'index de la ligne KBar en cours lors de l'exécution du script Pine.

plot(bar_index, "bar_index")

img

plotLa fonction est l'une des fonctions que nous utiliserons le plus dans l'avenir. L'utilisation est très simple, c'est de tracer des lignes sur le graphique en fonction des paramètres transmis, les données transmises sont:bar_indexLa ligne est nomméebar_indexOn peut voir que la valeur de la ligne appelée bar_index au-dessus du premier nom de Bar est 0, et que l'augmentation de Bar à droite est suivie d'une augmentation de 1.

Selon la configuration de la stratégie, les modèles de stratégie diffèrent également dans la façon dont ils sont exécutés.收盘价模型et实时价模型Nous avons également présenté brièvement le concept de modèle de prix de clôture et de modèle de prix en temps réel.

  • Modèle de prix de clôture

    Lors de l'exécution du code de stratégie, le cycle de la ligne KBar actuelle est entièrement exécuté et le cycle de la ligne K est terminé à la fermeture de la ligne K. Une fois la stratégie Pine exécutée, le signal de transaction déclenché est exécuté au début de la prochaine ligne KBar.

  • Modèle de prix en temps réel

    Lors de l'exécution du code de stratégie, la barre K actuelle est exécutée à chaque changement de marché, qu'il soit fermé ou non. La stratégie Pine est exécutée à chaque changement de marché et le signal de transaction déclenché est exécuté immédiatement.

Lorsque la stratégie de la langue Pine est exécutée de gauche à droite sur le graphique, la ligne KBar sur le graphique est divisée en历史Baret实时BarJe suis désolée.

  • Bar historique

    Lorsque la stratégie est configurée comme "Modèle de prix réel", toutes les lignes KBar du graphique, à l'exception de la ligne KBar à droite, sont activées.历史BarLa logique stratégique est présente dans tous les cas.历史BarIl n'y a qu'une seule exécution. Lorsque la stratégie est configurée pour exécuter le modèle de prix de clôture, toutes les barres du graphique sont历史BarLa logique stratégique est présente dans tous les cas.历史BarIl n'y a qu'une seule exécution.

    Les calculs basés sur l'historique Bar: Le code de stratégie est exécuté une fois dans l'état de clôture de la barre d'historique, puis le code de stratégie continue à être exécuté dans la barre d'historique suivante jusqu'à ce que toutes les barres d'historique soient exécutées une fois.

  • Bar en temps réel

    Lorsque la stratégie est exécutée sur la dernière ligne K Bar à droite, la barre devient une barre en temps réel. Lorsque la barre en temps réel est fermée, la barre devient une barre en temps réel passée (qui devient une barre historique).

    Lorsque la stratégie est configurée comme "modèle de prix en temps réel", une stratégie logique est exécutée pour chaque évolution du marché sur la barre en temps réel. La stratégie est définie comme "modèle de prix de clôture" et n'affiche pas de bar en temps réel sur le graphique lors de l'exécution.

    Les calculs basés sur Bar en temps réel: Si la stratégie est définie comme " modèle de prix de clôture " et que le graphique n'affiche pas de Bar en temps réel, le code de la stratégie n'est exécuté qu'une seule fois lors de la clôture actuelle de Bar. Si la politique est définie comme "modèle de prix réel", le calcul sur le bar réel est complètement différent de celui sur le bar historique, où un code de stratégie est exécuté pour chaque changement de marché sur le bar réel; par exemple, une variable intégrée.highlowcloseDans l'historique Bar, il est certain que ces valeurs évoluent à chaque fois que le marché peut changer dans l'historique Bar. Ainsi, les données telles que les indicateurs calculés sur la base de ces valeurs évoluent également en temps réel.closeLes prix actuels sont toujours les prix les plus récents, et les prix les plus bas sont toujours les prix les plus bas.highetlowToujours représente les plus hauts et les plus bas depuis le début de la barre en temps réel actuelle. Ces variables intégrées représentent la valeur finale de la dernière mise à jour de la barre en temps réel.

    Le mécanisme de rebond lors de l'exécution de la stratégie sur le bar en temps réel (modèle de prix en temps réel): Lors de l'exécution en temps réel de Bar, la variable définie par l'utilisateur qui est réinitialisée avant l'exécution de chaque nouvelle itération de la politique est appelée un retournement. Pour comprendre le mécanisme de retournement, nous allons utiliser un exemple dans le code de test suivant.

    Attention:

    /*backtest 
    ...
    ..
    .
    */
    

    Le contenu du paquet est des informations de configuration de retouche stockées sous forme de code sur la plateforme FMZ.

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
    
    var n = 0
    if not barstate.ishistory
        runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index)
        n := n + 1
        runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
      
    plot(n, title="n")
    

    img

    img

    Nous n'avons examiné que les scènes qui ont été exécutées en temps réel.not barstate.ishistoryLa restriction d'expression n'est utilisée que pour l'addition de variables n en temps réel Bar et avant et après l'exécution de l'addition.runtime.logLes informations de sortie des fonctions sont enregistrées dans les journaux de stratégie.plotLa courbe n peut être vue comme n ayant toujours été 0 lorsque la stratégie était en cours d'exécution dans l'historique de Bar. On peut voir que n a déclenché une opération en plus de 1 lorsque l'opération a été exécutée jusqu'à Bar en temps réel et qu'elle a été exécutée en plus de 1 chaque fois que la stratégie a été exécutée sur Bar en temps réel. On peut observer dans les informations du journal que n a été réinitialisé à la valeur de la dernière soumission de la stratégie précédente lors de chaque nouvelle exécution.

    Il y a aussi des gens qui ont des problèmes avec leur santé. 1, lorsque la politique commence à s'exécuter en temps réel, une fois par mise à jour de la zone, un code de stratégie est exécuté. 2, lors de l'exécution sur Bar en temps réel, la variable est retournée avant chaque exécution du code de stratégie. 3, lorsque l'exécution est effectuée sur Bar en temps réel, la variable est envoyée une fois lors de la mise à jour de la clôture.

    Les opérations graphiques telles que les courbes sur les graphiques peuvent également entraîner des redrapages, car les données retournent en arrière, par exemple en modifiant le code de test que nous venons de modifier:

    var n = 0
    if not barstate.ishistory
        runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index)
        n := open > close ? n + 1 : n
        runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
      
    plot(n, title="n")
    

    Capture d'écran du moment Aimg

    Capture d'écran du moment Bimg

    Nous n'avons modifié que cette phrase:n := open > close ? n + 1 : nOn peut voir que dans le premier graphique, au moment A, n est ajouté à 1, puisque le prix d'ouverture est alors supérieur au prix de clôture, la courbe n affiche une valeur de 5; puis le mouvement de marché, la mise à jour des prix, comme dans le deuxième graphique, au moment B.

  • Le contexte des variables dans une fonction

    Ci-dessous, nous étudions ensemble les variables dans les fonctions de la langue Pine. Selon les descriptions de certains tutoriels de Pine, les variables dans les fonctions diffèrent des variables en dehors des fonctions comme suit:

    L'historique de la série de variables utilisée dans la fonction Pine est créé par chaque appel successif de la fonction. Si la fonction n'est pas appelée sur chaque colonne où le script est exécuté, cela entraînera une différence entre les valeurs historiques à l'intérieur du bloc de la fonction et celles de la série externe. Ainsi, si la fonction n'est pas appelée sur chaque colonne, la série utilisant la même valeur d'indexation à l'intérieur de la fonction et à l'extérieur ne fera pas référence au même point historique.

    C'est un peu difficile à lire, n'est-ce pas? C'est bon, nous avons essayé de résoudre le problème avec un code de test qui fonctionne sur FMZ:

    /*backtest
    start: 2022-06-03 09:00:00
    end: 2022-06-08 15:00:00
    period: 1m
    basePeriod: 1m
    exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
    */
      
    f(a) => a[1]
    f2() => close[1]  
    
    oneBarInTwo = bar_index % 2 == 0
    plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")   
    plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")   
    plot(close[2], title = "close[2]", color = color.red, overlay = true)
    plot(close[1], title = "close[1]", color = color.green, overlay = true)
    

    Capture d'écran du test de détection

    img

    Le code de test est relativement simple et vise principalement à examiner les données qui sont citées de deux manières:f(a) => a[1]etf2() => close[1]

    • f(a) => a[1]Comment utiliser les paramètres de transmission: la fonction est finalement retournéea[1]

    • f2() => close[1]Utilisation directe des variables intégréescloseLa fonction retourne finalement.close[1]

    []Le symbole est utilisé pour une opération de référence sur les valeurs historiques des variables d'une série de données, close[1] qui est une référence à la date de clôture sur la barre précédant le prix de clôture actuel. Notre code de test dessine au total 4 données sur le graphique:

    • plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")Tracez un caractère A A, de couleur rouge, que vous ne dessinez que lorsque oneBarInTwo est vrai, la position dessinée (sur l'axe Y) est:f(close)La valeur est retournée.

    • plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")Tracez un caractère en B en vert, et lorsque oneBarInTwo est vrai, la position dessinée (sur l'axe Y) est:f2()La valeur est retournée.

    • plot(close[2], title = "close[2]", color = color.red, overlay = true)Les lignes sont en rouge et la position dessinée (sur l'axe Y) est:close[2]C'est-à-dire le prix de clôture sur le bar, le 2ème pilier avant le nombre de Bar (à 2 piles de gauche).

    • plot(close[1], title = "close[1]", color = color.green, overlay = true)Les lignes sont de couleur verte et leur position (sur l'axe Y) est:close[1]C'est le prix de clôture sur Bar, la première ligne avant le nombre Bar (à gauche).

    Une capture d'écran peut être vue en cours d'exécution par stratégie de retouche, bien que l'image A marque les fonctions utiliséesf(a) => a[1]et les fonctions utilisées pour marquer la figure Bf2() => close[1]Les deux sont utilisés[1] pour référencer les données historiques de la série de données, mais la position des balises "A" et "B" sur le graphique est complètement différente. La position des balises "A" tombe toujours sur la ligne rouge, c'est-à-dire le code de la stratégie.plot(close[2], title = "close[2]", color = color.red, overlay = true)Les données utilisées pour les lignes sont les suivantes:close[2]

    img

    C'est parce que nous avons utilisé l'index de la ligne KBar, la variable intégrée.bar_indexCalculer si les marques "A" et "B" sont dessinées. Les marques "A" et "B" ne sont pas dessinées sur chaque ligne KBar.f(a) => a[1]La valeur citée de cette façon, si la fonction n'est pas appelée à chaque bar, est associée à la fonction.f2() => close[1]Les valeurs citées ne sont pas les mêmes (même si l'on utilise le même index comme [1]).

  • Certaines fonctions intégrées doivent être calculées sur chaque Bar pour calculer correctement leurs résultats.

    Il y a un exemple simple:

    res = close > close[1] ? ta.barssince(close < close[1]) : -1
    plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
    

    Nous appelons les fonctions par le code.ta.barssince(close < close[1])Écrire dans un opérateur à trois caractères.condition ? value1 : value2Il y a une différence entre les deux.close > close[1]时去调用ta.barssince函数。可偏偏ta.barssinceLa fonction est calculée à partir de la dernière foisclose < close[1]Le nombre de lignes K à l'appel; ta.barssince est close > close[1] lorsque la fonction est appelée, c'est-à-dire que le prix de clôture actuel est supérieur au prix de clôture du précédent Bar, la fonction ta.barssince n'a pas de condition close < close[1] lorsqu'elle est appelée et n'a pas de position de clôture la plus récente.

    ta.barssince : Lorsque la fonction est appelée, elle renvoie na si cette condition n'a jamais été satisfaite avant la ligne K actuelle.

    Voici le graphique:

    img

    Donc, lorsque nous dessinons, nous ne dessinons que les données lorsque la variable res a une valeur ((-1) ).

    Pour éviter ce problème, nous avons juste utiliséta.barssince(close < close[1])L'appel à la fonction est extrait de l'opérateur trinitaire et écrit à l'extérieur de la branche de n'importe quelle condition possible; il peut donc effectuer des calculs sur chaque ligne KBar.

    a = ta.barssince(close < close[1])
    res = close > close[1] ? a : -1
    plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
    

    img

Séquence de temps

Le concept de la séquence temporelle est très important dans le langage Pine, c'est un concept que nous devons comprendre lorsque nous apprenons le langage Pine. La séquence temporelle n'est pas un type mais une structure fondamentale pour la valeur continue des variables stockées dans le temps.openest une variable intégrée à la langue Pine dont la structure permet de stocker une séquence de temps pour le prix d'ouverture de chaque ligne KBar.openCette structure de séquence de temps représente le prix d'ouverture de tous les K-strings de la K-string actuelle depuis le premier Bar au début jusqu'à ce que ce Bar soit exécuté par le script actuel. Si la K-string actuelle est un cycle de 5 minutes, nous citons ((ou utilisons)) dans le code de stratégie PineopenLe temps est le prix d'ouverture de la ligne KBar lors de l'exécution actuelle du code de la stratégie. Si vous souhaitez référencer une valeur historique dans une séquence de temps, il est nécessaire d'utiliser[]Opérateur. Utilisé lorsque la stratégie Pine est exécutée sur une ligne KBar.open[1]Indique une référenceopenLe prix d'ouverture de la ligne KBar précédente (c'est-à-dire le prix d'ouverture du cycle de la ligne K précédente) de cette ligne KBar exécutée par le script en cours sur la séquence temporelle.

  • Les variables de la séquence sont très faciles à calculer. Nous avons des fonctions intégrées.ta.cumPar exemple:

    ta.cum
    
    Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
    ta.cum(source) → series float
    RETURNS
    Total sum series.
    ARGUMENTS
    source (series int/float)
    SEE ALSO
    math.sum
    

    Le code de test:

    v1 = 1
    v2 = ta.cum(v1)
    plot(v1, title="v1")
    plot(v2, title="v2")
    plot(bar_index+1, title="bar_index")
    

    Il y a beaucoup de similitudes.ta.cumUne telle fonction intégrée peut traiter directement des données sur une séquence de temps, par exempleta.cumL'idée est d'ajouter les valeurs correspondantes des variables transmises sur chaque ligne KBar, et ensuite nous utilisons un graphique pour faciliter la compréhension.

    Le processus de mise en œuvre Variable intégrée bar_index v1 V2
    La stratégie s'exécute sur la première ligne KBar 0 1 1
    La stratégie s'exécute sur la 2e ligne KBar 1 1 2
    La stratégie s'exécute sur la 3ème ligne KBar 2 1 3
    La stratégie s'exécute sur la n + 1e ligne KBar N 1 N+1

    On peut voir que v1, v2 et même bar_index sont en fait des structures de séquences chronologiques, avec des données correspondantes sur chaque Bar. Ce code de test distingue entre le "modèle de prix en temps réel" et le "modèle de prix de clôture" simplement en fonction de l'affichage de Bar en temps réel sur le graphique.

    img

    La variable v1 est donc 1, pour chaque bar.ta.cum(v1)Lorsque la fonction est exécutée sur la première ligne KBar, le résultat du calcul est 1, car il n'y a que la première ligne Bar. Quandta.cum(v1)Lorsqu'il est exécuté sur la deuxième ligne KBar, il y a déjà 2 lignes KBar (la première variable intégrée correspondante bar_index est 0, la deuxième variable intégrée correspondante bar_index est 1), donc le résultat est 2, attribuant la variable v2, et ainsi de suite. On peut observer que v2 est en fait le nombre de lignes KBar dans le graphique, car l'index de la ligne K est le même que celui de la variable v2.bar_indexDonc si on commence à partir de zéro et on augmente, alorsbar_index + 1C'est en fait le nombre de barres de la ligne K. Vous pouvez également voir les lignes sur le graphique d'observation.v2etbar_indexIl est vrai que c'est superposé.

    img

    Je peux aussi utiliserta.cumLa fonction intégrée calcule la somme des prix de clôture de tous les Bar sur le graphique en cours, et peut être écrite simplement comme ceci:ta.cum(close)Lorsque la stratégie est exécutée sur la barre en temps réel en haut à droite.ta.cum(close)Le résultat du calcul est la somme des prix de clôture de tous les Bar sur le graphique (s'il n'est pas exécuté jusqu'à la extrémité droite, il suffit d'ajouter le Bar actuel).

    Les variables de la séquence de temps peuvent également être calculées à l'aide d'opérateurs, comme le code:ta.sma(high - low, 14)Il y a une variable intégrée.high(Le prix le plus élevé de la ligne KBar) moinslow(K-Line Bar le prix le plus bas), utilisé pour la finta.smaLa fonction demande une moyenne.

  • Le résultat d'un appel à une fonction laisse également une trace de valeur dans la séquence temporelle.

    v1 = ta.highest(high, 10)[1]
    v2 = ta.highest(high[1], 10)
    plot(v1, title="v1", overlay=true)
    plot(v2, title="v2", overlay=true)
    

    Le code de test s'exécute lors de la retestation et on peut observerv1etv2Les valeurs sont les mêmes, les lignes dessinées sur le graphique sont également complètement superposées. Les résultats des appels de fonctions laissent une trace de valeur dans la séquence de temps, par exemple le code.ta.highest(high, 10)[1]Parmi eux:ta.highest(high, 10)Les résultats calculés par l'appel de la fonction peuvent également être utilisés[1] pour référencer sa valeur historique. Basée sur la correspondance Bar précédente de la fonction actuelle.ta.highest(high, 10)Le résultat est:ta.highest(high[1], 10)Pourquoi?ta.highest(high[1], 10)etta.highest(high, 10)[1]Je suis très heureux de voir que vous avez réussi.

    Exporter des informations de vérification à l'aide d'une autre fonction graphique:

    a = ta.highest(close, 10)[1]
    b = ta.highest(close[1], 10)
    plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true)
    plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
    

    On peut voir que les valeurs des variables a et b dans la séquence de temps sont affichées au-dessus et au-dessous de la barre correspondante. Le code graphique peut être conservé pendant l'apprentissage, car il est souvent nécessaire de produire des informations sur le graphique pour les observer lors de tests.

    img

Structure du scénario

Structure générale

Dans la première partie du tutoriel, nous avons résumé certaines des différences entre l'utilisation de la langue Pine sur FMZ et celle du langage Pine sur Trading View.indicator()strategy()Le blogueur a également publié un article intitulé:library()Bien sûr, pour être compatible avec les versions antérieures du script Pine, les stratégies doivent être écrites comme://@version=5indicator()strategy()Il est possible d'installer des paramètres de stratégie sur le serveur.strategy()Les paramètres de transmission dans la fonction.

<version>
<declaration_statement>
<code>

<version>Les informations de contrôle de version peuvent être omises.

Les notes

L'utilisation de la langue pine//En tant qu'annotateur à une ligne, FMZ étend l'annotation car la langue Pine n'a pas d'annotateur à plusieurs lignes./**/Pour les annotations à plusieurs lignes.

Le code

Les lignes dans un script qui ne sont pas des annotations ou des instructions de compilateur sont des phrases qui mettent en œuvre l'algorithme du script. Une phrase peut être l'une de ces choses.

  • Déclaration des variables
  • Réattribuer des valeurs aux variables
  • Déclaration de fonction
  • Appel de fonction intégré, appel de fonction défini par l'utilisateur
  • ifforwhileouswitchStructure équivalente

Les phrases peuvent être classées de plusieurs façons.

  • Certaines déclarations peuvent être exprimées en une seule ligne, comme la plupart des déclarations de variables, qui ne contiennent qu'une seule ligne d'appel à la fonction ou des déclarations de fonction en une seule ligne. D'autres, comme les structures, ont toujours besoin de plusieurs lignes car elles nécessitent un bloc local.
  • Les phrases à l'échelle globale du script (c'est-à-dire les parties qui n'appartiennent pas à un sous-ensemble) ne peuvent pas être utilisées comme des phrases dans le cadre d'un scénario.空格ou制表符(touche tab) commence. Leur premier caractère doit également être le premier caractère de la ligne. La ligne qui commence à la première position de la ligne est, par définition, une partie de la portée globale du script.
  • Une déclaration de structure ou de fonction multi-lignes nécessite toujours unlocal block; un bloc local doit être condensé en un symbole ou en quatre espaces (sinon, il sera résolu en une ligne de code en série précédente, c'est-à-dire déterminé comme le contenu continu de la ligne précédente), et chaque bloc local définit une gamme locale différente.
  • Plusieurs phrases à une ligne peuvent être reliées en une seule ligne en utilisant le comma ((,) comme séparateur.
  • Une ligne peut contenir des annotations ou simplement des annotations.
  • Les lignes peuvent également être enveloppées (en continuant sur plusieurs lignes).

Par exemple, il y a trois blocs locaux, dont un dans une déclaration de fonction personnalisée et deux dans une déclaration de variable utilisant la structure if, avec le code suivant:

indicator("", "", true)             // 声明语句(全局范围),可以省略不写

barIsUp() =>                        // 函数声明(全局范围)
    close > open                    // 本地块(本地范围)

plotColor = if barIsUp()            // 变量声明 (全局范围)
    color.green                     // 本地块 (本地范围)
else
    color.red                       // 本地块 (本地范围)

runtime.log("color", color = plotColor)  // 调用一个内置函数输出日志 (全局范围)

Modifier le code

Les lignes longues peuvent être divisées en plusieurs lignes, ou être "enveloppées"; les lignes enveloppées doivent être condensées en n'importe quel nombre d'espaces, à moins qu'elles ne soient des multiples de 4 (les limites sont utilisées pour condenser les parties).

a = open + high + low + close

Le nombre d'espaces compressés par ligne n'est pas un multiple de 4):

a = open +
      high +
          low +
             close

Un appel long plot (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

close1 = request.security(syminfo.tickerid, "D", close)      // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close)    // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100),                       // 一行长的plot()调用可以被包装
   color = color.new(color.purple, 40),
   style = plot.style_area,
   trackprice = true)

Les statements dans les déclarations de fonctions définies par l'utilisateur peuvent également être enveloppés. Cependant, comme le morceau local doit commencer par une contraction (quatre espaces ou un symbole), la suite de la phrase doit commencer par plus d'une contraction (pas plus d'un multiple de quatre espaces) lorsqu'elle est divisée en la ligne suivante. Par exemple:

test(c, o) =>
    ret = c > o ?
       (c > o+5000 ? 
          1 :
              0):
       (c < o-5000 ? 
          -1 : 
              0)
           
                   
a = test(close, open)
plot(a, title="a")

Identifiant et opérateur

Identifiant

Avant de comprendre les variables, nous devons d'abord comprendre le concept des symboles d'algorithmes. Les symboles d'algorithmes communs sont utilisés comme des symboles de variables.Les fonctionsetVariablesLe nom de l'appareil (utilisé pour nommer les variables, les fonctions) ≠.Les fonctionsComme nous le verrons plus loin dans notre tutoriel, nous allons d'abord apprendre les symboles de l'icône.

  • 1, l'identifiant doit être en majuscules(A-Z)ou en minuscules.(a-z)Les lettres ou les signes(_)Le début, le premier caractère d'un identifiant.
  • Le premier caractère de l'identifiant peut être remplacé par le caractère suivant.Les lettresLa ligne inférieureouLes chiffres
  • Les noms des identifiants sont en minuscules.

Par exemple, les identifiants suivants:

fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown  // 错误的命名!使用了数字字符作为标识符的开头字符

Comme la plupart des langages de programmation, le langage Pine a des suggestions d'écriture.

  • 1, toutes les lettres en majuscules sont utilisées pour nommer les constantes.
  • 2, UtilisationLes règles de la petite collineLes noms utilisés pour les autres identifiants.
// 命名变量、常量
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7

// 命名函数
zeroOne(boolValue) => boolValue ? 1 : 0

Opérateur

Les opérateurs sont des symboles d'opération utilisés dans un langage de programmation pour construire des expressions, et les expressions sont des règles de calcul que nous avons conçues pour un certain type de calcul lorsque nous écrivons des stratégies. Les opérateurs dans le langage Pine sont classés par fonctionnalité comme:

Les opérateurs d'attribution, les opérateurs d'arithmétique, les opérateurs de comparaison, les opérateurs logiques,? :Les opérateurs à trois chiffres.[]L'opérateur de référence historique.

Opérateur d'arithmétique*Par exemple, le type de problème différencié par le type d'opérateur de la langue Pine sur Trading View qui renvoie des résultats est le code de test suivant:

//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength)  // Compilation error!
plot(ma)

Le scénario peut être compilé avec des erreurs lors de l'exécution de ce script dans Trading View.adjustedLength = lenInput * factorOn multiplie et on obtientseries intType (série), cependantta.emaLe deuxième paramètre de la fonction ne prend pas en charge ce type. Cependant, il n'y a pas de restrictions strictes sur FMZ et le code ci-dessus peut fonctionner normalement.

Nous allons voir ensemble comment les différents opérateurs sont utilisés.


Opérateur d'attribution

Il existe deux types d'opérateurs d'attribution:=:=Nous l'avons vu dans quelques exemples au début de ce tutoriel.

=L'opérateur est utilisé pour l'initialisation ou l'attribution d'une variable.=L'initialisation, la déclaration de l'attribution et les variables suivantes commencent par cette valeur à chaque Bar qui suit.

a = close           // 使用内置变量赋值给a
b = 10000           // 使用数值赋值
c = "test"          // 使用字符串赋值
d = color.green     // 使用颜色值赋值
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)

Attention!a = closeStatement d'attribution, pour chaque variable Bar, la variable a est le prix de clôture (close) actuel de cette Bar.bcdLe résultat de cette analyse est stable et peut être testé dans un système de retouche sur FMZ.

:=Utilisé pour réassigner une valeur à une variable existante, il peut être simplement compris comme:=L'opérateur est utilisé pour modifier une valeur de variable déjà déclarée, initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement initialement. Si vous utilisez:=L'opérateur donne des erreurs aux variables non initiales ou déclarées, par exemple:

a := 0

Je suis un homme de parole.:=Les opérateurs d'attribution sont généralement utilisés pour réattribuer des variables existantes, par exemple:

a = close > open 
b = 0 
if a
    b := b + 1

plot(b)

Juge siclose > open(c'est-à-dire que le BAR actuel est la ligne verticale), la variable a est la valeur vraie.b := b + 1Utilisez les opérateurs d'attribution.:=On réattribue une valeur à b en ajoutant un 1; puis on utilise la fonction plot pour tracer sur le graphique les valeurs de la variable b sur les BAR de chaque séquence de temps, en lignes.

Est-ce que nous pensons qu'il y a une virgule BAR et que b va continuer à ajouter 1? Bien sûr que non, ici nous déclarons la variable b sans utiliser de mot-clé spécifié lors de l'initialisation à 0.b=0On peut donc voir que le résultat de ce code est de réinitialiser la variable b à 0 à chaque fois si la variable a est vraie.close > openDonc, cette fois-ci, b va ajouter 1, alors que le diagramme de la fonction plot est b 1, mais la prochaine fois que le code est exécuté, b est réassigné à 0. C'est aussi un endroit où les débutants de la langue Pine peuvent facilement tomber.

En ce qui concerne les opérateurs d'attribution, il faut élargir l'explication de deux mots clés:varvarip

  • - Je ne sais pas.

    En fait, ce mot clé, nous l'avons déjà vu et utilisé dans des tutoriels précédents, mais nous ne l'avons pas abordé en détail à l'époque.

    var est un mot-clé utilisé pour attribuer et initialement une variable une seule fois. Généralement, la syntaxe d'attribution des variables qui n'inclut pas le mot-clé var entraîne la suppression de la valeur de la variable à chaque fois que les données sont mises à jour. En revanche, lorsqu'on utilise le mot-clé var pour attribuer des variables, elles peuvent rester dans l'état de verrouillage même si les données sont mises à jour.

    On utilise encore cet exemple, mais on l'utilise quand on attribue une valeur à b.varLes mots clés.

    a = close > open 
    var b = 0 
    if a
        b := b + 1
    
    plot(b)
    

    varLe mot-clé permet à la variable b d'exécuter uniquement la première affectation initiale et de ne pas réinitialiser b à 0 à chaque fois que la logique de la stratégie est exécutée, de sorte que la ligne dessinée à partir de l'exécution peut être observée comme b, qui est la mesure de retour du nombre de rayons de soleil BAR qui sont apparus lors de la ligne K actuelle BAR.

    Les variables déclarées var peuvent être écrites non seulement à l'échelle globale, mais aussi dans des blocs de code, comme dans cet exemple:

    strategy(overlay=true)
    var a = close
    var b = 0.0
    var c = 0.0
    var green_bars_count = 0
    if close > open
        var x = close
        b := x
        green_bars_count := green_bars_count + 1
        if green_bars_count >= 10
            var y = close
            c := y
    plot(a, title = "a")
    plot(b, title = "b")
    plot(c, title = "c")
    

    La variable a maintient le prix de clôture de la première colonne de la série. La variante a maintenu le prix de clôture de la barre de prix de la première soupe de soupe verte de la série. La variable c est maintenue au cours de la clôture de la dixième série de bananes vertes.

  • variété

    varipNous avons vu ce mot clé pour la première fois, et nous pouvons voir la description de ce mot clé:

    varip (var intrabar persist) est un mot-clé utilisé pour l'attribution et l'initialisation ponctuelle de variables. Il est similaire au mot-clé var, mais les variables déclarées avec varip conservent leur valeur entre les mises à jour en ligne K en temps réel.

    C'est plus difficile à comprendre? C'est bon, on peut expliquer avec des exemples, c'est facile à comprendre.

    strategy(overlay=true)
    
    // 测试 var varip
    var i = 0
    varip ii = 0  
    
    // 将策略逻辑每轮改变的i、ii打印在图上
    plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
    plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)  
    
    // 每轮逻辑执行都给i、ii递增1
    i := i + 1
    ii := ii + 1
    

    Le code de test se présente différemment sur le modèle de prix de clôture et le modèle de prix en temps réel:

    Le modèle de prix réel: Rappelez-vous que nous avons expliqué plus tôt que la stratégie est divisée en phases historiques BAR et phases en temps réel BAR.varvaripVariables déclaréesiiiLes opérations d'incrémentation sont exécutées à chaque fois que le code de stratégie est exécuté. Ainsi, on peut voir que les chiffres affichés sur le BAR de la ligne K des résultats de rétrospection augmentent un par un. Lorsque la phase historique de la ligne K se termine et commence la phase de la ligne K en temps réel. Les variables de la déclaration var, varip commencent à changer.i := i + 1etii := ii + 1La différence est que ii est modifié à chaque fois. Bien que i soit modifié à chaque fois, la valeur précédente est restaurée lors de l'exécution de la logique de stratégie au prochain tour (se souvient-on du mécanisme de retournement que nous avons expliqué dans le chapitre précédent "Exécution du modèle"?), la valeur de i n'est déterminée qu'après la mise à jour de la ligne K.

    Le modèle de clôture: Puisque le modèle de prix de clôture n'exécute une seule stratégie logique que lorsque chaque ligne K BAR est terminée. Ainsi, dans le modèle de prix de clôture, les phases historiques de la ligne K et les phases de la ligne K en temps réel, les variables de la déclaration var, varip sont parfaitement cohérentes dans l'exemple ci-dessus.


Opérateur d'arithmétique
Opérateur Expliquer
+ Le gaffa
- Déduction
* La multiplication
/ À l'exception
% Le moule

+-L'opérateur peut être utilisé comme un opérateur binaire ou comme un opérateur primaire. Les autres opérateurs d'arithmétique ne peuvent être utilisés que comme un opérateur binaire, et rendent des erreurs s'ils sont utilisés comme un opérateur primaire.

1, les deux côtés de l'opérateur sont de type numérique, le résultat est de type numérique, entier ou floppy, selon le résultat de l'opération. Si l'un des opérateurs est une chaîne, l'opérateur est+Le résultat est une chaîne, la valeur est convertie en forme de chaîne, puis les chaînes sont collées. Si c'est un autre opérateur d'arithmétique, il tente de convertir la chaîne en valeur numérique, puis l'opération. 3, si l'opérateur est na, le résultat du calcul est null na, qui s'affiche sur NaN lors de l'impression sur FMZ.

a = 1 + 1 
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na 

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)   
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN

Le langage Pine sur FMZ est un peu différent du langage Pine sur Trading View, le langage Pine sur FMZ n'est pas très strict sur les exigences de type de variable; par exemple:

a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A" 

plot(a)
plot(b)
plot(c)

Il est possible de l'exécuter sur FMZ, mais le type d'erreur est affiché dans la vue de trading. Pour les opérateurs arithmétiques, le système calcule la valeur après la conversion de la chaîne en un nombre. Si la chaîne non numérique ne peut pas être calculée, le résultat de l'opération est nul na.


Opérateur de comparaison

L'opérateur de comparaison est un opérateur binaire.

Opérateur Expliquer
< inférieure à
> plus grand que
<= C'est moins égal à
>= est égal à
== Également
!= Les inégalités

Voici un exemple de test:

a = 1 > 2 
b = 1 < 2 
c = "1" <= 2 
d = "1" >= 2 
e = 1 == 1 
f = 2 != 1 
g = open > close 
h = na > 1 
i = 1 > na

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)   
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false

Vous pouvez voir que l'opérateur de comparaison est très simple à utiliser, mais c'est aussi l'opérateur que nous utilisons le plus souvent lorsque nous écrivons des stratégies.closeopenJe ne sais pas. Comme pour l'opérateur d'opération, il y a une différence avec le Pine de Trading View sur FMZ, FMZ n'a pas de type de requête particulièrement strict, donc des déclarations comme celle-ci sont utilisées.d = "1" >= 2Il n'y a pas d'erreur sur FMZ, qui convertit une chaîne en valeur numérique lors de l'exécution, puis compare l'opération.


Opérateur logique
Opérateur Le code Expliquer
Non Je ne sais pas. Opérateur unique, non-opéré
avec et Opérateur binaire qui fonctionne avec ((et)
ou ou Opérateur binaire, ou opération

Si on parle d'opérateurs logiques, il faut parler de tables de vraies valeurs. Comme nous l'avons appris au lycée, mais ici, nous faisons des tests dans un système de retouche, nous apprenons:

a = 1 == 1  // 使用比较运算符构成的表达式,结果为布尔值
b = 1 != 1
c = not b   // 逻辑非操作符
d = not a   // 逻辑非操作符

runtime.log("测试逻辑操作符:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)

runtime.log("测试逻辑操作符:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)

runtime.error("stop")

Pour éviter que le système de retouche n'affecte les informations imprimées, nous avons utiliséruntime.error("stop")Une fois l'instruction imprimée, une erreur exceptionnelle est lancée qui arrête la vérification, puis l'on peut observer l'information produite et voir que le contenu imprimé et la table des valeurs réelles sont en fait les mêmes.


Opérateur triangulaire

Utiliser des opérateurs triangulaires? :Les expressions triangulaires qui se combinent avec les nombres d'opérateurscondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseNous l'avons déjà vu dans les cours précédents. Les expressions dites triangulaires, les opérateurs triangulaires signifient qu'il y a trois opérations au total.

condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseDans le centre.conditionSi la valeur de l'expression est vraie, elle est:valueWhenConditionIsTrueJe ne sais pas.conditionLa valeur de l'expression est:valueWhenConditionIsFalse

Il n'y a pas beaucoup d'utilité pratique, mais il y a un exemple pratique:

a = close > open
b = a ? "阳线" : "阴线"
c = not a ? "阴线" : "阳线"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

Si vous rencontrez un astérisque, ce n'est pas grave! Les expressions en trois dimensions peuvent également être imbriquées, comme nous l'avons fait dans le tutoriel précédent.

a = close > open
b = a ? math.abs(close-open) > 30 ? "阳线" : "十字星" : math.abs(close-open) > 30 ? "阴线" : "十字星"
c = not a ? math.abs(close-open) > 30 ? "阴线" : "十字星" : math.abs(close-open) > 30 ? "阳线" : "十字星"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

C'est en fait la même chose.condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseDansvalueWhenConditionIsTruevalueWhenConditionIsFalseL'expression est également remplacée par une autre expression triangulaire.


Opérateur historique

Utiliser les opérateurs historiques[], les valeurs historiques de la séquence de temps de référence. Ces valeurs historiques sont les valeurs de la variable sur la ligne K avant la ligne K BAR actuelle lorsque le script est exécuté.[]Les opérateurs sont utilisés après les appels de variables, d'expressions et de fonctions.[]La valeur dans cette parenthèse est la déviation de la distance de la ligne K BAR à partir des données historiques que nous voulons citer. Par exemple, si je cite le prix de clôture d'une ligne K BAR précédente, on peut écrire:close[1]

Nous avons déjà vu des phrases comme celle-ci dans des cours précédents:

high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)

[]L'opérateur ne peut être utilisé qu'une seule fois sur la même valeur, il est donc écrit de manière erronée et renvoie une erreur:

a = close[1][2]   // 错误

Vous pouvez voir ici, certains de vos camarades diront, les opérateurs.[]C'est pour les structures de séries, qui ressemblent à des séries et à des matrices! Voici un exemple pour montrer la différence entre une série et une matrice dans le langage Pine.

strategy("test", overlay=true)

a = close
b = close[1]
c = b[1]

plot(a, title="a")
plot(b, title="b")
plot(c, title="c")

Bien quea = close[1][2]Il y a une erreur dans la description, mais:

b = close[1]
c = b[1]

Si vous lisez les mathématiques de base, vous verrez qu'il n'y a pas d'erreur dans l'écriture séparée.b = close[1]Après l'attribution, b devrait être une valeur, cependant.c = b[1]On voit que le concept de série dans le langage Pine n'est pas aussi simple que l'arithmétique. On peut comprendre que la valeur historique sur le précédent Bar qui est proche est attribuée à b, et b est aussi une structure de séquence temporelle dont on peut continuer à citer la valeur historique. On voit donc que dans les trois lignes a, b et c dessinées, la ligne b est plus lente qu'une ligne BAR et la ligne c est plus lente qu'une ligne BAR.

Nous pouvons faire glisser le graphique vers la gauche et voir que sur la première ligne K, les valeurs de b et c sont toutes les deux des valeurs nulles (na) ; c'est parce que lorsque le script est exécuté sur la première ligne K BAR, une référence à l'avant, une valeur historique de deux cycles n'existe pas, elle n'existe pas.nanzNous avons déjà abordé cette question dans notre étude précédente.nznaLes fonctions, vous souvenez-vous de quel chapitre?) traitent spécifiquement des cas de valeurs vides, par exemple:

close > nz(close[1], open)    // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量

C'est un traitement qui peut faire référence à une valeur nulle ((na)).


Priorité des opérateurs

Nous avons déjà appris beaucoup d'opérateurs de la langue Pine qui forment des expressions en utilisant diverses combinaisons de nombres d'opérateurs. Alors, quelle est la priorité de ces opérations lorsqu'elles sont calculées dans une expression?

Les priorités Opérateur
9 []
8 L'opérateur de base+-etnot
7 */%
6 L'opérateur binaire+-
5 ><>=<=
4 ==!=
3 and
2 or
1 ?:

Les parties d'expressions à haute priorité sont traitées en premier, si la priorité est la même, elles sont traitées de gauche à droite.()L'expression partielle est enveloppée dans une expression obligatoire qui doit d'abord être traitée.

Variables

Déclaration des variables

Nous avons déjà étudié le concept de l'indicateur d'étalonnage, où l'indicateur d'étalonnage sert de nom à une variable.

  • Le modèle de déclaration: La première chose que l'on écrit quand on déclare une variable est " mode de déclaration " et il y a trois modes de déclaration de la variable: 1° Utilisez le mot clévarJe suis désolé. 2° Utilisez des mots clésvaripJe ne sais pas. Il n'y a rien à écrire.

    varvaripLe mot-clé que nous avons déjà appris dans le chapitre précédent " les opérateurs d'attribution " n'est plus mentionné ici. Si le mode de déclaration de la variable n'écrit rien, par exemple:i = 1En fait, nous avons déjà dit que les variables ainsi déclarées et leur attribution sont exécutées sur chaque ligne KBAR.

  • Le type Le langage Pine sur FMZ n'est pas strict sur les exigences de type et peut généralement être omis. Cependant, pour être compatible avec les stratégies de script sur Trading View, il est également possible de déclarer des variables avec un type. Par exemple:

    int i = 0 
    float f = 1.1
    

    Les types sont plus exigeants dans Trading View, et l'erreur est signalée si vous utilisez le code suivant dans Trading View:

    baseLine0 = na          // compile time error!
    
  • Identifiant L'identifiant est le nom d'une variable, dont le nom a été mentionné dans le chapitre précédent.https://www.fmz.com/bbs-topic/9390#标识符

En résumé, déclarer une variable peut s'écrire comme suit:

// [<declaration_mode>] [<type>] <identifier> = value 
   声明模式             类型     标识符       = 值

L'opérateur d'attribution est utilisé ici:=Lorsqu'une variable est déclarée, elle est attribuée une valeur.ifforwhileouswitchLa structure de l'if est un élément de base de la structure de l'if. Les mots-clés et l'utilisation des phrases seront expliqués plus en détail dans les cours suivants, mais nous avons déjà appris dans les cours précédents une simple attribution de phrases if.

Ici, nous avons mis l'accent sur la fonction d'entrée, une fonction que nous utilisons très souvent lorsque nous concevons des stratégies.

Fonction d'entrée:

input函数,参数defval、title、tooltip、inline、group

La fonction d'entrée sur FMZ est légèrement différente de celle de Trading View, mais elle est utilisée comme entrée d'attribution de paramètres de stratégie. Voici un exemple pour illustrer l'utilisation de la fonction d'entrée sur FMZ:

param1 = input(10, title="参数1名称", tooltip="参数1的描述信息", group="分组名称A")
param2 = input("close", title="参数2名称", tooltip="参数2的描述信息", group="分组名称A")
param3 = input(color.red, title="参数3名称", tooltip="参数3的描述信息", group="分组名称B")
param4 = input(close, title="参数4名称", tooltip="参数4的描述信息", group="分组名称B")
param5 = input(true, title="参数5名称", tooltip="参数5的描述信息", group="分组名称C")

ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)

Lorsqu'une variable est déclarée, une fonction d'entrée est souvent utilisée. Dans FMZ, la fonction d'entrée dessine automatiquement le contrôle utilisé pour définir les paramètres de la politique dans l'interface de la politique FMZ. Les contrôles pris en charge sur FMZ sont actuellement disponibles dans les boîtes d'entrée numériques, les boîtes d'entrée textuelles, les boîtes de défilement, les coffres-forts et les coffres-forts.

img

Nous avons présenté quelques paramètres principaux pour les fonctions d'entrée:

  • defval: la valeur par défaut de l'option paramètre de stratégie pour la fonction d'entrée, qui prend en charge les variables, les nombres et les chaînes intégrés du langage Pine
  • title : le nom du paramètre affiché par la politique sur l'interface politique de la disquette/réévaluation.
  • tooltip: Astuce pour les paramètres de stratégie, qui affiche le texte de la paramétrie lorsque la souris s'arrête sur les paramètres de stratégie.
  • group: nom de groupe de paramètres de stratégie, vous pouvez donner le nom de groupe de paramètres.

En plus de déclarer des variables individuelles, des attributions, le langage Pine déclare un ensemble de variables et les attribue:

[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构

Le plus commun est celui que nous utilisonsta.macdLorsque la fonction calcule l'indicateur MACD, puisque l'indicateur MACD est un indicateur multilinial, trois ensembles de données sont calculés.

[dif,dea,column] = ta.macd(close, 12, 26, 9)

plot(dif, title="dif")
plot(dea, title="dea")
plot(column, title="column", style=plot.style_histogram)

Nous pouvons facilement dessiner un diagramme MACD en utilisant le code ci-dessus, et non seulement les fonctions intégrées peuvent retourner plusieurs variables, mais aussi les fonctions personnalisées écrites peuvent retourner plusieurs données.

twoEMA(data, fastPeriod, slowPeriod) =>
    fast = ta.ema(data, fastPeriod)
    slow = ta.ema(data, slowPeriod)
    [fast, slow]

[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)

L'utilisation d'une structure telle que if comme attribution de plusieurs variables est similaire à la façon dont les fonctions personnalisées ci-dessus sont écrites.

[ema10, ema20] = if true
    fast = ta.ema(close, 10)
    slow = ta.ema(close, 20)
    [fast, slow]

plot(ema10, title="ema10", color=color.fuchsia, overlay=true)
plot(ema20, title="ema20", color=color.aqua, overlay=true)

Structure conditionnelle

Certaines fonctions ne peuvent pas être écrites dans des blocs de code locaux avec des branches conditionnelles.

couleur à barres (), remplissage (), ligne (), indicateur (), graphique (), bougie de graphique (), graphique graphique (), forme graphique ().

La restriction sur FMZ n'est pas aussi sévère, mais il est recommandé de suivre les règles d'écriture sur Trading View. Par exemple, bien que cela ne soit pas recommandé sur FMZ.

strategy("test", overlay=true)
if close > open 
    plot(close, title="close")
else 
    plot(open, title="open")

Le langage if


Plus de