Chiến lược đột phá kênh trung bình chuyển động thích nghi là một chiến lược đột phá theo xu hướng dựa trên Đường trung bình chuyển động thích nghi (AMA) và phạm vi kênh thích nghi để tạo ra tín hiệu giao dịch. Nó sử dụng AMA để xác định hướng xu hướng giá hiện tại và mức kênh thích nghi để phát hiện tín hiệu đột phá giá cho các bước vào và ra kịp thời.
Chỉ số cốt lõi của chiến lược này là Đường trung bình động thích nghi (AMA), được sử dụng để nắm bắt xu hướng giá.
AMA (t) = α (t-1) * P (t) + [1 - α (t-1) ] * AMA (t-1)
Trong đó P (t) là giá hiện tại, và α (t) là hằng số làm mịn giữa 0 và 1. α (t) được điều chỉnh động theo một số quy tắc nhất định để kiểm soát độ nhạy của AMA đối với sự thay đổi giá. Cụ thể, α (t) tỷ lệ với độ lệch SNRT giữa AMA và giá, được tính như sau:
SNRT = (P(t) - AMA(t-1)) / AMA(t-1)
Do đó, khi biến động giá tăng lên, α ((t) sẽ tăng lên để làm cho AMA đáp ứng nhanh hơn; khi biến động giảm xuống, α ((t) sẽ giảm xuống để làm cho AMA mượt mà hơn.
Dựa trên AMA, chiến lược xây dựng một phạm vi kênh thích nghi để phát hiện tín hiệu đột phá giá.
Trên: H ((t) = (1 + β*H ((t-1)) * AMA ((t)
Hạ: L ((t) = (1 - β*L ((t-1)) * AMA ((t)
Trong đó β là một tham số có thể điều chỉnh điều khiển chiều rộng kênh. Cuối cùng, chiến lược tạo ra các giao dịch dựa trên sự đột phá giá của các mức kênh:
Nhập dài khi giá phá vỡ trên mức trên.
Nhập ngắn khi giá phá vỡ dưới mức thấp hơn.
Nếu không, cứ ở yên.
Những lợi thế của chiến lược này bao gồm:
AMA linh hoạt hơn trong việc nắm bắt xu hướng giá so với trung bình động đơn giản, đặc biệt là trong các thị trường biến động.
Kênh thích nghi có thể điều chỉnh chiều rộng của nó một cách năng động, mở rộng khi xu hướng không rõ ràng và thu hẹp khi xu hướng xuất hiện.
Các tín hiệu đột phá giá có thể bắt kịp thời xu hướng bắt đầu với tỷ lệ thắng cao hơn.
Logic là đơn giản và rõ ràng, dễ hiểu và tự động hóa cho giao dịch định lượng.
Những rủi ro của chiến lược này bao gồm:
Các thông số AMA không chính xác có thể bỏ qua xu hướng giá hoặc tạo ra các tín hiệu sai.
Các thông số kênh thích nghi như β cần điều chỉnh cẩn thận, nếu không có quá nhiều whipsaw hoặc xu hướng bị bỏ lỡ có thể xảy ra.
Sự đột phá giá dễ bị phá vỡ sai, đòi hỏi nhiều bộ lọc hơn.
Chiến lược không bao gồm quản lý rủi ro hoặc cơ chế dừng lỗ.
Chiến lược có thể được tối ưu hóa bằng cách:
Cải thiện tính toán α để làm cho AMA đáp ứng nhanh hơn.
Thêm xác nhận thêm sau khi đột phá ban đầu để tránh tín hiệu sai.
Áp dụng các bộ lọc như khối lượng hoặc biến động để xác nhận tính hợp lệ của sự đột phá.
Bao gồm dừng lỗ để khóa lợi nhuận và kiểm soát rủi ro.
Tối ưu hóa kích thước vị trí cho các loại tài sản khác nhau.
Tóm lại, Chiến lược Breakout kênh trung bình chuyển động thích nghi là một chiến lược breakout đơn giản và thực tế theo xu hướng. Nó sử dụng AMA linh hoạt để theo dõi xu hướng giá và một kênh thích nghi để phát hiện tín hiệu breakout. Chiến lược có một số lợi thế nhưng cũng có những rủi ro tiềm ẩn. Với các tối ưu hóa như điều chỉnh tham số, thêm bộ lọc và cải thiện dừng, nó có thể trở nên mạnh mẽ hơn. Nhìn chung, nó cung cấp một mô hình cơ sở vững chắc cho giao dịch định lượng.
/*backtest start: 2022-10-26 00:00:00 end: 2023-11-01 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // CryptoStatistical - 2019 // AMA Strategy Channel Breakout Strategy from E. Durenard - Professional Automated Trading // https://www.amazon.com/Professional-Automated-Trading-Theory-Practice/dp/1118129857 strategy(title="[CS] AMA Strategy - Channel Break Out", shorttitle="AMA_ChannelBreakout_Strategy", initial_capital = 1000, overlay=true, pyramiding = 0, calc_on_every_tick=false, calc_on_order_fills=false, commission_type= strategy.commission.percent, commission_value = 0.08, currency=currency.USD) testStartYear = input(2019, "Backtest Start Year") testStartMonth = input(6, "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) testPeriodBackground = input(title="Color Background?", type=input.bool, defval=true) testPeriodBackgroundColor = testPeriodBackground and (time >= testPeriodStart) and (time <= testPeriodStop) ? #00FF00 : na bgcolor(testPeriodBackgroundColor, transp=95) testPeriod() => true price = input(title='Price Source:', type=input.source, defval=close) ama = price hb = price lb = price // Static model parameters minfactor = 0. maxfactor = 1. deviation_max = 1. deviation_min = 1. beta_hb = 1. beta_lb = 1. snr = 1. normalized_atan= 0. alpha = 0.5 // Suggested snr-factor from .5 upto 3.1 by .3 to find best parameter snrfactor = input(title='SNR Factor:', type=input.float, minval=0.6, maxval=3.3, step=0.3, defval=2.1) // Sensitivity Lookback search for the best perdiod from 5 to 20 lookback = input(title='Sensitivity Lookback:', type=input.integer, defval=5) // Suggested Beta from .5 below 4.5 by .3, usually in the range 1.2, 1.5 beta = input(title='Beta:', type=input.float, minval=0.6, maxval=4.5, step=0.3, defval=2.1) offsetlabel = input(title='Offset Label:', type=input.float, minval=0.001, maxval=0.03, step=0.001, defval=0.001) // pi/2 pi2 = 1.5707963267948966 // Zero-lag resampled moving average (Durschner nwma) f_nwma(_src, _period) => fast = _period/2 lambda = _period/fast alpha = lambda * (_period - 1)/(_period - lambda) average1 = wma(_src,_period) average2 = wma(average1,fast) nwma = (1+alpha)*average1 - alpha*average2 ama := alpha[1]*price + (1-alpha[1])*nz(ama[1]) deviation_max := alpha[1]*max((price[0] - price[1])/price[1],0) + (1-alpha[1])*nz(deviation_max[1]) deviation_min := -alpha[1]*min((price[0] - price[1])/price[1],0) + (1-alpha[1])*nz(deviation_min[1]) beta_hb := beta*deviation_max beta_lb := beta*deviation_min hb := (1 + beta_hb[1])*ama lb := (1 - beta_lb[1])*ama snr := if price > hb ((price - ama[1])/ama[1])/beta_lb else if price < lb -((price - ama[1])/ama[1])/beta_hb else 0 normalized_atan := (atan(snrfactor*snr) + pi2)/(2*pi2) alpha := f_nwma(minfactor + (maxfactor - minfactor)*normalized_atan, lookback) plot(ama, color=color.black) plot(hb, color=color.green) plot(lb, color=color.red) // Buy Condition Var bc = false // Sell Condition Var sc = false d = color.black // Buy Condition if(price > hb) bc := true d := color.green // Sell Condition if(price < lb) sc := true d := color.red if(testPeriod()) strategy.entry("Long", strategy.long, when = bc) strategy.entry("Short", strategy.short, when = sc) alertcondition(bc, title='BuyCondition', message='Buy') alertcondition(sc, title='SellCondition', message='Sell') plotshape(title='Buy', series=bc ? price * (1 - offsetlabel) : na, text='A1B', style=shape.labelup, location=location.absolute, color=d, textcolor=color.white, offset=0) plotshape(title='Sell', series=sc ? price * (1 + offsetlabel) : na, text='A1S', style=shape.labeldown, location=location.absolute, color=d, textcolor=color.white, offset=0)