Стратегия MACD - двусторонняя торговля выходом

Автор:Чао ЧжанДата: 2023-12-12 12:44:50
Тэги:

img

Обзор

Эта стратегия использует индикатор Движущейся средней конвергенции дивергенции (MACD) для генерации длинных и коротких сигналов и совершает реверсионные сделки в хороших условиях тренда, динамически устанавливая точки выхода для получения прибыли.

Принципы стратегии

Ядро этой стратегии основано на золотом кресте MACD для длинных сигналов и смертном кресте для коротких сигналов.

На золотых крестовых сигналах, идти долго, если цена закрытия выше EMA; на смертных крестовых сигналах, идти коротко, если цена закрытия ниже EMA. Это обеспечивает обратную торговлю в условиях восходящей тенденции.

После входа в позиции стратегия использует стоп-лосс и прибыль для динамического управления выходом. В частности, стоп-лосс для длинных позиций устанавливается по цене входа * (1 - максимальное снижение); прибыль устанавливается по цене входа * (1 + TARGET_STOP_RATIO * максимальное снижение). И наоборот для коротких позиций. Здесь максимальное снижение динамически рассчитывается как процент снижения цены от низкого уровня до закрытия; TARGET_STOP_RATIO по умолчанию равен 2, что означает соотношение риск/вознаграждение 2.

Преимущество этой динамической стратегии остановки заключается в том, что она может корректировать стоп-лосс и соотношение риск/вознаграждение на основе волатильности рынка.

Преимущества

  1. MACD является эффективным индикатором для выявления возможностей для реверсии.

  2. Фильтр EMA гарантирует, что длинные сделки происходят только на рынке с восходящим трендом.

  3. Динамическая система управления выходом максимизирует прибыль, эффективно управляя рисками.

  4. Быстрая скорость сокращает время мониторинга, что делает его подходящим для занятых инвесторов.

Риски и решения

  1. MACD часто колеблется на боковых рынках, генерируя ложные сигналы.

  2. При экстремальных рыночных изменениях следует учитывать фиксированное соотношение риск/прибыль.

  3. Ограниченная прибыль на одну сделку требует частой торговли. Инвесторам нужна определенная психологическая выносливость и временная приверженность. Они могут переключаться на более высокие временные рамки, если слишком заняты.

Руководство по оптимизации

  1. Отметьте параметры MACD на основе характеристик символа для оптимизации качества сигнала.

  2. Проверьте различные скользящие средние в качестве фильтра тренда, чтобы найти оптимальный.

  3. Испытать расчет TARGET_STOP_RATIO и определение максимального вывода средств для оптимизации стратегии выхода.

  4. Добавьте другие факторы, такие как объем, волатильность и т. Д., Чтобы улучшить качество сигнала.

  5. Исследуйте модели машинного обучения, чтобы извлечь больше функций и создать адаптивные многофакторные модели для более умных выходов.

Заключение

Эта стратегия имеет большое практическое значение в целом. С MACD как основным торговым сигналом, дополнительные модули фильтра тренда и динамического контроля выхода могут значительно улучшить саму производительность MACD. Контроль выхода необходим для оптимизации стратегии, и эта стратегия существенно внедряет инновации в этой области.


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 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/
// © maxencetajet

//@version=5
strategy("MACD Strategy", overlay=true, initial_capital=1000, slippage=25)

src = input(title="Source", defval=close)
target_stop_ratio = input.float(title='Risk/Reward', defval=2, minval=0.5, maxval=100)
risk = input.float(2, title="Risk per Trade %")

riskt = risk / 100 + 1

useDateFilter = input.bool(true, title="Filter Date Range of Backtest",
     group="Backtest Time Period")
backtestStartDate = input(timestamp("5 June 2022"), 
     title="Start Date", group="Backtest Time Period",
     tooltip="This start date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
backtestEndDate = input(timestamp("5 July 2022"),
     title="End Date", group="Backtest Time Period",
     tooltip="This end date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")

inTradeWindow =  true
emaV = input.int(200, title="Length", group="EMA")
swingHighV = input.int(7, title="Swing High", group="number of past candles")
swingLowV = input.int(7, title="Swing Low", group="number of past candles")

ema = ta.ema(src, emaV)

fast_length = input(title="Fast Length", defval=12, group="MACD")
slow_length = input(title="Slow Length", defval=26, group="MACD")
signal_length = input.int(title="Signal Smoothing",  minval = 1, maxval = 50, defval = 9, group="MACD")
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"], group="MACD")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD")

fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal

longcondition = close > ema and ta.crossover(macd, signal) and macd < 0
shortcondition = close < ema and ta.crossunder(macd, signal) and macd > 0

float risk_long = na
float risk_short = na
float stopLoss = na
float takeProfit = na
float entry_price = na

risk_long := risk_long[1]
risk_short := risk_short[1]

swingHigh = ta.highest(high, swingHighV)
swingLow = ta.lowest(low, swingLowV)

lotB = (strategy.equity*riskt-strategy.equity)/(close - swingLow)
lotS = (strategy.equity*riskt-strategy.equity)/(swingHigh - close)

if strategy.position_size == 0 and longcondition and inTradeWindow
    risk_long := (close - swingLow) / close
    strategy.entry("long", strategy.long, qty=lotB)
    
if strategy.position_size == 0 and shortcondition and inTradeWindow
    risk_short := (swingHigh - close) / close  
    strategy.entry("short", strategy.short, qty=lotS)

if strategy.position_size > 0

    stopLoss := strategy.position_avg_price * (1 - risk_long)
    takeProfit := strategy.position_avg_price * (1 + target_stop_ratio * risk_long)
    entry_price := strategy.position_avg_price
    strategy.exit("long exit", "long", stop = stopLoss, limit = takeProfit)
    
if strategy.position_size < 0

    stopLoss := strategy.position_avg_price * (1 + risk_short)
    takeProfit := strategy.position_avg_price * (1 - target_stop_ratio * risk_short)
    entry_price := strategy.position_avg_price
    strategy.exit("short exit", "short", stop = stopLoss, limit = takeProfit)
    
plot(ema, color=color.white, linewidth=2, title="EMA")
p_ep = plot(entry_price, color=color.new(color.white, 0), linewidth=2, style=plot.style_linebr, title='entry price')
p_sl = plot(stopLoss, color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr, title='stopLoss')
p_tp = plot(takeProfit, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title='takeProfit')
fill(p_sl, p_ep, color.new(color.red, transp=85))
fill(p_tp, p_ep, color.new(color.green, transp=85))



Больше