Chiến lược chéo góc xu hướng trung bình chuyển động

Tác giả:ChaoZhang, Ngày: 2024-01-25 14:35:13
Tags:

img

Tổng quan

Chiến lược logic

  1. Góc độ dốc trung bình chuyển động: Tính toán các góc dốc của trung bình chuyển động Jurik và trung bình chuyển động nhân tố để xác định hướng xu hướng giá.

  2. Tỷ lệ thay đổi giá: Tính toán tỷ lệ thay đổi giá đóng trong 12 thanh cuối cùng để lọc tín hiệu theo biến động.

Khi độ dốc trung bình động tăng lên (lớn hơn 0) và tỷ lệ thay đổi giá đáp ứng các tiêu chí, đi dài. Khi độ dốc giảm xuống (dưới 0) và tỷ lệ thay đổi giá đáp ứng các tiêu chí, đi ngắn.

Phân tích lợi thế

Những lợi thế của chiến lược này:

  1. Sử dụng độ dốc MA để xác định xu hướng là rất đáng tin cậy với tỷ lệ thắng tốt.

  2. Chỉ số tỷ lệ thay đổi giá lọc hiệu quả dao động dao động để tránh giao dịch không hợp lệ.

  3. Jurik MA cung cấp phản ứng nhanh chóng đối với sự đột phá trong khi EMA cung cấp đánh giá xu hướng ổn định, cả hai bổ sung.

  4. Đi cả hai dài và ngắn trong thị trường xu hướng có thể nắm bắt lợi nhuận lớn hơn.

Phân tích rủi ro

Một số rủi ro của chiến lược này:

  1. Trong giá cực đoan, MA có thể tạo ra tín hiệu sai. Điều này có thể được giảm bằng cách tối ưu hóa tham số.

  2. Các tín hiệu có thể thay đổi thường xuyên trong khoảng cách gây ra các giao dịch không cần thiết.

  3. Stop loss có thể bị phá vỡ trong các sự kiện chênh lệch giá đột ngột.

Hướng dẫn tối ưu hóa

Chiến lược có thể được tối ưu hóa trong các khía cạnh sau:

  1. Tối ưu hóa các tham số MA để tìm kết hợp tham số tốt nhất để cải thiện sự ổn định.

  2. Bao gồm các chỉ số khác để định vị dừng lỗ thông minh hơn.

  3. Phát triển các thuật toán định kích thước vị trí thích nghi để có lợi nhuận ổn định hơn.

Kết luận

Nhìn chung, đây là một chiến lược theo xu hướng rất thực tế. Nó xác định một cách đáng tin cậy xu hướng bằng cách sử dụng góc độ dốc MA và lọc hiệu quả các tín hiệu tiếng ồn bằng cách sử dụng chỉ số tỷ lệ thay đổi giá.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Based on ma angles code by Duyck which also uses Everget Jurik MA calulation and angle calculation by KyJ
strategy("Trend Angle BF", overlay=false)

/////////////// Time Frame ///////////////
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
    
src=input(ohlc4,title="source")

// definition of "Jurik Moving Average", by Everget
jma(_src,_length,_phase,_power) =>
    phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5
    beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2)
    alpha = pow(beta, _power)
    jma = 0.0
    e0 = 0.0
    e0 := (1 - alpha) * _src + alpha * nz(e0[1])
    e1 = 0.0
    e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1])
    e2 = 0.0
    e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
    jma := e2 + nz(jma[1])

//// //// Determine Angle by KyJ //// //// 
angle(_src) =>
    rad2degree=180/3.14159265359  //pi 
    ang=rad2degree*atan((_src[0] - _src[1])/atr(14)) 

jma_line=jma(src,10,50,1)
ma=ema(src,input(56))
jma_slope=angle(jma_line)
ma_slope=angle(ma)

///////////// Rate Of Change ///////////// 
source = close
roclength = input(12, minval=1)
pcntChange = input(2, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// Strategy ///////////////
long = ma_slope>=0 and isMoving()
short = ma_slope<=0 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])
sl_inp = input(2.0, title='Stop Loss %') / 100
tp_inp = input(900.0, title='Take Profit %') / 100 
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp) 

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
    
///////////// Plotting /////////////
hline(0, title='Zero line', color=color.purple, linewidth=1)
plot(ma_slope,title="ma slope", linewidth=2,color=ma_slope>=0?color.lime:color.red)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30) 


Thêm nữa