전략에 따른 양적 이동평균 트렌드

저자:차오장, 날짜: 2023-09-18 13:23:52
태그:

전반적인 설명

이 전략은 두 개의 볼륨 가중화 이동 평균을 빠른 라인과 느린 라인으로 계산합니다. 두 라인의 차이에 따라 트렌드 방향을 결정하고 그에 따라 긴 또는 짧은 포지션을 취합니다. 전략은 시장 트렌드를 추적하는 데 간단하고 효과적입니다.

전략 논리

  1. 사용자가 정의한 빠르고 느린 기간에 기초한 부피 가중화 이동 평균을 사용하여 빠르고 느린 선을 계산합니다.

  2. 빠른 줄과 느린 줄의 차이를 계산하세요.

  3. 트렌드 방향을 결정합니다. 느린 라인의 위의 빠른 라인의 교차는 상승 추세를 나타냅니다. 아래의 교차는 하락 추세를 나타냅니다.

  4. 긴 / 짧은 신호를 발사하십시오. 빠른 라인이 느린 라인을 넘을 때 길게 이동하십시오. 빠른 라인이 느린 라인을 넘을 때 짧게 이동하십시오.

  5. 사용자 정의 고정 비율 또는 동적 ATR에 기초한 스톱 손실을 설정합니다.

  6. 출구 규칙. 스톱 손실이 발생하거나 역 신호가 발생하면 포지션을 닫습니다.

장점

  1. 양적 지표를 사용해서 트렌드를 파악하고 잘못된 파장을 피합니다.

  2. 빠른 라인과 느린 라인 조합은 시장 소음을 필터링하고 과잉 거래를 피합니다.

  3. 스톱 로스는 하향 위험을 효과적으로 통제합니다.

  4. 단순하고 이해하기 쉬운 논리입니다.

  5. 다른 제품과 시간 프레임에 맞게 사용자 정의 가능한 매개 변수.

위험성

  1. 부적절한 매개 변수 설정은 과잉 거래 또는 놓친 트렌드를 유발할 수 있습니다.

  2. 고정 스톱 로즈는 변화하는 시장 조건에 너무 딱딱할 수 있습니다.

  3. 양과 가격 관계의 변화는 효과에 영향을 줄 수 있습니다.

  • 위험 1은 매개 변수 최적화를 통해 완화 될 수 있습니다.

  • 리스크 2는 동적 ATR 스톱 손실을 통해 처리 할 수 있습니다.

  • 위험 3은 부피 변화를 모니터링해야 합니다.

더 나은 기회

  1. 다른 빠른 라인과 느린 라인 매개 변수 조합을 테스트합니다.

  2. OBV, Williams %R 등과 같은 다른 부피 가격 지표를 시도하십시오.

  3. 변동성 기반의 정지를 추가합니다.

  4. 다른 지표와 결합하는 것을 평가하십시오.

  5. 다른 거래 도구에 대한 효과 테스트

결론

이 전략은 간단한 논리로 트렌드를 추적하기 위해 빠르고 느린 수치화 이동 평균을 사용합니다. 매개 변수를 최적화하고 위험을 제어 할 수 있습니다. 지표 조합에 대한 추가 평가는 효과를 향상시킬 수 있습니다.


/*backtest
start: 2023-08-18 00:00:00
end: 2023-09-17 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("EVWMA 6HR", overlay=false, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)
// Credit to QuantNomad for the main idea behind this code
/////////////// Time Frame ///////////////
_1 = input(false,  "════════ Test Period ═══════")
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

///////////// EVWMA /////////////
_2 = input(false,  "════════ EVMA ═══════")

fast_sum_length = input(5, title = "Fast Sum Length",  type = input.integer)
slow_sum_length = input(11, title = "Slow Sum Length",  type = input.integer)

fast_vol_period = sum(volume, fast_sum_length)
slow_vol_period = sum(volume, slow_sum_length)

fast_evwma = 0.0
fast_evwma := ((fast_vol_period - volume) * nz(fast_evwma[1], close) + volume * close) / (fast_vol_period)
slow_evwma = 0.0
slow_evwma := ((slow_vol_period - volume) * nz(slow_evwma[1], close) + volume * close) / (slow_vol_period)

diff = fast_evwma - slow_evwma

///////////////  Strategy  /////////////// 
long = fast_evwma > slow_evwma 
short = fast_evwma < slow_evwma 

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])

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

/////////////// Dynamic ATR Stop Losses ///////////////
_4 = input(false,  "════════ Stop Loss ═══════")
SL_type = input("Fixed", options=["Fixed", "ATR Derived"], title="Stop Loss Type")
sl_inp = input(9.0, title='Fixed Stop Loss %') / 100
atrLkb = input(20, minval=1, title='ATR Stop Period')
atrMult = input(1.5, step=0.25, title='ATR Stop Multiplier') 
atr1 = atr(atrLkb)

longStop1 = 0.0
longStop1 :=  short_signal ? na : long_signal ? close - (atr1 * atrMult) : longStop1[1]
shortStop1 = 0.0
shortStop1 := long_signal ? na : short_signal ? close + (atr1 * atrMult) : shortStop1[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

_5 = input(false,  "══════ Longs or Shorts ═════")
useLongs = input(true, title="Use Longs")
useShorts = input(true, title="Use Shorts")

/////////////// Execution ///////////////
if testPeriod()
    if useLongs
        strategy.entry("L", strategy.long, when=long)
        strategy.exit("L SL", "L", stop = SL_type == "Fixed" ? long_sl : longStop1, when=since_longEntry > -1)
    if useShorts
        strategy.exit("S SL", "S", stop = SL_type == "Fixed" ? short_sl : shortStop1, when=since_shortEntry > -1)
        strategy.entry("S", strategy.short, when=short)
    if not useShorts
        strategy.close("L", when=short)
    if not useLongs
        strategy.close("S", when=long)

/////////////// Plotting /////////////// 
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
p1 = plot(diff, title = "Delta", color = long ? color.lime : short ? color.red : na, transp=0)
p2 = plot(0, color = color.white)
fill(p1, p2, color = long ? color.lime : short ? color.red : na, transp=60)

더 많은