.3, límite=3)
si no es barstate.ishistory y cierre < abierto
Estrategia.cancel ((
---------------------------
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 funcionalidad y la configuración de parámetros destrategy.order
Las funciones de losstrategy.entry
La diferencia es que elstrategy.order
la función no se ve afectada por elpyramiding
configuración de los parámetros delstrategy
Función, y no hay límite de número de órdenes.
Parámetros:
id
Se puede entender como dar un nombre a una posición de negociación para la referencia.direction
: Si la dirección de la orden es larga (comprar), pasar en la variable incorporadastrategy.long
, y si desea ir corto (vender), pasar en la variablestrategy.short
.qty
: Especificar el importe de las órdenes a realizar, si no se pasa este parámetro, se utilizará el importe predeterminado de las órdenes.when
: Condición de ejecución, puede especificar este parámetro para controlar si se activa o no esta operación de orden actual.limit
: Especificar el precio límite de la orden.stop
Precio de suspensión de pérdida.Usaremos la característica questrategy.order
no tiene límite en el número de pedidos realizados, combinado con elstrategy.exit
la función de salida condicional para construir un guión similar al comercio en red.
/*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)
Los ejemplos de estrategias en este tutorial son solo para fines de instrucción, para guiar las ideas de diseño de estrategias, y no para cualquier guía o consejo comercial.
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()
Es muy fácil escribir una estrategia de tendencia usando el lenguaje Pine, y aquí vamos a diseñar una estrategia de tendencia simple con un indicador de tendencia súper.
En primer lugar, el código de estrategia comienza con algunas configuraciones simples mediante el uso de lastrategy
Función:strategy("supertrend", overlay=true)``, which just sets a strategy title "supertrend". The
superposiciónparameter is set to
Es cierto, 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
La función de entrada que aprendimos en el curso anterior
[supertendencia, dirección] = ta.supertendencia ((entrada ((5,
factor input.int(por ejemplo, en el caso de las empresas de servicios de telecomunicaciones, en el caso de las empresas de telecomunicaciones)),
Elinput
llamada de la función se utiliza como un parámetro directamente a lata.supertrend
función de indicador para calcular el indicador de supertendencia.
Por defecto, la función establece dos controles de parámetros en la pantalla de estrategia del lenguaje Pine, como se muestra a continuación:
Como podemos ver, el valor predeterminado en el control es el primer parámetro delinput
La función y elinput
La serie de funciones (aquí esinput.int
Con estas dos funciones, podemos entonces establecer los parámetros de lata.supertrend
La función en la pantalla de la estrategia.supertrend
Función calcula un precio de datossupertrend
y datos de direccióndirection
Entonces usamos elplot
La función para dibujar un gráfico, tenga en cuenta que al dibujar el gráfico, se basa en la dirección del indicador de supertrend, sólo se dibuja la dirección actual.direction
es -1, la tendencia actual del mercado es al alza, cuandodirection
Es 1, la tendencia actual del mercado es a la baja.plot
Función dibuja el gráfico cuando el juiciodirection
es mayor o menor que 0.
El siguienteif... else if
La lógica es el juicio de la señal de comercio.direction < 0
En este momento, si los datos de precios son correctos, el mercado actual se encuentra en una fase ascendente.supertrend
en el indicador de súper tendencia es superior al precio del indicador de súper tendencia en los dos BAR anteriores (es decir,supertrend[2], remember that the historical operator refers to the historical data of a variable
Si hay una posición actual, llamar a la función de orden inversa cerrará la posición anterior primero, y luego abrirá la posición de acuerdo con la dirección de negociación actual.supertrend > supertrend[2]
No se han cumplido, siempre y cuando elstrategy.position_size < 0
manteniendo posiciones cortas, activarástrategy.close_all()
ejecución de la función para cerrar todas las posiciones.
direction > 0
Si hay posiciones largas, todas las posiciones se cerrarán, y luego cuando la condiciónsupertrend < supertrend[3]
Cuando se cumple, se activará una señal corta.[3]
En el caso de los mercados de valores, el riesgo corto en algunos mercados, como el mercado de negociación de contratos, es ligeramente mayor que el riesgo largo.
Parata.supertrend
Indicador, ¿alguien está interesado en cómo juzgar si la tendencia actual es al alza o a la baja?
De hecho, este indicador también se puede implementar en forma de funciones personalizadas en el lenguaje 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 función personalizada es exactamente el mismo algoritmo que la función incorporadata.supertrend
, y, por supuesto, los datos de los indicadores calculados también son exactamente los mismos.
Como podemos ver en este algoritmo de función personalizada, el indicador de tendencia súper incorporado de Pinehl2
En el caso de los precios más bajos y los más altos, se calcula el valor medio de los precios más altos y los más bajos, y el indicador ATR (volatilidad) se calcula para un determinado período basándose en el parámetro atrPeriod.
ActualizaciónlowerBand
yupperBand
de acuerdo con las expresiones ternaras del 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 si la tendencia al alza ha cambiado. upperBand: upperBand, utilizado para determinar si la tendencia a la baja ha cambiado. lowerBand y upperBand siempre se calculan, solo se determina la dirección de tendencia actual al final de esta función personalizada.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Aquí se juzga que si el valor del precio de la última barra en la tendencia súper esprevUpperBand
, es decir, la banda superior, significa que la corriente es una tendencia a la baja.close
excede elupperBand
La variable de dirección es la variable de dirección de la tendencia.direction
Es por eso que se ve en la estrategia de la súper tendenciaif direction < 0
cuando la condición de la señal se activa para ir largo.direction > 0
, la condición de la señal se activa para ir corto.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Por último, se devuelven datos específicos de precios y datos de dirección del Super Trend Indicator basados en la selección de dirección.
/*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)
Continuemos con algunos ejemplos de diseño de estrategia en lenguaje Pine, esta vez aprenderemos una estrategia de equilibrio dinámico.BaseCurrency
y la cantidad deQuoteCurrency
. Cualquiera que sea el precio relativo del activo, el valor mantenido en la cuenta aumenta y el activo se vende. Si el precio relativo de un activo disminuye, el valor mantenido en la cuenta disminuye y el activo se compra. Esto se conoce como una estrategia de equilibrio dinámico. De hecho, la estrategia de equilibrio dinámico es un tipo de estrategia de red que funciona bien en los mercados oscilantes. Pero en el mercado de tendencia, continuará perdiendo dinero, necesitamos esperar a que el precio regrese para reducir las pérdidas lentamente a la ganancia, pero la ventaja es que la estrategia de equilibrio dinámico siempre puede capturar la tendencia oscilante del mercado.
La desventaja, como se muestra en el gráfico de backtest de esta estrategia, es que la estrategia tiene una gran pérdida flotante durante la etapa de la tendencia general del precio hacia arriba (o hacia abajo).
Veamos el diseño del código de estrategia:
Utilizamos un diseño simplificado que simula unbalance
(es decir, el número de activos en moneda de cotización) ystocks
En la estrategia, el número de activos de base de divisas (es decir, el número de activos de base de divisas) es la información de balance.maxDiffValue
, que es el criterio de evaluación para llevar a cabo la compensación.BaseCurrency
yQuoteCurrency
excedemaxDiffValue
¿se lleva a cabo el proceso de equilibración, vendiendo el activo a un precio alto y comprando el activo a un precio bajo para reequilibrar el activo?
El activador de la señal de negociación de estrategia debe estar en la etapa BAR en tiempo real, por lo que si los juicios en las condiciones de negociación de la estrategia se establecen connot barstate.ishistory
Comprar cuando elbalance
el valor excede elstocks
En el caso de las operaciones de venta, el valor de la transacción se calcula en función del precio actual.balance
ystocks
Las variables se actualizan y luego esperan el siguiente balance.
La información anterior de la estrategia backtest contiene el precio de la especie en el momento de inicio de la estrategia backtest, el precio es 1458, por lo que establezco el parámetrobalance
para: 4374 (1458*3) deliberadamente, establecer el parámetrostocks
Para: 3. Que el activo comience en equilibrio.
En el curso anterior, hemos aprendido acerca de lastrategy.exit
En este ejemplo de diseño de estrategia, vamos a utilizar la función de salida de posición, de la que no tenemos un ejemplo para explicar el seguimiento de la parada y tomar beneficios función.strategy.exit
La función de optimizar una estrategia de súper tendencia.
En primer lugar, veamos los parámetros de seguimiento de stop-loss y take-profit de lastrategy.exit
Función:
trail_price
: La posición que desencadena la acción lógica de colocar una orden de stop-loss de seguimiento y una orden de cierre de stop-loss (en la posición especificada por el precio).trail_offset
: Distancia entre el precio más alto (en caso de transacción larga) o el precio más bajo (en caso de transacción corta) de una posición cerrada colocada después de la ejecución de una acción de seguimiento de stop-loss y take-profit.trail_points
Como eltrail_price
Parámetro, excepto que toma puntos de ganancia como la posición especificada.¿No es eso fácil de entender? No importa! Vamos a pasar por un escenario de backtesting de estrategia para entender, que en realidad es bastante 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")
Inmediato entrada larga cuando la estrategia comienza a ejecutarse, y luego inmediatamente colocado unstrategy.exit
orden de salida (especifica los parámetros de seguimiento de stop-loss y take-profit), cuando el precio del cambio de mercado se elevó por encima de la línea de activación de trail_price, la implementación de la lógica de stop-loss y take-profit, la línea de stop-loss y take-profit (azul) comenzó a seguir el ajuste dinámico de precio más alto, la posición de la línea azul es el detente de stop-loss y take-profit para cerrar la posición, y finalmente cuando el precio de mercado cae por debajo de la línea azul que desencadena el cierre de la posición. Combinado con la línea dibujada en el gráfico, es muy fácil de entender.
Luego usamos esta característica para optimizar una estrategia de super tendencias, simplemente asignamos unstrategy.exit
la orden de salida del plan a la orden de entrada de la estrategia para añadir esta característica de stop-loss y 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 de la estrategia:
/*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)