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

CCI+RSI+KC 트렌드 필터 양방향 거래 전략

저자:차오장, 날짜: 2024-05-15 16:56:03
태그:CCIRSIKCSMAEMASMMACMATMA

img

전반적인 설명

이 전략은 CCI, RSI, Keltner Channels (KC) 라는 세 가지 기술 지표를 결합하고, AUDNZD와 GBPNZD 통화 쌍에서 양방향 거래를 달성하기 위해 트렌드 필터를 사용합니다. CCI와 RSI를 사용하여 과잉 구매 및 과잉 판매 조건을 결정하고, KC를 스톱 로스 및 영업 취득의 기준으로 사용하고, 트렌드에 따라 포지션을 여는 트렌드 필터로 이동 평균을 사용합니다. 전략은 지난 5 년 동안 역사적 데이터에 대한 역 테스트를 통해 안정적인 수익을 얻었습니다.

전략 원칙

  1. CCI, RSI 및 KC 지표를 계산합니다. 상단 KC 선은 중간선 더하기 ATR이고 하단 선은 중간선 빼기 ATR입니다.
  2. 입력 매개 변수에 기초하여 이동 평균 유형 (SMA, EMA, SMMA, CMA, 또는 TMA) 및 트렌드 필터 방법 (OFF, Normal, 또는 Reversed) 을 선택합니다.
  3. 긴 진입 조건: 긴, CCI < 과잉 판매 라인, 닫기 < KC 하위 라인, RSI < 과잉 판매 라인, 볼륨 > 50 기간 평균 볼륨 * 곱셈자, 현재 긴 포지션이 없습니다.
  4. 단기 입시 조건: 단기, CCI > 과잉 매수 라인, 클로즈 > KC 상위 라인, RSI > 과잉 매수 라인, 볼륨 > 50 기간 평균 볼륨 * 곱셈자, 현재 단기 포지션이 없습니다.
  5. 긴 출구 조건: CCI > 0. 짧은 출구 조건: CCI < 0.
  6. 포지션을 열고 닫을 때 경고를 보내십시오.

전략적 장점

  1. 포괄적인 분석을 위해 여러 지표를 결합하여 신호 정확성을 향상시킵니다.
  2. 트렌드 필터 방법을 사용해서 시장 트렌드에 따라 유연한 조정을 할 수 있습니다.
  3. 다양한 시장 특성에 적응하는 여러 이동 평균 유형을 제공합니다.
  4. 장기적인 역사 데이터를 통해 검증되었으며 안정성과 장기적인 사용에 적합성을 보여줍니다.
  5. 다양한 시장 조건에 적합한 양방향 거래로 더 많은 수익 기회를 제공합니다.
  6. 고도로 자동화 되어서, 수동 개입이 필요없고, 시간과 노력을 절약합니다.

전략 위험

  1. 기존의 스톱 로즈와 테크프리트가 없어서 극한 시장 조건에서 상당한 마감으로 이어질 수 있습니다.
  2. 불안한 시장에서 포지션의 빈번한 개점과 폐쇄를 경험할 수 있으며 거래 비용을 증가시킬 수 있습니다.
  3. 비교적 짧은 CCI 기간을 사용해서 소음 신호를 생성할 수 있습니다.
  4. 트렌드 필터는 트렌드가 불분명하거나 시장 변동성이 증가할 때 제한된 효과를 가질 수 있습니다.
  5. 고정된 포지션 사이즈, 시장 변동성 변화에 적응할 수 없습니다.

전략 최적화 방향

  1. 단일 거래 리스크를 제어하기 위해 트레일링 스톱 또는 고정 포인트 스톱 손실을 추가하는 것을 고려하십시오.
  2. 소음 신호를 줄이기 위해 RSI와 CCI 매개 변수를 더 최적화합니다.
  3. ATR와 같은 변동성 지표를 도입하여 시장 변동성에 따라 포지션 크기와 스톱 로스를 조정하는 것을 고려하십시오.
  4. 더 많은 통화 쌍을 추가하고 각 도구의 특성에 따라 매개 변수를 개별적으로 최적화하십시오.
  5. 기계 학습과 다른 인공지능 기술을 도입하여 적응적 매개 변수 최적화를 시도합니다.

요약

이 전략은 여러 가지 고전적 인 지표를 사용하며 트레이딩뷰에서 비교적 쉽게 코딩 및 백테스트 할 수 있습니다. 백테스트 결과가 좋지만 라이브 트레이딩에 대한 위험 관리 및 매개 변수 조정은 여전히 필요합니다. 테스트를 위해 작은 자금으로 시작하여 경험을 축적함에 따라 점차 투자를 증가시키는 것이 좋습니다. 높은 수준의 자동화로 보수적인 투자자가 장기적으로 사용할 수 있습니다.


/*backtest
start: 2024-04-01 00:00:00
end: 2024-04-30 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('CCI Strategy with Trend Filter AUDNZD, GBPNZD', overlay=true, default_qty_type=strategy.cash, default_qty_value=50000, commission_value=0.0005, slippage=2, initial_capital=10000)

// State variables to ensure one entry per signal
var bool isLongOpen = false
var bool isShortOpen = false

// Input Parameters for allowing long and short trades
allowLong = input(true, title='Allow Long Trades')
allowShort = input(true, title='Allow Short Trades')

// Trend Filter Inputs
maType = input.string(title='MA Type', options=['OFF', 'SMA', 'EMA', 'SMMA', 'CMA', 'TMA'], defval='OFF')
trendFilterMethod = input.string(title='Trend Filter Method', options=['OFF', 'Normal', 'Reversed'], defval='OFF')
maLength = input(14, title='MA Length')

// Other Input Parameters
lengthKC = input(30, title='Keltner Channels Length')
multKC = input(0.7, title='Keltner Channels Multiplier')
lengthCCI = input(5, title='CCI Length')
overboughtCCI = input(75, title='CCI Overbought Level')
oversoldCCI = input(-75, title='CCI Oversold Level')
rsiPeriod = input(30, title='RSI Period')
rsiOverbought = input(60, title='RSI Overbought Level')
rsiOversold = input(60, title='RSI Oversold Level')
volumeMultiplier = input.float(0, title='Volume Multiplier', step=0.1, minval=0)

// Define Moving Averages
var float maValue = na
if maType == 'SMA'
    maValue := ta.sma(close, maLength)
else if maType == 'EMA'
    maValue := ta.ema(close, maLength)
else if maType == 'SMMA'
    float initialSMMA = ta.sma(close, maLength)
    maValue := na(maValue[1]) ? initialSMMA : (maValue[1] * (maLength - 1) + close) / maLength
else if maType == 'CMA'
    float firstSMA = ta.sma(close, maLength)
    float secondSMA = ta.sma(close, maLength)
    maValue := na(maValue[1]) ? firstSMA : (firstSMA + secondSMA - maValue[1]) / 2
else if maType == 'TMA'
    maValue := ta.sma(ta.sma(close, math.round(maLength / 2)), math.round(maLength / 2) + 1)

// Entry Conditions with Trend Filter
longCondition = allowLong and (trendFilterMethod == 'OFF' or trendFilterMethod == 'Normal' and close > maValue or trendFilterMethod == 'Reversed' and close < maValue)
shortCondition = allowShort and (trendFilterMethod == 'OFF' or trendFilterMethod == 'Normal' and close < maValue or trendFilterMethod == 'Reversed' and close > maValue)

// Keltner Channels
typicalPrice = hlc3
middleLine = ta.sma(typicalPrice, lengthKC)
range_1 = multKC * ta.atr(lengthKC)
upperChannel = middleLine + range_1
lowerChannel = middleLine - range_1

// CCI
cci = ta.cci(close, lengthCCI)

// RSI
rsi = ta.rsi(close, rsiPeriod)

// Volume
volCondition = volume > ta.sma(volume, 50) * volumeMultiplier

// Combined Entry Conditions with Trend Filter and state check
longCondition := longCondition and cci < oversoldCCI and low < lowerChannel and rsi < rsiOversold and volCondition and not isLongOpen
shortCondition := shortCondition and cci > overboughtCCI and high > upperChannel and rsi > rsiOverbought and volCondition and not isShortOpen

// Execute orders at the open of the new bar after conditions are met
if longCondition
    strategy.entry('Long', strategy.long)
    alert('LicenseID,buy,AUDNZD,risk=1')
    isLongOpen := true
if shortCondition
    strategy.entry('Short', strategy.short)
    alert('LicenseID,sell,AUDNZD,risk=1')
    isShortOpen := true

// Exit Conditions and Alerts
longExitCondition = cci > 0
shortExitCondition = cci < 0
if (longExitCondition and isLongOpen)
    strategy.close('Long')
    alert('LiceneseID,closelong,AUDNZD')
    isLongOpen := false
if (shortExitCondition and isShortOpen)
    strategy.close('Short')
    alert('LicenseID,closeshort,AUDNZD')
    isShortOpen := false

// Plotting
plot(upperChannel, color=color.new(color.red, 0), linewidth=1)
plot(lowerChannel, color=color.new(color.green, 0), linewidth=1)
hline(overboughtCCI, 'Overbought', color=color.red)
hline(oversoldCCI, 'Oversold', color=color.green)


관련

더 많은