Стратегия балансирования тренда MACD

Автор:Чао Чжан, Дата: 2023-10-17 16:15:53
Тэги:

img

Обзор

Это стратегия, которая определяет бычьи и медвежие направления с помощью индикатора MACD. Она генерирует основную линию MACD путем расчета разницы между быстрыми и медленными средними показателями. Стратегия использует золотой крест основной линии MACD и линии сигнала для генерации сигналов покупки, а крест смерти для генерации сигналов продажи, достигая сбалансированного отслеживания тенденций.

Логика стратегии

Код сначала устанавливает временные рамки обратного тестирования для проверки исторической эффективности стратегии.

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

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

После входа в позицию, непрерывно отслеживать самую высокую и самую низкую цену позиции.

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

  1. Показатель MACD может эффективно идентифицировать тенденции и является одним из классических технических показателей.

  2. Разница между быстрыми и медленными скользящими средними показателями позволяет заранее определить динамику цен и изменения направления.

  3. Эффект фильтрации скользящих средних помогает отфильтровать некоторые ложные сигналы.

  4. Стратегия включает в себя механизм стоп-лосса для контроля рисков.

Риски

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

  2. Неправильное размещение стоп-лосса может быть слишком активным или консервативным, что требует индивидуальной оптимизации по всем продуктам.

  3. Размер позиции на фиксированной основе может легко привести к чрезмерному использованию заемных средств. Рассмотрим размеры позиций на основе размера счета.

  4. Рациональное обоснование временных рамок обратных испытаний необходимо подтвердить, чтобы избежать переподготовки.

Оптимизация

  1. Оптимизировать комбинации быстрых и медленных скользящих средних для поиска наилучших параметров, подходящих для различных продуктов.

  2. Добавьте другие индикаторы, такие как свечи, полосы Боллинджера, RSI, чтобы отфильтровать сигналы.

  3. Оценить различные уровни стоп-лосса на основе снижения, коэффициента Шарпа.

  4. Исследуйте методы стоп-лосса, такие как отслеживание стоп-лосса, лимитные ордера.

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

Заключение

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


/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
strategy("MACD BF", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)

/////////////// Component Code Start ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "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)

// A switch to control background coloring of the test period
testPeriodBackground = input(title="Color Background?", type=bool, defval=true)
testPeriodBackgroundColor = testPeriodBackground and (time >= testPeriodStart) and (time <= testPeriodStop) ? #00FF00 : na
bgcolor(testPeriodBackgroundColor, transp=97)

testPeriod() => true

///////////////  MACD Component - Default settings for one day. /////////////// 
fastLength = input(12) // 72 for 4hr
slowlength = input(26) // 156 for 4 hr
MACDLength = input(12)  // 12 for 4hr

MACD = ema(close, fastLength) - ema(close, slowlength)
aMACD = ema(MACD, MACDLength)
delta = MACD - aMACD

long = crossover(delta, 0) 
short = crossunder(delta, 0) 

last_long = long ? time : nz(last_long[1])
last_short = short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal = short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = long_signal ? time : nz(last_long_signal[1])
last_short_signal = short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low = not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

sl_inp = input(5.0, title='Stop Loss %', type=float)/100

/////////////// Strategy Component /////////////// 
// Strategy Entry
if testPeriod()
    strategy.entry("Long Entry",  strategy.long, when=long_signal)
    strategy.entry("Short Entry", strategy.short, when=short_signal)

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) // LONG SL
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) // SHORT SL

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

// Strategy SL Exit
if testPeriod()
    strategy.exit("Long SL", "Long Entry", stop=long_sl, when=since_longEntry > 1)
    strategy.exit("Short SL", "Short Entry", stop=short_sl, when=since_shortEntry > 1)

//plot(strategy.equity, title="equity", color=blue, linewidth=2, style=areabr)

Больше