Chiến lược đường xu hướng tức thời của Ehlers được đề xuất bởi John Ehlers trong cuốn sách của ông
Cốt lõi của chiến lược này là tính toán Instantaneous Trendline (IT).
it := (a-((a*a)/4.0))*src+0.5*a*a*src[1]-(a-0.75*a*a)*src[2]+2*(1-a )*it[1]-(1-a )*(1-a )*it[2]
nơi src là giá, a là một yếu tố làm mịn, mặc định là 0,07. Công thức này là một bộ lọc thứ hai có thể làm mịn giá và tạo ra xu hướng.
Một chỉ số quan trọng khác là đường trễ, được tính bằng:
lag = 2.0 * it - nz(it[2])
Khi giá vượt qua trên đường lag, nó báo hiệu một sự đột phá tăng, đi dài. Khi giá vượt qua dưới đường lag, nó báo hiệu một sự đột phá giảm, đi ngắn.
Ngoài ra, chiến lược đặt lệnh dừng lỗ để kiểm soát rủi ro.
Những lợi thế của chiến lược này bao gồm:
Ngoài ra còn có một số rủi ro với chiến lược này:
Những rủi ro này có thể được giảm bớt bằng cách:
Chiến lược này có thể được tối ưu hóa thêm trong các khía cạnh sau:
Nhìn chung, chiến lược đường xu hướng tức thời Ehlers sử dụng các chỉ số kỹ thuật để xác định xu hướng thời gian thực trong cổ phiếu / tương lai và các vị trí mở khi xu hướng đảo ngược. Nó có những lợi thế của việc lọc tiếng ồn hiệu quả, khả năng điều chỉnh tham số cao, logic tạo tín hiệu rõ ràng và kiểm soát rủi ro tích hợp. Với việc tối ưu hóa hơn nữa về lựa chọn tham số, lọc tín hiệu, kích thước vị trí và điều chỉnh dừng lỗ, chiến lược này có thể đạt được hiệu suất thậm chí tốt hơn. Cấu trúc mã rõ ràng cũng làm cho nó dễ hiểu và sửa đổi.
/*backtest start: 2022-12-13 00:00:00 end: 2023-12-19 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy("Ehlers Instantaneous Trendline Strategy", shorttitle = "Ehlers Instantaneous Trendline Strategy", overlay = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100.0, pyramiding = 1, backtest_fill_limits_assumption = 1) src = input(hl2, title="Source") a = input(0.07, title="Alpha", step=0.01) fr = input(false, title="Fill Trend Region") it = na if (na(it[2]) or na(it[1])) it := (src + 2 * src[1] + src[2]) / 4.0 else it := (a-((a*a)/4.0))*src+0.5*a*a*src[1]-(a-0.75*a*a)*src[2]+2*(1-a )*it[1]-(1-a )*(1-a )*it[2] lag = 2.0 * it - nz(it[2]) rngFrac = input(0.35) revPct = input(0.015) stopType = input(title="Stop type", defval = "stop-order", options = ["stop-order", "market-order", "None"]) diff = input(0.5, title = "Spread") LongPrice(p) => LongPrice = diff == 0 ? p : floor(p / diff) * diff ShortPrice(p) => ShortPrice = diff == 0 ? p : ceil(p / diff) * diff strategy.cancel_all() reverseTrade = false if stopType == "market-order" if strategy.position_size > 0 and close < strategy.position_avg_price * (1 - revPct) strategy.order("StopLoss open short", strategy.short, 2 * strategy.position_size, limit = close - 2 * diff) reverseTrade := true if strategy.position_size < 0 and close > strategy.position_avg_price * (1 + revPct) strategy.order("StopLoss open long", strategy.long, -2 * strategy.position_size, limit = close + 2 * diff) reverseTrade := true if lag > it and not reverseTrade price = LongPrice(max(close - (high - low) * rngFrac, low)) if strategy.position_size <= 0 strategy.order("Open long", strategy.long, strategy.equity / price - strategy.position_size, limit = price) if stopType == "stop-order" strategy.order("StopLoss open long", strategy.short, 2 * strategy.equity / price, stop = ShortPrice(price * (1 - revPct))) else if stopType == "stop-order" strategy.order("StopLoss open short", strategy.short, 2 * strategy.position_size, stop = ShortPrice(strategy.position_avg_price * (1 - revPct))) if lag < it and not reverseTrade price = ShortPrice(min(close - (high - low) * rngFrac, high)) if strategy.position_size >= 0 strategy.order("Open short", strategy.short, strategy.equity / price + strategy.position_size, limit = price) if stopType == "stop-order" strategy.order("StopLoss open short", strategy.long, 2 * strategy.equity / price, stop = LongPrice(price * (1 + revPct))) else if stopType == "stop-order" strategy.order("StopLoss open long", strategy.long, -2 * strategy.position_size, stop = LongPrice(strategy.position_avg_price * (1 + revPct))) itPlot=plot(it, color=red, linewidth=1, title="Trend") lagPlot=plot(lag, color=blue, linewidth=1, title="Trigger") fill(itPlot, lagPlot, it < lag ? green : red, transp=70) // === Backtesting Dates === testPeriodSwitch = input(false, "Custom Backtesting Dates") testStartYear = input(2018, "Backtest Start Year") testStartMonth = input(9, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testStartHour = input(0, "Backtest Start Hour") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0) testStopYear = input(2018, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(14, "Backtest Stop Day") testStopHour = input(14, "Backtest Stop Hour") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0) testPeriod() => time >= testPeriodStart and time <= testPeriodStop ? true : false isPeriod = testPeriodSwitch == true ? testPeriod() : true // === /END if not isPeriod strategy.cancel_all() strategy.close_all()