איך להוריד נתוני מכירות בחסר יומיים מ-FINRA
הורידו נתוני מכירות בחסר יומיים מ-FINRA באמצעות curl, קראו את עמודות קובץ Reg SHO וחשבו יחס מכירות בחסר לסימול עם awk. תאריך קבוע ותהליך ניתן לשחזור.
להורדת נתוני נפח המכירות בחסר היומיים של FINRA, יש להוריד קובץ טקסט פשוט אחד לכל יום מסחר משרת התוכן הציבורי של FINRA. אין צורך בהתחברות או במפתח API. זהו קובץ Regulation SHO Daily Short Sale Volume, ובו שורה אחת המופרדת באמצעות תווי pipe לכל סימול. כל שורה כוללת את נפח המכירות בחסר ואת הנפח הכולל באותו יום, וכן את תת-הקבוצה של מכירות בחסר הפטורות מדרישות הסימון, עבור עסקאות שדווחו מחוץ לבורסה למתקן של FINRA. המדריך מתמקד בתאריך היסטורי מסוים, 12 ביוני 2026, ומדגים את התהליך בסביבת Ubuntu חדשה: התקנת curl, הורדת הקובץ, קריאת העמודות ולאחר מכן חישוב יחס נפח המכירות בחסר עבור סימול אחד באמצעות awk. כל פקודה פועלת כפי שהיא כתובה, היום או בעוד שנה.
היכן FINRA מפרסמת את קובץ מחזור המכירות בחסר היומי?
הקובץ המאוחד של כל יום מסחר נמצא בכתובת צפויה:
https://cdn.finra.org/equity/regsho/daily/CNMSshvolYYYYMMDD.txt
החליפו את YYYYMMDD בתאריך המסחר. CNMS הוא קובץ ה-NMS המאוחד (National Market System, היקום של המניות הרשומות למסחר בבורסות): כל מניה רשומה, בסיכום של כל מתקני הדיווח על עסקאות (TRFs) של FINRA. FINRA מפרסמת את הקובץ של כל יום לכל המאוחר בשעה 18:00 לפי שעון החוף המזרחי (ET) ביום המסחר עצמו — בערך בקצב המהיר ביותר שבו מתקבלים נתונים ציבוריים על מכירות בחסר. המחיר לכך הוא היקף הכיסוי. הקובץ כולל רק עסקאות שדווחו למתקן של FINRA, כלומר בפועל עסקאות שבוצעו מחוץ לבורסות, כגון עסקאות של סיטונאים המבצעים פקודות של משקיעים קמעונאיים ועסקאות ב-dark pools. עסקאות שבוצעו בבורסות עצמן אינן נכללות בו. לכן עמודת המחזור הכולל תמיד קטנה ממחזור המסחר היומי המופיע בגרף המחירים.
הקבצים קיימים רק עבור ימי מסחר. אם מבקשים קובץ לתאריך של סוף שבוע או של חופשת מסחר בבורסה, השרת מחזיר 403 Forbidden במקום קובץ ריק. לכן סקריפט שעובר על לוח שנה צריך לדלג על תאריכים אלה או לדעת להתמודד עם השגיאה.
שלב 1: יצירת קונטיינר Ubuntu חדש והתקנת curl
התחילו מקונטיינר נקי והתקינו בו curl. תמונת הבסיס של Ubuntu כבר כוללת את awk, בגרסת mawk, ולכן אין צורך בשום רכיב נוסף:
docker run --rm -it ubuntu:24.04 bash
apt-get update && apt-get install -y curl
שלב 2: הורדת קובץ נפח השורט היומי של FINRA עבור תאריך קבוע
קבעו מראש את התאריך. פקודה המבוססת על "היום" נכשלת בסופי שבוע ובחגים, ושוב מדי בוקר לפני ש-FINRA מפרסמת את הקובץ. 12 ביוני 2026 היה יום שישי עם מסחר רגיל, והקובץ שלו עדיין שמור בשרת:
curl -fsSLO https://cdn.finra.org/equity/regsho/daily/CNMSshvol20260612.txt
הדגלים: -f גורם ל-curl להיכשל במקרה של שגיאת HTTP, במקום לשמור את דף השגיאה כנתונים; -s משתיק את מד ההתקדמות; -S עדיין מציג שגיאה אמיתית; -L עוקב אחר הפניה; ו--O שומר את הקובץ תחת שמו המרוחק. בדקו את שני הקצוות של הקובץ שהתקבל:
head -3 CNMSshvol20260612.txt
tail -1 CNMSshvol20260612.txt
השורה הראשונה היא כותרת העמודות, Date|Symbol|ShortVolume|ShortExemptVolume|TotalVolume|Market. השורה האחרונה היא שורת סיום: מספר שלם בלבד, המציין את מספר רשומות הנתונים בקובץ. כל מנתח נתונים חייב להסיר את שתי השורות. כעת הוכיחו את כלל סוף השבוע באמצעות בקשה ליום הקלנדרי הבא, שבת, 13 ביוני:
curl -fsSLO https://cdn.finra.org/equity/regsho/daily/CNMSshvol20260613.txt
Curl מדפיס שגיאה ומסתיים בקוד 22: השרת החזיר 403, ו--f סירב לו. אותו הדבר קורה ב-19 ביוני 2026, חג Juneteenth. עותק שמור של אותה סדרה מציג ישירות את מבנה לוח השנה, שורה אחת לכל יום מסחר וללא שורות בין לבין:
| תאריך מסחר | יום בשבוע | תווית מסחר | ניירות ערך שדווחו | תווית ניירות ערך |
|---|---|---|---|---|
| 2026-06-01 | Monday | June 1 | 15118 | 15.12 thousand |
| 2026-06-02 | Tuesday | June 2 | 14907 | 14.91 thousand |
| 2026-06-03 | Wednesday | June 3 | 14839 | 14.84 thousand |
| 2026-06-04 | Thursday | June 4 | 5136 | 5.14 thousand |
| 2026-06-05 | Friday | June 5 | 14740 | 14.74 thousand |
| 2026-06-08 | Monday | June 8 | 14815 | 14.81 thousand |
| 2026-06-09 | Tuesday | June 9 | 14751 | 14.75 thousand |
| 2026-06-10 | Wednesday | June 10 | 5694 | 5.69 thousand |
| 2026-06-11 | Thursday | June 11 | 14687 | 14.69 thousand |
| 2026-06-12 | Friday | June 12 | 14734 | 14.73 thousand |
| 2026-06-15 | Monday | June 15 | 14948 | 14.95 thousand |
| 2026-06-16 | Tuesday | June 16 | 5631 | 5.63 thousand |
| 2026-06-17 | Wednesday | June 17 | 14611 | 14.61 thousand |
| 2026-06-18 | Thursday | June 18 | 14700 | 14.70 thousand |
| 2026-06-22 | Monday | June 22 | 14922 | 14.92 thousand |
| 2026-06-23 | Tuesday | June 23 | 5767 | 5.77 thousand |
| 2026-06-24 | Wednesday | June 24 | 14743 | 14.74 thousand |
| 2026-06-25 | Thursday | June 25 | 14716 | 14.72 thousand |
| 2026-06-26 | Friday | June 26 | 15052 | 15.05 thousand |
| 2026-06-29 | Monday | June 29 | 5489 | 5.49 thousand |
ה-SQL המדויק מאחורי כל מספר
SELECT
toString(date) AS trade_date,
formatDateTime(date, '%W') AS weekday,
concat(monthName(date), ' ', toString(toDayOfMonth(date))) AS session_label,
count(DISTINCT ticker) AS symbols_reported,
formatReadableQuantity(count(DISTINCT ticker)) AS symbols_label
FROM global_markets.stocks_short_volume
WHERE date >= '2026-06-01'
AND date < '2026-07-01'
GROUP BY date
ORDER BY dateביוני 2026 נוצרו 21 קבצים מתוארכים. הראשון, June 1, שהיה Monday, כלל 15.12 thousand סימולים. כל שורה בלוח היא יום מסחר במהלך השבוע, ואין שורה עבור 19 ביוני.
מה משמעות העמודות בקובץ נפח המכירות בחסר של FINRA?
כל שורת נתונים כוללת שישה שדות המופרדים באמצעות קווים אנכיים.
Dateהוא תאריך המסחר בפורמט YYYYMMDD.Symbolהוא הטיקר, באורך של עד 14 תווים.ShortVolumeהוא מספר המניות שנמכרו בחסר באותו יום במסגרת עסקאות שדווחו ל-FINRA, כולל עסקאות short exempt.ShortExemptVolumeהוא תת-הקבוצה שסומנה כ-short exempt: מכירות שסומנו כפטורות ממבחן המחיר לפי כלל 201 של Reg SHO, מנגנון מפסק המגביל מכירות בחסר לאחר שמניה יורדת ב-10% ממחיר הסגירה הקודם.TotalVolumeהוא מספרן של כל המניות שדווחו עבור הסימול באותו יום, במכירות בחסר ובמכירות רגילות יחד.Marketהוא מתקן הדיווח:Nעבור NYSE TRF,Qעבור Nasdaq TRF בקרטרט,Bעבור Nasdaq TRF בשיקגו, ו-Dעבור Alternative Display Facility (ADF).
בקובץ המאוחד, השדה Market מציג את כל מתקני הדיווח שדיווחו על הסימול, כשהם מופרדים בפסיקים. לכן שורה מסתיימת במחרוזת כגון B,Q,N. הפסיקים האלה הם הסיבה לכך שהקובץ משתמש בקווים אנכיים כמפרידים. יש שינוי עדכני שכדאי להביא בחשבון: מאז 23 בפברואר 2026, שלושת שדות הנפח כוללים מניות חלקיות בדיוק של שש ספרות אחרי הנקודה, ולכן ערך עם שש ספרות אחרי הנקודה הוא תקין. קבצים שתאריכם מוקדם יותר כוללים מספרים שלמים בלבד, ומנתח נתונים שממיר את הערך למספר שלם יקצץ בשקט את הערכים בקבצים החדשים.
כיצד מחשבים את יחס המחזור בחסר באמצעות awk?
יחס המחזור בחסר הוא המחזור בחסר חלקי המחזור הכולל, ומוצג באחוזים. שורת awk אחת מחשבת אותו עבור סימול יחיד:
awk -F'|' '$2 == "AAPL" { printf "%s %s short=%s total=%s ratio=%.1f\n", $1, $2, $3, $5, 100 * $3 / $5 }' CNMSshvol20260612.txt
-F'|' מגדיר את קו ההפרדה כמפריד השדות, $2 == "AAPL" משאיר רק את שורת AAPL (הכותרת ושורת הסיום לעולם אינן תואמות), ופקודת printf מחלקת את שדה 3 בשדה 5. החליפו את הסימול בכל סימול אחר. הלוח שלהלן קורא את אותו תאריך עבור שש מניות מוכרות מסדרת FINRA השמורה, כשהנתונים מעוגלים למיליוני מניות, כך שתוכלו להשוות את השורה שזה עתה הרצתם מולו:
| ticker | מחזור מכירות בחסר במיליונים | מחזור כולל במיליונים | אחוז מכירות בחסר |
|---|---|---|---|
| AAPL | 6.66 | 13.16 | 50.6 |
| AMZN | 5.88 | 21.76 | 27 |
| KO | 2.06 | 3.65 | 56.3 |
| MSFT | 3.73 | 14.24 | 26.2 |
| NVDA | 15.19 | 45.34 | 33.5 |
| SPY | 7.48 | 15.48 | 48.3 |
ה-SQL המדויק מאחורי כל מספר
SELECT
ticker,
round(toFloat64(max(short_volume)) / 1e6, 2) AS short_volume_millions,
round(toFloat64(max(total_volume)) / 1e6, 2) AS total_volume_millions,
round(100 * toFloat64(max(short_volume)) / toFloat64(max(total_volume)), 1) AS short_pct
FROM global_markets.stocks_short_volume
WHERE ticker IN ('AAPL', 'AMZN', 'KO', 'MSFT', 'NVDA', 'SPY')
AND date = '2026-06-12'
GROUP BY ticker
HAVING max(total_volume) > 0
ORDER BY tickerעבור AAPL ב-12 ביוני 2026, הקובץ מתעד 6.66 מיליון מניות שנמכרו בחסר, לעומת 13.16 מיליון מניות שדווחו במחזור הכולל; יחס המחזור בחסר הוא 50.6%. חמשת הסימולים האחרים נמצאים באותו תחום, וזהו המצב הרגיל בקובץ הזה. בחלק מאוחר יותר מוסבר מדוע יחס הקרוב למחצית אינו סימן אזהרה כפי שהוא עשוי להיראות.
יום יחיד הוא תמונת מצב, והיחס משתנה מיום מסחר אחד למשנהו. הורידו קובץ אחד לכל תאריך, ותוכלו לבנות סדרה חודשית.
מה ההבדל בין קובץ CNMS לבין הקבצים לפי מתקן דיווח?
CNMS הוא נתון מצרפי. FINRA מפרסמת גם קובץ נפרד לכל מתקן דיווח באותו לוח זמנים, באותו מבנה ובחותמת תאריך זהה, אך עם קידומת שונה: FNSQshvol עבור Nasdaq TRF Carteret (שוק Q), FNQCshvol עבור Nasdaq TRF Chicago (B), FNYXshvol עבור NYSE TRF (N) ו־FNRAshvol עבור ADF (D). קובץ חמישי, FORFshvol, מכסה את OTC Reporting Facility, המטפל במניות OTC שאינן רשומות ואינו נכלל ב־CNMS. הורידו את קובץ Carteret עבור התאריך שנקבע מראש ושלפו את אותו סימול:
curl -fsSLO https://cdn.finra.org/equity/regsho/daily/FNSQshvol20260612.txt
awk -F'|' '$2 == "AAPL"' FNSQshvol20260612.txt
הריצו את אותן שתי שורות מול FNQCshvol20260612.txt ו־FNYXshvol20260612.txt, ושלושת השדות ShortVolume מסתכמים בדיוק, עד לספרה העשרונית האחרונה, לנתון של CNMS. קובץ ADF לאותו תאריך כולל רק כותרת ורשומת סיום עם הערך 0, וזה מצב נפוץ. כך נראה הפיצול עבור AAPL:
| זירת מסחר | מחזור מכירות בחסר במיליונים | אחוז מהמחזור המאוחד |
|---|---|---|
| Consolidated (CNMS) | 6.659 | 100 |
| Nasdaq TRF Carteret (Q) | 6.412 | 96.3 |
| NYSE TRF (N) | 0.194 | 2.9 |
| Nasdaq TRF Chicago (B) | 0.053 | 0.8 |
| ADF (D) | 0 | 0 |
ה-SQL המדויק מאחורי כל מספר
SELECT
tupleElement(v, 1) AS venue,
round(tupleElement(v, 2) / 1e6, 3) AS short_volume_millions,
round(100 * tupleElement(v, 2) / consolidated, 1) AS share_of_consolidated_pct
FROM
(
SELECT
consolidated,
arrayJoin([
('Consolidated (CNMS)', consolidated),
('Nasdaq TRF Carteret (Q)', carteret),
('Nasdaq TRF Chicago (B)', chicago),
('NYSE TRF (N)', nyse),
('ADF (D)', adf)
]) AS v
FROM
(
SELECT
toFloat64(ifNull(max(short_volume), 0)) AS consolidated,
toFloat64(ifNull(max(nasdaq_carteret_short_volume), 0)) AS carteret,
toFloat64(ifNull(max(nasdaq_chicago_short_volume), 0)) AS chicago,
toFloat64(ifNull(max(nyse_short_volume), 0)) AS nyse,
toFloat64(ifNull(max(adf_short_volume), 0)) AS adf
FROM global_markets.stocks_short_volume
WHERE ticker = 'AAPL'
AND date = '2026-06-12'
)
)
ORDER BY tupleElement(v, 2) DESCNasdaq TRF Carteret (Q) היוו 96.3% מנפח המכירות בחסר של AAPL מחוץ לבורסה באותו יום. Nasdaq TRF Carteret מטפל ברוב דיווחי העסקאות מחוץ לבורסה בשוק, והפיצול הזה ממחיש זאת. הקבצים לפי מתקן דיווח חשובים כאשר רוצים לדעת דרך איזה זירת מסחר בוצעה עסקה; לכל יתר השימושים יש להשתמש בקובץ המאוחד.
מדוע נפח מכירות בחסר של FINRA אינו שווה לפוזיציות בחסר?
נפח מכירות בחסר הוא תזרים: מספר המניות שנמכרו בחסר במהלך יום מסחר אחד, בעסקאות מחוץ לבורסה בלבד. פוזיציות בחסר הן נתון מצטבר: מספר המניות שעדיין מוחזקות בחסר במועד הסליקה. FINRA אוספת את הנתון פעמיים בחודש ומפרסמת אותו כעבור כשבועיים. שני הנתונים אינם מתיישבים זה עם זה, ויחס גבוה של נפח מכירות בחסר אינו מעיד על פוזיציית חסר גדולה. עושה שוק שמבצע פקודת קנייה של לקוח באמצעות מלאי שאינו מוחזק אצלו מוכר בחסר, ולכן נרשמת מכירת בחסר. אם הוא מכסה את הפוזיציה כעבור שעה, הקובץ מציג את המכירה בחסר בלי תיעוד של הקנייה. בימים רגילים, היחס במניות סחירות קרוב למחצית, כפי שמראה פאנל שש המניות לעיל, ומנגנון עשיית השוק הזה הוא ההסבר המקובל. פוזיציות בחסר לעומת נפח מכירות בחסר מסביר את המושג, ו-מהן פוזיציות בחסר עוסק בצד של הפוזיציה; הפוסט הזה מתמקד בהשגת הקובץ. עבור סדרת הפוזיציות עצמה, התחילו ב-נתוני הפוזיציות בחסר של FINRA, ולאחר מכן עיינו ב-מתי מתפרסם נתון הפוזיציות בחסר וב-מדוע נתון הפוזיציות בחסר מפגר בשבועיים כדי להבין את פער הפרסום.
מוזרויות מוכרות בקובץ מחזור המכירות בחסר של FINRA
כמה מאפיינים עלולים להפתיע משתמשים חדשים. בורסות מעבירות סמלי בדיקה דרך מערכות הייצור שלהן. משפחת הסמלים ZVZZT של Nasdaq היא הדוגמה המוכרת ביותר. שורות עבור סמלים אלה עשויות להופיע בקבצים עם מחזור שנראה אמיתי. לפני יצירת תרשימים, יש להסיר כל סמל שאי־אפשר להתאים לנייר ערך רשום.
במקרים נדירים FINRA מפרסמת מחדש את הקובץ של יום מסוים עם נתונים מתוקנים. בעמוד הקטלוג שלה הקובץ מסומן "Updated". לכן מספר שנשלף בערב יום המסחר עשוי להיות שונה מאותו קובץ שנשלף שבוע לאחר מכן. יש להוריד את הקובץ מחדש לפני שמצטטים אותו.
שורת הסיום כוללת ספירה בלבד, ללא תווי הפרדה. מנתח פשוט שמניח שבכל שורה יש שישה שדות ייכשל בעת עיבודה.
המחזורים מוצגים כשברים החל מ־23 בפברואר 2026, ולפני מועד זה הם מוצגים כמספרים שלמים. נספרות רק עסקאות בשעות המסחר הרגילות, ורק עסקאות שדווחו מחוץ לבורסה למתקן של FINRA. לכן עמודת המחזור הכולל לעולם אינה תואמת לסרט הקונסולידציה.
אלה מאפיינים של הקובץ, ולא פגמים בו. מנתח שמכיר אותם מפיק נתונים נקיים.
שאלות נפוצות
היכן ניתן להוריד בחינם נתוני נפח מכירות החסר היומיים של FINRA?
משרת התוכן הציבורי של FINRA בכתובת cdn.finra.org/equity/regsho/daily/. קיים קובץ אחד לכל יום מסחר, בשם CNMSshvolYYYYMMDD.txt, עבור הקובץ המאוחד של NMS. אין צורך בחשבון; די בפקודת curl יחידה כדי להוריד אותו. באתר FINRA יש גם תצוגה אינטראקטיבית עם אפשרות לייצא CSV עבור עד שבעה ימים בכל פעם.
מדוע אין קובץ נפח מכירות חסר של FINRA עבור סוף שבוע או חג?
הקבצים מופקים רק עבור תאריכי מסחר. בקשה עבור תאריך של סוף שבוע או חג בורסה מחזירה HTTP 403, ולא קובץ ריק. לכן סקריפט שעובר על לוח השנה צריך לדלג על ימים שאינם ימי מסחר או להתמודד עם השגיאה.
האם נפח המכירות בחסר היומי של FINRA זהה ל-short interest?
לא. נפח מכירות בחסר סופר את המניות שנמכרו בחסר במהלך יום אחד בעסקאות מחוץ לבורסה, לרבות מכירות בחסר של עושי שוק שכוסו בתוך דקות. short interest סופר את המניות שעדיין מוחזקות בפוזיציית חסר במועד הסליקה, והנתון נאסף פעמיים בחודש. יחס נפח מכירות בחסר הקרוב ל-50% הוא נתון שגרתי במניה סחירה, ואינו מלמד דבר על היקפה של פוזיציית חסר פתוחה.
מדוע קובץ נפח המכירות בחסר של FINRA מכיל מספרים עשרוניים?
מאז 23 בפברואר 2026, FINRA מדווחת על כמויות של מניות חלקיות במניות NMS, עד שש ספרות אחרי הנקודה, בכל שלושת שדות הנפח. קבצים שנוצרו לפני מועד זה מכילים מניות שלמות בלבד. לכן מנתח שממיר את הנתונים למספרים שלמים יקצץ את הערכים בקבצים החדשים.
מה משמעות העמודה Market בקובץ נפח המכירות בחסר של FINRA?
העמודה מזהה את המתקן של FINRA שקיבל את דיווח העסקה: N עבור NYSE TRF, Q עבור Nasdaq TRF בקרטרט, B עבור Nasdaq TRF בשיקגו ו-D עבור ADF. הקובץ המאוחד CNMS מציג, כשהוא מופרדים בפסיקים, את כל המתקנים שדיווחו על הסימול.
כל אחד מהלוחות שלעיל כולל את שאילתת ה-SQL שלו מתחתיו. פתחו לוח כלשהו כדי לראות כיצד חושב הנתון. כדי להפיק את היסטוריית נפח המכירות בחסר של סימול בלי להוריד קובץ, בקשו זאת באנגלית פשוטה במסוף Strasmore.