Chiến lược giao dịch lưới lượng tử tự điều chỉnh

Tác giả:ChaoZhang, Ngày: 2024-02-02 18:08:22
Tags:

img

Tổng quan

Chiến lược này thiết lập một lưới giao dịch năng động để đạt được lợi nhuận ổn định giữa các thị trường biến động. Nó tự động tính toán khoảng cách lưới và giới hạn trên / dưới dựa trên số lượng các đường lưới đã đặt trước. Khi giá vượt qua từng đường lưới, các vị trí dài / ngắn sẽ được xây dựng theo lô. Lợi nhuận sẽ được lấy khi giá chạm vào các đường lưới ban đầu một lần nữa. Chiến lược hỗ trợ cả điều chỉnh thủ công và tự động các thông số lưới để thích nghi với điều kiện thị trường thay đổi.

Chiến lược logic

  1. Tính toán ranh giới lưới và mảng giá đường lưới dựa trên các thông số đầu vào.

  2. Khi giá giảm xuống dưới một đường lưới mà không có lệnh tương ứng, các lệnh dài sẽ được đặt ở mức giá đường lưới. Khi giá tăng lên trên đường lưới trước (đầu tiên bị loại trừ) với vị trí hiện có, các lệnh dài của dòng trước sẽ được đóng.

  3. Nếu điều chỉnh tự động được bật, giới hạn trên/dưới lưới, khoảng cách lưới và mảng lưới sẽ được tính lại theo định kỳ dựa trên dữ liệu nến gần đây.

Phân tích lợi thế

  1. Thực hiện lợi nhuận ổn định trong bối cảnh thị trường biến động. các vị trí dài / ngắn được xây dựng và đóng theo lô ở các mức giá khác nhau để đạt được lợi nhuận tổng thể.

  2. Hỗ trợ cả điều chỉnh tham số thủ công và tự động. Điều chỉnh thủ công cung cấp kiểm soát tốt hơn nhưng đòi hỏi sự can thiệp. Điều chỉnh tự động làm giảm khối lượng công việc và thích nghi với sự thay đổi động lực thị trường.

  3. Khi giá phá vỡ tất cả các đường lưới, rủi ro được kiểm soát.

  4. Điều chỉnh khoảng cách lưới để điều chỉnh lợi nhuận / lỗ cho mỗi giao dịch.

Phân tích rủi ro

  1. Rủi ro bị mắc kẹt trong chấn thương.

  2. Cần vốn ban đầu đầy đủ.

  3. Số lưới cực đoan gây bất lợi cho lợi nhuận. Quá ít lưới không thể tận dụng đầy đủ sự biến động trong khi quá nhiều lưới dẫn đến lợi nhuận tối thiểu cho mỗi giao dịch. Kiểm tra rộng rãi cần thiết để xác định cài đặt tối ưu.

  4. Điều chỉnh tự động rủi ro thao túng giá dựa trên các ngọn nến gần đây có thể bị ảnh hưởng bởi các hoạt động giá ngắn hạn.

Tối ưu hóa

  1. Đưa ra logic dừng lỗ như dừng lỗ theo dõi để hạn chế thêm rủi ro giảm theo hướng.

  2. Tối ưu hóa các tham số lưới thông qua học máy. Kiểm tra các tham số khác nhau trên các điều kiện thị trường và đào tạo các mô hình ML để có được các tham số thích nghi tối ưu.

  3. Bao gồm các chỉ số kỹ thuật bổ sung. Đánh giá sức mạnh xu hướng hiện tại với các chỉ số như MACD và RSI để hướng dẫn số lượng lưới và điều chỉnh tham số.

  4. Tăng cường kiểm soát rủi ro bằng cách thiết lập tỷ lệ rút tiền tối đa được phép.

Kết luận

Chiến lược này sử dụng đầy đủ các đặc điểm của thị trường biến động và đạt được lợi nhuận ổn định thông qua khuôn khổ giao dịch lưới năng động cung cấp cả tính linh hoạt của các tham số và dễ vận hành.


/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 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

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