Chiến lược này được gọi là RSI_OTT-TP/SL. Chiến lược này kết hợp các chỉ số RSI và các phán đoán về tín hiệu OTT mang lại cho giao dịch, thuộc chiến lược theo dõi xu hướng. Chiến lược xác định hướng xu hướng thị trường thông qua các chỉ số RSI và sử dụng các sóng OTT để định vị điểm vào cụ thể.
Chiến lược này sử dụng cả hai chỉ số RSI và OTT để đánh giá xu hướng và điểm vào.
RSI được sử dụng để xác định hướng xu hướng tổng thể. Chỉ số RSI có thể cho thấy thị trường đang mua hoặc bán quá mức. Khu vực bán quá mức được đặt trên RSI là tín hiệu mua quá mức và khu vực bán quá mức dưới RSI là khu vực bán quá mức.
Dải sóng OTT được sử dụng để phát hiện điểm vào. Nó được hình thành trên cơ sở chỉ số biến động VAR. Khi giá từ dưới lên phá vỡ đường OTT xuống, nó được sử dụng để báo hiệu nhiều; Khi giá từ trên xuống phá vỡ đường OTT lên, nó được sử dụng để báo hiệu khoảng trống.
Sau khi đánh giá xu hướng và xác nhận điểm vào, chiến lược này sẽ mở thêm hoặc mở lỗ khi phá vỡ dải OTT.
Hạn chế dừng lỗ có hộp đầu vào cho phép người dùng tự thiết lập. Khi giá dừng hoặc dừng lỗ được kích hoạt, chiến lược sẽ tự động thanh toán.
Chiến lược này cũng cho phép giao dịch chỉ với số dư, chỉ với số dư hoặc giao dịch hai chiều.
Kết hợp RSI và dải sóng OTT, có thể tìm thấy điểm vào có xác suất cao với giả định tính chính xác của xu hướng.
Dải sóng OTT sử dụng chỉ số động lượng, có khả năng nhạy cảm với biến động giá, có thể phát hiện ra các điểm biến chuyển trước.
Chiến lược cung cấp chức năng dừng lỗ, có thể khóa lợi nhuận hoặc có thể dừng lỗ trước khi tổn thất mở rộng, có lợi cho kiểm soát rủi ro.
Cấu trúc mã rõ ràng, có đầy đủ chú thích, dễ hiểu và sửa đổi.
Các tham số chiến lược có thể được điều chỉnh linh hoạt thông qua giao diện để thích ứng với các môi trường thị trường khác nhau.
Chỉ số RSI có vấn đề về sự chậm trễ, có thể bỏ lỡ điểm chuyển hướng, dẫn đến tổn thất không cần thiết.
Dải sóng OTT cũng có thể tạo ra tín hiệu báo cáo sai, nên kết hợp hình dạng K-line để xác minh.
Cài đặt dừng lỗ không đúng cũng ảnh hưởng đến hiệu suất của chiến lược, cần điều chỉnh tham số cho các giống khác nhau.
Chiến lược này chỉ dựa trên một loại thu hồi, các tham số khác nhau trong thực tế cần được tối ưu hóa riêng biệt.
Mức thời gian phản hồi ngắn, có thể không xác minh đầy đủ hiệu quả của chiến lược, nên mở rộng chu kỳ phản hồi
Có thể xem xét việc lọc thêm các chỉ số khác, chẳng hạn như MACD, KD, v.v., để giảm thông báo sai lệch nhập học.
Có thể điều chỉnh động stop loss dựa trên phương pháp biến động.
Có thể nghiên cứu tối ưu hóa tham số của các giống khác nhau, xây dựng tiêu chuẩn lựa chọn tham số.
Bạn có thể thử các phương pháp học máy để tối ưu hóa các tham số chiến lược động.
Bạn có thể thêm xác nhận giá cả, tránh phá vỡ giả. Bạn cũng có thể sử dụng chỉ số trung bình để đánh giá xu hướng.
Có thể xem xét việc cắt ngang MA như một phương thức dừng lỗ, thay vì dừng lỗ tỷ lệ đơn giản.
Chiến lược này nói chung là một chiến lược theo dõi xu hướng điển hình. Đầu tiên, nó đánh giá hướng xu hướng thông qua RSI, sau đó sử dụng hỗ trợ dải sóng OTT để xác định thời điểm nhập cảnh cụ thể, và cuối cùng thiết lập dừng lỗ để khóa lợi nhuận và kiểm soát rủi ro. Ưu điểm của chiến lược này là danh mục chỉ số đơn giản và hiệu quả, hiệu suất đo lường lại tốt hơn.
/*backtest
start: 2023-09-08 00:00:00
end: 2023-10-08 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BigCoinHunter
//@version=5
strategy(title="RSI_OTT-TP/SL", overlay=true,
pyramiding=0, default_qty_type=strategy.percent_of_equity,
default_qty_value=100, initial_capital=1000,
currency=currency.USD, commission_value=0.05,
commission_type=strategy.commission.percent,
process_orders_on_close=true)
//----------- get the user inputs --------------
//---------- RSI -------------
price = input(close, title="Source")
RSIlength = input.int(defval=6,title="RSI Length")
RSIoverSold = input.int(defval=50, title="RSI OverSold", minval=1)
RSIoverBought = input.int(defval=50, title="RSI OverBought", minval=1)
//------- OTT Bands ----------------
src = close
length=input.int(defval=1, title="OTT Period", minval=1)
percent=input.float(defval=5, title="OTT Percent", step=0.1, minval=0.001)
mav = input.string(title="OTT MA Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"])
ottUpperPercent = input.float(title="OTT Upper Line Coeff", defval=0.01, minval = 0.001, step=0.001)
ottLowerPercent = input.float(title="OTT Lower Line Coeff", defval=0.01, minval = 0.001, step=0.001)
Var_Func(src,length)=>
valpha=2/(length+1)
vud1=src>src[1] ? src-src[1] : 0
vdd1=src<src[1] ? src[1]-src : 0
vUD=math.sum(vud1,9)
vDD=math.sum(vdd1,9)
vCMO=nz((vUD-vDD)/(vUD+vDD))
VAR=0.0
VAR:=nz(valpha*math.abs(vCMO)*src)+(1-valpha*math.abs(vCMO))*nz(VAR[1])
VAR=Var_Func(src,length)
Wwma_Func(src,length)=>
wwalpha = 1/ length
WWMA = 0.0
WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1])
WWMA=Wwma_Func(src,length)
Zlema_Func(src,length)=>
zxLag = length/2==math.round(length/2) ? length/2 : (length - 1) / 2
zxEMAData = (src + (src - src[zxLag]))
ZLEMA = ta.ema(zxEMAData, length)
ZLEMA=Zlema_Func(src,length)
Tsf_Func(src,length)=>
lrc = ta.linreg(src, length, 0)
lrc1 = ta.linreg(src,length,1)
lrs = (lrc-lrc1)
TSF = ta.linreg(src, length, 0)+lrs
TSF=Tsf_Func(src,length)
getMA(src, length) =>
ma = 0.0
if mav == "SMA"
ma := ta.sma(src, length)
ma
if mav == "EMA"
ma := ta.ema(src, length)
ma
if mav == "WMA"
ma := ta.wma(src, length)
ma
if mav == "TMA"
ma := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1)
ma
if mav == "VAR"
ma := VAR
ma
if mav == "WWMA"
ma := WWMA
ma
if mav == "ZLEMA"
ma := ZLEMA
ma
if mav == "TSF"
ma := TSF
ma
ma
MAvg=getMA(src, length)
fark=MAvg*percent*0.01
longStop = MAvg - fark
longStopPrev = nz(longStop[1], longStop)
longStop := MAvg > longStopPrev ? math.max(longStop, longStopPrev) : longStop
shortStop = MAvg + fark
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := MAvg < shortStopPrev ? math.min(shortStop, shortStopPrev) : shortStop
dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir
MT = dir==1 ? longStop: shortStop
OTT=MAvg>MT ? MT*(200+percent)/200 : MT*(200-percent)/200
light_green=#08ff12
light_red=#fe0808
OTTupper = nz(OTT[2])*(1+ottUpperPercent)
OTTlower = nz(OTT[2])*(1-ottLowerPercent)
p1 = plot(OTTupper, color=light_green, linewidth=1, title="OTT UPPER")
p2 = plot(nz(OTT[2]), color=color.new(color.yellow,0), linewidth=1, title="OTT MIDDLE")
p3 = plot(OTTlower, color=light_red, linewidth=1, title="OTT LOWER")
fill(plot1=p1, plot2=p3, title="OTT Background", color=color.new(color.aqua,90), fillgaps=false, editable=true)
buyEntry = ta.crossover(src, OTTlower)
sellEntry = ta.crossunder(src, OTTupper)
//---------- input TP/SL ---------------
tp = input.float(title="Take Profit:", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01
sl = input.float(title="Stop Loss: ", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01
isEntryLong = input.bool(defval=true, title= 'Long Entry', inline="11")
isEntryShort = input.bool(defval=true, title='Short Entry', inline="11")
//---------- backtest range setup ------------
fromDay = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear = input.int(defval = 2021, title = "From Year", minval = 2010)
toDay = input.int(defval = 30, title = "To Day", minval = 1, maxval = 31)
toMonth = input.int(defval = 12, title = "To Month", minval = 1, maxval = 12)
toYear = input.int(defval = 2022, title = "To Year", minval = 2010)
//------------ time interval setup -----------
start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window
finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window
window() => true // create function "within window of time"
//------- define the global variables ------
var bool long = true
var bool stoppedOutLong = false
var bool stoppedOutShort = false
//--------- Colors ---------------
//TrendColor = RSIoverBought and (price[1] > BBupper and price < BBupper) and BBbasis < BBbasis[1] ? color.red : RSIoverSold and (price[1] < BBlower and price > BBlower) and BBbasis > BBbasis[1] ? color.green : na
//bgcolor(switch2?(color.new(TrendColor,50)):na)
//--------- calculate the input/output points -----------
longProfitPrice = strategy.position_avg_price * (1 + tp) // tp -> take profit percentage
longStopPrice = strategy.position_avg_price * (1 - sl) // sl -> stop loss percentage
shortProfitPrice = strategy.position_avg_price * (1 - tp)
shortStopPrice = strategy.position_avg_price * (1 + sl)
//---------- RSI + Bollinger Bands Strategy -------------
vrsi = ta.rsi(price, RSIlength)
rsiCrossOver = ta.crossover(vrsi, RSIoverSold)
rsiCrossUnder = ta.crossunder(vrsi, RSIoverBought)
OTTCrossOver = ta.crossover(src, OTTlower)
OTTCrossUnder = ta.crossunder(src, OTTupper)
if (not na(vrsi))
if rsiCrossOver and OTTCrossOver
long := true
if rsiCrossUnder and OTTCrossUnder
long := false
//------- define the global variables ------
buySignall = false
sellSignall = false
//------------------- determine buy and sell points ---------------------
buySignall := window() and long and (not stoppedOutLong)
sellSignall := window() and (not long) and (not stoppedOutShort)
//---------- execute the strategy -----------------
if(isEntryLong and isEntryShort)
if long
strategy.entry("LONG", strategy.long, when = buySignall, comment = "ENTER LONG")
stoppedOutLong := true
stoppedOutShort := false
else
strategy.entry("SHORT", strategy.short, when = sellSignall, comment = "ENTER SHORT")
stoppedOutLong := false
stoppedOutShort := true
else if(isEntryLong)
strategy.entry("LONG", strategy.long, when = buySignall)
strategy.close("LONG", when = sellSignall)
if long
stoppedOutLong := true
else
stoppedOutLong := false
else if(isEntryShort)
strategy.entry("SHORT", strategy.short, when = sellSignall)
strategy.close("SHORT", when = buySignall)
if not long
stoppedOutShort := true
else
stoppedOutShort := false
//----------------- take profit and stop loss -----------------
if(tp>0.0 and sl>0.0)
if ( strategy.position_size > 0 )
strategy.exit(id="LONG", limit=longProfitPrice, stop=longStopPrice, comment="Long TP/SL Trigger")
else if ( strategy.position_size < 0 )
strategy.exit(id="SHORT", limit=shortProfitPrice, stop=shortStopPrice, comment="Short TP/SL Trigger")
else if(tp>0.0)
if ( strategy.position_size > 0 )
strategy.exit(id="LONG", limit=longProfitPrice, comment="Long TP Trigger")
else if ( strategy.position_size < 0 )
strategy.exit(id="SHORT", limit=shortProfitPrice, comment="Short TP Trigger")
else if(sl>0.0)
if ( strategy.position_size > 0 )
strategy.exit(id="LONG", stop=longStopPrice, comment="Long SL Trigger")
else if ( strategy.position_size < 0 )
strategy.exit(id="SHORT", stop=shortStopPrice, comment="Short SL Trigger")