Les ressources ont été chargées... Je charge...

FMZ PINE Script est un fichier

Auteur:L'inventeur de la quantification - un petit rêve, Créé: 2022-05-06 14:27:06, mis à jour: 2024-10-12 15:27:04

[TOC] Je vous en prie.

Les mots-clés, la grammaire, les paramètres et les résumés

Structure du code

La structure générale du code dans Pine est la suivante:

<version>
<declaration_statement>
<code>

Les notes

Symbole d'annotation supporté par FMZ dans la langue Pine: annotation en une seule ligne//Le blogueur a écrit:/* */Par exemple, dans les exemples suivants, les annotations sont écrites:

[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9)  // 计算MACD指标

/*
plot函数在图表上画出指标线
*/
plot(macdLine, color = color.blue, title='macdLine')
plot(signalLine, color = color.orange, title='signalLine')
plot(histLine, color = color.red, title='histLine')

Édition

Les instructions de compilation de la forme suivante indiquent au compilateur quelle version du script a été écrite avec Pine:

//@version=5

Par défaut, la version v5 peut être omise dans le code.//@version=5

Les déclarations

  • indicator()
  • strategy()

Les déclarations définissent le type de script, ce qui détermine ce qu'il permet et comment il est utilisé et exécuté. Elles définissent les attributs clés du script, tels que son nom, où il apparaîtra lorsqu'il sera ajouté au graphique, la précision et le format des valeurs qu'il affichera, et certaines valeurs qui contrôlent ses actions à l'exécution, telles que le nombre maximal d'objets graphiques qu'il affichera dans le graphique. Pour les stratégies, les attributs comprennent des paramètres qui contrôlent la répétition, tels que les capitaux initiaux, les commissions, les points de défilement, etc. FMZ ne demande pas que Pine soit inclus dans le code d'une stratégie.indicator()Ou alorsstrategy()Il y a aussi des gens qui ont été tués.

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

Séquence de temps

La séquence temporelle n'est pas un type ou un format de données, mais une notion de structure fondamentale dans le langage PINE. Elle est utilisée pour stocker des valeurs qui changent continuellement dans le temps, chaque valeur correspondant à un point de temps. Variables intégréesopenPar exemple:openLa variable par défaut enregistre le prix d'ouverture de chaque ligne KBAR si cetteopenC'est la période de cinq minutes de la ligne K.openCe qui est enregistré dans la variable est le prix d'ouverture de la colonne BAR de la ligne K toutes les 5 minutes.openC'est-à-dire en référence au prix d'ouverture de la ligne K BAR où elle se trouve actuellement. Pour citer la valeur précédente (la valeur passée) dans la séquence de temps, nous utilisons[]L'opérateur d'historique, lorsque la stratégie est exécutée sur un certain K-line BAR.open[1]Cela signifie qu'il s'agit du prix d'ouverture du premier K-Line BAR en référence au BAR actuel.

Bien queSéquence de tempsIl est facile de penser à une structure de données telle que "l'arithmétique", bien que le langage PINE ait aussi des types d'arithmétiques. Mais ce sont des concepts complètement différents de la séquence temporelle.

Les séquences de temps ainsi conçues dans le langage PINE permettent de calculer facilement la valeur cumulée du prix de clôture dans le code stratégique, sans avoir besoin d'utiliser des structures cycliques telles que for, et uniquement en utilisant des fonctions intégrées dans le langage PINE.ta.cum(close)Dans un autre exemple, nous devons calculer la moyenne des différences entre le prix le plus élevé et le prix le plus bas des 14 dernières lignes K BAR (c'est-à-dire le prix le plus proche de 14 lignes K BAR) au moment où le code est exécuté.ta.sma(high - low, 14)

Le résultat d'un appel à une fonction sur une séquence de temps laisse également une trace sur la séquence de temps.[]L'opérateur historique renvoie à la valeur précédente. Par exemple, lorsque le prix de clôture de la ligne K BAR actuelle est supérieur à la valeur maximale du prix le plus élevé des 10 dernières lignes K BAR (excluant la ligne K BAR actuelle), nous pouvons écrire:breach = close > ta.highest(close, 10)[1]On peut aussi écrire:breach = close > ta.highest(close[1], 10)Pourquoi?ta.highest(close, 10)[1]etta.highest(close[1], 10)Il y a aussi des gens qui ont été victimes de violences.

Vous pouvez vérifier avec le code suivant:

strategy("test pine", "test", true) 

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)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green)

Le code de test ci-dessus exécute les valeurs de a et b sur leur séquence de temps correspondante sur chaque BAR. On voit que les valeurs a et b sont toujours égales, donc les deux méthodes d'expression sont équivalentes.

Paramètres du modèle de la bibliothèque de classes de transactions de la langue Pine

Les paramètres du modèle intégré de la stratégie PINE, "Pine Language Exchange Library", sont définis.

img

Les réglages des transactions

  • Comment le faire Modèle de prix de clôture: le modèle n'est exécuté qu'à l'expiration de la barre actuelle, et les transactions sont exécutées au début de la barre inférieure. Modèle de prix en temps réel: le modèle est exécuté à chaque variation de prix, avec des signaux pour exécuter immédiatement la transaction.
  • Nombre d'opérations par défaut: Si l'instruction de transaction ne spécifie pas le nombre de transactions, les transactions sont exécutées selon ce nombre de positions.
  • Volume maximal de transaction unique: en fonction de la transaction réelle, en combinaison avec ce paramètre, définissez le nombre maximal de transactions par transaction, afin d'éviter les chocs sur la surface de la transaction.
  • Nombre de points de vente: selon定价货币精度Les paramètres et ce paramètre déterminent le prix à la livraison lors de la commande. Par exemple, la précision de la devise est réglée sur 2, c'est-à-dire exacte jusqu'à la deuxième place des décimales et exacte jusqu'à 0.01 ; alors le nombre de points à la livraison représente 0.01 unité de prix.
  • Le nombre de cycles le plus long de la variable: affecte le nombre de lignes BAR du graphique K, avecjavascriptAppelez dans la stratégieSetMaxBarLenLa fonction fonctionne de la même façon.

Options à terme

  • Code de variété: code de contrat, qui n'est nécessaire que lorsque l'objet de l'échange est un objet de l'échange non sur le marché.
  • Nombre minimum de contrats: le nombre minimum de transactions du contrat au moment de la commande.

Options de disque

  • Autorecovery: Récupère automatiquement l'état avant l'arrêt de la dernière stratégie.
  • Nombre de tentatives de commande: l'ordre n'est pas transactionnel, l'ordre est annulé et la transaction est tentée à nouveau. Ce paramètre est utilisé pour limiter le nombre maximum de tentatives de commande.
  • Intervalle de consultation de réseau (millisecondes): uniquement valable pour le protocole REST, contrôlant l'intervalle de requête du réseau et évitant des requêtes trop fréquentes et dépassant les limites de l'échange.
  • Temps de synchronisation des comptes (secondes): la période de synchronisation des données des comptes.
  • Temps de synchronisation des positions après l'ouverture (millisecondes): pour les positions répétitives causées par un certain retard de données sur les échanges, un temps de synchronisation plus long peut atténuer ce problème.
  • Multiples d'effet de levier: régler le multiplicateur d'effet de levier.

Traitements instantanés, autres paramètres

  • Volume de transaction: le volume de transaction par défaut est le même et ne s'applique qu'aux transactions en espèces.
  • Le volume de transactions est le plus petit possible.
  • La précision de la monnaie: la précision des prix, c'est-à-dire les petites quantités de prix.
  • Précision de la variété de transaction: la précision de la dernière unité, c'est-à-dire le petit nombre de chiffres de la dernière unité.
  • Frais de service: pour calculer certaines données selon ce paramètre, 0.002 est 2 parts de millième.
  • L'écart entre les statistiques sur les gains et les pertes: les statistiques sur les gains et les pertes ne sont affichées que sur le disque.
  • Réessayer après un échec (millisecondes): intervalle de réessayage lorsque la demande réseau échoue.
  • Utiliser des agents: validé uniquement pour le protocole REST.
  • Masquer les erreurs courantes du réseau: Masquer les erreurs courantes du journal dans la zone des journaux.
  • Le changement d'adresse de base est valable uniquement pour le protocole REST.
  • Envoyez des notifications: envoyez des messages à votre boîte de réception.

Compte à rebours

Ouverture du marché

strategy(title = "open long example", pyramiding = 3)                                // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.01)                                         // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.02, when = close > ta.ema(close, 10))       // 条件触发,执行下单,市价开多仓
strategy.entry("long3", strategy.long, 0.03, limit = 30000)                          // 指定(较低的)价格,计划下买单订单,等待成交开仓,限价开仓

Plateau

strategy(title = "close long example", pyramiding = 2)                              // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.1)                                         // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.1)                                         // 市价开多仓,指定分组标签为long2
strategy.close("long1", when = strategy.position_size > 0.1, qty_percent = 50, comment = "close buy entry for 50%")   // 平仓,指定平掉分组标签为long1的仓位的50%持仓
strategy.close("long2", when = strategy.position_size > 0.1, qty_percent = 80, comment = "close buy entry for 80%")   // 平仓,指定平掉分组标签为long2的仓位的80%持仓

Mécanisme de négociation

Le mécanisme de possession du langage PINE est similaire à celui de la possession unidirectionnelle. Par exemple, lorsqu'il y a une position multi-tête (" multi-tête "), l'ordre déclenché s'il y a des ordres de vente, des listes de plans, etc. (versus la direction de la possession) est exécuté en aplatissant d'abord la position multi-tête (" aplatissant toutes les multi-têtes ") avant d'exécuter l'ordre déclenché par rapport à la direction inverse de la possession avant la possession.

Liste des projets

Lorsque vous utilisez la commande de sous-titres, la commande de marché est la commande par défaut si aucun prix n'est spécifié. En plus de la commande de marché, vous pouvez également commander par le biais du sous-titre de plan, qui n'est pas immédiatement opérationnel. Le sous-titre de plan peut être utilisé dans la file d'attente du programme qui n'existe pas lorsqu'il est déclenché.Disque réelL'information de l'état temporel (c'est-à-dire le panneau d'état de la stratégie en cours d'exécution) est visible dans la section "Ordres planifiés" du tableau. Le système n'effectue de véritables commandes que lorsque les conditions de prix du marché en temps réel sont remplies pour déclencher ces ordres.strategy.entryOn peut spécifier une fonction sous forme delimitstopParamètres.

var isTrade = false 
if not barstate.ishistory and not isTrade
    isTrade := true 
    strategy.entry("test 1", strategy.long, 0.1, stop=close*1.3, comment="test 1 order")                     // stop
    strategy.entry("test 2", strategy.long, 0.2, limit=close*0.7, comment="test 2 order")                    // limit
    strategy.entry("test 3", strategy.short, 0.3, stop=close*0.6, limit=close*1.4, comment="test 3 order")   // stop-limit    
  • Commande limitée

    Le prix de l'offre est fixé à la limite de la commande, c'est-à-dire lorsque l'offre est payante (c'est-à-dire que la commande est payante).directionLe paramètre eststrategy.longL'ordre n'est déclenché que lorsque le prix actuel du marché est inférieur à ce prix. Lorsque la commande est une vente (c'est-à-diredirectionLe paramètre eststrategy.shortL'ordre n'est déclenché que lorsque le prix actuel du marché est supérieur à ce prix.

  • Arrêtez la commande

    Le prix d'arrêt d'une commande est fixé, lorsque l'ordre est un paiement, et que l'ordre n'est déclenché que lorsque le prix actuel du marché est supérieur à ce prix. Lorsqu'une commande est une vente, elle n'est déclenchée que lorsque le prix actuel du marché est inférieur à ce prix.

  • Commande stop-limit

    Il est possible de configurer simultanémentlimitstopParamètres, les commandes sont déclenchées au premier prix qui répond aux conditions.

Pourcentage des droits et intérêts

//@version=5
strategy("Percent of Equity Order", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)  

// 简单的均线交叉策略
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))  

// 如果均线交叉条件满足,则买入或卖出
if (longCondition)
    strategy.entry("Long", strategy.long)  

if (shortCondition)
    strategy.entry("Short", strategy.short)
  

Définitiondefault_qty_type=strategy.percent_of_equityEnsuite, le réglagedefault_qty_valuePour le nombre de pourcentages ((0 à 100), 1 est 1%;; le montant est calculé en fonction du nombre de monnaies cotées dans le compte;; par exemple: le compte actuel a 10000 USDT, le pourcentage de 1% est défini, c'est-à-dire un pourcentage de 100 USDT est utilisé (calculé en fonction du prix actuel lors de la vente).

Déclaration, mot clé de structure logique

- Je ne sais pas.

var est le mot clé utilisé pour l'attribution et l'initialisation de variables à usage unique. Généralement, la syntaxe d'attribution des variables qui ne contient 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, même si les données sont mises à jour, elles peuvent être maintenues dans l'état d'état et ne changer que si les conditions dans les if-expressions sont remplies.

var variable_name = expression

Il a écrit:

  • variable_name- N'importe quel nom de variable utilisateur autorisé dans Pine Script ((peut contenir des caractères latins en majuscules et en minuscules, des chiffres et des signes de bas de page ((_), mais ne peut pas commencer par un chiffre)).
  • expression- n'importe quelle expression arithmétique, comme définir une variable régulière.

Exemples

// Var keyword example
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 ligne de chaque pilier 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.

Sur FMZ, il existe deux modèles de prix en temps réel, le modèle de prix de clôture et le modèle de prix de vente au détail.varvaripLes variables déclarées sont testées avec le code suivant:

strategy("test pine", "test 1", 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
if true
    i := i + 1
    ii := ii + 1
  • Modèle de prix en temps réel Le code de test ci-dessus est divisé en deux phases lors de l'exécution: la phase K historique; la phase K en temps réel.varvaripLes variables déclarées i、ii exécutent des opérations d'incrémentation à chaque fois que le code de stratégie est exécuté (parce queif trueOn peut donc voir que les chiffres affichés sur la ligne BAR du résultat de la récupération augmentent de 1 chacun. Lorsque la phase de la ligne K historique se termine, la phase de la ligne K en temps réel commence.varvaripLes variables déclarées commencent à changer différemment. Parce que c'est un modèle de prix en temps réel, chaque changement de prix dans un K-line BAR est exécuté en code stratégique une fois.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, jusqu'à ce que la ligne K actuelle BAR soit terminée.

  • Modèle de prix de clôture Comme 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.varvaripLes variables déclarées sont parfaitement cohérentes dans l'exemple ci-dessus, avec une augmentation de 1 pour chaque ligne KBAR.

variété

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.

varip variable_name = expression

Il a écrit:

  • variable_name- N'importe quel nom de variable utilisateur autorisé dans le script Pine (qui peut contenir des caractères latins en majuscules et en minuscules, des chiffres et des signes de bas de page (_), mais ne peut pas commencer par un chiffre).
  • expression- n'importe quelle expression arithmétique, comme lors de la définition d'une variable régulière. Sur la première ligne K, l'expression est calculée une seule fois et attribuée à la variable une seule fois.

Exemples

// varip
varip int v = -1
v := v + 1
plot(v)

En utilisant var, le graphique renvoie la valeur de bar_index. En utilisant varip, le même comportement se produit sur la ligne historique K, mais sur la ligne en temps réel K, le graphique renvoie une valeur qui augmente d'une pour chaque tick.

Nom de l'auteurNe peut être utilisé qu'avec des types simples, tels que float, int, boolean, string, et avec des tableaux de ces types.

vrai

Indique la valeur d'une variable de type Boole, ou lorsque l'expression est utiliséeComparaisonouLa logiqueLa valeur que l'opérateur peut calculer.

Nom de l'auteurVoir aussiComparaisonLes opérateurs etLa logiqueDescription de l'opérateur.

À bientôt bool

faux

Indique la valeur d'une variable de type Boole, ainsi que le résultat d'opérations de comparaison, d'opérations logiques.

Nom de l'auteurVoir aussiComparaisonLes opérateurs etLa logiqueDescription de l'opérateur.

À bientôt bool

si

Les if-statements définissent les blocs de phrases qui doivent être exécutés lorsque les conditions de l'expression sont remplies. La 4e version du langage de script Pine vous permet d'utiliser la syntaxe if-else.

Le code générique provient de:

var_declarationX = if condition
    var_decl_then0
    var_decl_then1
    ...
    var_decl_thenN
    return_expression_then
else if [optional block]
    var_decl_else0
    var_decl_else1
    ...
    var_decl_elseN
    return_expression_else
else
    var_decl_else0
    var_decl_else1
    ...
    var_decl_elseN
    return_expression_else

Nom de l'auteur var_declarationX- Cette variable obtient la valeur de la phrase ifcondition- Si la condition est true, utilisez le bloc de phrasesthenLa logique est la suivante:var_decl_then0var_decl_then1etc) ⇒ Si la condition est false, on utilise les blocs de phraseselse ifOu alorselseLa logique est la suivante:var_decl_else0var_decl_else1Je suis désolée.return_expression_then , return_expression_else- La dernière expression dans le module ou l'expression du blocelse renvoie la valeur finale de la phrase. Si la variable est déclarée à la fin, sa valeur sera la valeur de résultat.

Le type de la valeur retournée de l'instruction if dépend dereturn_expression_thenetreturn_expression_elseLorsqu'elles sont exécutées sur TradingView, leurs types doivent correspondre: il est impossible de retourner une valeur entière à partir du bloc de syntaxe then lorsque vous avez une valeur de chaîne dans le blocelse. Lorsqu'elles sont exécutées sur FMZ, les exemples suivants ne renvoient pas d'erreur, lorsque la valeur y est prise pour "open", la valeur du graphique de plot est n/a.

Exemples

// This code compiles
x = if close > open
    close
else
    open  

// This code doesn’t compile by trading view
// y = if close > open
//     close
// else
//     "open"
plot(x)

On peut omettreelsebloc. Dans ce cas, si la condition est false, on attribue à la variable var_declarationX une valeur de seuil naempty ((na、false ou na):

Exemples

// if
x = if close > open
    close
// If current close > current open, then x = close.
// Otherwise the x = na.
plot(x)

Il est possible d'utiliser plusieurs blocs ou de ne pas les utiliser du tout. Les blocs then, else if, else if sont déplacés en quatre espaces:

Exemples

// if
x = if open > close
    5
else if high > low
    close
else
    open
plot(x)

Je ne sais pas.ifLa valeur de résultat d'une déclaration ((var_declarationX= peut être omise)). Elle peut être utile si vous avez besoin d'un côté-fonctionnement de l'expression, par exemple dans une transaction stratégique:

Exemples

if (ta.crossover(high, low))
    strategy.entry("BBandLE", strategy.long, stop=low)
else
    strategy.cancel(id="BBandLE")

Les phrases if peuvent être mutuellement contenues:

Exemples

// if
float x = na
if close > open
    if close > close[1]
        x := close
    else
        x := close[1]
else
    x := open
plot(x)

pour

La structure for permet d'exécuter plusieurs phrases en répétition:

[var_declaration =] for counter = from_num to to_num [by step_num]
    statements | continue | break
    return_expression

var_declaration- Une variable facultative déclarée, qui sera assignée comme valeur de l'expression return_expression de la boucle de retour.counter- Stocke les variables de la valeur du compteur de la boucle de retour, augmentant/diminuant la valeur de 1 ou step_num à chaque fois que la boucle de retour est effectuée;from_num- La valeur initiale du compteur. L'utilisation de l'expression int/float threshold/series est autorisée.to_num- La valeur finale du compteur. Le cycle est interrompu lorsque le compteur est supérieur à to_num (ou inférieur à to_num dans le cas de from_num > to_num). L'utilisation de l'expression int/float threshold/series est autorisée, mais elle n'est évaluée que lors de la première itération du cycle.step_num- la valeur d'augmentation/diminution du compteur. Elle est optionnelle. La valeur par défaut est +1 ou -1, selon la plus grande valeur de from_num ou de to_num.statements | continue | break- N'importe quel nombre de phrases, ou les mots-clés "continue" ou "break", réduit à 4 espaces ou à un onglet.return_expression- la valeur de retour du cycle, si elle existe, est attribuée à une variable dans la déclaration var_declaration. Si le cycle quitte à cause du mot clé "continue" ou "break", la valeur de retour du cycle est la valeur de retour de la dernière variable à laquelle la valeur a été attribuée avant de quitter le cycle.continue- le mot-clé qui ne peut être utilisé que dans la boucle de retour. Il entraîne l'exécution de la prochaine itération de la boucle de retour.break- Le mot clé pour sortir du cercle de retour.

Exemples

// Here, we count the quantity of bars in a given 'lookback' length which closed above the current bar's close
qtyOfHigherCloses(lookback) =>
    int result = 0
    for i = 1 to lookback
        if close[i] > close
            result += 1
    result
plot(qtyOfHigherCloses(14))

À bientôt for...in while

Pour... dans

for...inLa structure permet d'exécuter plusieurs déclarations en répétition pour chaque élément de l'array. Elle peut être utilisée avec n'importe quel paramètre:array_element, ou en combinaison avec deux paramètres:[index, array_element]La seconde forme n'affecte pas la fonction de la boucle. Elle suit l'index de l'itération en cours dans la première variable de l'élément.

[var_declaration =] for array_element in array_id
    statements | continue | break
    return_expression

[var_declaration =] for [index, array_element] in array_id
    statements | continue | break
    return_expression

var_declaration- une déclaration de variable facultative qui sera attribuée à la bouclereturn_expressionLa valeur de l'image estindex- Suivre les variables optionnelles de l'index de l'itération en cours. L'index commence à zéro. Les variables sont invariantes dans le corps de la boucle.array_elementIl y a une différence entre les deux.array_element- contient les variables de chaque élément d'une matrice continue à traiter dans le cercle. Cette variable est invariable dans le cercle.array_id- L'ID d'une matrice qui fait le tour de l'itinéraire.statements | continue | break- N'importe quel nombre de phrases, ou les mots-clés "continue" ou "break", réduit à 4 espaces ou à un onglet.return_expression- la valeur de retour du cycle est attribuée àvar_declarationLes variables, si elles existent. Si le cercle se déconnecte en raison du mot clé "continue" ou "break", la valeur de retour du cercle est la dernière variable attribuée avant de se déconnecter.continue- le mot-clé qui ne peut être utilisé que dans la boucle de retour. Il entraîne l'exécution de la prochaine itération de la boucle de retour.break- Le mot clé pour sortir du cercle de retour.

Permet de modifier l'élément de l'array ou sa taille pendant le cycle. Ici, nous utilisonsfor...inLa forme de l'option monogène pour déterminer combien de lignes K ont une valeur OHLC supérieure à la SMA de la valeur de l'angle proche sur chaque ligne K est:

Exemples

// Here we determine on each bar how many of the bar's OHLC values are greater than the SMA of 'close' values
float[] ohlcValues = array.from(open, high, low, close)
qtyGreaterThan(value, array) =>
    int result = 0
    for currentElement in array
        if currentElement > value
            result += 1
        result
plot(qtyGreaterThan(ta.sma(close, 20), ohlcValues))

Ici, nous utilisons les deux formes de paramètres de for...in pour rendre notreisPosLa valeur de l'ensemble est définie commetrueIls sont dans notre pays.valuesArrayLes valeurs correspondantes dans l'arithmétique sont:

Exemples

// for...in
var valuesArray = array.from(4, -8, 11, 78, -16, 34, 7, 99, 0, 55)
var isPos = array.new_bool(10, false)  

for [index, value] in valuesArray
    if value > 0
        array.set(isPos, index, true)  

if barstate.islastconfirmedhistory
    runtime.log(str.tostring(isPos))

À bientôt for while array.sum array.min array.max

pendant que

whileLes statements permettent l'hypothèse de conditions dans les blocs de code locaux.

variable_declaration = while boolean_expression
    ...
    continue
    ...
    break
    ...
    return_expression

Il a écrit:variable_declaration- Déclaration de variable facultative.return expressionUne valeur d'initialisation peut être fournie pour cette variable.boolean_expression- Exécuter si c'est vraiwhileLe bloc local de l'instruction.whileAprès la phrase, continuez à exécuter le script.continue - continueLes mots clés conduisent à la branche circulaire jusqu'à la prochaine itération.break - breakLes mots clés entraînent la fin du cycle.whileLe texte est repris après la phrase.return_expression- fourniwhileLa valeur de retour de la phrase est une ligne facultative.

Exemples

// This is a simple example of calculating a factorial using a while loop.
int i_n = input.int(10, "Factorial Size", minval=0)
int counter   = i_n
int factorial = 1
while counter > 0
    factorial := factorial * counter
    counter   := counter - 1

plot(factorial)

Nom de l'auteurLes débutswhileLe bloc de code local après la ligne doit être condensé en quatre espaces ou en un caractère.whileLe cyclewhileL'expression de Boole suivante doit éventuellement devenir false ou doit être exécutée.break

échangeur

L'opérateur switch transfère le contrôle vers l'une des statements en fonction de la valeur de la condition et de l'expression.

[variable_declaration = ] switch expression
    value1 => local_block
    value2 => local_block
    ...
    => default_local_block

[variable_declaration = ] switch
    boolean_expression1 => local_block
    boolean_expression2 => local_block
    ...
    => default_local_block

Le commutateur avec une expression:

Exemples

// Switch using an expression

string i_maType = input.string("EMA", "MA type", options = ["EMA", "SMA", "RMA", "WMA"])

float ma = switch i_maType
    "EMA" => ta.ema(close, 10)
    "SMA" => ta.sma(close, 10)
    "RMA" => ta.rma(close, 10)
    // Default used when the three first cases do not match.
    => ta.wma(close, 10)

plot(ma)

Le commutateur sans expression:

Exemples

strategy("Switch without an expression", overlay = true)

bool longCondition  = ta.crossover( ta.sma(close, 14), ta.sma(close, 28))
bool shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))

switch
    longCondition  => strategy.entry("Long ID", strategy.long)
    shortCondition => strategy.entry("Short ID", strategy.short)

Retourne la valeurLa valeur de la dernière expression dans le bloc d'instructions locale exécuté.

Nom de l'auteurIl suffit d'exécuterlocal_blockexemple oudefault_local_blockL'un d'eux est là.default_local_blockseulement avec=>Les balises sont introduites en même temps et ne sont exécutées que si le bloc précédent n'est pas exécuté.switchLe résultat de la phrase est attribué à une variable et n'est pas spécifiédefault_local_blockSi cela n'est pas fait,local_blockLa phrase est retournée.naJe vais.switchQuand les résultats de la phrase sont attribués à une variable, tous les résultats sont attribués à une variable.local_blockL'instance doit retourner une valeur du même type.

À bientôt if ?:

séries

series est un mot-clé qui désigne le type de série de données.seriesLes mots clés sont généralement inutiles.

Opérateur

=

Utilisé pour attribuer des valeurs à des variables, mais uniquement lorsque les variables sont déclarées (pour la première fois).

:=

L'opérateur d'attribution donne une attribution à la variable de gauche.

!=

Ce n'est pas équivalent à: ⇒ appliqué à n'importe quel type d'expression

expr1 != expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

%

Les nombres modulaires (les nombres entiers positifs) ≠ sont utilisés pour les expressions numériques.

expr1 % expr2

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

Nom de l'auteurDans le script Pine, le marchand est coupé lorsqu'il calcule le résultat d'un nombre entier; c'est-à-dire qu'il est coupé en quatre-quarts-cinq jusqu'à sa valeur absolue la plus faible. La valeur obtenue a le même symbole que le dividende.

Exemple: -1 % 9 = -1 - 9 * truncate ((-1/9) = -1 - 9 * truncate ((-0.111) = -1 - 9 * 0 = -1.

%=

Désignation des nombres modulaires. Pour les expressions numériques.

expr1 %= expr2

Exemples

// Equals to expr1 = expr1 % expr2.
a = 3
b = 3
a %= b
// Result: a = 0.
plot(a)

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

*

La multiplication. Elle s'applique aux expressions numériques.

expr1 * expr2

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

*=

Le terme "multiplication" est utilisé pour les expressions numériques.

expr1 *= expr2

Exemples

// Equals to expr1 = expr1 * expr2.
a = 2
b = 3
a *= b
// Result: a = 6.
plot(a)

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

+

Ajout ou unité de chiffres. Pour une expression numérique ou une chaîne.

expr1 + expr2
+ expr

Retourne la valeurLe système binaire de la chaîne+Retournez la combinaison d'expr1 et d'expr2. Les chiffres renvoient des nombres entiers ou des valeurs à virgule, ou une série de valeurs: Le binomial +' retourne express1 plus express2 ≠. Une unité de valeur + une unité de valeur renvoie expr ((pas de contenu ajouté à la symétrie des unités d'opérateurs)).

Nom de l'auteurVous pouvez utiliser des opérateurs arithmétiques avec des chiffres ainsi que des colonnes de variables. Dans le cas où vous utilisez des colonnes de nombres, les opérateurs sont appliqués aux éléments.

+=

Les désignations additionnelles sont utilisées pour les expressions numériques ou les chaînes de caractères.

expr1 += expr2

Exemples

// Equals to expr1 = expr1 + expr2.
a = 2
b = 3
a += b
// Result: a = 5.
plot(a)

Retourne la valeurPour les chaînes, retournez la séquence d'expr1 et d'expr2; pour les chiffres, retournez l'entier ou la valeur à flèche, ou une série de valeurs.

Nom de l'auteurVous pouvez utiliser des opérateurs arithmétiques avec des chiffres ainsi que des colonnes de variables. Dans le cas où vous utilisez des colonnes de nombres, les opérateurs sont appliqués aux éléments.

-

La loi de la subtraction ou le nombre unitaire négatif.

expr1 - expr2
- expr

Retourne la valeurRetourne un entier ou une valeur à virgule, ou une série de valeurs: Le binomial +' retourne express1 moins express2 ≠. Un dollar-Retournez la négation d'expr.

Nom de l'auteurVous pouvez utiliser des opérateurs arithmétiques avec des chiffres ainsi que des colonnes de variables. Dans le cas où vous utilisez des colonnes de nombres, les opérateurs sont appliqués aux éléments.

-=

Désignation de la subtraction. Cette désignation s'applique aux expressions numériques.

expr1 -= expr2

Exemples

// Equals to expr1 = expr1 - expr2.
a = 2
b = 3
a -= b
// Result: a = -1.
plot(a)

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

/

L'exception << s'applique à l'expression numérique <<.

expr1 / expr2

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

/=

En plus de la désignation.

expr1 /= expr2

Exemples

// Equals to expr1 = expr1 / expr2.
a = 3
b = 3
a /= b
// Result: a = 1.
plot(a)

Retourne la valeurLes nombres entiers ou les valeurs à virgule, ou une série de valeurs.

<

Moins que. s'applique à l'expression numérique.

expr1 < expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

<=

est inférieur ou égal à ; s'applique à l'expression numérique.

expr1 <= expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

==

L'équivalent d'une expression peut être appliqué à n'importe quel type d'expression.

expr1 == expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

=>

L'opérateur '=>' est utilisé pour les déclarations de fonctions définies par l'utilisateur etswitchIl y a des gens qui sont en colère.

La syntaxe de la déclaration de fonction est:

<identifier>([<parameter_name>[=<default_value>]], ...) =>
    <local_block>
    <function_result>

Une<local_block>Il s'agit de zéro ou plusieurs phrases Pine.<function_result>Une variable, une expression ou un élément.

Exemples

// single-line function
f1(x, y) => x + y
// multi-line function
f2(x, y) => 
    sum = x + y
    sumChange = ta.change(sum, 10)
    // Function automatically returns the last expression used in it
plot(f1(30, 8) + f2(1, 3))

Nom de l'auteurVous trouverez plus d'informations sur les fonctions définies par l'utilisateur dans la page Déclarations et bibliothèques de scripts du manuel utilisateur.

>

Plus grand que ─ s'applique à l'expression numérique ─

expr1 > expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

>=

est supérieur ou égal à.

expr1 >= expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

?:

L'opérateur à trois conditions.

expr1 ? expr2 : expr3

Exemples

// Draw circles at the bars where open crosses close
s2 = ta.cross(open, close) ? math.avg(open,close) : na
plot(s2, style=plot.style_circles, linewidth=2, color=color.red)  

// Combination of ?: operators for 'switch'-like logic
c = timeframe.isintraday ? color.red : timeframe.isdaily ? color.green : timeframe.isweekly ? color.blue : color.gray
plot(hl2, color=c)

Retourne la valeurSi l'expr1 est évalué comme vrai, alors l'expr2 est évalué comme vrai, sinon l'expr3 est évalué comme vrai.

Nom de l'auteurSi vous n'en avez pas besoin, veuillez utiliser na comme branche de l'élanelse. Vous pouvez combiner deux ou plusieurs opérateurs?: pour réaliser des phrases similaires aux phrases de commutateur de commutateur (voir l'exemple ci-dessus). Vous pouvez utiliser des opérateurs arithmétiques avec des chiffres ainsi que des colonnes de variables. Dans le cas où vous utilisez des colonnes de nombres, les opérateurs sont appliqués aux éléments.

À bientôt na

[]

Les sous-titres de la série↑ donnent accès aux valeurs précédentes de la série expr1↑ expr2 est le nombre de lignes k passées et doit être un nombre↑ la flottabilité sera omise à la baisse↑

expr1[expr2]

Exemples

// [] can be used to "save" variable value between bars
a = 0.0 // declare `a`
a := a[1] // immediately set current value to the same as previous. `na` in the beginning of history
if high == low // if some condition - change `a` value to another
    a := low
plot(a)

Retourne la valeurUne série de valeurs.

À bientôt math.floor

et

La logique AND ─ est appliquée à l'expression de Boole ─.

expr1 and expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

ou

La logique OR↑ est appliquée à l'expression de Boole↑

expr1 or expr2

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

Je ne sais pas.

La requête logique inverse ((NOT) ⇒ s'applique à l'expression de Boole.

not expr1

Retourne la valeurLes valeurs de Boole, ou une série de valeurs de Boole.

Mots clés de type de données

Boole

Mots-clés de type "Bool" utilisés pour déclarer explicitement une variable ou un paramètre. La valeur de la variable "Bool" peut être true, false ou na.

Exemples

// bool
bool b = true    // Same as `b = true`
b := na
plot(b ? open : close)

Nom de l'auteurUne mention explicite du type dans la déclaration de la variable est facultative, sauf si elle est initialement initialisée avec na. En savoir plus sur le type Pine sur la page du manuel utilisateur du système de types.

À bientôt var varip int float color string true false

int

Mots-clés de type int ((int) ), utilisés pour déclarer explicitement une variable ou un paramètre.

Exemples

// int
int i = 14    // Same as `i = 14`
i := na
plot(i)

Nom de l'auteurUne mention explicite du type dans la déclaration de la variable est facultative, sauf si elle est initialement initialisée avec na. En savoir plus sur le type Pine sur la page du manuel utilisateur du système de types.

À bientôt var varip float bool color string

flottant

Mots-clés de type float ("point flottant") utilisés pour déclarer explicitement une variable ou un paramètre.

Exemples

// float
float f = 3.14    // Same as `f = 3.14`
f := na
plot(f)

Nom de l'auteurUne mention explicite du type dans la déclaration de la variable est facultative, à moins qu'il ne soit initialement en na.

À bientôt var varip int bool color string

une chaîne

Mots-clés de type "string" pour déclarer explicitement une variable ou un paramètre.

Exemples

// string
string s = "Hello World!"    // Same as `s = "Hello world!"`
// string s = na // same as "" 
plot(na, title=s)

Nom de l'auteurUne mention explicite du type dans la déclaration de la variable est facultative, sauf si elle est initialement initialisée avec na. En savoir plus sur le type Pine sur la page du manuel utilisateur du système de types.

À bientôt var varip int float bool str.tostring str.format

couleur

Mots clés de type "color" pour déclarer explicitement une variable ou un paramètre.

Exemples

// color
color textColor = color.green
if barstate.islastconfirmedhistory
    runtime.log("test", textcolor = textColor)

Nom de l'auteurLes caractères de couleur ont le format suivant: #RRGGBB ou #RRGGBBAA. Les lettres représentent les valeurs à seize chiffres de 00 à FF (de 0 à 255 décimales), où RR, GG et BB sont les valeurs des facteurs rouge, vert et bleu de la couleur. AA est la valeur optionnelle de la transparence des couleurs (ou du facteur alpha), où 00 est invisible et FF est opaque. Une mention explicite du type dans la déclaration de la variable est facultative, sauf si elle est initialement initialisée avec na. En savoir plus sur le type Pine sur la page du manuel utilisateur du système de types.

À bientôt var varip int float string color.rgb color.new

séquence

Mots-clés pour le type de chaîne de chaîne de l'array qui déclare explicitement une variable ou un paramètre.array.new<type>,array.fromLa fonction crée des objets d'array ((ou ID)).

Exemples

// array
array<float> a = na
a := array.new<float>(1, close)
plot(array.get(a, 0))

Nom de l'auteurLes objets d'une matrice sont toujours en forme de chaîne en chaîne.

À bientôt var array.new array.from

Objets

Les objets du langage PINE sont des instances de type défini par l'utilisateur (UDT), qui peut être compris comme une classe sans méthode, permettant aux utilisateurs de créer des types personnalisés dans une stratégie organisant des valeurs différentes dans une entité.

Définition du type

Nous allons définir un type d'ordre pour stocker l'information de l'ordre:

type order
    float price
    float amount
    string symbol
  • UtilisationtypeLe type de déclaration de mots clés.
  • type est le nom du type suivi du mot clé.
  • La première ligne type définit le nom du type, puis, en réduisant les quatre champs, définit le champ que contient ce type.
  • Chaque champ a besoin de déclarer son type de données, tel que int, float, string.

Créer des objets

Utiliser des types déclarés, appelernew()Les objets créés par la fonction:

order1 = order.new()
order1 = order.new(100, 0.1, "BTC_USDT")
order1 = order.new(amount = 0.1, symbol = "BTC_USDT", price = 100)

Vous pouvez également créer des objets vides:

order order1 = na

Voici un exemple concret:

type order
    float price
    float amount
    string symbol

if strategy.position_size == 0 and open > close
    strategy.entry("long", strategy.long, 1)

order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
// runtime.log(order1)   // 输出 {"data":{"price":46002.8,"amount":1,"symbol":"swap"},"_meta":0,"_type":"order"}

L'exemple suivant:

order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)

Il est également possible d'écrire ceci:

order order1 = na
order1 := order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)

Type d'objet utilisé pour le mot clé var

//@version=5
indicator("Objects using `var` demo")

//@type A custom type to hold index, price, and volume information.
type BarInfo
    int   index = bar_index
    float price = close
    float vol   = volume

//@variable A `BarInfo` instance whose fields persist through all iterations, starting from the first bar.
var BarInfo firstBar = BarInfo.new()
//@variable A `BarInfo` instance declared on every bar.
BarInfo currentBar = BarInfo.new()

// Plot the `index` fields of both instances to compare the difference.
plot(firstBar.index, "firstBar")
plot(currentBar.index, "currentBar")

Lorsqu'une variable est attribuée à un objet de type défini par l'utilisateur à l'aide d'une déclaration de mot-clé var, ce mot-clé est automatiquement appliqué à tous les champs de cet objet. Cela signifie que l'objet déclaré par le mot-clé var conserve son état entre chaque itération sans avoir à réinitialement sa valeur de champ à chaque itération.

  • L'objet firstBar est déclaré avec le mot-clé var, de sorte que ses champs (index, price, vol) conserveront leur valeur dans chaque itération, de la première entrée à la dernière entrée.
  • L'objet currentBar n'utilise pas de déclaration de mots-clés var, de sorte que ses champs seront réinitialisés à chaque entrée et qu'il y aura un nouvel objet à chaque itération.

Vous pouvez comparer les différences entre les deux objets en dessinant des champs d'index. firstBar.index conserve la valeur précédemment définie dans chaque itération, tandis que currentBar.index est réinitialisé dans chaque itération en tant que valeur de bar_index de l'article en cours.

Type d'objet utilisé pour le mot-clé varip

//@version=5
indicator("Objects using `varip` fields demo")

//@type A custom type that counts the bars and ticks in the script's execution.
type Counter
    int       bars  = 0
    varip int ticks = 0

//@variable A `Counter` object whose reference persists throughout all bars.
var Counter counter = Counter.new()

// Add 1 to the `bars` and `ticks` fields. The `ticks` field is not subject to rollback on unconfirmed bars.
counter.bars  += 1
counter.ticks += 1

// Plot both fields for comparison.
plot(counter.bars, "Bar counter", color.blue, 3)
plot(counter.ticks, "Tick counter", color.purple, 3)

Dans Pine, l'utilisation du mot-clé varip indique que les champs d'un objet peuvent persister tout au long de l'exécution du script, sans être roulés dans des colonnes non confirmées. Dans une déclaration de type Counter, le champ bars n'utilise pas le mot-clé varip, et donc il roule dans chaque colonne non confirmée; tandis que le champ ticks utilise le mot-clé varip, et donc il ne roule pas dans la colonne non confirmée. L'objet counter est déclaré avec le mot-clé var, il sera donc présent tout au long de l'exécution du script. Dans chaque itération, les champs bars et ticks sont augmentés de 1; les champs bars sont redirigés dans chaque colonne non vérifiée, tandis que les champs ticks ne le sont pas. Enfin, en dessinant les champs counter.bars et counter.ticks, on peut comparer les différences entre eux. Les valeurs de counter.bars vont rouler dans chaque colonne non confirmée, tandis que les valeurs de counter.ticks vont continuer à augmenter jusqu'à ce que le script soit terminé.

Modifier la valeur du champ

type order
    float price
    float amount
    string symbol

if strategy.position_size == 0 and open > close
    strategy.entry("long", strategy.long, 1)
    
order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)

if strategy.position_size != 0
    runtime.log(order1)
    order1.price := 999
    order1.amount := 100
    runtime.log(order1)
    runtime.error("stop")

Vous pouvez utiliser:=L'opérateur de réattribution modifie la valeur d'un champ d'objet.

Ensemble d'objets

L'exemple déclare une matrice vide qui stocke des objets de type ordre défini par l'utilisateur:

type order
    float price
    float amount
    string symbol

arrOrder = array.new<order>()

order1 = order.new(99, 1, "BTC_USDT")
order2 = order.new(100, 2, "ETH_USDT")

array.push(arrOrder, order1)
array.push(arrOrder, order2)

runtime.log(arrOrder)
runtime.error("stop")

Ou alors

type order
    float price
    float amount
    string symbol

var array<order> arrOrder = na
arrOrder := array.new<order>()

order1 = order.new(99, 1, "BTC_USDT")
order2 = order.new(100, 2, "ETH_USDT")

array.push(arrOrder, order1)
array.push(arrOrder, order2)

runtime.log(arrOrder)
runtime.error("stop")

Objet de réplication

Dans Pine, l'objet est attribué par référence. Lorsque l'objet existant est attribué à une nouvelle variable, les deux pointent vers le même objet.

//@version=5
indicator("")
type pivotPoint
    int x
    float y
pivot1 = pivotPoint.new()
pivot1.x := 1000
pivot2 = pivot1
pivot2.x := 2000
// Both plot the value 2000.
plot(pivot1.x)
plot(pivot2.x)

Dans l'exemple ci-dessous, nous créons un objet pivot1 et nous fixons son champ x à 1000. Ensuite, nous déclarons qu'un pivot2 contient une variable qui fait référence à cet objet pivot1, de sorte qu'ils pointent tous les deux vers le même exemple. Ainsi, changer pivot2.x change également pivot1.x, car ils font tous les deux référence au champ x du même objet.

Pour créer une copie indépendante de l'objet d'origine, dans ce cas, nous pouvons utiliser la méthode de copie intégrée (//). Dans cet exemple, nous déclarons que pivot2 fait référence à une variable d'une instance de copie de l'objet pivot1. Maintenant, changer pivot2.x ne changera pas pivot1.x, car il fait référence à un champ d'un objet distinct x:

//@version=5
indicator("")
type pivotPoint
    int x
    float y
pivot1 = pivotPoint.new()
pivot1.x := 1000
pivot2 = pivotPoint.copy(pivot1)
pivot2.x := 2000
// Plots 1000 and 2000.
plot(pivot1.x)
plot(pivot2.x)

Il est important de noter que la méthode de copie de TradingView est basse copie. Si un objet a des champs de type particulier (array, etc.), ces champs dans la copie basse de cet objet vont pointer vers l'instance identique à cet objet. La plate-forme FMZ implique directement la copie profonde, sans traitement supplémentaire.

Copie en profondeur

//@version=5

indicator("test deepCopy")

type orderInfo
    float price
    float amount

type labelInfo
    orderInfo order
    string labelMsg

labelInfo1 = labelInfo.new(orderInfo.new(100, 0.1), "test labelInfo1")
labelInfo2 = labelInfo.copy(labelInfo1)

labelInfo1.labelMsg := "labelInfo1->2"    // 修改 labelInfo1 的基础类型字段,看是否影响 labelInfo2
labelInfo1.order.price := 999             // 修改 labelInfo1 的复合类型字段,看是否影响 labelInfo2

runtime.log(labelInfo1)
runtime.log(labelInfo2)
runtime.error("stop")

Les résultats du test, labelInfo.copy ((labelInfo1) est une copie en profondeur lors de l'exécution.

Les méthodes

Les méthodes du langage Pine sont des fonctions spécialisées associées à des types intégrés ou définis par l'utilisateur dans des instances spécifiques. Dans la plupart des cas, elles sont essentiellement les mêmes que les fonctions régulières, mais offrent une syntaxe plus courte et plus pratique. Les utilisateurs peuvent accéder directement aux méthodes sur les variables à l'aide de symboles ponctuels, comme pour accéder à des champs d'objets Pine.

Méthodes intégrées

Par exemple, un extrait de code de script comme celui-ci:

//@version=5
indicator("Custom Sample BB", overlay = true)

float sourceInput  = input.source(close, "Source")
int   samplesInput = input.int(20, "Samples")
int   n            = input.int(10, "Bars")
float multiplier   = input.float(2.0, "StdDev")

var array<float> sourceArray = array.new<float>(samplesInput)
var float        sampleMean  = na
var float        sampleDev   = na

// Identify if `n` bars have passed.
if bar_index % n == 0
    // Update the queue.
    array.push(sourceArray, sourceInput)
    array.shift(sourceArray)
    // Update the mean and standard deviaiton values.
    sampleMean := array.avg(sourceArray)
    sampleDev  := array.stdev(sourceArray) * multiplier

// Calculate bands.
float highBand = sampleMean + sampleDev
float lowBand  = sampleMean - sampleDev

plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)

L'équivalent peut être traduit par:

//@version=5
indicator("Custom Sample BB", overlay = true)

float sourceInput  = input.source(close, "Source")
int   samplesInput = input.int(20, "Samples")
int   n            = input.int(10, "Bars")
float multiplier   = input.float(2.0, "StdDev")

var array<float> sourceArray = array.new<float>(samplesInput)
var float        sampleMean  = na
var float        sampleDev   = na

// Identify if `n` bars have passed.
if bar_index % n == 0
    // Update the queue.
    sourceArray.push(sourceInput)
    sourceArray.shift()
    // Update the mean and standard deviaiton values.
    sampleMean := sourceArray.avg()
    sampleDev  := sourceArray.stdev() * multiplier

// Calculate band values.
float highBand = sampleMean + sampleDev
float lowBand  = sampleMean - sampleDev

plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)

Vous pouvez voir le support de PINE.MethodsEnsuite, le codearray.avg(sourceArray)Les utilisateurs peuvent écrire leurs méthodes sous la forme suivante:sourceArray.avg()Je ne sais pas. Attention, FMZ n'est pas supporté pour le momentarray.avgIl y a des gens qui se disent que c'est une bonne chose.

Méthodes définies par l'utilisateur

Pine permet aux utilisateurs de définir des méthodes personnalisées à utiliser avec n'importe quel type d'objet de type intégré ou défini par l'utilisateur. Les méthodes de définition sont essentiellement les mêmes que les fonctions de définition, mais avec deux différences clés:

Le mot clé méthode doit être inclus avant le nom de la fonction. Paramètres de méthode, dont le premier paramètre doit être explicitement déclaré car il indique le type d'objet auquel la méthode sera associée.

Par exemple, dans le code suivant, enveloppez le code pour calculer l'indicateur de Brin comme une méthode personnalisée par l'utilisateur:

//@version=5
indicator("Custom Sample BB", overlay = true)

float sourceInput  = input.source(close, "Source")
int   samplesInput = input.int(20, "Samples")
int   n            = input.int(10, "Bars")
float multiplier   = input.float(2.0, "StdDev")

var array<float> sourceArray = array.new<float>(samplesInput)
var float        sampleMean  = na
var float        sampleDev   = na

// Identify if `n` bars have passed.
if bar_index % n == 0
    // Update the queue.
    sourceArray.push(sourceInput)
    sourceArray.shift()
    // Update the mean and standard deviaiton values.
    sampleMean := sourceArray.avg()
    sampleDev  := sourceArray.stdev() * multiplier

// Calculate band values.
float highBand = sampleMean + sampleDev
float lowBand  = sampleMean - sampleDev

plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)

Modifié comme suit:

//@version=5
indicator("Custom Sample BB", overlay = true)

float sourceInput  = input.source(close, "Source")
int   samplesInput = input.int(20, "Samples")
int   n            = input.int(10, "Bars")
float multiplier   = input.float(2.0, "StdDev")

var array<float> sour

Plus de

- Je suis désolé.Comment faire fonctionner plusieurs transactions en même temps?

Des nuages légersPourriez-vous m'expliquer si pine peut effectuer plusieurs transactions, comme JS?

Je vous en prie.Merci pour les détails.

l'artisteBonjour! Comment ce script pine utilise-t-il le disque de simulation d'okex sur la plateforme?

l'artisteC'est comme si les stratégies de tradingview étaient directement copiées sur la plateforme de l'inventeur pour être utilisées!

L'inventeur de la quantification - un petit rêveLe langage PINE n'utilise que des stratégies mono-variées, les stratégies multivariées sont préférables ou sont conçues en python, javascript, c++.

L'inventeur de la quantification - un petit rêveOh, oui, OKX est un peu spécial, leur environnement d'analogie et leur environnement de disque réel ont la même adresse, mais ils font une différence ailleurs.

Des nuages légersJe ne peux pas utiliser l'analogue okx.

L'inventeur de la quantification - un petit rêveCe problème d'architecture multiforme n'est pas résolu, car chaque échange dispose d'une interface différente et de limites de fréquence différentes, ce qui pose de nombreux problèmes.

L'inventeur de la quantification - un petit rêveBien, merci à Cloud pour les suggestions, et partagez-les ici.

Des nuages légersIl est préférable d'utiliser le JS pour une meilleure adaptation aux différents modes de transactions.

Les chasseurs de tendanceLe prix d'achat est le même pour chaque variété.

L'inventeur de la quantification - un petit rêveJe suis désolée.

Des nuages légersBien, merci beaucoup.

L'inventeur de la quantification - un petit rêveBonjour, la stratégie linguistique PINE ne fonctionne que pour une seule variété pour l'instant.

L'inventeur de la quantification - un petit rêveMerci pour votre soutien. La documentation continuera d'être améliorée.

L'inventeur de la quantification - un petit rêveJe ne sais pas si c'est vrai.

L'inventeur de la quantification - un petit rêveLa bibliothèque de modèles PINE, dont les paramètres permettent de définir l'adresse de base de l'échange de commutation.