//_BetterCrash - Crash and Correction Indicator
//Plots 10% Correction and 20% Crash trailing levels off the rolling LookBack high
//Daily, Weekly or Monthly charts of indices (set LookBack to suit - see below)
//4Jul24 - Version 1
//7Sep26 - Version 2: ShowCorrection / ShowCrash on-off inputs (line, dot and label),
//                    legacy Text_New replaced with TextLabel drawing objects
//emini-watch.com/free-indicators/stock-market-crash/

using elsystem;
using elsystem.drawing;
using elsystem.drawingobjects;

Inputs:
    ShowCorrection(True),   // Switch the whole Correction package on/off (trailing line, dot, label)
    ShowCrash(True),        // Switch the whole Crash package on/off (trailing line, dot, label)
    LookBack(52),           // Rolling high lookback in bars: 250 Daily, 52 Weekly, 12 Monthly
    CorrectionPct(10),      // Percentage drop to trigger "Correction"
    CrashPct(20),           // Percentage drop to trigger "Crash"
    CorrectionColor(Cyan),
    CrashColor(Red);

Variables:
    CorrectionSetUp(False), // Flag: Are we waiting for a correction?
    CrashSetUp(False),      // Flag: Are we waiting for a crash?
    HighestHigh52(C),       // Holds the "High Watermark" price
    CorrectionLevel(0),     // Holds the calculated price for the Correction drop
    CrashLevel(0),          // Holds the calculated price for the Crash drop
    TextLabel TL(null);     // drawing object for the breach label

// --- LABEL DRAWING METHOD (must be declared before any main code) ---
// Text starts to the RIGHT of the dot and sits ABOVE the level line, so neither the
// dot nor the trailing line covers it. Leading spaces in txt push it clear of the dot.
Method void Draw_Label( double price, string txt, color mycolor )
begin
    TL = TextLabel.Create( DTPoint.Create( BarDateTime, price ), txt );
    TL.Color = mycolor;
    TL.HStyle = HorizontalStyle.Left;    // left edge of text at the anchor -> text runs right
    TL.VStyle = VerticalStyle.Bottom;    // bottom edge of text on the anchor -> text sits ABOVE the level line
    TL.Persist = True;
    DrawingObjects.Add( TL );
End;

// --- 1. PEAK DETECTION ---
// If the current High is the highest in the last LookBack bars, we reset the baseline.
If H = Highest(H,LookBack) then begin
    CorrectionSetUp = True; // "Arm" the system: We are at a new high, so we are watching for a drop again.
    CrashSetUp = True;      // "Arm" the crash alert as well.
    HighestHigh52 = H;      // Store this new high price to calculate drops from.
End;

// --- 2. CALCULATE LEVELS ---
// These calculations happen on every bar, projecting the lines down from the stored HighestHigh52.
CorrectionLevel = HighestHigh52 * (1 - CorrectionPct / 100);
CrashLevel = HighestHigh52 * (1 - CrashPct / 100);

// --- 3. PLOT TRAILING LINES (only when switched on) ---
If ShowCorrection then Plot1(CorrectionLevel,"Correction Level",CorrectionColor);
If ShowCrash then Plot2(CrashLevel,"Crash Level",CrashColor);

// --- 4. CORRECTION LOGIC ---
// Only fires if switched on AND armed AND the Low hits the level. Disarms after one fire per drop.
If ShowCorrection and CorrectionSetUp and L <= CorrectionLevel then begin
    CorrectionSetUp = False;
    Plot3(CorrectionLevel,"Correction",CorrectionColor); // dot at the breach point
    Draw_Label( CorrectionLevel, "   Correction",
        Color.FromARGB( 255, GetRValue( CorrectionColor ), GetGValue( CorrectionColor ), GetBValue( CorrectionColor ) ) );
End;

// --- 5. CRASH LOGIC ---
If ShowCrash and CrashSetUp and L <= CrashLevel then begin
    CrashSetUp = False;
    Plot4(CrashLevel,"Crash",CrashColor);
    Draw_Label( CrashLevel, "   Crash",
        Color.FromARGB( 255, GetRValue( CrashColor ), GetGValue( CrashColor ), GetBValue( CrashColor ) ) );
End;