ADR 일평선 교차 전략 - 다차원 기술 지표와 엄격한 손해배상 방지 거래 방법을 통합

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

ADR均线交叉策略 - 融合多维度技术指标和严格止盈止损的交易方法

개요

ADR 일평선 교차 전략은 트레이딩뷰 플랫폼을 기반으로 한 정량화 거래 전략으로, 트렌드를 판단하기 위해 여러 기술 지표, 필터링 신호 및 스톱 손실을 설정하는 기술을 통합합니다. 이 전략은 두 개의 다른 주기의 지표 이동 평균 (EMA) 을 사용하여 주요 추세를 식별하고 평균 실제 파장 (ATR) 을 유동률 필터로 사용하여 위험 대비 동적 스톱 손실을 설정하고 있습니다. 또한 이 전략은 거래 시간 창, 손익계산, 최대 일일 손실과 같은 시장을 통제하는 조치를 도입하여 트렌드 기회를 파악하는 동시에 하향 위험을 엄격하게 제어합니다.

전략적 원칙

  1. 쌍평선 교차: 전략은 두 개의 다른 주기를 가진 EMA 라인을 사용하여 추세를 판단합니다. 단기 EMA가 긴 EMA를 통과할 때 추세가 상승한다고 생각하면 더 많은 신호를 생성합니다. 반대로 단기 EMA가 긴 EMA를 통과할 때 추세가 하락한다고 생각하면 빈 신호를 생성합니다.

  2. ADR 변동률 필터링: 낮은 변동률 환경에서 거래 신호를 생성하는 것을 피하기 위해, 전략은 ADR 지표를 변동률 필터링으로 도입했다. ADR 값이 설정된 최소 문턱보다 높을 때만 거래를 허용한다.

  3. 거래 시간 창: 이 정책은 사용자가 매일 거래의 시작 및 종료 시간을 설정하도록 허용한다. 거래는 지정된 시간 창 내에서만 실행된다. 이는 유동성이 낮거나 더 높은 시기를 피하는 데 도움이됩니다.

  4. 동적 스톱 러스 스톱 러스: 전략은 최근 N根 K 라인의 평균 최고 가격과 최저 가격에 기초하여, 미리 설정된 위험 수익률과 결합하여, 동적 스톱 러스 스톱 러스 스톱 러스 가격을 계산한다. 이것은 각 거래의 위험 수익을 통제할 수 있도록 한다.

  5. 손익/손실 균형: 보유가 일정 수익률을 달성한 후 (사용자가 위험/이익 비율을 설정할 수 있다) 전략은 중지 손실 지점을 오픈 가격, 즉 손익/손실 균형 지점으로 이동시킨다. 이것은 얻은 이익을 보호하는데 도움이 된다.

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

  7. 클로즈 플라이스: 포지션이 스톱레이드 또는 스톱레이드 라인을 만지는지 여부에 관계없이 전략은 모든 포지션을 매 거래일의 일정한 시간에 (예: 16시) 풀고 밤새의 위험을 피합니다.

장점 분석

  1. 강한 트렌드 추적 능력: 트렌드를 판단하기 위해 양평선 교차를 통해 시장의 주요 트렌드를 효과적으로 파악하여 전략의 승률과 수익 잠재력을 높일 수 있습니다.

  2. 유동성 적응력: 유동성 필터로서 ADR 지표를 도입하여 낮은 유동성 환경에서 빈번한 거래를 피할 수 있으며, 무효 신호 및 가짜 돌파로 인한 손실을 줄일 수 있습니다.

  3. 엄격한 위험 통제: 이 전략은 다중 차원에서 동적 금지, 손해배상 균형, 최대 일일 손실 제한 등으로 풍력 통제 조치를 설정하여 전략의 하향 위험을 효과적으로 제어하고 위험 조정 수익을 향상시킵니다.

  4. 매개 변수 유연 조정: 전략의 매개 변수들, 예를 들어, 평균 라인 주기, ADR의 길이, 위험 수익률, 거래 시간 창, 등은 사용자 선호도와 시장 특성에 따라 유연하게 설정되어 전략 성능을 최적화 할 수 있다.

  5. 높은 자동화: 이 전략은 TradingView 플랫폼에 기반하여 거래 논리가 프로그램에서 완전히 자동으로 실행되며, 인간 감정과 주관적 판단의 간섭을 줄여 장기적으로 전략의 안정적인 운영을 유도합니다.

위험 분석

  1. 매개 변수 최적화 위험: 이 전략의 매개 변수가 유연하게 조정될 수 있지만, 과도하게 최적화되면 과도한 적합성으로 이어질 수 있으며, 샘플 외부에서 좋지 않은 성능을 보일 수 있다. 따라서, 매개 변수 설정 시, 전략의 안정성을 보장하기 위해 충분한 재검토와 분석이 필요하다.

  2. 갑작스러운 이벤트 위험: 이 전략은 주로 기술 지표 거래에 기반하고 있으며, 정책 변화, 경제 데이터의 큰 변동 등 일부 갑작스러운 주요 기본 이벤트에 대한 반응이 부족하여 큰 탈퇴를 초래할 수 있습니다.

  3. 트렌드 전환 위험: 트렌드 전환의 중요한 시기에 쌍평선 교차 신호가 지연되어 전략이 최적의 입지 시기를 놓치거나 트렌드 전환 초기 손실을 입게 될 수 있다.

  4. 유동성 위험: 전략이 거래 시간 창을 설정하고 있음에도 불구하고 거래 지표의 유동성이 좋지 않으면 슬라이드 포인트, 거래 지연 등의 위험이 발생할 수 있으며 전략의 성과에 영향을 줄 수 있습니다.

  5. 기술 지표의 실패 위험: 이 전략은 기술 지표에 매우 의존하고 있으며 시장 환경이 크게 변화하여 지표가 원래의 지표적 의미를 잃게 할 경우 전략의 효과는 감소 할 수 있습니다.

최적화 방향

  1. 더 많은 차원의 지표를 도입: 기존의 쌍평선과 ADR를 기반으로 신호의 신뢰성 및 안정성을 높이기 위해 MACD, RSI 등의 더 효과적인 기술 지표를 도입하는 것을 고려할 수 있다.

  2. 동적 최적화 매개 변수: 매개 변수 최적화 메커니즘을 구축할 수 있으며, 다른 시장 상태에 따라 (트렌드형, 격동형 등) 전략의 핵심 매개 변수를 동적으로 조정하여 시장의 변화에 적응할 수 있다.

  3. 기본 요소를 추가하십시오: 경제 데이터, 정책 방향 등과 같은 중요한 기본 지표들을 적절히 고려하면 전략이 시장 추세를 더 잘 파악하고 제때 시스템적 위험을 피하는 데 도움이 될 수 있습니다.

  4. 개선된 항손실 메커니즘: 기존의 동적 항손실 메커니즘을 바탕으로, 추적 항손실, 부분 항손실 등의 방법을 도입하여 수익을 더 잘 보호하고 위험을 통제하기 위해 항손실 메커니즘을 더욱 최적화할 수 있다.

  5. 멀티 지표, 멀티 시간 사이클: 여러 거래 지표와 여러 시간 사이클에 전략을 확장하여 투자 분산 및 시간 사이클 최적화를 통해 전략의 적응성과 안정성을 향상시킵니다.

요약

ADR 일평선 교차 전략은 기술 분석에 기반한 양자화 거래 전략으로 양평선 교차로로 트렌드를 판단하고, ADR 지표로 변동률을 필터링한다. 이 전략은 또한 하향 위험을 제어하기 위해 동적 스톱 손실, 이익 균형, 최대 일일 손실 제한 등을 포함한 엄격한 위험 통제 조치를 설정한다. 이 전략의 장점은 강한 트렌드 추적 능력, 좋은 변동률 적응력, 엄격한 리스크 제어, 파라미터 가변성, 높은 수준의 자동화이다. 그러나 또한 파라미터 최적화 위험, 돌발성 위험, 트렌드 탈환 위험, 유동성 위험 및 기술 지표의 실효성 위험과 같은 몇 가지 위험도 존재한다. 앞으로, 이 전략은 더 많은 지표의 입출, 동적 지표의 최적화, 기본 요소의 추가, 변경된 메커니즘, 주기적 지표의 개조, 적절한 거래의 장점, 그리고 거래의 안정성 및 수익성 등을 고려할 필요가 있다. 그러나 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)


더 많은 내용