Strategy vault / Mean reversion
CCI Mean Reversion Channel Strategy
This strategy is designed as a flexible trend following trading system based on the CCI indicator. It can generate trading signals based on CCI zero line crossovers or custom upper/lower band crosses. The strategy…

Overview
This strategy is designed as a flexible trend following trading system based on the CCI indicator. It can generate trading signals based on CCI zero line crossovers or custom upper/lower band crosses. The strategy allows setting fixed stop loss and take profit ratios, trading in specific time frames, and more.
Strategy Logic
Use CCI zero line crossovers to determine market trends. CCI crossing above zero is a bullish signal and crossing below is a bearish signal.
Set custom CCI upper and lower bands. CCI crossing above upper band is bullish and crossing below lower band is bearish. Band crossovers act as stops.
Option to only trade in specific time frames and close all positions outside those periods. Can also trade in fixed daily time frames.
Set fixed stop loss and take profit percentages.
Customizable alert messages for entry and exit signals.
Highly customizable strategy with adjustable CCI parameters, bands, stops, etc.
Advantage Analysis
CCI sensitive to price changes, good for catching trend reversals.
Custom bands can be adjusted for different markets. Band cross stops help control risk.
Support trading in different time frames with optimized parameters based on characteristics.
Fixed stop loss/take profit preset risk/reward ratios and limit risk.
Fully customizable parameters optimize strategy for different products and market conditions.
Risk Analysis
CCI prone to false signals, should verify signals with longer timeframe indicators.
Fixed stop/take percentages cannot adapt to changing market conditions.
Trading in fixed time frames risks missing opportunities during range periods.
Frequent parameter optimizations may lead to over-trading or missing trades.
Macro factors should be considered, optimization alone insufficient to eliminate risks.
Optimization Directions
Add longer timeframe indicators to verify CCI signals.
Incorporate dynamic stops/takes such as ATR.
Test parameters in different time frames and find high-efficiency periods.
Optimize CCI parameters and bands for changing markets.
Consider incorporating other factors like volatility and volume.
Select time frames fitting for traded products.
Consider machine learning to automate strategy optimizations.
Summary
Overall this is a very flexible and customizable trend following system. Key advantages are using CCI for trends, custom bands to limit risk, fixed stops/takes, and time frame selection. Need to watch for false CCI signals and inflexible stops. Future improvements could come from optimizing parameters, filtering signals, selecting efficient time frames, and incorporating machine learning for automatic adaptations to market changes, in order to achieve more consistent excess returns.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1 | 20 | CCI Length |
| v_input_2_close | 0 | Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4 |
| v_input_3 | timestamp(2099-10-01T00:00:00) | Backtesting Start Date |
| v_input_4 | timestamp(9999-12-31T00:00:00) | Backtesting End Date |
| v_input_5 | Time Frame To Enter Trades | |
| v_input_6 | false | Enable Close Trade At End Of Time Frame |
| v_input_7 | true | Enter First Trade ASAP |
| v_input_8 | false | Wait For Cross To Enter First Trade |
| v_input_9 | true | Use CCI Simple Cross Line For Entries & Exits |
| v_input_10 | false | Use Upper & Lower Bands For Entries & Exits |
| v_input_11 | false | CCI Simple Cross |
| v_input_12 | 100 | CCI Enter Long Band |
| v_input_13 | 100 | CCI Exit Long Band |
| v_input_14 | -100 | CCI Enter Short Band |
| v_input_15 | -100 | CCI Exit Short Band |
| v_input_16 | false | Enable Stop Loss |
| v_input_17 | false | Enable Take Profit |
| v_input_18 | 5 | Stop Loss % |
| v_input_19 | 10 | Take Profit % |
| v_input_20 | Long Entry message | |
| v_input_21 | Short Entry message | |
| v_input_22 | Close Long message | |
| v_input_23 | Close Short message |
Source Pine Script
/*backtest
start: 2023-10-01 00:00:00
end: 2023-10-31 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © REV0LUTI0N
//@version=4
strategy(title="CCI Strategy", overlay=true, initial_capital = 10000, default_qty_value = 10000, default_qty_type = strategy.cash)
//CCI Code
length = input(20, minval=1, title="CCI Length")
src = input(close, title="Source")
ma = sma(src, length)
cci = (src - ma) / (0.015 * dev(src, length))
// Strategy Backtesting
startDate = input(timestamp("2099-10-01T00:00:00"), type = input.time, title='Backtesting Start Date')
finishDate = input(timestamp("9999-12-31T00:00:00"), type = input.time, title='Backtesting End Date')
time_cond = true
//Time Restriction Settings
startendtime = input("", title='Time Frame To Enter Trades')
enableclose = input(false, title='Enable Close Trade At End Of Time Frame')
timetobuy = true
timetoclose = true
//Strategy Settings
//Strategy Settings - Enable Check Boxes
enableentry = input(true, title="Enter First Trade ASAP")
enableconfirmation = input(false, title="Wait For Cross To Enter First Trade")
enablezero =input(true, title="Use CCI Simple Cross Line For Entries & Exits")
enablebands = input(false, title="Use Upper & Lower Bands For Entries & Exits")
//Strategy Settings - Band Sources
ccisource = input(0, title="CCI Simple Cross")
upperbandsource =input(100, title="CCI Enter Long Band")
upperbandexitsource =input(100, title="CCI Exit Long Band")
lowerbandsource =input(-100, title="CCI Enter Short Band")
lowerbandexitsource =input(-100, title="CCI Exit Short Band")
//Strategy Settings - Crosses
simplecrossup = crossover(cci, ccisource)
simplecrossdown = crossunder(cci, ccisource)
uppercrossup = crossover(cci, upperbandsource)
lowercrossdown = crossunder(cci, lowerbandsource)
uppercrossdown = crossunder(cci, upperbandexitsource)
lowercrossup = crossover(cci, lowerbandexitsource)
upperstop = crossunder(cci, upperbandsource)
lowerstop = crossover(cci, lowerbandsource)
// Stop Loss & Take Profit % Based
enablesl = input(false, title='Enable Stop Loss')
enabletp = input(false, title='Enable Take Profit')
stopTick = input(5.0, title='Stop Loss %', type=input.float, step=0.1) / 100
takeTick = input(10.0, title='Take Profit %', type=input.float, step=0.1) / 100
longStop = strategy.position_avg_price * (1 - stopTick)
shortStop = strategy.position_avg_price * (1 + stopTick)
shortTake = strategy.position_avg_price * (1 - takeTick)
longTake = strategy.position_avg_price * (1 + takeTick)
plot(strategy.position_size > 0 and enablesl ? longStop : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Fixed SL")
plot(strategy.position_size < 0 and enablesl ? shortStop : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Short Fixed SL")
plot(strategy.position_size > 0 and enabletp ? longTake : na, style=plot.style_linebr, color=color.green, linewidth=1, title="Long Take Profit")
plot(strategy.position_size < 0 and enabletp ? shortTake : na, style=plot.style_linebr, color=color.green, linewidth=1, title="Short Take Profit")
// Alert messages
message_enterlong = input("", title="Long Entry message")
message_entershort = input("", title="Short Entry message")
message_closelong = input("", title="Close Long message")
message_closeshort = input("", title="Close Short message")
//Strategy Execution
//Strategy Execution - Simple Line Cross
if (cci > ccisource and enablezero and enableentry and time_cond and timetobuy)
strategy.entry("Long", strategy.long, alert_message = message_enterlong)
if (cci < ccisource and enablezero and enableentry and time_cond and timetobuy)
strategy.entry("Short", strategy.short, alert_message = message_entershort)
if (simplecrossup and enablezero and enableconfirmation and time_cond and timetobuy)
strategy.entry("Long", strategy.long, alert_message = message_enterlong)
if (simplecrossdown and enablezero and enableconfirmation and time_cond and timetobuy)
strategy.entry("Short", strategy.short, alert_message = message_entershort)
//Strategy Execution - Upper and Lower Band Entry
if (uppercrossup and enablebands and time_cond and timetobuy)
strategy.entry("Long", strategy.long, alert_message = message_enterlong)
if (lowercrossdown and enablebands and time_cond and timetobuy)
strategy.entry("Short", strategy.short, alert_message = message_entershort)
//Strategy Execution - Upper and Lower Band Exit
if strategy.position_size > 0 and uppercrossdown and enablebands and time_cond and timetobuy
strategy.close_all(alert_message = message_closelong)
if strategy.position_size < 0 and lowercrossup and enablebands and time_cond and timetobuy
strategy.close_all(alert_message = message_closeshort)
//Strategy Execution - Upper and Lower Band Stops
if strategy.position_size > 0 and upperstop and enablebands and time_cond and timetobuy
strategy.close_all(alert_message = message_closelong)
if strategy.position_size < 0 and lowerstop and enablebands and time_cond and timetobuy
strategy.close_all(alert_message = message_closeshort)
//Strategy Execution - Close Trade At End Of Time Frame
if strategy.position_size > 0 and timetoclose and enableclose and time_cond
strategy.close_all(alert_message = message_closelong)
if strategy.position_size < 0 and timetoclose and enableclose and time_cond
strategy.close_all(alert_message = message_closeshort)
//Strategy Execution - Stop Loss and Take Profit
if strategy.position_size > 0 and enablesl and time_cond
strategy.exit(id="Close Long", stop=longStop, limit=longTake, alert_message = message_closelong)
if strategy.position_size < 0 and enablesl and time_cond
strategy.exit(id="Close Short", stop=shortStop, limit=shortTake, alert_message = message_closeshort)
if strategy.position_size > 0 and enabletp and time_cond
strategy.exit(id="Close Long", stop=longStop, limit=longTake, alert_message = message_closelong)
if strategy.position_size < 0 and enabletp and time_cond
strategy.exit(id="Close Short", stop=shortStop, limit=shortTake, alert_message = message_closeshort)
Published by ChaoZhang on the FMZ strategy square · last modified 2023-11-01. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.
Build this with AgenKit
A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/CCI-Mean-Reversion-Channel-Strategy.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- Get tests, backtest, risk controls and a paper-trading switch
Understand it first
Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.
Related specs
- Multi Indicator Scoring Trading StrategyPine Script · Mean reversion · 1d
- MACD RSI and EMA StrategyPine Script · Mean reversion · 1d
- Dynamic CCI Support and Resistance StrategyPine Script · Mean reversion · 1h
- Triple Indicator Momentum Reversal StrategyPine Script · Mean reversion · 2h
- Mean Reversion Line StrategyPine Script · Mean reversion · 1d
- Trend Reversal SystemPine Script · Mean reversion · 1d