리소스 로딩... 로딩...

동적 신호 라인 트렌드 추적 및 변동성 필터링 전략

저자:차오장, 날짜: 2024-11-29 17:02:33
태그:DSLATRRSIZLEMASMAEMA

img

전반적인 설명

이 전략은 동적 신호 라인 (DSL), 변동성 및 동력 지표를 결합한 포괄적 인 거래 시스템입니다. 이 시스템은 정확한 거래 타이밍을 달성하기 위해 신호 필터링을 위해 동력 지표를 사용하여 동적 임계 및 적응성 변동성 대역을 통해 시장 추세를 효과적으로 식별합니다. 이 시스템은 동적 스톱-손실 및 리스크-어워드 비율에 기반한 수익 목표를 포함한 완전한 리스크 관리 메커니즘을 통합합니다.

전략 원칙

핵심 논리는 세 가지 주요 구성 요소로 구성되어 있습니다.

먼저, 동적 신호 라인 시스템은 이동 평균에 기초하여 동적 상위 및 하위 채널 라인을 계산합니다. 이러한 채널 라인은 최근 시장의 최고와 최저에 따라 위치를 자동으로 조정하여 적응 트렌드 추적을 달성합니다. 이 시스템은 또한 트렌드 강도를 확인하고 스톱 로스 포지션을 설정하기 위해 ATR 기반의 동적 변동성 대역을 통합합니다.

두 번째로, 모멘텀 분석 시스템은 제로-래그 기하급수적 이동 평균 (ZLEMA) 으로 최적화된 RSI 지표를 사용합니다. 동적 신호 라인 개념을 RSI에 적용함으로써 시스템은 과잉 구매 및 과잉 판매 지역을 더 정확하게 식별하고 모멘텀 돌파 신호를 생성 할 수 있습니다.

세 번째, 신호 통합 메커니즘. 트레이드 신호는 동시 트렌드 확인 및 추진력 돌파 조건 모두를 만족시켜야 합니다. 긴 엔트리는 상위 밴드 이상의 가격 돌파와 채널 이상의 유지가 필요하며, RSI는 하위 동적 신호 라인을 통과합니다. 짧은 신호는 반대 조건이 동시에 충족되어야합니다.

전략적 장점

  1. 강력한 적응력: 동적 신호 라인 및 변동성 대역은 시장 조건에 자동으로 조정되며 전략이 다른 시장 환경에 적응 할 수 있습니다.
  2. 거짓 신호 필터링: 트렌드와 모멘텀의 이중 확인을 요구함으로써 거짓 신호의 확률을 크게 감소시킵니다.
  3. 포괄적 리스크 관리: ATR 기반의 역동적 스톱 로스 및 리프트 타겟을 리스크 리워드 비율에 기초하여 통합하여 체계적인 리스크 통제를 달성합니다.
  4. 유연한 사용자 정의: 전략 매개 변수는 다른 시장과 기간에 최적화 될 수 있습니다.

전략 위험

  1. 트렌드 역전 위험: 심각한 시장 역전 시, 동적 신호 라인 조정은 충분히 시기적절하지 않을 수 있으며, 더 큰 마감으로 이어질 수 있습니다.
  2. 범위에 제한된 시장 위험: 범위에 제한된 시장에서 빈번한 브레이크오웃은 여러 개의 스톱 로스로 이어질 수 있습니다.
  3. 매개 변수 민감성: 전략 성능은 매개 변수 설정에 민감하며, 부적절한 매개 변수는 전략의 효과에 영향을 줄 수 있습니다.

전략 최적화 방향

  1. 시장 환경 인식: 다른 시장 상태에서 다른 매개 변수 설정을 사용하도록 시장 환경 분류 메커니즘을 추가합니다.
  2. 동적 매개 변수 최적화: 시장 변동성에 따라 신호 라인 및 변동성 대역 매개 변수를 자동으로 최적화하기 위해 적응적 매개 변수 조정 메커니즘을 도입합니다.
  3. 다중 시간 프레임 분석: 거래 결정 신뢰성을 향상시키기 위해 여러 시간 프레임에서 신호를 통합합니다.
  4. 변동성 적응: 높은 변동성 기간 동안 위험 조정 수익률을 향상시키기 위해 중지 손실 범위와 위험 보상 비율을 조정합니다.

결론

이 전략은 동적 신호 라인과 모멘텀 지표의 혁신적인 조합을 통해 효과적인 시장 트렌드 캡처를 달성합니다. 포괄적인 위험 관리 메커니즘과 신호 필터링 시스템은 강력한 실용적 응용 가치를 제공합니다. 지속적인 최적화 및 매개 변수 조정을 통해 전략은 다른 시장 환경에서 안정적인 성능을 유지할 수 있습니다. 특정 위험 지점이 존재하지만 합리적인 매개 변수 설정 및 위험 관리 조치로 제어 할 수 있습니다.


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

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DailyPanda

//@version=5
strategy("DSL Strategy [DailyPanda]",
     initial_capital = 2000,
     commission_value=0.00,
     slippage=3,
     overlay = true)

//--------------------------------------------------------------------------------------------------------------------
// USER INPUTS
//--------------------------------------------------------------------------------------------------------------------

// DSL Indicator Inputs CP
int   len         = input.int(34, "Length", group="CP")      // Length for calculating DSL
int   offset      = input.int(30, "Offset", group="CP")      // Offset for threshold levels
float width       = input.float(1, "Bands Width", step = 0.1, maxval = 2, minval = 0.5, group="CP") // Width for ATR-based bands
float risk_reward = input.float(1.5, "Risk Reward", group="Risk Mgmt") // Risk Reward ratio

// Colors for upper and lower trends
color upper_col = input.color(color.lime, "+", inline = "col")
color lower_col = input.color(color.orange, "-", inline = "col")

// DSL-BELUGA
len_beluga  = input.int(10, "Beluga Length", group="BELUGA")
dsl_mode_inp = input.string("Fast", "DSL Lines Mode", options=["Fast", "Slow"], group="BELUGA")
dsl_mode    = dsl_mode_inp == "Fast" ? 2 : 1

// Colors for DSL-BELUGA
color color_up = #8BD8BD
color color_dn = #436cd3

i_lossPct = input.int(defval=100, title="% max day DD", minval=1, maxval=100, step=1, group="Risk Management")
i_goal = input.bool(title="Enable Daily Goal", defval=false, group="Risk Management")
i_goalPct = input.int(defval=4, title="% Daily Goal", minval=1, step=1, group="Risk Management")


//############################## RISK MANAGEMENT ##############################
// Set maximum intraday loss to our lossPct input
// strategy.risk.max_intraday_loss(i_lossPct, strategy.percent_of_equity)
//strategy.risk.max_intraday_loss(value=1200, type=strategy.cash)

// Store equity value from the beginning of the day
eqFromDayStart = ta.valuewhen(ta.change(dayofweek) > 0, strategy.equity, 0)
// Calculate change of the current equity from the beginning of the current day
eqChgPct = 100 * ((strategy.equity - eqFromDayStart - strategy.openprofit) / (strategy.equity-strategy.openprofit))
f_stopGain = eqChgPct >= i_goalPct and i_goal ? true : false


//--------------------------------------------------------------------------------------------------------------------
// INDICATOR CALCULATIONS
//--------------------------------------------------------------------------------------------------------------------

// Function to calculate DSL lines based on price
dsl_price(float price, int len) =>
    // Initialize DSL lines
    float dsl_up = na
    float dsl_dn = na
    float sma    = ta.sma(price, len)

    // Dynamic upper and lower thresholds calculated with offset
    float threshold_up = ta.highest(len)[offset] 
    float threshold_dn = ta.lowest(len)[offset] 

    // Calculate the DSL upper and lower lines based on price compared to the thresholds
    dsl_up := price > threshold_up ? sma : nz(dsl_up[1]) 
    dsl_dn := price < threshold_dn ? sma : nz(dsl_dn[1])

    // Return both DSL lines
    [dsl_up, dsl_dn]

// Function to calculate DSL bands based on ATR and width multiplier
dsl_bands(float dsl_up, float dsl_dn) =>
    float atr = ta.atr(200) * width // ATR-based calculation for bands
    float upper = dsl_up - atr       // Upper DSL band
    float lower = dsl_dn + atr       // Lower DSL band

    [upper, lower]

// Get DSL values based on the closing price
[dsl_up, dsl_dn] = dsl_price(close, len)

// Calculate the bands around the DSL lines
[dsl_up1, dsl_dn1] = dsl_bands(dsl_up, dsl_dn)


//--------------------------------------------------------------------------------------------------------------------
// DSL-BELUGA INDICATOR CALCULATIONS
//--------------------------------------------------------------------------------------------------------------------

// Calculate RSI with a period of 10
float RSI = ta.rsi(close, 10)

// Zero-Lag Exponential Moving Average function
zlema(src, length) =>
    int   lag      = math.floor((length - 1) / 2)
    float ema_data = 2 * src - src[lag]
    float ema2     = ta.ema(ema_data, length)
    ema2

// Discontinued Signal Lines function
dsl_lines(src, length)=>
    float up  = 0.
    float dn  = 0.
    up := (src > ta.sma(src, length)) ? nz(up[1]) + dsl_mode / length * (src - nz(up[1])) : nz(up[1])  
    dn := (src < ta.sma(src, length)) ? nz(dn[1]) + dsl_mode / length * (src - nz(dn[1])) : nz(dn[1])
    [up, dn]

// Calculate DSL lines for RSI
[lvlu, lvld] = dsl_lines(RSI, len_beluga)

// Calculate DSL oscillator using ZLEMA of the average of upper and lower DSL Lines
float dsl_osc = zlema((lvlu + lvld) / 2, 10)

// Calculate DSL Lines for the oscillator
[level_up, level_dn] = dsl_lines(dsl_osc, 10)

// Detect crossovers for signal generation
bool up_signal = ta.crossover(dsl_osc, level_dn) and dsl_osc < 55
bool dn_signal = ta.crossunder(dsl_osc, level_up) and dsl_osc > 50

//--------------------------------------------------------------------------------------------------------------------
// VISUALIZATION
//--------------------------------------------------------------------------------------------------------------------

// Plot the DSL lines on the chart
plot_dsl_up = plot(dsl_up, color=color.new(upper_col, 80), linewidth=1, title="DSL Up")
plot_dsl_dn = plot(dsl_dn, color=color.new(lower_col, 80), linewidth=1, title="DSL Down")

// Plot the DSL bands
plot_dsl_up1 = plot(dsl_up1, color=color.new(upper_col, 80), linewidth=1, title="DSL Upper Band")
plot_dsl_dn1 = plot(dsl_dn1, color=color.new(lower_col, 80), linewidth=1, title="DSL Lower Band")

// Fill the space between the DSL lines and bands with color
fill(plot_dsl_up, plot_dsl_up1, color=color.new(upper_col, 80))
fill(plot_dsl_dn, plot_dsl_dn1, color=color.new(lower_col, 80))

// Plot signals on the chart
plotshape(up_signal, title="Buy Signal", style=shape.triangleup, location=location.belowbar, size=size.tiny, text="Enter")
plotshape(dn_signal, title="Sell Signal", style=shape.triangledown, location=location.abovebar, size=size.tiny, text="Exit")

// Color the background on signal occurrences
bgcolor(up_signal ? color.new(color_up, 90) : na, title="Up Signal Background", editable = false)
bgcolor(dn_signal ? color.new(color_dn, 90) : na, title="Down Signal Background", editable = false)

//--------------------------------------------------------------------------------------------------------------------
// STRATEGY CONDITIONS AND EXECUTION
//--------------------------------------------------------------------------------------------------------------------

// Variables to hold stop loss and take profit prices
var float long_stop_loss_price  = na
var float long_take_profit_price = na
var float short_stop_loss_price = na
var float short_take_profit_price = na
float pos_size = math.abs(strategy.position_size)

// Long Entry Conditions
bool long_condition1 = not na(dsl_up1) and not na(dsl_dn) and dsl_up1 > dsl_dn
bool long_condition2 = open > dsl_up and close > dsl_up and open[1] > dsl_up and close[1] > dsl_up and open[2] > dsl_up and close[2] > dsl_up
bool long_condition3 = up_signal and pos_size == 0
bool long_condition  = long_condition1 and long_condition2 and long_condition3 and (not f_stopGain)

// Short Entry Conditions
bool short_condition1 = not na(dsl_dn1) and not na(dsl_up) and dsl_dn < dsl_up1
bool short_condition2 = open < dsl_dn1 and close < dsl_dn1 and open[1] < dsl_dn1 and close[1] < dsl_dn1 and open[2] < dsl_dn1 and close[2] < dsl_dn1
bool short_condition3 = dn_signal and pos_size == 0
bool short_condition  = short_condition1 and short_condition2 and short_condition3 and (not f_stopGain)

// Long Trade Execution
if (long_condition and not na(dsl_up1))
    long_stop_loss_price := dsl_up1
    float risk = close - long_stop_loss_price
    if (risk > 0)
        long_take_profit_price := close + risk * risk_reward
        strategy.entry("Long", strategy.long)
        strategy.exit("Exit Long", from_entry="Long", stop=long_stop_loss_price, limit=long_take_profit_price)
else if (strategy.position_size <= 0)
    // Reset when not in a long position
    long_stop_loss_price  := na
    long_take_profit_price := na

// Short Trade Execution
if (short_condition and not na(dsl_dn1))
    short_stop_loss_price := dsl_dn1
    float risk = short_stop_loss_price - close
    if (risk > 0)
        short_take_profit_price := close - risk * risk_reward
        strategy.entry("Short", strategy.short)
        strategy.exit("Exit Short", from_entry="Short", stop=short_stop_loss_price, limit=short_take_profit_price)
else if (strategy.position_size >= 0)
    // Reset when not in a short position
    short_stop_loss_price := na
    short_take_profit_price := na

//--------------------------------------------------------------------------------------------------------------------
// PLOTTING STOP LOSS AND TAKE PROFIT LEVELS
//--------------------------------------------------------------------------------------------------------------------

// Plot the stop loss and take profit levels only when in a position
float plot_long_stop_loss   = strategy.position_size > 0 ? long_stop_loss_price : na
float plot_long_take_profit = strategy.position_size > 0 ? long_take_profit_price : na

float plot_short_stop_loss   = strategy.position_size < 0 ? short_stop_loss_price : na
float plot_short_take_profit = strategy.position_size < 0 ? short_take_profit_price : na

plot(plot_long_stop_loss, title="Long Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr, editable=false)
plot(plot_long_take_profit, title="Long Take Profit", color=color.green, linewidth=2, style=plot.style_linebr, editable=false)

plot(plot_short_stop_loss, title="Short Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr, editable=false)
plot(plot_short_take_profit, title="Short Take Profit", color=color.green, linewidth=2, style=plot.style_linebr, editable=false)


관련

더 많은