Một chiến lược lưới năng động thích nghi ngắn hạn dựa trên

Tác giả:ChaoZhang, Ngày: 2024-03-19 14:19:12
Tags:

img

Tổng quan

Đây là một chiến lược giao dịch lưới động thích nghi dài ngắn 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 mức giá cao và thấp gần đây hoặc trung bình di chuyển đơn giản, và sau đó chia phạm vi này thành nhiều đường lưới. Khi giá đạt đến một đường lưới nhất định, nó sẽ mở một vị trí dài hoặc đóng một vị trí ở mức đó. Bằng cách này, chiến lược có thể liên tục mở và đóng các vị trí trong một thị trường phạm vi để nắm bắt sự lây lan giá. Đồng thời, bằng cách điều chỉnh năng động các ranh giới lưới, nó cũng có thể thích nghi với các xu hướng thị trường khác nhau.

Nguyên tắc chiến lược

  1. Tính toán ranh giới lưới. Dựa trên sự lựa chọn của người dùng, ranh giới có thể được tính toán từ các điểm cao nhất và thấp nhất của nến N gần đây, với tùy chọn mở rộng hoặc thu hẹp phạm vi một tỷ lệ phần trăm; hoặc chúng có thể dựa trên trung bình động đơn giản của giá đóng của nến N gần đây, với tùy chọn để thiết lập tỷ lệ lệ lệ biến động lên và xuống.

  2. Tạo mảng đường lưới. Theo số lượng các đường lưới đã thiết lập, chia phạm vi lưới bằng nhau để tạo một mảng giá đường lưới.

  3. Đưa vào/Thêm vị trí. Chuyển qua các đường lưới từ dưới lên trên. Nếu giá đóng hiện tại thấp hơn giá đường lưới và không có vị trí trên đường lưới đó, sau đó mở một vị trí dài ở mức đó. Bằng cách này, khi giá đạt đến các đường lưới cao hơn, nó sẽ tiếp tục thêm các vị trí.

  4. Đi ra/Giảm vị trí. Đi qua các đường lưới từ trên xuống dưới. Nếu giá đóng hiện tại lớn hơn giá đường lưới và có một vị trí trên đường lưới bên dưới, sau đó đóng vị trí dài trên đường lưới bên dưới. Bằng cách này, khi giá giảm lại, nó sẽ tiếp tục giảm vị trí.

  5. Điều chỉnh động: Nếu chọn chức năng lưới động, giới hạn trên và dưới của lưới và mảng đường lưới sẽ được tính lại trên mỗi nến, để lưới có thể liên tục thích nghi với sự thay đổi của thị trường.

Phân tích lợi thế

  1. Khả năng thích nghi mạnh mẽ. Chiến lược giao dịch lưới có thể thích nghi với cả thị trường giới hạn và xu hướng. Trong thị trường giới hạn, chiến lược lưới có thể liên tục mở và đóng các vị trí để kiếm được chênh lệch giá; trong thị trường xu hướng, vì lưới theo dõi chuyển động giá, nó cũng có thể duy trì một vị trí nhất định để có được lợi nhuận xu hướng.

  2. Rủi ro có thể kiểm soát được. Kích thước vị trí của mỗi mở được xác định bởi số lưới đặt, vì vậy việc tiếp xúc rủi ro duy nhất là nhỏ và có thể kiểm soát được. Đồng thời, vì đạt đến các đường lưới trên sẽ đóng các vị trí để kiếm lợi nhuận, nó cũng bảo hiểm tổn thất tiềm năng ở một mức độ nhất định.

  3. Mức độ tự động hóa cao. Chiến lược này về cơ bản có thể chạy hoàn toàn tự động mà không cần can thiệp thủ công, phù hợp với các nhà đầu tư cần lợi nhuận ổn định dài hạn.

  4. Các tham số linh hoạt. Người dùng có thể linh hoạt thiết lập số lượng đường lưới, tham số lưới động, vv theo đặc điểm thị trường để tối ưu hóa hiệu suất chiến lược.

Phân tích rủi ro

  1. Rủi ro thiên nga đen. Trong trường hợp xảy ra sự sụp đổ thị trường cực đoan, nếu giá trực tiếp giảm xuống dưới đường lưới thấp nhất, chiến lược sẽ hoàn thành các vị trí và phải đối mặt với sự rút vốn lớn hơn. Để giảm rủi ro này, điều kiện dừng lỗ có thể được thiết lập để đóng tất cả các vị trí một khi lỗ đạt ngưỡng.

  2. Thiết lập tham số lưới không chính xác. Nếu mật độ lưới quá cao, sự lây lan của mỗi mở và đóng sẽ rất nhỏ, và chi phí giao dịch có thể làm xói mòn hầu hết các lợi nhuận. Nếu chiều rộng lưới quá lớn, tỷ lệ mở một lần cao và rủi ro lớn. Các đặc điểm của tài sản cơ bản cần được đánh giá cẩn thận để chọn các tham số lưới phù hợp.

  3. Rủi ro cơ bản. Chiến lược này thiết lập các điều kiện mở và đóng dựa trên giá hiện tại. Trong các thị trường như tương lai, nếu giá hợp đồng khác nhau rất nhiều so với giá cơ bản, giá mở và đóng thực tế có thể lệch đáng kể so với mong đợi.

Hướng dẫn tối ưu hóa

  1. Thêm bộ lọc xu hướng. Các chiến lược lưới không hoạt động tốt trong các thị trường xu hướng đơn phương. Các chỉ số xu hướng có thể được thêm làm bộ lọc, chẳng hạn như chỉ kích hoạt lưới khi ADX dưới ngưỡng, và đóng lưới khi xu hướng rõ ràng, chỉ giữ các vị trí đơn phương.

  2. Tối ưu hóa tín hiệu. Các tín hiệu khác có thể được chồng chéo trên cơ sở lưới, chẳng hạn như lưới + trung bình động, nghĩa là việc mở và đóng chủ yếu được xác định bởi lưới, nhưng chỉ mở các vị trí khi giá vượt qua một mức trung bình động nhất định, nếu không thì không mở các vị trí. Điều này có thể làm giảm chi phí mở và đóng thường xuyên.

  3. Quản lý vị trí. Hiện tại, vị trí của mỗi lưới trong chiến lược được cố định. Nó có thể được thiết lập để giảm vị trí của mỗi lưới khi giá xa với giá trung bình thị trường và tăng vị trí khi gần với giá trung bình thị trường để cải thiện hiệu quả sử dụng vốn.

  4. Độ dày đặc lưới thích nghi. Điều chỉnh mật độ lưới theo biến động giá. Khi biến động cao, số lưới có thể được tăng thích hợp; khi biến động thấp, số lưới có thể được giảm. Điều này có thể tối ưu hóa chiều rộng lưới và cải thiện việc sử dụng vốn.

Tóm lại

Thông qua lưới năng động thích nghi, chiến lược này có thể thường xuyên mở và đóng các vị trí để kiếm được chênh lệch giá trên các thị trường giới hạn phạm vi, và cũng có thể duy trì một mức độ nhất định về hướng tiếp xúc trong các thị trường xu hướng để có được lợi nhuận xu hướng. Đây là một chiến lược định lượng trung hạn đến dài hạn có khả năng thích nghi mạnh mẽ. Bằng cách thiết lập hợp lý lưới kích hoạt logic và quản lý vị trí, lợi nhuận ổn định có thể đạt được. Tuy nhiên, cần phải chú ý đến rủi ro của điều kiện thị trường cực đoan và khoảng cách giá, đòi hỏi phải 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 trong thiết lập tham số và quản lý rủi ro. Sự mạnh mẽ và lợi nhuận của chiến lược có thể được cải thiện bằng cách giới thiệu lọc xu hướng, chồng chất tín hiệu, quản lý vị trí, mật độ lưới thích ứng và các phương tiện khác. Tóm lại, dựa trên logic cơ bản của lưới, chiến lược này kết hợp một cơ chế thích ứng, có thể cung cấp các ý tưởng định lượng mới và định lượng cho các nhà đầu


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

Thêm nữa