
Chiến lược này kết hợp các chỉ số trung bình di chuyển và các chỉ số xu hướng siêu, để thực hiện một chiến lược theo dõi xu hướng có chức năng theo dõi dừng lỗ. Chiến lược tận dụng đầy đủ khả năng phán đoán xu hướng của trung bình di chuyển và chức năng dừng lỗ của xu hướng siêu, có thể theo dõi xu hướng một cách hiệu quả, đồng thời kiểm soát rủi ro.
Chiến lược này sử dụng hai đường trung bình FRAMA để đánh giá tín hiệu mua và bán và lọc kết hợp với chỉ số siêu xu hướng.
Cụ thể, khi đường nhanh vượt qua đường chậm sẽ tạo ra tín hiệu mua, và khi đường nhanh vượt qua đường chậm sẽ tạo ra tín hiệu bán. Để tránh sự phá vỡ giả, chiến lược đã thêm điều kiện lọc chỉ số siêu xu hướng, giao dịch chỉ được thực hiện khi chỉ số siêu xu hướng đồng hướng.
Trong quản lý vị trí, chiến lược sử dụng biến động của chỉ số siêu xu hướng làm tín hiệu thoát lỗ. Khi chỉ số siêu xu hướng bị đảo ngược, hãy thực hiện thoát lỗ.
Ngoài ra, chiến lược cũng có chức năng theo dõi dừng lỗ tùy chọn. Sau khi đạt được lợi nhuận nhất định, bạn có thể bật theo dõi dừng lỗ để khóa lợi nhuận.
Những rủi ro này có thể được giảm bằng cách điều chỉnh các tham số trung bình di chuyển, tối ưu hóa các thiết lập chỉ số siêu xu hướng và sử dụng hợp lý các điểm dừng theo dõi.
Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:
Có thể thử nghiệm các kết hợp của các tham số chu kỳ khác nhau để tìm sự cân bằng tối ưu giữa hiệu quả mịn và độ nhạy.
Có thể thử nghiệm các tham số ATR và tham số nhân khác nhau để tối ưu hóa hiệu quả dừng lỗ.
Có thể thử nghiệm thêm các chỉ số kênh hàng hóa, chỉ số tỷ lệ dao động để lọc thêm các tín hiệu.
Có thể thử nghiệm các mức dừng theo dõi khác nhau để tìm các tham số tốt nhất để tối đa hóa lợi nhuận và kiểm soát rủi ro.
Có thể thử nghiệm kết hợp với các chiến lược như dừng chung, dừng rung, dừng động.
Chiến lược này tích hợp các phán đoán xu hướng của các đường trung bình di chuyển và quản lý lỗ hổng của các siêu xu hướng, tạo thành một chiến lược theo dõi xu hướng hoàn chỉnh hơn với chức năng theo dõi lỗ hổng. Bằng cách tối ưu hóa tham số và quản lý rủi ro, bạn có thể tăng cường thêm sự ổn định và khả năng sinh lợi của chiến lược. Chiến lược này phù hợp để sử dụng cho các nhà giao dịch định lượng có một nền tảng nhất định.
/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-13 00:00:00
period: 30m
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/
// © 03.freeman
//@version=4
// strategy("FRAMA strategy", overlay=true,precision=6, initial_capital=1000,calc_on_every_tick=true, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=10000, currency=currency.EUR)
ma_src = input(title="MA FRAMA Source", type=input.source, defval=close)
ma_frama_len = input(title="MA FRAMA Length", type=input.integer, defval=12)
res = input(title="Resolution", type=input.resolution, defval="1W")
frama_FC = input(defval=1,minval=1, title="* Fractal Adjusted (FRAMA) Only - FC")
frama_SC = input(defval=200,minval=1, title="* Fractal Adjusted (FRAMA) Only - SC")
High = security(syminfo.tickerid, res, high)
Low = security(syminfo.tickerid, res, low)
source = security(syminfo.tickerid, res, ma_src)
enterRule = input(false,title = "Use supertrend for enter")
exitRule = input(false,title = "Use supertrend for exit")
ma(src, len) =>
float result = 0
int len1 = len/2
e = 2.7182818284590452353602874713527
w = log(2/(frama_SC+1)) / log(e) // Natural logarithm (ln(2/(SC+1))) workaround
H1 = highest(High,len1)
L1 = lowest(Low,len1)
N1 = (H1-L1)/len1
H2_ = highest(High,len1)
H2 = H2_[len1]
L2_ = lowest(Low,len1)
L2 = L2_[len1]
N2 = (H2-L2)/len1
H3 = highest(High,len)
L3 = lowest(Low,len)
N3 = (H3-L3)/len
dimen1 = (log(N1+N2)-log(N3))/log(2)
dimen = iff(N1>0 and N2>0 and N3>0,dimen1,nz(dimen1[1]))
alpha1 = exp(w*(dimen-1))
oldalpha = alpha1>1?1:(alpha1<0.01?0.01:alpha1)
oldN = (2-oldalpha)/oldalpha
N = (((frama_SC-frama_FC)*(oldN-1))/(frama_SC-1))+frama_FC
alpha_ = 2/(N+1)
alpha = alpha_<2/(frama_SC+1)?2/(frama_SC+1):(alpha_>1?1:alpha_)
frama = 0.0
frama :=(1-alpha)*nz(frama[1]) + alpha*src
result := frama
result
frama = ma(sma(source,1),ma_frama_len)
signal = ma(frama,ma_frama_len)
plot(frama, color=color.red)
plot(signal, color=color.green)
longCondition = crossover(frama,signal)
shortCondition = crossunder(frama,signal)
Factor=input(3, minval=1,maxval = 100)
Pd=input(7, minval=1,maxval = 100)
Up=hl2-(Factor*atr(Pd))
Dn=hl2+(Factor*atr(Pd))
TrendUp = 0.0
TrendDown = 0.0
Trend = 0.0
Tsl = 0.0
TrendUp :=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown :=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl := Trend==1? TrendUp: TrendDown
linecolor = Trend == 1 ? color.green : color.red
//plot(Tsl, color = linecolor , style = plot.style_line , linewidth = 2,title = "SuperTrend")
plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,color.green,0,0)
plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, color.red,0,0)
plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0)
plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0)
// Strategy: (Thanks to JayRogers)
// === STRATEGY RELATED INPUTS ===
//tradeInvert = input(defval = false, title = "Invert Trade Direction?")
// the risk management inputs
inpTakeProfit = input(defval = 0, title = "Take Profit Points", minval = 0)
inpStopLoss = input(defval = 0, title = "Stop Loss Points", minval = 0)
inpTrailStop = input(defval = 0, title = "Trailing Stop Loss Points", minval = 0)
inpTrailOffset = input(defval = 0, title = "Trailing Stop Loss Offset Points", minval = 0)
// === RISK MANAGEMENT VALUE PREP ===
// if an input is less than 1, assuming not wanted so we assign 'na' value to disable it.
useTakeProfit = inpTakeProfit >= 1 ? inpTakeProfit : na
useStopLoss = inpStopLoss >= 1 ? inpStopLoss : na
useTrailStop = inpTrailStop >= 1 ? inpTrailStop : na
useTrailOffset = inpTrailOffset >= 1 ? inpTrailOffset : na
// === STRATEGY - LONG POSITION EXECUTION ===
enterLong() => enterRule? (longCondition and Trend ==1):longCondition // functions can be used to wrap up and work out complex conditions
exitLong() => exitRule and Trend == -1
strategy.entry(id = "Buy", long = true, when = enterLong() ) // use function or simple condition to decide when to get in
strategy.close(id = "Buy", when = exitLong() ) // ...and when to get out
// === STRATEGY - SHORT POSITION EXECUTION ===
enterShort() => enterRule? (shortCondition and Trend ==-1):shortCondition
exitShort() => exitRule and Trend == 1
strategy.entry(id = "Sell", long = false, when = enterShort())
strategy.close(id = "Sell", when = exitShort() )
// === STRATEGY RISK MANAGEMENT EXECUTION ===
// finally, make use of all the earlier values we got prepped
strategy.exit("Exit Buy", from_entry = "Buy", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
strategy.exit("Exit Sell", from_entry = "Sell", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset)
// === Backtesting Dates === thanks to Trost
testPeriodSwitch = input(false, "Custom Backtesting Dates")
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testStopHour = input(23, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
testPeriod() =>
time >= testPeriodStart and time <= testPeriodStop ? true : false
isPeriod = true
// === /END
if not isPeriod
strategy.cancel_all()
strategy.close_all()