Me aparece el error "No se puede crear una orden con una cantidad negativa".

Este error aparece si la equidad de la estrategia se vuelve negativa y el número total de contratos calculado para las funciones strategy.entry() o strategy.order() es un valor entero negativo (qty <0). Se puede evitar ajustando la configuración de la estrategia desde el menú Propiedades o cambiando directamente la lógica de la estrategia.

Fuente del error

Veamos el script en el que la cantidad de la orden se calcula como un porcentaje de la equidad, ya sea a través de la configuración del tamaño de la orden en la configuración de la estrategia, o a través de la constante strategy_percent_of_equity en la fuente Pine de la estrategia. En cada vela, se llama a la función strategy.entry() para introducir la posición:

//@version=5
strategy("negative_qty", default_qty_type = strategy.percent_of_equity)

strategy.entry("Short", strategy.short)
plot(strategy.equity)

Al añadir el script a un gráfico de NASDAQ:AAPL para el marco temporal 1D, el script se bloquea con un error de ejecución:

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

Para entender la razón de este error, debe graficar el capital utilizando la variable strategy.equity y añadiendo una restricción en la llamada a la función strategy.entry() utilizando cualquier operador de condición. De esa manera, la función para entrar en una posición no se llamará en cada vela (y no causará un recálculo adicional de los parámetros, incluyendo el valor de qty) y el script se calculará con éxito:

//@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) 

En la apertura de la segunda vela (bar_index = 1), la estrategia entra en una posición corta. Pero con el crecimiento del valor de AAPL, el beneficio (el valor de la variable strategy.openprofit) de la posición Short abierta cae en picado, y al final el capital de la estrategia (strategy.initial_capital + strategy.netprofit + strategy.openprofit) se vuelve negativo.

El número de contratos calculado por el motor de la estrategia se calcula como qty = (order size * equity / 100) / close. El área en la que el capital de la estrategia se convierte en valores negativos se puede mostrar de la siguiente manera:

//@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)

La captura de pantalla muestra la etiqueta situada en la sección de equidad negativa, donde el número de contratos resultante es - 2. El número de contratos en la sección verde es >= 0:

Si al calcular una estrategia, se llama a strategy.entry()en una vela con equidad negativa (y en la que el número de contratos es negativo), el cálculo de la estrategia se detiene con un error.

¿Cómo puedo solucionar esto?

Por norma general, este error no suele aparece en una estrategia correctamente implementada. Para evitar errores, la estrategia debe utilizar condiciones de entrada y salida de una posición, stops y margen.

Si se produce un error, los métodos correctos para depurar la estrategia son:

1. Using margin leverage (Margin For Long/Short positions in the Properties of the strategy or margin_long and margin_short parameters in the strategy() function). If specified, a part of a position will be automatically liquidated if the strategy does not have enough equity to maintain it. You can find out more about this functionality in the article in our User Manual or in a blog post.

1. Utilizar el margen de apalancamiento (Margen para posiciones largas/cortas en las Propiedades de la estrategia o los parámetros margin_long y margin_short en la función strategy(). Si se especifica, una parte de una posición se liquidará automáticamente si la estrategia no tiene suficiente capital para mantenerla. Puede encontrar más información sobre esta funcionalidad en el artículo de nuestro Manual de Usuario o en nuestra entrada del 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. Comprobar el valor de la equidad para ver si es superior a cero antes de llamar a las funciones strategy.entry() o strategy.order() o redefinir adicionalmente el 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. Utilizando las variables de la categoría strategy.risk para la gestión del riesgo. Puede leer más sobre esto en nuestro Manual de Usuario.