Chiến lược này là một chiến lược động lực dựa trên chỉ số, sử dụng các chỉ số oscillators như RSI, Stoch, MACD để xây dựng tín hiệu giao dịch chiến lược. Ý tưởng chính của chiến lược là sử dụng chỉ số để xác định hướng xu hướng khi giá bị dao động, và tham gia theo tín hiệu chỉ số.
Chiến lược này gọi hàm f_getOscilatorValues để lấy giá trị của các chỉ số dao động khác nhau, bao gồm RSI, Stoch, MACD, v.v. Sau đó, tính toán giá trị của chỉ số xu hướng vượt trội chậm trễ thông qua hàm f_getSupertrend để theo dõi lỗ.
Sau khi tính toán chỉ số, chiến lược sẽ gọi hàm f_getBuySellStops để tính toán điểm dừng và điểm dừng cho mục nhập dựa trên giá trị chỉ số. Cụ thể hơn, nó sẽ tính toán chỉ số ATR và tính ATR nhân với một hệ số dừng là điểm dừng cho mục nhập và ATR nhân với một hệ số dừng cho điểm dừng.
Sau đó, chiến lược sẽ đánh giá hướng thực tế của đường K, nếu là đường K tăng, nó sẽ được vẽ bằng màu xanh lá cây, đường K giảm sẽ được vẽ bằng màu đỏ. Sau khi vẽ đường K và chỉ số, chiến lược sẽ đánh giá xem có phù hợp với điều kiện nhập cảnh hay không. Điều kiện nhập cảnh là khi chỉ số hiển thị quá mua, giá sẽ phá vỡ đường đua; khi chỉ số hiển thị quá bán, giá sẽ phá vỡ đường đua và làm trống. Ngoài ra, chiến lược cũng giới thiệu bộ lọc đường trung bình cao chu kỳ, điều kiện giá cần phá vỡ đường trung bình để tham gia.
Sau khi vào, điểm dừng sẽ được theo dõi, theo dõi điểm dừng là trên đường ray hoặc dưới đường ray whichever is closer. Khi điểm dừng được kích hoạt và thanh toán. Khi giá đạt đến điểm dừng, phần dừng.
Chiến lược này có những ưu điểm sau:
Sử dụng các chỉ số dao động để xác định xu hướng, có thể bắt kịp thời cơ hội đảo ngược đường ngắn của thị trường.
Ứng dụng chiến lược dừng lỗ vượt quá xu hướng trì hoãn, có thể dừng lỗ trước khi tổn thất mở rộng, hạn chế tổn thất đơn lẻ.
Kích thước vị trí có thể được điều chỉnh động theo mức độ rủi ro của ATR.
Bộ lọc kết hợp với đường trung bình chu kỳ cao để tránh bị bịt.
Chiến lược dừng lại một phần để lợi nhuận tiếp tục hoạt động và khóa một phần lợi nhuận.
Các chiến lược này rất đơn giản, dễ hiểu và phù hợp cho người mới bắt đầu giao dịch số lượng.
Chiến lược này cũng có một số rủi ro:
Chỉ số oscillators có vấn đề về độ trễ, có thể dẫn đến tín hiệu vào muộn, tín hiệu ra sớm. Bạn có thể tối ưu hóa thông số chỉ số bằng cách điều chỉnh hoặc thêm các chỉ số hỗ trợ theo xu hướng.
Các điểm dừng gần, có thể sẽ bị phá vỡ dừng. Bạn có thể mở rộng phạm vi dừng thích hợp, hoặc sử dụng các chiến lược dừng động như Chandelier Stop.
Sau khi dừng một phần, các vị trí còn lại có thể bị dừng lại. Bạn có thể giảm tỷ lệ dừng một phần, để có chỗ trống.
Rủi ro của sự phù hợp của dữ liệu phản hồi. Cần xác minh nhiều lần trong các thị trường khác nhau để tránh quá phù hợp.
Đường trung bình chu kỳ cao cũng có thể không hiệu quả như là điều kiện lọc. Các phương pháp như phân loại xu hướng nên được sử dụng để hỗ trợ xác định xu hướng chu kỳ lớn.
Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:
Kiểm tra các kết hợp tham số của các chỉ số khác nhau của dao động, chọn kết hợp có thể cung cấp tín hiệu chất lượng tốt hơn, chẳng hạn như chỉ số Sttoch của đường K nhanh.
Cố gắng thay đổi một phần dừng sang dừng di chuyển, đặt vị trí dừng theo ATR hoặc trung bình di chuyển.
Tham gia thuật toán học máy để đánh giá xu hướng chu kỳ lớn, thay thế phương pháp lọc đường trung bình chu kỳ cao, cải thiện độ chính xác đánh giá.
Các chỉ số năng lượng gia tăng như là điều kiện lọc nhập cảnh để tránh giao dịch đảo ngược không cần thiết.
Các chỉ số được tích hợp và tối ưu hóa trọng lượng, lọc các kết hợp chỉ số phù hợp nhất với giống hiện tại.
Thêm mô-đun điều khiển gió học máy, tối ưu hóa động lực cho vị trí dừng lỗ, vị trí dừng, vị trí vị trí.
Thêm tín hiệu giao dịch của trọng tài tam giác hoặc trọng tài bán sớm, tận dụng chênh lệch giá giữa tương lai và hiện tại.
Chiến lược tổng thể là một chiến lược rất phù hợp để học tập của người mới bắt đầu giao dịch định lượng, tư duy rõ ràng, điểm quan trọng dựa trên phân tích chỉ số và kiểm soát rủi ro. Tuy nhiên, vẫn cần phải tối ưu hóa tham số và tránh rủi ro cho thực tế để có được lợi nhuận ổn định. Ngoài ra, có thể nâng cao chiến lược từ các khía cạnh như đánh giá xu hướng, tối ưu hóa lỗ hổng, học tập tích hợp, để làm cho chiến lược trở nên thô lỗ hơn.
/*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)