Chiến lược này kết hợp chỉ số Trung tâm trọng lực và chỉ số kênh SSL để xác định xu hướng giá và theo dõi sự đột phá, thuộc về danh mục chiến lược theo xu hướng.
Tính toán chỉ số Trung tâm trọng lực, với các dải trên và dưới là giới hạn cho xu hướng tăng và giảm.
Tính toán chỉ số kênh SSL, trong đó là phạm vi, bên ngoài là hướng xu hướng.
Khi giá vượt qua dải trên hoặc kênh, xác định xu hướng tăng và mua. Khi giá vượt qua dải dưới hoặc kênh, xác định xu hướng giảm và mua ngắn.
Sử dụng lỗ dừng ATR động để theo dõi mức lỗ dừng và tránh tổn thất lớn hơn.
Kết hợp với thời gian backtest để tạo ra các tín hiệu giao dịch thực tế.
Chiến lược này sử dụng hai chỉ số để xác định xu hướng, một để phát hiện sự đột phá và một để xác nhận xu hướng, kết hợp chúng có thể cải thiện độ chính xác.
Sử dụng hai chỉ số cải thiện độ chính xác trong việc xác định xu hướng.
Trung tâm trọng lực nhạy cảm với sự thay đổi xu hướng, kênh SSL xác định rõ hướng xu hướng.
Động lực ATR dừng lỗ điều chỉnh linh hoạt dựa trên biến động thị trường.
Quy tắc chiến lược đơn giản và rõ ràng, dễ hiểu và thực hiện.
Không gian tối ưu hóa lớn cho các thông số, có thể được điều chỉnh cho các thị trường khác nhau.
Hoàn thành chức năng backtest để xác minh hiệu suất chiến lược.
Cả Trung tâm trọng lực và SSL có thể thất bại trong một số trường hợp, dẫn đến tín hiệu sai. Có thể thêm các chỉ số khác để xác nhận.
Động lực dừng lỗ có thể quá hung hăng, có thể nới lỏng phạm vi dừng lỗ.
Lựa chọn thời gian backtest không chính xác có thể dẫn đến kết quả chiến lược kém, cần phải backtest trên các giai đoạn thị trường khác nhau.
Cần phải xem xét đầy đủ tác động của chi phí thương mại.
Kiểm tra các kết hợp tham số khác nhau để tìm các cặp tối ưu.
Tối ưu hóa thời gian ATR dừng lỗ động và các thông số nhân.
Đưa ra các chỉ số khác để lọc tín hiệu, ví dụ như MACD, KDJ.
Thêm các mô hình học máy để hỗ trợ dự đoán hướng xu hướng.
Tối ưu hóa việc quản lý tiền, thiết lập các quy tắc định kích thước vị trí.
Các thông số tinh chỉnh cho các sản phẩm cụ thể.
Chiến lược này kết hợp Trung tâm trọng lực và Kênh SSL để xác định xu hướng, và sử dụng ATR dừng lỗ năng động để kiểm soát rủi ro. Đây là một chiến lược theo xu hướng có thể thực hiện. Những cải tiến hơn nữa có thể được thực hiện thông qua tối ưu hóa tham số, giới thiệu các chỉ số khác và học máy vv. Nhìn chung đây là một chiến lược rất thực tế và có thể mở rộng, phục vụ như một tài liệu tham khảo có giá trị cho giao dịch thuật toán.
/*backtest start: 2023-08-19 00:00:00 end: 2023-09-13 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // Thanks to HPotter for the original code for Center of Gravity Backtest strategy("CoG SSL BF 🚀", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075) /////////////// Time Frame /////////////// _0 = input(false, "════════ Test Period ═══════") testStartYear = input(2017, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0) testStopYear = input(2019, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0) testPeriod() => true /////////////// SSL Channels /////////////// _1 = input(false, "═════════ SSL ══════════") len1=input(title="SMA Length 1", defval=12) len2=input(title="SMA Length 2", defval=13) smaHigh = sma(high, len1) smaLow = sma(low, len2) Hlv = 0 Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1] sslDown = Hlv < 0 ? smaHigh : smaLow sslUp = Hlv < 0 ? smaLow : smaHigh ///////////// Center of Gravity ///////////// _2 = input(false, "═════════ CoG ══════════") Length = input(25, minval=1) m = input(5, minval=0) Percent = input(6, minval=0, title="COG %") xLG = linreg(close, Length, m) xLG1r = xLG + ((close * Percent) / 100) xLG1s = xLG - ((close * Percent) / 100) pos = 0.0 pos := iff(close > xLG1r, 1, iff(close < xLG1s, -1, nz(pos[1], 0))) possig = iff(pos == 1, 1, iff(pos == -1, -1, pos)) ///////////// Rate Of Change ///////////// _3 = input(false, "══════ Rate of Change ══════") source = close roclength = input(2, "ROC Length", minval=1) pcntChange = input(10, "ROC % Change", minval=1) roc = 100 * (source - source[roclength]) / source[roclength] emaroc = ema(roc, roclength / 2) isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2)) /////////////// Srategy /////////////// long = possig == 1 or (sslUp > sslDown and isMoving()) short = possig == -1 or (sslUp < sslDown and isMoving()) last_long = 0.0 last_short = 0.0 last_long := long ? time : nz(last_long[1]) last_short := short ? time : nz(last_short[1]) long_signal = crossover(last_long, last_short) short_signal = crossover(last_short, last_long) last_open_long_signal = 0.0 last_open_short_signal = 0.0 last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1]) last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1]) last_long_signal = 0.0 last_short_signal = 0.0 last_long_signal := long_signal ? time : nz(last_long_signal[1]) last_short_signal := short_signal ? time : nz(last_short_signal[1]) in_long_signal = last_long_signal > last_short_signal in_short_signal = last_short_signal > last_long_signal last_high = 0.0 last_low = 0.0 last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) /////////////// Dynamic ATR Stop Losses /////////////// _4 = input(false, "════════ Stop Loss ═══════") atrLkb = input(1, minval=1, title='ATR Stop Period') atrMult = input(2, step=0.25, title='ATR Stop Multiplier') atr1 = atr(atrLkb) longStop = 0.0 longStop := short_signal ? na : long_signal ? close - (atr1 * atrMult) : longStop[1] shortStop = 0.0 shortStop := long_signal ? na : short_signal ? close + (atr1 * atrMult) : shortStop[1] /////////////// Execution /////////////// if testPeriod() strategy.entry("L", strategy.long, when=long) strategy.entry("S", strategy.short, when=short) strategy.exit("L SL", "L", stop=longStop, when=since_longEntry > 0) strategy.exit("S SL", "S", stop=shortStop, when=since_shortEntry > 0) /////////////// Plotting /////////////// p1 = plot(sslDown, linewidth = 1, color=color.red, title="SSL down") p2 = plot(sslUp, linewidth = 1, color=color.lime, title="SSL up") fill(p1, p2, color = not isMoving() ? color.white : sslDown < sslUp ? color.lime : color.red, transp=80) plot(xLG1r, color=color.lime, title="LG1r") plot(xLG1s, color=color.red, title="LG1s") plot(strategy.position_size <= 0 ? na : longStop, title="Long Stop Loss", color=color.yellow, style=plot.style_circles, linewidth=1) plot(strategy.position_size >= 0 ? na : shortStop, title="Short Stop Loss", color=color.orange, style=plot.style_circles, linewidth=1) bgcolor(long ? color.green : short ? color.red : not isMoving() ? color.white : na, transp=80) bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=60)