Đây là một chiến lược dựa trên động lực sử dụng các chỉ số dao động như RSI, Stoch, MACD để tạo ra các tín hiệu giao dịch. Ý tưởng chính là xác định hướng xu hướng khi giá dao động bằng cách sử dụng các chỉ số và tham gia giao dịch dựa trên các tín hiệu chỉ số. Chiến lược cũng sử dụng siêu xu hướng trì hoãn để dừng lỗ.
Chiến lược đầu tiên gọi hàm tùy chỉnh f_getOscilatorValues để có được giá trị của các chỉ số dao động khác nhau bao gồm RSI, Stoch, MACD v.v. Sau đó nó tính toán các giá trị siêu xu hướng bị trì hoãn với f_getSupertrend để theo dõi dừng lỗ.
Sau khi tính toán các chỉ số, chiến lược gọi f_getBuySellStops để tính toán các điểm dừng nhập và mục tiêu lợi nhuận dựa trên các giá trị chỉ số. Cụ thể, nó tính toán ATR và sử dụng ATR nhân với hệ số dừng lỗ như điểm dừng nhập, và ATR nhân với hệ số lấy lợi nhuận như mục tiêu lợi nhuận. Các điểm dừng và mục tiêu sẽ điều chỉnh khi xu hướng đảo ngược.
Sau đó, chiến lược xác định hướng nến. Nến xu hướng tăng có màu xanh lá cây và nến xu hướng giảm có màu đỏ. Sau khi vẽ các nến và chỉ số, chiến lược kiểm tra xem các điều kiện nhập cảnh có được đáp ứng không. Các điều kiện nhập cảnh là mua khi chỉ số hiển thị quá mua và giá phá vỡ trên dải trên, và bán khi chỉ số hiển thị quá bán và giá phá vỡ dưới dải dưới.
Sau khi vào, stop loss được theo dõi bởi dải trên / dưới, bất cứ điều nào gần hơn. Khi stop loss được kích hoạt, vị trí được đóng. Khi giá đạt mục tiêu lợi nhuận, lợi nhuận một phần được lấy.
Những lợi thế của chiến lược này là:
Sử dụng dao động để xác định hướng xu hướng có thể nắm bắt các cơ hội đảo ngược ngắn hạn kịp thời.
Ứng dụng quá trình dừng lỗ siêu xu hướng trì hoãn có thể dừng lại trước khi lỗ tăng, hạn chế lỗ giao dịch duy nhất.
Việc tính toán mục tiêu dừng lỗ và lợi nhuận dựa trên ATR năng động giúp điều chỉnh kích thước vị trí.
Việc lọc với đường trung bình động theo khung thời gian cao hơn tránh bị mắc kẹt trong việc hợp nhất.
Lấy lợi nhuận một phần cho phép lợi nhuận chạy trong khi khóa một số lợi nhuận.
Lý thuyết đơn giản và dễ hiểu cho những người mới bắt đầu giao dịch lượng tử.
Một số rủi ro của chiến lược này bao gồm:
Các dao động có thể có các vấn đề chậm trễ, gây ra tín hiệu bước vào và bước ra sớm. Điều này có thể được cải thiện bằng cách tối ưu hóa các thông số hoặc thêm các chỉ số theo xu hướng.
Phạm vi dừng lỗ có thể được mở rộng hoặc dừng động như Chandelier có thể được sử dụng.
Các vị trí còn lại sau khi lấy lợi nhuận một phần có thể được dừng lại.
Phương pháp nên được xác nhận trên các thị trường khác nhau.
Trục trặc của bộ lọc trung bình động khung thời gian cao hơn.
Chiến lược có thể được tối ưu hóa trong các khía cạnh sau:
Kiểm tra các kết hợp khác nhau của các thông số dao động và tìm những người cung cấp tín hiệu chất lượng.
Cố gắng thay thế phần lợi nhuận bằng việc dừng lợi nhuận dựa trên ATR hoặc trung bình động.
Thêm các thuật toán học máy để thay thế trung bình động cho phân tích xu hướng và cải thiện độ chính xác.
Thêm các chỉ số âm lượng như điều kiện lọc để tránh đảo ngược không cần thiết.
Tập hợp và cân nhắc các chỉ số tối ưu để tìm ra sự kết hợp tối ưu cho tài sản.
Thêm các mô-đun kiểm soát rủi ro học máy để tối ưu hóa năng động các điểm dừng, mục tiêu và kích thước vị trí.
Tích hợp các tín hiệu giao dịch ngang hình tam giác hoặc cơ sở bằng cách sử dụng chênh lệch giá giữa tương lai và giao dịch tại chỗ.
Nhìn chung, đây là một chiến lược tuyệt vời cho những người mới bắt đầu giao dịch lượng với logic rõ ràng tập trung vào các chỉ số và quản lý rủi ro. Nhưng tối ưu hóa tham số và giảm rủi ro vẫn cần thiết cho giao dịch trực tiếp. Nó cũng có thể được tăng cường trong các khía cạnh như phân tích xu hướng, tối ưu hóa dừng lỗ, mô hình tập hợp vv để cải thiện độ bền. Là một mẫu chiến lược giao dịch, nó cung cấp tài liệu tham khảo có giá trị.
/*backtest start: 2023-08-26 00:00:00 end: 2023-09-25 00:00:00 period: 1h 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/ // © HeWhoMustNotBeNamed //@version=4 strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true) oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"]) length = input(3) shortlength = input(3) longlength = input(9) showSupertrend = input(true) AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"]) AtrLength = input(30, step=10) stopMultiplier = input(4) targetMultiplier = input(3) wicks = input(true) considerWicksForDelayByStep = input(false) colorByPreviousClose = input(true) useHTFPivot = input(false) resolution = input("12M", type=input.resolution) HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1) PivotLength = input(2, step=1) tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short]) i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time) i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time) inDateRange = true f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=> oOpen = rsi(open, length) oClose = rsi(close, length) oHigh = rsi(high, length) oLow = rsi(low, length) if(oscilatorType == "tsi") oOpen := tsi(open, shortlength, longlength) oClose := tsi(close, shortlength, longlength) oHigh := tsi(high, shortlength, longlength) oLow := tsi(low, shortlength, longlength) if(oscilatorType == "stoch") oOpen := stoch(open, longlength, shortlength, length) oClose := stoch(close, longlength, shortlength, length) oHigh := stoch(high, longlength, shortlength, length) oLow := stoch(low, longlength, shortlength, length) if(oscilatorType == "cci") oOpen := cci(open, length) oClose := cci(close, length) oHigh := cci(high, length) oLow := cci(low, length) if(oscilatorType == "cog") oOpen := cog(open, length) oClose := cog(close, length) oHigh := cog(high, length) oLow := cog(low, length) if(oscilatorType == "cmo") oOpen := cmo(open, length) oClose := cmo(close, length) oHigh := cmo(high, length) oLow := cmo(low, length) if(oscilatorType == "mfi") oOpen := mfi(open, length) oClose := mfi(close, length) oHigh := mfi(high, length) oLow := mfi(low, length) if(oscilatorType == "macd") [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length) [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length) [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length) [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length) oOpen := macdLineOpen oClose := macdLineClose oHigh := macdLineHigh oLow := macdLineLow [oOpen, oClose, oHigh, oLow] f_getMovingAverage(source, MAType, length)=> ma = sma(source, length) if(MAType == "ema") ma := ema(source,length) if(MAType == "hma") ma := hma(source,length) if(MAType == "rma") ma := rma(source,length) if(MAType == "vwma") ma := vwma(source,length) if(MAType == "wma") ma := wma(source,length) ma f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=> truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength) atr = averagetruerange * stopMultiplier longStop = oClose - atr longStopPrev = nz(longStop[1], longStop) longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop shortStop = oClose + atr shortStopPrev = nz(shortStop[1], shortStop) shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop dir = 1 dir := nz(dir[1], dir) dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir trailingStop = dir == 1? longStop : shortStop [dir, trailingStop] f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=> barState = 0 source = oClose truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) atr = f_getMovingAverage(truerange, AtrMAType, AtrLength) buyStop = source - atr * stopMultiplier sellStop = source + atr * stopMultiplier buyStopDerived = buyStop sellStopDerived = sellStop highTarget = considerWicks ? oHigh : source lowTarget = considerWicks ? oLow : source highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0) buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier buyStop := source - atr * buyMultiplier sellStop := source + atr * sellMultiplier buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop buyStopDerived := buyStop sellStopDerived := sellStop buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived [buyStopDerived, sellStopDerived, barState] f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off) f_multiple_resolution(HTFMultiplier) => target_Res_In_Min = timeframe.multiplier * HTFMultiplier * ( timeframe.isseconds ? 1. / 60. : timeframe.isminutes ? 1. : timeframe.isdaily ? 1440. : timeframe.isweekly ? 7. * 24. * 60. : timeframe.ismonthly ? 30.417 * 24. * 60. : na) target_Res_In_Min <= 0.0417 ? "1S" : target_Res_In_Min <= 0.167 ? "5S" : target_Res_In_Min <= 0.376 ? "15S" : target_Res_In_Min <= 0.751 ? "30S" : target_Res_In_Min <= 1440 ? tostring(round(target_Res_In_Min)) : tostring(round(min(target_Res_In_Min / 1440, 365))) + "D" f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=> derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh) HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow) CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose) pivothi = pivothigh(HTFHigh, PivotLength, PivotLength) pivotlo = pivotlow(HTFLow, PivotLength, PivotLength) pivothi := na(pivothi)? nz(pivothi[1]) : pivothi pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo [pivothi, pivotlo] [oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength) [dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks) candleColor = colorByPreviousClose ? (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver) plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor) [buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier) trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red) [pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength) buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot) exitBuyConditin = (barState == -1) sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot) exitSellCondition = (barState == 1) // strategy.risk.allow_entry_in(tradeDirection) strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca") strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca") strategy.close("Buy", when = exitBuyConditin) strategy.close( "Sell", when = exitSellCondition)