Стратегия перекрестного пересечения углового движения

Автор:Чао Чжан, Дата: 2024-01-25 14:35:13
Тэги:

img

Обзор

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

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

  1. Коэффициент изменения цены: рассчитывается коэффициент изменения цены закрытия за последние 12 бар для фильтрации сигналов по волатильности.

Когда скользящий средний наклон поднимается (более 0) и коэффициент изменения цены соответствует критериям, перейдите на длинный. Когда наклон падает (менее 0) и коэффициент изменения цены соответствует критериям, перейдите на короткий.

В частности, стратегия сначала рассчитывает углы наклона Jurik MA и EMA. Затем индикатор курса изменения цены рассчитывается для фильтрации периода, ограниченного диапазоном. Когда как движущийся средний сигнал наклона, так и курс изменения цены соответствуют критериям, генерируется торговый сигнал.

Анализ преимуществ

Преимущества этой стратегии:

  1. Использование наклона MA для определения тренда очень надежно с хорошей скоростью выигрыша.

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

  3. Юрик МА дает быструю реакцию на прорыв, а EMA предлагает стабильное суждение о тенденции, оба дополняющие друг друга.

  4. Если идти как на длинный, так и на короткий рынок, можно получить большую прибыль.

Анализ рисков

Некоторые риски этой стратегии:

  1. В экстремальных ценовых условиях MA может генерировать неправильные сигналы. Это может быть уменьшено оптимизацией параметров.

  2. Сигналы могут часто меняться во время диапазона, вызывая ненужные сделки.

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

Стратегия может быть оптимизирована в следующих аспектах:

  1. Добавить волатильность, фильтры объема и т.д. для дальнейшего снижения недействительных сделок.

  2. Включить другие индикаторы для более умного позиционирования стоп-лосса.

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

Заключение

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


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Based on ma angles code by Duyck which also uses Everget Jurik MA calulation and angle calculation by KyJ
strategy("Trend Angle BF", overlay=false)

/////////////// Time Frame ///////////////
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)

testPeriod() => true
    
src=input(ohlc4,title="source")

// definition of "Jurik Moving Average", by Everget
jma(_src,_length,_phase,_power) =>
    phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5
    beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2)
    alpha = pow(beta, _power)
    jma = 0.0
    e0 = 0.0
    e0 := (1 - alpha) * _src + alpha * nz(e0[1])
    e1 = 0.0
    e1 := (_src - e0) * (1 - beta) + beta * nz(e1[1])
    e2 = 0.0
    e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
    jma := e2 + nz(jma[1])

//// //// Determine Angle by KyJ //// //// 
angle(_src) =>
    rad2degree=180/3.14159265359  //pi 
    ang=rad2degree*atan((_src[0] - _src[1])/atr(14)) 

jma_line=jma(src,10,50,1)
ma=ema(src,input(56))
jma_slope=angle(jma_line)
ma_slope=angle(ma)

///////////// Rate Of Change ///////////// 
source = close
roclength = input(12, minval=1)
pcntChange = input(2, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// Strategy ///////////////
long = ma_slope>=0 and isMoving()
short = ma_slope<=0 and isMoving()

last_long = 0.0
last_short = 0.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 = 0.0
last_open_short_signal = 0.0
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 = 0.0
last_short_signal = 0.0
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 = 0.0
last_low = 0.0
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(2.0, title='Stop Loss %') / 100
tp_inp = input(900.0, title='Take Profit %') / 100 
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp) 

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

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

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
    
///////////// Plotting /////////////
hline(0, title='Zero line', color=color.purple, linewidth=1)
plot(ma_slope,title="ma slope", linewidth=2,color=ma_slope>=0?color.lime:color.red)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30) 


Больше