1) The histogram displays but without the line that traces the prices. Currenty it just shows the Histogram bars. What need to be added or could you just add. It should only be one line but the lines I have tried has not worked.
2) How do I change the default from RSI to CCI??? When you put it on a chart and go to edit properties RSI is the default but want the CCI default and could not figure it out.
Thanks.
//Global Variables
var grID = 0;
var study1 = null;
var sStudyString = null;
var PPPrice = 0; //holds the price type of the pivot we have found (0=low, 1=high)
var bInitStudy = false;
var bInitialized = false;
var aFPArray = new Array();
//== PreMain function required by eSignal to set things up
function preMain() {
var x;
setPriceStudy(false);
//setComputeOnClose();
setPlotType(PLOTTYPE_HISTOGRAM, 0);
setDefaultBarStyle(PS_SOLID, 0);
setDefaultBarThickness(4, 0);
setDefaultBarFgColor( Color.black, 0 );
setDefaultBarFgColor( Color.magenta, 1 );
setPlotType(PLOTTYPE_INSTANTCOLORLINE,0);
grID = 0;
aFPArray[x] = new FunctionParameter( "frPeriod", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "Period" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 14 );
}
x++;
aFPArray[x] = new FunctionParameter( "frK", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "%K Smoothing (Stoch Only)" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 1 );
}
x++;
aFPArray[x] = new FunctionParameter( "frD", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "%D (Stoch Only)" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 3 );
}
x++;
aFPArray[x] = new FunctionParameter( "frStudy", FunctionParameter.STRING);
with( aFPArray[x] ) {
setName( "Study To Use" );
addOption( "RSI" );
addOption( "CCI" );
addOption( "Slow Stoch" );
setDefault( "RSI" );
}
}
//== Main processing function
function main( frPeriod, frK, frD, frStudy ) {
var x;
var nPiv1, nPiv2;
var nVal1, nVal2;
var nSVal1, nSVal2;
var nStudyValue;
//period to use for our study, default is 14
if (frPeriod==null) {
frPeriod = 14;
}
if (getBarState() == BARSTATE_ALLBARS) {
return null;
}
if ( bInitialized == false ) {
if ( frStudy == "CCI" ) {
setStudyTitle( "Divergence (CCI)" );
study1 = new CCIStudy( frPeriod, "HLC/3" );
sStudyString = CCIStudy.CCI;
setCursorLabelName("CCI("+frPeriod+")",0);
addBand( 150, PS_SOLID, 1, Color.black, gID());
addBand(-150, PS_SOLID, 1, Color.black, gID());
}
if ( frStudy == "RSI" ) {
setStudyTitle( "Divergence (RSI)" );
study1 = new RSIStudy( frPeriod );
sStudyString = RSIStudy.RSI;
setCursorLabelName("RSI("+frPeriod+")",0);
addBand(70, PS_SOLID, 1, Color.black, gID());
addBand(30, PS_SOLID, 1, Color.black, gID());
}
if ( frStudy == "Slow Stoch" ) {
setStudyTitle( "Divergence (Stochastic)" );
study1 = new StochStudy(frPeriod, frK, frD);
sStudyString = StochStudy.SLOW;
setCursorLabelName("Stoch %K("+frPeriod+")",0);
setCursorLabelName("Stoch %D("+frD+")",1);
addBand(85, PS_SOLID, 1, Color.black, gID());
addBand(15, PS_SOLID, 1, Color.black, gID());
}
bInitialized = true;
}
//get current value of our study which we will return to the study pane
//regardless of what else happens
nStudyValue = study1.getValue( sStudyString );
if ( frStudy=="Slow Stoch" )
nStudyValue2 = study1.getValue( StochStudy.FAST );
//Find the most recent pivots and look for a divergence
if (( getCurrentBarIndex() > -1 ) && ( getBarState()==BARSTATE_NEWBAR ) ) {
nOffset = 0;
//clear our workspace
clearLines();
clearText();
nPiv1 = -1;
//first, see if we have a potential high or low pivot forming based on
//the most recent 2 or 3 bars. If so, then we will use this point as our
//first pivot and we will work back from there.
//see if we have a potential low pivot forming
if ( ( low(nOffset-1)<low(nOffset) ) && ( low(nOffset-1) < Math.min(low(nOffset-2), low(nOffset-3), low(nOffset-4)) )) {
nPiv1 = 1;
PPPrice = 0;
}
//see if we have a potential high pivot forming
else if ( ( high(nOffset-1)>high(nOffset) ) && ( high(nOffset-1) > Math.max(high(nOffset-2), high(nOffset-3), high(nOffset-4)) )) {
nPiv1 = 1;
PPPrice = 1;
}
//just try to find any pivot in the last few bars
else {
nPiv1 = findPivot( Math.abs(nOffset), 0, true );
}
//nPiv1 is -1 on error or data not found.
//just bail if this happens.
if ( nPiv1 == -1 ) return( nStudyValue );
//was it a high pivot we found
if (PPPrice==1) {
nVal1 = high( -nPiv1 );
//get the next high price pivot
nPiv2 = findPivot( nPiv1+1, 1, false );
nVal2 = high( -nPiv2 );
//now get the study values at these points
nSVal1 = study1.getValue(sStudyString, -nPiv1);
nSVal2 = study1.getValue(sStudyString, -nPiv2);
//if a divergence, draw it
if ((nVal1 >= nVal2) && (nSVal1 < nSVal2)) {
//Bearish Divergence - CCI (nSVal2) must be LT 150
if (nSVal1<150) //--remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.grey, gID());
}
else if ((nVal1 <= nVal2) && (nSVal1 > nSVal2)) {
//Bullish Divergence - CCS (nsVal2) must be GT -150
if (nSVal1>-150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.grey, gID());
}
}
//or a low pivot?
else {
nVal1 = low( -nPiv1 );
//get the next low price pivot
nPiv2 = findPivot( nPiv1+1, -1, false );
nVal2 = low( -nPiv2 );
//now get the study values at these points
nSVal1 = study1.getValue(sStudyString, -nPiv1);
nSVal2 = study1.getValue(sStudyString, -nPiv2);
//if a divergence, draw it
if ((nVal1 >= nVal2) && (nSVal1 < nSVal2)) {
//Bearish Divergence - CCI (nsVal2) must be LT 150
if (nSVal2 < 150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.red, gID());
}
else if ((nVal1 <= nVal2) && (nSVal1 > nSVal2)) {
//Bullish Divergence - CCI (nsVal2) must be GT -150
if (nSVal2 > -150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.red, gID());
}
}
if (PPPrice==1) {
drawTextRelative(-nPiv1, nSVal1, "P", Color.black, null, Text.ONTOP | Text.BOTTOM | Text.CENTER, null, 14, gID() );
drawTextRelative(-nPiv2, nSVal2, "P", Color.black, null, Text.ONTOP | Text.BOTTOM | Text.CENTER, null, 14, gID() );
}
if (PPPrice==0) {
drawTextRelative(-nPiv1, nSVal1, "P", Color.maroon, null, Text.ONTOP | Text.TOP | Text.CENTER, null, 10, gID() );
drawTextRelative(-nPiv2, nSVal2, "P", Color.maroon, null, Text.ONTOP | Text.TOP | Text.CENTER, null, 10, gID() );
}
//p( "0-bar", low(0) );
//p( "Piv1", nPiv1 );
//p( "pr1", nVal1 );
//p( "Piv2", nPiv2 );
//p( "pr2", nVal2 );
}
if ( frStudy == "Slow Stoch" ) {
return new Array( nStudyValue2, nStudyValue );
}
return( nStudyValue );
}
//==This is simply an adaptation of the findPivot function that I have used
//== in other scripts. Our usage here will be to scan backwards to find the
//== pivots we need in the price series.
function findPivot( nCurOffset, nDataKind, bRelax ) {
var x,y;
var nLvls;
var nPivot;
var vH,vL;
var lB;
var nPad;
//== nCurOffset is the offset from current bar where we want to start scanning
//== nDataKind: 0=find any pivot, 1=find next high pivot, -1=find next low pivot
//== bRelax: true=look for a semi-pivot of 1 bar, false=look for regular pivot
//define size of a pivot (x-bars on either side lower or higher)
if (bRelax==false) {
nPivot = 4;
}
else {
nPivot = 2;
}
//scan backwards for pivots
if ( 1 == 1 ) {
lB = 100;
//scan price series
vH = getValue("High", -nCurOffset, -(lB));
vL = getValue("Low", -nCurOffset, -(lB));
if (vH==null) return( -1 );
x=0;
while(x<lB) {
if (x>nPivot+1) {
//we are scanning price data
if (nDataKind <=0) {
nLvls = 0;
for(y=0; y<nPivot; y++) {
if (vL[x-y]>vL[x-nPivot]) nLvls++;
if (vL[x-(y+(nPivot+1))]>=vL[x-nPivot]) nLvls++;
}
if (nLvls>((nPivot*2)-1)) {
PPPrice = 0;
return( (x-nPivot)+nCurOffset );
}
}
if (nDataKind >=0) {
nLvls = 0;
for(y=0; y<nPivot; y++) {
if (vH[x-y]<vH[x-nPivot]) nLvls++;
if (vH[x-(y+(nPivot+1))]<=vH[x-nPivot]) nLvls++;
}
if (nLvls>((nPivot*2)-1)) {
PPPrice = 1;
return( (x-nPivot)+nCurOffset );
}
}
}
x++;
}
}
return (-1);
}
/*************************************************
SUPPORT FUNCTIONS
**************************************************/
function p( a, b ) {
debugPrint( a + ": " + b + "\n" );
return;
}
//== gID function assigns unique identifier to graphic/text routines
function gID() {
grID ++;
return( grID );
}
//== displayError function displays an error to the user
function displayError( ErrStr ) {
clearText();
drawTextRelative(20, 50, ErrStr, Color.maroon, Color.lightgrey, Text.FRAME | Text.ONTOP | Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM, null, 16, gID());
}
//== SortMe function sorts an array in ascending order
function SortMe( arg1, arg2 ) {
if (arg1<arg2) {
return( -1 )
}
else {
return( 1 );
}
}
//==fmt will truncate the degrees value for display purposes.
function fmt( value ) {
var tmp;
tmp = value;
value = Math.abs( value );
value = Math.round( value );
if (tmp<0) value = 0-value;
return( value );
}
//==rnd will round to N digits.
function rnd(value, N) {
var n;
var mult=1;
for(n=0;n<N;n++) mult*=10;
value*=mult;
return Math.round( value,N)/mult;
}
//== Frac functions returns the fractional portion of a real number
function Frac( iVal ) {
var x = Math.floor( iVal );
return( iVal - x );
}
2) How do I change the default from RSI to CCI??? When you put it on a chart and go to edit properties RSI is the default but want the CCI default and could not figure it out.
Thanks.
//Global Variables
var grID = 0;
var study1 = null;
var sStudyString = null;
var PPPrice = 0; //holds the price type of the pivot we have found (0=low, 1=high)
var bInitStudy = false;
var bInitialized = false;
var aFPArray = new Array();
//== PreMain function required by eSignal to set things up
function preMain() {
var x;
setPriceStudy(false);
//setComputeOnClose();
setPlotType(PLOTTYPE_HISTOGRAM, 0);
setDefaultBarStyle(PS_SOLID, 0);
setDefaultBarThickness(4, 0);
setDefaultBarFgColor( Color.black, 0 );
setDefaultBarFgColor( Color.magenta, 1 );
setPlotType(PLOTTYPE_INSTANTCOLORLINE,0);
grID = 0;
aFPArray[x] = new FunctionParameter( "frPeriod", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "Period" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 14 );
}
x++;
aFPArray[x] = new FunctionParameter( "frK", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "%K Smoothing (Stoch Only)" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 1 );
}
x++;
aFPArray[x] = new FunctionParameter( "frD", FunctionParameter.NUMBER);
with( aFPArray[x] ) {
setName( "%D (Stoch Only)" );
setLowerLimit( 1 );
setUpperLimit( 200 );
setDefault( 3 );
}
x++;
aFPArray[x] = new FunctionParameter( "frStudy", FunctionParameter.STRING);
with( aFPArray[x] ) {
setName( "Study To Use" );
addOption( "RSI" );
addOption( "CCI" );
addOption( "Slow Stoch" );
setDefault( "RSI" );
}
}
//== Main processing function
function main( frPeriod, frK, frD, frStudy ) {
var x;
var nPiv1, nPiv2;
var nVal1, nVal2;
var nSVal1, nSVal2;
var nStudyValue;
//period to use for our study, default is 14
if (frPeriod==null) {
frPeriod = 14;
}
if (getBarState() == BARSTATE_ALLBARS) {
return null;
}
if ( bInitialized == false ) {
if ( frStudy == "CCI" ) {
setStudyTitle( "Divergence (CCI)" );
study1 = new CCIStudy( frPeriod, "HLC/3" );
sStudyString = CCIStudy.CCI;
setCursorLabelName("CCI("+frPeriod+")",0);
addBand( 150, PS_SOLID, 1, Color.black, gID());
addBand(-150, PS_SOLID, 1, Color.black, gID());
}
if ( frStudy == "RSI" ) {
setStudyTitle( "Divergence (RSI)" );
study1 = new RSIStudy( frPeriod );
sStudyString = RSIStudy.RSI;
setCursorLabelName("RSI("+frPeriod+")",0);
addBand(70, PS_SOLID, 1, Color.black, gID());
addBand(30, PS_SOLID, 1, Color.black, gID());
}
if ( frStudy == "Slow Stoch" ) {
setStudyTitle( "Divergence (Stochastic)" );
study1 = new StochStudy(frPeriod, frK, frD);
sStudyString = StochStudy.SLOW;
setCursorLabelName("Stoch %K("+frPeriod+")",0);
setCursorLabelName("Stoch %D("+frD+")",1);
addBand(85, PS_SOLID, 1, Color.black, gID());
addBand(15, PS_SOLID, 1, Color.black, gID());
}
bInitialized = true;
}
//get current value of our study which we will return to the study pane
//regardless of what else happens
nStudyValue = study1.getValue( sStudyString );
if ( frStudy=="Slow Stoch" )
nStudyValue2 = study1.getValue( StochStudy.FAST );
//Find the most recent pivots and look for a divergence
if (( getCurrentBarIndex() > -1 ) && ( getBarState()==BARSTATE_NEWBAR ) ) {
nOffset = 0;
//clear our workspace
clearLines();
clearText();
nPiv1 = -1;
//first, see if we have a potential high or low pivot forming based on
//the most recent 2 or 3 bars. If so, then we will use this point as our
//first pivot and we will work back from there.
//see if we have a potential low pivot forming
if ( ( low(nOffset-1)<low(nOffset) ) && ( low(nOffset-1) < Math.min(low(nOffset-2), low(nOffset-3), low(nOffset-4)) )) {
nPiv1 = 1;
PPPrice = 0;
}
//see if we have a potential high pivot forming
else if ( ( high(nOffset-1)>high(nOffset) ) && ( high(nOffset-1) > Math.max(high(nOffset-2), high(nOffset-3), high(nOffset-4)) )) {
nPiv1 = 1;
PPPrice = 1;
}
//just try to find any pivot in the last few bars
else {
nPiv1 = findPivot( Math.abs(nOffset), 0, true );
}
//nPiv1 is -1 on error or data not found.
//just bail if this happens.
if ( nPiv1 == -1 ) return( nStudyValue );
//was it a high pivot we found
if (PPPrice==1) {
nVal1 = high( -nPiv1 );
//get the next high price pivot
nPiv2 = findPivot( nPiv1+1, 1, false );
nVal2 = high( -nPiv2 );
//now get the study values at these points
nSVal1 = study1.getValue(sStudyString, -nPiv1);
nSVal2 = study1.getValue(sStudyString, -nPiv2);
//if a divergence, draw it
if ((nVal1 >= nVal2) && (nSVal1 < nSVal2)) {
//Bearish Divergence - CCI (nSVal2) must be LT 150
if (nSVal1<150) //--remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.grey, gID());
}
else if ((nVal1 <= nVal2) && (nSVal1 > nSVal2)) {
//Bullish Divergence - CCS (nsVal2) must be GT -150
if (nSVal1>-150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.grey, gID());
}
}
//or a low pivot?
else {
nVal1 = low( -nPiv1 );
//get the next low price pivot
nPiv2 = findPivot( nPiv1+1, -1, false );
nVal2 = low( -nPiv2 );
//now get the study values at these points
nSVal1 = study1.getValue(sStudyString, -nPiv1);
nSVal2 = study1.getValue(sStudyString, -nPiv2);
//if a divergence, draw it
if ((nVal1 >= nVal2) && (nSVal1 < nSVal2)) {
//Bearish Divergence - CCI (nsVal2) must be LT 150
if (nSVal2 < 150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.red, gID());
}
else if ((nVal1 <= nVal2) && (nSVal1 > nSVal2)) {
//Bullish Divergence - CCI (nsVal2) must be GT -150
if (nSVal2 > -150) //-- remove this line if not using CCI
drawLineRelative(-nPiv1, nSVal1, -nPiv2, nSVal2, PS_SOLID, 2, Color.red, gID());
}
}
if (PPPrice==1) {
drawTextRelative(-nPiv1, nSVal1, "P", Color.black, null, Text.ONTOP | Text.BOTTOM | Text.CENTER, null, 14, gID() );
drawTextRelative(-nPiv2, nSVal2, "P", Color.black, null, Text.ONTOP | Text.BOTTOM | Text.CENTER, null, 14, gID() );
}
if (PPPrice==0) {
drawTextRelative(-nPiv1, nSVal1, "P", Color.maroon, null, Text.ONTOP | Text.TOP | Text.CENTER, null, 10, gID() );
drawTextRelative(-nPiv2, nSVal2, "P", Color.maroon, null, Text.ONTOP | Text.TOP | Text.CENTER, null, 10, gID() );
}
//p( "0-bar", low(0) );
//p( "Piv1", nPiv1 );
//p( "pr1", nVal1 );
//p( "Piv2", nPiv2 );
//p( "pr2", nVal2 );
}
if ( frStudy == "Slow Stoch" ) {
return new Array( nStudyValue2, nStudyValue );
}
return( nStudyValue );
}
//==This is simply an adaptation of the findPivot function that I have used
//== in other scripts. Our usage here will be to scan backwards to find the
//== pivots we need in the price series.
function findPivot( nCurOffset, nDataKind, bRelax ) {
var x,y;
var nLvls;
var nPivot;
var vH,vL;
var lB;
var nPad;
//== nCurOffset is the offset from current bar where we want to start scanning
//== nDataKind: 0=find any pivot, 1=find next high pivot, -1=find next low pivot
//== bRelax: true=look for a semi-pivot of 1 bar, false=look for regular pivot
//define size of a pivot (x-bars on either side lower or higher)
if (bRelax==false) {
nPivot = 4;
}
else {
nPivot = 2;
}
//scan backwards for pivots
if ( 1 == 1 ) {
lB = 100;
//scan price series
vH = getValue("High", -nCurOffset, -(lB));
vL = getValue("Low", -nCurOffset, -(lB));
if (vH==null) return( -1 );
x=0;
while(x<lB) {
if (x>nPivot+1) {
//we are scanning price data
if (nDataKind <=0) {
nLvls = 0;
for(y=0; y<nPivot; y++) {
if (vL[x-y]>vL[x-nPivot]) nLvls++;
if (vL[x-(y+(nPivot+1))]>=vL[x-nPivot]) nLvls++;
}
if (nLvls>((nPivot*2)-1)) {
PPPrice = 0;
return( (x-nPivot)+nCurOffset );
}
}
if (nDataKind >=0) {
nLvls = 0;
for(y=0; y<nPivot; y++) {
if (vH[x-y]<vH[x-nPivot]) nLvls++;
if (vH[x-(y+(nPivot+1))]<=vH[x-nPivot]) nLvls++;
}
if (nLvls>((nPivot*2)-1)) {
PPPrice = 1;
return( (x-nPivot)+nCurOffset );
}
}
}
x++;
}
}
return (-1);
}
/*************************************************
SUPPORT FUNCTIONS
**************************************************/
function p( a, b ) {
debugPrint( a + ": " + b + "\n" );
return;
}
//== gID function assigns unique identifier to graphic/text routines
function gID() {
grID ++;
return( grID );
}
//== displayError function displays an error to the user
function displayError( ErrStr ) {
clearText();
drawTextRelative(20, 50, ErrStr, Color.maroon, Color.lightgrey, Text.FRAME | Text.ONTOP | Text.RELATIVETOLEFT | Text.RELATIVETOBOTTOM, null, 16, gID());
}
//== SortMe function sorts an array in ascending order
function SortMe( arg1, arg2 ) {
if (arg1<arg2) {
return( -1 )
}
else {
return( 1 );
}
}
//==fmt will truncate the degrees value for display purposes.
function fmt( value ) {
var tmp;
tmp = value;
value = Math.abs( value );
value = Math.round( value );
if (tmp<0) value = 0-value;
return( value );
}
//==rnd will round to N digits.
function rnd(value, N) {
var n;
var mult=1;
for(n=0;n<N;n++) mult*=10;
value*=mult;
return Math.round( value,N)/mult;
}
//== Frac functions returns the fractional portion of a real number
function Frac( iVal ) {
var x = Math.floor( iVal );
return( iVal - x );
}
Comment