High-Low Index म्हणजे काय? Market Breadth गणना
High-Low Index हा Record High Percentचा 10-दिवसांचा सरासरी निर्देशांक आहे. round numbersमधील formula आणि शांत बाजारातील sample size trap समजून घ्या.
High-Low Index हा बाजारातील breadth मोजणारा निर्देशांक आहे. तो दोन मोजमापांवर आधारित असतो: तो Record High Percentची 10-दिवसांची simple moving average आहे. Record High Percent म्हणजे नवीन 52-week highsची संख्या आणि नवीन 52-week highs व नवीन 52-week lows यांच्या बेरजेचे गुणोत्तर, 100 ने गुणलेले. 50 पेक्षा जास्त reading म्हणजे नवीन lowsपेक्षा नवीन highsवर बंद होणारे शेअर्स अधिक आहेत. 50 पेक्षा कमी reading म्हणजे याच्या उलट स्थिती. Formula इतकाच संक्षिप्त आहे. पुढे round numbersमध्ये केलेली arithmetic आणि sample sizeमधील त्रुटी दिली आहे. या त्रुटीमुळे मोजक्या शेअर्सवर आधारित reading निर्णायक दिसू शकते.
High-Low Indexची गणना कशी करतात?
दोन पायऱ्या आहेत. दोन्ही एका ओळीत मावतात.
- एका sessionसाठी Record High Percent: तुमच्या universeमधील नवीन 52-week highवर बंद झालेले शेअर्स मोजा. नवीन 52-week lowवर बंद झालेले शेअर्स मोजा. highsची संख्या या दोन्ही संख्यांच्या बेरजेने भागा आणि 100 ने गुणा.
- High-Low Index: मागील 10 दैनिक Record High Percent readingsची average काढा.
Round numbersमुळे हे स्पष्ट होते. एखाद्या tapeवर 90 new highs आणि 30 new lows आहेत. Highs आणि lows मिळून 120 होतात. 90 ला 120 ने भागल्यास 0.75 येते. त्यामुळे त्या sessionचा Record High Percent 75 असतो. आता दहा sessionsच्या readings घ्या: 75, 70, 65, 60, 55, 50, 45, 40, 35 आणि 30. त्यांची बेरीज 525 आहे. 525 ला 10 ने भागल्यास 52.5 येते. त्या दिवशीचा Record High Percent 75 असतानाही High-Low Index 52.5 दाखवतो.
Moving averageने केलेला trade-off हाच आहे. दहा दिवसांची memory एका रात्रीत 100 वरून 0 पर्यंत बदलू शकणारी मालिका smooth करते. मात्र त्यामुळे reading उशिरा येते. हा index दोन आठवड्यांच्या कालावधीत breadth कुठे होता हे सांगतो. आज दुपारी काय घडले, हे तो कधीच सांगत नाही.
नवीन 52-week high कशाला म्हणतात?
एखाद्या शेअरची किंमत मागील 52 weeksमध्ये नोंदवलेल्या प्रत्येक किंमतीपेक्षा वर गेली, तर तो शेअर नवीन 52-week high करतो. Data providers यासाठी वेगवेगळे आधार वापरतात. काही intraday highs आणि lowsची तुलना करतात. काही फक्त closing pricesची तुलना करतात. त्यामुळे त्याच sessionसाठी दोन्ही पद्धतींमध्ये वेगवेगळे counts मिळतात. या संपूर्ण पानावर closing prices हा आधार आहे. नवीन 52-week highs आणि lows या यादीचेच स्पष्टीकरण देते.
खालील panelमध्ये 1 April ते 31 July 2026 या कालावधीत निश्चित केलेल्या 40 large-cap US namesच्या basketसाठी प्रत्येक sessionमधील दोन्ही extremes मोजले आहेत. या आकाराच्या basketमुळे counts हाताने तपासता येतील इतके लहान राहतात. पुढे formulaमधील त्रुटी स्पष्ट दिसण्याचे कारण हेच आहे.
प्रत्येक आकड्यामागील अचूक SQL
WITH daily_close AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(close, window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
AND window_start >= toDateTime('2025-03-01 00:00:00')
AND window_start < toDateTime('2026-08-01 05:00:00')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session_date
),
extremes AS (
SELECT cur.ticker AS ticker,
cur.session_date AS session_date,
cur.close_px AS close_px,
max(hist.close_px) AS high_52w,
min(hist.close_px) AS low_52w
FROM daily_close AS cur
INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
WHERE cur.session_date >= toDate('2026-04-01')
AND hist.session_date <= cur.session_date
AND hist.session_date > cur.session_date - 364
GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
SELECT session_date,
countIf(close_px >= high_52w) AS new_highs,
countIf(close_px <= low_52w) AS new_lows,
countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
FROM extremes
GROUP BY session_date
HAVING names_at_extreme > 0
)
SELECT session_date AS date,
formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
new_highs,
new_lows
FROM daily
ORDER BY session_date77 sessionsमध्ये हे दोन counts क्वचितच एकाच वेळी वाढतात. Jul 29 रोजी, म्हणजे या windowमधील शेवटच्या sessionला, 40 namesपैकी 3 names 52-week highवर बंद झाले आणि 0 names 52-week lowवर बंद झाले. Apr 1 रोजी, म्हणजे पहिल्या sessionला, highsची संख्या 1 आणि lowsची संख्या 1 होती. Basketमधील इतर प्रत्येक name आपल्या rangeच्या आत होता आणि calculationमध्ये आला नाही.
High-Low Indexची चांगली reading कोणती?
50 ही pivot line आहे. या पातळीवर highs आणि lows संतुलित असतात. Conventional strong marker 70 आहे. या पातळीवर संपूर्ण 10-day averageमध्ये new highsनी new lowsपेक्षा two-to-oneपेक्षा अधिक आघाडी घेतलेली असते. Conventional weak marker 30 आहे. तो त्याच स्थितीचा उलटा आहे. 30 आणि 70 दरम्यान index बाजारातील extremes मिश्र असल्याचे सांगतो. तो बहुतांश वेळा याच पट्ट्यात असतो.
खालील panelमध्ये त्याच basketसाठी raw daily Record High Percent आणि त्याची 10-day average दाखवली आहे. Lagचे स्वरूप chartवरच दिसते.
प्रत्येक आकड्यामागील अचूक SQL
WITH daily_close AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(close, window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
AND window_start >= toDateTime('2025-03-01 00:00:00')
AND window_start < toDateTime('2026-08-01 05:00:00')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session_date
),
extremes AS (
SELECT cur.ticker AS ticker,
cur.session_date AS session_date,
cur.close_px AS close_px,
max(hist.close_px) AS high_52w,
min(hist.close_px) AS low_52w
FROM daily_close AS cur
INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
WHERE cur.session_date >= toDate('2026-04-01')
AND hist.session_date <= cur.session_date
AND hist.session_date > cur.session_date - 364
GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
SELECT session_date,
countIf(close_px >= high_52w) AS new_highs,
countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
FROM extremes
GROUP BY session_date
HAVING names_at_extreme > 0
),
rhp AS (
SELECT session_date,
round(100 * new_highs / names_at_extreme, 1) AS record_high_pct
FROM daily
),
smoothed AS (
SELECT session_date,
record_high_pct,
round(avg(record_high_pct) OVER (ORDER BY session_date
ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS high_low_index_pct,
count() OVER (ORDER BY session_date
ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) AS sessions_in_window
FROM rhp
)
SELECT session_date AS date,
formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
record_high_pct,
high_low_index_pct
FROM smoothed
WHERE sessions_in_window = 10
ORDER BY session_dateदाखवलेली range Apr 15 रोजी 100 Record High Percentने सुरू होते आणि त्या वेळी index 52.5 होता. Jul 29 रोजी ती 100वर बंद होते आणि index 64 होता. प्रत्येक readingची 70 आणि 30 markersशी तुलना करा. दोन linesमधील अंतर हे smoothingची किंमत दाखवते. कोणत्याही दिवशी averageमध्ये आधीच्या नऊ sessionsचा प्रभाव अजून असतो. Windowमधील पहिले नऊ sessions panelमधून वगळले आहेत, कारण 10-day averageसाठी 10 दिवस आवश्यक असतात.
Denominator बाजारातील बहुतांश भागाकडे दुर्लक्ष करतो
लक्षात ठेवण्यासारखी मर्यादा ही आहे. Record High Percentचा denominator म्हणजे new highs आणि new lows यांची बेरीज. त्यात इतर काहीही नसते. एखादा शेअर आपल्या 52-week rangeच्या मध्यावर असेल, तर तो numeratorमध्येही नसतो आणि denominatorमध्येही नसतो. 3,000 namesपैकी 900 names extremeवर पोहोचलेल्या sessionला आणि केवळ 9 names extremeवर पोहोचलेल्या sessionला हा index वेगळे ओळखू शकत नाही. दोन्ही ठिकाणी तो समान, निर्णायक दिसणारी दोन अंकी संख्या दाखवतो.
6,000 names असलेल्या exchangeवर Augustमधील मंद sessionची कल्पना करा. 40 stocks नवीन highs करतात आणि 20 नवीन lows करतात. Record High Percent म्हणजे 40 ला 60 ने भागलेले, म्हणजे 66.7. ही reading व्यापक वाढीसारखी दिसते. मात्र ती listingsपैकी 1% वर आधारित आहे. उरलेल्या 5,940 namesना कोणतेही मत नव्हते.
40-name basket हीच बाब मोजता येईल अशा स्वरूपात दाखवते. Windowमधील प्रत्येक sessionमध्ये किती namesनी कोणताही extreme नोंदवला, यानुसार त्यांना bucketमध्ये वर्गीकृत केले आहे.
प्रत्येक आकड्यामागील अचूक SQL
WITH daily_close AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(close, window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
AND window_start >= toDateTime('2025-03-01 00:00:00')
AND window_start < toDateTime('2026-08-01 05:00:00')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session_date
),
extremes AS (
SELECT cur.ticker AS ticker,
cur.session_date AS session_date,
cur.close_px AS close_px,
max(hist.close_px) AS high_52w,
min(hist.close_px) AS low_52w
FROM daily_close AS cur
INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
WHERE cur.session_date >= toDate('2026-04-01')
AND hist.session_date <= cur.session_date
AND hist.session_date > cur.session_date - 364
GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
SELECT session_date,
countIf(close_px >= high_52w) AS new_highs,
countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
FROM extremes
GROUP BY session_date
HAVING names_at_extreme > 0
)
SELECT multiIf(names_at_extreme <= 3, '1 to 3 names',
names_at_extreme <= 9, '4 to 9 names',
'10 or more names') AS sample_size_bucket,
count() AS readings,
round(avg(names_at_extreme), 1) AS avg_names_in_denominator,
round(quantileDeterministic(0.5)(100 * new_highs / names_at_extreme,
cityHash64(session_date)), 1) AS median_record_high_pct,
round(quantileDeterministic(0.5)(abs(100 * new_highs / names_at_extreme - 50),
cityHash64(session_date)), 1) AS median_distance_from_50
FROM daily
GROUP BY sample_size_bucket
ORDER BY avg_names_in_denominator1 to 3 names bucketमधील 39 sessionsमध्ये संपूर्ण reading 40पैकी सरासरी 2 namesवर आधारित होती. त्या sessionsचा median Record High Percent 100 होता आणि ते 50 lineपासून median 50 points दूर होते. 10 or more names sessionsमध्ये 1 sessionsचा denominatorमध्ये सरासरी 10 namesचा समावेश होता. त्यांचा median 70 होता आणि ते middleपासून 20 points दूर होते.
Arithmeticमुळे thin sessionमध्ये कोणत्या readings शक्य आहेत, यालाही मर्यादा येते. Extremeवर तीन names असतील, तर शक्य readings फक्त 0, 33.3, 66.7 आणि 100 असतात. दोन names असतील, तर फक्त 0, 50 आणि 100 शक्य असतात. दोन highs आणि एक low यांवर आधारित 66.7 readingमध्ये decimal point असतो; मात्र तिचा sample size इतकी अचूकता समर्थित करत नाही. हे टाळण्याचा सरळ मार्ग असा आहे: indexकडे एकट्याने पाहू नका. त्याच्यासोबत highs आणि lowsचे raw counts नेहमी वाचा.
Market breadth: High-Low Index विरुद्ध advance/decline
दोन्ही measures किती शेअर्स सहभागी आहेत, हे विचारतात. मात्र त्यांचे horizons वेगवेगळे आहेत. Advance/decline breadth कालच्या तुलनेत वर किंवा खाली बंद झालेल्या प्रत्येक nameची संख्या मोजते. त्याचा denominator संपूर्ण universe असतो आणि तो एका दिवसाचे चित्र दाखवतो. High-Low Index फक्त 52-week extremeवर असलेल्या namesची संख्या मोजतो. त्याचा denominator लहान असतो आणि तो prices वर्षभराच्या इतिहासाच्या तुलनेत कुठे आहेत, हे दाखवतो. एखाद्या दिवशी tape व्यापकपणे वर जाऊ शकतो, तरीही फारच कमी names 52-week highच्या जवळ असू शकतात.
खालील panelमध्ये त्याच basketवर दोन्ही measuresची त्याच 10 sessionsची average दाखवली आहे. त्यामुळे दोन्ही एकाच scaleवर दिसतात.
प्रत्येक आकड्यामागील अचूक SQL
WITH daily_close AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS session_date,
argMax(close, window_start) AS close_px
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','AVGO','JPM','JNJ','XOM','PG',
'KO','PEP','WMT','HD','CVX','MRK','PFE','ABBV','CSCO','ORCL',
'CRM','ADBE','MCD','NKE','VZ','T','DIS','BA','CAT','GE',
'IBM','MMM','UNH','LLY','COST','TGT','SBUX','GS','MS','LIN')
AND window_start >= toDateTime('2025-03-01 00:00:00')
AND window_start < toDateTime('2026-08-01 05:00:00')
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, session_date
),
extremes AS (
SELECT cur.ticker AS ticker,
cur.session_date AS session_date,
cur.close_px AS close_px,
max(hist.close_px) AS high_52w,
min(hist.close_px) AS low_52w
FROM daily_close AS cur
INNER JOIN daily_close AS hist ON cur.ticker = hist.ticker
WHERE cur.session_date >= toDate('2026-04-01')
AND hist.session_date <= cur.session_date
AND hist.session_date > cur.session_date - 364
GROUP BY cur.ticker, cur.session_date, cur.close_px
),
daily AS (
SELECT session_date,
countIf(close_px >= high_52w) AS new_highs,
countIf(close_px >= high_52w) + countIf(close_px <= low_52w) AS names_at_extreme
FROM extremes
GROUP BY session_date
HAVING names_at_extreme > 0
),
prior AS (
SELECT ticker,
session_date,
close_px,
lagInFrame(close_px, 1) OVER (PARTITION BY ticker ORDER BY session_date
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev_close
FROM daily_close
),
breadth AS (
SELECT session_date,
round(100 * countIf(close_px > prev_close) / count(), 1) AS advancing_pct
FROM prior
WHERE session_date >= toDate('2026-04-01')
AND prev_close > 0
GROUP BY session_date
HAVING count() >= 20
),
combined AS (
SELECT d.session_date AS session_date,
round(100 * d.new_highs / d.names_at_extreme, 1) AS record_high_pct,
b.advancing_pct AS advancing_pct
FROM daily AS d
INNER JOIN breadth AS b ON d.session_date = b.session_date
),
smoothed AS (
SELECT session_date,
round(avg(record_high_pct) OVER (ORDER BY session_date
ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS high_low_index_pct,
round(avg(advancing_pct) OVER (ORDER BY session_date
ROWS BETWEEN 9 PRECEDING AND CURRENT ROW), 1) AS advancing_pct_10d,
count() OVER (ORDER BY session_date
ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) AS sessions_in_window
FROM combined
)
SELECT session_date AS date,
formatDateTimeInJodaSyntax(session_date, 'MMM d') AS session_label,
high_low_index_pct,
advancing_pct_10d
FROM smoothed
WHERE sessions_in_window = 10
ORDER BY session_dateदाखवलेली range Apr 15 रोजी High-Low Indexसाठी 52.5 आणि 10-day advancing shareसाठी 52.8 येथे सुरू होते. Jul 29 रोजी ती अनुक्रमे 64 आणि 52.5 येथे संपते. या कालावधीत 68 plotted sessions आहेत. Advancing share अरुंद bandमध्ये राहतो. सामान्य sessionमध्ये basketमधील साधारण निम्मे names वर बंद होतात. अशा दहा readingsची average काढल्यावर line scaleच्या middleजवळ राहते. High-Low Indexला असा anchor नसतो. Basketमधील कोणत्याही nameने सलग दहा sessions 52-week low नोंदवला नाही, तर प्रत्येक daily reading 100 असते आणि averageही 100 असते.
Participation measuresसोबत breadth वाचल्यास चित्र अधिक स्पष्ट होते. Relative volume एखादा name आज त्याच्या नेहमीच्या तुलनेत असामान्यपणे मोठ्या volumeमध्ये trade होत आहे का, हे विचारते. या आठवड्यातील सर्वाधिक हालचाल केलेले stocks प्रत्यक्षात कोणत्या namesमध्ये मोठी हालचाल झाली, हे दाखवते. या आठवड्यातील unusual volume stocks trading कुठे झाले, हे दाखवते.
High-Low Index FAQ
70 पेक्षा जास्त High-Low Index readingचा अर्थ काय?
मागील ten sessionsच्या averageमध्ये new 52-week highsनी new 52-week lowsपेक्षा two-to-oneपेक्षा अधिक आघाडी घेतली, असा त्याचा अर्थ आहे. हा conventional strong-tape marker आहे. मात्र किती stocksनी कोणताही extreme गाठला, हे तो सांगत नाही. त्याच्यासोबत तपासायचा महत्त्वाचा count तोच आहे.
Record High Percent आणि High-Low Indexमध्ये काय फरक आहे?
Record High Percent हा single-session figure आहे. तो new highsला new highs आणि new lows यांच्या बेरजेने भागून 100 ने गुणल्यावर मिळतो. High-Low Index हा त्या figureची 10-day simple moving average आहे. एक आजचे चित्र दाखवतो. दुसरा मागील दोन आठवड्यांचे चित्र दाखवतो.
High-Low Index 0 किंवा 100 असू शकतो का?
होय. जर universeमधील कोणत्याही stockने सलग दहा sessionsमध्ये नवीन 52-week low केला नाही, तर प्रत्येक daily reading 100 असते आणि averageही 100 असते. कोणत्याही stockने high किंवा low केले नाही, तर fractionचा denominator zero असतो. त्या sessionसाठी reading defined नसते.
High-Low Index आणि advance/decline breadth एकच आहेत का?
नाही. Advance/decline breadth संपूर्ण universeने भाग देऊन एका दिवसातील दिशेचे चित्र दाखवते. High-Low Index 52-week extremesवर असलेल्या लहान groupने भाग देतो आणि एका वर्षाच्या pricesच्या तुलनेत शेअर्सची स्थिती दाखवतो.
High-Low Indexच्या denominatorमध्ये साधारण किती stocks असतात?
April ते July 2026 या कालावधीत येथे मोजलेल्या 40-name basketमध्ये 1 to 3 names bucketमधील sessionsमध्ये denominatorमध्ये सरासरी 2 names होते. Exchange-wide counts absolute termsमध्ये मोठे असतात. तरीही ते सर्व listingsच्या तुलनेत thin slice राहतात. म्हणून indexच्या शेजारी raw counts screenवर ठेवणे आवश्यक आहे.
या पानावरील प्रत्येक count हा closing pricesवर आधारित stored, versioned queryमधून आला आहे. कोणताही panel उघडून त्यामागील SQL वाचा. किंवा Strasmore terminalवर स्वतःच्या basketवर हीच breadth series पुन्हा तयार करा.