تفاوت مهرهای زمانی SIP و ساعتهای صرافی در دادههای بازار
مهرهای زمانی دادههای بازار از چهار منبع مختلف میآیند. بررسی کنید که چگونه مرتبسازی معاملات بر اساس هر ساعت، خروجی نوار را تغییر داده و کدام ساعت برای چه کاربردی مناسب است.
مهر زمانی دادههای بازار، ساعتهایی هستند که روی هر «پرینت» (ثبت معامله) درج میشوند؛ این مهرها نشان میدهند که معامله از لحظه اجرا در موتور تطبیق تا لحظه نمایش روی صفحه، چه مسیری را طی کرده است. در سوابق عمومی معاملات سهام در ایالات متحده، هر معامله با سه مهر زمانی مختلف ثبت میشود که هر کدام به پرسش متفاوتی پاسخ میدهند. اگر پرینتهای یک روز معاملاتی را بر اساس یک ساعت مرتب کنید و سپس با ساعتی دیگر، با دو نوار (Tape) کاملاً متفاوت مواجه خواهید شد.
چهار ساعتی که یک پرینت از آنها عبور میکند
یک پرینت در مسیر رسیدن به شما، بهطور مکرر مهر میخورد. به ترتیب:
- زمان موتور تطبیق (Matching engine time): لحظهای که موتور تطبیق یک بازار، دو سفارش را با هم جفت میکند. هیچکس خارج از آن بازار به این مقدار دسترسی مستقیم ندارد. این زمان، حقیقت محضِ وقوع معامله است و تمام ساعتهای بعدی، تقریبی از آن هستند.
- زمان شرکتکننده (Participant time) که زمان بازار یا صرافی نیز نامیده میشود: مهری که بازار هنگام انتشار پرینت روی فید اختصاصی خود درج میکند و در فیلد
participant_timestampحمل میشود. از میان تمام دادههایی که قابل خواندن هستند، این زمان به موتور تطبیق نزدیکتر است. - زمان SIP: مهری که پردازشگر اطلاعات اوراق بهادار (Securities Information Processor) هنگام رسیدن پرینت به «نوار تجمیعی» (Consolidated Tape) درج میکند؛ این نوار، فید رسمی واحدی است که تمام بازارهای سهام ایالات متحده را ادغام میکند. این زمان در فیلد
sip_timestampقرار دارد و توالی رسمی نوار بر اساس آن تعیین میشود. تفاوت میان این فید و فید مستقیم صرافیها در SIP در برابر فیدهای مستقیم صرافی بررسی شده است. - زمان ثبت (Capture time): مهری که کارت شبکه شما هنگام دریافت بسته داده درج میکند. این زمان هرگز در سوابق فروشندگان ظاهر نمیشود، زیرا مسیر شما را توصیف میکند، نه بازار را. کارهای مربوط به ضبط و بازپخش بسته داده کاملاً بر اساس این ساعت انجام میشود.
پرینتهای خارج از صرافی (Off-exchange) دارای مهر پنجم، یعنی trf_timestamp هستند که نشان میدهد یک تسهیلات گزارشدهی معاملات (TRF)، گزارش را در چه زمانی دریافت کرده است.
چرا مهرهای زمانی دادههای بازار در بازارهای مختلف متفاوت است
شکاف بین مهر زمانی یک بازار و مهر زمانی تجمیعی، مدت زمانی است که پرینت در مسیر انتقال و در صف پردازشگر سپری کرده است. این یک عدد ثابت نیست. هر بازار فاصله متفاوتی تا پردازشگر دارد، از سختافزارهای متفاوتی استفاده میکند و پشت صفهای متفاوتی قرار دارد. جدول زیر این شکاف را برای تمام بازارهایی که در یک بازه زمانی ثابت 30 دقیقهای در 10 ژوئن 2026، نماد AAPL را پرینت کردهاند، اندازهگیری میکند.
کد دقیق SQL پشت هر عدد
WITH venues AS
(
SELECT
toUInt32(id) AS exchange_id,
any(coalesce(nullIf(acronym, ''), name)) AS venue_name
FROM global_markets.stocks_exchanges
WHERE asset_class = 'stocks'
GROUP BY exchange_id
)
SELECT
if(v.venue_name = '', concat('Venue ', toString(t.exchange)), v.venue_name) AS venue,
count() AS print_count,
round(quantileDeterministic(0.5)(
toFloat64(toUnixTimestamp64Nano(t.sip_timestamp)
- toUnixTimestamp64Nano(t.participant_timestamp)) / 1000,
toUInt64(t.sequence_number)), 1) AS median_lag_us,
round(quantileDeterministic(0.99)(
toFloat64(toUnixTimestamp64Nano(t.sip_timestamp)
- toUnixTimestamp64Nano(t.participant_timestamp)) / 1000,
toUInt64(t.sequence_number)), 1) AS p99_lag_us
FROM global_markets.stocks_trades AS t
LEFT JOIN venues AS v ON v.exchange_id = toUInt32(t.exchange)
WHERE t.ticker = 'AAPL'
AND t.sip_timestamp >= '2026-06-10 14:30:00'
AND t.sip_timestamp < '2026-06-10 15:00:00'
AND ifNull(toUnixTimestamp64Nano(t.trf_timestamp), 0) = 0
GROUP BY venue
HAVING count() >= 200
ORDER BY median_lag_us DESC
LIMIT 15در میان آن بازارها، بیشترین شکاف میانه بین مهر زمانی بازار و مهر زمانی تجمیعی، 346.2 میکروثانیه در NYSE Arca, Inc. بوده است. دقیقترین بازار در همان بازه، 13.7 میکروثانیه اختلاف داشته است. ستون p99 همان ستونی است که باید به آن دقت کرد: برای همان کندترین بازار، این مقدار به 420.8 میکروثانیه رسید؛ دمِ توزیعی که میانه آن را پنهان میکند.
از کدام مهر زمانی باید استفاده کنید
چهار قاعده تقریباً تمام موارد را پوشش میدهند.
- زمان شرکتکننده برای تحلیلهای ریزساختار و مطالعات رویداد: هر چیزی که اندازهگیری میکند در یک بازار چه اتفاقی افتاده و به چه ترتیبی بوده، باید بر اساس ساعت همان بازار باشد. بازسازی دفتر سفارشات که موضوع دادههای دفتر سفارشات MBO در برابر MBP است، با هیچ ساعت دیگری قابل انجام نیست.
- زمان SIP برای هر چیزی که باید با نوار رسمی مطابقت داشته باشد: گزارشهای نظارتی، بررسی اجرای بهینه (Best Execution)، قیمتهای رسمی بازگشایی و بستهشدن، و هر رقمی که طرف مقابل معامله با سوابق تجمیعی چک میکند.
- زمان ثبت فقط برای اندازهگیری مسیر خودتان: این زمان به شما میگوید دادهها چقدر طول کشیده تا به دستگاه شما برسند. این زمان هیچ اطلاعاتی درباره لحظه وقوع معامله نمیدهد و دو دستگاه هرگز در مورد آن توافق ندارند.
- هرگز ساعتها را در یک مجموعه داده ترکیب نکنید: یک اتصال (Join) که مظنهها را با یک ساعت و معاملات را با ساعت دیگر تطبیق میدهد، اعدادی را برمیگرداند که در ظاهر معقول به نظر میرسند اما دقیقاً در لحظاتی که اهمیت دارند، شکست میخورند.
همان پرینتها، مرتبشده به دو روش
مرتبسازی جایی است که انتزاع فرو میپاشد. جدول زیر شلوغترین ده میلیثانیه از آن نیمساعت را در نظر میگیرد، دوازده پرینت اول صرافی را به ترتیب ساعت بازار نگه میدارد و سپس همان دوازده مورد را بر اساس ترتیب نوار تجمیعی رتبهبندی میکند. جدول بر اساس میزان جابهجایی هر پرینت بین دو رتبهبندی مرتب شده است.
کد دقیق SQL پشت هر عدد
WITH
burst AS
(
SELECT intDiv(toUnixTimestamp64Nano(participant_timestamp), 10000000) AS slice_10ms
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-06-10 14:30:00'
AND sip_timestamp < '2026-06-10 15:00:00'
AND ifNull(toUnixTimestamp64Nano(trf_timestamp), 0) = 0
GROUP BY slice_10ms
ORDER BY count() DESC, slice_10ms ASC
LIMIT 1
),
sample AS
(
SELECT
participant_timestamp,
sip_timestamp,
toUInt64(sequence_number) AS seq,
toUnixTimestamp64Nano(sip_timestamp)
- toUnixTimestamp64Nano(participant_timestamp) AS lag_ns
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-06-10 14:30:00'
AND sip_timestamp < '2026-06-10 15:00:00'
AND ifNull(toUnixTimestamp64Nano(trf_timestamp), 0) = 0
AND intDiv(toUnixTimestamp64Nano(participant_timestamp), 10000000)
IN (SELECT slice_10ms FROM burst)
ORDER BY participant_timestamp ASC, seq ASC
LIMIT 12
),
ranked AS
(
SELECT
participant_timestamp,
sip_timestamp,
lag_ns,
row_number() OVER (ORDER BY participant_timestamp ASC, seq ASC) AS participant_rank,
row_number() OVER (ORDER BY sip_timestamp ASC, seq ASC) AS sip_rank
FROM sample
)
SELECT
concat('P', leftPad(toString(participant_rank), 2, '0')) AS print_label,
concat(formatDateTime(toTimeZone(participant_timestamp, 'America/New_York'), '%H:%i:%S'), '.',
leftPad(toString(intDiv(toUnixTimestamp64Nano(participant_timestamp) % 1000000000, 1000)), 6, '0')) AS venue_clock_et,
concat(formatDateTime(toTimeZone(sip_timestamp, 'America/New_York'), '%H:%i:%S'), '.',
leftPad(toString(intDiv(toUnixTimestamp64Nano(sip_timestamp) % 1000000000, 1000)), 6, '0')) AS tape_clock_et,
participant_rank,
sip_rank,
abs(toInt32(sip_rank) - toInt32(participant_rank)) AS places_moved,
round(lag_ns / 1000, 1) AS sip_lag_delta_us
FROM ranked
ORDER BY places_moved DESC, participant_rank ASCبزرگترین شکاف بین دو رتبه یک پرینت، 6 است. آن پرینت در ساعت 10:44:17.160712 بازار خود را ترک کرده و 305.7 میکروثانیه بعد، در ساعت 10:44:17.161018 به نوار رسیده است و از جایگاه 6 در ساعت بازار به جایگاه 12 در نوار منتقل شده است. هیچکدام از این ترتیببندیها غلط نیستند. آنها به پرسشهای متفاوتی پاسخ میدهند. مطالعه توالی معاملات که بر اساس ساعت نوار اجرا شود، این جهش را به ترتیبی میخواند که هیچ بازاری هرگز تولید نکرده است، و بررسی اجرای بهینه که بر اساس ساعت بازار اجرا شود، با سوابق رسمی اختلاف خواهد داشت.
پرینتهای خارج از صرافی با تأخیر زیاد ثبت میشوند
معاملهای که خارج از صرافی، نزد یک عمدهفروش یا در یک دارکپول (Dark Pool) اجرا میشود، به جای تطبیق در دفتر سفارشات عمومی، به یک تسهیلات گزارشدهی معاملات گزارش میشود. گزارش شامل زمان اجرا است و پس از آن به نوار میرسد. این فاصله، یک تأخیر گزارشدهی است تا زمان انتقال، و چندین مرتبه بزرگتر است.
کد دقیق SQL پشت هر عدد
WITH off_exchange AS
(
SELECT
(toUnixTimestamp64Nano(sip_timestamp)
- toUnixTimestamp64Nano(participant_timestamp)) / 1000000.0 AS delay_ms
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-06-10 14:30:00'
AND sip_timestamp < '2026-06-10 15:00:00'
AND ifNull(toUnixTimestamp64Nano(trf_timestamp), 0) > 0
)
SELECT
multiIf(delay_ms < 1, 'under 1 ms',
delay_ms < 10, '1 to 10 ms',
delay_ms < 100, '10 to 100 ms',
delay_ms < 1000, '100 ms to 1 s',
delay_ms < 10000, '1 s to 10 s',
'over 10 s') AS reporting_delay,
count() AS print_count,
round(100 * count() / (SELECT count() FROM off_exchange), 2) AS share_pct
FROM off_exchange
GROUP BY reporting_delay
ORDER BY min(delay_ms) ASCاز پرینتهای خارج از صرافی AAPL در آن بازه، 24.8% در بازه under 1 ms قرار میگیرند. دم توزیع تا بازه 1 s to 10 s ادامه مییابد که شامل 74 پرینت است. پرینتی که ده ثانیه دیرتر میرسد، همچنان زمان ساعت بازارِ لحظه اجرای واقعی را حمل میکند، در حالی که در جریان نوار، ده ثانیه پایینتر از آن قرار میگیرد. اگر بر اساس زمان نوار مرتب کنید، در دقیقه اشتباهی ظاهر میشود. پرینتهایی که خارج از توالی عادی گزارش میشوند، دارای کدهای وضعیت فروش هستند که این موضوع را اعلام میکنند؛ این یکی از مواردی است که کدهای وضعیت معامله برای علامتگذاری آن وجود دارند.
چرا دو نفر از معاملات یکسان، نمودارهای متفاوتی میسازند
تقریباً تمام تیکتهای «دادهها غلط است» به اینجا ختم میشوند. یک میله (Bar) مجموعهای از پرینتهاست و اینکه یک پرینت در کدام میله قرار میگیرد، به این بستگی دارد که بر اساس کدام مهر زمانی دستهبندی کنید. جدول زیر تعداد پرینتهایی را میشمارد که هنگام تغییر از ساعت بازار به ساعت نوار، تغییر میله میدهند؛ این کار در چهار طول میله رایج انجام شده است.
کد دقیق SQL پشت هر عدد
WITH
prints AS
(
SELECT
toUnixTimestamp64Nano(participant_timestamp) AS venue_ns,
toUnixTimestamp64Nano(sip_timestamp) AS tape_ns
FROM global_markets.stocks_trades
WHERE ticker = 'AAPL'
AND sip_timestamp >= '2026-06-10 14:30:00'
AND sip_timestamp < '2026-06-10 15:00:00'
),
grids AS
(
SELECT arrayJoin([1, 10, 60, 300]) AS bar_seconds
)
SELECT
multiIf(bar_seconds = 1, '1 second',
bar_seconds = 10, '10 seconds',
bar_seconds = 60, '1 minute',
'5 minutes') AS bar_length,
countIf(intDiv(venue_ns, toInt64(bar_seconds) * 1000000000)
!= intDiv(tape_ns, toInt64(bar_seconds) * 1000000000)) AS moved_print_count,
round(100 * countIf(intDiv(venue_ns, toInt64(bar_seconds) * 1000000000)
!= intDiv(tape_ns, toInt64(bar_seconds) * 1000000000)) / count(), 3) AS moved_pct
FROM prints
CROSS JOIN grids
GROUP BY bar_seconds
ORDER BY bar_seconds ASCدر یک شبکه 1 second، 8.966% از پرینتهای آن بازه در دو ساعت مختلف در میلههای متفاوتی قرار میگیرند که در مجموع 8944 پرینت است. اگر میله را به 5 minutes افزایش دهید، این رقم به 0.024% کاهش مییابد. الگو مکانیکی است: یک پرینت هر زمان که شکاف ساعتیاش از یک مرز عبور کند، تغییر میله میدهد و میلههای کوتاهتر مرزهای بیشتری دارند. دو فروشنده میتوانند هر دو درست بگویند و همچنان حجم متفاوتی برای همان دقیقه منتشر کنند. ساختار این کار در چگونگی ساخت میلههای OHLCV توضیح داده شده است.
فیلد نانوثانیه به معنای دقت نانوثانیهای نیست
هر دو مهر زمانی به صورت اعداد صحیح با رزولوشن نانوثانیه میرسند. رزولوشن چیزی است که یک فیلد میتواند بیان کند. دقت، میزان نزدیکی مقدار به زمان واقعی است و این دو توسط عوامل کاملاً متفاوتی تعیین میشوند.
همترازی ساعتها در صنعت، به جای فیزیک، توسط تلورانسهای نظارتی کنترل میشود. قانون همگامسازی ساعت FINRA، ساعتهای تجاری شرکتهای عضو را ملزم میکند که حداکثر 50 میلیثانیه با مرجع NIST اختلاف داشته باشند. صرافیها و پردازشگرها با دقت بسیار بیشتری کار میکنند و از پروتکل زمان دقیق (PTP، استاندارد شده به عنوان IEEE 1588) استفاده میکنند که یک ساعت مرجع را روی همان شبکهای که دادهها را حمل میکند توزیع کرده و دستگاهها را در همترازی زیر میکروثانیه نگه میدارد.
دو نتیجه حاصل میشود. در مهرهای زمانی یک سازمان، ترتیببندی با رزولوشن میکروثانیه معنادار است. در میان سازمانها، اختلاف چند صد نانوثانیهای بین دو مهر زمانی در محدوده خطای مجاز قرار دارد و برخورد با آن به عنوان یک ترتیببندی واقعی، خواندن نویز است.
پرسشهای متداول
تفاوت بین مهر زمانی SIP و مهر زمانی شرکتکننده چیست؟
مهر زمانی شرکتکننده توسط بازار در لحظه انتشار معامله روی فید اختصاصیاش درج میشود. مهر زمانی SIP توسط پردازشگر نوار تجمیعی در لحظه رسیدن آن معامله به فید رسمی ترکیبی درج میشود. شکاف بین آنها، زمان انتقال و صفبندی است که برای پرینتهای داخل صرافی با میکروثانیه و برای پرینتهای گزارششده از طریق تسهیلات گزارشدهی معاملات، اغلب با میلیثانیه یا بیشتر اندازهگیری میشود.
برای بکتست (Backtesting) از کدام مهر زمانی دادههای بازار استفاده کنم؟
برای هر چیزی که مدلسازی میکند یک شرکتکننده در یک بازار چه چیزی را دیده یا انجام داده، از مهر زمانی شرکتکننده استفاده کنید و برای هر چیزی که باید با سوابق رسمی تجمیعی مطابقت داشته باشد، از مهر زمانی SIP استفاده کنید. هر کدام را که انتخاب کردید، آن را برای تمام جداول مطالعه، از جمله مظنهها، اعمال کنید.
چرا میلههای یکدقیقهای من با دادههای ارائهدهنده من مطابقت ندارد؟
عدم تطابق ساعت معمولاً پاسخ این پرسش است. پرینتی که مهر زمانی بازارش درست قبل از مرز دقیقه قرار دارد، میتواند مهر زمانی نوارش درست بعد از آن باشد که باعث میشود همان معامله در دو میله مختلف تحت دو قرارداد قرار گیرد. پرینتهای خارج از صرافی که با تأخیر گزارش میشوند، این اثر را تشدید میکنند.
آیا مهرهای زمانی نانوثانیهای با دقت نانوثانیه هستند؟
خیر. فیلد دارای رزولوشن نانوثانیه است و دقت آن توسط میزان همگامسازی ساعت دستگاه نویسنده تعیین میشود. سیستمهای صرافی و پردازشگر که از PTP استفاده میکنند، همترازی زیر میکروثانیه دارند، در حالی که ساعتهای تجاری کارگزاران با تلورانس نظارتی 50 میلیثانیه نگهداری میشوند. مقایسههای دقیقتر از تلورانس ساعت ضعیفتر، معنادار نیستند.
هر پنل در بالا به همراه کد SQL تولیدکننده آن ارائه شده است تا بتوانید دقیقاً ببینید هر عدد از کدام ساعت آمده است. برای مرتبسازی مجدد بازه پرینتهای خود با ساعتی دیگر و مشاهده تغییرات نوار، پرسش خود را به زبان ساده در ترمینال Strasmore مطرح کنید.