Chiến lược giao dịch lưới của Ocean Theory


Ngày tạo: 2023-10-13 17:07:39 sửa đổi lần cuối: 2023-10-13 17:07:39
sao chép: 0 Số nhấp chuột: 787
1
tập trung vào
1617
Người theo dõi

Tổng quan

Chiến lược này sử dụng phương pháp giao dịch lưới trong lý thuyết đại dương, trong phạm vi giá được thiết lập, lưới phân phối đồng đều, mua và bán hoạt động dựa trên mối quan hệ giữa giá và lưới. Chiến lược có tính toán tự động phạm vi giá lưới, lưới phân phối đồng đều, và các tính năng khác, có thể kiểm soát rủi ro hiệu quả.

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

Chiến lược này đầu tiên tính toán các giới hạn trên và dưới của lưới giá theo lựa chọn hoặc cài đặt mặc định của người dùng, đó là giá cao nhất và giá thấp nhất của lưới. Có hai cách tính toán, một là tìm kiếm giá cao nhất và giá thấp nhất trong chu kỳ đo đạc, hai là tính toán đường trung bình của một chu kỳ nhất định.

Tạo ra tín hiệu giao dịch phụ thuộc vào mối quan hệ giữa giá và đường lưới. Khi giá thấp hơn đường lưới bên dưới, hãy đặt nhiều vị trí theo số lượng cố định; Khi giá cao hơn đường lưới bên trên, hãy giữ vị trí bằng số lượng cố định. Như vậy, khi giá dao động, vị trí cũng dao động trong mạng lưới, để đạt được lợi nhuận.

Cụ thể, các chiến lược duy trì một mảng giá của mảng lưới và một mảng bool cho biết mỗi mảng lưới có giao dịch hay không. Khi giá thấp hơn một mảng lưới và mảng lưới không có giao dịch, giá trên mảng lưới sẽ tăng; khi giá cao hơn một mảng lưới và mảng lưới bên dưới có giao dịch, mảng lưới bên dưới sẽ thoái hóa. Bằng cách này, giao dịch trên mảng lưới được thực hiện.

Lợi thế chiến lược

  1. Tự động tính toán khoảng cách lưới, tránh khó khăn khi thiết lập thủ công. Bạn có thể chọn cách tính toán khác nhau.

  2. Lưới lưới được phân phối đồng đều, tránh khối lượng lưới dẫn đến giao dịch quá mức. Số lượng lưới có thể điều chỉnh.

  3. Sử dụng phương pháp giao dịch lưới, bạn có thể kiểm soát rủi ro một cách hiệu quả, và biến động giá trong lưới luôn có thể mang lại lợi nhuận.

  4. Không có hướng dự kiến về giá cả, áp dụng cho các trường hợp chấn động.

  5. Lệ phí xử lý và số vị trí có thể được tùy chỉnh để phù hợp với các loại giao dịch khác nhau.

  6. Dòng lưới được hiển thị trực quan, giúp dễ dàng nắm bắt giao dịch.

Rủi ro chiến lược

  1. Rủi ro phá vỡ rào lưới. Bước ra khỏi rào lưới có thể dẫn đến tổn thất lớn.

  2. Rủi ro của khoảng cách lưới quá rộng. Một lưới quá rộng sẽ khó kiếm được lợi nhuận, nhưng một lưới quá hẹp sẽ làm tăng phí xử lý.

  3. Rủi ro của việc giữ vị thế quá lâu.

  4. Rủi ro khi cài đặt tham số không đúng. Các tham số không đúng như chu kỳ đo đạc hoặc chu kỳ trung bình sẽ ảnh hưởng đến tính toán khoảng lưới.

  5. Rủi ro hệ thống của thị trường. Chiến lược này thích hợp hơn cho các tình huống chấn động, không thích hợp cho các tình huống đơn phương lâu dài.

Tối ưu hóa chiến lược

  1. Thiết lập tham số lưới tối ưu hóa. Xét các yếu tố như đặc điểm thị trường, chi phí giao dịch, số lượng lưới tối ưu hóa, chu kỳ đo lường trở lại.

  2. Phân tích động giữa các phân khúc. Khi thị trường thay đổi lớn, có thể giới thiệu cơ chế điều chỉnh động giữa các phân khúc.

  3. Tham gia vào cơ chế dừng lỗ. Thiết lập một đường dừng lỗ hợp lý, tránh thua lỗ quá lớn. Các đường dừng lỗ có thể được điều chỉnh động.

  4. Trình lọc giao dịch kết hợp với các chỉ số khác, chẳng hạn như đường Brin, chỉ số xu hướng, v.v., để tránh giao dịch không phù hợp.

  5. Tối ưu hóa hiệu quả sử dụng vốn. Tham gia phân tích nóng lạnh, giảm giao dịch khi có ít biến động.

Tóm tắt

Chiến lược này sử dụng nguyên tắc giao dịch lưới, để thực hiện giao dịch trong tình trạng biến động có thể kiểm soát rủi ro. Chiến lược có những ưu điểm như lưới tự động tính toán, lưới phân phối đồng đều, có thể thích ứng với môi trường thị trường khác nhau bằng cách điều chỉnh các tham số. Rủi ro có thể được kiểm soát và dễ vận hành.

Mã nguồn chiến lược
/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@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
strategy.initial_capital = 50000
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

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)