prsi_pcci
Download scriptOverview
This script is a multi-functional technical analysis tool designed for the MetaTrader platform. Its primary purpose is to provide traders with a visual representation of momentum and price relative strength by combining multiple indicators into a single viewing area. Instead of cluttering your chart with many separate windows, this tool consolidates specific data points to help identify trends and potential reversals more efficiently.
Core Functionality
The script allows users to monitor two distinct sets of indicators simultaneously. It provides the flexibility to choose between four different types of mathematical calculations:
- Relative Strength Index (RSI): Measures the speed and change of price movements.
- Commodity Channel Index (CCI): Identifies new trends by looking at pricing activity relative to an average price level.
- Percent Range of RSI (PRSI): A specialized calculation that looks at where the RSI sits within its own recent range.
- Percent Range of CCI (PCCI): A specialized calculation that determines the position of the CCI within its recent highs and lows.
Key Features
Dual Timeframe Analysis One of the most powerful aspects of this script is its ability to pull data from different timeframes at once. For example, you can view the momentum of a 15-minute chart while simultaneously seeing the trend of a 4-hour chart on the same indicator window. This helps traders understand the "bigger picture" without switching back and forth between different tabs.
Smart Visual Feedback The script utilizes specific colors (Lime Green, Fire Brick, and Royal Blue) to differentiate between the various data streams. It also includes logic to identify direction:
- It tracks whether the indicator values are rising or falling.
- It uses a "histogram" style visual for the primary indicators, making it easy to see the immediate momentum of the market.
Customizable Calculations Users have full control over the sensitivity of the tool. You can adjust the "Periods" (how much historical data the script looks at) and the "Price Type" (whether the calculation is based on the opening price, closing price, etc.). This allows you to tailor the tool to specific assets, such as Forex pairs, commodities, or stocks.
Signal Processing The script includes a specialized logic for "Signal" modes. Rather than just showing raw data, it can calculate a "Percent Range." This translates complex numbers into a percentage-based value, making it much easier for the human eye to see if an indicator is "overbought," "oversold," or sitting in the middle of its typical trading range.
Summary for the Trader
In simple terms, this script acts as a "dashboard." It takes complex market data from two different timeframes and translates them into clear, color-coded visual signals. By combining these views, it helps you stay aware of the overall market trend while identifying precise moments where price momentum might be shifting.
//+------------------------------------------------------------------+
//| PRSI & PCCI.mq4 |
//| Copyright 2005-2014, MetaQuotes Software Corp. |
//| http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "2005-2014, MetaQuotes Software Corp."
#property link "http://www.mql4.com"
#property description "PRSI & PCCI by pipPod"
#property strict
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrLimeGreen
#property indicator_color2 clrFireBrick
#property indicator_color3 clrRoyalBlue
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
enum indicators
{
INDICATOR_RSI, //Relative Strength Index
INDICATOR_CCI, //Commodity Channel Index
INDICATOR_PRSI, //Percent Range of RSI
INDICATOR_PCCI, //Percent Range of CCI
INDICATOR_NONE //No Indicator
};
input indicators Indicator_1=INDICATOR_CCI;
input indicators Indicator_2=INDICATOR_PRSI;
//--- indicator parameters
input int RSIPeriod=14; // RSI Period
input ENUM_APPLIED_PRICE RSIPrice=PRICE_CLOSE; // RSI Price
input int CCIPeriod=14; // CCI Period
input ENUM_APPLIED_PRICE CCIPrice=PRICE_CLOSE; // CCI Price
input int PRSIPeriod=14; // PRSI Period
input ENUM_APPLIED_PRICE PRSIPrice=PRICE_CLOSE; // PRSI Price
input int PCCIPeriod=14; // PCCI Period
input ENUM_APPLIED_PRICE PCCIPrice=PRICE_CLOSE; // PCCI Price
input ENUM_TIMEFRAMES TimeFrame_1=0;
input ENUM_TIMEFRAMES TimeFrame_2=0;
//--- indicator buffers
double IndexBuffer__1[];
double IndexBuffer_1A[];
double IndexBuffer_1B[];
double IndexBuffer__2[];
double Index_1,
Index_1A,
Index_1B,
Index_2;
//--- right input parameters flag
bool ExtParameters=false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
IndicatorDigits(1);
//--- drawing settings
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexStyle(2,DRAW_LINE);
SetIndexStyle(3,INDICATOR_DATA,EMPTY,EMPTY,clrNONE);
//--- indicator buffers mapping
SetIndexBuffer(0,IndexBuffer_1A);
SetIndexBuffer(1,IndexBuffer_1B);
SetIndexBuffer(2,IndexBuffer__2);
SetIndexBuffer(3,IndexBuffer__1);
SetIndexDrawBegin(0,RSIPeriod);
SetIndexDrawBegin(1,RSIPeriod);
SetIndexDrawBegin(2,RSIPeriod);
SetIndexDrawBegin(3,RSIPeriod);
string timeFrame_1,
timeFrame_2;
switch(TimeFrame_1)
{
case PERIOD_MN1: timeFrame_1 = "MN1 ";break;
case PERIOD_W1: timeFrame_1 = "W1 "; break;
case PERIOD_D1: timeFrame_1 = "D1 "; break;
case PERIOD_H4: timeFrame_1 = "H4 "; break;
case PERIOD_H1: timeFrame_1 = "H1 "; break;
case PERIOD_M30: timeFrame_1 = "M30 ";break;
case PERIOD_M15: timeFrame_1 = "M15 ";break;
case PERIOD_M5: timeFrame_1 = "M5 "; break;
case PERIOD_M1: timeFrame_1 = "M1 "; break;
default: timeFrame_1 = " "; break;
}
switch(TimeFrame_2)
{
case PERIOD_MN1: timeFrame_2 = "MN1 ";break;
case PERIOD_W1: timeFrame_2 = "W1 "; break;
case PERIOD_D1: timeFrame_2 = "D1 "; break;
case PERIOD_H4: timeFrame_2 = "H4 "; break;
case PERIOD_H1: timeFrame_2 = "H1 "; break;
case PERIOD_M30: timeFrame_2 = "M30 ";break;
case PERIOD_M15: timeFrame_2 = "M15 ";break;
case PERIOD_M5: timeFrame_2 = "M5 "; break;
case PERIOD_M1: timeFrame_2 = "M1 "; break;
default: timeFrame_2 = " "; break;
}
string shortname_1,
shortname_2,
label_1,
label_2,
label_3;
switch(Indicator_1)
{
case INDICATOR_RSI:
shortname_1="RSI "+timeFrame_1+"("+
IntegerToString(RSIPeriod)+")";
label_1="RSI "+timeFrame_1;
label_2="RSI "+timeFrame_1;
break;
case INDICATOR_CCI:
shortname_1="CCI "+timeFrame_1+"("+
IntegerToString(CCIPeriod)+")";
label_1="CCI "+timeFrame_1;
label_2="CCI "+timeFrame_1;
break;
case INDICATOR_PRSI:
shortname_1="PRSI "+timeFrame_1+"("+
IntegerToString(PRSIPeriod)+")";
label_1="PRSI "+timeFrame_1;
label_2="PRSI "+timeFrame_1;
break;
case INDICATOR_PCCI:
shortname_1="PCCI "+timeFrame_1+"("+
IntegerToString(PCCIPeriod)+")";
label_1="PCCI "+timeFrame_1;
label_2="PCCI "+timeFrame_1;
break;
case INDICATOR_NONE:
break;
}
switch(Indicator_2)
{
case INDICATOR_RSI:
shortname_2="RSI "+timeFrame_2+"("+
IntegerToString(RSIPeriod)+")";
label_3="RSI "+timeFrame_2;
break;
case INDICATOR_CCI:
shortname_2="CCI "+timeFrame_2+"("+
IntegerToString(CCIPeriod)+")";
label_3="CCI "+timeFrame_2;
break;
case INDICATOR_PRSI:
shortname_2="PRSI "+timeFrame_2+"("+
IntegerToString(PRSIPeriod)+")";
label_3="PRSI "+timeFrame_2;
break;
case INDICATOR_PCCI:
shortname_2="PCCI "+timeFrame_2+"("+
IntegerToString(PCCIPeriod)+")";
label_3="PCCI "+timeFrame_2;
break;
case INDICATOR_NONE:
break;
}
//--- name for DataWindow and indicator subwindow label
IndicatorShortName(shortname_1+" "+shortname_2);
SetIndexLabel(0,label_1);
SetIndexLabel(1,label_2);
SetIndexLabel(2,label_3);
//--- check for input parameters
if(RSIPeriod<=1 || CCIPeriod<=1 || PRSIPeriod<=1 || PCCIPeriod<=1)
{
Print("Wrong input parameters");
ExtParameters=false;
return(INIT_FAILED);
}
else
ExtParameters=true;
//--- initialization done
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int i,limit,shift_1,shift_2;
//---
if(rates_total<=100 || !ExtParameters)
return(0);
//---
bool newBar=prev_calculated==0 || NewBar(time[0]);
limit=rates_total-prev_calculated;
if(prev_calculated==0)
limit=rates_total-50;
for(i=limit; i>=0; i--)
{
shift_1=iBarShift(_Symbol,TimeFrame_1,time[i]);
switch(Indicator_1)
{
case INDICATOR_RSI:
Index_1=iRSI(_Symbol,TimeFrame_1,RSIPeriod,RSIPrice,MODE_MAIN,newBar,shift_1);
break;
case INDICATOR_CCI:
Index_1=iCCI(_Symbol,TimeFrame_1,CCIPeriod,CCIPrice,MODE_MAIN,newBar,shift_1);
break;
case INDICATOR_PRSI:
Index_1=iRSI(_Symbol,TimeFrame_1,PRSIPeriod,PRSIPrice,MODE_SIGNAL,newBar,shift_1);
break;
case INDICATOR_PCCI:
Index_1=iCCI(_Symbol,TimeFrame_1,PCCIPeriod,PCCIPrice,MODE_SIGNAL,newBar,shift_1);
break;
case INDICATOR_NONE:
break;
}
shift_2=iBarShift(_Symbol,TimeFrame_2,time[i]);
switch(Indicator_2)
{
case INDICATOR_RSI:
Index_2=iRSI(_Symbol,TimeFrame_2,RSIPeriod,RSIPrice,MODE_MAIN,newBar,shift_2);
break;
case INDICATOR_CCI:
Index_2=iCCI(_Symbol,TimeFrame_2,CCIPeriod,CCIPrice,MODE_MAIN,newBar,shift_2);
break;
case INDICATOR_PRSI:
Index_2=iRSI(_Symbol,TimeFrame_2,PRSIPeriod,PRSIPrice,MODE_SIGNAL,newBar,shift_2);
break;
case INDICATOR_PCCI:
Index_2=iCCI(_Symbol,TimeFrame_2,PCCIPeriod,PCCIPrice,MODE_SIGNAL,newBar,shift_2);
break;
case INDICATOR_NONE:
break;
}
IndexBuffer__1[i] = Index_1;
if(IndexBuffer__1[i]>=IndexBuffer__1[i+1])
{
IndexBuffer_1A[i] = IndexBuffer__1[i];
IndexBuffer_1B[i] = EMPTY_VALUE;
}
else
{
IndexBuffer_1B[i] = IndexBuffer__1[i];
IndexBuffer_1A[i] = EMPTY_VALUE;
}
if(Indicator_2==INDICATOR_NONE)
IndexBuffer__2[i] = EMPTY_VALUE;
else
IndexBuffer__2[i] = Index_2;
}
//--- done
return(rates_total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool NewBar(const datetime& time)
{
static datetime time_prev;
if(time!=time_prev)
{
time_prev=time;
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
const double iRSI(const string symbol,
const ENUM_TIMEFRAMES timeframe,
const int period,
const ENUM_APPLIED_PRICE price,
const int mode,
const bool new_bar,
const int idx)
{
int i,count;
double prsi;
if(mode==MODE_SIGNAL)
{
static double rsi[1];
if(ArraySize(rsi)!=period)
ArrayResize(rsi,period);
if(!new_bar)
count=1;
else
count=period;
for(i=0;i<count;i++)
{
rsi[i]=iRSI(symbol,timeframe,period,price,idx+i);
}
prsi=iPRIOnArray(rsi,period,idx)-50;
}
else
prsi=iRSI(symbol,timeframe,period,price,idx)-50;
return(prsi);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
const double iCCI(const string symbol,
const ENUM_TIMEFRAMES timeframe,
const int period,
const ENUM_APPLIED_PRICE price,
const int mode,
const bool new_bar,
const int idx)
{
int i,count;
double pcci;
double mul=1.5/period;
if(mode==MODE_SIGNAL)
{
static double cci[1];
if(ArraySize(cci)!=period)
ArrayResize(cci,period);
if(!new_bar)
count=1;
else
count=period;
for(i=0;i<count;i++)
{
cci[i]=iCCI(symbol,timeframe,period,price,idx+i);
}
pcci=iPRIOnArray(cci,period,idx)-50;
}
else
pcci=iCCI(symbol,timeframe,period,price,idx)*mul;
return(pcci);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
const double iPRIOnArray(const double &array[],
const int period,
const int idx)
{
double pri;
double low;
double high;
double range;
double price=array[0];
int count=period;
int arraySize=ArraySize(array);
if(arraySize<period)
count=WHOLE_ARRAY;
if(arraySize<2)
return(50);
low=array[ArrayMinimum(array,count,0)];
high=array[ArrayMaximum(array,count,0)];
range=high-low;
if(!range)
pri=50;
else
pri=100*(price-low)/range;
return(pri);
}
//+------------------------------------------------------------------+
Comments