Los ejemplos:
var lineColor = na
n = if bar_index > 10 and bar_index <= 20
lineColor := color.green
else if bar_index > 20 and bar_index <= 30
lineColor := color.blue
else if bar_index > 30 and bar_index <= 40
lineColor := color.orange
else if bar_index > 40
lineColor := color.black
else
lineColor := color.red
plot(close, title="close", color=n, linewidth=5, overlay=true)
plotchar(true, title="bar_index", char=str.tostring(bar_index), location=location.abovebar, color=color.red, overlay=true)
Nota: Expresiones para juzgar, que devuelven valores de Boole. Nota de reducción. Sólo puede haber un máximo de una rama deelse. Todas las expresiones de rama no son verdaderas y no tienen una rama deelse, que devuelven na.
x = if close > open
close
plot(x, title="x")
Dado que cuando la K-línea BAR es una línea cintil, es decir, cuando close < open, la expresión después de la frase if es falsa, no se ejecuta el bloque de código local de si. En este caso tampoco hay una ramaelse, la frase if devuelve na. x se asigna a na.
Las declaraciones de switch también son una estructura de ramificación para diseñar diferentes rutas de ejecución según ciertas condiciones. Las declaraciones de switch generalmente tienen los siguientes puntos clave de conocimiento.
1, como la expresión switch y la expresión if, puede devolver valores. 2, a diferencia de las declaraciones de switch en otros lenguajes, cuando se ejecuta la estructura de switch, solo se ejecuta un bloque local de su código, por lo que la declaración de break no es necesaria (es decir, no se necesita escribir palabras clave como break). Cada rama del switch puede escribir un bloque de código local, y la última línea de este bloque de código local es el valor de retorno (puede ser un conjunto de valores). Si no se ejecuta ninguno de los bloques de código local ramificados, se devuelve na. 4, la determinación de la posición de las expresiones en la estructura del switch, que puede escribirse como una cadena, una variable, una expresión o una llamada de función. 5. El switch permite especificar un valor de retorno que se usa como valor predeterminado cuando no se ejecuta ninguna otra situación en la estructura.
Los switches se dividen en dos formas, y vamos a ver ejemplos para entender cómo se usan.
1 con la expresiónswitch
En la página web del blog, se puede leer:
// input.string: defval, title, options, tooltip
func = input.string("EMA", title="指标名称", tooltip="选择要使用的指标函数名称", options=["EMA", "SMA", "RMA", "WMA"])
// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="周期参数")
fastPeriod = input.int(10, title="快线周期参数", options=[5, 10, 20])
slowPeriod = input.int(20, title="慢线周期参数", options=[20, 25, 30])
data = input(close, title="数据", tooltip="选择使用收盘价、开盘价、最高价...")
fastColor = color.red
slowColor = color.red
[fast, slow] = switch func
"EMA" =>
fastLine = ta.ema(data, fastPeriod)
slowLine = ta.ema(data, slowPeriod)
fastColor := color.red
slowColor := color.red
[fastLine, slowLine]
"SMA" =>
fastLine = ta.sma(data, fastPeriod)
slowLine = ta.sma(data, slowPeriod)
fastColor := color.green
slowColor := color.green
[fastLine, slowLine]
"RMA" =>
fastLine = ta.rma(data, fastPeriod)
slowLine = ta.rma(data, slowPeriod)
fastColor := color.blue
slowColor := color.blue
[fastLine, slowLine]
=>
runtime.error("error")
plot(fast, title="fast" + fastPeriod, color=fastColor, overlay=true)
plot(slow, title="slow" + slowPeriod, color=slowColor, overlay=true)
En este caso, la función de entrada es la función de entrada y la función de entrada es la función de entrada.input.string
、input.int
La función.input.string
En el caso de los usuarios de Twitter, el número de mensajes que envían es el siguiente:input.int
La función se utiliza para devolver valores enteros. En este ejemplo, se añade un nuevo valor.options
¿Cómo se usan los parámetros?options
Los parámetros se pueden pasar a una matriz de valores seleccionables; por ejemplo, en el ejemplo anterior.options=["EMA", "SMA", "RMA", "WMA"]
yoptions=[5, 10, 20]
(Nota que uno es de tipo de cadena y el otro de tipo de número). Así, los controles en la interfaz de la política no necesitan ingresar valores específicos, sino que se convierten en un cuadro desplegable para seleccionar las opciones que se ofrecen en el parámetro de opciones.
El valor de la variable func es una cadena, la variable func es la expresión del switch (puede ser una variable, una llamada de función, una expresión) para determinar qué rama del switch se ejecuta. Si la variable func no puede coincidir con la expresión en cualquiera de las ramas del switch (es decir, es igual), se ejecuta el bloque de código de rama predeterminado, que se ejecutará.runtime.error("error")
La función hace que la política deje de lanzar excepciones.
En nuestro código de prueba anterior, después de la última línea de runtime.error del bloque de código de rama por defecto de Switch, no agregamos código como [na, na] para devolver el valor de compatibilidad, en el punto de vista comercial se necesita considerar el problema, si el tipo no es coherente, se reportará un error. Pero en FMZ se puede omitir este código de compatibilidad debido a que no hay requisitos estrictos de tipo.
strategy("test", overlay=true)
x = if close > open
close
else
"open"
plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)
En FMZ no se reportan errores, en trading view se reportan errores; porque el tipo de la rama que se devuelve no es el mismo.
2 no tiene una expresiónswitch
Ahora vamos a ver.switch
La otra forma de usar la palabra es escribirla sin una expresión.
up = close > open // up = close < open
down = close < open
var upOfCount = 0
var downOfCount = 0
msgColor = switch
up =>
upOfCount += 1
color.green
down =>
downOfCount += 1
color.red
plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true)
plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)
Como se puede ver en el ejemplo de código de prueba, el switch coincide con el bloque de código local verdadero en las condiciones de ejecución de la rama. En general, las condiciones de rama después de la declaración del switch deben ser mutuamente contradictorias. Es decir, en el ejemplo, el up y el down no pueden ser simultáneamente verdaderos.up = close > open // up = close < open
Reemplazar el contenido de los comentarios, volver a evaluar los resultados observados. Se encontrará que la rama de switch sólo puede ejecutar la primera rama. Además, se debe tener cuidado de no escribir las llamadas de funciones en la rama de switch, las funciones no pueden ser llamadas en cada BAR, lo que puede causar algunos problemas de cálculo de datos.switch
En el ejemplo de "la rama de ejecución está definida y no se cambiará durante la ejecución de la estrategia").
返回值 = for 计数 = 起始计数 to 最终计数 by 步长
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
El uso de la declaración for es muy simple, ya que el ciclo for puede devolver finalmente un valor (o devolver varios valores, en forma de [a, b, c]); como en el pseudo código anterior, la variable asignada a la posición de "valor de retorno" es seguida por una variable de "cuento" para controlar el número de vueltas, citar otros valores, etc. La variable "cuento" se asigna como "cuento inicial" antes de que comience el ciclo, y luego se pasa según la configuración de "crecimiento", y el ciclo se detiene cuando el número de "cuento" es mayor que el de "variable final".
para el ciclobreak
Palabras clave: Cuando se ejecutabreak
Después de una frase, el ciclo se detiene.
para el ciclocontinue
Palabras clave: Cuando se ejecutacontinue
Después de una frase, el ciclo se desvanece.continue
El código posterior, ejecuta directamente el siguiente ciclo. La frase for devuelve el valor de la última vez que se ejecutó el ciclo. Si no se ejecuta ningún código, devuelve el valor en blanco.
A continuación mostramos un ejemplo sencillo:
ret = for i = 0 to 10 // 可以增加by关键字修改步长,暂时FMZ不支持 i = 10 to 0 这样的反向循环
// 可以增加条件设置,使用continue跳过,break跳出
runtime.log("i:", i)
i // 如果这行不写,就返回空值,因为没有可返回的变量
runtime.log("ret:", ret)
runtime.error("stop")
for ... in
Las frases tienen dos formas, las cuales se explican con el siguiente código falso:
返回值 = for 数组元素 in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Se puede ver que la principal diferencia entre las dos formas está en lo que sigue después de la palabra clave for, una es usar una variable como referencia a los elementos de la matriz. La otra es usar una estructura que contiene una variable de índice, un elemento de matriz y una matriz de variables para hacer referencia. La otra es usar reglas de valor de retorno, reglas como break, continuue y for. También mostramos el uso con un ejemplo simple.
testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray // 修改成 [i, ele]的形式:for [i, ele] in testArray , runtime.log("ele:", ele, ", i:", i)
runtime.log("ele:", ele)
runtime.error("stop")
Cuando se necesita un índice, se usa.for [i, ele] in testArray
El nombre de la ciudad es el siguiente:
para aplicaciones circulares
Cuando se pueden realizar algunos cálculos de lógica circular con funciones integradas proporcionadas por el lenguaje Pine, se pueden escribir directamente con estructuras circulares, o se puede procesar con funciones integradas. Demos dos ejemplos.
1 es la media calculada.
Cuando se utiliza el diseño de estructuras circulares:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
En el ejemplo, se utiliza el for para la suma circular, y luego se calcula la igualdad.
Calcular la línea media directamente con la función integrada:
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Utilice directamente las funciones integradasta.sma
El cálculo de los indicadores de la línea uniforme es, evidentemente, más sencillo que el cálculo de la línea uniforme mediante funciones integradas. En el gráfico, el contraste puede ver que los resultados calculados son perfectamente coincidentes.
2 y suma
También puede utilizar el ejemplo anterior para ilustrarlo.
Cuando se utiliza el diseño de estructuras circulares:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
sum = 0
for ele in a
sum += ele
avg = sum / length
plot(avg, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Para calcular todos los elementos de la matriz y que se pueden procesar con el ciclo, también se pueden usar funciones integradas.array.sum
¿Qué es lo que está sucediendo?
Calcular la suma directamente con las funciones integradas:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
plot(array.sum(a) / length, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Se puede ver que los datos calculados se muestran perfectamente coherentes en el gráfico usando el gráfico de la trama.
¿Por qué diseñar ciclos si se puede hacer todo esto con funciones integradas? 1, algunas operaciones para el conjunto de matrices, cálculo. 2, Revisando el historial, por ejemplo, para averiguar cuántos picos pasados son más altos que los picos del BAR actual. Como el pico del BAR actual solo se conoce en el BAR en el que se ejecuta el script, se necesita un ciclo para regresar a tiempo y analizar el BAR pasado. 3, en el caso de que las funciones integradas que utilizan el lenguaje Pine no puedan completar el cálculo de BAR en el pasado.
while
Las instrucciones permiten que el código de la parte circular se ejecute hasta que la condición de juicio en la estructura while sea falsa.
返回值 = while 判断条件
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Las otras reglas de while son similares a las de los ciclos for, donde la última línea del bloque de código local del ciclista es el valor de retorno, y puede devolver varios valores. Cuando la "condición del ciclo" es real, se ejecuta el ciclo, y cuando la condición es falsa, se detiene el ciclo. También se pueden usar las declaraciones break, continue en el cuerpo del ciclo.
En la actualidad, la mayoría de los usuarios de Twitter están usando el teléfono móvil como una herramienta de comunicación.
length = 10
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Se puede ver que el uso del ciclo de whilst también es muy sencillo, y también se puede diseñar algunas lógicas de cálculo que no pueden ser reemplazadas por funciones integradas, por ejemplo, el cálculo de la multiplicación:
counter = 5
fact = 1
ret = while counter > 0
fact := fact * counter
counter := counter - 1
fact
plot(ret, title="ret") // ret = 5 * 4 * 3 * 2 * 1
Similar a la definición de las matrices en el lenguaje Pine y en otros lenguajes de programación, las matrices de Pine son matrices en una dimensión. Generalmente se utilizan para almacenar una serie continua de datos. Las matrices en las que se almacenan datos individuales se llaman elementos de la matriz, y los tipos de estos elementos pueden ser: entero, tipo de punto flotante, cadena, valor de color, valor de Boole. El lenguaje Pine en FMZ no requiere un tipo muy estricto, incluso puede almacenar cadenas y valores al mismo tiempo en una matriz.[]
Es necesario usarlo.array.get()
yarray.set()
Función. La secuencia de índices de los elementos en el conjunto es 0 para el primer elemento y 1 para el siguiente elemento.
En el caso de los bloggers, el código es muy simple:
var a = array.from(0)
if bar_index == 0
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 1
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 2
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2])
else if bar_index == 3
array.push(a, bar_index)
runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2], ", 向前数3根BAR上的a,即a[3]值:", a[3])
else if bar_index == 4
// 使用array.get 按索引获取元素,使用array.set按索引修改元素
runtime.log("数组修改前:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
array.set(a, 1, 999)
runtime.log("数组修改后:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
Usoarray<int> a
、float[] b
Las matrices declaradas o las que declaran solo una variable pueden ser asignadas a matrices, por ejemplo:
array<int> a = array.new(3, bar_index)
float[] b = array.new(3, close)
c = array.from("hello", "fmz", "!")
runtime.log("a:", a)
runtime.log("b:", b)
runtime.log("c:", c)
runtime.error("stop")
Utilización general para la inicialización de variables de matrizarray.new
yarray.from
函数。Pine语言中还有很多和类型相关的与array.new类似的函数:array.new_int()
、array.new_bool()
、array.new_color()
、array.new_string()
Y luego.
La palabra clave var también puede funcionar con el modo de declaración de la matriz, donde la matriz con la palabra clave var se inicializa solo en la primera barra.
var a = array.from(0)
b = array.from(0)
if bar_index == 1
array.push(a, bar_index)
array.push(b, bar_index)
else if bar_index == 2
array.push(a, bar_index)
array.push(b, bar_index)
else if barstate.islast
runtime.log("a:", a)
runtime.log("b:", b)
runtime.error("stop")
Se puede ver que los cambios en el conjunto a se determinan continuamente y no se vuelven a colocar; el conjunto b se inicializa en cada BAR; y finalmente en elbarstate.islast
En el caso de la impresión en tiempo real, solo queda un elemento, el valor 0♦.
Obtener elementos que especifican la posición del índice en una matriz con array.get y modificar elementos que especifican la posición del índice en una matriz con array.set.
El primer parámetro de array.get es el parámetro a tratar, y el segundo parámetro es el índice indicado. El primer parámetro de array.set es el parámetro a procesar, el segundo parámetro es el índice a especificar y el tercero es el elemento a escribir.
Para ilustrarlo, utilice el siguiente ejemplo simple:
lookbackInput = input.int(100)
FILL_COLOR = color.green
var fillColors = array.new(5)
if barstate.isfirst
array.set(fillColors, 0, color.new(FILL_COLOR, 70))
array.set(fillColors, 1, color.new(FILL_COLOR, 75))
array.set(fillColors, 2, color.new(FILL_COLOR, 80))
array.set(fillColors, 3, color.new(FILL_COLOR, 85))
array.set(fillColors, 4, color.new(FILL_COLOR, 90))
lastHiBar = - ta.highestbars(high, lookbackInput)
fillNo = math.min(lastHiBar / (lookbackInput / 5), 4)
bgcolor(array.get(fillColors, int(fillNo)), overlay=true)
plot(lastHiBar, title="lastHiBar")
plot(fillNo, title="fillNo")
Este ejemplo inicializa el color base verde, declara e inicializa una matriz para guardar el color, y luego asigna una transparencia diferente al valor del color (utilizando la función color.new). El rango del color se calcula calculando la distancia máxima del valor high en 100 ciclos de visualización del BAR actual. La distancia más cercana al máximo de high en los ciclos de visualización más recientes es el rango más alto y el valor de color correspondiente es más profundo (baja transparencia). Muchas estrategias similares se usan de esta manera para representar el nivel del precio en N ciclos de visualización actuales.
¿Cómo se puede recorrer una matriz, podemos hacerlo con la oración for/for in/while que hemos aprendido anteriormente.
a = array.from(1, 2, 3, 4, 5, 6)
for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1)
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
i = 0
while i < array.size(a)
array.set(a, i, i)
i += 1
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
for [i, ele] in a
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
Los tres métodos de exploración tienen el mismo resultado.
Las matrices pueden declararse en el ámbito global del guión, o en el ámbito local de la función o de la rama if.
Para el uso de los elementos de la matriz, la siguiente forma es equivalente, podemos ver en el siguiente ejemplo que se dibujan dos grupos de líneas en el gráfico, dos líneas por grupo, y el número de líneas de cada grupo es exactamente el mismo.
a = array.new_float(1)
array.set(a, 0, close)
closeA1 = array.get(a, 0)[1]
closeB1 = close[1]
plot(closeA1, "closeA1", color.red, 6)
plot(closeB1, "closeB1", color.black, 2)
ma1 = ta.sma(array.get(a, 0), 20)
ma2 = ta.sma(close, 20)
plot(ma1, "ma1", color.aqua, 6)
plot(ma2, "ma2", color.black, 2)
1, Función relacionada con el aumento de la operación del conjunto:
array.unshift()
、array.insert()
、array.push()
。
Función relacionada con la operación de eliminación de la matriz 2:
array.remove()
、array.shift()
、array.pop()
、array.clear()
。
Utilizamos los siguientes ejemplos para probar las funciones de adición, eliminación y operación de estas matrices.
a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.insert(a, 1, "Y")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.push(a, "D")
runtime.log("数组a:", a, ", ret:", ret)
ret := array.remove(a, 2)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.shift(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.pop(a)
runtime.log("数组a:", a, ", ret:", ret)
ret := array.clear(a)
runtime.log("数组a:", a, ", ret:", ret)
runtime.error("stop")
Aplicaciones para agregar y eliminar: matriz como columna
Usando las matrices, y algunas funciones de adición y eliminación de matrices, podemos construir estructuras de datos de "columnas". Las columnas se pueden usar para calcular las medias móviles de los precios de los ticks. Algunos estudiantes pueden preguntar: ¿Por qué construir estructuras de columnas?
Una cola es una estructura que se utiliza a menudo en el campo de la programación.
Primero entra el elemento de la cola, primero sale de la cola.
Esto garantiza que los datos que existen en la cola son los más recientes y que la longitud de la cola no se expande infinitamente (el código de inflación infinita solo se puede escribir a mediodía, ya que los días tempranos o tardíos pueden ser problemáticos).
En el ejemplo siguiente, utilizamos una estructura de cola para registrar el precio de cada tick, calcular el precio promedio móvil a nivel de tick y luego compararlo con el promedio de observación de la línea móvil a nivel de línea K de 1 minuto.
strategy("test", overlay=true)
varip a = array.new_float(0)
var length = 10
if not barstate.ishistory
array.push(a, close)
if array.size(a) > length
array.shift(a)
sum = 0.0
for [index, ele] in a
sum += ele
avgPrice = array.size(a) == length ? sum / length : na
plot(avgPrice, title="avgPrice")
plot(ta.sma(close, length), title="ta.sma")
Nota, cuando declaramos una matriz, hemos especificado el modelo de declaración, usando la palabra clave.varip
Así, cada cambio de precio se registra en una matriz a.
Calcular las funciones:
array.avg()
El valor medio de todos los elementos de la matriz.array.min()
Es el elemento más pequeño de la matriz.array.max()
El elemento más grande de la matriz.array.stdev()
El valor de los elementos de la matriz es el valor de los valores de los elementos de la matriz.array.sum()
La suma de todos los elementos de la matriz.
Funciones relacionadas con la operación:array.concat()
Combinar o conectar dos matrices.array.copy()
Replicación de las matrices.array.join
Conecta todos los elementos de la matriz en una sola cadena.array.sort()
En la lista de las personas que han sido seleccionadas, el nombre de la persona que ha sido seleccionada debe estar en el orden ascendente o descendente.array.reverse()
El conjunto invertido.array.slice()
Se hace un corte en el conjunto.array.includes()
Los elementos de juicio.array.indexof()
Devuelve el índice en el que apareció por primera vez el valor del parámetro enviado. Si no se encuentra, devuelve −1.array.lastindexof()
Encuentra el valor que apareció por última vez.
Ejemplos de pruebas de funciones relacionadas con el cálculo aritmético:
a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)
runtime.log("数组a的算数平均:", array.avg(a))
runtime.log("数组a中的最小元素:", array.min(a))
runtime.log("数组a中的最大元素:", array.max(a))
runtime.log("数组a中的标准差:", array.stdev(a))
runtime.log("数组a的所有元素总和:", array.sum(a))
runtime.error("stop")
Estas son las funciones de computación de arítmetos más usadas.
Ejemplos de funciones relacionadas:
a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)
runtime.log("数组a:", a, ", 数组b:", b)
runtime.log("数组a,数组b连接在一起:", array.concat(a, b))
c = array.copy(b)
runtime.log("复制一个数组b,赋值给变量c,变量c:", c)
runtime.log("使用array.join处理数组c,给每个元素中间增加符号+,连接所有元素结果为字符串:", array.join(c, "+"))
runtime.log("排序数组b,按从小到大顺序,使用参数order.ascending:", array.sort(b, order.ascending)) // array.sort函数修改原数组
runtime.log("排序数组b,按从大到小顺序,使用参数order.descending:", array.sort(b, order.descending)) // array.sort函数修改原数组
runtime.log("数组a:", a, ", 数组b:", b)
array.reverse(a) // 此函数修改原数组
runtime.log("反转数组a中的所有元素顺序,反转之后数组a为:", a)
runtime.log("截取数组a,索引0 ~ 索引3,遵循左闭右开区间规则:", array.slice(a, 0, 3))
runtime.log("在数组b中搜索元素11:", array.includes(b, 11))
runtime.log("在数组a中搜索元素100:", array.includes(a, 100))
runtime.log("将数组a和数组b连接,搜索其中第一次出现元素2的索引位置:", array.indexof(array.concat(a, b), 2), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.log("将数组a和数组b连接,搜索其中最后一次出现元素6的索引位置:", array.lastindexof(array.concat(a, b), 6), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.error("stop")
El lenguaje Pine puede diseñar funciones personalizadas, y en general, las funciones personalizadas del lenguaje Pine tienen las siguientes reglas:
1, todas las funciones están definidas en el ámbito global del script. No se puede declarar una función en otra función.
2, no permite que las funciones se llamen a sí mismas en su propio código.
3. En principio, todas las lenguas PINE tienen funciones gráficas incorporadas.barcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()
) no puede ser llamado dentro de funciones personalizadas.
4, la función puede ser escrita como una sola línea, varias líneas. El valor de retorno de la última frase es el valor de retorno de la función actual, el valor de retorno puede ser de forma de grupo.
En tutoriales anteriores también hemos usado varias veces funciones personalizadas, como diseñar funciones personalizadas en una sola línea:
barIsUp() => close > open
Esta función devuelve si el BAR actual es el rayo solar.
Se ha diseñado como una función personalizada de varias líneas:
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Una función de cálculo de la línea media de SMA que hemos implementado nosotros mismos con funciones personalizadas.
También, podemos devolver ejemplos de funciones personalizadas con dos variables:
twoEMA(data, fastPeriod, slowPeriod) =>
fast = ta.ema(data, fastPeriod)
slow = ta.ema(data, slowPeriod)
[fast, slow]
[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)
Una función puede calcular una línea rápida, una línea lenta, dos indicadores de EMA equilíneos.
Las funciones integradas se pueden usar fácilmenteFMZ PINE Script documentaciónEncuesta en el centro.
Las funciones integradas en el lenguaje Pine:
1, la función de procesamiento de la cadenastr.
La serie también incluye:
2, función de procesamiento de valor de colorcolor.
La serie también incluye:
3, función de entrada de parámetrosinput.
La serie también incluye:
Función de cálculo de indicadoresta.
La serie también incluye:
5, la función de dibujoplot.
La serie también incluye:
Función de procesamiento de matrices 6.array.
La serie también incluye:
7 Funciones relacionadas con transaccionesstrategy.
La serie también incluye:
Funciones relacionadas con las operaciones matemáticasmath.
La serie también incluye:
9, otras funciones (procesamiento de tiempo, funciones de gráficos de series no plot, etc.)request.
Las funciones de serie, las funciones de procesamiento de tipos, etc.)
strategy.
Las funciones de serie son funciones que usamos a menudo en las estrategias de diseño, que están estrechamente relacionadas con la ejecución de operaciones cuando se ejecutan específicamente.
1、strategy.entry
strategy.entry
La función es una función de subordinación que es más importante cuando escribimos la política, que es más importante en varios parámetros:id
, direction
, qty
, when
Y luego.
Parámetros:
id
Se puede entender que: se usa para referirse a un nombre para una posición comercial. Se puede referirse a este id para cancelar, modificar la orden, liquidar.direction
: si la dirección de la orden es hacer más (comprar) el parámetro se transmitestrategy.long
Esta variable está hecha para pasar si se quiere hacer un espacio libre (venda).strategy.short
Esta es una variable.qty
: especifica la cantidad a ordenar, si no se transmite este parámetro se usa la cantidad de unidad por defecto.when
: Condición de ejecución, se puede especificar este parámetro para controlar si se activa o no la operación de la orden actual.limit
El precio límite para el pedido es:stop
El precio de la suspensión de pérdida.strategy.entry
Los detalles específicos de ejecución de la funciónstrategy
Los parámetros de configuración del control cuando se llama una función también se pueden controlar mediante"Parámetros para el modelo de la librería de transacciones de lenguaje Pine"Para más detalles sobre el control de transacciones, consulte la documentación en el enlace.
¿Qué es lo que está sucediendo?strategy
En el caso de las funciones,pyramiding
、default_qty_value
Parámetros. Prueba con el siguiente código:
/*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(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
ema10 = ta.ema(close, 10)
findOrderIdx(idx) =>
if strategy.opentrades == 0
false
else
ret = false
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := true
break
ret
if not findOrderIdx("long1")
strategy.entry("long1", strategy.long)
if not findOrderIdx("long2")
strategy.entry("long2", strategy.long, 0.2, when = close > ema10)
if not findOrderIdx("long3")
strategy.entry("long3", strategy.long, 0.2, limit = low[1])
strategy.entry("long3", strategy.long, 0.3, limit = low[1])
if not findOrderIdx("long4")
strategy.entry("long4", strategy.long, 0.2)
plot(ema10, title="ema10", color=color.red)
Inicio del código/*backtest ... */
La parte del paquete está configurada para la revisión, es para registrar información como el tiempo de la revisión en ese momento, para facilitar el desactivación, no el código de la política.
En el código:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
Cuando lo especificamos,pyramiding
Cuando el parámetro es 3, tenemos un máximo de tres transacciones en la misma dirección.strategy.entry
Una de las siguientes operaciones no se ejecutó.default_qty_value
El parámetro es 0.1, por lo que el ID es el 1 por tonelado.strategy.entry
La cantidad de menús de la operación de menús está configurada por defecto como 0.1′.strategy.entry
La función que llamamos.direction
Es el mismostrategy.long
En la actualidad, la mayoría de los usuarios de Twitter no tienen acceso a la red social, por lo que los usuarios deben pagar para volver a probar.
En el código.strategy.entry("long3", ...
La siguiente operación se llama dos veces, para el mismo ID: strategy.entry
No se ha completado la siguiente operación, se llama por segunda vez.strategy.entry
Función para modificar el ID de la orden (los datos que se muestran en la prueba de retrospección también pueden ver que el volumen de la orden de este pedido de precio límite se ha modificado para 0.3); en otro caso, por ejemplo, si la primera orden de ID se realiza con el ID de la transacción, continúa con el ID de la transacción.strategy.entry
Si la función pone un pedido, las posiciones de pedido se acumulan en el ID de la pieza de 3 piezas.
2、strategy.close
strategy.close
La función se utiliza para especificar el ID de identificación de la posición de entrada de la posición de liquidación. Los parámetros principales son:id
,when
,qty
,qty_percent
。
Parámetros:
id
En la actualidad, la mayoría de los usuarios de Facebook están usando el nombre de usuario de Facebook.strategy.entry
El ID que se indica cuando se abre la función de entrada.when
Las condiciones de ejecución:qty
El número de operaciones de liquidación.qty_percent
Porcentaje de liquidación.Para familiarizarse con los detalles de uso de esta función, veamos un ejemplo:
En el código/*backtest ... */
是FMZ.COM国际站回测时的配置信息,可以删掉,设置自己需要测试的市场、品种、时间范围等信息。
/*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("close Demo", pyramiding=3)
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.2)
if strategy.opentrades >= 3
strategy.close("long1") // 多个入场订单,不指定qty参数,全部平仓
// strategy.close() // 不指定id参数,会平掉当前的持仓
// strategy.close("long2") // 如果指定一个不存在的id则什么都不操作
// strategy.close("long1", qty=0.15) // 指定qty参数平仓
// strategy.close("long1", qty_percent=50) // qty_percent设置50即为平掉long1标识仓位的50%持仓
// strategy.close("long1", qty_percent=80, when=close<open) // 指定when参数,修改为close>open就不触发了
enableStop := true
La estrategia de prueba muestra que se comienza a hacer múltiples entradas tres veces consecutivas, con un ID de entrada de 1 strategy.close
Los diferentes resultados obtenidos cuando los diferentes parámetros de la función se ponen en equilibrio pueden encontrarse.strategy.close
Esta función no tiene parámetros para especificar el precio de un pedido de liquidación, y se utiliza principalmente para liquidar de inmediato el precio actual del mercado.
3、strategy.close_all
strategy.close_all
La función se utiliza para nivelar todas las posiciones actuales, ya que el script de Pine solo puede tener una dirección de posicionamiento, es decir, si hay una señal en contra de la dirección de la posición actual, el gatillo se aplanará y abrirá la posición según la señal.strategy.close_all
Cuando se le llama, estabiliza todas las posiciones en la dirección actual.strategy.close_all
Los parámetros principales de la función son:when
。
Parámetros:
when
Las condiciones de ejecución:En el caso de los que no tienen acceso a la red, la información es más fácil de obtener.
/*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("closeAll Demo")
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open)
strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open)
if strategy.position_size < 0
strategy.close_all()
enableStop := true
Cuando el código de prueba comienza, el volumen de almacenamiento es 0 (es decir,strategy.position_size==0
Para ver), por lo que cumple con las condiciones del parámetro de cuando sólo se ejecuta el ID para el parámetro de when.strategy.entry
Función de entrada. Después de mantener varias posicionesstrategy.position_size
La función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de entrada de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida de la función de salida destrategy.position_size < 0
Cuando se mantiene una posición vacía, se estabiliza toda la posición en la dirección de la posición actual; y se marcaenableStop := true
Por ejemplo, en el caso de los registros de seguridad, la política de bloqueo de la aplicación puede ser más fácil de observar.
¿Cómo se puede encontrar?strategy.close_all
Esta función no tiene parámetros para especificar el precio de un pedido de liquidación, y se utiliza principalmente para liquidar de inmediato el precio actual del mercado.
4、strategy.exit
strategy.exit
La función se utiliza para operaciones de liquidación de entradas de tenencia, que difiere de la funciónstrategy.close
ystrategy.close_all
La función se estabiliza inmediatamente en el precio actual del mercado.strategy.exit
La función planea el equilibrio de acuerdo con los parámetros.
Parámetros:
id
: el identificador de pedido de la lista de condiciones de liquidación actual.from_entry
: se utiliza para especificar el ID de entrada para realizar operaciones de liquidación.qty
El número de operaciones de liquidación.qty_percent
Porcentaje de liquidación, rango: 0 ~ 100.profit
El objetivo de la ganancia, expresado en puntos.loss
El objetivo es detener los daños, indicado en puntos.limit
Los objetivos de ganancias se determinan por el precio.stop
El objetivo es detener los daños, y el precio es el indicado.when
Las condiciones de ejecución:Utilice una estrategia de prueba para entender el uso de los parámetros.
/*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"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("strategy.exit Demo", pyramiding=3)
varip isExit = false
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
strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0)
strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0)
strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0)
if not isExit and strategy.opentrades > 0
// strategy.exit("exitAll") // 如果仅仅指定一个id参数,则该退场订单无效,参数profit, limit, loss, stop等出场条件也至少需要设置一个,否则也无效
strategy.exit("exit1", "long1", profit=50) // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1
strategy.exit("exit2", "long2", qty=0.1, profit=100) // 指定参数qty,平掉ID为long2的持仓中0.1个持仓
strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000) // 指定参数qty_percent,平掉ID为long3的持仓中50%的持仓
isExit := true
if bar_index == 0
runtime.log("每点价格为:", syminfo.mintick) // 每点价格和Pine语言模板参数上「定价货币精度」参数设置有关
Utilizando la prueba de retrospección del modelo de precios en tiempo real, esta estrategia de prueba comienza con la ejecución de 3 operaciones de entrada.strategy.entry
Función), conlong1 tiene una configuración intencionallimit
Parámetros, el precio del pedido de suspensión es 1 lo que hace que sea imposible de negociar. Luego prueba la condición de salida de la funciónstrategy.exit
; se utilizan paradas por número de puntos, paradas por precio, paradas por número de posiciones fijas, paradas por porcentaje. Dado que en el ejemplo de este artículo solo se demuestra el paradas. Las operaciones de paradas y pérdidas también son simétricas.strategy.exit
La función también tiene parámetros de seguimiento más complejos:trail_price
、trail_points
、trail_offset
También se puede probar en este ejemplo para aprender cómo usarlo.
5、strategy.cancel
strategy.cancel
Funciones para cancelar/desactivar todos los comandos de las listas de espera. Estas funcionesstrategy.order
, strategy.entry
, strategy.exit
Se puede generar un ID de entrada. El parámetro principal de esta función es:id
、when
。
Parámetros:
id
En la página web de la organización, se puede leer:when
Las condiciones de ejecución:Esta función se entiende bien porque se utiliza para cancelar órdenes de acceso sin transacción.
/*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("long1")
strategy.cancel("long2")
strategy.cancel("long3")
isStop := true
6、strategy.cancel_all
strategy.cancel_all
Función ystrategy.cancel
Función similar a: ⇒ cancelar/desactivar todos los comandos de lista de espera. ⇒ puede especificarwhen
Los parámetros.
Parámetros:
when
Las condiciones de ejecución:/*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
7、strategy.order
strategy.order
Las funciones, los parámetros, etc. son casi iguales.strategy.entry
En la actualidad, la mayoría de los blogs están en línea.strategy.order
La función no puedestrategy
La funciónpyramiding
Los parámetros afectan a la configuración, no hay límite de número de veces.
Parámetros:
id
Se puede entender que: se usa para referirse a un nombre para una posición comercial. Se puede referirse a este id para cancelar, modificar la orden, liquidar.direction
: si la dirección de la orden es hacer más (comprar) el parámetro se transmitestrategy.long
Esta variable está hecha para pasar si se quiere hacer un espacio libre (venda).strategy.short
Esta es una variable.qty
: especifica la cantidad a ordenar, si no se transmite este parámetro se usa la cantidad de unidad por defecto.when
: Condición de ejecución, se puede especificar este parámetro para controlar si se activa o no la operación de la orden actual.limit
El precio límite para el pedido es:stop
El precio de la suspensión de pérdida.Así que usamosstrategy.order
No hay limitación en el número de unidades siguientes, la combinaciónstrategy.exit
Función de salida condicional. Construye un script similar a una transacción de red. El ejemplo es muy simple, sólo para aprender:
/*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 se utilizan solo para la enseñanza de estrategias y ideas de diseño de estrategias de orientación, y no son ninguna guía de transacciones, sugerencias o consejos.
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 sencillo escribir estrategias de tendencia en el lenguaje Pine, aquí diseñamos una estrategia de seguimiento de tendencias simple con un indicador de tendencia súper. Vamos a analizar el código fuente de esta estrategia juntos.
Primero, el código estratégico comienza a utilizarse.strategy
La función hace algunos ajustes simples:strategy("supertrend", overlay=true)
, sólo tiene que establecer una política titulada Supertrend.overlay
El parámetro estrue
Cuando diseñamos una estrategia Pine o aprendemos un guión de la estrategia Pine, lo primero que debemos ver es el diseño de parámetros de la interfaz de la estrategia.input
Función
[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)),
input
Las llamadas a funciones se utilizan directamente comota.supertrend
Los parámetros de las funciones de indicadores se utilizan para calcular los indicadores de supertrend; entre ellos:
Por defecto, la función establece dos controles de parámetros en la interfaz de la política del lenguaje Pine:
Como se puede ver, el valor predeterminado en el control esinput
Función yinput
La función de serie (() aquí esinput.int
Los dos primeros parámetros se explican en los capítulos anteriores. Con estas dos funciones podemos configurar en la interfaz estratégicata.supertrend
Los parámetros de la función. La función del indicador de tendencia súper calcula un dato de precio.supertrend
y datos de una dirección.direction
Y luego se usa.plot
Diagrama de función, tenga en cuenta que cuando se dibuja el diagrama se dibuja en función de la dirección del indicador de supertrend, y se dibuja solo la dirección actual; cuandodirection
La tendencia actual del mercado es al alza a las -1 horas, cuandodirection
La tendencia actual es a la baja a la hora 1:00, así que podemos ver que el mercado está bajando.plot
Decidir cuando dibujar una funcióndirection
Es mayor o menor que 0.
El siguiente:if ... else if
La lógica es el juicio de la señal de transacción, cuando la expresióndirection < 0
En tiempo real indica que el mercado está en la fase de subida, cuando los datos de precios en el indicador de supertrend están en la fase de subida.supertrend
Más alto que el precio del indicador de supertrend en los dos primeros BAR (es decir,supertrend[2],还记得历史操作符引用某个变量历史数据吧
Si hay una posición en ese momento, una llamada a la función inversa a la baja de una sola función se despejará primero la posición anterior y luego abrirá la posición según la dirección actual de la operación.supertrend > supertrend[2]
Las condiciones no se han cumplido, por lo tanto, por ahora.strategy.position_size < 0
El hecho de tener una posición de cabeza vacía también puede desencadenar el problema.strategy.close_all()
La función se ejecuta, se realiza todo el equilibrio.
direction > 0
Cuando se encuentra en la fase de tendencia a la baja, también es lo mismo, si hay varias tenencias, todas se estabilizan, entonces cumple con las condiciones.supertrend < supertrend[3]
¿Por qué se ha configurado esto? ¿Por qué se ha configurado esto?[3]
¿Qué pasa con la referencia a los datos de precios del indicador de súper tendencia en la tercera barra anterior? Puede que sea intencional para el estratega, después de todo, en algunos mercados, como el mercado de operaciones de contratos, el riesgo de hacer nada es ligeramente mayor que el riesgo de hacer más.
En cuanto ata.supertrend
El indicador, si algunos de sus compañeros están interesados, es cómo se determina si la tendencia actual es alcista o descendente.
En realidad, 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 es una función de configuraciónta.supertrend
El algoritmo es el mismo y, por supuesto, los datos de los indicadores que se calculan son los mismos.
De este algoritmo de funciones personalizadas podemos ver que el cálculo de los indicadores de supertrend que Pine tiene incorporados se usa para calcular el valor de las tendencias.hl2
Las variables de configuración (el precio más alto, el precio más bajo sumado y dividido por 2, es decir, el promedio del precio más alto y el precio más bajo) se calculan según el parámetro trPeriod.
Actualizaciones basadas en expresiones tridimensionales en el códigolowerBand
yupperBand
。
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
LowerBand: línea descendente, para determinar si la tendencia ascendente ha cambiado. UpperBand: línea descendente, para determinar si la tendencia descendente ha cambiado. LowerBand y upperBand están siempre siendo calculados, sólo que en esta función de configuración final se determina la dirección de la tendencia actual.
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Aquí se determina si el valor de la súper tendencia en la última barra esprevUpperBand
La línea ascendente es la que indica la tendencia descendente.close
Más deupperBand
El precio se rompe, creyendo que en ese momento la tendencia cambia y se convierte en una tendencia al alza.direction
La variable de dirección se establece en -1 (trend ascendente); de lo contrario, se mantiene en 1 (trend descendente); por lo que se verá en la estrategia de supertrend.if direction < 0
Cuando la señal se dispara, haz más.direction > 0
Cuando se dispara la señal, las condiciones son inactivas.
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Por último, los datos de precios y de dirección de los indicadores de súper tendencia específicos se devuelven según la dirección seleccionada.
/*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)
Continuamos aprendiendo algunos ejemplos de diseño de estrategias en el lenguaje Pine, y esta vez vamos a ver una estrategia de equilibrio dinámico.BaseCurrency
(variedad negociada) yQuoteCurrency
La cantidad de (moneda de cuentas) siempre se trata de un equilibrio. El aumento del precio relativo de un activo, el aumento del valor de lo que se tiene en la cuenta, el aumento del valor de lo que se vende en la cuenta. Si el precio relativo de un activo disminuye, el valor de lo que se tiene en la cuenta disminuye, se compra el activo.
La desventaja de esta estrategia es que, como se puede ver en el gráfico de retrospectiva, la estrategia de flotación es más grande en la fase de la tendencia al alza (o a la baja) de los precios. Por lo tanto, esta estrategia es buena para la estrategia de contado, y su uso en futuros requiere controlar el riesgo.
En este caso, la estrategia de diseño de código es la siguiente:
Usamos un diseño simplificado para simular una estrategia en la que se usa un sistema de control de velocidad.balance
(es decir, el número de activos de la moneda cotizada)stocks
(es decir, el número de activos BaseCurrency) información de equilibrio. No vamos a leer el número de activos reales en la cuenta, sólo usamos la cantidad simulada para calcular la compra y venta adecuadas.maxDiffValue
Este parámetro es el criterio de equilibrio.BaseCurrency
yQuoteCurrency
La desviación excedemaxDiffValue
En el caso de los bancos, el precio de los activos es el mismo que el de los bancos, y el precio de los activos es el mismo que el de los bancos.
La activación de la señal de negociación estratégica debe tener sentido en la etapa BAR en tiempo real, por lo que las condiciones de negociación estratégica se establecen en el juicio sinot barstate.ishistory
Los precios de los productos de la industria se han incrementado en los últimos años.balance
El valor es superiorstocks
Comprar cuando el valor es; vender al revés; actualizar después de ejecutar la declaración de transacción.balance
ystocks
El resultado es que el número de personas que se encuentran en la misma situación de equilibrio es igual al número de personas que se encuentran en la misma situación.
La información de la estrategia de recuperación anterior contiene el precio de la variedad en la que la estrategia de recuperación comenzó, el precio es 1458, así que he configurado el parámetro a propósito.balance
Para: 4374 ((1458*3), el parámetro de configuraciónstocks
Por ejemplo: 3: mantener el activo en equilibrio al principio.
En las clases anteriores hemos aprendidostrategy.exit
Función de salida de posición, en la que no tenemos un ejemplo de la función de stop loss tracking. En el ejemplo de diseño de estrategias de esta sección, usamosstrategy.exit
La función de seguimiento de stop-loss para optimizar una estrategia de supertrend.
Primero vamos a ver.strategy.exit
Parámetros de parálisis de parálisis de parálisis de parálisis de parálisis de parálisis de parálisis de parálisis de parálisis de parálisis:
1、trail_price
Parámetros: activar la ubicación del comportamiento lógico de la orden de liquidación de seguimiento de pérdidas y pérdidas (especificado en el precio)