O recurso está a ser carregado... Carregamento...

Se não sabes escrever uma estratégia numa linguagem tão fácil de aprender e de usar...

Autora:FMZ~Lydia, Criado: 2023-02-16 14:55:00, Atualizado: 2023-09-18 20:18:52

img

Se não sabes escrever uma estratégia numa linguagem tão fácil de aprender e de usar...

O número de estratégias de código aberto no TradingView é grande. É uma pena que tantas estratégias, ideias e indicadores excelentes não possam ser usados em bot real. Vendo isso, a FMZ, que está comprometida em popularizar a tecnologia de negociação quantitativa para muitos comerciantes, naturalmente não pode suprimir esse desejo de resolver o problema!

Esta partilha de experiências é absolutamente a oferecer!

Então, depois de caminhar pelo mundo da programação e desenvolvimento de código, passando por 9 * 9 = 81 poços, sobrevivendo a inúmeras noites sem dormir, e empilhando uma montanha de latas vazias de Red Bull no canto.

Quando se trata da linguagem Pine, eu só recentemente aprendi sozinho. Mas para ser honesto, a linguagem Pine para negociação quantitativa é realmente fácil de usar e fácil de aprender. Deixe-me escrever uma estratégia de rede 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="Spacing prices")
var dir = input.string("long", title="Directions", options = ["long", "short", "both"])
var amount = input.float(-1, title="Order quantity")
var numbers = input.int(-1, title="Number of grids")
var profit = input.int(-1, title="Profit spreads") / syminfo.mintick

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("Parameter errors")

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 

// Real-time K-line stage
if not barstate.ishistory
    // Retrieve grid
    for i = 1 to numbers
        // Going long
        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)
        // Going short
        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)

O FMZ é um bot real, ferramentas de backtesting e inúmeras funções combinadas com a simplicidade da linguagem Pine são um ótimo complemento! Incluindo a configuração de parâmetros e o código de configuração de backtesting, o código total é inferior a 50 linhas.

É claro que esta estratégia é uma estratégia de grade, que também tem falhas, e não é uma máquina de impressão de dinheiro que sempre ganha. A chave depende do uso e parâmetros. Vamos nos concentrar mais em como escrever estratégias facilmente para implementar nossa própria lógica de negociação, e ganhar dinheiro escrevendo estratégias e negociando nós mesmos. É tão legal não pedir ajuda!

Explicação do código

Eu vou explicar a todos, o código é simples e fácil de entender, com uma linguagem tão fácil de aprender e usar Pine, se você ainda não sabe escrever uma estratégia, então eu vou... dizer-lhe em detalhes!

O conteúdo do/*backteste*/no início está o código de configuração de backtest de FMZ. Esta é a função de FMZ, não o conteúdo da linguagem Pine. Claro, você pode deixar esta parte fora, e você vai clicar no controle de parâmetros manualmente para definir a configuração de backtest e parâmetros durante o backtesting.

/*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 próximo código:

strategy(overlay=true)

varip beginPrice = 0
var spacing = input.float(-1, title="Spacing prices")
var dir = input.string("long", title="Directions", options = ["long", "short", "both"])
var amount = input.float(-1, title="Order quantity")
var numbers = input.int(-1, title="Number of grids")
var profit = input.int(-1, title="Profit points") / syminfo.mintick
  • strategy(overlay=true): É usado para definir algumas opções do script, overlay=true, que é atribuir valor verdadeiro ao parâmetrooverlay, de modo que ao desenhar o gráfico, ele é desenhado no gráfico principal (K-line chart é o gráfico principal, pode ser entendido tão simplesmente).
  • varip beginPrice = 0: Uma variável beginPrice é declarada com a palavra-chave varip com um valor inicial de 0, que é utilizado como preço inicial para a grade.
  • var spacing = input.float(-1, title="Spacing prices"): Configure um parâmetro de estratégia, o nome do parâmetro é preço de espaçamento, que é o espaçamento de cada ponto da grade, definindo 100 significa que o preço será negociado uma vez a cada 100.
  • var dir = input.string("long", title="Directions", options = ["long", "short", "both"]): Configure um parâmetro de estratégia chamado direction, este parâmetro é uma caixa suspensa com opções long, short e ambos, o que significa que a grade é longa apenas, curta apenas e ambos, respectivamente.
  • var amount = input.float(-1, title="Order quantity"): Definir um parâmetro para controlar o volume de transacções em cada transacção de ponto de rede.
  • var numbers = input.int(-1, title="Number of grids"): o número de pontos da grade, definindo 20 é 20 pontos da grade em uma direção.
  • var profit = input.int(-1, title="Profit spreads") / syminfo.mintick: Definir um parâmetro para controlar a margem de lucro de cada posição de ponto de rede antes de fechar a posição.

Em seguida, olhem para o código:

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("Parameter errors")

Significa que se quaisquer parâmetros como espaçamento, quantidade, números e lucro não forem definidos, o padrão é -1, e a estratégia vai parar (você não pode operar cegamente sem definir parâmetros)

Vamos, vamos!

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

O que isso significa aqui é que quando a estratégia está no estágio de linha K em tempo real e startPrice == 0, mude o valor de startPrice para o último preço atual. Pode-se entender que quando a estratégia está sendo executada oficialmente, o preço atual inicial é o preço inicial da grade. Como o script tem um estágio histórico de BAR da linha K, a estratégia executará a lógica uma vez no estágio histórico de BAR, e definitivamente não faz sentido organizar a grade no BAR histórico.

Qual é a fase histórica do BAR?

Para dar um exemplo simples, no momento atual A, a estratégia começa a ser executada, e a estratégia obtém dados com 100 K-line BARs. Com o passar do tempo, 100 BARs se tornarão 101, 102...N. Quando começa a ser executado a partir do momento A, o 101o BAR é o estágio da linha K em tempo real, e este tempo é os dados mais recentes em tempo real.

barstate.ishistoryesta é uma variável embutida na linguagem Pine,barstate.ishistoryé verdade se o BAR atual é um BAR histórico, e falso se não for um BAR histórico.

Em seguida, uma função é criada

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 

O papel desta função é descobrir se uma determinada id existe em todas as ordens que atualmente abriram uma posição. Se houver uma chamada da função findTradeId, ela retornará a ID da ordem existente (note que esta ID não é a ID da ordem da bolsa, é o nome dado à ordem pela estratégia ou entendido como um rótulo), se não existir, a cadeia notFound é devolvida.

O próximo passo é iniciar a folha da grade:

// Real-time K-line stage
if not barstate.ishistory
    // Retrieve grid
    for i = 1 to numbers
        // Going long
        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)
        // Going short
        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)

O loop for é usado, e o número de loops é determinado de acordo com o valor do parâmetro números, ou seja, o número correspondente de ordens são organizadas. 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 da grade atual foi aberta, e apenas coloque a ordem planejada se não houver posição aberta (se a posição estiver aberta, não pode ser repetida). Para colocar uma ordem, use a função strategy.order para especificar o parâmetro limite como uma ordem planejada. Coloque a ordem de fechamento correspondente enquanto coloca a ordem planejada. A ordem de fechamento usa ostrategy.exitFunção, especifica o parâmetro de lucro e especifica os pontos de lucro.

img

img

Olhando para a curva de lucro, podemos ver que a rede também é arriscada. Não é uma vitória garantida. É apenas que o risco de expandir a rede em grande escala é um pouco menor.

Bem, se não sabes escrever uma estratégia numa linguagem tão fácil de aprender e usar, então eu...


Relacionados

Mais.