[TOC]
A estrutura geral do código em Pine é:
<version>
<declaration_statement>
<code>
O símbolo de anotação suportado pela linguagem Pine do FMZ: anotação de linha única//
O que é que você está a fazer?/* */
O que você pode fazer para evitar que o seu blog seja destruído, por exemplo:
[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9) // 计算MACD指标
/*
plot函数在图表上画出指标线
*/
plot(macdLine, color = color.blue, title='macdLine')
plot(signalLine, color = color.orange, title='signalLine')
plot(histLine, color = color.red, title='histLine')
As instruções do compilador da seguinte forma informam o compilador em que versão do script o Pine foi escrito:
//@version=5
A versão v5 por defeito pode ser omitida no código.//@version=5
。
indicator()
strategy()
A declaração define o tipo de script, que também determina o que é permitido e como ele é usado e executado. Configura propriedades-chave do script, como seu nome, onde ele aparecerá quando for adicionado ao gráfico, a precisão e o formato dos valores que ele exibirá, e controla certos valores de seu comportamento quando executado, como o número máximo de objetos gráficos que ele exibirá no gráfico. Para a política, a propriedade inclui parâmetros que controlam a retrospecção, como o capital inicial, comissões, pontos de deslizamento, etc.indicator()
Oustrategy()
A declaração diz:
As linhas que não são comentários ou instruções do compilador no script são as instruções que implementam o algoritmo do script. Uma instrução pode ser uma delas.
if
,for
,while
Ouswitch
Estruturas equivalentesAs frases podem ser organizadas de várias maneiras.
空格
Ou制表符
(tab) começa. Seu primeiro caractere também deve ser o primeiro caractere da linha. A linha que começa na primeira posição da linha, por definição, faz parte do escopo global do script.local block
O bloco local deve ser reduzido a um símbolo ou quatro espaços (caso contrário, ele será resolvido como a linha de código serial anterior, ou seja, será considerado como o conteúdo contínuo da linha anterior), e cada bloco local define um escopo local diferente.Por exemplo, três blocos locais, um em declarações de funções personalizadas e dois em declarações de variáveis, usam a estrutura if, com o seguinte código:
indicator("", "", true) // 声明语句(全局范围),可以省略不写
barIsUp() => // 函数声明(全局范围)
close > open // 本地块(本地范围)
plotColor = if barIsUp() // 变量声明 (全局范围)
color.green // 本地块 (本地范围)
else
color.red // 本地块 (本地范围)
runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)
As linhas longas podem ser divididas em várias linhas, ou podem ser "enroladas". As linhas enroladas devem ser enroladas em qualquer número de espaços, desde que não sejam múltiplos de 4 (estas fronteiras são usadas para enrolar blocos).
a = open + high + low + close
Pode ser embalado em ((observe que o número de espaços encolhidos por linha não é um múltiplo de 4):
a = open +
high +
low +
close
Uma chamada longa de plot ((() pode ser embalada em.
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100), // 一行长的plot()调用可以被包装
color = color.new(color.purple, 40),
style = plot.style_area,
trackprice = true)
As declarações de uma função definida pelo usuário também podem ser encapsuladas. No entanto, como o local deve começar gramaticalmente com um encolhimento ((quatro espaços ou um símbolo), quando dividido para a linha seguinte, a parte contínua da declaração deve começar com mais de um encolhimento ((não é igual a um múltiplo de 4 espaços)); por exemplo:
test(c, o) =>
ret = c > o ?
(c > o+5000 ?
1 :
0):
(c < o-5000 ?
-1 :
0)
a = test(close, open)
plot(a, title="a")
A sequência de tempo não é um tipo ou formato de dados, mas um conceito de estrutura básica na linguagem PINE. É usado para armazenar valores que variam continuamente no tempo, cada valor correspondendo a um ponto de tempo.
Variações embutidasopen
Por exemplo:open
A variável interna registra o preço de abertura de cada linha K BAR, se estaopen
Então, se você fizer isso, você vai ter um ciclo de 5 minutos.open
O que é registrado na variável é o preço de abertura da coluna BAR da linha K a cada 5 minutos.open
Ou seja, referindo-se ao preço de abertura da linha BAR em que está atualmente. Para referir o valor anterior na sequência de tempo (o valor passado), usamos[]
O operador histórico, quando a política é executada em uma barra de linha K, é executado em uma barra de linha K.open[1]
Significa referir-se ao preço de abertura do anterior K-line BAR do atual K-line BAR.
Não é?Sequência de tempoÉ fácil lembrar estruturas de dados como "arquivos", embora a linguagem PINE também tenha tipos de arquivos. Mas eles são conceitos completamente diferentes da sequência de tempo.
A linguagem PINE desenha sequências de tempo assim, com a facilidade de calcular o valor acumulado do preço de fechamento no código da estratégia, e sem o uso de estruturas circulares como for, usando apenas funções internas da linguagem PINE.ta.cum(close)
Por outro lado, para dar um exemplo, precisamos calcular a média entre o valor máximo e o valor mínimo de diferença entre os últimos 14 K-string BAR (ou seja, o 14 K-string BAR mais próximo do momento em que o código foi executado) e podemos escrever:ta.sma(high - low, 14)
Os resultados de chamadas de funções em uma sequência de tempo também deixam uma marca na sequência de tempo.[]
O operador histórico refere-se ao valor anterior. Por exemplo, quando testamos se o preço de fechamento do Kline BAR atual é maior que o valor máximo do preço mais alto dos últimos 10 Kline BARs (excluindo o Kline BAR atual), podemos escrever:breach = close > ta.highest(close, 10)[1]
A mesma coisa pode ser escrita como:breach = close > ta.highest(close[1], 10)
Por isso.ta.highest(close, 10)[1]
eta.highest(close[1], 10)
O que é o que você está fazendo?
A verificação pode ser feita com o seguinte código:
strategy("test pine", "test", true)
a = ta.highest(close, 10)[1]
b = ta.highest(close[1], 10)
plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green)
O código de teste acima produz valores de a e b em suas respectivas sequências de tempo em cada BAR, e você pode ver que os valores de a e b são sempre iguais, então os dois métodos de representação são equivalentes.
A configuração dos parâmetros do modelo embutido para a política do PINE, "Pine Language Exchange Library".
定价货币精度
O parâmetro e o parâmetro determinam o preço de deslizamento quando o pedido é feito. Por exemplo, se o preço da moeda for definido com precisão de 2, ou seja, com precisão até o segundo ponto da fração, com precisão até 0.01..., então o ponto de deslizamento representa 0.01 unidades de preço.javascript
Invocação na estratégiaSetMaxBarLen
A função funciona da mesma maneira.strategy(title = "open long example", pyramiding = 3) // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.01) // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.02, when = close > ta.ema(close, 10)) // 条件触发,执行下单,市价开多仓
strategy.entry("long3", strategy.long, 0.03, limit = 30000) // 指定(较低的)价格,计划下买单订单,等待成交开仓,限价开仓
strategy(title = "close long example", pyramiding = 2) // pyramiding 允许的同方向下单的次数
strategy.entry("long1", strategy.long, 0.1) // 市价开多仓,指定分组标签为long1
strategy.entry("long2", strategy.long, 0.1) // 市价开多仓,指定分组标签为long2
strategy.close("long1", when = strategy.position_size > 0.1, qty_percent = 50, comment = "close buy entry for 50%") // 平仓,指定平掉分组标签为long1的仓位的50%持仓
strategy.close("long2", when = strategy.position_size > 0.1, qty_percent = 80, comment = "close buy entry for 80%") // 平仓,指定平掉分组标签为long2的仓位的80%持仓
O mecanismo de posicionamento da linguagem PINE é semelhante ao posicionamento unidirecional. Por exemplo, quando uma posição é mantida em várias direções ("multi-head holding"), se houver uma ordem de venda, lista de planos, etc. (em relação à direção inversa da posição), a ordem é executada.
Quando se usa a instrução de submissão, se não for especificado nenhum preço, a submissão é a submissão de preço de mercado. Além da submissão de preço de mercado, a submissão de preço também pode ser executada por submissão de plano, o qual não opera a submissão imediatamente. A submissão de plano pode ser executada na fila de submissão de plano do programa que existe quando não é desencadeada.Disco real/retestadoAs informações de estado do tempo (ou seja, a barra de estado do momento em que a política está sendo executada) são vistas no separador de páginas do "Plano de pedidos"; o sistema só vai realmente fazer os pedidos quando os preços do mercado em tempo real satisfazem as condições para ativar esses pedidos; portanto, esses pedidos têm um pequeno desvio no preço de transação.strategy.entry
Quando a função é ordenada, podemos especificarlimit
、stop
Parâmetros.
var isTrade = false
if not barstate.ishistory and not isTrade
isTrade := true
strategy.entry("test 1", strategy.long, 0.1, stop=close*1.3, comment="test 1 order") // stop
strategy.entry("test 2", strategy.long, 0.2, limit=close*0.7, comment="test 2 order") // limit
strategy.entry("test 3", strategy.short, 0.3, stop=close*0.6, limit=close*1.4, comment="test 3 order") // stop-limit
Ordens limitadas
O preço limite da encomenda é definido quando a encomenda é paga (ou seja, quando a encomenda é paga).direction
O parâmetro éstrategy.long
A ordem é ativada somente quando o preço atual do mercado está abaixo desse preço.
Quando a encomenda é para venda (isto é,direction
O parâmetro éstrategy.short
O preço de venda é o preço de venda de um produto ou serviço (ou seja, o preço de venda de um produto ou serviço é o preço de venda do produto ou serviço).
Encomenda de stop
O preço de stop loss da ordem é definido, quando a ordem é para pagar, e a ordem só é desencadeada quando o preço atual do mercado é superior a esse preço. Quando o pedido é um pedido de venda, o pedido só é desencadeado quando o preço atual do mercado está abaixo desse preço.
Ordem stop-limit
Pode ser configurado simultaneamentelimit
、stop
Parâmetros, os pedidos são desencadeados no preço que atende primeiro às condições.
//@version=5
strategy("Percent of Equity Order", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// 简单的均线交叉策略
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
// 如果均线交叉条件满足,则买入或卖出
if (longCondition)
strategy.entry("Long", strategy.long)
if (shortCondition)
strategy.entry("Short", strategy.short)
Especificardefault_qty_type=strategy.percent_of_equity
Em seguida, configuredefault_qty_value
Para o número de percentagens ((0 a 100), 1 ou 1%;; calculada em função do número de moedas cotadas na conta;; por exemplo: a conta atual tem 10000 USDT e a ordem de pagamento é definida em 1%, ou seja, a ordem de pagamento é feita usando uma escala de 100 USDT (compreendida em função do preço atual no momento da venda).
var é a palavra-chave para distribuição e inicialização de variáveis de uma só vez. Normalmente, a sintaxe de atribuição de variáveis que não contém a palavra-chave var leva a que o valor da variável seja coberto toda vez que os dados são atualizados. Em contraste, quando as variáveis de atribuição com a palavra-chave var são usadas, elas podem manter o status quo mesmo que os dados sejam atualizados e só podem ser alteradas quando as condições das if-expressions forem atendidas.
var variable_name = expression
Explicação:
variable_name
- Qualquer nome de variável de usuário permitido no Pine Script ((pode conter caracteres latinos em maiúsculas e minúsculas, números e signos de pontuação ((_), mas não pode começar por números) )).expression
- Qualquer expressão aritmética, como definir uma variável regular.Exemplos
// Var keyword example
var a = close
var b = 0.0
var c = 0.0
var green_bars_count = 0
if close > open
var x = close
b := x
green_bars_count := green_bars_count + 1
if green_bars_count >= 10
var y = close
c := y
plot(a, title = "a")
plot(b, title = "b")
plot(c, title = "c")
A variável
No FMZ, os preços são divididos em modelos de preços em tempo real, modelos de preços de fechamento e modelos de preços de venda.var
、varip
A variável declarada é testada usando o seguinte código:
strategy("test pine", "test 1", true)
// 测试 var varip
var i = 0
varip ii = 0
// 将策略逻辑每轮改变的i、ii打印在图上
plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)
// 每轮逻辑执行都给i、ii递增1
if true
i := i + 1
ii := ii + 1
Modelo de preços em tempo real
O código de teste acima é dividido em duas fases de execução: 1, fase da linha K histórica; 2, fase da linha K em tempo real.var
、varip
A variável declarada i, ii executa operações incrementadas a cada rodada de execução do código da política, porqueif true
Portanto, é certo executar o bloco de código de condição correspondente); portanto, pode-se ver que os números exibidos no resultado do retorno da linha K BAR são cada um incremental de 1; quando o estágio da linha K histórico termina, começa o estágio da linha K em tempo real.var
、varip
As variáveis declaradas começam a mudar. Como é um modelo de preços em tempo real, cada mudança de preço em uma barra de K é executada com código de estratégia repetido.i := i + 1
eii := ii + 1
A diferença é que i é modificado cada vez. Embora a lógica da política seja modificada cada vez, o valor anterior é restaurado na próxima rodada de execução da lógica da política, até que o valor da i seja atualizado para determinar o valor anterior (ou seja, não é restaurado na próxima rodada de execução da lógica da política). Assim, pode-se ver que a variável i ainda é um BAR1 por cada raiz; mas a variável ii é adicionada várias vezes por cada BAR.
Modelo de preços de fechamento
Como o modelo de preço de fechamento executa uma lógica de estratégia quando cada linha K BAR termina.var
、varip
As variáveis declaradas apresentam-se de forma perfeitamente consistente no exemplo acima, em cada linha K BAR incrementada por 1.
varip (var intrabar persist) é uma palavra-chave usada para atribuir e iniciar variáveis de uma só vez. É semelhante à palavra-chave var, mas as variáveis que usam a declaração varip mantêm seus valores entre as atualizações de linhas K em tempo real.
varip variable_name = expression
Explicação:
variable_name
- Qualquer nome de variável de usuário permitido no script Pine (podendo incluir letras maiúsculas e minúsculas em letras latinas, números e sigilo (_), mas não pode começar com um número).expression
- Qualquer expressão aritmética, como na definição de variáveis regulares. Na primeira linha K, a expressão é calculada apenas uma vez e é atribuída às variáveis uma vez.Exemplos
// varip
varip int v = -1
v := v + 1
plot(v)
Quando o var é usado, o gráfico retorna o valor do bar_index. Usando o varip, o mesmo comportamento ocorre na linha K histórica, mas na linha K em tempo real, o gráfico retorna um valor que aumenta um para cada tick.
NotasPode ser usado somente com tipos simples, como float, int, boolean, string, e matrizes desses tipos.
Indique o valor de uma variável de tipo Boole, ou quando a expressão é usadaComparaçãoOuLógicaO valor que pode ser calculado quando o operador.
NotasVeja tambémComparaçãoOperador eLógicaDescrição do operador.
Até logo.
bool
Indica o valor de uma variável de tipo Boole, bem como o resultado de uma operação de comparação ou de uma operação lógica.
NotasVeja tambémComparaçãoOperador eLógicaDescrição do operador.
Até logo.
bool
As instruções definem blocos de instruções que devem ser executados quando as condições da expressão são atendidas. A linguagem de scripting Pine da 4a edição permite que você use a sintaxe
O código comum vem de:
var_declarationX = if condition
var_decl_then0
var_decl_then1
...
var_decl_thenN
return_expression_then
else if [optional block]
var_decl_else0
var_decl_else1
...
var_decl_elseN
return_expression_else
else
var_decl_else0
var_decl_else1
...
var_decl_elseN
return_expression_else
Notas
var_declarationX
- Esta variável obtém o valor da se declaraçãocondition
- Se a condição for true, usar blocos de sentença.then
A lógica no (((var_decl_then0
,var_decl_then1
etc) ⇒ Se a condição for false, use o bloco de sentençaelse if
Ouelse
A lógica no (((var_decl_else0
,var_decl_else1
E assim por diante.return_expression_then , return_expression_else
- A última expressão no módulo ou a expressão do blocoelse retornará o valor final da declaração. Se a declaração da variável estiver no final, seu valor será o valor do resultado.
O tipo de valor de retorno da expressão if depende de:return_expression_then
ereturn_expression_else
Tipos. Quando executado no TradingView, seus tipos devem corresponder: é impossível retornar um valor inteiro do bloco then quando você tem um valor de string no blocoelse. Quando executado no FMZ, os seguintes exemplos não retornam erros: quando o valor y é "open", o valor do gráfico do plot é n/a.
Exemplos
// This code compiles
x = if close > open
close
else
open
// This code doesn’t compile by trading view
// y = if close > open
// close
// else
// "open"
plot(x)
Pode ser omitido.else
bloco. Nesse caso, se a condição for false, é atribuído um limiar naempty para a variável var_declarationX ((na、false ou na):
Exemplos
// if
x = if close > open
close
// If current close > current open, then x = close.
// Otherwise the x = na.
plot(x)
Pode-se usar vários blocos de
Exemplos
// if
x = if open > close
5
else if high > low
close
else
open
plot(x)
Não se esqueça.if
O valor de resultado da declaração ((
Exemplos
if (ta.crossover(high, low))
strategy.entry("BBandLE", strategy.long, stop=low)
else
strategy.cancel(id="BBandLE")
As frases de "if" podem conter uma outra:
Exemplos
// if
float x = na
if close > open
if close > close[1]
x := close
else
x := close[1]
else
x := open
plot(x)
A estrutura 'for' permite a execução repetida de várias instruções:
[var_declaration =] for counter = from_num to to_num [by step_num]
statements | continue | break
return_expression
var_declaration
- Uma declaração de variável opcional, que será designada como o valor da expressão return_expression do círculo de retorno.counter
- Armazena a variável do valor do contador de retorno, aumentando/diminuindo o valor de 1 ou step_num em cada repetição do retorno;from_num
- O valor inicial do contador. É permitido o uso de um conjunto de valores int/float thresholds/expressões.to_num
O ciclo é interrompido quando o contador é maior do que to_num (ou menor do que to_num no caso de from_num > to_num). O uso da expressão int/float thresholds/series é permitido, mas eles são avaliados apenas na primeira repetição do ciclo.step_num
- Aumenta/desce o valor do contador. É opcional. O valor padrão é +1 ou-1, dependendo do maior de from_num ou to_num. Quando o valor é usado, o contador também aumenta/desce com base no maior de from_num ou to_num, portanto o símbolo +/- do step_num é opcional.statements | continue | break
- Qualquer número de sentenças, ou a palavra-chave "continue" ou "break", reduzidas a 4 espaços ou uma guia;return_expression
- O valor de retorno do ciclo, se existir, é atribuído a uma variável na var_declaration. Se o ciclo sair por causa da palavra-chave "continue" ou "break", o valor de retorno do ciclo é o valor da última variável que recebeu o valor antes de sair do ciclo.continue
- A palavra-chave que só pode ser usada no ciclo de retorno.break
- A palavra-chave para sair do círculo de volta.
Exemplos
// Here, we count the quantity of bars in a given 'lookback' length which closed above the current bar's close
qtyOfHigherCloses(lookback) =>
int result = 0
for i = 1 to lookback
if close[i] > close
result += 1
result
plot(qtyOfHigherCloses(14))
Até logo.
for...in
while
for...in
A estrutura permite executar várias declarações repetidas para cada elemento da matriz. Pode ser usada com qualquer parâmetro:array_element
, ou em conjunto com dois parâmetros:[index, array_element]
A segunda forma não afeta a função do ciclo. Segue o índice da atual iteração na primeira variável do grupo.
[var_declaration =] for array_element in array_id
statements | continue | break
return_expression
[var_declaration =] for [index, array_element] in array_id
statements | continue | break
return_expression
var_declaration
- uma declaração de variável opcional que será atribuída ao cicloreturn_expression
O valor de.index
- A seguir variáveis opcionais do índice iterativo atual. O índice começa em 0. A variável é invariável no ciclo. Quando usada, ela deve ser incluída em um índice também incluído.array_element
A partir daí, o grupo de elementos de um sistema é chamado de grupo de elementos.array_element
- contém uma variável para cada elemento de uma matriz contínua a ser processado no ciclo.array_id
- ID de matriz de rotação iterativa.statements | continue | break
- Qualquer número de sentenças, ou a palavra-chave "continue" ou "break", reduzidas a 4 espaços ou uma guia;return_expression
- o valor de retorno do ciclo é atribuído avar_declaration
Variações no interior, se existirem. Se o ciclo sair por causa da palavra-chave "continue" ou "break", o valor de retorno do ciclo é a última variável atribuída antes do ciclo sair.continue
- A palavra-chave que só pode ser usada no ciclo de retorno.break
- A palavra-chave para sair do círculo de volta.
Permite modificar o elemento ou o tamanho da matriz durante o ciclo.
Aqui, usamosfor...in
A forma de um único parâmetro para determinar em cada linha K, quantos linhas K têm um valor OHLC maior do que o SMA do limiar de "close":
Exemplos
// Here we determine on each bar how many of the bar's OHLC values are greater than the SMA of 'close' values
float[] ohlcValues = array.from(open, high, low, close)
qtyGreaterThan(value, array) =>
int result = 0
for currentElement in array
if currentElement > value
result += 1
result
plot(qtyGreaterThan(ta.sma(close, 20), ohlcValues))
Aqui, nós usamos a forma de dois parâmetros de for...in para transformar o nossoisPos
O valor da matriz é definido comotrue
Quando eles estão no nossovaluesArray
O valor correspondente no conjunto é:
Exemplos
// for...in
var valuesArray = array.from(4, -8, 11, 78, -16, 34, 7, 99, 0, 55)
var isPos = array.new_bool(10, false)
for [index, value] in valuesArray
if value > 0
array.set(isPos, index, true)
if barstate.islastconfirmedhistory
runtime.log(str.tostring(isPos))
Até logo.
for
while
array.sum
array.min
array.max
while
A expressão permite a repetição de condições de blocos de código locais.
variable_declaration = while boolean_expression
...
continue
...
break
...
return_expression
Explicação:variable_declaration
- Declaração de variável opcional.return expression
Pode ser fornecido um valor de inicialização para esta variável.boolean_expression
- Execute se for verdade.while
O bloco local da sentença. Se for falso, ele está em:while
Depois da frase, continue executando o script.continue
- continue
A palavra-chave leva a um ciclo de ramificação até a próxima iteração.break
- break
A palavra-chave causa a interrupção do ciclo.while
A frase é retomada depois.return_expression
- Fornecido.while
A frase retorna um valor opcional.
Exemplos
// This is a simple example of calculating a factorial using a while loop.
int i_n = input.int(10, "Factorial Size", minval=0)
int counter = i_n
int factorial = 1
while counter > 0
factorial := factorial * counter
counter := counter - 1
plot(factorial)
NotasIníciowhile
O bloco de código local após a linha deve ser reduzido a quatro espaços ou um símbolo de cronograma.while
O ciclo.while
A seguinte expressão de Boole tem que acabar por se tornar false, ou tem que ser executadabreak
。
O operador switch transfere o controle para uma das várias instruções, dependendo do valor da condição e da expressão.
[variable_declaration = ] switch expression
value1 => local_block
value2 => local_block
...
=> default_local_block
[variable_declaration = ] switch
boolean_expression1 => local_block
boolean_expression2 => local_block
...
=> default_local_block
O que é que ele está a fazer?
Exemplos
// Switch using an expression
string i_maType = input.string("EMA", "MA type", options = ["EMA", "SMA", "RMA", "WMA"])
float ma = switch i_maType
"EMA" => ta.ema(close, 10)
"SMA" => ta.sma(close, 10)
"RMA" => ta.rma(close, 10)
// Default used when the three first cases do not match.
=> ta.wma(close, 10)
plot(ma)
O que é que ele está a fazer?
Exemplos
strategy("Switch without an expression", overlay = true)
bool longCondition = ta.crossover( ta.sma(close, 14), ta.sma(close, 28))
bool shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
switch
longCondition => strategy.entry("Long ID", strategy.long)
shortCondition => strategy.entry("Short ID", strategy.short)
Retorno de valorO valor da última expressão no bloco de expressão local executado.
NotasApenas executadolocal_block
Exemplo oudefault_local_block
Uma delas.default_local_block
Apenas com=>
Introdução do marcador em conjunto, e somente quando o bloco anterior não é executado; seswitch
O resultado da declaração é atribuído a uma variável e não especificadodefault_local_block
Se não for executadolocal_block
A frase é devolvida.na
Não, não é.switch
Quando o resultado da declaração é atribuído a uma variável, todoslocal_block
O exemplo deve retornar valores do mesmo tipo.
Até logo.
if
?:
series é uma palavra-chave que indica o tipo de série de dados.series
A palavra-chave geralmente é desnecessária.
É usado para atribuir valores a variáveis, mas somente quando as variáveis são declaradas (ou usadas pela primeira vez).
O operador de atribuição dá atribuições às variáveis à esquerda. É usado para atribuir atribuições às variáveis declaradas anteriormente.
Não é igual a. Aplica-se a qualquer tipo de expressão.
expr1 != expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
Número de módulo (numero inteiro residual); aplica-se a expressões numéricas.
expr1 % expr2
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
NotasNo script Pine, quando se calcula o restante de um número inteiro, o negócio é cortado; isto é, ele é quadrado até o menor valor absoluto. O valor obtido terá o mesmo símbolo que o dividendo.
Exemplo: -1 % 9 = -1 - 9 * truncate ((-1/9) = -1 - 9 * truncate ((-0.111) = -1 - 9 * 0 = -1.
Indicação de módulo.
expr1 %= expr2
Exemplos
// Equals to expr1 = expr1 % expr2.
a = 3
b = 3
a %= b
// Result: a = 0.
plot(a)
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
Multiplicação. Aplica-se às expressões numéricas.
expr1 * expr2
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
As designações de multiplicação. Aplicam-se às expressões numéricas.
expr1 *= expr2
Exemplos
// Equals to expr1 = expr1 * expr2.
a = 2
b = 3
a *= b
// Result: a = 6.
plot(a)
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
Adição ou unidade de número verdadeiro. Aplica-se a expressões numéricas ou strings.
expr1 + expr2
+ expr
Retorno de valorO binário de uma string+
Retorna a combinação de express1 e express2
Um número retorna um inteiro ou um valor de ponto flutuante, ou uma série de valores:
O binomial +'retorna express1 mais express2.
O valor de 1 + 1 retorna express (não adiciona nada à simetria de um operador de 1).
NotasVocê pode usar operadores aritméticos com números, bem como colunas de variáveis. No caso de colunas de números, os operadores são aplicados aos elementos.
A designação de um gráfico. Aplica-se a uma expressão numérica ou uma string.
expr1 += expr2
Exemplos
// Equals to expr1 = expr1 + expr2.
a = 2
b = 3
a += b
// Result: a = 5.
plot(a)
Retorno de valorPara uma string, retorna a sequência de express1 e express2; para um número, retorna um inteiro ou um valor de ponto flutuante, ou uma série de valores.
NotasVocê pode usar operadores aritméticos com números, bem como colunas de variáveis. No caso de colunas de números, os operadores são aplicados aos elementos.
Subtração ou número negativo único.
expr1 - expr2
- expr
Retorno de valorRetorna um inteiro ou um valor de ponto flutuante, ou uma série de valores:
O binomial i +'retorna express1 menos express2.
Um dólar-
Retornar o negativo de expressão.
NotasVocê pode usar operadores aritméticos com números, bem como colunas de variáveis. No caso de colunas de números, os operadores são aplicados aos elementos.
Designação de subtração.
expr1 -= expr2
Exemplos
// Equals to expr1 = expr1 - expr2.
a = 2
b = 3
a -= b
// Result: a = -1.
plot(a)
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
Exclusão.. Aplica-se a expressões numéricas..
expr1 / expr2
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
Excepção de designação. Aplica-se à expressão numérica.
expr1 /= expr2
Exemplos
// Equals to expr1 = expr1 / expr2.
a = 3
b = 3
a /= b
// Result: a = 1.
plot(a)
Retorno de valorUm número inteiro ou um valor flutuante, ou uma série de valores.
Menor do que. Aplica-se a expressões numéricas.
expr1 < expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
Menor ou igual a. Aplica-se a expressões numéricas.
expr1 <= expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
É igual a. Aplica-se a qualquer tipo de expressão.
expr1 == expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
O operador '=>' é usado para declarar funções definidas pelo usuário eswitch
O que você está fazendo é errado.
A sintaxe da declaração de funções é:
<identifier>([<parameter_name>[=<default_value>]], ...) =>
<local_block>
<function_result>
Um<local_block>
São zero ou mais sentenças Pine.<function_result>
É uma variável, uma expressão ou um elemento.
Exemplos
// single-line function
f1(x, y) => x + y
// multi-line function
f2(x, y) =>
sum = x + y
sumChange = ta.change(sum, 10)
// Function automatically returns the last expression used in it
plot(f1(30, 8) + f2(1, 3))
NotasVocê pode obter mais informações sobre funções definidas pelo usuário na página de funções de declaração e script library do manual do usuário.
Maior que. Aplica-se a expressões numéricas.
expr1 > expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
Maior que ou igual a. Aplica-se à expressão numérica.
expr1 >= expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
O operador de três condições.
expr1 ? expr2 : expr3
Exemplos
// Draw circles at the bars where open crosses close
s2 = ta.cross(open, close) ? math.avg(open,close) : na
plot(s2, style=plot.style_circles, linewidth=2, color=color.red)
// Combination of ?: operators for 'switch'-like logic
c = timeframe.isintraday ? color.red : timeframe.isdaily ? color.green : timeframe.isweekly ? color.blue : color.gray
plot(hl2, color=c)
Retorno de valorSe o expres1 for avaliado como verdadeiro, o expres2 será avaliado como verdadeiro, caso contrário, o expres3 será avaliado como falso. 0 e NaN+, Infinity,-Infinity) são considerados falsos e todos os outros valores são verdadeiros.
NotasSe você não precisar, use na como uma ramificação do
Até logo.
na
Subtítulo da série. O subtítulo fornece acesso aos valores anteriores da série expr1. Expr2 é o número da linha k passada e deve ser um valor. O flutuante será substituto.
expr1[expr2]
Exemplos
// [] can be used to "save" variable value between bars
a = 0.0 // declare `a`
a := a[1] // immediately set current value to the same as previous. `na` in the beginning of history
if high == low // if some condition - change `a` value to another
a := low
plot(a)
Retorno de valorUma série de valores.
Até logo.
math.floor
A lógica AND ─ aplica-se à expressão de Boole ─.
expr1 and expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
A lógica OR↑ aplica-se às expressões de Boole↑
expr1 or expr2
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
A contra-expressão lógica ((NOT) ー aplica-se à expressão de Boole.
not expr1
Retorno de valorO valor de Boole, ou uma série de valores de Boole.
Palavras-chave do tipo "Bool" para variáveis ou parâmetros declarados explicitamente. O valor da variável "Bool" pode ser "true", "false" ou "na".
Exemplos
// bool
bool b = true // Same as `b = true`
b := na
plot(b ? open : close)
NotasÉ opcional mencionar explicitamente o tipo na declaração da variável, a menos que seja initializado com na. Veja mais informações sobre o tipo Pine na página do manual do usuário do sistema de tipos.
Até logo.
var
varip
int
float
color
string
true
false
Palavras-chave do tipo
Exemplos
// int
int i = 14 // Same as `i = 14`
i := na
plot(i)
NotasÉ opcional mencionar explicitamente o tipo na declaração da variável, a menos que seja initializado com na. Veja mais informações sobre o tipo Pine na página do manual do usuário do sistema de tipos.
Até logo.
var
varip
float
bool
color
string
Palavras-chave do tipo float (float) para declaração expressa de variáveis ou parâmetros.
Exemplos
// float
float f = 3.14 // Same as `f = 3.14`
f := na
plot(f)
NotasÉ opcional mencionar explicitamente o tipo na declaração da variável, a menos que seja initializado com na.
Até logo.
var
varip
int
bool
color
string
Palavras-chave do tipo "string" para declaração expressa de variáveis ou parâmetros.
Exemplos
// string
string s = "Hello World!" // Same as `s = "Hello world!"`
// string s = na // same as ""
plot(na, title=s)
NotasÉ opcional mencionar explicitamente o tipo na declaração da variável, a menos que seja initializado com na. Veja mais informações sobre o tipo Pine na página do manual do usuário do sistema de tipos.
Até logo.
var
varip
int
float
bool
str.tostring
str.format
A palavra-chave do tipo "color" usada para declarar explicitamente variáveis ou parâmetros.
Exemplos
// color
color textColor = color.green
if barstate.islastconfirmedhistory
runtime.log("test", textcolor = textColor)
NotasA letra de cor tem o seguinte formato: #RRGGBB ou #RRGGBBAA. As letras representam os valores de 00 a FF em 16 dígitos (de 0 a 255 em 10 dígitos), onde RR, GG e BB são os valores dos componentes vermelho, verde e azul da cor. AA é o valor opcional da transparência de cores (ou componente alfa), onde 00 é invisível e FF é opaco. Quando não há AA, o FF é usado. É opcional mencionar explicitamente o tipo na declaração da variável, a menos que seja initializado com na. Veja mais informações sobre o tipo Pine na página do manual do usuário do sistema de tipos.
Até logo.
var
varip
int
float
string
color.rgb
color.new
Palavras-chave para o tipo de chaves de matrizes de chaves para declarações expressivas de variáveis ou parâmetros; pode ser usadoarray.new<type>
,array.from
A função cria objetos de matriz ((ou ID)).
Exemplos
// array
array<float> a = na
a := array.new<float>(1, close)
plot(array.get(a, 0))
NotasOs objetos da matriz são sempre em forma de matrizes de séries quadradas.
Até logo.
var
array.new
array.from
Os objetos da linguagem PINE são exemplos de tipos definidos pelo usuário (UDT), que podem ser entendidos como classes sem métodos, permitindo que os usuários criem tipos personalizados em políticas para organizar diferentes valores em uma entidade.
Tipo definido
Vamos definir um tipo de ordem para armazenar a informação da ordem:
type order
float price
float amount
string symbol
type
Tipo de declaração de palavras-chave.Criar objetos
Utilize tipos declarados, chamadasnew()
Objeto criado pela função:
order1 = order.new()
order1 = order.new(100, 0.1, "BTC_USDT")
order1 = order.new(amount = 0.1, symbol = "BTC_USDT", price = 100)
A partir daí, você pode criar objetos vazios:
order order1 = na
Aqui está um exemplo prático:
type order
float price
float amount
string symbol
if strategy.position_size == 0 and open > close
strategy.entry("long", strategy.long, 1)
order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
// runtime.log(order1) // 输出 {"data":{"price":46002.8,"amount":1,"symbol":"swap"},"_meta":0,"_type":"order"}
A frase do exemplo:
order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
O texto também pode ser escrito da seguinte forma:
order order1 = na
order1 := order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
Tipo de objeto usado para a palavra-chave var
//@version=5
indicator("Objects using `var` demo")
//@type A custom type to hold index, price, and volume information.
type BarInfo
int index = bar_index
float price = close
float vol = volume
//@variable A `BarInfo` instance whose fields persist through all iterations, starting from the first bar.
var BarInfo firstBar = BarInfo.new()
//@variable A `BarInfo` instance declared on every bar.
BarInfo currentBar = BarInfo.new()
// Plot the `index` fields of both instances to compare the difference.
plot(firstBar.index, "firstBar")
plot(currentBar.index, "currentBar")
Quando a declaração da palavra-chave var é atribuída a uma variável de um objeto de tipo definido pelo usuário, a palavra-chave é automaticamente aplicada a todos os campos desse objeto. Isso significa que os objetos declarados com a palavra-chave var manterão seu estado entre cada iteração, sem a necessidade de reiniciar o valor de seus campos em cada iteração.
Ao traçar os campos de índice dos dois objetos, você pode comparar as diferenças entre eles. firstBar.index manterá o valor previamente definido em cada iteração, enquanto o currentBar.index será reiniciado em cada iteração como o valor bar_index da entrada atual.
Tipos de objetos usados para palavras-chave varip
//@version=5
indicator("Objects using `varip` fields demo")
//@type A custom type that counts the bars and ticks in the script's execution.
type Counter
int bars = 0
varip int ticks = 0
//@variable A `Counter` object whose reference persists throughout all bars.
var Counter counter = Counter.new()
// Add 1 to the `bars` and `ticks` fields. The `ticks` field is not subject to rollback on unconfirmed bars.
counter.bars += 1
counter.ticks += 1
// Plot both fields for comparison.
plot(counter.bars, "Bar counter", color.blue, 3)
plot(counter.ticks, "Tick counter", color.purple, 3)
No Pine, o uso da palavra-chave varip pode indicar que os campos de um objeto continuam a existir durante toda a execução do script, sem rolar em colunas não confirmadas. Na declaração do tipo Counter, o campo bars não usa a palavra-chave varip e, portanto, rola em cada coluna não confirmada; enquanto o campo ticks usa a palavra-chave varip e, portanto, não rola em coluna não confirmada. O objeto counter é declarado com a palavra-chave var e, portanto, continuará a existir durante toda a execução do script. Em cada iteração, o campo de bars e o campo de ticks são adicionados. O campo de bars rola em cada coluna não confirmada, enquanto o campo de ticks não rola. Por fim, é possível comparar as diferenças entre eles através de um desenho dos campos counter.bars e counter.ticks. Os valores de counter.bars serão redirecionados em cada coluna não confirmada, enquanto os valores de counter.ticks continuarão aumentando até o final da execução do script.
Modificar o valor do campo
type order
float price
float amount
string symbol
if strategy.position_size == 0 and open > close
strategy.entry("long", strategy.long, 1)
order1 = order.new(strategy.opentrades.entry_price(strategy.opentrades - 1), strategy.opentrades.size(strategy.opentrades - 1), syminfo.ticker)
if strategy.position_size != 0
runtime.log(order1)
order1.price := 999
order1.amount := 100
runtime.log(order1)
runtime.error("stop")
Pode ser usado:=
O operador de reapropriação muda o valor do campo do objeto.
Conjunto de objetos
O exemplo declara um conjunto de arquivos vazios que irá armazenar objetos com o tipo de ordem definido pelo usuário:
type order
float price
float amount
string symbol
arrOrder = array.new<order>()
order1 = order.new(99, 1, "BTC_USDT")
order2 = order.new(100, 2, "ETH_USDT")
array.push(arrOrder, order1)
array.push(arrOrder, order2)
runtime.log(arrOrder)
runtime.error("stop")
Ou
type order
float price
float amount
string symbol
var array<order> arrOrder = na
arrOrder := array.new<order>()
order1 = order.new(99, 1, "BTC_USDT")
order2 = order.new(100, 2, "ETH_USDT")
array.push(arrOrder, order1)
array.push(arrOrder, order2)
runtime.log(arrOrder)
runtime.error("stop")
Objeto de replicação
No Pine, os objetos são atribuídos por referência. Quando os objetos existentes são atribuídos a novas variáveis, ambos apontam para o mesmo objeto.
//@version=5
indicator("")
type pivotPoint
int x
float y
pivot1 = pivotPoint.new()
pivot1.x := 1000
pivot2 = pivot1
pivot2.x := 2000
// Both plot the value 2000.
plot(pivot1.x)
plot(pivot2.x)
No exemplo abaixo, criamos um objeto pivot1 e definimos seu campo x como 1000. Então, declaramos um pivot2 contendo uma variável que faz referência a esse objeto pivot1, de modo que ambos apontem para o mesmo exemplo. Portanto, mudar o pivot2.x também mudará o pivot1.x, pois ambos fazem referência ao campo x do mesmo objeto.
Para criar cópias independentes do objeto original, nesse caso, podemos usar o método de cópia (//) embutido. Neste exemplo, declaramos que pivot2 refere-se a uma variável de um exemplo de cópia do objeto pivot1. Agora, alterar pivot2.x não altera pivot1.x, pois refere-se a um campo de x como um objeto separado:
//@version=5
indicator("")
type pivotPoint
int x
float y
pivot1 = pivotPoint.new()
pivot1.x := 1000
pivot2 = pivotPoint.copy(pivot1)
pivot2.x := 2000
// Plots 1000 and 2000.
plot(pivot1.x)
plot(pivot2.x)
É importante notar que o método de cópia do TradingView é baseado em uma cópia. Se um objeto tem campos de tipos especiais (array, etc.), esses campos na base do objeto apontam para o mesmo exemplo do objeto. A plataforma FMZ implementa diretamente a cópia profunda sem a necessidade de processamento adicional.
Cópia profunda
//@version=5
indicator("test deepCopy")
type orderInfo
float price
float amount
type labelInfo
orderInfo order
string labelMsg
labelInfo1 = labelInfo.new(orderInfo.new(100, 0.1), "test labelInfo1")
labelInfo2 = labelInfo.copy(labelInfo1)
labelInfo1.labelMsg := "labelInfo1->2" // 修改 labelInfo1 的基础类型字段,看是否影响 labelInfo2
labelInfo1.order.price := 999 // 修改 labelInfo1 的复合类型字段,看是否影响 labelInfo2
runtime.log(labelInfo1)
runtime.log(labelInfo2)
runtime.error("stop")
Resultados do teste, labelInfo.copy ((labelInfo1) é uma cópia profunda quando executada, modificando o labelInfo1 qualquer campo não afetará o labelInfo2.
Os métodos da linguagem Pine são funções especializadas associadas a tipos construídos ou definidos pelo usuário em um determinado exemplo. Em muitos aspectos, eles são basicamente iguais aos tipos de funções convencionais, mas oferecem uma sintaxe mais curta e conveniente. Os usuários podem usar diretamente métodos de acesso com símbolos pontuais em variáveis, como se fossem campos de acesso a objetos Pine. O Pine inclui todos os tipos especiais de métodos construídos, incluindo números de grupo, matrizes, mapeamentos de matrizes, linhas, linhas de preenchimento, etc. Estes métodos fornecem aos usuários uma maneira mais simples de invocar programas específicos desses tipos no script.
Método embutido
Por exemplo, um trecho de código do script que diz:
//@version=5
indicator("Custom Sample BB", overlay = true)
float sourceInput = input.source(close, "Source")
int samplesInput = input.int(20, "Samples")
int n = input.int(10, "Bars")
float multiplier = input.float(2.0, "StdDev")
var array<float> sourceArray = array.new<float>(samplesInput)
var float sampleMean = na
var float sampleDev = na
// Identify if `n` bars have passed.
if bar_index % n == 0
// Update the queue.
array.push(sourceArray, sourceInput)
array.shift(sourceArray)
// Update the mean and standard deviaiton values.
sampleMean := array.avg(sourceArray)
sampleDev := array.stdev(sourceArray) * multiplier
// Calculate bands.
float highBand = sampleMean + sampleDev
float lowBand = sampleMean - sampleDev
plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)
O equivalente pode ser traduzido como:
//@version=5
indicator("Custom Sample BB", overlay = true)
float sourceInput = input.source(close, "Source")
int samplesInput = input.int(20, "Samples")
int n = input.int(10, "Bars")
float multiplier = input.float(2.0, "StdDev")
var array<float> sourceArray = array.new<float>(samplesInput)
var float sampleMean = na
var float sampleDev = na
// Identify if `n` bars have passed.
if bar_index % n == 0
// Update the queue.
sourceArray.push(sourceInput)
sourceArray.shift()
// Update the mean and standard deviaiton values.
sampleMean := sourceArray.avg()
sampleDev := sourceArray.stdev() * multiplier
// Calculate band values.
float highBand = sampleMean + sampleDev
float lowBand = sampleMean - sampleDev
plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)
Como pode ver, o PINE está a apoiá-lo.Methods
Depois, o códigoarray.avg(sourceArray)
O usuário pode escrever o formulário "Methods" da forma:sourceArray.avg()
Não, não.
Nota: FMZ não está disponível.array.avg
O que é que ele está a fazer?
Métodos definidos pelo usuário
O Pine permite que o usuário defina métodos personalizados para uso junto com qualquer objeto de tipo construído ou definido pelo usuário. Os métodos de definição são essencialmente os mesmos que as funções de definição, mas com duas diferenças fundamentais:
O método deve estar antes do nome da função. 2, o parâmetro do método, onde o tipo do primeiro parâmetro deve ser declarado explicitamente, pois indica o tipo do objeto ao qual o método será associado.
Por exemplo, o código para o cálculo do indicador de Brin pode ser envelopado como um método personalizado pelo usuário:
//@version=5
indicator("Custom Sample BB", overlay = true)
float sourceInput = input.source(close, "Source")
int samplesInput = input.int(20, "Samples")
int n = input.int(10, "Bars")
float multiplier = input.float(2.0, "StdDev")
var array<float> sourceArray = array.new<float>(samplesInput)
var float sampleMean = na
var float sampleDev = na
// Identify if `n` bars have passed.
if bar_index % n == 0
// Update the queue.
sourceArray.push(sourceInput)
sourceArray.shift()
// Update the mean and standard deviaiton values.
sampleMean := sourceArray.avg()
sampleDev := sourceArray.stdev() * multiplier
// Calculate band values.
float highBand = sampleMean + sampleDev
float lowBand = sampleMean - sampleDev
plot(sampleMean, "Basis", color.orange)
plot(highBand, "Upper", color.lime)
plot(lowBand, "Lower", color.red)
Tradução:
//@version=5
indicator("Custom Sample BB", overlay = true)
float sourceInput = input.source(close, "Source")
int samplesInput = input.int(20, "Samples")
int n = input.int(10, "Bars")
float multiplier = input.float(2.0, "StdDev")
var array<float> sour
- O que?Como é que é possível que um contrato Bitcoin seja executado simultaneamente em várias transações?
Nuvens levesPor favor, diga-me, o pine pode fazer mais transações, certo?
Lisa20231Obrigado pela documentação detalhada
arteComo é que o script do pine pode usar o simulador do okex na plataforma?
arteIsso equivale a que a estratégia da plataforma tradingview seja copiada diretamente para a plataforma do inventor para ser usada!
Inventor quantificado - sonho pequenoA linguagem PINE só pode executar uma política de variedade única, a política de variedades múltiplas é melhor ou escrever projetos em Python, JavaScript, C++.
Inventor quantificado - sonho pequenoOh, sim, OKX é muito especial, eles têm o mesmo endereço do ambiente analógico e do ambiente real, mas fazem a diferença em outro lugar.
Nuvens levesNão é possível usar o simulador okx............
Inventor quantificado - sonho pequenoEste problema de arquitetura variada não é resolvido, pois cada interface é diferente e a restrição de freqüência de interface não é diferente, o que pode gerar muitos problemas.
Inventor quantificado - sonho pequenoMuito bem, obrigada pela sugestão do Cloudways, por favor, informe a necessidade aqui.
Nuvens levesO JS pode ser melhor adaptado a diferentes maneiras de transação.
Caçadores de tendênciasO preço de fechamento é para cada variedade.
Inventor quantificado - sonho pequenoNão é cortês.
Nuvens levesMuito bem, obrigada.
Inventor quantificado - sonho pequenoOlá, a estratégia de linguagem do PINE é temporária e só pode fazer uma variedade.
Inventor quantificado - sonho pequenoNão tem graça, obrigado pelo seu apoio. A documentação continuará sendo aperfeiçoada.
Inventor quantificado - sonho pequenoSim, eu sei.
Inventor quantificado - sonho pequenoA biblioteca de modelos de linguagem PINE, em que os parâmetros podem ser definidos para alterar o endereço de base do exchange.