
Đây là một chiến lược giao dịch định lượng theo dõi xu hướng lưới động cao cấp. Ý tưởng chính của chiến lược này là phân chia nhiều đường lưới trong phạm vi giá được thiết lập trước và tự động đặt mua hoặc bán bán khi giá chạm vào đường lưới, để kiếm lợi nhuận trong tình huống xung đột.
Các nguyên tắc cốt lõi của chiến lược này là:
Đầu tiên, tùy theo cài đặt của người dùng, xác định ranh giới trên và dưới của lưới và số lượng đường lưới. Các ranh giới có thể là giá trị cố định hoặc có thể được tính tự động dựa trên điểm cao hoặc thấp gần đây hoặc trung bình di chuyển.
Trong ranh giới được xác định, phân chia phạm vi giá thành một số lưới. Mỗi đường lưới tương ứng với một giá mua hoặc bán.
Mỗi khi giá chạm vào đường lưới, chiến lược sẽ kiểm tra xem có vị trí nào đã nắm giữ vị trí tương ứng với đường lưới hay không. Nếu không có, vị trí được mua, và nếu có, vị trí được bán.
Bằng cách bán ở mức tương đối cao và mua ở mức thấp, chiến lược này có thể liên tục kiếm lợi nhuận khi giá dao động.
Trong khi đó, nếu người dùng bật tính năng điều chỉnh ranh giới tự động, vị trí của đường lưới sẽ được điều chỉnh tùy thuộc vào điểm cao hoặc thấp của giá gần đây hoặc trung bình di chuyển được đặt để tối ưu hóa bố trí lưới.
Bằng các nguyên tắc trên, chiến lược này có thể thực hiện mua bán tự động khi giá dao động và điều chỉnh lợi thế theo xu hướng để tăng lợi nhuận tổng thể.
Chiến lược mạng lưới động có những ưu điểm sau:
Khả năng thích ứng mạnh. Có thể điều chỉnh các tham số để thích ứng với các thị trường và giống khác nhau, có khả năng thích ứng tốt với tình trạng chấn động.
Mức độ tự động hóa cao. Do chiến lược dựa trên logic toán học nghiêm ngặt, điểm đặt hàng được xác định rõ ràng, do đó giao dịch hoàn toàn tự động có thể được thực hiện, giảm sự can thiệp của cảm xúc chủ quan.
Có thể kiểm soát rủi ro. Bằng cách đặt số lượng lưới, ranh giới lưới và các tham số khác, bạn có thể kiểm soát hiệu quả lỗ hổng rủi ro cho mỗi giao dịch, do đó duy trì rủi ro tổng thể trong phạm vi chấp nhận được.
Khả năng thích ứng với xu hướng. Trong chiến lược này, có chức năng điều chỉnh các ranh giới của lưới một cách động, cho phép lưới có thể theo dõi xu hướng giá và tối ưu hóa, tăng khả năng sinh lợi trong các tình huống xu hướng.
Tỷ lệ chiến thắng ổn định. Vì giao dịch lưới là bản chất của việc tăng và giảm thường xuyên trong biến động giá, chiến lược này có thể tiếp tục kiếm lợi nhuận miễn là giá tiếp tục biến động, do đó có tỷ lệ chiến thắng cao trong thời gian dài.
Mặc dù có những lợi thế rõ ràng, chiến lược này cũng có một số rủi ro:
Rủi ro xu hướng: Nếu giá có xu hướng đơn phương mạnh mẽ vượt qua ranh giới lưới, thì không gian lợi nhuận của chiến lược này sẽ bị hạn chế và có thể phải đối mặt với sự rút lui lớn hơn.
Các tham số tối ưu hóa rất khó. Chiến lược này có nhiều tham số, bao gồm số lượng lưới, biên độ ban đầu, tham số biên độ động, v.v. Sự kết hợp các tham số khác nhau có ảnh hưởng lớn đến hiệu suất của chiến lược và khó tối ưu hóa thực tế.
Giao dịch thường xuyên. Chiến lược lưới là một chiến lược có tần số cao, thường xuyên đặt hàng, có nghĩa là chi phí giao dịch cao hơn và rủi ro trượt điểm tiềm ẩn.
Phương pháp này phụ thuộc rất nhiều vào các biến động của thị trường và có khả năng sẽ bị rút lui lớn nếu giá đi vào xu hướng đơn phương nhanh chóng.
Đối với những rủi ro này, có thể bắt đầu cải thiện từ các khía cạnh sau: thêm các chỉ số đánh giá xu hướng làm điều kiện lọc để khởi động chiến lược, tối ưu hóa không gian và phương pháp tìm kiếm tham số, giới thiệu logic quản lý tài chính và kiểm soát vị trí, tăng xu hướng phá vỡ logic cân bằng. Bằng cách tối ưu hóa này, bạn có thể nâng cao hơn nữa sức mạnh và lợi nhuận của chiến lược.
Dựa trên những phân tích trên, chiến lược này có thể được tối ưu hóa bởi:
Tham gia vào điều kiện lọc xu hướng. Trước khi bắt đầu chiến lược, hãy thêm các chỉ số đánh giá xu hướng, chẳng hạn như đường trung bình di chuyển, ADX, v.v.
Tìm kiếm tham số tối ưu hóa. Sử dụng các thuật toán thông minh để tối ưu hóa tham số lưới, chẳng hạn như thuật toán di truyền, thuật toán nhóm hạt, để tự động tìm kiếm các tổ hợp tham số tối ưu nhất, cải thiện hiệu quả và chất lượng tối ưu hóa.
Cải thiện logic kiểm soát rủi ro. Thêm nhiều logic kiểm soát rủi ro vào chiến lược, chẳng hạn như điều chỉnh chiều rộng lưới theo biến động giá, thiết lập ngưỡng rút lui tối đa để kích hoạt vị thế bằng phẳng, v.v., để kiểm soát rủi ro tốt hơn.
Đặt một mức độ phá vỡ đường dừng của xu hướng, chẳng hạn như một tỷ lệ nhất định của biên giới lưới, một khi giá phá vỡ đường dừng, toàn bộ vị trí bằng phẳng, tránh sự lùi lại lớn trong tình huống xu hướng.
Tối ưu hóa thực hiện giao dịch. Tối ưu hóa các bước thực hiện giao dịch, chẳng hạn như sử dụng các thuật toán điều kiện và lệnh cao hơn, giảm tần suất và chi phí giao dịch, nâng cao hiệu quả thực hiện.
Bằng cách tối ưu hóa như trên, bạn có thể nâng cao khả năng thích ứng, ổn định và khả năng sinh lợi của chiến lược này, làm cho nó gần gũi hơn với nhu cầu thực tế.
Nói chung, chiến lược theo dõi xu hướng mạng động này là một chiến lược giao dịch tần số trung bình và cao dựa trên nguyên tắc giao dịch mạng, đồng thời tích hợp cơ chế điều chỉnh động và thích ứng xu hướng. Ưu điểm của nó là khả năng thích ứng mạnh, mức độ tự động cao, rủi ro có thể kiểm soát được, khả năng thích ứng xu hướng tốt, tỷ lệ chiến thắng ổn định, nhưng đồng thời cũng có rủi ro mạnh về xu hướng, khó tối ưu hóa tham số, giao dịch thường xuyên, phụ thuộc vào hành vi.
Tư tưởng giao dịch lưới tự nó là một phương pháp định lượng tương đối lâu đời và thực tế, được mở rộng và phát triển bằng cách tích hợp các cơ chế tối ưu hóa động và thích ứng với xu hướng của chiến lược này, làm cho các lợi thế của giao dịch lưới cổ điển được mở rộng và phát triển. Nó cung cấp cho các nhà đầu tư một loại tư tưởng và khả năng giao dịch định lượng mới trong bối cảnh bất ổn. Sau khi được tối ưu hóa và cải tiến thêm, chiến lược này có khả năng trở thành một công cụ giao dịch định lượng tần số trung bình và cao.
/*backtest
start: 2024-03-01 00:00:00
end: 2024-03-21 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)