Expressions et fonctions

Les expressions ne contiennent que deux types de données : des réels en double précision et des chaînes de caractères. Même si un bloc expose une valeur entière (par exemple la longueur d’un RSI), cette valeur est traitée comme une variable réelle lorsqu’elle est utilisée dans une expression. Les résultats des comparaisons et des opérations logiques sont également des réels qui valent 0 ou 1. Les valeurs manquantes sont représentées par NaN. Lorsqu’une expression est utilisée comme garde booléenne dans [[condition]] ou [[if]], 0.0 et NaN sont traités comme faux. Toute autre valeur non nulle est traitée comme vraie.

Où faut-il saisir des expressions ?

Dans une stratégie TOML, les expressions peuvent être saisies à plusieurs endroits. Règle générale : un champ d’expression accepte un nombre non quoté (TOML integer ou floating-point) ou une chaîne (TOML string). Exception : dans [[objective]], la clé formula doit être écrite comme chaîne TOML.

Dans les calculs de séries personnalisées

Les séries personnalisées utilisent une formule pour calculer une nouvelle série à partir des séries de prix, des sorties d’indicateurs déjà disponibles et des variables qu’ils exposent. Ces variables incluent par exemple fast.length, fast.type, fast.symbol et fast.timeframe. La formule est compilée au chargement, puis évaluée pendant le calcul de la série. Dans [[custom_series]], seules les variables disponibles au niveau indicateur peuvent être utilisées. Les variables runtime du backtest, du portefeuille, des ordres et des trades n’y sont pas disponibles.

[[custom_series]]
id      = "mad"
formula = "fast / slow"

Dans le filtrage des combinaisons

Le filtrage des combinaisons utilise une expression de condition pour éliminer les combinaisons d’hyperparamètres qui ne respectent pas vos critères. Cette expression est évaluée pour chaque combinaison avant le lancement du backtest correspondant.

[constraints]
condition = "fast.length < slow.length and fast.type = slow.type"

Dans la définition de l’objectif

L’objectif utilise une formule pour transformer les métriques du résultat en un score. La formule est compilée avant les exécutions, puis évaluée après chaque backtest. Dans ce bloc, formula est toujours lue comme une chaîne TOML.

[[objective]]
id        = "risk_adjusted_return"
formula   = "(grossprofit_percent - grossloss_percent) / max_drawdown_percent"
ascending = false

Dans les blocs conditionnels

Les blocs conditionnels utilisent des expressions pour décider du chemin d’exécution. Selon le type de bloc, l’expression est évaluée soit quand le bloc est exécuté, soit à chaque mise à jour de bougie pour conserver un état inter-bougies.

[[condition]]
id            = "entry_filter"
condition     = "fast > slow and fast[1] <= slow[1]"
next_block_id = "enter_long"

Dans les calculs de variables

Le bloc [[variable]] utilise deux expressions : une initialisation et une formule d’actualisation. initialization est évaluée une fois au démarrage du backtest, puis formula est évaluée à chaque passage dans le bloc.

[[variable]]
id             = "variable_trend_streak"
variable       = "trend_streak"
initialization = 0
formula        = "close > ema_200 ? trend_streak + 1 : 0"
next_block_id  = "check_entry"

Dans les blocs d’action liés aux ordres

Les blocs d’ordres peuvent utiliser des expressions pour la quantité et pour les prix. Ces valeurs sont évaluées au moment où le bloc d’ordre s’active, juste avant la soumission ou la mise à jour des ordres.

[[entry]]
id            = "enter_long"
order_id      = "main"
qty_percent   = 50
limit         = "close * 0.995"
stop          = "close * 1.005"
next_block_id = "watch_exit"

Précision et arrondis

Toutes les expressions sont évaluées en réels double précision. Les contraintes opérationnelles du marché (pas de prix, pas de quantité, taille minimale) ne s’appliquent pas pendant le calcul d’expression ; elles sont appliquées lors de l’exécution des ordres.

Constantes

Les constantes mathématiques suivantes sont disponibles. Leurs noms sont réservés et ne peuvent pas être utilisés comme identifiants de variables.

ConstanteDescription
eulerBase des logarithmes naturels
piConstante pi
phiNombre d’or
rphiInverse du nombre d’or

Séries et champs

Les expressions peuvent utiliser les séries de prix standards open, high, low, close, volume, hl2, hlc3, ohlc4 et hlcc4. Les blocs indicateurs exposent leurs séries sous forme de variables, dont le nom correspond à l’identifiant du bloc (ou à des identifiants distincts si le bloc produit plusieurs sorties).

Pour accéder à l’historique d’une série, ajoutez un indice entre crochets : serie[n] fait référence à la valeur à n barres dans le passé (0 désigne la bougie courante, 1 la bougie précédente, etc.). L’accès direct, par exemple close, est équivalent à close[0]. Si l’indice dépasse l’historique disponible, la valeur renvoyée est NaN. Dans [[condition]] et [[if]], une telle valeur ne valide donc pas la condition tant que l’historique requis n’est pas disponible.

Exemple : détecter un croisement haussier d’une moyenne mobile rapide au-dessus d’une lente (la rapide passe de dessous à dessus entre la bougie précédente et la bougie courante) :

[[condition]]
condition = "ema_fast > ema_slow and ema_fast[1] <= ema_slow[1]"

Chaînes de caractères

Certaines variables exposent des chaînes, par exemple ticker et tickerid ou des métadonnées de blocs. Les chaînes peuvent être comparées avec == ou != et concaténées avec +.

Les littéraux de chaîne sont écrits entre apostrophes.

[[condition]]
condition = "tickerid == 'BINANCE:BTCUSDT'"

Vous pouvez extraire une sous-chaîne avec s[debut:fin]. La forme s[] renvoie la longueur.

Opérateurs

Les expressions supportent les opérateurs suivants. Les exemples utilisent des réels et renvoient des réels (les comparaisons et la logique renvoient 0 ou 1).

Arithmétiques

SymboleNom
+Addition
-Soustraction
*Multiplication
/Division
%Modulo
^Puissance

Comparaisons (retour 0.0 ou 1.0)

SymboleNom
<Inférieur
<=Inférieur ou égal
>Supérieur
>=Supérieur ou égal
==Egal
!=Différent

Les opérateurs = et <> sont acceptés comme alias de == et !=.

Logiques (retour 0.0 ou 1.0)

Les opérateurs logiques traitent toute valeur non nulle comme vrai et zéro comme faux. Ils renvoient 1.0 pour vrai et 0.0 pour faux.

SymboleNom
andET
orOU
notNON
nandNAND
norNOR
xorXOR
xnorXNOR

Exemple d’utilisation :

Supposons que nous voulions une condition d’entrée qui n’est vraie que si le RSI est en dessous de 30 et que le prix de clôture est au-dessus de la moyenne mobile ema_200.

[[condition]]
id        = "entry_condition"
condition = "rsi_value < 30 and close > ema_200"

L’expression condition sera évaluée à 1.0 (vrai) uniquement si les deux comparaisons sont vraies. Si l’une ou l’autre est fausse, le résultat sera 0.0 (faux).

Ternaires

SymboleNom
cond ? a : bTernaire

Unaires

SymboleNom
+xPlus unaire
-xMoins unaire
not xNégation logique

Mise à jour dans les blocs variable

Dans un bloc variable, la variable est déclarée par la clé variable. Ensuite, vous fournissez initialization et formula comme expressions simples, puis le moteur applique lui-même la mise à jour de la variable.

Pour conserver un export PineScript sans ambiguïté, initialization et formula ne doivent pas contenir de séparateur d’instructions ; ni d’opérateur d’affectation (:=, +=, -=, *=, /=, %=).

Fonctions disponibles

Gestion des valeurs manquantes

NomDescription
na(x)1 si x est manquant, sinon 0
nz(x)0 si x est manquant, sinon x
bool(x)1 si x est défini et non nul, sinon 0

Math de base

NomDescription
abs(x)Valeur absolue
ceil(x)Arrondi supérieur
floor(x)Arrondi inférieur
exp(x)Exponentielle
log(x)Logarithme népérien
log10(x)Logarithme base 10
pow(a,b)Puissance
round(x)Arrondi au plus proche
sqrt(x)Racine carrée
sign(x)Signe de x (-1, 0, 1)
min(...)Minimum (au moins 2 valeurs)
max(...)Maximum (au moins 2 valeurs)
avg(...)Moyenne (au moins 2 valeurs)
clamp(min, x, max)Force x dans l’intervalle [min, max]
inrange(min, x, max)1 si x est dans l’intervalle, sinon 0
random(...)Nombre aléatoire uniforme dans un intervalle

Formes acceptées : random(), random(min), random(min, max) et random(min, max, seed). Sans seed, le générateur est initialisé à l’exécution, donc deux backtests distincts peuvent produire des valeurs différentes.

Trigonométrie et angles

NomDescription
sin(x)Sinus
cos(x)Cosinus
tan(x)Tangente
asin(x)Arc-sinus
acos(x)Arc-cosinus
atan(x)Arc-tangente
atan2(y,x)Arc-tangente avec quadrants
sinh(x)Sinus hyperbolique
cosh(x)Cosinus hyperbolique
tanh(x)Tangente hyperbolique
asinh(x)Arc-sinus hyperbolique
acosh(x)Arc-cosinus hyperbolique
atanh(x)Arc-tangente hyperbolique
todegrees(x)Conversion radians vers degrés
toradians(x)Conversion degrés vers radians