Esta estratégia combina três indicadores técnicos: CCI, RSI e Keltner Channels (KC), juntamente com um filtro de tendência para alcançar a negociação bidirecional nos pares de moedas AUDNZD e GBPNZD. Ele usa o CCI e o RSI para determinar as condições de sobrecompra e sobrevenda, o KC como uma referência para stop-loss e take-profit e uma média móvel como um filtro de tendência para abrir posições em linha com a tendência. A estratégia foi testada em dados históricos nos últimos 5 anos, alcançando retornos estáveis.
Esta estratégia emprega vários indicadores clássicos e é relativamente fácil de codificar e backtestar no TradingView. Embora os resultados do backtesting sejam bons, o controle de risco e os ajustes de parâmetros ainda são necessários para negociação ao vivo. Recomenda-se começar com pequenos fundos para testes e aumentar gradualmente o investimento à medida que a experiência se acumula. Com um alto grau de automação, é adequado para investidores conservadores usarem a longo prazo.
/*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)