.3, limite = 3)
Si ce n'est pas le cas, barstate.ishistory et close < open
stratégie.annuler ((
---------------------------
6. ```strategy.cancel_all```
The ```strategy.cancel_all``` function is similar to the ```strategy.cancel``` function. It can cancel/stop all pre-listed commands. The ```when``` parameter can be specified.
Parameters:
- ```when```: Execution conditions.
```pine
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0.3, limit=3)
if not barstate.ishistory and close < open
strategy.cancel_all()
isStop := true
strategy.order
La fonctionnalité et les paramètresstrategy.order
Les fonctions sont presque identiques àstrategy.entry
La différence est que lestrategy.order
La fonction n'est pas affectée par lepyramiding
paramètres de lastrategy
fonction, et il n'y a pas de limite de nombre d'ordres.
Paramètres:
id
L'id peut être utilisé pour annuler, modifier des ordres et fermer des positions.direction
: Si la direction de l'ordre est longue (acheter), passer dans la variable intégréestrategy.long
, et si vous voulez vendre, passez la variablestrategy.short
.qty
: spécifier le montant des ordres à passer, si ce paramètre n'est pas passé, le montant par défaut des ordres sera utilisé.when
: Condition d'exécution, vous pouvez spécifier ce paramètre pour contrôler si cette opération d'ordre en cours est déclenchée ou non.limit
: Indiquer le prix limite de commande.stop
Le prix stop-loss.Nous utiliserons la fonctionnalité quistrategy.order
n'a pas de limite sur le nombre de commandes passées, combiné avec lestrategy.exit
la fonction de sortie conditionnelle pour construire un script similaire au trading en grille.
/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/
varip beginPrice = -1
if not barstate.ishistory
if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0)
beginPrice := close
for i = 0 to 20
strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)
Les exemples de stratégie dans ce tutoriel sont uniquement à des fins pédagogiques, pour guider les idées de conception de stratégie, et non pour des conseils ou des conseils commerciaux.
strategy("supertrend", overlay=true)
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)
if direction < 0
if supertrend > supertrend[2]
strategy.entry("entry long", strategy.long)
else if strategy.position_size < 0
strategy.close_all()
else if direction > 0
if supertrend < supertrend[3]
strategy.entry("entry short", strategy.short)
else if strategy.position_size > 0
strategy.close_all()
Il est très facile d'écrire une stratégie de tendance en utilisant le langage Pine, et ici nous allons concevoir une stratégie de suivi de tendance simple avec un indicateur de super tendance.
Tout d'abord, le code de stratégie commence par quelques réglages simples en utilisant lestrategy
fonction:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". The
couvertureparameter is set to
vrai, so that the drawn indicator lines and other content are displayed on the main chart. The first thing we need to look at when designing a Pine strategy or learning a Pine strategy script is the strategy interface parameter design. Let's look at the source code of the ''supertrend indicator strategy'', which has the
fonction d'entrée que nous avons apprise dans le cours précédent
[supertrend, direction] = ta.supertrend ((input ((5,
facteur input.int(Période de référence)),
Leinput
l'appel de fonction est utilisé comme paramètre directement sur leta.supertrend
fonction d'indicateur pour le calcul de l'indicateur de supertendance.
Par défaut, la fonction définit deux contrôles de paramètres sur l'écran de stratégie de la langue Pine, comme indiqué ci-dessous:
Comme nous pouvons le voir, la valeur par défaut sur la commande est le premier paramètre de lainput
fonction et leinput
série de fonctions (iciinput.int
Ces deux fonctions permettent ensuite de définir les paramètres de l'interfaceta.supertrend
La fonction de l'écran de stratégie.supertrend
fonction calcule une donnée de prixsupertrend
et les données de directiondirection
On utilise alors leplot
Lorsque l'indicateur de tendance est basé sur la direction de l'indicateur de tendance, seule la direction actuelle est dessinée.direction
est -1, la tendance actuelle du marché est à la hausse, lorsquedirection
est 1, la tendance actuelle du marché est à la baisse.plot
fonction dessine le graphique lorsque le jugementdirection
est supérieur ou inférieur à 0.
Le prochain.if... else if
La logique est le jugement du signal de trading.direction < 0
Si les données relatives aux prix sont vraies, cela signifie que le marché actuel est en phase ascendante.supertrend
dans l'indicateur de super tendance est supérieur au prix de l'indicateur de super tendance sur les deux BAR précédentes (c'est-à-diresupertrend[2], remember that the historical operator refers to the historical data of a variable
Si vous avez une position en cours, l'appel de la fonction d'ordre inverse fermera d'abord la position précédente, puis ouvrira la position en fonction de la direction actuelle du trading.supertrend > supertrend[2]
Les conditions de concurrence ne sont pas remplies tant que les conditions de concurrencestrategy.position_size < 0
En tenant des positions courtes, il déclencherastrategy.close_all()
l'exécution de la fonction de clôture de toutes les positions.
direction > 0
Si les positions sont longues, toutes les positions seront fermées, et lorsque la condition est à la baisse, toutes les positions seront fermées.supertrend < supertrend[3]
Le signal de détection de l'émission est atteint, un court signal sera déclenché.[3]
Il est possible que l'auteur de la stratégie ait l'intention de le faire. Après tout, le risque court sur certains marchés, comme le marché du contract trading, est légèrement supérieur au risque long.
Pourta.supertrend
Indicateur, est-ce que quelqu'un s'intéresse à la façon de juger si la tendance actuelle est à la hausse ou à la baisse?
En fait, cet indicateur peut également être mis en œuvre sous forme de fonctions personnalisées dans le langage Pine:
pine_supertrend(factor, atrPeriod) =>
src = hl2
atr = ta.atr(atrPeriod)
upperBand = src + factor * atr
lowerBand = src - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
direction := 1
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Cette fonction personnalisée est exactement le même algorithme que la fonction intégréeta.supertrend
, et bien sûr les données d'indicateur calculées sont également exactement les mêmes.
Comme nous pouvons le voir à partir de cet algorithme de fonction personnalisée, l'indicateur de super tendance intégré de Pinehl2
La valeur de l'indicateur ATR (volatilité) est calculée pour une certaine période sur la base du paramètre atrPeriod.
Mise à jourlowerBand
etupperBand
selon les expressions ternaires du code.
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: lowerBand, utilisé pour déterminer si la tendance à la hausse a changé. upperBand: upperBand, utilisé pour déterminer si la tendance à la baisse a changé. lowerBand et upperBand sont toujours calculés, seule la direction de la tendance actuelle est déterminée à la fin de cette fonction personnalisée.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Ici, il est jugé que si la valeur du prix du dernier BAR sur la super tendance estprevUpperBand
, c'est-à-dire la bande supérieure, cela signifie que le courant est en baisse.close
dépasse leupperBand
La variable de direction est la variable de direction de la tendance à la hausse.direction
La tendance à la hausse est définie sur -1 (tendance à la hausse). Sinon, elle est toujours définie sur 1 (tendance à la baisse).if direction < 0
lorsque la condition de signal est déclenchée pour aller long.direction > 0
, la condition de signal est déclenchée pour passer à court.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Enfin, des données spécifiques sur les prix et les données de direction de l'indicateur Super Trend sont renvoyées sur la base de la sélection de la direction.
/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/
varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")
maxDiffValue = input(1000, "maxDiffValue")
if balance - close * stocks > maxDiffValue and not barstate.ishistory
// more balance , open long
tradeAmount = (balance - close * stocks) / 2 / close
strategy.order("long", strategy.long, tradeAmount)
balance := balance - tradeAmount * close
stocks := stocks + tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
else if close * stocks - balance > maxDiffValue and not barstate.ishistory
// more stocks , open short
tradeAmount = (close * stocks - balance) / 2 / close
strategy.order("short", strategy.short, tradeAmount)
balance := balance + tradeAmount * close
stocks := stocks - tradeAmount
runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)
plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)
Continuons avec quelques exemples de conception de stratégie en langage Pine, cette fois nous allons apprendre une stratégie d'équilibrage dynamique.BaseCurrency
et le montant deQuoteCurrency
. Quelle que soit la hausse du prix relatif de l'actif, la valeur détenue dans le compte augmente et l'actif est vendu. Si le prix relatif d'un actif diminue, la valeur détenue dans le compte diminue et l'actif est acheté. Ceci est connu sous le nom de stratégie d'équilibrage dynamique. En fait, la stratégie d'équilibrage dynamique est une sorte de stratégie de grille qui fonctionne bien sur les marchés oscillants. Mais sur le marché tendance, il continuera à perdre de l'argent, nous devons attendre que le prix revienne pour réduire les pertes lentement au profit, mais l'avantage est que la stratégie d'équilibrage dynamique peut toujours capturer la tendance oscillant du marché.
L'inconvénient, comme le montre le graphique de backtest de cette stratégie, est que la stratégie a une grande perte flottante pendant la phase de la tendance générale des prix à la hausse (ou à la baisse).
Examinons la conception du code de stratégie:
Nous utilisons une conception simplifiée qui simule unbalance
(c'est-à-dire le nombre d'actifs en devises cotées) etstocks
Nous ne lisons pas le nombre réel d'actifs dans le compte, nous utilisons simplement le montant simulé pour calculer les achats et les ventes appropriés.maxDiffValue
, qui est le critère de jugement pour effectuer l'équilibrage.BaseCurrency
etQuoteCurrency
dépassemaxDiffValue
le processus d'équilibrage a-t-il lieu, en vendant l'actif à un prix élevé et en achetant l'actif à un prix bas pour rééquilibrer l'actif?
Le déclencheur du signal de négociation de stratégie doit être dans la phase BAR en temps réel, donc si les jugements dans les conditions de négociation de stratégie sont définis avecnot barstate.ishistory
. Acheter quand lebalance
la valeur dépasse lestocks
L'opération de vente est effectuée sur la base de la valeur calculée en fonction du prix en cours.balance
etstocks
Les variables sont mises à jour et attendent ensuite le prochain déclenchement de l'équilibre.
L'information ci-dessus de la stratégie backtest contient le prix de l'espèce au moment du début de la stratégie backtest, le prix est 1458, donc je définis le paramètrebalance
à: 4374 (1458*3) délibérément, définir le paramètrestocks
Laissez l'actif commencer en équilibre.
Dans le cours précédent, nous avons étudié lesstrategy.exit
Dans cet exemple de conception de stratégie, nous utiliserons la fonction d'arrêt de suivi et de prise de profit.strategy.exit
La fonction de l'optimisation d'une stratégie de super tendance.
Tout d'abord, examinons les paramètres de suivi du stop-loss et du take-profit dustrategy.exit
fonction:
trail_price
: La position qui déclenche l' action logique consistant à placer un ordre stop-loss de suivi et un ordre de clôture de stop-loss (à la position spécifiée par le prix).trail_offset
: La distance entre le prix le plus élevé (en long) ou le prix le plus bas (en court) d'une position fermée placée après l'exécution d'une action de suivi stop-loss et take-profit.trail_points
Comme letrail_price
Paramètre, sauf qu'il prend des points de profit comme position spécifiée.Ce n'est pas facile à comprendre? Cela n'a pas d'importance! Passons par un scénario de backtesting stratégique pour comprendre, qui est en fait assez simple.
/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("test", overlay = true)
varip a = na
varip highPrice = na
varip isTrade = false
varip offset = 30
if not barstate.ishistory and not isTrade
strategy.entry("test 1", strategy.long, 1)
strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
a := close + offset
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close)
isTrade := true
if close > a and not barstate.ishistory
highPrice := na(highPrice) ? close : highPrice
highPrice := close > highPrice ? close : highPrice
plot(a, "trail_price trigger line")
plot(strategy.position_size>0 ? highPrice : na, "current highest price")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "moving stop trigger line")
Entrée longue immédiate lorsque la stratégie commence à exécuter, puis immédiatement placé unstrategy.exit
l'ordre de sortie (il spécifiait les paramètres de suivi stop-loss et take-profit), lorsque le prix du changement de marché s'élevait au-dessus de la ligne de déclenchement de trail_price, la mise en œuvre de la logique de stop-loss et take-profit de trailing, la ligne de stop-loss et take-profit (bleu) a commencé à suivre l'ajustement dynamique de prix le plus élevé, la position de ligne bleue est le déclencheur de stop-loss et take-profit pour fermer la position, et enfin lorsque le prix du marché tombe en dessous de la ligne bleue qui déclenche la fermeture de la position. Combiné avec la ligne dessinée sur le graphique, il est très facile à comprendre.
Ensuite, nous utilisons cette fonctionnalité pour optimiser une stratégie de super tendance, nous assignons simplement unstrategy.exit
l'ordre de plan de sortie à l'ordre d'entrée de stratégie pour ajouter cette fonctionnalité de stop-loss et de take-profit.
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
Code de stratégie complet:
/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
if strategy.position_size == 0
trail_price := na
state := 0
[superTrendPrice, dir] = ta.supertrend(input(2, "atr coefficient"), input(20, "atr period"))
if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.long, 1)
state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.short, 1)
state := 1
// Reverse signal, close all positions
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
strategy.cancel_all()
strategy.close_all()
runtime.log("trend reversal, long positions all closed")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
strategy.cancel_all()
strategy.close_all()
runtime.log("trend reversal, short positions all closed")
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("the price per point is:", syminfo.mintick, ", current close:", close, ", trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)