I see 'Cannot create an order with negative quantity' error

This error appears if the strategy equity becomes negative and the total number of contracts calculated for the strategy.entry() or strategy.order() functions is a negative integer value (qty <0). It can be avoided by tweaking the strategy settings from the Properties menu or by directly changing the logic of the strategy.

Source of the error

Let’s take a look at the script where the order quantity is calculated as a percentage of equity, either through the Order Size setting in the strategy settings, or via the strategy_percent_of_equity constant in the Pine source of the strategy. On each bar, the strategy.entry() function is called to enter the position:

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

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

When adding the script to a NASDAQ:AAPL chart for 1D timeframe, the script crashes with a runtime error:

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

To understand the reason for this error, you should plot the capital using the strategy.equity variable and add a constraint on the call to the strategy.equity() function using any condition operator. That way, the function for entering a position will not be called on each bar (and will not cause additional recalculation of parameters, including the qty value) and the script will be calculated successfully:

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

At the opening of the second bar (bar_index = 1), the strategy enters a short position. But with the growth of the AAPL value, the profit (the value of the strategy.openprofit variable) from the open short position Short plummets, and in the end the capital of the strategy (strategy.equity = strategy.initial_capital + strategy.netprofit + strategy.openprofit) becomes negative.

The number of contracts calculated by the strategy engine is calculated as qty = (order size * equity / 100) / close. The area where the strategy capital turns into negative values can be displayed as follows:

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

The screenshot shows the label located on the negative equity section, where the resulting number of contracts is - 2. The number of contracts on the green section is >= 0:

If, when calculating a strategy, strategy.entry() is called on a bar with negative equity (and on which the number of contracts is negative), the calculation of the strategy stops with an error.

How do I fix this?

As a rule, this error does not appear in a correctly implemented strategy. To avoid mistakes, the strategy should use conditions for entering and exiting a position, stops, and margin.

If an error occurs, the correct methods for debugging the strategy are:

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.

//@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. Checking the equity value to see if it’s above zero before calling strategy.entry() or strategy.order() functions or additionally redefining the number of entry contracts.

//@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. Using variables of the strategy.risk category for risk management. You can read more about these in our User Manual.