
Đây là một chiến lược giao dịch mạng lưới động tự thích ứng đa không gian được viết dựa trên Pine Script. Ý tưởng cốt lõi của chiến lược này là tự động tính toán giới hạn trên và dưới của một lưới dựa trên các điểm cao và thấp gần đây của giá hoặc trung bình di chuyển đơn giản, sau đó chia phạm vi đó thành nhiều đường lưới.
Tính toán đường nét trên và dưới. Tùy thuộc vào tùy chọn của người dùng, đường nét trên và dưới có thể được dựa trên điểm cao nhất và thấp nhất của dòng N gốc K gần nhất và có thể được thiết lập để mở rộng hoặc thu nhỏ tỷ lệ phần trăm; hoặc có thể dựa trên giá trung bình di chuyển đơn giản của dòng N gốc K gần nhất và có thể được thiết lập tỷ lệ lệ lệch hướng lên xuống.
Tạo mảng lưới. Phân chia phạm vi lưới theo số lượng lưới được thiết lập, tạo mảng lưới với giá tương ứng.
Bước vào / đặt hàng. Đi qua đường lưới từ dưới lên, nếu giá đóng cửa hiện tại thấp hơn giá của một đường lưới và đường lưới đó chưa giữ vị trí, hãy mở nhiều lệnh ở vị trí đó. Như vậy, khi giá chạm vào đường lưới cao hơn, sẽ tiếp tục đặt hàng.
Xuất / giảm vị trí. Đi qua đường lưới từ trên xuống, nếu giá đóng cửa hiện tại lớn hơn giá của một đường lưới và đường lưới thấp hơn có vị trí, hãy xóa nhiều đơn vị của đường lưới thấp hơn. Như vậy sẽ tiếp tục giảm vị trí khi giá giảm trở lại.
Điều chỉnh động. Nếu chọn chức năng lưới động, mỗi dòng K sẽ tính toán lại giới hạn trên và dưới của lưới và mảng lưới, cho phép lưới có thể thích nghi liên tục với sự thay đổi của tình hình.
Khả năng thích ứng mạnh. Chiến lược giao dịch lưới có thể thích ứng với tình trạng chấn động và xu hướng. Trong tình huống chấn động, chiến lược lưới có thể tiếp tục mở vị thế bằng và thu được chênh lệch giá; Trong tình huống xu hướng, do lưới theo giá, nó cũng có thể duy trì một vị trí nhất định và thu được lợi nhuận xu hướng.
Rủi ro có thể kiểm soát được. Kích thước vị trí của mỗi lần mở vị trí được quyết định bởi số lượng lưới được thiết lập, lỗ hổng rủi ro đơn lẻ là nhỏ và có thể kiểm soát được. Đồng thời, do giá chạm vào đường lưới phía trên sẽ thu lợi nhuận khi đóng vị trí, cũng có một mức độ bảo vệ rủi ro tiềm ẩn.
Mức độ tự động hóa cao. Chiến lược này hoạt động hoàn toàn tự động, không cần sự can thiệp của con người, phù hợp với các nhà đầu tư muốn thu nhập ổn định lâu dài.
Các tham số linh hoạt. Người dùng có thể tùy chỉnh số lượng đường lưới, tham số lưới động, tùy thuộc vào đặc điểm thị trường để tối ưu hóa hiệu suất chiến lược.
Rủi ro của thiên nga đen. Nếu gặp phải một sự sụt giảm cực đoan, giá sẽ nhảy thẳng xuống dưới đường lưới thấp nhất, thì chiến lược này sẽ hoàn toàn và phải đối mặt với sự rút lui lớn. Để giảm nguy cơ này, bạn có thể thiết lập điều kiện dừng lỗ, hoàn toàn thanh toán khi mất mát đạt đến mức thấp.
Các tham số lưới không được thiết lập đúng. Nếu lưới quá dày, mỗi lần mở lỗ sẽ có giá chênh lệch rất nhỏ, phí xử lý có thể ăn mòn phần lớn thu nhập. Nếu lưới quá rộng, tỷ lệ mở lỗ một lần cao, lỗ hổng rủi ro lớn. Cần đánh giá cẩn thận tính chất tài sản của chỉ số và chọn tham số lưới phù hợp.
Rủi ro chênh lệch cơ sở. Chiến lược này dựa trên các điều kiện mở vị thế bằng giá hiện tại. Trong thị trường như tương lai, nếu giá hợp đồng khác biệt lớn so với giá tiêu chuẩn, giá mở vị thế thực tế có thể lệch khỏi dự kiến nhiều hơn.
Thêm lọc xu hướng. Chiến lược lưới không hoạt động tốt trong một xu hướng duy nhất, bạn có thể thêm chỉ số xu hướng làm bộ lọc, ví dụ như kích hoạt lưới chỉ khi ADX thấp hơn một ngưỡng nhất định, và đóng lưới khi xu hướng rõ ràng, chỉ giữ vị trí duy nhất.
Tín hiệu tối ưu hóa: Các tín hiệu khác có thể được chồng lên trên nền tảng lưới, chẳng hạn như lưới + đường trung bình, tức là chủ yếu do lưới quyết định mở lỗ, nhưng nếu giá vượt qua một đường trung bình, thì sẽ mở lại. Như vậy, bạn có thể giảm chi phí của việc mở lỗ thường xuyên.
Quản lý vị trí. Mỗi vị trí của chiến lược hiện tại là cố định, có thể được thiết lập để giảm vị trí mỗi vị trí khi giá xa hơn giá trung bình thị trường, và tăng vị trí khi gần giá trung bình thị trường, tăng hiệu quả sử dụng vốn.
Tật độ lưới tự điều chỉnh. Điều chỉnh mật độ lưới theo động lực của biến động giá, có thể tăng số lượng lưới khi có biến động cao và giảm số lượng lưới khi có biến động thấp. Như vậy, có thể tối ưu hóa chiều rộng lưới và cải thiện tỷ lệ sử dụng vốn.
Chiến lược này là một chiến lược định lượng đường dài trung bình có khả năng thích ứng mạnh mẽ bằng cách thích ứng với mạng lưới động, có thể thường xuyên mở lỗ để lấy giá trong tình huống biến động, cũng có thể duy trì một số hướng ngõ trong tình huống xu hướng. Bằng cách thiết lập logic kích hoạt và quản lý vị trí của lưới một cách hợp lý, có thể đạt được lợi nhuận ổn định. Tuy nhiên, cần chú ý đến tình trạng cực đoan và rủi ro nhảy vọt giá, điều này cần thiết lập các điều kiện dừng lỗ thích hợp để kiểm soát. Ngoài ra, có thêm không gian tối ưu hóa về các tham số và quản lý rủi ro, có thể tăng cường sự ổn định và lợi nhuận từ các chiến lược bằng cách giới thiệu bộ lọc xu hướng, tín hiệu chồng lên, quản lý vị trí vị trí, thích ứng với mật độ mạng.
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jcloyd
//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool) // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"]) // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1) // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float) // for manual grid bounds only. The upperbound price of your grid
i_lowerBound = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float) // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty = input(group="Grid Lines", title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer) // how many grid lines are in your grid
f_getGridBounds(_bs, _bl, _bd, _up) =>
if _bs == "Hi & Low"
_up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl) * (1 - _bd)
else
avg = sma(close, _bl)
_up ? avg * (1 + _bd) : avg * (1 - _bd)
f_buildGrid(_lb, _gw, _gq) =>
gridArr = array.new_float(0)
for i=0 to _gq-1
array.push(gridArr, _lb+(_gw*i))
gridArr
f_getNearGridLines(_gridArr, _price) =>
arr = array.new_int(3)
for i = 0 to array.size(_gridArr)-1
if array.get(_gridArr, i) > _price
array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
array.set(arr, 1, i == 0 ? i : i-1)
break
arr
var upperBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound // upperbound of our grid
var lowerBound = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth = (upperBound - lowerBound)/(i_gridQty-1) // space between lines in our grid
var gridLineArr = f_buildGrid(lowerBound, gridWidth, i_gridQty) // an array of prices that correspond to our grid lines
var orderArr = array.new_bool(i_gridQty, false) // a boolean array that indicates if there is an open order corresponding to each grid line
var closeLineArr = f_getNearGridLines(gridLineArr, close) // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0) // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1) // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
buyId = i
array.set(orderArr, buyId, true)
strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
if close > array.get(gridLineArr, i) and i != 0
if array.get(orderArr, i-1)
sellId = i-1
array.set(orderArr, sellId, false)
strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))
if i_autoBounds
upperBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
lowerBound := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
gridWidth := (upperBound - lowerBound)/(i_gridQty-1)
gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)
closeLineArr := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)