Tôi thấy lỗi 'Không thể tạo lệnh với số lượng âm'

Lỗi này xuất hiện khi chiến lược tính toán quy mô mục nhập của nó theo tỷ lệ phần trăm vốn chủ sở hữu của nó. Nếu vốn chủ sở hữu giảm xuống dưới 0, quy mô của vị thế cũng trở thành số âm, điều này là không thể và dẫn đến lỗi thời gian chạy.

Cách tốt nhất để khắc phục sự cố này là chuyển đổi chiến lược sang Pine Script v6. Trong Pine v6, theo mặc định, chiến lược sẽ áp dụng giới hạn về quy mô vị thế. Nếu vốn chủ sở hữu của chiến lược bắt đầu giảm quá nhiều, các vị thế hiện tại sẽ bị thanh lý cưỡng bức bằng lệnh gọi ký quỹ và nếu tiền hết hoàn toàn, chiến lược sẽ không cố gắng tạo các lệnh mới với số lượng âm, tránh được lỗi này.

Nếu bạn muốn tìm hiểu thêm về nguồn gốc của lỗi này và cách tránh lỗi này trong các phiên bản Pine trước đó, hãy tham khảo văn bản bên dưới.

nếu vốn chủ sở hữu của chiến lược trở thành số âm và tổng số hợp đồng được tính cho các hàm strategy.entry() hoặc strategy.order() là số âm. Có thể tránh được lỗi này bằng cách điều chỉnh cài đặt chiến lược từ menu Thuộc tính hoặc trực tiếp thay đổi logic của chiến lược.

Nguồn của lỗi

Hãy xem tập lệnh trong đó số lượng đặt hàng được tính theo phần trăm vốn chủ sở hữu, thông qua cài đặt Quy mô đơn hàng trong cài đặt chiến lược hoặc thông qua hằng số strategy_percent_of_equity  trong Nguồn thông của chiến lược. Trên mỗi thanh, hàm Strategy.entry () được gọi để nhập vị trí:

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

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

Khi thêm tập lệnh vào biểu đồ NASDAQ: AAPL cho khung thời gian 1D, tập lệnh gặp sự cố với lỗi thời gian chạy:

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

Để hiểu lý do của lỗi này, bạn nên vẽ biểu đồ vốn bằng cách sử dụng biến strategy.equity và thêm một ràng buộc đối với lệnh gọi đến hàm Strategy.entry () bằng cách sử dụng bất kỳ toán tử điều kiện nào. Bằng cách đó, hàm để nhập một vị trí sẽ không được gọi trên mỗi thanh (và sẽ không gây ra tính toán lại bổ sung các tham số, bao gồm giá trị qty) và tập lệnh sẽ được tính thành công:

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

Khi mở thanh thứ hai (bar_index = 1), chiến lược đi vào vị thế bán. Nhưng với sự tăng trưởng của giá trị AAPL, lợi nhuận (strategy.equity = strategy.initial_capital + strategy.netprofit + strategy.openprofit)  thành âm.

Số lượng hợp đồng được tính toán bởi công cụ chiến lược được tính là qty = (quy mô lệnh * vốn chủ sở hữu / 100) / lần đóng. Khu vực mà vốn chiến lược chuyển thành giá trị âm có thể được hiển thị như sau:

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

Ảnh chụp màn hình hiển thị nhãn nằm trên phần vốn chủ sở hữu âm, trong đó số lượng hợp đồng kết quả là - 2. Số lượng hợp đồng trên phần màu xanh lá cây là> = 0:


Nếu khi tính toán chiến lược, strategy.entry () được gọi trên thanh có giá trị vốn chủ sở hữu âm (và số lượng hợp đồng là số âm), thì việc tính toán chiến lược sẽ dừng lại với một lỗi.

Cách sửa lỗi này?

Theo quy định, lỗi này không xuất hiện trong một chiến lược được triển khai chính xác. Để tránh những sai lầm, chiến lược nên sử dụng các điều kiện để vào và thoát một vị trí, điểm dừng và ký quỹ.

Nếu lỗi xảy ra, các phương pháp chính xác để gỡ lỗi chiến lược là:

1. Sử dụng đòn bẩy ký quỹ (Ký quỹ cho các vị trí Dài / Ngắn trong Properties  của chiến lược hoặc tham số margin_long và margin_short trong hàm strategy()). Nếu được chỉ định, một phần của vị thế sẽ tự động bị thanh lý nếu chiến lược không có đủ vốn chủ sở hữu để duy trì nó. Bạn có thể tìm hiểu thêm về chức năng này trong bài viết trong Hướng dẫn sử dụng của chúng tôi hoặc trong một bài đăng trên 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. Kiểm tra giá trị vốn chủ sở hữu để xem nó có lớn hơn 0 hay không trước khi gọi các hàm strategy.entry() hoặc strategy.order() hoặc xác định lại số lượng hợp đồng nhập mục.

//@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. Sử dụng các biến của danh mục strategy.risk để quản lý rủi ro. Bạn có thể đọc thêm về nội dung này trong Hướng dẫn sử dụng của chúng tôi.