avatar of 发明者量化-小小梦 发明者量化-小小梦
focar em Mensagem privada
4
focar em
1271
Seguidores

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu...

Criado em: 2022-06-01 17:37:55, atualizado em: 2023-09-18 20:19:45
comments   6
hits   2992

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Há um número esmagador de estratégias de código aberto no TradingView. É uma pena que tantas estratégias, ideias e indicadores excelentes não possam ser colocados em prática. Vendo isso, a FMZ, que está comprometida em popularizar a tecnologia de negociação quantitativa para muitos traders, naturalmente não consegue suprimir a vontade de resolver essa demanda!

Essa demanda é absolutamente insuportável!

Então, no mundo do código de programação, viajei por montanhas e rios e experimentei 9*9=81 pit, depois de suportar inúmeras noites sem dormir, uma montanha de latas vazias de Red Bull se amontoou no canto. Por fim, o FMZ suporta e é compatível com a linguagem Pine, e vários scripts Pine do TradingView podem ser usados.

Falando da língua Pine, eu só a aprendi recentemente. Mas, para ser honesto, a linguagem Pine para negociação quantitativa é realmente simples, fácil de usar e fácil de aprender. O que? Não acredita? Olhe para mim escrevendo uma estratégia de grade para você~

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利价差") / syminfo.mintick

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

A negociação em tempo real, as ferramentas de backtesting, as inúmeras funções e a facilidade de uso da linguagem Pine da FMZ são como adicionar asas a um tigre! Incluindo configurações de parâmetros e códigos de configuração de backtest, o número total de códigos não excede 50 linhas. Iniciantes não precisam mais se preocupar em escrever uma grade…

Claro, essa estratégia é uma estratégia de grade. Estratégias de grade também têm suas falhas, e não é uma máquina de impressão de dinheiro garantida. A chave está em seu uso e parâmetros. Não vou elaborar sobre esse ponto. Vamos focar mais em como escrever estratégias facilmente, implementar sua própria lógica de negociação e ganhar dinheiro escrevendo suas próprias estratégias. É tão bom sem pedir ajuda a ninguém! !

Explicação do código

Deixe-me explicar a você, o código é simples e fácil de entender. Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu vou… ……… …………………….Deixe-me contar em detalhes!

No começo/*backteste*/O conteúdo encapsulado é o código de configuração do backtest FMZ, que é a função do FMZ, não o conteúdo da linguagem Pine. Claro, você pode escolher não escrever esta parte. Ao fazer backtesting, você precisará clicar manualmente nos controles de parâmetros para definir a configuração e os parâmetros do backtest.

/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/

O código a seguir:

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="间距价格")
var dir = input.string("long", title="方向", options = ["long", "short", "both"])
var amount = input.float(-1, title="下单量")
var numbers = input.int(-1, title="网格数量")
var profit = input.int(-1, title="盈利点数") / syminfo.mintick
  • strategy(overlay=true): Usado para definir algumas opções do script, overlay=true, que é para fornecer parâmetrosoverlayAtribua um valor true para desenhar a imagem na imagem principal do gráfico (o gráfico de linhas K é a imagem principal, pode ser entendido tão simples quanto isto).
  • varip beginPrice = 0: Uma variável beginPrice é declarada usando a palavra-chave varip e recebe inicialmente um valor de 0, que é usado como o preço inicial da grade.
  • var spacing = input.float(-1, title="间距价格"): Defina um parâmetro de estratégia. O nome do parâmetro é “interval price”, que é o intervalo entre cada ponto da grade. Se for definido como 100, significa que uma transação será feita toda vez que o preço exceder 100.
  • var dir = input.string("long", title="方向", options = ["long", "short", "both"]): Um parâmetro de estratégia é definido, chamado “direction”. Este parâmetro é uma opção com uma caixa suspensa, e você pode escolher long, short ou ambos. Eles indicam respectivamente que a grade só negocia longo, só negocia curto ou negocia longo e curto.
  • var amount = input.float(-1, title="下单量"): Defina um parâmetro para controlar o volume de transações em cada transação de ponto de grade.
  • var numbers = input.int(-1, title="网格数量"): O número de pontos de grade. Definir como 20 significa que há 20 pontos de grade em uma direção.
  • var profit = input.int(-1, title="盈利价差") / syminfo.mintick: Defina um parâmetro para controlar a diferença de preço na qual a posição em cada ponto da grade será fechada.

Em seguida, observe o código:

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("参数错误")

Isso significa que se algum dos parâmetros, como espaçamento, quantidade, números e lucro, não for definido, o valor padrão é -1, o que significa que a estratégia será interrompida (você não pode correr sem definir parâmetros ~ haha!)

Go on !

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

O que isto significa é que quando a estratégia estiver no estágio K-line em tempo real e beginPrice == 0, modifique o valor de beginPrice para o preço mais recente atual. Pode-se entender que quando a estratégia está oficialmente em execução, o preço atual inicial é o preço inicial da rede. Como o script tem um estágio BAR histórico de K-line, a estratégia executará a lógica no estágio BAR histórico. Definitivamente não faz sentido organizar a grade no BAR histórico.

O que é a fase BAR histórica?

Para dar um exemplo simples, no momento atual A, a estratégia começa a rodar, e a estratégia obtém dados com 100 BARs de linha K. Com o passar do tempo, os 100 BARs definitivamente se tornarão 101, 102… N. Ao executar a partir do tempo A, a 101ª BARRA é o estágio da linha K em tempo real, que são os dados mais recentes em tempo real. Então, do 1º BAR ao 100º BAR, essas são todas condições históricas de mercado que já passaram, mas a estratégia também será executada nessas condições históricas de mercado, então esse estágio é o estágio histórico da linha K.

barstate.ishistoryEsta é uma variável interna da linguagem Pine. Se o BAR atual for um BAR histórico,barstate.ishistorySe não for um BAR histórico, é falso. Portanto, quando not barstate.ishistory é verdadeiro, ele está no estágio K-line em tempo real.

Em seguida, criamos uma função

findTradeId(id) =>
    ret = "notFound"
    for i = 0 to strategy.opentrades - 1
        if strategy.opentrades.entry_id(i) == id 
            ret := strategy.opentrades.entry_id(i)
    ret 

A função desta função é descobrir se um determinado ID existe em todas as ordens abertas no momento. Se existir, a função findTradeId retornará o ID da ordem existente quando for chamada (observe que este ID não é o ID da ordem de a troca, mas o ID atribuído à ordem pela estratégia). , ou interpretado como um rótulo), se não existir, retorna a string “notFound”.

Em seguida, iniciamos a planilha de malha:

// 实时K线阶段
if not barstate.ishistory
    // 检索网格
    for i = 1 to numbers
        // 做多
        direction = dir == "both" ? "long" : dir 
        plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
        if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.long,  qty=amount, limit=beginPrice-i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
        // 做空
        direction := dir == "both" ? "short" : dir 
        plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
        if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
            strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
            strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)

Um loop for é usado para determinar o número de loops com base no valor do parâmetro numbers, ou seja, para organizar o número correspondente de ordens. Defina a direção de acordo com o parâmetro dir. Use a função findTradeId para descobrir se a ordem do rótulo na posição atual da grade foi aberta. Somente coloque uma ordem planejada se ela não tiver sido aberta (se tiver sido aberta, você não pode colocar uma ordem duplicada). Ao fazer um pedido, use a função strategy.order para especificar o parâmetro limit para fazer um pedido de plano. Coloque a ordem de fechamento correspondente ao mesmo tempo em que coloca a ordem do plano. Para fechar uma posição, use a função strategy.exit, especifique o parâmetro de lucro e especifique os pontos de lucro.

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…

Olhando apenas para a curva de rendimento, você pode ver que a grade também tem riscos e não é uma vitória garantida. Só que o risco é relativamente menor quando a grade é ampliada em larga escala.

Bem, se você ainda não consegue escrever estratégias usando a linguagem Pine, fácil de aprender e usar, então eu…