Двухнаправленная стратегия торговли движущимися средними ценами (англ. Dual Direction Price Breakthrough Moving Average Timing Trading Strategy) - это количественная стратегия торговли, которая использует ценовой прорыв движущихся средних для определения торговых сигналов.
Основная логика этой стратегии заключается в следующем:
Вычислять скользящие средние (EMA) за определенный период (например, 200 дней) с использованием функции EMA.
Сравните цену закрытия с EMA, чтобы определить, прорывается ли цена через EMA. В частности, когда цена закрытия выше EMA, цена прорывается через EMA; когда цена закрытия ниже EMA, цена прорывается через EMA.
Определите длинные и короткие сигналы на основе прорывов. Когда цена проходит через EMA, генерируйте длинный сигнал; когда цена проходит через EMA, генерируйте короткий сигнал.
Когда сигнал запускается, разместите ордер с определенным процентом (например, 100%) и установите цены стоп-лосса и прибыли.
Когда цена стоп-лосса или прибыли достигается, позиция закрывается.
Повторите процесс, чтобы извлечь выгоду из времени прорыва цены через скользящие средние.
Стратегия проста и проста в понимании и реализации. Она направлена на захват краткосрочного импульса по сигналам прорыва скользящих средних.
Методы оптимизации включают настройку параметров, использование более эффективных индикаторов, снижение частоты торговли и т. Д. Адаптивные остановки и условия фильтрации также могут контролировать риски.
Стратегия имеет относительно простую логику отслеживания скользящих средних для захвата краткосрочного импульса. Преимущества включают быстродействие и простоту использования; недостатки включают отставание и инерцию. Дальнейшие оптимизации могут быть сделаны на выборе индикатора, механизмы остановки потерь, методы фильтрации, чтобы сделать стратегию более солидной и всеобъемлющей.
/*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)