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.