/*  Market breadth dashboard
    -------------------------------------------------------------------------
    Part 16 - Market Breadth, project formula 2 of 2.

    Reads the eight composites written by breadth-composite-builder.afl and
    draws one of three panels, chosen in the Parameters dialog (Ctrl+R):

        Participation        percent of members above their 50-bar and
                             200-bar averages
        New highs and lows   net new 252-bar highs, as a percent of members
        Advance/decline      the cumulative advance/decline line

    Apply it three times, once per panel, to build a three-pane breadth sheet.

    WHERE TO PLOT IT
    On ~BR_MEMBERS, or on a broad index symbol whose trading calendar matches
    the universe. Foreign() aligns foreign data to the CURRENT symbol, so
    plotting this on a share that does not trade every day silently deletes
    composite bars from the picture.

    WHAT IT IS NOT
    None of these lines forecasts anything. They describe how widely a move
    was shared at the time it happened, which is a different and much smaller
    claim than "the market is about to turn".
*/

_SECTION_BEGIN( "Market breadth dashboard" );

// ---- Configuration -------------------------------------------------------
Prefix = "~BR_";

Panel = ParamList( "Panel",
                   "Participation|New highs and lows|Advance/decline", 0 );

// The A/D line is a running total, so it must see the whole history rather
// than only the bars currently on screen.
SetBarsRequired( sbrAll, sbrAll );

// ---- Read the composites -------------------------------------------------
Members   = Nz( Foreign( Prefix + "MEMBERS",  "V" ) );
Adv       = Nz( Foreign( Prefix + "ADV",      "V" ) );
Dec       = Nz( Foreign( Prefix + "DEC",      "V" ) );
Unc       = Nz( Foreign( Prefix + "UNC",      "V" ) );
AboveFast = Nz( Foreign( Prefix + "ABOVE50",  "V" ) );
AboveSlow = Nz( Foreign( Prefix + "ABOVE200", "V" ) );
NewHighs  = Nz( Foreign( Prefix + "NEWHIGH",  "V" ) );
NewLows   = Nz( Foreign( Prefix + "NEWLOW",   "V" ) );

// SafeDivide returns the third argument wherever the divisor is zero, which
// is exactly what happens on bars before any member was eligible.
PctAboveFast = 100 * SafeDivide( AboveFast, Members, 0 );
PctAboveSlow = 100 * SafeDivide( AboveSlow, Members, 0 );
PctNetNewHi  = 100 * SafeDivide( NewHighs - NewLows, Members, 0 );

NetAdvances = Adv - Dec;
ADLine      = Cum( NetAdvances );

// ---- Health check --------------------------------------------------------
// Two ways a breadth panel lies: the composites are missing, or they were
// built by a scan that did not finish. Both are visible in the numbers.
Mismatch      = Adv + Dec + Unc - Members;
LatestMembers = LastValue( Members );

if( LatestMembers > 0 )
    Health = StrFormat( "contributors %g   arithmetic check %g (must be 0)",
                        SelectedValue( Members ), SelectedValue( Mismatch ) );
else
    Health = "NO COMPOSITE DATA - run breadth-composite-builder.afl as a Scan first";

// ---- Panels --------------------------------------------------------------
if( Panel == "Participation" )
{
    Plot( PctAboveSlow, "Above 200-bar MA", colorBlue, styleLine | styleThick, 0, 100 );
    Plot( PctAboveFast, "Above 50-bar MA", colorSkyblue, styleLine, 0, 100 );
    PlotGrid( 20, colorLightGrey );
    PlotGrid( 50, colorDarkGrey );
    PlotGrid( 80, colorLightGrey );

    Title = StrFormat( "%s   participation: %.1f per cent above the 200-bar "
                     + "average, %.1f per cent above the 50-bar average   -   ",
                       Name(), SelectedValue( PctAboveSlow ),
                       SelectedValue( PctAboveFast ) ) + Health;
}
else if( Panel == "New highs and lows" )
{
    Plot( PctNetNewHi, "Net new highs, per cent of members",
          IIf( PctNetNewHi >= 0, colorGreen, colorRed ), styleHistogram );
    PlotGrid( 0, colorDarkGrey );

    Title = StrFormat( "%s   net new highs %.2f per cent of members "
                     + "(%g new highs, %g new lows)   -   ",
                       Name(), SelectedValue( PctNetNewHi ),
                       SelectedValue( NewHighs ), SelectedValue( NewLows ) )
          + Health;
}
else
{
    Plot( ADLine, "A/D line", colorBlue, styleLine | styleThick );
    Plot( NetAdvances, "Net advances", colorLightGrey,
          styleHistogram | styleOwnScale | styleNoLabel );

    Title = StrFormat( "%s   A/D line %g   net advances %g   -   ",
                       Name(), SelectedValue( ADLine ),
                       SelectedValue( NetAdvances ) ) + Health;
}

_SECTION_END();
