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

EMA 크로스 ADR 전략 - 엄격한 리스크 관리와 함께 다차원적 기술 지표 기반 거래 방법

저자:차오장, 날짜: 2024-03-28 16:46:29
태그:

img

전반적인 설명

EMA 크로스 ADR 전략은 트레이딩뷰 플랫폼을 기반으로 한 양적 거래 전략이다. 트렌드를 결정하고 필터 신호를 표시하며 스톱 로스 및 영업 한도를 설정하기 위해 여러 기술적 지표를 결합합니다. 이 전략은 주요 트렌드를 식별하기 위해 서로 다른 기간을 가진 두 개의 기하급수적인 이동 평균 (EMA) 을 사용하고, 평균 일일 범위 (ADR) 를 변동성 필터로 사용하고, 위험-상금 비율을 기반으로 스톱 로스 및 영업 한도를 동적으로 설정합니다. 또한 전략에는 거래 시간 창, 브레이크 이븐 스톱 및 최대 일일 손실 한도와 같은 위험 관리 조치가 포함되어 있으며, 추세 기회를 포착하는 동시에 하락 위험을 엄격히 제어하는 것을 목표로합니다.

전략 원칙

  1. 듀얼 EMA 크로스오버 (Dual EMA Crossover): 이 전략은 트렌드를 결정하기 위해 서로 다른 기간을 가진 두 개의 EMA를 사용합니다. 단기 EMA가 장기 EMA를 넘으면 상승 추세로 간주되어 긴 신호를 생성합니다. 반대로 단기 EMA가 장기 EMA를 넘으면 하향 추세로 간주되어 짧은 신호를 생성합니다.

  2. ADR 변동성 필터: 낮은 변동성 환경에서 거래 신호를 생성하는 것을 피하기 위해 전략은 변동성 필터로 ADR 지표를 도입합니다. ADR 값이 미리 설정된 최소 문턱을 초과 할 때만 포지션을 열 수 있습니다.

  3. 거래 시간 창: 전략은 사용자가 매일 거래의 시작 및 종료 시간을 설정할 수 있습니다. 거래는 지정된 시간 창 내에서만 실행되며, 유동성 또는 매우 변동적인 기간을 피하는 데 도움이됩니다.

  4. 동적 스톱 로스 및 트레이프: 전략은 가장 최근의 N 촛불의 평균 최고 및 최저 가격을 기반으로 동적으로 스톱 로스 및 트레이프 가격을 계산하며, 미리 설정된 리스크 리워드 비율과 결합하여 각 거래의 리스크 리워드를 제어 할 수 있도록합니다.

  5. 브레이크 이븐 스톱: 포지션이 특정 수익 수준 (사용자 정의 위험 보상 비율) 에 도달하면 전략은 스톱 로스를 브레이크 이븐 포인트 (입시 가격) 로 이동시킵니다. 이것은 이미 얻은 이익을 보호하는 데 도움이됩니다.

  6. 최대 일일 손실 제한: 하루 최대 손실을 제어하기 위해 전략은 일일 손실 제한을 설정합니다. 일일 손실이 이 제한에 도달하면 전략은 다음 날 열리기 전까지 거래를 중단합니다.

  7. 모든 포지션을 하루 끝으로 닫습니다. 포지션이 수익을 취하거나 손해를 막는 수준에 도달했는지 여부에 관계없이 전략은 하루 하루 위험을 피하기 위해 모든 포지션을 매 거래일에 일정한 시간에 닫습니다. (예: 16:00)

이점 분석

  1. 강한 트렌드 추적 능력: 트렌드를 결정하기 위해 이중 EMA 크로스오버를 사용하여 전략은 주요 시장 트렌드를 효과적으로 파악하여 승률과 수익 잠재력을 향상시킬 수 있습니다.

  2. 변동성에 대한 좋은 적응력: 변동성 필터로서의 ADR 지표의 도입은 낮은 변동성 환경에서 빈번한 거래를 피할 수 있으며, 유효하지 않은 신호 및 잘못된 파업으로 인한 손실을 줄일 수 있습니다.

  3. 엄격한 위험 통제: 전략은 다중 차원에서 위험 통제 조치를 설정합니다. 동적 인 스톱 로스 및 영업 취득, 브레이크 이븐 스톱 및 최대 일일 손실 제한을 포함하여 하향 위험을 효과적으로 제어하고 위험 조정 수익을 향상시킵니다.

  4. 유연한 매개 변수 설정: EMA 기간, ADR 길이, 리스크/어워드 비율, 거래 시간 창 등 전략의 다양한 매개 변수들은 전략 성과를 최적화하기 위해 사용자 선호도와 시장 특성에 따라 유연하게 설정될 수 있습니다.

  5. 높은 자동화 수준: 전략은 트레이딩뷰 플랫폼을 기반으로 하며, 거래 논리는 전적으로 프로그램에서 실행되며, 인간의 감정과 주관적 판단의 간섭을 줄여 전략의 장기적인 안정적인 작동을 촉진합니다.

위험 분석

  1. 매개 변수 최적화 위험: 전략의 매개 변수를 유연하게 조정할 수 있지만, 과도한 최적화는 과도한 적합성과 샘플 외의 낮은 성능을 초래할 수 있습니다. 따라서 매개 변수를 설정할 때 전략의 견고성을 보장하기 위해 충분한 백테스팅과 분석이 필요합니다.

  2. 갑작스러운 이벤트 위험: 전략은 주로 기술 지표에 기반하여 거래되며 정책 변화 또는 중요한 경제 데이터 변동과 같은 갑작스러운 주요 근본 이벤트에 충분히 반응하지 않을 수 있습니다.

  3. 트렌드 역전 위험: 트렌드 역전의 중요한 기간 동안 이중 EMA 크로스오버 신호는 지연될 수 있으며, 트렌드 역전 초기에는 전략이 가장 좋은 시기를 놓치거나 손실을 입을 수 있습니다.

  4. 유동성 위험: 전략은 거래 시간 창을 설정하지만 거래되는 도구의 유동성이 좋지 않으면 여전히 슬리프 및 거래 지연과 같은 위험에 직면 할 수 있으며 전략 성과에 영향을 줄 수 있습니다.

  5. 기술 지표 실패 위험: 전략은 기술 지표에 크게 의존합니다. 시장 조건이 크게 변화하여 지표가 원래의 의미를 잃게되면 전략의 효과는 감소 할 수 있습니다.

최적화 방향

  1. 더 많은 차원 지표를 도입: 기존의 이중 EMA와 ADR를 기반으로 신호의 신뢰성과 견고성을 향상시키기 위해 MACD 및 RSI와 같은 더 효과적인 기술적 지표를 도입하는 것을 고려하십시오.

  2. 동적 매개 변수 최적화: 시장 변화에 적응하기 위해 다른 시장 상태 (트렌드 또는 오스실레이션과 같은) 를 기반으로 주요 전략 매개 변수를 동적으로 조정하는 매개 변수 최적화 메커니즘을 구축합니다.

  3. 기본 요소를 포함합니다. 경제 데이터와 정책 방향과 같은 몇 가지 중요한 기본 지표를 적절히 고려하여 전략이 시장 동향을 더 잘 파악하고 제때 시스템 위험을 피하도록 도울 수 있습니다.

  4. 스톱 로스 및 영업 취득 메커니즘을 개선: 기존의 동적 스톱 로스 및 영업 취득 기반의 스톱 로스 및 영업 취득의 논리를 더 최적화하여 수익을 더 잘 보호하고 위험을 통제하기 위해 후속 스톱 로스 및 부분 영업 취득을 도입합니다.

  5. 여러 도구와 시간 프레임: 여러 거래 도구와 시간 프레임에 전략을 확장하고 다양한 투자 및 시간 프레임 최적화를 통해 전략의 적응력과 안정성을 향상시킵니다.

요약

EMA 크로스 ADR 전략은 기술 분석을 기반으로 한 양적 거래 전략이다. 이중 EMA 크로스오버를 통해 트렌드를 결정하고 변동성 필터링을 위해 ADR 지표를 사용합니다. 전략은 또한 역동적 인 스톱 로스 및 수익 취득, 브레이크 이븐 스톱 및 최대 일일 손실 제한을 포함한 엄격한 위험 통제 조치를 설정합니다. 전략의 장점은 트렌드 추적 능력, 좋은 변동성 적응력, 엄격한 위험 통제, 유연한 매개 변수 설정 및 높은 수준의 자동화입니다. 그러나, 그것은 또한 매개 변수 최적화 위험, 갑작스러운 이벤트 위험, 트렌드 역전 위험, 유동성 위험, 기술 지표 실패 위험과 같은 몇 가지 위험을 가지고 있습니다. 미래에 전략은 더 실용적인 매개 변수, 역동적 인 최적화, 기본 위험 요소를 통합하고 수익을 개선하는 것과 같은 여러 측면을 고려하고 최적화 할 수 있습니다.


/*backtest
start: 2024-02-26 00:00:00
end: 2024-03-27 00:00:00
period: 2h
basePeriod: 15m
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/
// © Sameh_Hussein

//@version=5
strategy('EMA Cross ADR Strategy with Stats', overlay=true)

// Adjustable Parameters
shortEmaLength = input(10, title='Short EMA Length')
longEmaLength = input(50, title='Long EMA Length')
adrLength = input(14, title='ADR Length')
riskRewardRatio = input(2.0, title='Risk/Reward Ratio')
lookbackCandles = input(10, title='Lookback Candles for Stop Loss')
startTime = input(0900, title='Start Time')
endTime = input(1600, title='End Time')
minAdrValue = input(10, title='Minimum ADR Value for Entry')
breakEvenProfit = input.float(1.0, title='Break-Even Profit', minval=0.0)
breakEvenRR = input.float(1.0, title='Break-Even Risk-Reward Ratio', minval=0.0)
dailyLossLimit = input(-2000.0, title='Daily Loss Limit')

// Exponential Moving Averages
shortEma = ta.ema(close, shortEmaLength)
longEma = ta.ema(close, longEmaLength)

// Average Daily Range
adr = ta.sma(ta.tr, adrLength)

// Time Filter Function
timeFilter() => true

// Entry Conditions with ADR filter
longCondition = ta.crossover(shortEma, longEma) and timeFilter() and adr > minAdrValue
shortCondition = ta.crossunder(shortEma, longEma) and timeFilter() and adr > minAdrValue

// Calculate the average low and average high of the previous 'lookbackCandles' candles
averageLow = ta.sma(low, lookbackCandles)
averageHigh = ta.sma(high, lookbackCandles)

// Risk and Reward Calculation
stopLossLong = averageLow
takeProfitLong = close + (close - averageLow) * riskRewardRatio
stopLossShort = averageHigh
takeProfitShort = close - (averageHigh - close) * riskRewardRatio

// Entry Control Variables
var longEntryAllowed = true
var shortEntryAllowed = true

// Update entry price on trade execution
var float entryPriceLong = na
var float entryPriceShort = na

if (strategy.position_size > 0)
    if (strategy.position_size[1] <= 0)
        entryPriceLong := strategy.opentrades.entry_price(strategy.opentrades - 1)
    else
        entryPriceLong := entryPriceLong
else
    entryPriceLong := na

if (strategy.position_size < 0)
    if (strategy.position_size[1] >= 0)
        entryPriceShort := strategy.opentrades.entry_price(strategy.opentrades - 1)
    else
        entryPriceShort := entryPriceShort
else
    entryPriceShort := na

// Adjust stop loss to break-even plus the defined profit when the specified risk-reward ratio is reached
breakEvenTriggerLong = entryPriceLong + (entryPriceLong - stopLossLong) * breakEvenRR
breakEvenTriggerShort = entryPriceShort - (stopLossShort - entryPriceShort) * breakEvenRR

if (longEntryAllowed and close >= breakEvenTriggerLong)
    stopLossLong := entryPriceLong + breakEvenProfit

if (shortEntryAllowed and close <= breakEvenTriggerShort)
    stopLossShort := entryPriceShort - breakEvenProfit

// Close all trades at 1600
if (hour == 15 and minute == 59)
    strategy.close_all(comment='Close at 1600')

// Define the daily loss variable and last trade day
var float[] dailyLossArray = array.new_float(1, 0.0)
var int[] lastTradeDayArray = array.new_int(1, na)

// Function to update the daily loss
updateDailyLoss() =>
    _dailyLoss = array.get(dailyLossArray, 0)
    _lastTradeDay = array.get(lastTradeDayArray, 0)
    if na(_lastTradeDay) or dayofmonth != _lastTradeDay
        _dailyLoss := 0.0
        array.set(lastTradeDayArray, 0, dayofmonth)
    if not na(strategy.closedtrades.entry_bar_index(strategy.closedtrades - 1))
        _dailyLoss += strategy.closedtrades.profit(strategy.closedtrades - 1)
    array.set(dailyLossArray, 0, _dailyLoss)

// Call the function to update the daily loss
updateDailyLoss()

// Execute Strategy
if longCondition and longEntryAllowed
    strategy.entry('Long', strategy.long)
    strategy.exit('Take Profit/Stop Loss', 'Long', stop=stopLossLong, limit=takeProfitLong)
    longEntryAllowed := false

if shortCondition and shortEntryAllowed
    strategy.entry('Short', strategy.short)
    strategy.exit('Take Profit/Stop Loss', 'Short', stop=stopLossShort, limit=takeProfitShort)
    shortEntryAllowed := false

// Reset entry control variables on position close
if strategy.position_size == 0
    longEntryAllowed := true
    shortEntryAllowed := true

// // Statistics
// winRate = strategy.wintrades / strategy.closedtrades * 100
// totalTrades = strategy.closedtrades
// averageProfit = strategy.grossprofit / strategy.wintrades
// averageLoss = strategy.grossloss / strategy.losstrades

// // Plotting
// plot(shortEma, color=color.new(color.red, 0), title='Short EMA')
// plot(longEma, color=color.new(color.blue, 0), title='Long EMA')

// // Display Table
// table statsTable = table.new(position=position.top_right, columns=2, rows=4, bgcolor=color.gray, border_width=1)
// table.cell(statsTable, column=0, row=0, text='Win Rate (%)', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=0, text=str.tostring(winRate), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=1, text='Total Trades', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=1, text=str.tostring(totalTrades), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=2, text='Average Profit', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=2, text=str.tostring(averageProfit), bgcolor=color.blue)
// table.cell(statsTable, column=0, row=3, text='Average Loss', bgcolor=color.blue)
// table.cell(statsTable, column=1, row=3, text=str.tostring(averageLoss), bgcolor=color.blue)


더 많은