Vejo o erro 'Cannot create an order with negative quantity'

Este erro aparece se o equity da estratégia se tornar negativo e o número total de contratos calculados para as funções  strategy.entry()  ou  strategy.order()  for um valor inteiro negativo (qtd <0). Isso pode ser evitado ajustando as configurações da estratégia no menu Propriedades ou alterando diretamente a lógica da estratégia.

Origem do erro

Vamos dar uma olhada no script em que a quantidade do pedido é calculada como uma porcentagem do patrimônio, seja por meio da configuração Tamanho do pedido nas configurações da estratégia ou por meio da constante  strategy_percent_of_equity  na fonte Pine da estratégia. Em cada barra, a função strategy.entry() é chamada para inserir a posição:

//@version=5 
strategy("negative_qty", default_qty_type = strategy.percent_of_equity) 
strategy.entry("Short", strategy.short) plot(strategy.equity)

Ao adicionar o script a um gráfico NASDAQ:AAPL para o período 1D, o script trava com um erro de tempo de execução:Ao adicionar o script a um gráfico NASDAQ:AAPL para o 1D timeframe, o script trava com um erro de tempo de execução:

Cannot create an order with negative quantity. Current qty_type is percent_of_equity and equity is less than 0

Para entender o motivo desse erro, você deve plotar o capital usando a variável strategy.equity  e adicionar uma restrição na chamada da função strategy.entry() usando qualquer operador de condição. Dessa forma, a função para inserir uma posição não será chamada em cada barra (e não causará recálculo adicional de parâmetros, incluindo o valor qty) e o script será calculado com sucesso:

//@version=5 strategy("negative_qty", default_qty_type = strategy.percent_of_equity) 
if strategy.equity > 0     strategy.entry("Short", strategy.short) 
hline(0, "zero line", color = color.black, linestyle = hline.style_dashed) plot(strategy.equity, color = color.black, linewidth = 3) 

Na abertura da segunda barra (bar_index = 1), a estratégia entra em uma posição curta. Mas com o crescimento do valor da AAPL, o lucro (o valor da variável strategy.openprofit) da posição curta aberta despenca e, no final, o capital da estratégia (strategy.equity = strategy.initial_capital + strategy.netprofit + strategy.openprofit) torna-se negativo.

O número de contratos calculado pelo mecanismo de estratégia é calculado como qty = (tamanho do pedido * patrimônio / 100) / fechamento. A área onde o capital da estratégia se transforma em valores negativos pode ser exibida da seguinte forma:

//@version=5 strategy("negative_qty", default_qty_type = strategy.percent_of_equity) 
if strategy.equity > 0     strategy.entry("Short", strategy.short) 
hline(0, "zero line", color = color.black, linestyle = hline.style_dashed) plot(strategy.equity, color = color.black, linewidth = 3)  equity_p = 1  // percents of equity  order size value (1% is default) qty = (equity_p * strategy.equity / 100) / close  if qty <= -1     var l1  = label.new(bar_index, strategy.equity, text = "Negative qty_value at \n bar index: " + str.tostring(bar_index) + ".\n" +  "Order size: " + str.tostring(math.round(qty)), color = color.white)     var l2 = label.new(bar_index - 1, strategy.equity[1], text = "Order size : " + str.tostring(math.round(qty[1])), color = color.white)    var l3 = label.new(bar_index - 2, strategy.equity[2], text = "Order size: " + str.tostring(math.round(qty[2])), color = color.white)    bgcolor(qty > -1 ? color.green : color.red)

A figura abaixo mostra o rótulo localizado na seção de patrimônio líquido negativo, onde o número resultante de contratos é - 2. O número de contratos na seção verde é >= 0:

Se, ao calcular uma estratégia, strategy.entry() for chamado em uma barra com patrimônio líquido negativo (e na qual o número de contratos for negativo), o cálculo da estratégia será interrompido com um erro.

Como faço para corrigir isso?

Como regra, esse erro não aparece em uma estratégia implementada corretamente. Para evitar erros, a estratégia deve usar condições para entrar e sair de uma posição, paradas e margem.

Se ocorrer um erro, os métodos corretos para depurar a estratégia são:

1. Usando a alavancagem de margem (Margem para posições Long/Short nas Propriedades da estratégia ou parâmetros margin_long e margin_short na função strategy()). Se especificado, uma parte de uma posição será automaticamente liquidada se a estratégia não tiver patrimônio suficiente para mantê-la. Você pode descobrir mais sobre essa funcionalidade no artigo em nosso  Manual do Usuário do usuário ou em uma postagem no blog.

//@version=5 strategy("", default_qty_type = strategy.percent_of_equity, default_qty_value = 10, margin_long = 100, margin_short = 100) 
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28)) if (longCondition)    strategy.entry("Long", strategy.long) 
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28)) if (shortCondition)    strategy.entry("Short", strategy.short)

2. Verificar o valor patrimonial para ver se está acima de zero antes de chamar as funções strategy.entry() ou strategy.order() ou redefinir adicionalmente o número de contratos de entrada. 

//@version=5 strategy("", default_qty_type = strategy.percent_of_equity, default_qty_value = 10) 
if strategy.equity > 0     strategy.entry("Short", strategy.short)  // enter at 10 % of currently available equity else     strategy.entry("Long", strategy.long, qty = 1) // Reverse position with fixed contract size

3. Utilização de variáveis da categoria strategy.risk  para gestão de riscos. Você pode ler mais sobre isso em nosso Manual do Usuário.