다중 이동 평균 교차 추세 추적 및 변동성 필터링 전략

MA EMA SMA WMA VWMA SMMA RMA
생성 날짜: 2024-07-29 13:37:09 마지막으로 수정됨: 2024-07-29 13:37:09
복사: 0 클릭수: 636
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

다중 이동 평균 교차 추세 추적 및 변동성 필터링 전략

개요

이 전략은 여러 이동 평균의 교차와 변동율 필터링에 기반한 트렌드 추적 거래 시스템이다. 시장의 추세를 식별하기 위해 세 개의 다른 기간의 이동 평균을 사용하며, 네 번째 이동 평균을 거시적 시장 판단의 기준으로 사용한다. 이 전략은 또한 낮은 변동성 환경에서 거래를 피하기 위해 거래 필터링 조건으로 변동율 지표를 도입했다. 이 전략은 장과 공백을 지원하며, 유연한 위치 관리 및 손실 차단 장치를 제공합니다.

전략 원칙

  1. 이동 평균 선택: 전략은 세 가지 주요 이동 평균을 사용하여 (단기, 중기, 장기) 트렌드를 판단한다. 사용자는 6 가지 사전 정의 된 이동 평균 중에서 선택할 수 있으며, 각 이동 평균은 계산 주기, 데이터 소스 및 유형 (SMA, EMA 등) 을 포함하여 개별적으로 파라미터를 구성 할 수 있습니다.

  2. 트렌드 판단:

    • 다단계 경향: 단기 평균선이 장기 평균선보다 높고, 중기 평균선이 상향으로 장기 평균선을 통과할 때.
    • 상향 트렌드: 단기 평균선이 장기 평균선보다 낮고, 중기 평균선이 아래로 장기 평균선을 통과할 때.
  3. 황금지름 시장 판단: 제4의 이동 평균을 황금지름 시장의 경계선으로 사용하는 것을 선택할 수 있습니다. 가격이 이 선 위에있을 때만 더 많이 할 수 있으며, 반대로 공백만 허용됩니다.

  4. 변동율 필터: 최고 가격과 최저 가격에 기반한 변동율 지표가 사용된다. 변동율이 사용자가 설정한 경계를 초과할 때만 거래 신호를 낸다.

  5. 입력 논리:

    • 다수 입시: 다수 트렌드가 확인되고, 변동률 조건이 충족되고, 가격이 장기 평균선보다 높을 때 더 많은 입장을 한다.
    • 허공 입시: 허공 트렌드가 확인되고, 변동률 조건이 충족되고, 가격이 장기 평균선보다 낮으면 포지션을 허공한다.
  6. 출전 논리:

    • 부분 평소: 트렌드가 반전될 때 (중기 평균선과 장기 평균선이 다시 교차) 일정 비율의 포지션을 평소한다.
    • 모든 평점: 가격이 황소와 곰의 시장을 가로질러 갈 때, 반대 방향으로의 모든 포지션을 평행한다.
  7. 상쇄: 고정된 상쇄 비율을 사용하여 사용자 지정 상쇄 비율을 설정할 수 있습니다.

  8. 포지션 관리: 포지션을 개설할 때마다 계정 사용권 이득의 고정 비율을 사용자 지정할 수 있다.

전략적 이점

  1. 다차원 트렌드 분석: 다중 이동 평균을 사용함으로써 전략은 시장의 추세를 더 포괄적으로 포착하고 잘못된 신호를 줄일 수 있습니다.

  2. 유연한 변수 구성: 사용자는 다른 시장과 거래 품종의 특성에 따라 평균선 유형, 주기 및 데이터 소스 등 다양한 변수를 유연하게 조정할 수 있습니다.

  3. 변동률 필터링: 변동률 지표를 도입함으로써, 전략은 낮은 변동률 환경에서 거래를 피하고, 신호 품질을 향상시킬 수 있다.

  4. 호우-베어 시장 적응: 선택 가능한 호우-베어 시장 판단 메커니즘은 전략이 다른 시장 환경에 더 잘 적응할 수 있도록 해 역경 거래를 줄여줍니다.

  5. 다이내믹 포지션 관리: 계정 권익 기반의 포지션 관리 방법, 계정 크기가 변함에 따라 거래 규모를 자동으로 조정할 수 있다.

  6. 다단계 위험 제어: 변동률 필터링, 트렌드 확인, 부분 평점 및 고정 중지 등 다단계 위험 제어 장치.

  7. 양방향 거래: 상장과 하자를 지원하여 다양한 시장 환경에서 거래 기회를 찾을 수 있습니다.

  8. 시각적 도움말: 전략은 각 이동 평균과 거래 신호 태그를 그래프에 그려서 직관적으로 분석하고 재검토할 수 있습니다.

전략적 위험

  1. 뒤처짐: 이동 평균은 본질적으로 뒤처진 지표이며, 입단 및 출전 시간이 약간 늦어져 수익성에 영향을 미칠 수 있다.

  2. 위축 시장의 부실성: 위축 시장의 위축 시장에서, 전략은 종종 잘못된 신호를 생성하여 과도한 거래와 손실을 초래할 수 있습니다.

  3. 변수 민감성: 전략의 성과는 변수 설정에 크게 의존하며, 다른 시장과 시간 프레임에 따라 다른 변수 조합이 필요할 수 있습니다.

  4. 탈퇴 위험: 트렌드가 역전될 경우, 전략이 모든 것을 적시에 출전시키지 못하여 더 큰 탈퇴가 발생할 수 있다.

  5. 과도한 기술 지표 의존: 전략은 전적으로 기술 지표에 기반하여 기본 요소를 무시하고, 중요한 뉴스 또는 사건이 발생했을 때 좋지 않을 수 있습니다.

  6. 자금 관리 위험: 고정 비율의 포지션 관리 방법은 연속적인 손실이 발생할 경우 과도한 위험 틈을 초래할 수 있다.

  7. 중지 손실 설정: 고정 비율 중지 손실은 모든 시장 환경에 적용되지 않을 수 있으며, 높은 변동성이있는 기간 동안 조기 중단으로 이어질 수 있습니다.

전략 최적화 방향

  1. 적응 파라미터: 적응 메커니즘을 도입하여 시장 상황에 따라 이동 평균 파라미터와 변동률 값을 조정한다.

  2. 다중 시간 프레임 분석: 더 긴 시간 프레임과 더 짧은 시간 프레임 정보를 결합하여 트렌드 판단의 정확성을 향상시킵니다.

  3. 변동률 지표 최적화: ATR 또는 볼린저 대역폭과 같은 더 복잡한 변동률 지표를 사용하여 시장 상황을 더 정확하게 평가하는 것을 고려하십시오.

  4. 동력 지표 도입: RSI 또는 MACD와 같은 동력 지표와 결합하여 진출 및 출전 시간을 최적화한다.

  5. 손실 메커니즘의 개선: 시장의 변동에 더 잘 적응하기 위해 추적된 손실 또는 ATR 기반의 동적 손실을 구현합니다.

  6. 시장 정서 지표 통합: 시장 정서 지표, 예를 들어 VIX를 도입하여 다양한 시장 환경에서 전략을 최적화하십시오.

  7. 포지션 관리를 최적화: 변동률이나 현재 수익을 기반으로 하는 역동적인 포지션 관리를 구현하여 위험을 더 잘 제어한다.

  8. 기본적인 필터링을 추가하세요: 중요한 경제 데이터 발표나 회사 실적과 같은 기본적인 요소를 고려하고, 위험성이 높은 기간 동안 거래를 피하십시오.

  9. 머신러닝 최적화: 머신러닝 알고리즘을 사용하여 변수 조합과 의사 결정 규칙을 최적화하여 전략의 적응성을 향상시킵니다.

  10. 역검사와 전향 테스트: 전략의 안정성을 검증하기 위해 더 포괄적인 역검사를 실시하고, 다양한 시장과 시간대에 전향 테스트를 실시한다.

요약하다

다중평평선 교차 트렌드 추적과 변동률 필터링 전략은 다중 이동 평균, 변동률 지표 및 트렌드 추적 원리를 결합한 포괄적이고 유연한 거래 시스템입니다. 다차원적인 트렌드 분석과 엄격한 위험 통제를 통해이 전략은 다양한 시장 환경에서 지속적인 트렌드를 포착 할 잠재력이 있습니다. 그러나 사용자는 매개 변수 최적화 및 시장 적응성의 문제에 주의를 기울이고 더 많은 고급 기술 지표 및 위험 관리 기술을 도입하는 것을 고려하여 전략의 성능을 향상시킬 필요가 있습니다.

전략 소스 코드
/*backtest
start: 2023-07-23 00:00:00
end: 2024-07-28 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title="WODIsMA Strategy", shorttitle="WMA_Strategy", overlay=true, overlay=true, pyramiding=2, default_qty_value=6, default_qty_type=strategy.fixed, initial_capital=1000, currency=currency.USD)

// 用户输入参数
capital_pct = input.float(20, title="每笔订单使用的资金百分比(%)", minval=0.1, maxval=100, group="Position") / 100
close_pct = input.float(20, title="每次平仓使用的百分比(%)", minval=0, maxval=100, group="Position") / 100
stop_loss_user = input.float(10, title="止损百分比(%)", minval=0, maxval=100, group="Position") / 100
allow_long = input.bool(true, title="是否做多", group="Position")
allow_short = input.bool(true, title="是否做空", group="Position")

// 用户选择的移动平均线
short_term_ma = input.string("MA 0", title="短期趋势均线", options=["MA 0", "MA 1", "MA 2", "MA 3", "MA 4", "MA 5"], group="TrendIdentify")
mid_term_ma = input.string("MA 1", title="中期趋势均线", options=["MA 0", "MA 1", "MA 2", "MA 3", "MA 4", "MA 5"], group="TrendIdentify")
long_term_ma = input.string("MA 2", title="长期趋势均线", options=["MA 0", "MA 1", "MA 2", "MA 3", "MA 4", "MA 5"], group="TrendIdentify")
bull_bear_ma = input.string("MA 3", title="牛熊趋势均线", options=["MA 0", "MA 1", "MA 2", "MA 3", "MA 4", "MA 5"], group="TrendIdentify")
enable_bull_bear = input.bool(false, title="是否启用牛熊趋势线", group="TrendIdentify")
// 波动率指标参数
volatility_k = input.int(60, title="波动率数值K线数" , group="volatility")
volatility_threshold = input.float(1, minval=0, title="波动率值 0则不使用(%)", group="volatility")

// 定义不同类型的移动平均线函数
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

// 定义每根均线的输入参数和颜色
length0 = input.int(16, minval=1, title="Length 0", group="MA 0")
source0 = input.source(hl2, title="Source 0", group="MA 0")
type0 = input.string("SMA", title="Type 0", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 0")
timeframe0 = input.timeframe("", title="Timeframe 0", group="MA 0")
color0 = input.color(color.gray, title="Color 0", group="MA 0")
show0 = input.bool(true, title="Show MA 0", group="MA 0")

length1 = input.int(48, minval=1, title="Length 1", group="MA 1")
source1 = input.source(hl2, title="Source 1", group="MA 1")
type1 = input.string("SMA", title="Type 1", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 1")
timeframe1 = input.timeframe("", title="Timeframe 1", group="MA 1")
color1 = input.color(color.aqua, title="Color 1", group="MA 1")
show1 = input.bool(true, title="Show MA 1", group="MA 1")

length2 = input.int(144, minval=1, title="Length 2", group="MA 2")
source2 = input.source(hl2, title="Source 2", group="MA 2")
type2 = input.string("SMA", title="Type 2", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 2")
timeframe2 = input.timeframe("", title="Timeframe 2", group="MA 2")
color2 = input.color(color.orange, title="Color 2", group="MA 2")
show2 = input.bool(true, title="Show MA 2", group="MA 2")

length3 = input.int(432, minval=1, title="Length 3", group="MA 3")
source3 = input.source(hl2, title="Source 3", group="MA 3")
type3 = input.string("SMA", title="Type 3", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 3")
timeframe3 = input.timeframe("", title="Timeframe 3", group="MA 3")
color3 = input.color(color.green, title="Color 3", group="MA 3")
show3 = input.bool(true, title="Show MA 3", group="MA 3")

length4 = input.int(91, minval=1, title="Length 4", group="MA 4")
source4 = input.source(hl2, title="Source 4", group="MA 4")
type4 = input.string("SMA", title="Type 4", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 4")
timeframe4 = input.timeframe("D", title="Timeframe 4", group="MA 4")
color4 = input.color(color.rgb(159, 110, 208), title="Color 4", group="MA 4") // 浅紫色
style4 = input.string("step", title="Style 4", options=["line", "step"], group="MA 4")
show4 = input.bool(false, title="Show MA 4", group="MA 4")

length5 = input.int(182, minval=1, title="Length 5", group="MA 5")
source5 = input.source(hl2, title="Source 5", group="MA 5")
type5 = input.string("SMA", title="Type 5", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA 5")
timeframe5 = input.timeframe("D", title="Timeframe 5", group="MA 5")
color5 = input.color(color.red, title="Color 5", group="MA 5")
style5 = input.string("step", title="Style 5", options=["line", "step"], group="MA 5")
show5 = input.bool(true, title="Show MA 5", group="MA 5")

// 计算每根均线的值
value0 = request.security(syminfo.tickerid, timeframe0, ma(source0, length0, type0))
value1 = request.security(syminfo.tickerid, timeframe1, ma(source1, length1, type1))
value2 = request.security(syminfo.tickerid, timeframe2, ma(source2, length2, type2))
value3 = request.security(syminfo.tickerid, timeframe3, ma(source3, length3, type3))
value4 = request.security(syminfo.tickerid, timeframe4, ma(source4, length4, type4))
value5 = request.security(syminfo.tickerid, timeframe5, ma(source5, length5, type5))

// 绘制每根均线
plot(show0 ? value0 : na, title="MA 0", color=color0)
plot(show1 ? value1 : na, title="MA 1", color=color1)
plot(show2 ? value2 : na, title="MA 2", color=color2)
plot(show3 ? value3 : na, title="MA 3", color=color3)
plot(show4 ? value4 : na, title="MA 4", color=color4, style=style4 == "step" ? plot.style_stepline : plot.style_line, linewidth=2)
plot(show5 ? value5 : na, title="MA 5", color=color5, style=style5 == "step" ? plot.style_stepline : plot.style_line, linewidth=2)

// 添加策略部分

// 选择均线值
get_ma_value(ma_name) =>
    if (ma_name == "MA 0")
        value0
    else if (ma_name == "MA 1")
        value1
    else if (ma_name == "MA 2")
        value2
    else if (ma_name == "MA 3")
        value3
    else if (ma_name == "MA 4")
        value4
    else
        value5

short_ma_value = get_ma_value(short_term_ma)
mid_ma_value = get_ma_value(mid_term_ma)
long_ma_value = get_ma_value(long_term_ma)
bull_bear_ma_value = get_ma_value(bull_bear_ma)

// 计算波动率
high_close = ta.highest(high, volatility_k)
low_close = ta.lowest(low, volatility_k)
volatility = 100 * (high_close - low_close) / low_close

// 波动率条件背景色
volatilityCondition = (volatility > volatility_threshold)
volatilityConditionBG = (volatility > volatility_threshold) and volatility_threshold != 0

bgcolor(volatilityConditionBG ? color.new(color.green, 90) : na, title="Volatility Background")

// 策略信号
long_condition = (short_ma_value > long_ma_value and ta.crossover(mid_ma_value, long_ma_value))
short_condition = (short_ma_value < long_ma_value and ta.crossunder(mid_ma_value, long_ma_value))

var float stop_level_long = na
var float stop_level_short = na

// 执行策略
if (volatilityCondition and allow_long and (not enable_bull_bear or close > bull_bear_ma_value)) 
    if (long_condition and close > long_ma_value)  // 判断是否立即触发止损
        strategy.entry("Long", strategy.long, qty=capital_pct * strategy.equity / close)
        label.new(bar_index, low*0.996, text="BUY", color=color.green, textcolor=color.white, style=label.style_label_up, size=size.small)

if (volatilityCondition and allow_short and (not enable_bull_bear or close < bull_bear_ma_value)) 
    if (short_condition and close < long_ma_value)  // 判断是否立即触发止损
        strategy.entry("Short", strategy.short, qty=capital_pct * strategy.equity / close)
        label.new(bar_index, high*1.004, text="SELL", color=color.red, textcolor=color.white, style=label.style_label_down, size=size.small)

// 部分平仓逻辑
if (enable_bull_bear)
    // 当当前价格处在牛熊趋势均线之下时
    if (close < bull_bear_ma_value)
        // 平所有多仓
        if (strategy.position_size > 0)
            strategy.close("Long", comment="平所有多仓")
            label.new(bar_index, low*0.996, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_up, size=size.small)
        // 当短期均线在长期均线之上时,中期均线向上穿过长期均线,平空
        if (short_ma_value > long_ma_value and ta.crossover(mid_ma_value, long_ma_value) and volatilityCondition)
            if (strategy.position_size < 0)
                strategy.close("Short", qty=close_pct * strategy.position_size, comment="部分平空")
                label.new(bar_index, high*1.004, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_down, size=size.small)

    // 当当前价格处在牛熊趋势均线之上时
    if (close > bull_bear_ma_value)
        // 平所有空仓
        if (strategy.position_size < 0)
            strategy.close("Short", comment="平所有空仓")
            label.new(bar_index, high*1.004, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_up, size=size.small)
        // 当短期均线在长期均线之下时,中期均线向下穿过长期均线,平多
        if (short_ma_value < long_ma_value and ta.crossunder(mid_ma_value, long_ma_value) and volatilityCondition)
            if (strategy.position_size > 0)
                strategy.close("Long", qty=close_pct * strategy.position_size, comment="部分平多")
                label.new(bar_index, low*0.996, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_down, size=size.small)
else if (not enable_bull_bear and not (allow_long and allow_short))
    // 当短期均线在长期均线之上时,中期均线向上穿过长期均线,平空
    if (short_ma_value > long_ma_value and ta.crossover(mid_ma_value, long_ma_value) and volatilityCondition)
        if (strategy.position_size < 0)
            strategy.close("Short", qty=close_pct * strategy.position_size, comment="部分平空")
            label.new(bar_index, low*0.996, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_up, size=size.small)

    // 当短期均线在长期均线之下时,中期均线向下穿过长期均线,平多
    if (short_ma_value < long_ma_value and ta.crossunder(mid_ma_value, long_ma_value) and volatilityCondition)
        if (strategy.position_size > 0)
            strategy.close("Long", qty=close_pct * strategy.position_size, comment="部分平多")
            label.new(bar_index, high*1.004, text="CLOSE", color=color.gray, textcolor=color.white, style=label.style_label_down, size=size.small)

// 止损处理
if (strategy.position_size > 0)
    stop_level_long_user = strategy.position_avg_price * (1 - stop_loss_user)
    strategy.exit("Stop Loss", from_entry="Long", stop=stop_level_long_user)
else if (strategy.position_size < 0)
    stop_level_short_user = strategy.position_avg_price * (1 + stop_loss_user)
    strategy.exit("Stop Loss", from_entry="Short", stop=stop_level_short_user)