.3, limite=3)
se não barstate.ishistory e close < open
estratégia. cancelar ((
---------------------------
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
A funcionalidade e as definições dos parâmetros dostrategy.order
A sua função é quase idêntica à dosstrategy.entry
A diferença é que ostrategy.order
A função não é afectada pelopyramiding
configurações de parâmetros dostrategy
função, e não há limite de contagem de ordens.
Parâmetros:
id
O ID pode ser referenciado para cancelar, modificar ordens e fechar posições.direction
: Se a direcção da ordem for longa (comprar), passar na variável incorporadastrategy.long
, e se você quiser ficar curto (vender), passe na variávelstrategy.short
.qty
: Especificar o montante das ordens a realizar, se este parâmetro não for transmitido, será utilizado o montante por defeito das ordens.when
: Condição de execução, pode especificar este parâmetro para controlar se esta operação de ordem actual é desencadeada ou não.limit
: Especificar o preço limite da ordem.stop
Preço stop loss.Usaremos o recurso questrategy.order
não tem limite no número de encomendas feitas, combinado com ostrategy.exit
Função de saída condicional para construir um script semelhante à negociação em grade.
/*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)
Os exemplos de estratégia neste tutorial são apenas para fins de instrução, para orientar ideias de design de estratégia, e não para qualquer orientação ou conselho de negociação.
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()
É muito fácil escrever uma estratégia de tendência usando a linguagem Pine, e aqui vamos projetar uma estratégia simples de tendência com um indicador de tendência super.
Primeiro, o código de estratégia começa com algumas configurações simples usando ostrategy
Função:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". The
sobreposiçãoparameter is set to
verdade, 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
função input ` ` que aprendemos no curso anterior
[supertendência, direção] = ta.supertendência ((input ((5,
factor input.int(10,), atrPeriodo ))
Oinput
chamada de função é usado como um parâmetro diretamente para ota.supertrend
Função de indicador para calcular o indicador de supertendência.
Por padrão, a função define dois controles de parâmetros na tela de estratégia da linguagem Pine, conforme mostrado abaixo:
Como podemos ver, o valor padrão no controle é o primeiro parâmetro doinput
Função einput
série de funções (a seguirinput.int
Com estas duas funções, podemos então definir os parâmetros dota.supertrend
A função desupertrend
Função calcula dados de preçosupertrend
e dados de direcçãodirection
Então usamos oplot
Função para desenhar um gráfico, note que ao desenhar o gráfico, baseia-se na direção do indicador de supertendência, apenas a direção atual é desenhada.direction
é -1, a tendência actual do mercado é ascendente, quandodirection
Assim, podemos ver que a tendência de mercado atual é para baixo.plot
Função desenha o gráfico quando o julgamentodirection
é maior ou menor que 0.
O próximo.if... else if
A lógica é o julgamento do sinal de negociação.direction < 0
O mercado actual está numa fase ascendente.supertrend
no indicador de super tendência é superior ao preço do indicador de super tendência nos dois BAR anteriores (ou seja,supertrend[2], remember that the historical operator refers to the historical data of a variable
Se houver uma posição atual, chamar a função de ordem reversa fechará a posição anterior primeiro e depois abrirá a posição de acordo com a direção atual da negociação.supertrend > supertrend[2]
Não foram respeitadas, desde que ostrategy.position_size < 0
mantendo posições curtas, irá desencadearstrategy.close_all()
Execução da função para fechar todas as posições.
direction > 0
Se houver posições longas, todas as posições serão fechadas e, em seguida, quando a condiçãosupertrend < supertrend[3]
O que é que o sistema está a fazer?[3]
O risco de curto prazo em alguns mercados, como o mercado de negociação de contratos, é ligeiramente maior do que o risco de longo prazo.
Parata.supertrend
Indicador, alguém está interessado em como julgar se a tendência atual é para cima ou para baixo?
Na verdade, este indicador também pode ser implementado na forma de funções personalizadas na linguagem 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]
Esta função personalizada é exatamente o mesmo algoritmo que a função embutidata.supertrend
, e é claro que os dados do indicador calculado também são exactamente os mesmos.
Como podemos ver a partir deste algoritmo de função personalizada, Pinehl2
A variabilidade embutida (os preços mais altos e mais baixos são somados e depois divididos por 2, ou seja, a média dos preços mais altos e mais baixos), e depois o indicador ATR (volatilidade) é calculado para um determinado período com base no parâmetro atrPeriod.
AtualizaçãolowerBand
eupperBand
De acordo com as expressões ternárias do código.
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: lowerBand, utilizado para determinar se a tendência ascendente mudou. upperBand: upperBand, utilizado para determinar se a tendência descendente mudou. lowerBand e upperBand são sempre calculados, apenas a direção atual da tendência é determinada no final desta função personalizada.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Aqui é julgado que se o valor do preço do último BAR na super tendência éprevUpperBand
, ou seja, a banda superior, significa que a corrente é uma tendência descendente.close
excede oupperBand
A variável de direcção é a variável de direcção que, quando a tendência se transforma em uma tendência ascendente, é considerada como uma variável de direcção.direction
É por isso que você vê na estratégia de super tendênciaif direction < 0
quando a condição do sinal é desencadeada para ir longo.direction > 0
, a condição do sinal é desencadeada para ir curto.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Por último, são devolvidos dados específicos de preços e de direção do Indicador de Super Tendência com base na seleção de direção.
/*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)
Vamos continuar com alguns exemplos de design de estratégia em linguagem Pine, desta vez vamos aprender uma estratégia de equilíbrio dinâmico.BaseCurrency
e o montante deQuoteCurrency
. Qualquer que seja o preço relativo do ativo, o valor mantido na conta aumenta e o ativo é vendido. Se o preço relativo de um ativo diminui, o valor mantido na conta diminui e o ativo é comprado. Isso é conhecido como uma estratégia de equilíbrio dinâmico. Na verdade, a estratégia de equilíbrio dinâmico é um tipo de estratégia de grade que funciona bem em mercados oscilantes. Mas no mercado de tendência, continuará perdendo dinheiro, precisamos esperar que o preço retorne para reduzir as perdas lentamente para o lucro, mas a vantagem é que a estratégia de equilíbrio dinâmico sempre pode capturar a tendência oscilante do mercado.
A desvantagem, como mostrado no gráfico de backtest desta estratégia, é que a estratégia tem uma grande perda flutuante durante a fase da tendência geral de preços para cima (ou para baixo).
Vejamos o desenho do código de estratégia:
Utilizamos um projecto simplificado que simula umbalance
(ou seja, o número de activos em moeda de cotação) estocks
O número de ativos base (ou seja, o número de ativos BaseCurrency) informações de saldo na estratégia. Nós não ler o número real de ativos na conta, nós simplesmente usamos o valor simulado para calcular as compras e vendas apropriadas.maxDiffValue
, que constitui o critério de apreciação para a realização do equilíbrio.BaseCurrency
eQuoteCurrency
excedemaxDiffValue
O processo de equilíbrio ocorre, vendendo o ativo a um preço elevado e comprando o ativo a um preço baixo para reequilibrar o ativo.
O gatilho do sinal de negociação de estratégia deve estar na fase BAR em tempo real, por isso, se os julgamentos nas condições de negociação de estratégia são definidos comnot barstate.ishistory
. Compre quando obalance
valor excede ostocks
A operação de venda é executada após a execução da declaração de transacção, a operação de venda é executada após a execução da declaração de transacção, a operação de venda é executada após a execução da declaração de transacção.balance
estocks
As variáveis são atualizadas e, em seguida, aguardar o próximo balanço acionador.
A informação acima da estratégia backtest contém o preço da espécie no momento do início da estratégia backtest, o preço é 1458, então eu defino o parâmetrobalance
para: 4374 (1458*3) deliberadamente, definir o parâmetrostocks
Para: 3. Deixar o activo começar em equilíbrio.
No curso anterior, aprendemos sobre astrategy.exit
A função de saída de posição, da qual não tínhamos um exemplo para explicar a função de rastreamento stop e take profit.strategy.exit
A função de optimizar uma estratégia de super tendência.
Em primeiro lugar, vamos analisar os parâmetros de rastreamento de stop-loss e take-profit dostrategy.exit
Função:
trail_price
: A posição que desencadeia a ação lógica de colocação de uma ordem de stop-loss de acompanhamento e de encerramento de uma ordem de stop-loss (na posição especificada pelo preço).trail_offset
A distância entre o preço mais alto (no caso de transações longas) e o preço mais baixo (no caso de transações short) de uma posição fechada colocada após a execução de uma ação de stop-loss e take-profit de rastreamento.trail_points
Como otrail_price
Parâmetro, exceto que toma pontos de lucro como a posição especificada.Não é fácil de entender? Não importa! Vamos passar por um cenário de backtesting estratégico para entender, que é realmente bastante simples.
/*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")
Imediata entrada longa quando a estratégia começa a executar, e, em seguida, imediatamente colocado umstrategy.exit
ordem de saída (especificou os parâmetros de stop-loss e take-profit de rastreamento), quando o preço da mudança de mercado subiu acima da linha de gatilho trail_price, a implementação da lógica de stop-loss e take-profit de rastreamento, linha de stop-loss e take-profit (azul) começou a seguir o maior ajuste dinâmico de preço, a posição da linha azul é o gatilho de stop-loss e take-profit para fechar a posição e, finalmente, quando o preço de mercado cai abaixo da linha azul que desencadeia o fechamento da posição. Combinado com a linha desenhada no gráfico, é muito fácil de entender.
Então usamos este recurso para otimizar uma estratégia de super tendências, nós simplesmente atribuir umstrategy.exit
A ordem de saída do plano para a ordem de entrada da estratégia para adicionar este recurso de stop-loss e 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
Código completo da estratégia:
/*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)