Chiến lược giao dịch thời gian trung bình chuyển động đột phá giá hai hướng là một chiến lược giao dịch định lượng sử dụng đột phá giá của trung bình chuyển động để xác định tín hiệu giao dịch. Nó so sánh giá với trung bình chuyển động của các khoảng thời gian cụ thể và tạo ra tín hiệu giao dịch khi giá vượt qua trung bình chuyển động.
Logic cốt lõi của chiến lược này là:
Tính toán các đường trung bình động (EMA) trong một khoảng thời gian cụ thể (ví dụ 200 ngày) bằng hàm EMA.
So sánh giá đóng với EMA để xác định xem giá có vượt qua EMA hay không. Cụ thể, khi giá đóng trên EMA, giá sẽ phá vỡ qua EMA; khi giá đóng dưới EMA, giá sẽ phá vỡ qua EMA.
Xác định tín hiệu dài và ngắn dựa trên đột phá. Khi giá phá vỡ qua EMA, tạo tín hiệu dài; khi giá phá vỡ qua EMA, tạo tín hiệu ngắn.
Khi tín hiệu được kích hoạt, đặt lệnh với một tỷ lệ phần trăm nhất định (ví dụ: 100%) và đặt giá dừng lỗ và lấy lợi nhuận.
Khi giá dừng lỗ hoặc lấy lợi nhuận được chạm, đóng vị trí.
Lặp lại quy trình để kiếm lợi từ thời gian giá phá vỡ thông qua đường trung bình động.
Chiến lược này rất đơn giản và trực tiếp để hiểu và thực hiện. Nó nhằm mục đích nắm bắt đà ngắn hạn bằng các tín hiệu phá vỡ các đường trung bình động.
Các phương pháp tối ưu hóa bao gồm điều chỉnh tham số, sử dụng các chỉ số hiệu quả hơn, giảm tần suất giao dịch vv. Các điểm dừng thích nghi và điều kiện lọc cũng có thể kiểm soát rủi ro.
Chiến lược có logic tương đối đơn giản theo dõi các đường trung bình động để nắm bắt đà ngắn hạn. Ưu điểm bao gồm khả năng đáp ứng và dễ sử dụng; nhược điểm bao gồm trễ và quán tính.
/*backtest start: 2022-12-08 00:00:00 end: 2023-12-14 00:00:00 period: 1d basePeriod: 1h 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/ // Credits to the original Script - Range Filter DonovanWall https://www.tradingview.com/script/lut7sBgG-Range-Filter-DW/ // This version is the old version of the Range Filter with less settings to tinker with //@version=5 strategy(title='Range Filter - B&S Signals', shorttitle='RF - B&S Signals', initial_capital=1000, currency=currency.GBP, default_qty_value=100, default_qty_type=strategy.percent_of_equity, commission_type=strategy.commission.percent, commission_value=0.075, overlay=true) i_startTime = input(defval=timestamp('01 Jan 2020 12:00 +0000'), title='Backtest Start') i_endTime = input(defval=timestamp('01 Jan 2024 12:00 +0000'), title='Backtest End') inDateRange = true //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Functions //----------------------------------------------------------------------------------------------------------------------------------------------------------------- longLossPerc = input.float(title='Long Stop Loss (%)', minval=0.0, step=0.1, defval=1) * 0.01 shortLossPerc = input.float(title='Short Stop Loss (%)', minval=0.0, step=0.1, defval=1) * 0.01 longTakePerc = input.float(title='Long Take(%)', minval=0.0, step=0.1, defval=1) * 0.01 shortTakePerc = input.float(title='Short Take (%)', minval=0.0, step=0.1, defval=1) * 0.01 emaLength = input.int(200, title="EMA Length") // Determine stop loss price //Range Size Function rng_size(x, qty, n) => // AC = Cond_EMA(abs(x - x[1]), 1, n) wper = n * 2 - 1 avrng = ta.ema(math.abs(x - x[1]), n) AC = ta.ema(avrng, wper) * qty rng_size = AC rng_size //Range Filter Function rng_filt(x, rng_, n) => r = rng_ var rfilt = array.new_float(2, x) array.set(rfilt, 1, array.get(rfilt, 0)) if x - r > array.get(rfilt, 1) array.set(rfilt, 0, x - r) if x + r < array.get(rfilt, 1) array.set(rfilt, 0, x + r) rng_filt1 = array.get(rfilt, 0) hi_band = rng_filt1 + r lo_band = rng_filt1 - r rng_filt = rng_filt1 [hi_band, lo_band, rng_filt] //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Inputs //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Range Source rng_src = input(defval=close, title='Swing Source') //Range Period rng_per = input.int(defval=20, minval=1, title='Swing Period') //Range Size Inputs rng_qty = input.float(defval=3.5, minval=0.0000001, title='Swing Multiplier') //Bar Colors use_barcolor = input(defval=false, title='Bar Colors On/Off') //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Definitions //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Range Filter Values [h_band, l_band, filt] = rng_filt(rng_src, rng_size(rng_src, rng_qty, rng_per), rng_per) //Direction Conditions var fdir = 0.0 fdir := filt > filt[1] ? 1 : filt < filt[1] ? -1 : fdir upward = fdir == 1 ? 1 : 0 downward = fdir == -1 ? 1 : 0 //Trading Condition longCond = rng_src > filt and rng_src > rng_src[1] and upward > 0 or rng_src > filt and rng_src < rng_src[1] and upward > 0 shortCond = rng_src < filt and rng_src < rng_src[1] and downward > 0 or rng_src < filt and rng_src > rng_src[1] and downward > 0 CondIni = 0 CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1] longCondition = longCond and CondIni[1] == -1 shortCondition = shortCond and CondIni[1] == 1 //Colors filt_color = upward ? #05ff9b : downward ? #ff0583 : #cccccc bar_color = upward and rng_src > filt ? rng_src > rng_src[1] ? #05ff9b : #00b36b : downward and rng_src < filt ? rng_src < rng_src[1] ? #ff0583 : #b8005d : #cccccc ema = ta.ema(close,emaLength) //----------------------------------------------------------------------------------------------------------------------------------------------------------------- //Outputs //----------------------------------------------------------------------------------------------------------------------------------------------------------------- longStopPrice = strategy.position_avg_price * (1 - longLossPerc) shortStopPrice = strategy.position_avg_price * (1 + shortLossPerc) longTakePrice = strategy.position_avg_price * (1 + longTakePerc) shortTakePrice = strategy.position_avg_price * (1 - shortTakePerc) //Filter Plot filt_plot = plot(filt, color=filt_color, linewidth=3, title='Filter', transp=67) //Band Plots h_band_plot = plot(h_band, color=color.new(#05ff9b, 100), title='High Band') l_band_plot = plot(l_band, color=color.new(#ff0583, 100), title='Low Band') //Band Fills fill(h_band_plot, filt_plot, color=color.new(#00b36b, 92), title='High Band Fill') fill(l_band_plot, filt_plot, color=color.new(#b8005d, 92), title='Low Band Fill') //Bar Color barcolor(use_barcolor ? bar_color : na) if inDateRange and close>ema strategy.entry("Long", strategy.long, when=longCondition) if inDateRange and close<ema strategy.entry("Short", strategy.short, when=shortCondition) plot(ema) //Plot Buy and Sell Labels plotshape(longCondition, title='Buy Signal', text='BUY', textcolor=color.white, style=shape.labelup, size=size.normal, location=location.belowbar, color=color.new(color.green, 0)) plotshape(shortCondition, title='Sell Signal', text='SELL', textcolor=color.white, style=shape.labeldown, size=size.normal, location=location.abovebar, color=color.new(color.red, 0)) //Alerts alertcondition(longCondition, title='Buy Alert', message='BUY') alertcondition(shortCondition, title='Sell Alert', message='SELL') if strategy.position_size > 0 strategy.exit(id='Long', stop=longStopPrice, limit=longTakePrice) if strategy.position_size < 0 strategy.exit(id='Short', stop=shortStopPrice, limit=shortTakePrice)