StochCross_CCI_v2
Download scriptThis technical indicator is designed to identify high-probability trading entries by combining momentum, trend direction, and market volatility. Rather than relying on a single signal, it uses a multi-layered filtering system to ensure that buy and sell signals are only generated when several market conditions align simultaneously.
How the Logic Works
The script monitors four distinct types of market data to validate a trade signal:
1. Momentum Crossover (Stochastic Oscillator) The primary trigger is based on the Stochastic Oscillator. The tool looks for a "cross" between two specific internal lines of this oscillator. A bullish crossover occurs when the main line moves above the signal line, while a bearish crossover occurs when it moves below.
2. Trend Filtering (CCI - Commodity Channel Index) To avoid trading against the dominant market direction, the script uses the Commodity Channel Index (CCI). It evaluates two different timeframes of this indicator:
- Long-Term Trend: It checks the broader market trend to ensure the overall "big picture" is favorable.
- Entry Trend: It confirms that the immediate short-term momentum is moving in the same direction as the intended trade.
3. Volatility Confirmation (Bollinger Squeeze) One of the most important filters in this script is the volatility check. By calculating the relationship between standard deviation and the average range of price movement, the tool identifies "Squeezes." It effectively looks for periods where market activity is high enough to sustain a move; it filters out "choppy" or flat markets where signals are often unreliable (false positives).
4. Signal Execution & Alerts When all conditions—Momentum, Long-Term Trend, Short-Term Trend, and Volatility—align perfectly, the script generates a visual signal on your chart:
- Buy Signals: Marked with an upward arrow placed below the price candle.
- Sell Signals: Marked with a downward arrow placed above the price candle.
User Experience Features
- Real-Time Alerts: The script can be configured to send instant notifications (pop-ups) when a signal is triggered, providing the current Ask and Bid prices along with the specific timestamp for the trade.
- Dynamic Visuals: Signals are placed at a calculated distance from the candle based on recent price ranges, ensuring they remain clearly visible regardless of how volatile the market becomes.
//+----------------------------------------------------------------------------------+
//| Stochastic CCI filtered crossed over indicator |
//+----------------------------------------------------------------------------------+
//| Stochastic CCI filtered crossed over.mq4 |
//| Copyright © 2008, Melvin Tan |
//| |
//+----------------------------------------------------------------------------------+
#property copyright "Melvin Tan"
#property link "none at the moment"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
extern string note1 = "Stochastic settings";
extern int KPeriod1 = 5;
extern int DPeriod1 = 3;
extern int Slowing1 = 3;
extern string note2 = "0=sma, 1=ema, 2=smma, 3=lwma";
extern int MAMethod1 = 1;
extern string note3 = "0=high/low, 1=close/close";
extern int PriceField1 = 0;
extern int TrendCCI_Period = 50;
extern int EntryCCI_Period = 14;
extern bool AlertOn = false;
int bolPrd=20;
double bolDev=2.0;
int keltPrd=20;
double keltFactor=1.5;
double CrossUp[];
double CrossDown[];
string AlertPrefix;
string GetTimeFrameStr() {
switch(Period())
{
case 1 : string TimeFrameStr="M1"; break;
case 5 : TimeFrameStr="M5"; break;
case 15 : TimeFrameStr="M15"; break;
case 30 : TimeFrameStr="M30"; break;
case 60 : TimeFrameStr="H1"; break;
case 240 : TimeFrameStr="H4"; break;
case 1440 : TimeFrameStr="D1"; break;
case 10080 : TimeFrameStr="W1"; break;
case 43200 : TimeFrameStr="MN1"; break;
default : TimeFrameStr=Period();
}
return (TimeFrameStr);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0, 233);
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1, 234);
SetIndexBuffer(0, CrossUp);
SetIndexBuffer(1, CrossDown);
SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexEmptyValue(1,EMPTY_VALUE);
AlertPrefix=Symbol()+" ("+GetTimeFrameStr()+"): ";
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
bool NewBar()
{
static datetime lastbar;
datetime curbar = Time[0];
if(lastbar!=curbar)
{
lastbar=curbar;
return (true);
}
else
{
return(false);
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int limit, i, counter;
double stochastic1now, stochastic2now, stochastic1previous, stochastic2previous, stochastic1after, stochastic2after;
double Range, AvgRange;
double TrendCCI, EntryCCInow, EntryCCIprevious;
double diff, std, bbs;
int counted_bars=IndicatorCounted();
//---- check for possible errors
if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
for(i = 0; i <= limit; i++) {
counter=i;
Range=0;
AvgRange=0;
for (counter=i ;counter<=i+9;counter++)
{
AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
}
Range=AvgRange/10;
diff = iATR(NULL,0,keltPrd,i)*keltFactor;
std = iStdDev(NULL,0,bolPrd,MODE_SMA,0,PRICE_CLOSE,i);
bbs = bolDev * std / diff; //Bollinger Squeeze
stochastic1now = iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,0,i);
stochastic1previous = iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,0,i+1);
stochastic2now = iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,1,i);
stochastic2previous = iStochastic(NULL,0,KPeriod1,DPeriod1,Slowing1,MAMethod1,PriceField1,1,i+1);
TrendCCI = iCCI(NULL, 0, TrendCCI_Period, PRICE_TYPICAL, i);
EntryCCInow = iCCI(NULL, 0, EntryCCI_Period, PRICE_TYPICAL, i);
EntryCCIprevious = iCCI(NULL, 0, EntryCCI_Period, PRICE_TYPICAL, i+1);
if ((stochastic1now > stochastic2now) && (stochastic1previous < stochastic2previous) && (TrendCCI > 0) && (EntryCCInow > EntryCCIprevious) && (bbs > 1))
{
CrossUp[i] = Low[i] - Range*1.5;
if (AlertOn && NewBar()) {
Alert(AlertPrefix+"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses UP %D\nBUY signal @ Ask = ",Ask,"; Bid = ",Bid,"\nDate & Time = ",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()));
}
}
else if ((stochastic1now < stochastic2now) && (stochastic1previous > stochastic2previous) && (TrendCCI < 0) && (EntryCCInow < EntryCCIprevious) && (bbs > 1))
{
CrossDown[i] = High[i] + Range*1.5;
if (AlertOn && NewBar()){
Alert(AlertPrefix+"Stoch ("+KPeriod1+","+DPeriod1+","+Slowing1+") %K crosses DOWN %D\nSELL signal @ Ask = ",Ask,"; Bid = ",Bid,"\nDate & Time = ",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()));
}
}
else
{
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
}
}
return(0);
}
Comments