The Schaff Trend Cycle 1 is a technical analysis tool designed to help traders identify market trends and potential turning points by combining several momentum indicators into one streamlined visual output. Rather than looking at raw price action alone, this script processes the data through multiple layers of calculation to filter out "market noise" and highlight the underlying trend.
How the Logic Works
The script functions by processing data in four distinct stages, each building upon the previous one to refine the final signal:
1. The Foundation (MACD Calculation) The logic begins by comparing two different Exponential Moving Averages (EMA). By subtracting a slower moving average from a faster one, the script identifies the "momentum" of the market. This tells the system whether the price is accelerating upward or downward relative to its recent history.
2. Smoothing the Momentum (Chande Guassian) To prevent the signals from being too erratic or "jumpy," the script applies a smoothing calculation (based on the Chande Gaussian logic) to that initial momentum data. This step ensures that the trend lines moveFluidly, making it easier for a trader to see the general direction of the market without getting distracted by minor, temporary price fluctuations.
3. Normalizing the Trend (Stochastic Mapping) Once the smooth trend is established, the script applies a normalization process similar to a Stochastic Oscillator. It looks at the highest and lowest points over a specific period and calculates where the current smoothed value sits within that range. This transforms the data into a percentage-like scale, which helps in identifying "overbought" or "oversold" conditions within the trend cycle.
4. The Final Refinement (The Cycle) The final step repeats the smoothing process one last time on the normalized data. This produces the final Schaff Trend Cycle. By smoothing the smoothed data multiple times, the script produces a very clean, reactive curve that highlights the primary cycle of the market.
Summary for Traders
In plain terms, this script takes raw price movement, calculates its speed, smooths out the bumps, scales it to a readable range, and smooths it again. The end result is a visual indicator that helps you stay on the right side of the trend by showing you the "heartbeat" of the market’s current cycle.
//+------------------------------------------------------------------+
//| Schaff Trend Cycle 1.mq4 |
//| mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link "mladenfx@gmail.com"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
extern int STCPeriod = 10;
extern int CDPeriod = 25;
extern int FastMAPeriod = 23;
extern int SlowMAPeriod = 50;
extern double sm = 2;
double stcBuffer[];
double macdBuffer[];
double cdBuffer[];
double fastKBuffer[];
double fastDBuffer[];
double fastKKBuffer[];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
IndicatorBuffers(6);
SetIndexBuffer(0,stcBuffer);
SetIndexBuffer(1,macdBuffer);
SetIndexBuffer(2,cdBuffer);
SetIndexBuffer(3,fastKBuffer);
SetIndexBuffer(4,fastDBuffer);
SetIndexBuffer(5,fastKKBuffer);
IndicatorShortName("Schaff TC1 ("+STCPeriod+","+FastMAPeriod+","+SlowMAPeriod+","+CDPeriod+")");
return(0);
}
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double alphaCD = sm / (1.0 + CDPeriod);
int counted_bars = IndicatorCounted();
int limit,i;
if(counted_bars < 0) return(-1);
if(counted_bars>0) counted_bars--;
limit = Bars-counted_bars;
for(i = limit; i >= 0; i--)
{
macdBuffer[i] = iMA(NULL,0,FastMAPeriod,0,MODE_EMA,PRICE_CLOSE,i)-
iMA(NULL,0,SlowMAPeriod,0,MODE_EMA,PRICE_CLOSE,i);
cdBuffer[i] = cdBuffer[i+1]+alphaCD*(macdBuffer[i]-cdBuffer[i+1]);
double lowCd = minValue(cdBuffer,i);
double highCd = maxValue(cdBuffer,i)-lowCd;
if (highCd > 0)
fastKBuffer[i] = 100*((cdBuffer[i]-lowCd)/highCd);
else fastKBuffer[i] = fastKBuffer[i+1];
fastDBuffer[i] = fastDBuffer[i+1]+0.5*(fastKBuffer[i]-fastDBuffer[i+1]);
double lowStoch = minValue(fastDBuffer,i);
double highStoch = maxValue(fastDBuffer,i)-lowStoch;
if (highStoch > 0)
fastKKBuffer[i] = 100*((fastDBuffer[i]-lowStoch)/highStoch);
else fastKKBuffer[i] = fastKKBuffer[i+1];
stcBuffer[i] = stcBuffer[i+1]+0.5*(fastKKBuffer[i]-stcBuffer[i+1]);
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double minValue(double& array[],int shift)
{
double minValue = array[shift];
for (int i=1; i<STCPeriod; i++) minValue = MathMin(minValue,array[shift+i]);
return(minValue);
}
double maxValue(double& array[],int shift)
{
double maxValue = array[shift];
for (int i=1; i<STCPeriod; i++) maxValue = MathMax(maxValue,array[shift+i]);
return(maxValue);
}
Comments