No capítulo sobre cruzamentos, o indicador desenhava sinais nos cruzamentos das médias. Agora você vai usar o mesmo evento para disparar uma ordem simulada. O programa abre uma posição de compra no cruzamento para cima e a encerra no cruzamento para baixo.

O que faz uma estratégia?

Um indicador calcula e exibe resultados. Além disso, uma estratégia envia ordens ao simulador de backtest. Com base nos candles históricos e nas regras definidas, o simulador acompanha ordens, posições e resultados.

Chamamos esse teste histórico de backtest. Neste capítulo, todas as ordens são simuladas; iniciar Run Pyne code não envia ordens para uma conta de trading real.

Uma posição é a exposição existente depois de uma entrada executada. A ordem é a instrução; a execução é o evento que cria ou altera a posição. Não usamos esses três termos como sinônimos.

Primeiro, escreva as regras em palavras

As regras da estratégia atual:

  • Calcula SMAs de cinco e vinte em todos os candles.
  • No cruzamento para cima, envia uma ordem de entrada comprada de uma unidade.
  • No cruzamento para baixo, encerra a posição associada à entrada de identificador Long.
  • O cálculo usa os dados dos candles históricos encerrados.

Uma posição comprada, ou long, ganha valor quando o preço sobe e perde valor quando ele cai. Neste exemplo, não abrimos posições vendidas, ou short.

A regra não afirma que todo cruzamento para cima é lucrativo. O backtest serve justamente para verificar o que teria acontecido nesses dados com essas operações.

O programa completo

Crie o arquivo crossover_strategy.py:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta


@script.strategy(
    "Average Crossing Strategy",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    if crosses_up:
        strategy.entry("Long", strategy.long)
    if crosses_down:
        strategy.close("Long")
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

@script.strategy indica que main() é uma estratégia. Os cálculos e as duas linhas continuam disponíveis como antes. A nova importação é o namespace strategy, que contém as operações de ordens e os dados da estratégia.

O decorador é uma chamada com várias linhas. Suas configurações controlam a execução da estratégia; os parâmetros de main() são as entradas dos nossos cálculos.

Capital inicial e quantidade

initial_capital=10000 define o saldo inicial da simulação. Os metadados de mercado dos dados de demonstração determinam as unidades e os níveis de preço usados na execução.

default_qty_type=strategy.fixed significa quantidade fixa. default_qty_value=1 solicita uma ordem de uma unidade. Isso não significa um por cento do capital, nem necessariamente uma unidade monetária.

pyramiding=1 permite no máximo uma entrada na mesma direção. O exemplo não aumenta uma posição existente com novas entradas compradas.

Durante o aprendizado, acompanhamos as operações com uma quantidade pequena e fixa. Assim, ao examinar mudanças nos resultados, há menos fatores de dimensionamento diferentes a considerar ao mesmo tempo.

Os nomes da entrada e do encerramento

O primeiro argumento de strategy.entry("Long", strategy.long) é um identificador de ordem. O programa escolhe o texto Long; o segundo argumento determina a direção.

strategy.close("Long") se refere ao mesmo identificador. Os nomes precisam coincidir. Se você entrar com o identificador "Buy", encerrar "Long" não terá essa entrada como alvo.

Aqui, o cruzamento para baixo encerra uma posição; não abre uma posição vendida. Se não houver uma posição aberta associada ao nome, não há o que encerrar.

Execute no PyneIDE

  1. Salve o programa completo.
  2. Escolha Run Pyne code e os dados demo.
  3. No gráfico, confira as duas linhas de SMA e as marcações das operações.
  4. Abra o painel abaixo do gráfico e escolha a aba Trades.
Ao lado de crossover_strategy.py, aparecem duas linhas de SMA e as marcações de entrada e saída da estratégia.
Os cruzamentos das SMAs geram ordens; as operações executadas também aparecem no gráfico.

Se nenhuma operação aparecer, confira se você executou o arquivo da estratégia e se a marcação @script.strategy foi mantida. Confira também os valores efetivos dos dois inputs. SMAs de mesmo comprimento, calculadas com a mesma fonte, não se cruzam.

O instante do sinal e o da execução

Na configuração padrão usada aqui, o programa envia uma ordem a mercado com base nos dados de fechamento do candle. A ordem costuma ser executada na abertura do próximo candle. Por isso, o candle do sinal e o da entrada podem ser diferentes.

O mesmo vale para o encerramento a mercado. A ordem de encerramento criada no cruzamento para baixo pode fechar a posição na próxima abertura.

Se o último candle gerar uma nova ordem, não há um próximo candle no arquivo. Por isso, a ordem pode não ser executada. Uma posição aberta anteriormente também pode continuar aberta no fim dos dados.

O modo de execução das ordens faz parte das configurações. No próximo capítulo, vamos examiná-lo também na tela Properties. Interprete cada resultado com o mesmo modo de execução usado para produzi-lo.

Do sinal à execuçãoNas configurações padrão do exemplo, a estratégia cria uma ordem a mercado no fechamento da vela. Ela é executada na abertura da próxima vela, a um preço que pode ser diferente do preço do sinal. close → strategy.entry → open. process_orders_on_close = False.Vela do sinalPróxima velaOrdem pendenteFechamento: sinale ordem a mercadoPróxima abertura:execuçãoprocess_orders_on_close = False
Do sinal à execuçãoNas configurações padrão do exemplo, a estratégia cria uma ordem a mercado no fechamento da vela. Ela é executada na abertura da próxima vela, a um preço que pode ser diferente do preço do sinal.

Tente por conta própria

Abra os inputs da estratégia e defina os comprimentos rápido e lento como 20. Faça duas previsões: como ficarão as linhas e quantos cruzamentos poderão gerar operações?

Solução do exercício

As duas SMAs usam os mesmos preços e o mesmo tamanho de janela, por isso coincidem. Não há um candle em que uma passe para cima ou para baixo da outra. Essa regra não abre nenhuma operação na estratégia.

O gráfico existente só mostra esse resultado depois que você salva os inputs modificados e o recálculo termina. Depois da verificação, restaure os valores 5 e 20.

Escolha uma entrada

Encontre uma entrada executada e examine as duas médias no candle anterior. O cruzamento para cima deve ocorrer no candle do sinal. Compare o preço da operação com a abertura do candle da entrada, sem presumir que seja igual ao fechamento do sinal.