@awilson showed how to do that here: https://forum.amibroker.com/t/rsi-divergence-plot-on-chart/15795
I add some code here that you can drag over your price function (CELH).
What you need to add yourself in the code is func2. It compares 2 functions, func1 and func2. In func2 you have to put your SPX data. In the code below I have put in func2 ES-mini futures data. You can also use the RSI or whatever.
func1 = ZigZag;
//func2 = RSI();
func2 = Foreign( "@ES#", "C" );
_SECTION_BEGIN( "Divergence Forum" );
per = Param( "ATR Period", 100, 1, 100, 1 ); // you need at least "per" data points to run this code
mult = Param( "ATR Multiple", 3, 0.5, 20, 0.1 );
priceswitch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 0 );
showregularBull = ParamToggle( "Show Regular Divergence Bullish", "No|Yes", 1 );
showregularBear = ParamToggle( "Show Regular Divergence Bearish", "No|Yes", 1 );
showhiddenBull = ParamToggle( "Show Hidden Divergence Bullish", "No|Yes", 1 );
showhiddenBear = ParamToggle( "Show Hidden Divergence Bearish", "No|Yes", 1 );
showaffirmativeBull = ParamToggle( "Show Affirmative Divergence Bullish", "No|Yes", 0 );
showaffirmativeBear = ParamToggle( "Show Affirmative Divergence Bearish", "No|Yes", 0 );
showZigZag = ParamToggle( "Show ZigZag", "No|Yes", 1 );
showLabels = ParamToggle( "Show Labels", "No|Yes", 1 );
colorBullishRegular = ParamColor( "Bullish Regular Color", ColorRGB( 50, 50, 255 ) );
colorBullishHidden = ParamColor( "Bullish Hidden Color", ColorRGB( 176, 196, 222 ) );
colorBullishAffirmative = ParamColor( "Bullish Affirmative Color", ColorRGB( 0, 191, 255 ) );
colorBearishRegular = ParamColor( "Bearish Regular Color", ColorRGB( 154, 1, 80 ) );
colorBearishHidden = ParamColor( "Bearish Hidden Color", ColorRGB( 255, 69, 0 ) );
colorBearishAffirmative = ParamColor( "Bearish Affirmative Color", ColorRGB( 240, 128, 128 ) );
sz = Param( "Font Size", 10, 7, 20, 1 );
linethickness = Param( "Line Thickness", 2, 1, 10, 1 );
maxcnt = Param( "Maximum Number of Divergences shown in Chart", 10, 2, 20, 1 ); // maximum divergences shown in plot
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
pk = tr = Buy = Sell = BuyPrice = SellPrice = 0;
trailarrayup = trailarraydn = Null;
if( priceswitch )
{
prch = H;
prcl = L;
}
else
{
prch = C;
prcl = C;
}
// if ticksize is not set in code or information window use 0.01
if( TickSize == 0 )
{
TickSize = 0.01;
}
slip = TickSize * 0;
sup = round( ( prch - mult * ATR( per ) ) / TickSize ) * TickSize;
res = round( ( prcl + mult * ATR( per ) ) / TickSize ) * TickSize;
trend = 1; // start trend at 1 or -1 doesnt matter
topprc = 0;
topidx = 0;
botprc = 0;
botidx = 0;
for( i = per + 1; i < BarCount; i++ )
{
if( trend > 0 )
{
if( prcl[i] <= trailarrayup[i - 1] )// AND prch[i] < topprc )
{
// trend turning down, avoid same bar as the peak
pk[topidx] = 1;
botprc = prcl[i];
botidx = i;
trend = -1;
Sell[i] = 1;
trailarraydn[i] = res[i];
trailarrayup[i] = trailarrayup[i - 1];
if( priceswitch )
SellPrice[i] = Min( O[i], trailarrayup[i] ) - slip;
else
SellPrice[i] = C[i] - slip;
}
else
if( prch[i] >= topprc )
{
// still in uptrend but new top reached
topprc = prch[i];
topidx = i;
trailarrayup[i] = Max( trailarrayup[i - 1], sup[i] );
}
else
{
// continuation inside uptrend
trailarrayup[i] = Max( trailarrayup[i - 1], sup[i] );
}
}
else
if( trend < 0 )
{
if( prch[i] >= trailarraydn[i - 1] )// AND prcl[i] > botprc )
{
// trend turning up, avoid same bar as the trough
tr[botidx] = 1;
topprc = prch[i];
topidx = i;
trend = 1;
Buy[i] = 1;
trailarrayup[i] = sup[i];
trailarraydn[i] = trailarraydn[i - 1];
if( priceswitch )
BuyPrice[i] = Max( O[i], trailarraydn[i] ) + slip;
else
BuyPrice[i] = C[i] + slip;
}
else
if( prcl[i] <= botprc )
{
// still in downtrend but new trough reached
botprc = prcl[i];
botidx = i;
trailarraydn[i] = Min( trailarraydn[i - 1], res[i] );
}
else
{
// continuation inside downtrend
trailarraydn[i] = Min( trailarraydn[i - 1], res[i] );
}
}
}
line1 = Null;
lastidxpk = LastValue( ValueWhen( pk, bi ) );
lastidxtr = LastValue( ValueWhen( tr, bi ) );
lastvalpk = LastValue( ValueWhen( pk, prch ) );
lastvaltr = LastValue( ValueWhen( tr, prcl ) );
lastidxbuy = LastValue( ValueWhen( Buy, bi ) );
lastidxsell = LastValue( ValueWhen( Sell, bi ) );
valpk = LastValue( HighestSince( Ref( tr, -1 ), prch , 1 ) );
idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );
lastidxbuy0 = ValueWhen( Buy , bi, 0 );
lastidxsell0 = ValueWhen( Sell, bi, 0 );
if( lastidxsell > lastidxbuy AND lastidxsell > lastidxpk AND lastidxpk > lastidxtr )
{
x0 = lastidxpk;
y0 = lastvalpk;
x1 = idxtr;
y1 = valtr;
line1 = linedn = LineArray( x0, y0, x1, y1 );
tr[idxtr] = 1;
valpk = LastValue( HighestSince( Ref( tr, -1 ), prch, 1 ) );
idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
}
if( lastidxsell < lastidxbuy AND lastidxbuy > lastidxtr AND lastidxpk < lastidxtr )
{
x0 = lastidxtr;
y0 = lastvaltr;
x1 = idxpk;
y1 = valpk;
line1 = lineup = LineArray( x0, y0, x1, y1 );
pk[idxpk] = 1;
valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );
}
// create ZIGZAG array line
zigup = Flip( tr, pk );
zigupLow = ValueWhen( tr, prcl, 1 );
zigupHigh = ValueWhen( pk, prch, 0 );
zigupLowIndex = ValueWhen( tr, bi, 1 );
zigupHighIndex = ValueWhen( pk, bi, 0 );
slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );
zigdn = Flip( pk, tr );
zigdnLow = ValueWhen( tr, prcl, 0 );
zigdnHigh = ValueWhen( pk, prch, 1 );
zigdnLowIndex = ValueWhen( tr, bi, 0 );
zigdnHighIndex = ValueWhen( pk, bi, 1 );
slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );
ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );
ZigZag = IIf( !IsEmpty( line1 ), line1, ZigZag );
func1 = ZigZag;
//func2 = RSI();
func2 = Foreign( "@ES#", "C" );
Buy = Sell = 0;
onlywhen = pk;
pkFunc2 = SparseCompress( onlywhen, func2 );
pkFunc1 = SparseCompress( onlywhen, func1 );
Sell1 = pkFunc2 < Ref( pkFunc2, -1 ) AND pkFunc1 > Ref( pkFunc1, -1 ); // regular
Sell2 = pkFunc2 > Ref( pkFunc2, -1 ) AND pkFunc1 < Ref( pkFunc1, -1 ); // hidden
Sell3 = pkFunc2 < Ref( pkFunc2, -1 ) AND pkFunc1 < Ref( pkFunc1, -1 ); // affirmative
Sell = Sell1 OR Sell2 OR Sell3;
Sell = SparseExpand( onlywhen, Sell );
Sell1 = SparseExpand( onlywhen, Sell1 );
Sell2 = SparseExpand( onlywhen, Sell2 );
Sell3 = SparseExpand( onlywhen, Sell3 );
Sy0 = SparseExpand( onlywhen, Ref( pkFunc1, -1 ) );
Sy1 = SparseExpand( onlywhen, pkFunc1 );
pkBi = SparseCompress( onlywhen, bi );
Sx0 = SparseExpand( onlywhen, Ref( pkBi, -1 ) );
onlywhen = tr;
thFunc2 = SparseCompress( onlywhen, func2 );
thFunc1 = SparseCompress( onlywhen, func1 );
Buy1 = thFunc2 > Ref( thFunc2, -1 ) AND thFunc1 < Ref( thFunc1, -1 ); // regular
Buy2 = thFunc2 < Ref( thFunc2, -1 ) AND thFunc1 > Ref( thFunc1, -1 ); // hidden
Buy3 = thFunc2 > Ref( thFunc2, -1 ) AND thFunc1 > Ref( thFunc1, -1 ); // affirmative
Buy = Buy1 OR Buy2 OR Buy3;
Buy = SparseExpand( onlywhen, Buy );
Buy1 = SparseExpand( onlywhen, Buy1 );
Buy2 = SparseExpand( onlywhen, Buy2 );
Buy3 = SparseExpand( onlywhen, Buy3 );
By0 = SparseExpand( onlywhen, Ref( thFunc1, -1 ) );
By1 = SparseExpand( onlywhen, thFunc1 );
thBi = SparseCompress( onlywhen, bi );
Bx0 = SparseExpand( onlywhen, Ref( thBi, -1 ) );
// Plot the Lines
if( showZigZag )
{
Plot( ZigZag, "", colorYellow, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, -1, linethickness );
}
ft = "arial black";
cnt = 0;
ymin = Status( "axisminy" );
ymax = Status( "axismaxy" );
dy = ( ymax - ymin ) / 13;
lastidxbuy1 = ValueWhen( buy1, bi );
lastidxbuy2 = ValueWhen( buy2, bi );
lastidxbuy3 = ValueWhen( buy3, bi );
lastidxsell1 = ValueWhen( sell1, bi );
lastidxsell2 = ValueWhen( sell2, bi );
lastidxsell3 = ValueWhen( sell3, bi );
for( b = lvb; b > fvb; b-- )
{
// regular divergence (Exhaustion)
if( Buy[b] AND Buy1[b] AND showRegularBull )
{
if( lastidxbuy1[b] < lastidxbuy0[b] )
{
clrbck = ColorRGB( 135, 206, 250 );
}
else
if( lastidxbuy1[b] >= lastidxbuy0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Bx0[b], By0[b], b, By1[b] ), "", colorBullishRegular, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Regular (Exhaustion)", ft, sz, b, Max( ymin + dy, L[b] ), colorBlack, clrbck, -sz * 5 );
}
// hidden divergence (Absorbtion)
if( Buy[b] AND Buy2[b] AND showHiddenBull )
{
if( lastidxbuy2[b] < lastidxbuy0[b] )
{
clrbck = ColorRGB( 135, 206, 250 );
}
else
if( lastidxbuy2[b] >= lastidxbuy0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Bx0[b], By0[b], b, By1[b] ), "", colorBullishHidden, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Hidden (Absorbtion)", ft, sz, b, Max( ymin + dy, L[b] ), colorBlack, clrbck, -sz * 5 );
}
// affirmative
if( Buy[b] AND Buy3[b] AND showAffirmativeBull )
{
if( lastidxbuy3[b] < lastidxbuy0[b] )
{
clrbck = ColorRGB( 135, 206, 250 );
}
else
if( lastidxbuy3[b] >= lastidxbuy0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Bx0[b], By0[b], b, By1[b] ), "", colorBullishAffirmative, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Affirmative", ft, sz, b, Max( ymin + dy, L[b] ), colorBlack, clrbck, -sz * 5 );
}
// regular divergence (Exhaustion)
if( Sell[b] AND Sell1[b] AND showRegularBear )
{
if( lastidxsell1[b] < lastidxsell0[b] )
{
clrbck = ColorRGB( 255, 165, 0 );
}
else
if( lastidxsell1[b] >= lastidxsell0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Sx0[b], Sy0[b], b, Sy1[b] ), "", colorBearishRegular, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Regular (Exhaustion)", ft, sz, b, Min( ymax - dy, H[b] ), colorBlack, clrbck, sz * 4 );
}
// hidden divergence (absorbtion)
if( Sell[b] AND Sell2[b] AND showHiddenBear )
{
if( lastidxsell2[b] < lastidxsell0[b] )
{
clrbck = ColorRGB( 255, 165, 0 );
}
else
if( lastidxsell2[b] >= lastidxsell0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Sx0[b], Sy0[b], b, Sy1[b] ), "", colorBearishHidden, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Hidden (Absorbtion)", ft, sz, b, Min( ymax - dy, H[b] ), colorBlack, clrbck, sz * 4 );
}
// affirmative
if( Sell[b] AND Sell3[b] AND showAffirmativeBear )
{
if( lastidxsell3[b] < lastidxsell0[b] )
{
clrbck = ColorRGB( 255, 165, 0 );
}
else
if( lastidxsell1[b] >= lastidxsell0[b] )
{
clrbck = colorLightGrey;
}
Plot( LineArray( Sx0[b], Sy0[b], b, Sy1[b] ), "", colorBearishAffirmative, styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 15, linethickness );
cnt = cnt + 1;
if( showLabels ) PlotTextSetFont( "Affirmative", ft, sz, b, Min( ymax - dy, H[b] ), colorBlack, clrbck, sz * 4 );
}
if( cnt >= maxcnt ) break;
}
_SECTION_END();