
이 전략은 CCI, RSI 및 켄터커널 ((KC) 의 세 가지 기술 지표를 사용하여 트렌드 필터와 결합하여 AUDNZD 및 GBPNZD 통화 쌍에서 다방면 양방향 거래를 구현합니다. 이 전략은 CCI와 RSI를 통해 과매매 과매매 상황을 판단하고, KC는 중지 손실의 기준으로 사용하며, 이동 평균을 트렌드 필터로 사용하며, 순조로운 상황에서 포지션 개시 작업을 수행합니다. 이 전략은 지난 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)