Indicator ยท Pine Script v6 ยท Own pane

Manias, Panics and Crashes

by MeridianAlgo

Manias, Panics and Crashes is a separate-pane market regime indicator that quantifies market sentiment and systemic risk.

View on GitHub

GitHub stars9on the repository
Pine versionv6current
Lines of code538
Settings18inputs
LicenceMIT
Last update4 months ago29 Jun 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

538 lines of Pine Script v6 from examples/Manias_Panics_and_Crashes.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

Manias_Panics_and_Crashes.pine
//@version=6
indicator("Manias, Panics and Crashes", shorttitle="MPC", overlay=false, max_labels_count=500)

// ============================================================================
// IMPROVED COLOR PALETTE (Professional Trading Colors)
// ============================================================================
// Based on high-contrast, colorblind-friendly professional palette
color_green_bright = #00ff00     // Bright green for bullish/safe
color_green_soft = #26a69a       // Teal green (softer, professional)
color_yellow_bright = #ffd700    // Gold yellow for caution
color_orange_alert = #ff6b35     // Vibrant orange for warnings
color_red_danger = #ff1744       // Bright red for danger
color_purple_composite = #ab47bc // Purple for composite score
color_gray_neutral = #78909c     // Neutral gray
color_dark_bg = #1e1e1e         // Dark background

// ============================================================================
// INPUT PARAMETERS - ENHANCED UX/UI CONTROLS
// ============================================================================

// === DISPLAY OPTIONS ===
display_mode = input.string("Smoothed All Lines", "Display Mode",
     options=["Smoothed All Lines", "Single Dominant Line", "Both"],
     group="Display")
smooth_period = input.int(3, "Smoothing Period", minval=1, maxval=20, group="Display")
show_zones = input.bool(true, "Show Background Phase Zones", group="Display")
show_phase_labels = input.bool(true, "Show Phase Change Labels", group="Display")
show_historical_context = input.bool(true, "Show Historical Context", group="Display")

// === DASHBOARD SETTINGS ===
dashboard_position = input.string("Top Right", "Dashboard Position",
     options=["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Right", "Bottom Left", "Bottom Right"],
     group="Dashboard")
dashboard_size = input.string("Normal", "Dashboard Size",
     options=["Small", "Normal", "Large", "Extra Large"],
     group="Dashboard")
show_components = input.bool(true, "Show Component Health Panel", group="Dashboard")
show_action_hints = input.bool(true, "Show Action Guidance", group="Dashboard")

// === THRESHOLDS ===
mania_threshold = input.int(75, "Mania Alert Threshold", minval=0, maxval=100, group="Alert Thresholds")
panic_threshold = input.int(60, "Panic Alert Threshold", minval=0, maxval=100, group="Alert Thresholds")
crash_threshold = input.int(70, "Crash Alert Threshold", minval=0, maxval=100, group="Alert Thresholds")

// === TECHNICAL PARAMETERS ===
ma_period = input.int(200, "Long-term MA Period", minval=50, maxval=300, group="Technical Parameters")
rsi_period = input.int(14, "RSI Period", minval=5, maxval=30, group="Technical Parameters")
vol_period = input.int(20, "Volume Average Period", minval=10, maxval=50, group="Technical Parameters")

// === COMPONENTS ===
show_credit = input.bool(true, "Include Credit Risk Indicators", group="Components")
show_breadth = input.bool(true, "Include Market Breadth", group="Components")
show_vix = input.bool(true, "Include VIX Analysis", group="Components")

// ============================================================================
// EXTERNAL DATA REQUESTS
// ============================================================================
vix = show_vix ? request.security("TVC:VIX", timeframe.period, close) : na
vix_5 = show_vix ? request.security("TVC:VIX", timeframe.period, close[5]) : na
hyg = show_credit ? request.security("AMEX:HYG", timeframe.period, close) : na
lqd = show_credit ? request.security("AMEX:LQD", timeframe.period, close) : na
tlt = show_credit ? request.security("NASDAQ:TLT", timeframe.period, close) : na
xlf = show_credit ? request.security("AMEX:XLF", timeframe.period, close) : na
spy = show_credit ? request.security("AMEX:SPY", timeframe.period, close) : na
adv_dec = show_breadth ? request.security("INDEX:ADDN", timeframe.period, close) : na

// ============================================================================
// CREDIT RISK CALCULATIONS
// ============================================================================
hyg_lqd_ratio = show_credit and not na(hyg) and not na(lqd) ? lqd / hyg : na
hyg_lqd_spread = hyg_lqd_ratio
hyg_lqd_baseline = ta.sma(hyg_lqd_spread, 60)
hyg_lqd_stress = show_credit and not na(hyg_lqd_spread) and not na(hyg_lqd_baseline) ?
     ((hyg_lqd_spread - hyg_lqd_baseline) / hyg_lqd_baseline) * 100 : 0

tlt_spy_ratio = show_credit and not na(tlt) and not na(spy) ? tlt / spy : na
tlt_spy_baseline = ta.sma(tlt_spy_ratio, 60)
tlt_spy_flight = show_credit and not na(tlt_spy_ratio) and not na(tlt_spy_baseline) ?
     ((tlt_spy_ratio - tlt_spy_baseline) / tlt_spy_baseline) * 100 : 0

xlf_spy_ratio = show_credit and not na(xlf) and not na(spy) ? xlf / spy : na
xlf_spy_baseline = ta.sma(xlf_spy_ratio, 60)
xlf_spy_weakness = show_credit and not na(xlf_spy_ratio) and not na(xlf_spy_baseline) ?
     ((xlf_spy_baseline - xlf_spy_ratio) / xlf_spy_baseline) * 100 : 0

credit_stress_raw = show_credit ?
     (hyg_lqd_stress * 0.4) + (tlt_spy_flight * 0.3) + (xlf_spy_weakness * 0.3) : 0
credit_stress = math.max(0, math.min(100, credit_stress_raw * 5))

// ============================================================================
// TECHNICAL INDICATORS
// ============================================================================
ma_long = ta.sma(close, ma_period)
price_deviation = ((close - ma_long) / ma_long) * 100
rsi = ta.rsi(close, rsi_period)
rsi_overbought_days = ta.barssince(rsi < 70)
rsi_oversold = rsi < 30
roc = ta.roc(close, 20)
roc_ma = ta.sma(roc, 20)
roc_accelerating = roc > roc_ma
vol_avg = ta.sma(volume, vol_period)
vol_spike = volume / vol_avg
high_vol_down = vol_spike > 1.5 and close < open
[macd_line, signal_line, _] = ta.macd(close, 12, 26, 9)
macd_bearish = ta.crossunder(macd_line, signal_line)
vix_spike = show_vix and not na(vix) and not na(vix_5) ? (vix > vix_5 * 1.30 or vix > 25) : false
vix_extreme = show_vix and not na(vix) ? vix > 40 : false
vix_low = show_vix and not na(vix) ? vix < 20 : false
peak_20 = ta.highest(close, 20)
peak_60 = ta.highest(close, 60)
decline_20 = ((close - peak_20) / peak_20) * 100
decline_60 = ((close - peak_60) / peak_60) * 100
price_above_50ma = close > ta.sma(close, 50)
breadth_proxy = show_breadth ? ta.sma(price_above_50ma ? 1 : 0, 20) * 100 : 50
correlation_proxy = math.abs(ta.correlation(close, ma_long, 20)) * 100

// ============================================================================
// PHASE SCORES (RAW)
// ============================================================================
mania_price = price_deviation > 15 ? 25 : (price_deviation > 10 ? 15 : 0)
mania_rsi = (rsi > 70 and rsi_overbought_days > 10) ? 25 : (rsi > 70 ? 15 : 0)
mania_breadth = breadth_proxy > 60 ? 20 : (breadth_proxy > 50 ? 10 : 0)
mania_vix = vix_low ? 15 : 0
mania_momentum = roc_accelerating and roc > 0 ? 15 : 0
mania_score_raw = mania_price + mania_rsi + mania_breadth + mania_vix + mania_momentum

panic_decline = decline_20 < -5 and decline_20 > -15 ? 20 : 0
panic_vix_spike = vix_spike ? 20 : 0
panic_volume = high_vol_down ? 15 : 0
panic_breadth = breadth_proxy < 40 ? 15 : 0
panic_credit = credit_stress > 30 ? 15 : 0
panic_momentum = macd_bearish ? 15 : 0
panic_score_raw = panic_decline + panic_vix_spike + panic_volume + panic_breadth + panic_credit + panic_momentum

crash_extreme_decline = decline_60 < -15 ? 25 : (decline_60 < -10 ? 15 : 0)
crash_vix_extreme = vix_extreme ? 20 : 0
crash_volume_climax = vol_spike > 2.0 and close < open ? 15 : 0
crash_breadth_collapse = breadth_proxy < 20 ? 15 : 0
crash_correlation = correlation_proxy > 80 ? 15 : 0
crash_credit_freeze = credit_stress > 60 ? 10 : 0
crash_score_raw = crash_extreme_decline + crash_vix_extreme + crash_volume_climax + crash_breadth_collapse + crash_correlation + crash_credit_freeze

// ============================================================================
// SMOOTHING
// ============================================================================
mania_score = ta.sma(mania_score_raw, smooth_period)
panic_score = ta.sma(panic_score_raw, smooth_period)
crash_score = ta.sma(crash_score_raw, smooth_period)
composite_risk = math.max(mania_score, math.max(panic_score, crash_score))

// ============================================================================
// PHASE STATE MACHINE WITH PERSISTENCE
// ============================================================================
var string phase = "NORMAL"
var color phase_color = color_green_soft
var int phase_start_bar = na

// Determine dominant phase
string new_phase = "NORMAL"
if crash_score > crash_threshold
    new_phase := "CRASH"
else if panic_score > panic_threshold
    new_phase := "PANIC"
else if mania_score > mania_threshold
    new_phase := "MANIA"

// Detect phase change
phase_changed = new_phase != phase
if phase_changed
    phase := new_phase
    phase_start_bar := bar_index

// Update phase color with improved palette
phase_color := phase == "CRASH" ? color_red_danger :
     phase == "PANIC" ? color_orange_alert :
     phase == "MANIA" ? color_yellow_bright : color_green_soft

// Calculate days in current phase
days_in_phase = not na(phase_start_bar) ? bar_index - phase_start_bar + 1 : 0

// ============================================================================
// HISTORICAL CONTEXT COMPARISON
// ============================================================================
var string historical_context = ""
if show_historical_context
    if phase == "CRASH"
        if crash_score > 90
            historical_context := "Similar to: 2008 Crisis Peak"
        else if crash_score > 80
            historical_context := "Similar to: COVID-19 March 2020"
        else
            historical_context := "Similar to: Dec 2018 Selloff"
    else if phase == "PANIC"
        if panic_score > 75
            historical_context := "Similar to: Pre-2020 Crash"
        else
            historical_context := "Similar to: Flash Crash"
    else if phase == "MANIA"
        if mania_score > 85
            historical_context := "Similar to: Dot-Com Bubble 2000"
        else
            historical_context := "Similar to: Pre-2008 Peak"
    else
        historical_context := "Normal Market Conditions"

// ============================================================================
// ACTION GUIDANCE
// ============================================================================
var string action_hint = ""
if show_action_hints
    if phase == "CRASH"
        action_hint := "๐Ÿ†˜ CAPITULATION - Prepare to Buy Quality"
    else if phase == "PANIC"
        action_hint := "โš ๏ธ RAISE CASH - Avoid Buying Dips"
    else if phase == "MANIA"
        action_hint := "โš ๏ธ REDUCE EXPOSURE - Take Profits"
    else if composite_risk > 50
        action_hint := "โšก ELEVATED RISK - Monitor Closely"
    else
        action_hint := "โœ… NORMAL - Continue Regular Strategy"

// ============================================================================
// COMPONENT HEALTH STATUS
// ============================================================================
vix_status = show_vix and not na(vix) ?
     (vix > 40 ? "๐Ÿ”ด EXTREME" :
      vix > 25 ? "๐ŸŸ  HIGH" :
      vix < 20 ? "๐ŸŸข LOW" : "๐ŸŸก MODERATE") : "N/A"

credit_status = show_credit ?
     (credit_stress > 70 ? "๐Ÿ”ด FREEZE" :
      credit_stress > 40 ? "๐ŸŸ  STRESS" :
      credit_stress > 20 ? "๐ŸŸก ELEVATED" : "๐ŸŸข NORMAL") : "N/A"

breadth_status = show_breadth ?
     (breadth_proxy < 20 ? "๐Ÿ”ด COLLAPSE" :
      breadth_proxy < 40 ? "๐ŸŸ  WEAK" :
      breadth_proxy > 60 ? "๐ŸŸข STRONG" : "๐ŸŸก NEUTRAL") : "N/A"

momentum_status = rsi > 70 ? "๐Ÿ”ด OVERBOUGHT" :
     rsi < 30 ? "๐ŸŸข OVERSOLD" :
     roc > 5 ? "๐ŸŸข BULLISH" :
     roc < -5 ? "๐Ÿ”ด BEARISH" : "๐ŸŸก NEUTRAL"

// ============================================================================
// PHASE CHANGE LABELS ON CHART - UPDATED (No "NORMAL", shorter text)
// ============================================================================
if show_phase_labels and phase_changed and barstate.isconfirmed
    // Skip NORMAL labels, only show phase alerts
    if phase != "NORMAL"
        label_text = phase == "CRASH" ? "๐Ÿ”ด CRASH" :
             phase == "PANIC" ? "๐ŸŸ  PANIC" :
             phase == "MANIA" ? "๐ŸŸก MANIA" : ""

        label_color = phase == "CRASH" ? color.new(color_red_danger, 0) :
             phase == "PANIC" ? color.new(color_orange_alert, 0) :
             phase == "MANIA" ? color.new(color_yellow_bright, 0) : na

        if label_text != ""
            label.new(bar_index, composite_risk, label_text,
                 style=label.style_label_down,
                 color=label_color,
                 textcolor=color.white,
                 size=size.large,
                 textalign=text.align_center)

// ============================================================================
// PLOTTING - LINES (Improved colors)
// ============================================================================
// Choose display mode
show_all_lines = display_mode == "Smoothed All Lines" or display_mode == "Both"
show_dominant_only = display_mode == "Single Dominant Line" or display_mode == "Both"

// Plot individual lines (smoothed) with improved colors
plot(show_all_lines ? mania_score : na, title="Mania Score",
     color=color.new(color_yellow_bright, 0), linewidth=2)
plot(show_all_lines ? panic_score : na, title="Panic Score",
     color=color.new(color_orange_alert, 0), linewidth=2)
plot(show_all_lines ? crash_score : na, title="Crash Score",
     color=color.new(color_red_danger, 0), linewidth=2)

// Plot dominant line (thick, prominent)
dominant_color = phase == "CRASH" ? color_red_danger :
     phase == "PANIC" ? color_orange_alert :
     phase == "MANIA" ? color_yellow_bright : color_gray_neutral
plot(show_dominant_only ? composite_risk : na, title="Dominant Risk",
     color=color.new(dominant_color, 0), linewidth=4, style=plot.style_line)

// ============================================================================
// BACKGROUND ZONES - Improved colors with better contrast
// ============================================================================
bg_color = show_zones ?
     (phase == "CRASH" ? color.new(color_red_danger, 88) :
     phase == "PANIC" ? color.new(color_orange_alert, 92) :
     phase == "MANIA" ? color.new(color_yellow_bright, 94) :
     color.new(color_green_soft, 96)) : na

bgcolor(bg_color, title="Phase Background")

// ============================================================================
// THRESHOLD LINES & ZONES (Improved colors)
// ============================================================================
hline(100, "Max", color=color.new(color_gray_neutral, 70), linestyle=hline.style_solid)
hline(crash_threshold, "Crash Threshold",
     color=color.new(color_red_danger, 50), linestyle=hline.style_dashed, linewidth=2)
hline(panic_threshold, "Panic Threshold",
     color=color.new(color_orange_alert, 50), linestyle=hline.style_dashed, linewidth=2)
hline(mania_threshold, "Mania Threshold",
     color=color.new(color_yellow_bright, 50), linestyle=hline.style_dashed, linewidth=2)
hline(0, "Min", color=color.new(color_gray_neutral, 70), linestyle=hline.style_solid)

// Risk zone fills with improved colors
h100 = hline(100, color=color.new(color.gray, 100))
h85 = hline(85, color=color.new(color.gray, 100))
h60 = hline(60, color=color.new(color.gray, 100))
h30 = hline(30, color=color.new(color.gray, 100))
h0 = hline(0, color=color.new(color.gray, 100))

fill(h85, h100, color=color.new(color_red_danger, 92), title="Extreme Risk")
fill(h60, h85, color=color.new(color_orange_alert, 92), title="High Risk")
fill(h30, h60, color=color.new(color_yellow_bright, 95), title="Elevated Risk")
fill(h0, h30, color=color.new(color_green_soft, 95), title="Normal")

// ============================================================================
// ENHANCED DASHBOARD - NORMALIZED FONTS & IMPROVED DESCRIPTIONS
// ============================================================================
// Determine position
var string h_position = position.top_right
if dashboard_position == "Top Left"
    h_position := position.top_left
else if dashboard_position == "Top Center"
    h_position := position.top_center
else if dashboard_position == "Top Right"
    h_position := position.top_right
else if dashboard_position == "Middle Left"
    h_position := position.middle_left
else if dashboard_position == "Middle Right"
    h_position := position.middle_right
else if dashboard_position == "Bottom Left"
    h_position := position.bottom_left
else if dashboard_position == "Bottom Right"
    h_position := position.bottom_right

// Normalized font sizes (more consistent)
var string text_size_header = size.large
var string text_size_normal = size.normal
var string text_size_small = size.small

if dashboard_size == "Small"
    text_size_header := size.normal
    text_size_normal := size.small
    text_size_small := size.tiny
else if dashboard_size == "Large"
    text_size_header := size.large
    text_size_normal := size.normal
    text_size_small := size.small
else if dashboard_size == "Extra Large"
    text_size_header := size.huge
    text_size_normal := size.large
    text_size_small := size.normal
// Default "Normal" uses the var initialization values

// Calculate number of rows needed
title_rows = 1 // Title row
base_rows = 4 // Phase, Risk, Action, Historical
component_rows = show_components ? 5 : 0 // Header + 4 components
total_rows = title_rows + base_rows + component_rows

// Create main dashboard table
var table dashboard = table.new(h_position, 2, total_rows,
     bgcolor=color.new(color_dark_bg, 80),
     border_width=3,
     border_color=phase_color)

if barstate.islast
    row = 0

    // === ROW 0: TITLE ===
    // Note: Pine Script doesn't support multi-colored text or colspan,
    // so we merge visually by using both cells with centered text
    table.cell(dashboard, 0, row, "",
         bgcolor=color.new(phase_color, 20))
    table.cell(dashboard, 1, row, "๐ŸŸก Manias, ๐ŸŸ  Panics and ๐Ÿ”ด Crashes",
         text_color=color.white,
         text_size=text_size_header,
         text_halign=text.align_center,
         bgcolor=color.new(phase_color, 20))
    row := row + 1

    // === ROW 1: PHASE (BIG) ===
    table.cell(dashboard, 0, row, "PHASE",
         text_color=color.white,
         text_size=text_size_normal,
         bgcolor=color.new(color_gray_neutral, 60))
    table.cell(dashboard, 1, row, phase,
         text_color=phase_color,
         text_size=text_size_header,
         bgcolor=color.new(color_dark_bg, 50))
    row := row + 1

    // === ROW 2: RISK SCORE (GAUGE STYLE) ===
    risk_display = str.tostring(math.round(composite_risk)) + " / 100"
    risk_label = composite_risk > 85 ? "๐Ÿ”ด EXTREME RISK" :
         composite_risk > 60 ? "๐ŸŸ  HIGH RISK" :
         composite_risk > 30 ? "๐ŸŸก ELEVATED RISK" : "๐ŸŸข LOW RISK"

    table.cell(dashboard, 0, row, "RISK",
         text_color=color.white,
         text_size=text_size_normal,
         bgcolor=color.new(color_gray_neutral, 60))
    table.cell(dashboard, 1, row, risk_display + "\n" + risk_label,
         text_color=phase_color,
         text_size=text_size_normal,
         bgcolor=color.new(color_dark_bg, 50))
    row := row + 1

    // === ROW 3: ACTION GUIDANCE ===
    if show_action_hints
        table.cell(dashboard, 0, row, "ACTION",
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_gray_neutral, 60))
        table.cell(dashboard, 1, row, action_hint,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 50))
        row := row + 1

    // === ROW 4: HISTORICAL CONTEXT ===
    if show_historical_context
        table.cell(dashboard, 0, row, "CONTEXT",
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_gray_neutral, 60))
        table.cell(dashboard, 1, row, historical_context + "\nDay " + str.tostring(days_in_phase) + " of " + phase,
             text_color=color.gray,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 50))
        row := row + 1

    // === COMPONENT HEALTH PANEL - IMPROVED WITH DESCRIPTIONS ===
    if show_components
        // Header
        table.cell(dashboard, 0, row, "COMPONENTS",
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_purple_composite, 40))
        table.cell(dashboard, 1, row, "STATUS",
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_purple_composite, 40))
        row := row + 1

        // VIX - Volatility/Fear Gauge
        vix_value = show_vix and not na(vix) ? str.tostring(math.round(vix * 10) / 10) : "N/A"
        table.cell(dashboard, 0, row, "VIX (Fear): " + vix_value,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        table.cell(dashboard, 1, row, vix_status,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        row := row + 1

        // Credit - Stress in Bond Markets
        credit_value = show_credit ? str.tostring(math.round(credit_stress)) : "N/A"
        table.cell(dashboard, 0, row, "Credit (Bonds): " + credit_value,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        table.cell(dashboard, 1, row, credit_status,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        row := row + 1

        // Breadth - Market Participation
        breadth_value = show_breadth ? str.tostring(math.round(breadth_proxy)) + "%" : "N/A"
        table.cell(dashboard, 0, row, "Breadth (Participation): " + breadth_value,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        table.cell(dashboard, 1, row, breadth_status,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        row := row + 1

        // Momentum - Price Direction
        rsi_value = str.tostring(math.round(rsi))
        table.cell(dashboard, 0, row, "Momentum (RSI): " + rsi_value,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))
        table.cell(dashboard, 1, row, momentum_status,
             text_color=color.white,
             text_size=text_size_normal,
             bgcolor=color.new(color_dark_bg, 65))

// ============================================================================
// ALERTS - Fixed for Pine v6
// ============================================================================
mania_alert = phase == "MANIA" and phase[1] != "MANIA"
panic_alert = phase == "PANIC" and phase[1] != "PANIC"
crash_alert = phase == "CRASH" and phase[1] != "CRASH"
breadth_collapse_alert = breadth_proxy < 30 and breadth_proxy[1] >= 30
vix_spike_alert = show_vix and not na(vix) and not na(vix_5) and vix > vix_5 * 1.30 and vix[1] <= vix_5[1] * 1.30
credit_freeze_alert = credit_stress > 70 and credit_stress[1] <= 70

alertcondition(mania_alert, title="๐ŸŸก Mania Phase Detected",
     message="๐ŸŸก MANIA PHASE: Elevated crash risk detected. Consider reducing exposure and taking profits.")

alertcondition(panic_alert, title="๐ŸŸ  Panic Phase Detected",
     message="๐ŸŸ  PANIC PHASE: Severe market stress detected. Consider raising cash and avoiding buying dips.")

alertcondition(crash_alert, title="๐Ÿ”ด CRASH DETECTED",
     message="๐Ÿ”ด CRASH PHASE: Capitulation event detected. Extreme risk - prepare to buy quality after capitulation.")

alertcondition(breadth_collapse_alert, title="โš ๏ธ Breadth Collapse",
     message="โš ๏ธ Market breadth collapsed below 30% - participation deteriorating rapidly.")

alertcondition(vix_spike_alert, title="โš ๏ธ VIX Spike",
     message="โš ๏ธ VIX spiked >30% in 5 days - fear increasing rapidly.")

alertcondition(credit_freeze_alert, title="โš ๏ธ Credit Freeze",
     message="โš ๏ธ Credit stress extreme - potential liquidity crisis developing.")

// ============================================================================
// DATA WINDOW (For debugging)
// ============================================================================
plotchar(composite_risk, title="Composite Risk", char="", location=location.top, display=display.data_window)
plotchar(mania_score, title="Mania Score", char="", location=location.top, display=display.data_window)
plotchar(panic_score, title="Panic Score", char="", location=location.top, display=display.data_window)
plotchar(crash_score, title="Crash Score", char="", location=location.top, display=display.data_window)
plotchar(show_vix ? vix : na, title="VIX", char="", location=location.top, display=display.data_window)
plotchar(credit_stress, title="Credit Stress", char="", location=location.top, display=display.data_window)
plotchar(breadth_proxy, title="Breadth %", char="", location=location.top, display=display.data_window)

Overview

Manias, Panics and Crashes processes technical metrics including RSI, moving averages, and volume alongside optional intermarket data such as VIX volatility and credit spreads. The indicator outputs composite score lines for mania, panic, and crash risk, accompanied by background phase zones, phase change labels, and an onscreen dashboard featuring component health status and guidance hints.

Details

Published by

MeridianAlgo on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Oscillators & momentum, Volatility & bands, Screeners & dashboards, Trend

Markets

Stocks, Indices

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Topics

code-converterconverterjavascriptpinescripttranspilercode-reviewmeridianalgocode-conversionpinescript-algorithms

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Display ModestringSmoothed All Linesdisplay_mode
Smoothing Periodint3smooth_period
Show Background Phase Zonesbooltrueshow_zones
Show Phase Change Labelsbooltrueshow_phase_labels
Show Historical Contextbooltrueshow_historical_context
Dashboard PositionstringTop Rightdashboard_position
Dashboard SizestringNormaldashboard_size
Show Component Health Panelbooltrueshow_components
Show Action Guidancebooltrueshow_action_hints
Mania Alert Thresholdint75mania_threshold
Panic Alert Thresholdint60panic_threshold
Crash Alert Thresholdint70crash_threshold
Show all 18 settings
SettingTypeDefaultVariable
Long-term MA Periodint200ma_period
RSI Periodint14rsi_period
Volume Average Periodint20vol_period
Include Credit Risk Indicatorsbooltrueshow_credit
Include Market Breadthbooltrueshow_breadth
Include VIX Analysisbooltrueshow_vix
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This indicator scans a pasted list of symbols and shows matching long and short setups in a table in a separate pane. It uses a Supertrend crossover, then applies an ATR or fixed-point volatility range so quiet, sideways conditions can be skipped. Optional fil

Indicator v5 TrendVolatility & bands
Updated 1 year ago ยท MPL-2.0 GitHub repository of Trend Following Setup - Sideways Market Skipper Scanner

Test 009 Stat Mining

by ricardosantos79
261 stars

This statistical analysis tool mines historical relationships between RSI values and candle volatility. It calculates a 14-period RSI from the previous bar and normalizes absolute price change using a 14-period Average True Range (ATR). Based on the normalized

Indicator v4 Oscillators & momentumVolatility & bands
Updated 4 years ago ยท None stated GitHub repository of Test 009 Stat Mining

Market Speedometer

by TradersPost
218 stars

Market Speedometer plots a 0-100 market speed reading in a separate pane. It measures movement by bar-to-bar change, true range, or a short average of recent bars, then ranks that movement against ATR and a percentile lookback. An EMA smooths the reading, and

Indicator v6 Volatility & bandsOscillators & momentum
Updated 3 months ago ยท None stated GitHub repository of Market Speedometer
147 stars

This indicator generates trade entry signals and target levels optimized for 1-hour timeframes, designed for external signal extraction. It calculates 7-period and 16-period EMAs alongside 10-period RSI and ATR filters. Long signals occur when the fast EMA cro

Indicator v5 TrendOscillators & momentum
Updated 6 weeks ago ยท MIT GitHub repository of Signal Strategy 100 Candles of 1H Timeframe

KamaFama

by Mastaaa1987
141 stars

KamaFama is an indicator that translates a Freqtrade trading strategy into Pine Script for visualization. It combines Kaufman Adaptive Moving Average (KAMA), MAMA/FAMA calculations derived via Hilbert Transform, Williams %R, and correlation trend filters to ev

Indicator v6 Moving averagesOscillators & momentum
Updated 6 weeks ago ยท MIT GitHub repository of KamaFama

MultiIndicator

by capissimo
114 stars

MultiIndicator combines multiple technical indicators into a single separate pane to save chart space. It calculates and displays market regime detection based on ordinary least squares regression, a Holt exponential smoothing crossover, normalized RSI, ADX, a

Indicator v4 Oscillators & momentumTrend
Updated 1 year ago ยท None stated GitHub repository of MultiIndicator

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers