Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

راهنمای جامع و ترجمه سیستم‌های معاملات فرکانس بالا (HFT)

درباره این Vault

این والت اختصاصی شامل ترجمه دقیق، ساختاریافته و آموزشی کتاب مرجع: Developing High-Frequency Trading Systems (نوشته‌ی Sebastien Donadio, Sourav Ghosh, John Rizzo, Romain Rossier) می‌باشد. مفاهیم به زبان فارسی تخصصی بازنویسی شده، فرمول‌های ریاضی (LaTeX), کدهای الگوریتمی، دیاگرام‌ها و نکات بازار حفظ و تفهیم شده‌اند.


فهرست سرفصل‌ها و فصول

فصلعنوان فصلموضوع محوریپیوند نوت
۰۰واژه‌نامه تخصصیتعاریف لغات تخصصی کوانت و HFTواژه‌نامه تخصصی (Glossary)
۰۱مبانی سیستم‌های HFTتاریخچه، بازارسازی، آربیتراژ آماری، اسپرد01 - مبانی سیستم‌های معاملات فرکانس بالا
۰۲اجزای حیاتی سیستم معاملاتیمعماری سیستم، Gateway، مدیریت Order Book02 - اجزای حیاتی سیستم معاملاتی
۰۳پویایی صرافی و هسته تطبیقعملکرد بورس‌ها، Matching Engine، سناریوهای سفارش03 - پویایی صرافی و هسته تطبیق
۰۴زیرساخت سخت‌افزار و OSمعماری CPU، حافظه اشتراکی، فضای کرنل و کاربر04 - زیرساخت سخت‌افزار و OS
۰۵شبکه در حرکتسوئیچ‌ها، پروتکل FIX، چرخه عمر بسته داده (Packet Life)05 - شبکه در حرکت و پروتکل‌های تبادل
۰۶بهینه‌سازی OS و Lock-Freeحذف Context Switch، همگام‌سازی بدون قفل، Pre-fetching06 - بهینه‌سازی OS و ساختارهای داده Lock-Free
۰۷شتاب‌دهی کرنل و شبکهKernel Bypass، فایل‌های mmap، مایکروویو و فیبر توخالی07 - شتاب‌دهی کرنل، فیبر نوری و لاگینگ
۰۸کدنویسی ++C در مقیاس میکروثانیهMemory Model، حذف تصمیمات زمان اجرا، Constexpr و Template08 - پیاده‌سازی سی‌پلاس‌پلاس و تاخیر میکروثانیه
۰۹جاوا و JVM با کمترین تاخیرمدیریت GC، گرم کردن JVM، صف بدون قفل Disruptor09 - جاوا و معماری Low-Latency با JVM
۱۰پایتون برای پردازش با سرعت بالاCFFI ،Ctypes ،Cython و اتصال پایتون به ++C10 - پایتون در تحلیل و ترکیب با سی‌پلاس‌پلاس
۱۱سخت‌افزار FPGA و کریپتوکارنسیبرنامه‌ریزی مدار FPGA، تاخیر نانوثانیه، بازارهای کریپتو11 - سخت‌افزارهای FPGA و سیستم‌های کریپتو

مبانی سیستم‌های معاملات فرکانس بالا (HFT)

(Fundamentals of a High-Frequency Trading System)

اطلاعات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۱۹ تا ۳۶


مقدمه

در سال ۲۰۱۴، مایکل لوئیس (Michael Lewis) کتابی با عنوان Flash Boys: A Wall Street Revolt منتشر کرد. این کتاب به مدت سه هفته در صدر فهرست پرفروش‌ترین‌های نیویورک تایمز قرار داشت و به بررسی صنعت معاملات فرکانس بالا (HFT) و تأثیر شگرف آن بر دنیای مبادلات مالی می‌پرداخت. دانشگاهیان، فعالان بازارهای مالی و حتی افراد خارج از حوزه مالی، همگی مجذوب این شیوه نوین معاملات شدند. همزمان، این عصر نوین معاملاتی ترس و ابهام زیادی نیز برانگیخت؛ چرا که کنترل بازارها بیش از پیش به ماشین‌ها و الگوریتم‌های رایانه‌ای واگذار می‌شد.

هدف این کتاب، بررسی ماهیت واقعی HFT و نحوه ساخت چنین سیستم‌هایی از یک دیدگاه کاملاً فنی و مهندسی است. معاملات فرکانس بالا یک رشته چندوجهی (Multi-disciplinary) است که نیازمند دانش عمیق در حوزه‌های زیر است:

  • معماری کامپیوتر و پردازنده‌ها (Computer Architecture)
  • سیستم‌های عامل (Operating Systems)
  • شبکه‌های کامپیوتری و تبادل داده (Networking)
  • برنامه‌نویسی سطح پایین و فوق سریع (Low-Latency Programming)

در پایان این کتاب، شما خواهید آموخت که چگونه یک سیستم معاملاتی را از صفر (Scratch) با بهره‌گیری از پیشرفته‌ترین انتخاب‌های فنی برای بهینه‌سازی سرعت و مقیاس‌پذیری بسازید.


ساختار کلی کتاب

این کتاب به سه بخش اصلی تقسیم شده است:

  1. بخش اول (فصول ۱ تا ۳): بررسی نحوه کارکرد تاکتیک‌ها و استراتژی‌های HFT، ماهیت معاملاتی که می‌توان از آن انتظار داشت، کارکردهای درونی یک سیستم HFT و در نهایت تشریح دقیق نحوه کارکرد یک بورس و صرافی معاملاتی (Exchange).
  2. بخش دوم (فصول ۴ تا ۷): تشریح تئوری سیستم‌های عامل و سخت‌افزار، و دانش مورد نیاز برای بهینه‌سازی سیستم معاملاتی با در نظر گرفتن ویژگی‌های سخت‌افزار و سیستم‌عامل.
  3. بخش سوم (فصول ۸ تا ۱۱): آموزش گام‌به‌گام نحوه استفاده از زبان‌های ++C، جاوا، پایتون و تراشه‌های FPGA برای خلق یک سیستم HFT. این بخش دانش مذکور را به معاملات رمزارزها (Crypto Trading) تعمیم داده و ساخت سیستم در بسترهای ابری (Cloud) را نیز بررسی می‌کند.

اهداف فصل اول

در این فصل، چگونگی پیدایش HFT، استراتژی‌های معاملاتی کارآمد در این حوزه، و تفاوت‌های بنیادین معاملات فرکانس بالا با معاملات سنتی را بررسی خواهیم کرد:

  • تاریخچه HFT
  • تعریف و ماهیت HFT
  • شرکت‌کنندگان و بازیگران بازار HFT
  • استراتژی‌های سودآور در HFT

⏳ تاریخچه HFT (History of HFT)

دوران پیش از دهه ۱۹۳۰ (Prior to 1930)

هنگامی که از HFT صحبت می‌کنیم، تعیین یک تاریخ دقیق برای شروع آن دشوار است. باید به دوران کهن بازگردیم، زمانی که تجارت برای نخستین بار از ارتباط میان انسان‌ها شکل گرفت. پیش از اختراع پول مدرن، انسان‌های باستان برای مبادله کالا و خدمات به تجارت پایاپای و اقتصاد مبتنی بر هدیه تکیه داشتند. به گفته پیتر واتسون، تاریخچه تجارت‌های از راه دور به حدود ۱۵۰٬۰۰۰ سال پیش بازمی‌گردد. سال به سال، با افزایش جمعیت، کالاها و پول، تجارت به یکی از اصلی‌ترین فعالیت‌های بشریت بدل شد.

بدیهی است که کسب درآمد بیشتر در گرو معاملات بیشتر است؛ و یکی از متغیرهای کلیدی در این میان، سرعت بود:

اگر معاملات بیشتری در زمان کمتر انجام دهید، سود بیشتری کسب خواهید کرد.

داستان‌های تاریخی متعددی از تلاش معامله‌گران برای دسترسی به فناوری‌های ترابری سریع‌تر حکایت دارند تا بتوانند سریع‌تر معاملات را نهایی کنند یا اخبار را پیش از دیگرانی که به این ابزارهای فنی دسترسی ندارند دریافت نمایند.

خیلی زود موارد متعددی از «تجارت ناعادلانه» ناشی از مزیت فنی پدیدار شد:

  • واقعه تاریخی سال ۱۷۹۰ در ایالات متحده: نماینده‌ای از ایالت جورجیا در مجلس نمایندگان آمریکا سخنرانی کرد تا از تریدرهای فوق سریع پرده بردارد! کنگره در حال بحث بر سر پیشنهاد الکساندر همیلتون (وزیر خزانه‌داری) بود مبنی بر اینکه دولت فدرال، دیون و اوراق قرضه بجامانده از دوران انقلاب استقلال را بازخرید و تقبل کند (Funding Act of 1790).
  • معامله‌گرانی که از این تصمیم پشت‌پرده مطلع شدند، بلافاصله سریع‌ترین قایق‌های بادبانی را خریدند یا اجاره کردند. هدف آن‌ها این بود که از پیک‌های رسمی دولتی پیشی بگیرند (اصطلاحاً Front-run کنند) و اوراق دیون قدیمی مردم را در ایالت‌های دوردست با قیمت‌های بسیار نازل بخرند، زیرا می‌دانستند با تصویب قانون در پایتخت، ارزش این اوراق چند برابر خواهد شد. در طول قرن بیستم، ایده معاملات سرعتی به تکامل خود ادامه داد تا مفهوم مدرن HFT متولد شد.

دوران پس از دهه ۱۹۳۰ (The Post-1930s Era)

معامله‌گری (Trading) عبارت است از مبادله یک دارایی با دارایی دیگر؛ این دارایی می‌تواند محصول مالی، خدمت، وجه نقد یا دارایی دیجیتال باشد. یکی از اهداف ترید، کسب سود از این معاملات است. حجم پول ایجادشده با تعداد کل تراکنش‌ها همبستگی دارد: $$\text{سودآوری در طول زمان} \propto \frac{\text{تعداد تراکنش‌ها}}{\text{زمان}}$$

هنگامی که بتوانیم نسبت تعداد تراکنش‌ها به زمان را افزایش دهیم، سودآوری را در طول زمان ارتقا می‌دهیم. از این رو، توانایی در افزایش تعداد معاملات امری حیاتی است. بازیگران بازار خیلی زود پی بردند که باید زمان معامله را به حداقل برسانند؛ بنابراین در مکان‌های مشخصی گرد هم آمدند تا سفارش‌های خود را ثبت کنند؛ مکان‌هایی که امروزه آن‌ها را تالار بورس (Trading Floor یا Trading Exchange) می‌نامیم.

رویدادهای کلیدی در گسترش معاملات خودکار و پرسرعت عبارتند از:

  • سال ۱۹۶۹ (Instinet): نخستین زیرساخت سیستمی خودکار ایجاد شد و پیوستن به تراکنش‌های پرسرعت الکترونیکی را شتاب بخشید.
  • سال ۱۹۷۱ (NASDAQ): نزدک در سال ۱۹۷۱ با معاملات الکترونیکی متولد شد و به عنوان نخستین بازار بورس الکترونیکی جهان شناخته گردید (گرچه در ابتدا تنها برای ارسال مظنه‌ها استفاده می‌شد).
  • سال ۱۹۹۶ (Island ECN و Archipelago): شبکه ارتباط الکترونیکی پیشگام Island ECN برای دادوستد سهام آمریکا تأسیس شد و همزمان شرکت Archipelago با راه‌اندازی بورس ArcaEx، معاملات تمام‌الکترونیکی سهام را به اوج رساند.
  • دهه ۲۰۰۰: سهم معاملات فرکانس بالا از کل بازار به بیش از ۱۰ درصد رسید.

در اوایل دهه ۲۰۰۰، بخش مالی پای مهندسان و فناوران متعددی را به وال‌استریت باز کرد. با ورود این فناوری‌ها، تحول عمیقی آغاز شد: واژگانی چون خودکارسازی (Automation)، نرخ گذردهی (Throughput)، کارایی (Performance) و تاخیر زمانی (Latency) نقل محافل معاملاتی شد. تا سال ۲۰۰۹، تنها ۲ درصد از شرکت‌های معاملاتی بیش از ۷۵ درصد کل حجم معاملات بازار سهام آمریکا را به خود اختصاص داده بودند. امروزه تنها چند شرکت فوق‌العاده بزرگ و انگشت‌شمار در خط مقدم HFT باقی مانده‌اند؛ از جمله:

  • Citadel Securities
  • Virtu Financial
  • Jump Trading
  • IMC Trading
  • Tower Research Capital

عصر مدرن (The Modern Era)

دوران پس از ۱۹۳۰ عمدتاً بر مقررات‌گذاری و شفافیت بازارهای سنتی تمرکز داشت. اما عصر مدرن، معاملات تمام‌الکترونیکی را حاکم کرد. در سال ۲۰۰۰، کمیسیون بورس و اوراق بهادار آمریکا (SEC) طرح دفترچه مرکزی سفارشات محدود (CLOB - Central Limit Order Book) را ارائه داد. CLOB یک سامانه شفاف است که سفارش‌های میان خریداران و فروشندگان را با الگوریتم‌های مشخص تطبیق می‌دهد. بورس‌های جدید متعددی ظهور کردند و بازیگران الکترونیکی پشته‌های فناوری اختصاصی (Tech Stack) خود را ساختند تا سریع‌تر معامله کنند.

رقابت در HFT نیازمند سرمایه‌گذاری سنگین در سه بعد: پول، نیروی انسانی و زمان است. این صنعت محل پیوند تخصص‌های سطح پایین سیستم (سیستم‌عامل و سخت‌افزار)، دانشمندان کمی (Quants) و سرمایه‌گذاران مجهز به دانش فنی است:

  • مهندسانی که توانایی نگارش کدهای با کارایی فوق‌العاده بالا برای سیستم‌های با تاخیر فوق‌العاده کم (Ultra-low latency) را دارند بسیار کمیاب و گران‌قیمت هستند.
  • سخت‌افزارهای خاص، روترها، سرورها و تجهیزات شبکه با سرعت نور بسیار پرهزینه‌اند.
  • این موانع ورود سنگین (Barrier to Entry)، مانع حضور بسیاری از تازه‌واردان شده و رقابت را محدود به نخبگان کرده است.

علاوه بر غول‌های HFT، شرکت‌های بوتیکی کوچکی نیز وجود دارند که با یافتن یک مزیت رقابتی ظریف (Edge) در ساختار خرد بازار یا یک ترفند فنی که دیگران به آن توجه نکرده‌اند فعالیت می‌کنند. غول‌های HFT مسئول جابه‌جایی بیشترین حجم بازار سهام هستند. برآورد می‌شود که امروزه دست‌کم ۵۰ درصد از حجم معاملات سهام آمریکا توسط HFT انجام می‌شود (گرچه سودآوری و سهم بازار نسبت به سال اوج آن یعنی ۲۰۰۹ تا حدی تعدیل شده است).

از سال ۲۰۱۵ به بعد، گسترش ارزهای دیجیتال پنجره جدیدی از فرصت‌ها را پیش روی این معامله‌گران گشود. امروزه شاهد به‌کارگیری گسترده استراتژی‌های HFT در صرافی‌های رمزارز نظیر Coinbase، Binance و صدها پلتفرم دیگر هستیم. عصر مدرن، معاملات خودکار را برای همیشه تثبیت کرده است. کسب‌وکار فروش داده‌های بازار (Market Data) به منبع درآمد عظیم صرافی‌ها بدل شده و این داده‌ها، ماده خام الگوریتم‌های معاملاتی هستند.


چرا معاملات فرکانس بالا وجود دارند؟ (Why have HFT?)

هدف HFT ثبت تعداد بسیار بالایی تراکنش در هر ثانیه است. بدین ترتیب شرکت‌ها می‌توانند به سرعت به تغییرات بازار واکنش نشان دهند و فرصت‌هایی را شکار کنند که بدون این سرعت هرگز میسر نبود.

نهادهای بزرگ مالی با ارائه حجم‌های عظیم نقدینگی به بازارها، سودهای اندک اما تضمین‌شده‌ای می‌برند. سیستم‌های آن‌ها قادر به ارسال میلیون‌ها سفارش است. فایده آن‌ها برای بازار چیست؟

  1. آن‌ها به روان شدن بازار و کشف قیمت کمک می‌کنند.
  2. با کاهش اسپرد قیمت (Spread)، بازارهای رقابتی‌تری می‌سازند.
  3. از آنجا که سود هر سهم در این معاملات بسیار ناچیز است (گاهی کسری از سنت)، این شرکت‌ها باید تعداد بسیار بالایی معامله انجام دهند تا در مجموع سود چشمگیری به دست آورند.
  4. علاوه بر این، آنها از صرافی‌ها تخفیف‌های کارمزد نقدینگی (Rebates) دریافت می‌کنند؛ زیرا صرافی‌ها برای تشویق حضور بازارسازان، به ثبت‌کنندگان سفارش‌های منفعل مبالغی پاداش می‌دهند.

چه چیزی HFT را از معاملات سنتی متمایز می‌کند؟

معاملات HFT باید دارای کمترین تاخیر داده ممکن (حداقل Latency) و بالاترین سطح خودکارسازی باشند. شرکت‌ها از رایانه‌های مجهز به الگوریتم‌های دقیق برای کشف فرصت‌ها و ارسال، لغو یا تغییر سفارش‌ها در کسری از میلی‌ثانیه استفاده می‌کنند. این امر هم به فناوری داخل شرکت‌ها و هم به زیرساخت بورس‌ها وابسته است.

بورس‌های مطرح جهان صدها میلیون دلار در فناوری‌های HFT سرمایه‌گذاری کرده‌اند:

  • NASDAQ (نیویورک): نخستین بورس الکترونیکی سهام جهان که در ۱۹۷۱ با حذف نیاز به تالار فیزیکی و معامله رو در رو، بازارها را متحول ساخت. دومین بورس بزرگ جهان از نظر ارزش بازار است و سهم عمده آن را شرکت‌های فناوری تشکیل می‌دهند.
  • New York Stock Exchange - NYSE (نیویورک): بزرگ‌ترین بازار بورس سهام جهان که در سال ۲۰۱۳ توسط ICE خریداری شد.
  • Chicago Board Options Exchange - CBOE (شیکاگو): بزرگ‌ترین بازار اختیار معامله در آمریکا.
  • London Stock Exchange Group - LSE (لندن): بازار مالی باسابقه و بین‌المللی اروپا.
  • Japan Exchange Group - JPX (توکیو): دارنده سومین بازار سهام بزرگ دنیا.
  • Shanghai Stock Exchange - SSE (شانگهای): بزرگ‌ترین بورس چین با محدودیت‌های قانونی خاص.
  • Euronext (اروپا): بورس متمرکز کشورهای هلند، فرانسه، بلژیک، پرتغال و ایرلند.
  • Hong Kong Exchanges and Clearing - HKEX (هنگ‌کنگ): قطب تبادل مالی شرق آسیا.
  • CME Group (شیکاگو): بزرگ‌ترین بازار مشتقات و قراردادهای آتی (Futures) در دنیا.

اثر استخرهای تاریک (Effect of Dark Pools)

استخرهای تاریک (Dark Pools) شبکه‌های معاملاتی خصوصی و جایگزینی هستند که برای تسهیل مبادلات بدون نمایش اطلاعات به عموم طراحی شده‌اند. بر خلاف بورس‌های عمومی، دفترچه سفارشات در دارک پول‌ها به صورت عمومی منتشر نمی‌شود.

نهادهای مالی و صندوق‌ها از دارک پول‌ها استفاده می‌کنند تا بلوک‌های بسیار بزرگ سهام را بدون جابه‌جا کردن قیمت در بازار عمومی بخرند یا بفروشند (جلوگیری از ریزش یا پرش قیمت به ضرر خودشان). در غیاب دارک پول‌ها، ثبت یک سفارش خرید ۱۰ میلیون سهمی در تابلوی بورس عمومی باعث پرش سرسام‌آور قیمت می‌شد.

اما ورود الگوریتم‌های HFT به دارک پول‌ها پویایی این محیط را تغییر داد:

  • دارک پول‌ها به HFTها امکان دادند تا با سرعت بالا و هزینه کمتر به نقدینگی دست یابند.
  • در اثر فعالیت HFTها، متوسط اندازه سفارش‌ها در استخرهای تاریک به شدت کاهش یافت.
  • برخی الگوریتم‌ها با تکنیک‌هایی مانند Pinging توانستند محل وجود سفارش‌های سنگین پنهان را در دارک پول‌ها شکار کنند.
  • پرونده جنجالی بارکلیز (Barclays): در سال ۲۰۱۴ دادستان کل نیویورک علیه فعالیت‌های دارک پول بارکلیز شکایت کرد و مدعی شد این بانک مشتریان سنتی را فریب داده و تریدرهای شکارچی HFT را در سیستم تاریک خود آزاد گذاشته است. در سال ۲۰۱۶، بارکلیز ناچار شد ۳۵ میلیون دلار جریمه به SEC و ۷۰ میلیون دلار به ایالت نیویورک بپردازد.
  • برای مقابله با این شکارها، در سال ۲۰۱۷ محققانی چون پترسکو و ویدو پیشنهاد اعمال «حداقل اندازه سفارش» در استخرهای تاریک را دادند.

چه کسانی در HFT معامله می‌کنند؟ (Who trades HFT?)

پاسخ کوتاه کتاب این است: تقریباً همه نهادها. از فعالان سمت خرید (Buy-side) و سمت فروش (Sell-side) گرفته تا شبکه‌های ECN و کارگزاران بین‌بانکی.

  • بیش از نیمی از بازیگران HFT را شرکت‌های معاملاتی اختصاصی (Proprietary Trading Firms) تشکیل می‌دهند.
  • بخش دیگر شامل میزهای معاملاتی اختصاصی در بانک‌های بزرگ چندملیتی و هج‌فاندهای مطرح است.
  • غول‌های ادغام‌شده مانند KCG Holdings (حاصل ترکیب Getco و Knight Capital) و همچنین بازارهای جدیدی مانند IEX (با هدف محافظت از تریدرها در برابر تاخیرها) از بازیگران مهم هستند.
  • شرکت‌های HFT مانند Citadel امروزه بخش عمده‌ای از جریان سفارشات معامله‌گران خرد (Retail Flow) را نیز خریداری و مدیریت می‌کنند.

برای راه‌اندازی HFT به چه چیزهایی نیاز است؟

شرکت‌کنندگان در HFT باید به ابزارهای کلیدی زیر مجهز باشند:

  1. رایانه‌های فوق سریع: در اکثر استراتژی‌های HFT، تمرکز بر گذردهی تک‌هسته‌ای (Single-core throughput) پردازنده و حداقل کلاک سایکل است و لزوماً موازی‌سازی چند تردی استفاده نمی‌شود، زیرا همگام‌سازی تردها خود تاخیر ایجاد می‌کند.
  2. نزدیکی جغرافیایی به صرافی (Co-location): در آمریکا از قابلیت هم‌مکانی یا Colocation استفاده می‌شود؛ یعنی سرورهای پردازشی الگوریتم دقیقاً در همان مرکز داده‌ای که سرورهای هسته صرافی قرار دارند مستقر می‌شوند تا تاخیر مسافت فیزیکی به میکروثانیه برسد. کابل‌های اتصال همه شرکت‌ها به سرور صرافی دقیقاً به یک طول برش می‌خورند تا برابری و عدالت رعایت شود.
  3. تاخیر فوق‌العاده کم (Low Latency): تاخیر در HFT عبارت است از: $$\text{Latency} = \text{زمان دریافت داده} + \text{زمان تصمیم‌گیری الگوریتم} + \text{زمان رسیدن سفارش به صرافی}$$ اگر سفارشی حتی ۱ میکروثانیه دیرتر برسد، دیگران سود را ربوده‌اند و ممکن است سفارش شما در قیمتی زیان‌بار اجرا شود.
  4. الگوریتم‌های رایانه‌ای و خوراک داده زنده (Real-time data feeds)

استراتژی‌های HFT چه هستند؟ (What are HFT strategies?)

استراتژی‌های HFT زیرمجموعه‌ای از معاملات الگوریتمی هستند که در مقیاس میکروثانیه (و گاه نانوثانیه) اجرا می‌شوند. بازی اصلی این حوزه معیاری به نام Tick-to-Trade است: یعنی فاصله زمانی از لحظه ورود یک تیک داده جدید تا لحظه شلیک سفارش به سمت صرافی.

مفاهیم پایه:

  • کلاس‌های دارایی (Asset Classes): سهام، قراردادهای آتی (Futures)، اوراق قرضه، اختیار معامله (Options)، فارکس (FX) و ارزهای دیجیتال.
  • نقدینگی و عمق دفترچه (Liquidity & Depth):
    • تمایل شرکت‌کنندگان برای معامله یک دارایی نقدینگی نام دارد.
    • عمق (Depth): تعداد سطوح قیمتی موجود در دفترچه سفارشات.
    • اگر حجم در لایه‌ها زیاد باشد به آن دفترچه عمیق یا بزرگ می‌گویند. هرچه بازار عمیق‌تر باشد، معامله‌گر راحت‌تر و بدون پرش قیمت خرید و فروش می‌کند.
  • داده‌های تیک‌به‌تیک و توزیع آماری: داده‌های HFT تصادفی در زمان بوده و دارای دنباله‌های پهن (Fat Tail Distributions) هستند؛ یعنی احتمال رخداد نوسانات ناگهانی و زیان‌های سنگین در آن‌ها بسیار بیشتر از توزیع نرمال گاوسی است. دو ویژگی اصلی این داده‌ها عبارتند از:
    • خوشه‌بندی نوسانات (Volatility Clustering): نوسانات بزرگ به دنبال نوسانات بزرگ و دوره‌های آرام به دنبال دوره‌های آرام رخ می‌دهند.
    • وابستگی بلندمدت (Long memory): سرعت کاهش وابستگی آماری بین داده‌ها نسبت به فاصله زمانی.
  • تخفیف‌های نقدینگی (Maker-Taker Model): صرافی به سفارش‌گذارانی که با لیمیت اردر نقدینگی می‌آورند تخفیف/پاداش (Rebate) می‌دهد و از کسانی که نقدینگی برمی‌دارند کارمزد می‌گیرد.

۱. استراتژی بازارسازی (Market Making)

پیش از ورود به جزییات، باید تفاوت بین بازارساز و بازارگیر را بر روی دفترچه سفارشات محدود (Limit Order Book) درک کرد:

  • سفارش تهاجمی (Aggressive Order): سفارشی که با قیمتی ثبت می‌شود که فوراً تطبیق داده شود. این سفارش نقدینگی را از بازار حذف می‌کند؛ به ثبت‌کننده آن Market Taker می‌گویند. اگر خریدار مستقیماً قیمت Ask فروشنده را بخرد، اصطلاحاً اسپرد را رد کرده (Crosses the spread).
  • سفارش منفعل (Passive Order): سفارشی با قیمتی عقب‌تر که بلافاصله اجرا نمی‌شود، بلکه نقدینگی را درون دفترچه اضافه می‌کند؛ به این فرد Market Maker می‌گویند.

نحوه سودآوری بازارساز:

بازارساز بدون پیش‌بینی ارزش ذاتی دارایی، پیوسته پیشنهاد خرید و پیشنهاد فروش در بازار حفظ می‌کند و از اختلاف این دو (اسپرد) سود می‌برد. برای کاهش ریسک نگهداری سهام در طول زمان (Inventory Risk)، هر خرید باید سریعاً با یک فروش و هر فروش با یک خرید متناظر جفت شود:

  • مثال عددی کتاب: اگر سهامی در ۱۰۰ دلار معامله شود، بازارساز سفارش خرید را در ۹۹.۵۰ دلار و سفارش فروش را در ۱۰۰.۵۰ دلار قرار می‌دهد. اگر هر دو معامله انجام شوند، بازارساز ۱ دلار سود خالص کسب می‌کند بدون آنکه نوسان جهت بازار برایش اهمیت داشته باشد.

۲. استراتژی اسکالپینگ (Scalping)

اسکالپینگ یکی از متداول‌ترین استراتژی‌هاست که در آن معامله‌گر می‌کوشد از نوسانات بسیار کوچک قیمت در کسری از ثانیه سود کسب کند. پوزیشن‌ها برای مدت بسیار کوتاهی باز می‌مانند و هدف گرفتن چندین سود بسیار ناچیز با تعداد معاملات بالاست.


۳. استراتژی آربیتراژ آماری (Statistical Arbitrage / Stat-Arb)

فرضیه بازار کارا (EMH) ادعا می‌کند قیمت‌ها در هر لحظه منعکس‌کننده تمام اطلاعات موجود هستند و بدون اخبار بنیادی نباید نوسان کنند. اما در واقعیت روزمره چنین نیست؛ دلیل این نوسانات نقدینگی (Liquidity) است:

  • معاملات نهادی بزرگ ربطی به خبر ندارند، بلکه به پوشش ریسک یا خروج اضطراری مربوط‌اند.
  • جویندگان نقدینگی (Liquidity Seekers) حاضرند جریمه نقدی و قیمت‌های بدتر بپردازند تا فوراً خارج شوند؛ این امر به سود تأمین‌کنندگان نقدینگی تمام می‌شود و قیمت را به طور موقت از ارزش تعادلی منحرف می‌کند (Mispricing).
  • آربیتراژ آماری از همین عدم تعادل‌های آماری و همبستگی قیمت و نقدینگی سود می‌برد.

دو شیوه اجرای آربیتراژ آماری:

  1. یک دارایی در چند بازار (Cross-Venue): یک سهم یکسان در دو صرافی قیمت‌های متفاوتی پیدا می‌کند. الگوریتم ظرف کمتر از ۱ میلی‌ثانیه در بازار ارزان می‌خرد و در بازار گران می‌فروشد.
  2. دارایی‌های مرتبط (Linked Securities): مانند رابطه یک شاخص با سهام درون آن، یا دو سهم هم‌صنعت (مثلاً دو غول نفتی). الگوریتم با مدل‌سازی تاریخی ارتباط میان دو دارایی، به محض مشاهده انحراف از حالت نرمال وارد معامله جفتی شده و با بازگشت به تعادل، سود شناسایی می‌کند.

۴. آربیتراژ تاخیر (Latency Arbitrage)

بهره‌برداری از اختلاف زمانی رسیدن اطلاعات به مکان‌های مختلف جغرافیایی. اگر قیمت یک دارایی در بورس نیویورک تغییر کند، الگوریتمی که با لینک ارتباطی سریع‌تر خبر را زودتر به بورس شیکاگو برساند، می‌تواند سهام مربوطه را پیش از به‌روزرسانی قیمت در بورس دوم بخرد.


۵. اثر اخبار و استراتژی‌های اطلاعات‌محور (Impact of News)

اطلاعات قلب تپنده معاملات است. الگوریتم‌ها برای خواندن و تحلیل اخبار خبرگزاری‌ها و حتی شبکه‌های اجتماعی آموزش دیده‌اند:

  • خبرگزاری‌های بزرگ امروزه بیانیه‌های مطبوعاتی را به گونه‌ای بسته‌بندی می‌کنند که رایانه‌ها بتوانند با کلمات کلیدی مشخص بلافاصله اثر مثبت یا منفی را استخراج کنند.
  • آن‌ها سرورهای خود را در مراکز مالی قرار می‌دهند تا اخبار کسری از ثانیه زودتر تحویل شود.
  • ماجرای هک توییتر آسوشیتدپرس در سال ۲۰۱۳: در سال ۲۰۱۳ حساب توییتر خبرگزاری AP هک شد و توییت دروغینی منتشر کرد مبنی بر اینکه دو انفجار در کاخ سفید رخ داده و باراک اوباما زخمی شده است! در عرض چند ثانیه، الگوریتم‌های خبری با پردازش این منبع معتبر فروش‌های سنگینی انجام دادند و شاخص‌های مالی جهان ناگهان سقوط کردند، تا اینکه چند دقیقه بعد خبر تکذیب شد.

۶. جرقه‌زنی مومنتوم (Momentum Ignition)

روشی که در آن الگوریتم با ارسال حجم سنگینی از سفارش‌ها، توهم تغییر حجم و شروع یک روند پرشتاب را به بقیه بازار القا می‌کند:

  1. ابتدا تریدر پوزیشن اصلی و کوچک خود را مخفیانه باز می‌کند.
  2. سپس با ارسال رگباری از سفارش‌های ساختگی در تابلوی بورس، الگوریتم‌های دیگر را به خرید/فروش شتاب‌زده تحریک می‌کند (Self-fulfilling prophecy).
  3. با جهش قیمت، تریدر پوزیشن اولیه خود را با سود کلان می‌بندد و سفارش‌های قبلی را لغو می‌کند.

۷. استراتژی‌های تخفیف کارمزد (Rebate Strategies)

با بهره‌گیری از مدل کارمزد Maker-Taker، برخی شرکت‌ها استراتژی‌هایی پیاده می‌کنند که هدف اصلی‌شان معامله بدون سود سرمایه‌ای است و درآمد اصلی آن‌ها صرفاً از طریق جمع‌آوری تخفیف‌ها و پاداش‌های چند سنتی است که صرافی به ازای حجم بالای سفارش‌های لیمیت به آن‌ها پرداخت می‌کند. همچنین ساختار معکوس بنام Trader-Maker نیز در برخی بازارها وجود دارد.


۸. پینگینگ (Pinging)

ارسال سفارش‌های بسیار کوچک و فوری (معمولاً بلوک‌های ۱۰۰ سهمی) به صرافی‌ها و دارک پول‌ها. هدف این کار ماهیگیری و کشف این است که آیا نهاد بزرگی در حال اجرای یک سفارش خرید یا فروش چندمیلیونی پنهان در آن قیمت است یا خیر. به محض مثبت شدن پینگ، HFT می‌تواند بر اساس این اطلاعات معاملاتی مطمئن انجام دهد.


۹. فعالیت‌های غیرقانونی و دستکاری بازار (Illegal Activities)

سازمان‌های ناظر نظیر SEC و FBI در سال‌های اخیر نظارت شدیدی را بر تخلفات HFT آغاز کرده‌اند:

  • فرانت‌رانینگ (Front-running): ثبت سفارش بر اساس اطلاعات محرمانه یا سفارش‌هایی که هنوز برای عموم منتشر نشده‌اند. این کار توسط SEC و FINRA صراحتاً غیرقانونی اعلام شده است.
  • اسپوفینگ (Spoofing): ثبت سفارش‌های پرحجم بدون هیچ قصد واقعی برای اجرا، صرفاً به منظور فریب دیگران برای تغییر قیمت، و سپس لغو فوری آن‌ها درست قبل از اجرا. در قانون اصلاح وال‌استریت (Dodd-Frank Act 2010) این عمل جرم‌انگاری شد و در سال ۲۰۱۴ نخستین پرونده کیفری علیه یک معامله‌گر در شیکاگو تشکیل گردید.
  • لایه‌بندی (Layering): مشابه اسپوفینگ است با این تفاوت که سفارش‌های فریبنده در چندین طبقه و سطح قیمتی مختلف چیده می‌شوند تا تقاضای کاذب را عمیق‌تر نشان دهند. گرچه در بازارهای سنتی این روش‌ها ممنوع است، اما در بازارهای کم‌نظارت‌تر نظیر برخی صرافی‌های رمزارز کماکان مشاهده می‌شوند.

خلاصه و جمع‌بندی فصل اول (Summary)

در این فصل، ریشه‌ها و تاریخچه معاملات فرکانس بالا مرور شد. دانستیم چه عواملی HFT را در مقایسه با معاملات معمولی منحصر‌به‌فرد می‌سازد. همچنین لایه‌های مختلف استراتژی‌هایی را که یک سیستم HFT باید از آن‌ها پشتیبانی کند دسته‌بندی کردیم.

در فصل بعدی (02 - اجزای حیاتی سیستم معاملاتی)، کارکردهای اصلی نرم‌افزاری و معماری گام‌به‌گام یک سیستم معاملاتی را تشریح خواهیم کرد.

اجزای حیاتی سیستم معاملاتی

(The Critical Components of a Trading System)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۳۷ تا ۵۶


مقدمه

در فصل گذشته، با مبانی و استراتژی‌های معاملات فرکانس بالا (HFT) آشنا شدیم. در این فصل، چگونگی تبدیل این استراتژی‌های تئوریک به یک نرم‌افزار بی‌درنگ (Real-Time Software) را بررسی خواهیم کرد؛ نرم‌افزاری که مستقیماً به بورس و صرافی متصل شده و تئوری‌های آموخته‌شده را در عمل پیاده‌سازی می‌کند. ما عملکرد درونی یک سیستم معاملاتی کامل را که قادر به دادوستد دارایی‌هاست تشریح می‌کنیم.

در این فصل مباحث زیر به طور جامع پوشش داده می‌شوند:

  • شناخت و درک ساختار سیستم معاملاتی (Understanding the trading system)
  • برقراری ارتباط معاملاتی با صرافی‌ها (Making a trading system trade with exchanges)
  • مدیریت و مهندسی دفترچه سفارشات (Order book management)
  • موتور تصمیم‌گیری استراتژی برای معامله (Strategy making decisions on when to trade)

در پایان این فصل، شما قادر خواهید بود معماری یک سیستم معاملاتی را طراحی کنید، آن را به صرافی متصل نمایید و یک دفترچه سفارشات محدود (Limit Order Book) با کارایی بالا بسازید.


۱. شناخت سیستم معاملاتی (Understanding the Trading System)

طراحی یک سیستم معاملاتی برای حوزه HFT نیازمند دانشی بسیار فراتر از برنامه‌نویسی عادی و معامله‌گری سنتی است. یکی از مهم‌ترین گام‌ها در طراحی، داشتن توصیف دقیقی از نیازمندی‌ها (Requirements) است:

  • هدف نهایی سیستم، پشتیبانی فنی از ایده‌های معاملاتی شماست.
  • هر استراتژی معاملاتی با دریافت داده‌های بازار آغاز می‌شود و با اتخاذ یک تصمیم بر مبنای این داده‌ها پایان می‌یابد.
  • سیستم وظیفه جمع‌آوری داده‌های بازار (تغییرات لحظه‌ای قیمت یا Price Updates)، ارسال سفارش‌ها به صرافی و جمع‌آوری پاسخ‌های دریافتی از صرافی را بر عهده دارد.
  • این پاسخ‌ها نشان‌دهنده وضعیت‌های گوناگون سفارش هستند: لغوشده (Canceled)، ردشده (Rejected)، معامله‌شده کامل (Filled) یا معامله‌شده جزئی (Partially Filled).
  • علاوه بر این، سیستم باید سنجه‌های عملکرد سبد دارایی نظیر سود و زیان (PnL)، معیارهای مدیریت ریسک و وضعیت سلامت فرآیندهای نرم‌افزاری را به صورت آنی محاسبه کند.

ملاحظات کلیدی در آغاز طراحی سیستم:

۱. کلاس دارایی (Asset Class)

کلاس دارایی انتخابی، ساختار داده‌ای کل نرم‌افزار شما را تغییر می‌دهد. هر کلاس دارایی ماهیت و ویژگی‌های انحصاری خود را دارد:

  • بازار سهام آمریکا (US Equities): عمدتاً روی دو بورس غول‌پیکر متمرکز است: بورس نیویورک (NYSE) و نزدک (NASDAQ). این دو بورس روی هم حدود ۷٬۰۰۰ شرکت (نماد معاملاتی) را فهرست کرده‌اند.
  • بازار تبادلات ارزی (FX): ساختاری کاملاً متفاوت دارد؛ دارای ۶ جفت‌ارز اصلی (Major)، ۶ جفت‌ارز فرعی (Minor) و ۶ جفت‌ارز نامتعارف (Exotic) است. حتی با احتساب سایر ترکیب‌ها، کل نمادها کمتر از ۱۰۰ جفت‌ارز است؛ اما بر خلاف سهام آمریکا که دو بورس اصلی دارد، در فارکس با صدها صرافی، بانک و شبکه ECN پراکنده در سراسر جهان روبه‌رو هستیم.
  • این تفاوت اساسی میان «تعداد نمادها» و «تعداد بورس‌ها»، معماری سیستم معاملاتی شما را دگرگون می‌کند.

۲. نوع استراتژی معاملاتی (افق فرکانس بالا در برابر پوزیشن بلندمدت)

معماری نرم‌افزار به شدت از سبک معامله‌گری تأثیر می‌پذیرد:

  • تاکتیک‌های HFT نیازمند ارسال سفارش در کسری ناچیز از زمان هستند. در سهام آمریکا، یک سیستم معاملاتی معمولی در مقیاس میکروثانیه تصمیم به ارسال سفارش می‌گیرد؛ اما در بورس مشتقات شیکاگو (CME)، تاخیر رقابتی در مقیاس نانوثانیه سنجیده می‌شود!
  • با چنین سرعتی، زبان‌های برنامه‌نویسی تفسیری مانند پایتون به تنهایی پاسخگوی سرعت نخواهند بود و زبان‌هایی مانند ++C یا Java ترجیح داده می‌شوند.
  • در مقابل، اگر استراتژی شما نگهداری پوزیشن‌های چندروزه یا ماهانه باشد، سرعت دستیابی به نقدینگی در کسری از ثانیه کوچک‌ترین اهمیتی ندارد.

۳. تعداد کاربران و تاکتیک‌های معاملاتی (مقیاس‌پذیری)

با افزایش تعداد معامله‌گران و گوناگونی استراتژی‌ها، ترافیک سفارش‌ها سرسام‌آور می‌شود. سیستم پیش از ارسال هر سفارش به صرافی باید بررسی‌های امنیتی انجام دهد:

  • بررسی اعتبار سفارش (فرمت، قیمت و حجم).
  • اطمینان از اینکه حجم کلی پوزیشن برای آن ابزار از سقف مجاز ریسک فراتر نرود.
  • کنترل‌های انطباق مقرراتی (Compliance Tests) برای پایبندی به قوانین بورس.
  • تمامی این بررسی‌ها زمان محاسباتی را افزایش می‌دهند؛ بنابراین اگر سیستم به اندازه کافی مقیاس‌پذیر و سریع نباشد، سفارش‌ها در صف پردازش معطل شده و فرصت‌های سودآور از دست می‌روند.

معماری کلان سیستم معاملاتی (Trading System Architecture)

شکل زیر معماری پایه‌ای یک سیستم معاملاتی را به تصویر می‌کشد:

اجزای تشکیل‌دهنده:

  1. پلتفرم‌های مبادله (Venues): اصطلاحی جامع برای هر سامانه‌ای که سفارش‌های خرید و فروش را جفت می‌کند؛ شامل بورس‌های رسمی (Exchanges)، شبکه‌های ECN، تجمیع‌کننده‌ها (Aggregators) و بانک‌ها.
  2. درگاه‌ها (Gateways): نرم‌افزاری که وظیفه ارتباط با پلتفرم‌ها، دریافت قیمت‌ها و شلیک سفارش‌ها را بر عهده دارد.
  3. دفترچه‌ساز (Book Builder): داده‌های خامی که درگاه‌ها از بورس دریافت کرده‌اند را تجمیع کرده و یک دفترچه سفارشات محدود (Limit Order Book) مرتب و یکپارچه می‌سازد.
  4. استراتژی معاملاتی (Strategy): مغز تحلیل‌گر که سیگنال معامله را بر اساس دیتای دفترچه صادر می‌کند.
  5. مدیریت سفارشات (Order Manager / OMS): تمامی سفارش‌های برآمده از استراتژی‌ها را گردآوری کرده و چرخه حیات سفارش را تا انتها دنبال می‌کند.
  6. مسیر بحرانی (Critical Path): زنجیره میان درگاه، دفترچه‌ساز، استراتژی و OMS در مسیر بحرانی سیستم قرار دارند؛ هر نانوثانیه تاخیر در این مسیر، ضررهای مالی هنگفتی به دنبال خواهد داشت.
  7. سرویس‌های نظارتی (Viewers & Command and Control): نمایشگرهای مانیتورینگ برای پایش سلامت فرآیندها و هشدارهای آنی.

۲. درگاه‌های اتصال به بورس‌ها (Gateways)

درگاه‌ها حریص‌ترین و پرمصرف‌ترین بخش سیستم از حیث منابع پردازشی و زمان اجرا هستند. آن‌ها داده‌ها را از کارت شبکه می‌گیرند و پس از تبدیل، به بدنه سیستم تحویل می‌دهند:

جمع‌آوری داده‌ها (Data Collection)

درگاه وظیفه دارد قیمت‌ها را از بورس‌ها، ECNها و دارک‌پول‌ها گردآوری کند.

  • پیکان‌های جریان داده دوطرفه هستند؛ دریافت مظنه‌ها از بورس، و ارسال سفارش‌ها به بورس.
  • برای آغاز دریافت قیمت، درگاه ابتدا اتصال شبکه با صرافی برقرار می‌کند، احراز هویت (Authentication) می‌شود و سپس در ابزار مالی مورد نظر مشترک (Subscribe) می‌گردد.

فرآیند چرخه تبادل در درگاه سفارشات:

  • هنگام ثبت سفارش، درگاه پیام را از طریق شبکه به سمت صرافی ارسال می‌کند.
  • اگر صرافی پیام را دریافت کند، یک پیام تاییدیه (Acknowledgment) بازمی‌گرداند.
  • هنگامی که سفارش با سفارش دیگری در صرافی جفت شد، پیام اجرای معامله ارسال می‌شود.
  • اگر درگاه پاسخی از صرافی دریافت نکند، سیستم باید سفارش را منقضی‌شده (Timed Out) اعلام کند تا معامله‌گر انسانی بتواند سریعاً مداخله کرده و علت نقص شبکه را بررسی نماید.

بسترهای فیزیکی ارتباط و هم‌مکانی (Colocation)

  • سیستم معاملاتی روی رایانه شما و موتور تطبیق صرافی روی رایانه دیگری در مکانی دیگر است.
  • در شرایط هم‌مکانی (Colocation): اگر سرورهای تریدر دقیقاً در دیتاسنتر صرافی مستقر شوند، یک کابل اختصاصی مستقیم میان آن‌ها کشیده می‌شود که تاخیر فیزیکی را به کمترین حد ممکن می‌رساند.
  • در شرایط ابری (Cloud): ارتباط از بستر عمومی اینترنت می‌گذرد که نسبت به اتصال مستقیم به شدت کندتر و متغیر است.

۳. پروتکل‌ها و APIهای ارتباطی

پروتکل‌های شبکه قواعد تعامل میان رایانه‌ها را تعیین می‌کنند. در بازارهای مالی از سطوح زیر استفاده می‌شود:

  • لایه فیزیکی (Physical Media):
    • سیم مسی (Wire): جریان الکتریکی، پهنای باند کم.
    • فیبر نوری (Fiber): سرعت نور و پهنای باند بالا.
    • مایکروویو (Microwave): راه‌اندازی سریع با سرعت انتشار هوایی بالاتر از شیشه فیبر، اما آسیب‌پذیر در برابر شرایط نامساعد جوی و باران.
  • لایه شبکه و انتقال: پروتکل IP برای مسیریابی بسته‌ها، و پروتکل‌های TCP (اتصال مطمئن و بدون خطا) و UDP (ارسال فوق‌سریع بدون بررسی دریافت، ایده‌آل برای پخش زنده دیتای بازار).
  • لایه نرم‌افزاری (Financial APIs): صرافی سندی ارائه می‌دهد که فرمت پیام‌های لیمیت اردر، انصراف، دریافت قیمت و وضعیت‌ها را مشخص می‌کند (مانند پروتکل FIX یا باینری اختصاصی بورس).

۴. مدیریت و مهندسی دفترچه سفارشات (Order Book Management)

دفترچه سفارشات محدود (LOB) تمام به‌روزرسانی‌های قیمتی را دریافت و به شکلی ساختاریافته مرتب می‌کند تا الگوریتم بتواند در کمترین زمان تصمیم بگیرد.

  • دفترچه دارای دو بخش است: سفارش‌های خرید (Bids) و سفارش‌های فروش (Offers/Asks).
  • برای هر سفارش: نام بازار (Venue)، حجم (Volume) و قیمت (Price) ذخیره می‌شود.
  • وظیفه دفترچه‌ساز (Book Builder): جمع‌آوری سه دفترچه مجزا از سه بورس مختلف و ساخت یک دفترچه ادغام‌شده و واحد.

نحوه دریافت به‌روزرسانی‌های دفترچه از بورس

از آنجا که در بورس‌های بزرگی مانند NYSE و نزدک میلیون‌ها سفارش در هر ثانیه رد و بدل می‌شود، ارسال کل دفترچه (Full Book) با هر سفارش جدید، پهنای باند شبکه را فوراً فلج می‌کند. راهکار صرافی‌ها به این صورت است:

  1. در آغاز اتصال، یک عکس فوری کامل (Full Snapshot) از وضعیت موجود دفترچه فرستاده می‌شود.
  2. سپس، صرافی منحصراً تغییرات افزایشی لحظه‌ای (Incremental Updates) شامل درج سفارش جدید، تغییر حجم یا لغو سفارش را مخابره می‌کند.

سه عملیات بنیادین در دفترچه:

  1. درج (Insertion): افزودن سفارش جدید به دفترچه. نیازمند ساختار داده‌ای با مرتبه پیچیدگی زمانی $O(1)$ یا حداکثر $O(\log n)$.
  2. اصلاح (Amendment): جستجوی سریع سفارش بر اساس شناسه (Order ID) و تغییر حجم یا قیمت.
  3. ابطال (Cancelation): بیرون کشیدن و حذف سفارش از صف بر اساس Order ID.

الزامات طراحی ساختار داده بهینه برای Order Book در HFT

برای دستیابی به بیشترین سرعت، ساختار داده دفترچه باید شرایط زیر را تضمین کند:

  • جستجوی با زمان ثابت ($O(1)$) برای شناسه سفارش: به دلیل مواجهه با میلیون‌ها سفارش در ثانیه، جستجوی Order ID برای به‌روزرسانی باید بدون تاخیر باشد.
  • شاخص‌گذاری سریع قیمت‌ها: برای پیمایش در میان سطوح قیمتی باید شاخص‌بندی لگاریتمی باشد تا سطوح بهترین قیمت به سرعت استخراج شوند.
  • دسترسی زمان ثابت به بهترین قیمت (BBO - Best Bid and Offer): الگوریتم‌ها بیش از ۹۰٪ اوقات فقط با لایه اول دفترچه (بهترین خرید و فروش) کار دارند؛ بنابراین بازگرداندن BBO باید زمان ثابت ($O(1)$) داشته باشد.

ترفندهای مهندسی سطح پایین در ++C:

  1. آرایه انجمنی عظیم: نگاشت شناسه سفارش به متادیتای آن در یک std::unordered_map یا یک std::vector بزرگ.
  2. ارجاع مستقیم: متادیتای سفارش شامل ارجاع مستقیم به دفترچه و سطح قیمتی مربوطه است؛ بنابراین پیدا کردن سطح قیمت تنها با یک ارجاع ساده (Single Dereference) حافظه انجام می‌شود و عمل کاستن حجم ($O(1)$) است.
  3. استفاده از بردار (std::vector) به جای درخت در سطوح قیمت:
    • از آنجا که عمده تغییرات در لایه‌های ابتدایی (نزدیک به داخل دفترچه) رخ می‌دهد، نگهداری سطوح قیمت در یک وکتور و جستجوی خطی (Linear Search) از انتهای وکتور به طور میانگین از جستجوی دودویی (Binary Search) سریع‌تر است!
    • دلیل: جستجوی خطی در حافظه پیوسته برای پیش‌بینی‌کننده انشعاب CPU (Branch Predictor)، بهینه‌ساز کامپایلر و کش پردازنده (CPU Cache & TLB) بسیار سازگارتر است و از Cache Miss جلوگیری می‌کند. در بدترین حالت ممکن یک کپی سریع حافظه (memcpy) رخ می‌دهد، اما رفتار میانگین به شدت به $O(1)$ نزدیک است.

۵. تصمیم‌گیری استراتژی برای معامله (Trading Strategy)

استراتژی مغز متفکر سیستم است؛ جایی که الگوریتم معاملاتی شما جان می‌گیرد.

استراتژی به دو بخش کاملاً مجزا تقسیم می‌شود:

  1. بخش سیگنال (Signal Component): این بخش صرفاً به کشف فرصت‌ها و تولید سیگنال‌های خرید یا فروش می‌پردازد. با این حال، داشتن سیگنال هرگز به معنای تضمین دریافت نقدینگی نیست؛ در سرعت‌های بالای HFT، سفارش‌های شما بارها به دلیل رسیدن دیرتر به صرافی رد می‌شوند.
  2. بخش اجرا (Execution Component): این بخش مدیریت بازخوردها و پاسخ‌های دریافتی از بازار را به دست می‌گیرد. مثلاً اگر سفارش رد شد، فوراً تصمیم می‌گیرد که آیا تلاش برای شکار نقدینگی در قیمت دیگری ادامه یابد یا متوقف شود.

۶. سیستم مدیریت سفارشات (The OMS - Order Management System)

سیستم OMS تمام سفارش‌های تولیدشده توسط استراتژی را جمع‌آوری کرده و کل چرخه حیات آن‌ها را زیر نظر می‌گیرد:

وظایف حیاتی OMS:

  • پایش مراحل سفارش: ایجاد (Creation)، اجرا (Execution)، اصلاح (Amendment)، ابطال (Cancelation) و رد شدن (Rejection).
  • فیلتر و اعتبارسنجی پیش از ارسال (Pre-trade Risk Validation): اگر سفارشی ناقص یا نامعتبر باشد (مثلاً حجم بیش از حد مجاز، جهت معکوس اشتباه، قیمت‌های پرت، انباشت موقعیت فراتر از سقف مجاز، یا نوع سفارشی که توسط صرافی پشتیبانی نمی‌شود)، OMS آن را در همان داخل سیستم فوراً رد می‌کند (Internal Rejection).
  • فایده این رد درون‌سازمانی این است که پیام اصلاً از کارت شبکه خارج نمی‌شود و در نتیجه استراتژی بسیار سریع‌تر از زمانی که سفارش تا صرافی برود و صرافی آن را پس بزند، متوجه خطا شده و واکنش نشان می‌دهد.

۷. اجزای بحرانی در برابر اجزای غیربحرانی سیستم

اجزای بحرانی (Critical Components)

شامل: درگاه‌ها (Gateways)، دفترچه‌ساز (Book Builder)، استراتژی‌ها (Strategies) و سامانه مدیریت سفارش (OMS). این چهار جزء زنجیره مستقیم تصمیم تا اجرای معامله را تشکیل می‌دهند.

  • معیار سنجش کارایی (Tick-to-Trade): از لحظه‌ای که یک تیک به‌روزرسانی قیمت وارد شبکه سیستم معاملاتی می‌شود یک تایمر شروع به کار می‌کند؛ به محض آنکه سفارش ناشی از این قیمت از سیستم خارج شود، تایمر متوقف می‌گردد. به این فاصله زمانی حساس، Tick-to-Trade یا Tick-to-Order می‌گویند.

اجزای غیربحرانی و سرویس‌های پشتیبان (Non-Critical Components)

این اجزا مستقیماً در تصمیم‌گیری میلی‌ثانیه‌ای سفارش دخیل نیستند، بلکه وظیفه تغییر پارامترها، ثبت وقایع و گزارش‌دهی را دارند.

سامانه دستور و کنترل (Command and Control)

پل ارتباطی میان معامله‌گران انسانی و سامانه معاملاتی است؛ این بخش می‌تواند یک واسط خط فرمان (CLI) یا یک رابط گرافیکی (GUI) باشد که دستورات تنظیمی تریدر را به ماژول‌های سیستم می‌رساند:

سایر سرویس‌های جانبی مهم:

  • سرور موقعیت و دارایی (Position Server): ثبت پیوسته تمام معاملات و ارزش اسمی دارایی‌ها. برای مثال، اگر معامله‌ای به حجم ۱۰۰٬۰۰۰ یورو/دلار در نرخ ۱.۲ انجام شود، ارزش اسمی پوزیشن ۱۲۰٬۰۰۰ دلار ثبت می‌شود. اگر سقف موقعیت یک دارایی ۲۰۰٬۰۰۰ دلار تعیین شده باشد، سرور پوزیشن از ارسال سفارش‌های بعدی که سقف را رد کنند ممانعت به عمل می‌آورد.
  • سیستم لاگ‌گیری (Logging System): گردآوری تمامی گزارش‌ها و ثبت در فایل یا پایگاه داده برای خطایابی، بازبینی اتفاقات، کشف علل مشکلات و گزارش‌دهی مالی بدون اینکه سرعت مسیر بحرانی را کُند کند.
  • نمایشگرهای پایش (Viewers): صفحات دیداری فقط‌خواندنی برای نمایش زنده وضعیت سفارش‌ها، پوزیشن‌ها و وظایف سیستم.
  • نمایشگرهای کنترلی (Control Viewers): پنل‌های تعاملی برای شروع/توقف ماژول‌ها و تغییر پارامترهای استراتژی در لحظه.
  • سرور اخبار (News Server): دریافت خوراک اخبار لحظه‌ای از خبرگزاری‌های معتبر (مانند Bloomberg، Reuters و RavenPack) و مخابره آنی آن به سیستم استراتژی.

خلاصه و جمع‌بندی فصل دوم (Summary)

در این فصل، ساختار معماری و کلیه اجزای لازم برای طراحی یک سیستم معاملاتی از ابتدا فراگرفته شد:

  1. درگاه‌ها (Gateways) بار سنگین ارتباط شبکه‌ای و مدیریت پروتکل‌ها را به دوش می‌کشند.
  2. دفترچه‌ساز (Book Builder) با استفاده از ساختارهای داده هماهنگ با سخت‌افزار و کش CPU، وضعیت لحظه‌ای بازار را با کمترین تاخیر بازسازی می‌کند.
  3. استراتژی تصمیم‌گیری کرده و سیستم مدیریت سفارش (OMS) سلامت و اعتبار چرخه حیات سفارشات را تضمین می‌کند.

در فصل بعدی (03 - پویایی صرافی و هسته تطبیق)، با ورود به سمت دیگر بازار، کارکرد درونی صرافی‌ها و موتور تطبیق (Matching Engine) را موشکافی خواهیم کرد.

پویایی صرافی و هسته تطبیق

(Understanding the Trading Exchange Dynamics)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۵۷ تا ۷۰


مقدمه

در فصل دوم، نحوه ایجاد سیستم‌های معاملات فرکانس بالا (HFT) و اجزای حیاتی آن‌ها را مورد بررسی قرار دادیم. همچنین نحوه ساخت دفترچه سفارشات (Order Book) را آموختیم که در واقع نسخه‌ای بازسازی‌شده از همان اطلاعاتی است که صرافی از کلیه شرکت‌کنندگان بازار جمع‌آوری می‌کند.

در این فصل، به بررسی عمیق کارکرد درونی بورس و صرافی (Exchange) خواهیم پرداخت. اجزای عملکردی یک بورس را تشریح کرده و تمرکز ویژه‌ای بر موتور تطبیق سفارشات (Matching Engine) خواهیم داشت. درک سازوکار تطبیق سفارش‌ها در صرافی، یکی از حیاتی‌ترین مهارت‌هایی است که برای تدوین استراتژی‌های سودآور HFT به آن نیاز خواهید داشت؛ چرا که پیروزی و شکست در این بازارها در کسری از نانوثانیه رقم می‌خورد.

این فصل مباحث زیر را پوشش می‌دهد:

  • شناخت ماهیت و نقش صرافی‌های معاملاتی
  • معماری فنی صرافی برای پردازش انبوه سفارش‌ها
  • بررسی جامع موتور تطبیق و سناریوهای اجرای سفارش
  • الگوریتم‌های تطبیق: FIFO، تسهیم تناسبی (Pro-Rata) و مدل‌های هیبریدی

۱. معماری صرافی برای پردازش سفارش‌ها در مقیاس کلان

بورس‌های سهام بازارهایی هستند که در آن‌ها مالکان فعلی سهام با خریداران بالقوه دادوستد می‌کنند. صرافی‌ها بازارهای ثانویه یا ثالثیه هستند (نه بازار اولیه). شرکت‌هایی که سهام آن‌ها در بورس معامله می‌شود، هر روز سهام خود را نمی‌خرند و نمی‌فروشند؛ آن‌ها تنها در مواقع نیاز به افزایش سرمایه اقدام به انتشار سهام جدید می‌کنند یا در موارد خاص سهام خود را بازخرید می‌نمایند. در یک بورس، شما همواره سهم را از سهامدار دیگری می‌خرید و هنگام فروش نیز آن را به سرمایه‌گذار دیگری واگذار می‌کنید.

تاریخچه صرافی‌های معاملاتی (History of Trading Exchanges)

  • قرن‌های ۱۶ و ۱۷ میلادی در اروپا: نخستین بورس‌های جهان در شهرهای بندری و مراکز بازرگانی نظیر آنتورپ، آمستردام و لندن پدیدار شدند. با این حال، از آنجا که شمار اندکی از شرکت‌ها سهام منتشر می‌کردند، این بازارهای اولیه بیشتر شبیه بورس اوراق قرضه دولتی بودند و شرکت‌ها ماهیتی شبه‌دولتی داشتند.
  • اواخر قرن ۱۸ در آمریکا: بورس فیلادلفیا (PHLX) به عنوان نخستین بورس آمریکا آغاز به کار کرد. اندکی بعد در سال ۱۷۹۲ با امضای توافق‌نامه تاریخی و قانون بورس سهام نیویورک، NYSE متولد شد.
  • عصر مدرن: با ورود مقررات و استانداردهای حرفه‌ای، اطمینان خریداران و فروشندگان از انجام معاملات با قیمت منصفانه و در زمان معقول جلب شد. امروزه ده‌ها بورس در آمریکا و سراسر جهان به صورت کاملاً الکترونیکی به یکدیگر متصل هستند که حاصل آن کارایی و نقدینگی فوق‌العاده بازارهاست.

تعیین قیمت در بورس:

قیمت‌ها در بورس از طریق سازوکار حراج پیوسته (Continuous Auction) مشخص می‌شوند. خریداران با ثبت قیمت خرید (Bid) و فروشندگان با ثبت قیمت فروش (Offer یا Ask) به رقابت می‌پردازند؛ و در لحظه‌ای که بالاترین قیمت خرید با پایین‌ترین قیمت فروش برابر شود، معامله نهایی می‌گردد.


۲. ویژگی‌ها و اجزای عملکردی یک صرافی (Features of an Exchange)

یک بورس مدرن نهادی چندبعدی است که بازیگران بازار را گرد هم می‌آورد تا ریسک‌ها را کاهش داده، معاملات را تسهیل کند و در کشف قیمت (Price Discovery) نقش داشته باشد. ارکان اصلی یک صرافی عبارتند از:

  1. پذیرش شرکت‌ها (Listings): شرکت‌های سهامی که با طی مراحل عرضه اولیه (IPO) عمومی شده‌اند. عواملی همچون ارزش‌گذاری، نقدینگی و هزینه‌های انطباق در انتخاب بورس برای عرضه سهام تعیین‌کننده‌اند.
  2. موتور تطبیق (Matching Engine): جایگزین دیجیتالی تالارهای قدیمی (Pit) که کارگزاران در آن با فریاد زدن سفارش‌ها را تبادل می‌کردند. این موتور تمام‌الکترونیکی، سفارش‌های باز را در دفترچه منتشر کرده و سفارش‌های منطبق را در مقیاس نانوثانیه به معامله تبدیل می‌کند.
  3. فرآیندهای پس از معامله (Post-Trade): عملیات پرداختی، پایاپای و تسویه نهایی (Settlement & Clearing) و تطبیق مغایرت‌ها (Reconciliation) که تضمین می‌کند وجوه و دارایی‌ها بدون خطا جابه‌جا شوند.
  4. تجارت داده‌های بازار (Market Data): صرافی حجم عظیمی از داده‌های معاملاتی، عمق دفترچه، اعلان‌ها و شاخص‌ها را تولید می‌کند و به شرکت‌های معاملاتی می‌فروشد. همچنین با ارائه خدمات هم‌مکانی (Colocation)، سرعت دستیابی به این داده‌ها را به بالاترین قیمت به غول‌های HFT عرضه می‌کند.
  5. مشارکت‌کنندگان بازار (Market Participants):
    • اعضای معامله‌گر (Trading Members): کارگزاران و شرکت‌های معاملات اختصاصی (Prop firms).
    • اعضای تسویه (Clearing Members): نهادهای بزرگ مالی با استانداردهای سرمایه‌ای سخت‌گیرانه.
    • وثیقه‌گذاری (Collateral): کلیه اعضا باید نزد صرافی وثیقه بگذارند تا در صورت ورشکستگی یا تخلف یک طرف، صرافی با تکیه بر این وثایق خسارت طرف مقابل را جبران کرده و پایداری بازار را حفظ کند.
  6. مقررات و نظارت (Regulation): جلوگیری از پولشویی، مقابله با معاملات متکی بر اطلاعات نهانی (Insider Trading) و دستکاری بازار، به همراه الزام شرکت‌ها به شفافیت و افشای به‌موقع اطلاعات.

نیازمندی‌های معماری فنی صرافی

سیستم صرافی باید الزامات تجاری زیر را برآورده سازد:

  • پشتیبانی از بخش‌های Front، Middle و Back Office.
  • ارائه رابط‌های کاربری معاملاتی (Desktop، وب و موبایل).
  • پشتیبانی از مدل تجاری Trading as a Service (TaaS) از طریق APIهای استاندارد (نظیر FIX).
  • مقیاس‌پذیری فوق‌العاده بالا برای مدیریت میلیون‌ها پیام در ثانیه.

بررسی معماری صرافی (Exchange Architecture Diagram)

در تصویر زیر، معماری درونی یک صرافی به همراه صف‌های تفکیک‌شده برای نمادهای تسلا، مایکروسافت و اپل نمایش داده شده است:

مراحل پردازش سفارش در صرافی:

  1. سیستم معاملاتی تریدر (مانند T1) دو کانال اتصال با صرافی برقرار می‌کند: یکی برای دریافت تغییرات قیمت و دیگری برای ارسال سفارش‌ها.
  2. به محض ورود سفارش به بورس، بسته به کلاس دارایی و نماد مربوطه، به صف‌های پردازشی اختصاصی (Queues) هدایت می‌شود؛ هر صف برای یک سطح قیمتی و یک نماد مشخص ایجاد شده است.
  3. موتور تطبیق سفارش‌ها را یکی‌یکی (One at a time) برمی‌دارد و پردازش می‌کند.
  4. در صورت بروز هرگونه تغییر در دفترچه سفارشات، این تغییر فوراً به تریدر فرستنده اعلام شده و همزمان برای تمامی فعالان بازار و بخش تسویه (Clearing) مخابره می‌شود.
ضرورت استفاده از پروتکل‌های باینری

به دلیل لزوم دستیابی به تاخیرهای زیر میکروثانیه، پروتکل‌های متنی نظیر FIX به تنهایی برای ارسال سفارش در HFT کارآمد نیستند و بورس‌های پیشرو جهان از پروتکل‌های باینری اختصاصی (Binary Protocols) بهره می‌برند تا سربار تبدیل متن و پارس کردن رشته‌ها در CPU حذف شود.


۳. کارکرد درونی موتور تطبیق (General Order Book & Matching Engine)

در گذشته تطبیق سفارش‌ها به صورت سنتی و با فریاد و علائم دست در تالار معاملات (Open Outcry) انجام می‌شد، اما سامانه‌های رایانه‌ای مدرن این فرآیند را خودکار کرده و سرعت معاملات را به بالاترین سطح و هزینه‌ها را به حداقل رسانده‌اند.

سازوکار موتور تطبیق در تصویر زیر خلاصه شده است:

  • ورودی‌ها:
    1. سفارش جدید ورودی (Incoming Order) از سوی تریدر
    2. دفترچه سفارشات فعلی صرافی (Order Book)
  • خروجی‌ها: 3. فهرست معاملات نهایی‌شده (Trades) 4. فهرست سفارش‌های باقیمانده در دفترچه (Resting Orders)

۴. سناریوهای تطبیق سفارش در بورس

برای درک رفتار موتور صرافی، بررسی سناریوهای پایه زیر ضروری است:

۱. سناریوی بهترین قیمت (Best Price Scenario)

موتور تطبیق همواره سفارش ورودی را با بهترین قیمت در دسترس جفت می‌کند:

  • شرح سناریو: یک سفارش خرید (سفارش شماره ۱) با قیمت ۱۰۰ دلار وارد صرافی می‌شود.
  • در سمت فروش دفترچه، دو سفارش شماره ۲ (قیمت ۱۰۰ دلار) و شماره ۳ (قیمت ۹۹ دلار) قرار دارند.
  • از آنجا که خرید در ۹۹ دلار برای خریدار ارزان‌تر و سودآورتر است، موتور سفارش شماره ۱ را با سفارش شماره ۳ در قیمت ۹۹ دلار جفت می‌کند و معامله انجام می‌شود. سفارش شماره ۲ در دفترچه دست‌نخورده باقی می‌ماند.

۲. سناریوی پر شدن جزئی (Partial Fill Scenario)

زمانی رخ می‌دهد که حجم سفارش ورودی با حجم سفارش‌های مقابل برابر نباشد:

  • شرح سناریو: سفارش شماره ۱ برای خرید ۴ سهم وارد می‌شود.
  • در دفترچه، سفارش‌های شماره ۳ و ۲ روی هم تنها ۳ سهم برای فروش دارند.
  • نتیجه: سفارش‌های ۳ و ۲ کاملاً پر و بسته می‌شوند؛ اما ۱ سهم باقیمانده از سفارش شماره ۱ به عنوان سفارش فعال (Resting Order) در دفترچه سفارشات می‌نشیند تا فروشنده دیگری وارد بازار شود.

۳. سناریوی عدم تطبیق (No Match Scenario)

  • شرح سناریو: خریدار قیمتی معادل ۹۸ دلار پیشنهاد می‌دهد، اما پایین‌ترین فروشنده در دفترچه در ۹۹ دلار نشسته است.
  • به دلیل عدم توافق قیمتی ($Bid < Ask$)، هیچ معامله‌ای انجام نمی‌شود و سفارش شماره ۱ مستقیماً وارد دفترچه می‌شود.

۴. سفارش‌های متعدد در قیمت یکسان (Multiple Orders with Same Price)

هنگامی که چند معامله‌گر سفارشی با قیمت دقیقاً یکسان ثبت کرده باشند، موتور تطبیق چگونه اولویت‌بندی می‌کند؟

روش تقسیم و اجرا کاملاً به الگوریتم انتخابی صرافی بستگی دارد که در بخش بعدی تشریح شده‌اند.


۵. انواع الگوریتم‌های تطبیق سفارش در صرافی‌ها

الگوریتم موتور تطبیق، تعیین‌کننده نوع رفتار و اکوسیستم معامله‌گران در آن صرافی است:

۱. الگوریتم اولویت زمان/قیمت یا FIFO (First In, First Out)

این متداول‌ترین الگوریتم در بورس‌های سهام جهان است.

  • مکانیزم: تمام سفارش‌ها به محض ورود به موتور با دقت نانوثانیه برچسب زمانی (Timestamp) می‌خورند؛ بنابراین هیچ دو سفارشی زمان ورود یکسان ندارند.
  • هر سفارشی که زودتر ثبت شده باشد، زودتر اجرا می‌شود. در شکل، سفارش شماره ۳ قدیمی‌تر از سفارش شماره ۲ است؛ بنابراین سفارش ورودی شماره ۱ با سفارش شماره ۳ جفت می‌شود.
قانون سوختن اولویت صف در FIFO

در بورس‌های مبتنی بر FIFO، هرگونه تغییر قیمت در سفارش منجر به از دست رفتن قطعی اولویت زمانی و پرتاب به انتهای صف می‌شود. در بسیاری از بورس‌ها، حتی افزایش حجم سفارش نیز اولویت زمانی را می‌سوزاند؛ به همین دلیل الگوریتم‌های HFT سفارش‌های قبلی را به ندرت ویرایش می‌کنند و ترجیح می‌دهند با محاسبات دقیق از ابتدا سفارش را درست ثبت نمایند.


۲. الگوریتم تناسبی خالص (Pure Pro-Rata)

در برخی بازارها (به‌ویژه بازارهای مشتقات، بهره و اوراق)، صرافی برای خنثی کردن مزیت سرعت شرکت‌های HFT و جذب معامله‌گران نهادی سنگین، از مدل تسهیم به نسبت (Pro-Rata) استفاده می‌کند:

  • مکانیزم: سفارش ورودی میان تمام سفارش‌های مقابل در آن سطح قیمت، به نسبت اندازه سفارش آن‌ها تقسیم می‌شود؛ بدون در نظر گرفتن زمان ورود (Timestamp)!
  • فرمول تخصیص: $$\text{سهم هر سفارش} = \text{حجم سفارش ورودی} \times \left( \frac{\text{حجم سفارش معامله‌گر}}{\text{کل حجم موجود در آن قیمت}} \right)$$
  • در شکل ۳.۸، سفارش خرید ۱۰۰ دلاری به صورت مساوی یا متناسب میان دو سفارش در صف تقسیم می‌شود تا مشارکت‌کنندگان کندتر اما حجیم احساس امنیت کنند.

۳. الگوریتم هیبریدی Pro-Rata با اولویت سفارش اول (Pro-Rata with Top-Order)

  • مکانیزم: در این مدل ترکیبی، قدیمی‌ترین سفارش در صف (اولین ورودی از نظر زمان) به طور ۱۰۰٪ کامل پر می‌شود تا پاداش سرعت حفظ شود؛ سپس باقیمانده حجم سفارش ورودی میان سایر سفارش‌های موجود بر اساس فرمول تناسبی (Pro-Rata) توزیع می‌گردد.
  • همچنین بورس‌ها می‌توانند ضرایب وزنی به حجم‌های بزرگتر اضافه کنند تا مشوق‌های نقدینگی تقویت شوند.

خلاصه و جمع‌بندی فصل سوم (Summary)

  1. در معاملات HFT، حتی یک نانوثانیه می‌تواند تفاوت سود و زیان باشد. شناخت عمیق از ریزساختار بازار (Microstructure)، صف‌های اولویت و منطق موتور تطبیق برای طراحی الگوریتم‌های موفق الزامی است.
  2. دانستیم که ویرایش قیمت در مدل FIFO اولویت زمانی را می‌سوزاند و بورس‌ها با الگوریتم‌های گوناگون (FIFO یا Pro-Rata) الگوهای رفتاری متفاوتی را تشویق می‌کنند.
  3. با پایان فصل سوم، بخش اول کتاب (Trading Strategies, Trading Systems, and Exchanges) تکمیل گردید. در بخش دوم و فصل چهارم (04 - زیرساخت سخت‌افزار و OS) وارد لایه‌های بنیادین سخت‌افزار کامپیوتر، پردازنده‌ها و مدیریت سیستم‌عامل برای بهینه‌سازی سرعت خواهیم شد.

زیرساخت سخت‌افزار و سیستم‌عامل

(HFT System Foundations – From Hardware to OS)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۷۳ تا ۹۲ بخش دوم کتاب: چگونه یک سیستم معاملات فرکانس بالا را معماری کنیم؟ (Part 2)


مقدمه

برای آنکه یک استراتژی معاملاتی کم‌تاخیر (Low-Latency) به درستی عمل کند، درک نحوه تعامل نرم‌افزار با سیستم‌عامل و سخت‌افزار کامپیوتر ضروری است. عملکرد مناسب تنها زمانی حاصل می‌شود که تمام این لایه‌ها در هماهنگی کامل باشند. در فصل‌های آتی، با اعمال تکنیک‌های بهینه‌سازی پیشرفته، تاخیر زمانی سیستم را به کمتر از ۱۰ میکروثانیه خواهیم رساند.

اگر خواهان مطالعه فوق‌تخصصی درباره معماری کامپیوتر هستید، کتاب کلاسیک Computer Architecture: A Quantitative Approach نوشته جان هنسی و دیوید پترسون مرجع بی‌نظیری است. در این فصل، ما منحصراً بر بخش‌هایی از سخت‌افزار و سیستم‌عامل تمرکز می‌کنیم که یک سیستم HFT برای حیات و برتری به آن‌ها نیازمند است:

  • شناخت سخت‌افزار رایانه‌های HFT
  • معماری پردازنده‌ها، هسته‌ها و حافظه‌های اشتراکی NUMA
  • سلسله‌مراتب کش‌های L1، L2 و L3
  • تعامل با سیستم‌عامل، فضای کاربر در برابر کرنل و سوئیچ کانتکست
  • مدیریت حافظه، بافر TLB و صفحات غول‌پیکر (Huge Pages)
  • نقش کامپایلرها، بهینه‌سازی حلقه‌ها و پیوند ایستا (Static Linking)

۱. شناخت رایانه‌های HFT (Understanding HFT Computers)

شاید تصور کنید برای راه‌اندازی معاملات فرکانس بالا حتماً به کامپیوترهای سفارشی عجیب‌وغریب نیاز دارید؛ اما واقعیت این است که در اکثر موارد از سخت‌افزارهای تجاری استاندارد بازار (Off-the-shelf Hardware) استفاده می‌شود. آنچه تمایز ایجاد می‌کند، نحوه پیکربندی و درک عمیق از معماری این سخت‌افزارهاست.

تصویر زیر نگاه یک مهندس HFT به ساختار یک واحد پردازش مرکزی (CPU) را نشان می‌دهد:

مسیر جریان داده در رایانه HFT:

هدف اصلی سرور در یک سیستم HFT، انجام وظایف پایه‌ای معاملاتی است: دریافت داده‌های بازار، اجرای مدل‌های الگوریتمی، و ارسال سفارش به صرافی.

  1. بسته‌های داده (Packets) از طریق کابل فیزیکی وارد کارت شبکه (NIC) می‌شوند.
  2. کارت شبکه بسته‌ها را درون حافظه رم (Host Memory) قرار می‌دهد.
  3. پردازنده مرکزی (CPU) تکه‌های داده را از رم به درون حافظه‌های نهان (Caches) می‌کشد تا هسته‌های پردازشی بتوانند محتوای بسته را رمزگشایی کرده و فوراً تصمیم‌گیری کنند. برای دستیابی به تاخیر کم، باید مسیر حرکت این بایت‌ها را در لایه‌های سخت‌افزار به دقت مهندسی کرد.

۲. تکامل پردازنده‌ها: از چندپردازنده‌ای تا چندهسته‌ای

یک پردازنده (CPU) مجموعه‌ای از یک یا چند هسته پردازشی است که دستورالعمل‌های برنامه را واکشی (Fetch) و اجرا (Execute) می‌کنند. در گذشته، برای پردازش چندگانه باید چندین چیپ فیزیکی مجزا روی مادربورد نصب می‌شد. با رسیدن قانون مور (Moore’s Law) به محدودیت‌های فیزیکی مصرف توان و حرارت (Dennard Scaling)، سازندگان پردازنده‌ها به جای افزایش سرسام‌آور فرکانس، چندین هسته را روی یک دای سیلیکونی واحد (Multi-core on a single die) و امروزه درون چیپلت‌ها (Chiplets) قرار دادند.

هسته پردازنده در انجام عملیات منطقی و محاسباتی ریز فوق‌العاده سریع است؛ از جمع و تفریق ساده گرفته تا دستورات شتاب‌یافته سخت‌افزاری اختصاصی نظیر CRC32، مراحل رمزنگاری AES و ضرب‌های بدون انتقال مانند PCLMUQDQ.

چالش تک‌هسته‌ای در برابر چندهسته‌ای در HFT:

هنگامی که دیتای بازار می‌رسد، داده باید پارس شود، به دفترچه سفارشات ارسال شود و به استراتژی برسد. اگر سیستم تنها با یک هسته کار کند، تمام این اعمال باید به صورت متوالی (Sequential) انجام شوند؛ یعنی یک بسته باید کاملاً تمام شود تا بسته بعدی پردازش گردد. این امر باعث ایجاد صف طویل بسته‌ها و افزایش تاخیر می‌شود. برای حل این مشکل، نیازمند واحدهای پردازشی متعددی هستیم که بتوانند به صورت موازی داده‌ها را دست‌به‌دست کنند.


معماری حافظه غیریکنواخت: NUMA (Non-Uniform Memory Access)

در سرورهای مدرن، چند سوکت پردازنده روی مادربورد قرار دارد. به معماری سرورهای چندسوکت امروزی NUMA می‌گویند:

مفاهیم کلیدی NUMA:

  • حافظه محلی (Local Resource): هر سوکت پردازنده، مستقیماً به بانک حافظه RAM و اسلات‌های PCIe اختصاصی خود متصل است. دسترسی پردازنده به رم محلی خود در بالاترین سرعت انجام می‌شود.
  • حافظه از راه دور (Remote Resource): اگر یک پردازنده بخواهد به داده‌های موجود در رم متصل به یک پردازنده دیگر دسترسی یابد، باید از گذرگاه‌های پرسرعت بین‌پردازنده‌ای (نظیر Intel UPI یا AMD Infinity Fabric) عبور کند. این دسترسی به شدت کندتر از دسترسی محلی است (دسترسی غیریکنواخت).
  • سیستم‌های ccNUMA: اصطلاح Cache-Coherent NUMA تضمین می‌کند که داده‌های حافظه همواره بین هسته‌های مختلف یکپارچه و معتبر بمانند.
دام بزرگ هایپرتردینگ (Hyper-Threading / SMT)

فناوری Hyper-Threading باعث می‌شود هر هسته فیزیکی مانند دو هسته مجازی به نظر برسد. هنگامی که یک نخ منتظر رویدادی کند (مثل واکشی از RAM) بماند، هسته به اجرای نخ دوم سوئیچ می‌کند. با اینکه این کار ظرفیت کلی سرورهای عادی را بالا می‌برد، اما در HFT یک تاخیر غیرقابل‌پیش‌بینی شبیه کانتکست سوئیچ سخت‌افزاری ایجاد می‌کند؛ به همین دلیل در سیستم‌های جدی معاملات فرکانس بالا، Hyper-Threading در تنظیمات BIOS غیرفعال (Disable) می‌شود تا هر هسته ۱۰۰٪ ظرفیت خود را منحصراً به نخ حیاتی معاملاتی اختصاص دهد.


۳. سلسله‌مراتب حافظه و کش‌های پردازنده (Memory & Caches)

سرعت پردازنده در مقیاس گیگاهرتز عمل می‌کند (هر چرخه کلاک کمتر از ۰.۳ نانوثانیه)، در حالی که دسترسی به حافظه اصلی RAM صدها چرخه کلاک زمان می‌برد؛ شکافی که به دیوار حافظه (Memory Wall) معروف است. پردازنده‌ها برای حل این شکاف از سلسله‌مراتب حافظه نهان (کش) استفاده می‌کنند.

خط کش (Cache Line):

پردازنده هرگز تک‌بایت را از حافظه بارگذاری نمی‌کند، بلکه داده‌ها را در بلوک‌های متوالی ۶۴ بایتی به نام Cache Line به درون کش منتقل می‌کند:

سطوح سه‌گانه حافظه نهان:

  1. کش سطح یک (L1 Cache):
    • سریع‌ترین حافظه سیستم که چسبیده به واحدهای اجرایی هسته است.
    • به دو بخش مجزا تقسیم می‌شود: L1 Instruction (کش دستورالعمل‌ها) و L1 Data (کش داده‌ها).
    • سرعت آن حدود ۱۰۰ برابر سریع‌تر از حافظه رم اصلی است.
  2. کش سطح دو (L2 Cache):
    • بزرگ‌تر از L1 (بین ۲۵۶ کیلوبایت تا چند مگابایت)، اما اندکی کندتر از آن.
    • اختصاصی برای همان هسته فیزیکی بوده و حدود ۲۵ برابر سریع‌تر از RAM است.
  3. کش سطح سه (L3 Cache):
    • بزرگ‌ترین و کندترین لایه کش پردازنده که میان تمام هسته‌های پردازنده به اشتراک گذاشته می‌شود.
    • به عنوان یک Victim Cache عمل می‌کند؛ خطوط داده‌ای که از کش‌های L1 و L2 بیرون رانده می‌شوند، پیش از ارسال به RAM اصلی ابتدا در L3 ذخیره می‌گردند.

مدل‌های حافظه اشتراکی: UMA در برابر NUMA

  • در مدل‌های قدیمی UMA (Uniform Memory Access)، تمام پردازنده‌ها از یک کنترلر حافظه و گذرگاه مشترک استفاده می‌کردند که با افزایش هسته‌ها، گذرگاه به شدت مسدود شده و گلوگاه عملکردی می‌شد.
  • در مدل NUMA، هر پردازنده کنترلر حافظه خود را دارد و مقیاس‌پذیری بسیار بهتر است؛ اما چالش پروتکل‌های انسجام کش (Cache Coherency) به وجود می‌آید. برنامه باید طوری نوشته شود که تبادل داده بین سوکت‌های مختلف به حداقل برسد.

دستگاه‌های ورودی/خروجی و موقعیت کارت شبکه (PCIe)

دستگاه‌های I/O مانند کارت شبکه از طریق گذرگاه PCI Express (PCIe) مستقیماً به یک پردازنده خاص در معماری NUMA وصل می‌شوند:

اصل طلایی پین کردن کارت شبکه در HFT

هنگام توسعه درگاه دریافت داده بازار (Market Data Gateway)، فرآیند نرم‌افزاری شما باید دقیقاً روی همان هسته‌های پردازنده‌ای اجرا شود که کارت شبکه (NIC) فیزیکاً به اسلات PCIe آن سوکت متصل است؛ در غیر این صورت پکت‌های داده برای رسیدن به نرم‌افزار مجبورند از گذرگاه بین‌سوکت‌ها عبور کنند و تاخیرهای مرگبار میکروثانیه‌ای به سیستم تحمیل خواهد شد!

همچنین دیسک‌های سخت به دلیل کندی مطلق، در مسیر پردازش زنده بازار هرگز خوانده یا نوشته نمی‌شوند و تنها برای بک‌تست‌های تاریخی کاربرد دارند.


۴. بهره‌گیری از سیستم‌عامل برای سیستم‌های HFT

سیستم‌عامل (OS) به عنوان لایه انتزاعی میان نرم‌افزار و سخت‌افزار عمل می‌کند. در HFT رویکرد مهندسی بر این است که این لایه‌های انتزاعی را تا جای ممکن بشکنیم و مستقیماً با سخت‌افزار گفتگو کنیم.

وظایف اصلی سیستم‌عامل شامل: انتزاع منابع، زمان‌بندی فرآیندها، مدیریت حافظه، مدیریت فایل‌ها و دستگاه‌ها، و مدیریت وقفه (Interrupts).

فضای کاربر (User Space) در برابر فضای هسته (Kernel Space)

  • کرنل (Kernel): هسته دارای بالاترین سطح دسترسی سیستمی است که درایورها، پشته شبکه و دسترسی مستقیم به حافظه فیزیکی را در دست دارد.
  • فضای کاربر (User Space): برنامه‌های ما (سیستم معاملاتی) در فضای کاربر اجرا می‌شوند. هرگونه درخواست ارتباط با سخت‌افزار معمولاً نیازمند عبور از کرنل و یک تعویض زمینه (Context Switch) پرهزینه است که چرخه‌های گرانبهای CPU را تلف می‌کند.

زمان‌بندی فرآیندها (Process Scheduling)

در سیستم‌عامل‌های استاندارد مانند لینوکس، زمان‌بند (Scheduler) زمان پردازنده را با الگوریتم‌هایی نظیر CFS میان صدها فرآیند به صورت عادلانه در قالب برش‌های زمانی (Timeslices) تقسیم می‌کند.

  • در سیستم‌های بلادرنگ و HFT، از سیاست‌های زمان‌بندی با اولویت بالا نظیر SCHED_FIFO و SCHED_RR استفاده می‌شود تا تسک‌های معاملاتی بدون نوبت اجرا شوند (با مراقبت کامل برای جلوگیری از پدیده قفل یا معکوس شدن اولویت - Priority Inversion).

مدیریت حافظه، صفحات و بافر TLB

سیستم‌عامل حافظه فیزیکی را نمی‌شناسد، بلکه آن را به بلوک‌هایی استاندارد به نام صفحه (Page) با اندازه پیش‌فرض ۴ کیلوبایت تقسیم می‌کند:

  • واحد مدیریت حافظه (MMU): قطعه‌ای سخت‌افزاری در پردازنده که آدرس‌های مجازی برنامه را به آدرس‌های فیزیکی RAM ترجمه می‌کند.
  • بافر ترجمه آدرس (TLB - Translation Lookaside Buffer): کش فوق‌العاده سریع سخت‌افزاری در پردازنده که آخرین نگاشت‌های آدرس را نگهداری می‌کند.
  • اگر آدرسی در TLB پیدا نشود (TLB Cache Miss)، پردازنده باید به سراغ جدول صفحات در حافظه برود که تاخیر زیادی ایجاد می‌کند.

راهکار صفحات غول‌پیکر (Huge Pages):

در سیستم‌های HFT برای داده‌های بسیار حجیم (مانند دفترچه سفارشات)، از Huge Pages (صفحات ۲ مگابایتی یا ۱ گیگابایتی) به جای صفحات ۴ کیلوبایتی استفاده می‌شود. با بزرگ شدن صفحات، تعداد رکوردهای جدول صفحه کاهش یافته و تقریباً تمام آدرس‌ها درون TLB جا می‌گیرند و TLB Miss حذف می‌شود.


فراخوان‌های سیستمی (System Calls) و تکنولوژی مدرن vDSO

هر زمان برنامه به کرنل نیاز داشته باشد یک System Call صادر می‌کند. رفتن به کرنل و بازگشت به فضای کاربر زمان‌بر است.

  • برای خواندن فایل یا شبکه، سفر کامل به کرنل الزامی است.
  • تکنولوژی انقلابی vDSO (Virtual Dynamic Shared Object) در لینوکس: لینوکس برخی از پرکاربردترین عملکردهای کرنل (به‌ویژه دریافت ساعت دقیق سیستم با clock_gettime(CLOCK_MONOTONIC)) را مستقیماً به فضای کاربر مپ می‌کند! بدین ترتیب برنامه بدون نیاز به سوئیچ کانتکست و بدون رفتن به حالت کرنل، زمان دقیق را در حد چند نانوثانیه می‌خواند.

مدیریت وقفه (Interrupts) و پین کردن هسته‌ها (Core Pinning)

هنگام وقوع یک رویداد سخت‌افزاری (مثلاً رسیدن بسته به کارت شبکه)، یک وقفه (Interrupt) صادر می‌شود که اجرای برنامه را موقتاً متوقف می‌کند:

در مدل تک‌هسته‌ای (شکل ۴.۶)، پردازنده مداوم میان اجرای کد برنامه و مدیریت وقفه کرنل جابه‌جا می‌شود و زمان زیادی می‌سوزد.

راهکار طلایی: تفکیک هسته‌ها با دو پردازنده و پین کردن فرآیند:

همان‌طور که در شکل ۴.۷ مشاهده می‌شود:

  • با استفاده از قابلیت CPU Pinning (CPU Affinity)، فرآیند استراتژی به هسته دوم مقید (Pin) می‌شود.
  • کرنل طوری پیکربندی می‌شود که کلیه وقایع و وقفه‌های سخت‌افزاری توسط هسته اول مدیریت شوند.
  • در نتیجه، هسته دوم بدون کوچک‌ترین وقفه، کانتکست سوئیچ یا تداخلی از سوی کرنل، با سرعت ۱۰۰٪ خالص به اجرای کد استراتژی می‌پردازد.

۵. نقش کامپایلرها در معاملات فرکانس بالا (The Role of Compilers)

کامپایلرها کدهای سطح بالا (مانند ++C) را به دستورالعمل‌های اسمبلی و باینری ماشین تبدیل می‌کنند. در HFT، بیشترین زمان برنامه در حلقه‌ها (Loops) صرف می‌شود. کامپایلر با تکنیک‌های زیر زمان اجرا را به حداقل می‌رساند:

  1. باز کردن حلقه (Loop Unrolling): حذف گام‌های بررسی شرط پایان حلقه و پرش‌های شرطی؛ کاهش شدید سربار Branch Predictor پردازنده.
  2. درون‌خطی کردن توابع (Function Inlining): جایگزینی متن تابع در محل فراخوانی و حذف کامل سربار call و ret در سطح پشته اسمبلی.
  3. جداول محاسبات از پیش انجام‌شده (Pre-computed Lookup Tables): تبدیل محاسبات تکراری به آرایه‌های آماده در حافظه برای جلوگیری از پردازش مجدد.

فرمت فایل‌های اجرایی و تفاوت پیوند ایستا و پویا

در لینوکس فایل‌های اجرایی با فرمت ELF و در ویندوز با فرمت PE کامپایل می‌شوند. دو شیوه برای اتصال کتابخانه‌ها وجود دارد:

ویژگیپیوند پویا (Dynamic Linking)پیوند ایستا (Static Linking)
اندازه فایل باینریکوچک‌تر (فقط ارجاعات را نگه می‌دارد)بزرگ‌تر (تمام کد کتابخانه‌ها در باینری جا می‌گیرد)
اشتراک حافظهکد کتابخانه بین چند برنامه در رم مشترک استهر برنامه نسخه اختصاصی خود را در رم دارد
تاخیر در فراخوانی توابعکندتر؛ از طریق جدول ارجاع غیرمستقیم PLT فراخوانی می‌شودفوق‌العاده سریع؛ توابع مستقیماً فراخوانی می‌شوند
بهینه‌سازی کامپایلرامکان بهینه‌سازی بین کتابخانه‌ای وجود نداردکامپایلر با دید کلان می‌تواند LTO (Link-Time Optimization) انجام دهد
کاربرد در HFTتوصیه نمی‌شوداستاندارد مطلق سیستم‌های کم‌تاخیر HFT

خلاصه و جمع‌بندی فصل چهارم (Summary)

در این فصل، مدل ذهنی کاملی از فیزیک سخت‌افزار، معماری پردازنده و هسته سیستم‌عامل به دست آوردیم:

  1. شناخت سلسله‌مراتب کش‌های L1/L2/L3 و پرهیز از Cache Miss و خطوط ۶۴ بایتی کش.
  2. معماری NUMA و ضرورت قرار گرفتن کارت شبکه در کنار پردازنده متناظر محلی.
  3. خاموش کردن Hyper-Threading و پین کردن فرآیندهای حساس به هسته‌های ایزوله‌شده (CPU Pinning).
  4. استفاده از Huge Pages برای کاهش TLB Miss و بهره‌گیری از vDSO لینوکس برای توابع زمانی.
  5. پیوند ایستا (Static Linking) و بهینه‌سازی‌های کامپایلر.

در فصل بعدی (05 - شبکه در حرکت و پروتکل‌های تبادل)، نحوه حرکت بسته‌های شبکه با سرعت نور در سوئیچ‌ها و جزئیات پروتکل FIX و باینری را کالبدشکافی خواهیم کرد.

شبکه در حرکت و پروتکل‌های تبادل

(Networking in Motion)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۹۳ تا ۱۲۶


مقدمه

در فصل چهارم با زیرساخت‌های پردازنده، حافظه‌های NUMA، سطوح کش و سیستم‌عامل آشنا شدیم. اما در معاملات فرکانس بالا (HFT)، داده‌ها در خلاء پردازش نمی‌شوند؛ آن‌ها با سرعت نور در طول فیبرهای نوری و امواج مایکروویو میان صرافی‌ها و سیستم‌های معاملاتی در حال حرکت هستند.

این فصل به کالبدشکافی کامل زیرساخت شبکه، سوئیچ‌ها، پروتکل‌های انتقال مالی و چرخه حیات بسته‌های داده می‌پردازد. مباحث این فصل عبارتند از:

  • مدل‌های مفهومی شبکه (OSI و TCP/IP)
  • سازوکار درونی سوئیچ‌ها، صف‌بندی و حالت‌های سوئیچینگ (Cut-Through در برابر Store-and-Forward)
  • پروتکل‌های انتقال: مقایسه TCP با UDP و Multicast
  • طراحی پروتکل‌های مالی: بررسی عمیق FIX، نسخه فشرده FAST و پروتکل‌های باینری ITCH/OUCH و SBE
  • چرخه عمر بسته داده (Packet Life Cycle) از سیم فیزیکی تا کارت شبکه و پشته کرنل
  • مانیتورینگ سخت‌افزاری شبکه با Network TAP
  • همگام‌سازی زمان فوق دقیق با پروتکل‌های NTP و PTP (در مقیاس نانوثانیه)

۱. مدل‌های مفهومی شبکه (Network Conceptual Models)

برای درک رفتار شبکه، از مدل مرجع هفت لایه‌ای OSI و مدل ساده‌شده چهار لایه‌ای استفاده می‌شود:

لایه‌های حیاتی در HFT:

  1. لایه ۱ (فیزیکی - Physical): کابل‌های مسی، فیبر نوری، فرستنده‌ها و گیرنده‌های فوتونیکی، امواج مایکروویو.
  2. لایه ۲ (پیوند داده - Data Link): فریم‌های اترنت (Ethernet Frames)، مک‌آدرس‌ها (MAC Addresses) و سوئیچ‌ها.
  3. لایه ۳ (شبکه - Network): پروتکل اینترنت (IP) و مسیریابی بسته‌ها.
  4. لایه ۴ (انتقال - Transport): پروتکل‌های TCP (برقراری اتصال پایدار) و UDP (ارسال فوق‌سریع دیتاگرام).
  5. لایه کاربرد (Application): پروتکل‌های پیام‌رسانی مالی مانند FIX، ITCH، OUCH و SBE.

۲. ارتباطات شبکه‌ای و عملکرد سوئیچ‌ها در HFT

ارتباط میان سرور معاملاتی و صرافی از طریق زنجیره‌ای از گره‌ها و سوئیچ‌ها صورت می‌گیرد:

نحوه کارکرد درونی سوئیچ (Switch Architecture):

یک سوئیچ بسته را از پورت ورودی (Ingress) دریافت کرده، با جستجوی آدرس مقصد، آن را به صف پورت خروجی متناظر (Egress) هدایت می‌کند.

رابطه اندازه بسته با نرخ تبادل (Throughput vs Packet Rate):

هرچه اندازه بسته‌ها کوچک‌تر باشد، تعداد بسته‌های پردازش‌شده در هر ثانیه افزایش می‌یابد که پردازنده‌ها و سوئیچ‌ها را به شدت تحت فشار محاسباتی قرار می‌دهد.


صف‌بندی در سوئیچ و پدیده خطرناک HOL Blocking

هنگامی که حجم ترافیک ارسالی به یک پورت خروجی از پهنای باند فیزیکی آن فراتر رود، بسته‌ها در صف سوئیچ انباشته می‌شوند:

پدیده انسداد ابتدای خط (Head-of-Line / HOL Blocking)

اگر یک بسته در ابتدای صف پورت معطل بماند، مانع عبور تمام بسته‌های پشت سر خود می‌شود؛ حتی بسته‌هایی که مقصد دیگری دارند! این امر باعث تاخیرهای متغیر (Jitter)، جابه‌جا شدن ترتیب بسته‌ها و در بدترین حالت، افت پکت (Packet Drop) می‌شود. اگر بسته‌های داده‌های بازار بیفتند، بازسازی دفترچه سفارشات ناممکن شده و الگوریتم کور می‌شود.


حالت‌های سوئیچینگ: Cut-Through در برابر Store-and-Forward

سوئیچ‌ها برای ارسال یک فریم اترنت، بر اساس میزان بایتی که ابتدا باید بخوانند به سه دسته تقسیم می‌شوند:

  1. حالت Store-and-Forward:
    • سوئیچ ابتدا تمام فریم را به طور کامل دریافت می‌کند (بین ۶۴ تا ۱۵۱۸ بایت)، سپس کد کنترل خطای FCS (CRC) را محاسبه کرده و در صورت سلامت فریم، آن را فوروارد می‌کند.
    • بالاترین امنیت اما بیشترین تاخیر زمانی (نامناسب برای HFT).
  2. حالت Cut-Through Fast-Forward (استاندارد مطلق HFT):
    • سوئیچ به محض خواندن تنها ۶ بایت اول فریم (که حاوی مک‌آدرس مقصد است)، بلافاصله شروع به ارسال بایت‌ها به پورت خروجی می‌کند؛ حتی قبل از اینکه انتهای بسته به پورت ورودی رسیده باشد!
    • تاخیر در حد ده‌ها نانوثانیه؛ هیچ بررسی خطایی انجام نمی‌شود.
  3. حالت Fragment-Free:
    • سوئیچ ۶۴ بایت اول فریم را می‌خواند تا مطمئن شود بسته حاصل از تصادم الکتریکی (Collision Fragment) نیست، سپس ارسال می‌کند.

انواع سوئیچ‌ها: لایه ۱، لایه ۲ و لایه ۳

  • سوئیچ لایه ۱ (Layer 1 Switch): به عنوان یک پچ‌پنل الکترونیکی قابل برنامه‌ریزی عمل می‌کند. این دستگاه بدون خواندن هیچ هدر یا بسته‌ای، بیت‌های الکتریکی یا نوری را مستقیماً از یک پورت به پورت دیگر وصل می‌کند. تاخیر آن نزدیک به صفر (زیر ۵ نانوثانیه) است (نظیر سوئیچ‌های سری Arista 7130).
  • سوئیچ لایه ۲: بر اساس مک‌آدرس در جدول MAC کار می‌کند و خطاها را در لایه دیتا لینک فیلتر می‌کند.
  • سوئیچ لایه ۳ و NAT: سوئیچ‌هایی که کار مسیریابی IP را انجام می‌دهند. عمل ترجمه آدرس شبکه (NAT) به دلیل دستکاری هدر IP پردازنده را به شدت درگیر می‌کند و برای HFT باید حتماً در سخت‌افزار اختصاصی (ASIC) اجرا شود.

۳. مفاهیم پروتکل‌ها و لایه‌های انتقال

زیرساخت شبکه صرافی‌ها و سرورهای HFT بر بستر اترنت استوار است:

روش‌های انتشار پیام در اترنت:

  • تک‌پخشی (Unicast): ارتباط نظیر‌به‌نظیر میان یک فرستنده و یک گیرنده (شکل ۵.۹).
  • همه‌پخشی (Broadcast): ارسال پیام به تمام میزبان‌های موجود در آن شبکه محلی (شکل ۵.۱۰).
  • چندپخشی (Multicast): ارسال یک جریان داده واحد به گروهی از مشترکین علاقه‌مند (شکل ۵.۱۱).

مدیریت مالتی‌کست با IGMP Snooping

در صرافی‌ها، فید زنده داده‌های بازار از طریق Multicast پخش می‌شود. سوئیچ‌های هوشمند با استفاده از IGMP Snooping بسته‌ها را تنها به پورت‌هایی می‌فرستند که سرورهای متصل به آن‌ها رسماً عضو گروه مالتی‌کست شده باشند؛ در غیر این صورت ترافیک به اشتباه مانند Broadcast به کل شبکه سرازیر می‌شود.


مقایسه پروتکل‌های لایه انتقال: TCP در برابر UDP

شاخصپروتکل TCPپروتکل UDP
نوع اتصالاتصال‌گرا (Connection-Oriented با Handshake سه‌مرحله‌ای)بدون نیاز به اتصال اولیه (Connectionless)
تضمین تحویل۱۰۰٪ تضمین‌شده با تاییدیه (ACK) و ارسال مجدد بسته گمشدههیچ تضمینی برای تحویل یا ترتیب بسته‌ها وجود ندارد
سرعت و تاخیرکندتر با سربار هدر ۲۰ بایتی و کنترل ازدحامفوق‌العاده سریع با هدر سبک ۸ بایتی
پشتیبانی از مالتی‌کستغیرممکن (فقط Unicast)کاملاً هماهنگ با Multicast
کاربرد در تریدینگارسال سفارشات حساس (Order Entry)دریافت زنده مظنه‌ها و تیک‌ها (Market Data)
  • ترند نوین UFO (UDP for Orders): امروزه برخی صرافی‌های پیشرو برای تسریع در شلیک سفارش‌ها، از UDP برای ارسال سفارش استفاده کرده و مدیریت شماره سریال‌ها و کشف بسته‌های گم‌شده را به لایه اپلیکیشن می‌سپارند.

۴. پروتکل‌های مالی: از استانداردهای متنی تا باینری

مراحل استاندارد ارتباط مالی:

  1. ورود و احراز هویت (Logon)
  2. اشتراک در نمادها و فیدهای قیمت (Subscription)
  3. دریافت مظنه‌ها و ارسال سفارش‌ها
  4. ارسال ضربان قلب حیات اتصال (Heartbeat)
  5. خروج و پایان ارتباط (Logout)

پروتکل FIX (Financial Information eXchange)

پروتکل FIX در سال ۱۹۹۲ برای مبادلات سهام بین Fidelity و Salomon Brothers متولد شد. این یک پروتکل مبتنی بر متن (String-based) و انسان‌خوان است.

فرمت پیام FIX:

پیام‌ها به صورت جفت‌های «تگ=مقدار» هستند که با کاراکتر نامرئی SOH (ASCII 1 یا |) از هم جدا می‌شوند:

  • تمام پیام‌ها با تگ نسخه آغاز می‌شوند: 8=FIX.4.4|
  • تگ ۹: طول بدنه پیام (BodyLength)
  • تگ ۳۵: نوع پیام (MsgType)
  • تگ ۴۹: شناسه فرستنده (SenderCompID)
  • تگ ۵۶: شناسه گیرنده (TargetCompID)
  • تگ ۳۸: حجم سفارش (OrderQty)
  • تگ ۴۴: قیمت پیشنهادی (Price)
  • تگ ۱۰: کد اعتبارسنجی جمع خطای باینری (CheckSum)
نمونه یک پیام ورود (Logon):
8=FIX.4.4|9=76|35=A|34=1|49=TRADER1|52=20220117-12:11:44.224|56=VENUE1|98=0|108=30|141=Y|10=134|

جریان پیام‌های FIX در چرخه معاملات:


معایب FIX و پیدایش پروتکل‌های فوق سریع باینری

پردازش پیام‌های متنی FIX در CPU مستلزم پارس کردن کاراکتر به کاراکتر رشته‌ها و تبدیل متن به اعداد اعشاری است که ده‌ها میکروثانیه زمان تلف می‌کند. برای حل این مشکل دو نوآوری پدید آمد:

  1. پروتکل FAST (FIX Adapted for Streaming): نسخه فشرده‌شده FIX که ساختار داده را از قبل در قالب‌های از پیش تعریف‌شده (Templates) ثبت می‌کند تا فیلدهای تکراری حذف شوند.
  2. پروتکل‌های باینری SBE (Simple Binary Encoding):
    • پروتکل‌های ITCH و OUCH (نزدک و CBOE):
      • ITCH: پروتکل باینری فوق‌سریع برای دریافت داده‌های بازار و دفترچه سفارشات با فرمت بایت‌های مستقیم بدون نیاز به پارس متنی.
      • OUCH: پروتکل باینری اختصاصی برای ثبت، لغو و اصلاح سفارشات با حداقل تاخیر روی TCP.
    • پروتکل باینری بورس شیکاگو (CME SBE): فریم‌های استاندارد باینری برای معاملات قراردادهای آتی کم‌تاخیر.

۵. شبکه‌های داخلی در برابر شبکه‌های خارجی

  • شبکه خارجی (Exterior Network): پورت‌ها و خطوط اختصاصی ارتباط مستقیم با صرافی‌ها با استفاده از پروتکل‌های بورس.
  • شبکه داخلی (Interior Network): بستر ارتباط سرور معاملاتی با سرورهای پایش ریسک، سرور ثبت موقعیت و لاگینگ. برای حداقل تاخیر در شبکه داخلی، ارتباطات سرورها به صورت مستقیم یا بر روی تراشه‌های FPGA درون کارت شبکه پیاده‌سازی می‌شوند.

۶. کالبدشکافی چرخه عمر بسته داده (Packet Life Cycle)

هنگامی که یک پیام مالی از صرافی مخابره می‌شود، به صورت بسته‌ای با ساختار زیر درون شبکه حرکت می‌کند:


مراحل حرکت بسته از سیم تا برنامه معاملاتی در لینوکس

تصویر زیر مسیر پرپیچ‌وخم یک بسته داده بازار را از درون سخت‌افزار تا لایه‌های کرنل لینوکس نشان می‌دهد:

گام‌های اجرایی استاندارد سیستم‌عامل:

  1. دریافت در فیزیک کارت شبکه (NIC): کارت شبکه بسته را دریافت کرده و مک‌آدرس مقصد را تطبیق می‌دهد.
  2. بررسی کد سلامت (FCS Checksum): اعتبارسنجی تمامیت بسته در سخت‌افزار کارت شبکه.
  3. انتقال با DMA: کارت شبکه با استفاده از دسترسی مستقیم به حافظه (DMA)، بسته را بدون دخالت پردازنده به درون بافر حلقوی دریافتی (RX Ring Buffer) در رم کپی می‌کند.
  4. صدور وقفه سخت‌افزاری (Top-Half Interrupt): پردازنده کار فعلی را متوقف کرده، جدول توصیف‌گر وقفه (IDT) را می‌خواند و روتین وقفه درایور کارت شبکه را اجرا می‌کند.
  5. پردازش وقفه نرم‌افزاری (Soft-IRQ / Bottom-Half): پردازنده برای هر بسته یک ساختار داده سوکت به نام sk_buff (SKB) در رم تخصیص می‌دهد، هدرها را جدا می‌کند و بسته را وارد پشته استاندارد شبکه لینوکس (Linux Network Stack) می‌کند.
  6. کپی به فضای کاربر: برنامه ما با فراخوانی تابع سیستمی recv() بسته را از فضای کرنل به فضای کاربر کپی می‌کند.
پیش‌زمینه تکنولوژی Kernel Bypass

این فرآیند طولانی کرنل، صدها کپی حافظه و چندین کانتکست‌سوئیچ تحمیل می‌کند. در فصل‌های ۶ و ۷ خواهیم دید که چگونه غول‌های HFT با تکنیک Kernel Bypass (مثل Solarflare OpenOnload یا DPDK) این پشته لینوکس را دور می‌زنند و بسته را مستقیماً از کارت شبکه به برنامه تحویل می‌دهند!


۷. مانیتورینگ سخت‌افزاری شبکه با Network TAP

برای تحلیل تاخیر بدون افت کارایی سرورها، از سخت‌افزارهای پایشگر Network TAP استفاده می‌شود:

  • تپ‌های غیرفعال (Passive TAP): در فیبرهای نوری، پرتو نور ورودی توسط یک منشور نوری شکافته می‌شود (مثلاً ۷۰٪ به سرور معاملاتی و ۳۰٪ به سرور مانیتورینگ لاگ). این دستگاه نیاز به برق ندارد و حتی در صورت قطع برق، جریان ترید صدمه‌ای نمی‌بیند و هیچ تاخیری ایجاد نمی‌شود.
  • تپ‌های فعال (Active TAP): در شبکه‌های الکتریکی مسی که دارای مدارهای رله خودکار برای زمان قطعی برق هستند.

⏱ ۸. توزیع و همگام‌سازی زمان فوق دقیق در HFT

در HFT زمان با ارزش‌ترین منبع است. برای بازسازی دقیق رویدادهای بازار و رعایت قوانین انطباق مالی، ساعت تمام سرورها باید بر اساس زمان هماهنگ جهانی (UTC) همگام باشند.

سطوح پروتکل NTP در برابر PTP:

  1. پروتکل NTP (Network Time Protocol):
    • همگام‌سازی نرم‌افزاری با لایه‌های سلسله‌مراتبی (Stratum 0 متصل به ماهواره‌های اتمی GPS/GNSS، لایه Stratum 1 سرورهای متصل مستقیم).
    • دستیابی به دقت در مقیاس میلی‌ثانیه یا میکروثانیه.
  2. پروتکل فوق دقیق PTP (Precision Time Protocol - استاندارد IEEE 1588):
    • برچسب‌گذاری سخت‌افزاری زمان (Hardware Timestamping): زمان دقیق ورود و خروج بسته توسط خود تراشه کارت شبکه با سیگنال‌های پالس در ثانیه (PPS) با دقت نانوثانیه و پیکوثانیه ثبت می‌شود!
    • سوئیچ‌های سازگار با PTP مدت زمان ماندگاری بسته درون سوئیچ را اندازه‌گیری و کالیبره می‌کنند.
    • در هر دیتاسنتر یک ساعت مادر فوق دقیق به نام PTP Grandmaster Clock قرار داده می‌شود تا تمام کلاسترهای سرور معاملاتی همزمان شوند.

چرا همگام‌سازی تا این حد حیاتی است؟

برای تریدرهای مستقر در هم‌مکانی (Colocation)، زمان رسیدن بسته کمتر از ۵ میکروثانیه است؛ بنابراین اگر ساعت سیستم‌ها حتی چند میکروثانیه عدم انطباق داشته باشد، اندازه‌گیری متریک‌های سرعت، کشف صف‌ها و ثبت قانونی لاگ‌ها با خطا مواجه خواهد شد.


خلاصه و جمع‌بندی فصل پنجم (Summary)

در این فصل، زیرساخت ارتباطی شبکه‌های معاملات فرکانس بالا بررسی شد:

  1. استفاده از سوئیچینگ فوق‌سریع Cut-Through برای حذف تاخیر پردازش فریم‌ها.
  2. برتری UDP Multicast برای انتشار دیتای بازار و لزوم پروتکل‌های باینری نظیر ITCH/OUCH و SBE در برابر پروتکل متنی FIX.
  3. شناخت مراحل گذر بسته از کابل تا بافر حلقوی DMA و پشته کرنل لینوکس.
  4. مانیتورینگ بدون تاخیر با استفاده از Passive Optical TAP.
  5. همگام‌سازی ساعت‌ها با دقت نانوثانیه‌ای پروتکل PTP IEEE 1588.

در فصل بعدی (06 - بهینه‌سازی OS و ساختارهای داده Lock-Free)، وارد مباحث پیشرفته بهینه‌سازی معماری سیستم‌عامل، حذف Context Switch، ساختارهای داده بدون قفل (Lock-Free) و تکنیک‌های پیش‌واکشی حافظه (Pre-fetching) خواهیم شد!

بهینه‌سازی سیستم‌عامل و ساختارهای داده بدون قفل

(HFT Optimization – Architecture and Operating System)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۱۲۷ تا ۱۵۲


مقدمه

در فصول پیشین، با سازوکار کلی سخت‌افزار، لایه‌های سیستم‌عامل و مبانی شبکه آشنا شدیم. معاملات فرکانس بالا (HFT) در اصل یک «مسابقه تسلیحاتی فناورانه» است که در آن هر معامله‌گر می‌کوشد سفارش‌های خود را سریع‌تر از سایرین اجرا کند. تسلط بر مفاهیم علوم کامپیوتر و بهینه‌سازی‌های لایه‌های زیرین، به شما امکان می‌دهد سیستم‌های HFT با بالاترین کارایی و کمترین تاخیر زمانی ممکن تولید کنید.

در این فصل مباحث زیر به طور عمیق کالبدشکافی می‌شوند:

  • درک جامع تعویض زمینه (Context Switch): انواع، هزینه‌های ویرانگر آن در HFT و تکنیک‌های حذف کامل آن
  • طراحی ساختارهای داده بدون قفل (Lock-Free Data Structures): صف‌های SPSC، MPMC و رفع معضل Priority Inversion
  • سلسله‌مراتب حافظه، محاسبه فرمول AAT، مجاورت داده‌ها و پیش‌واکشی (Pre-fetching)
  • معضلات تخصیص پویای حافظه (Dynamic Allocation) و پیاده‌سازی مخازن حافظه از پیش تخصیص‌یافته (Memory Pools)

۱. درک تعویض زمینه (Understanding Context Switches)

تعویض زمینه (Context Switch) به فرآیندی اطلاق می‌شود که طی آن سیستم‌عامل اجرای یک فرآیند یا نخ (Thread) را روی هسته پردازنده متوقف ساخته، وضعیت جاری آن را ذخیره می‌کند و کنترل پردازنده را به فرآیند یا نخ دیگری واگذار می‌نماید.

انواع کانتکست سوئیچ:

  1. سخت‌افزاری در برابر نرم‌افزاری:
    • در سوئیچ سخت‌افزاری از قابلیت‌های معماری پردازنده نظیر Task State Segments (TSS) برای ذخیره خودکار ثبات‌ها استفاده می‌شود.
    • در سوئیچ نرم‌افزاری، کدهای کرنل سیستم‌عامل ثبات‌ها را روی پشته ذخیره می‌کنند.
  2. سوئیچ بین نخ‌ها (Thread Switch) در برابر بین فرآیندها (Process Switch):
    • جابه‌جایی میان دو نخ متعلق به یک فرآیند واحد، کم‌هزینه‌تر است زیرا فضای آدرس مجازی و جداول صفحه یکسان باقی می‌مانند.
    • سوئیچ میان دو فرآیند مستقل فوق‌العاده گران است؛ زیرا علاوه بر ثبات‌ها، ثبات CR3 پردازنده بازنویسی شده و کل فضای آدرس مجازی و بافر TLB باید تعویض شود.
  3. سوئیچ بین حالت کاربر و کرنل (User to Kernel Mode Switch):
    • هنگام رخ دادن یک وقفه سخت‌افزاری یا صدور فراخوان سیستمی، هسته برای رسیدگی وارد مد کرنل شده و مجدداً به فضای کاربر بازمی‌گردد.

چرا کانتکست سوئیچ برای برنامه‌های عادی خوب، اما برای HFT سمی است؟

  • در برنامه‌های عادی (مانند آفیس یا مرورگرها): کانتکست سوئیچ قابلیتی ارزشمند است؛ زیرا ترکیبی از تعامل کاربر، دیسک I/O و محاسبات را به صورت متوازن میان برنامه‌ها تقسیم می‌کند.
  • در معاملات فرکانس بالا (HFT): کانتکست سوئیچ یک فاجعه تمام‌عیار است!

هزینه‌های مخرب کانتکست سوئیچ در HFT:

  1. اتلاف چرخه‌های پردازنده: ذخیره و بازیابی بلوک کنترل فرآیند (PCB - Process Control Block) بین ۱٬۰۰۰ تا ۱۰٬۰۰۰ نانوثانیه (۱ تا ۱۰ میکروثانیه) زمان می‌سوزاند.
  2. آلودگی کش پردازنده (Cache Pollution): بزرگ‌ترین صدمه این است که با ورود فرآیند جدید، داده‌های حیاتی سیستم معاملاتی شما از کش‌های سریع L1 و L2 بیرون ریخته شده و بازنویسی می‌شوند. هنگامی که استراتژی دوباره CPU را پس می‌گیرد، با انبوهی از خطاهای کش (Cache Misses) مواجه می‌شود و باید متغیرها را با تاخیرهای صد نانوثانیه‌ای از RAM بخواند!
  3. تخلیه بافر TLB: پاک شدن نگاشت صفحات و کند شدن دسترسی به آدرس‌های حافظه.
  4. ایجاد تاخیر دنباله نوسانی (Jitter & Tail Latency): نوسان در زمان اجرای سفارشات که باعث می‌شود گاهی سیستم بسیار کند عمل کند.

راهکارهای مهندسی لینوکس برای حذف Context Switch در HFT:

  1. ایزوله‌سازی هسته‌ها در گراب (isolcpus): با افزودن آرگومان isolcpus=2,3 به زمان بوت لینوکس، زمان‌بند هسته لینوکس هرگز هیچ پردازشی را روی این هسته‌ها قرار نمی‌دهد.
  2. پین کردن نخ به هسته (Task Pinning / CPU Affinity): الصاق انحصاری فرآیند استراتژی به هسته ایزوله‌شده با استفاده از فراخوان pthread_setaffinity_np یا دستور taskset.
  3. پیکربندی کرنل بدون تیک (NO_HZ_FULL): خاموش کردن کامل وقفه‌های زمان‌سنج سیستم‌عامل (Timer Ticks) روی هسته ایزوله‌شده تا پردازنده بدون حتی یک وقفه میلی‌ثانیه‌ای ۱۰۰٪ در اختیار کد معاملاتی باشد.
  4. سیاست بلادرنگ SCHED_FIFO: تنظیم بالاترین اولویت پردازشی در لینوکس با اولویت ۹۹ به طوری که هیچ فرآیندی نتواند استراتژی را تعلیق کند.

۲. ساختارهای داده بدون قفل (Building Lock-Free Data Structures)

در برنامه‌نویسی سنتی چندهسته‌ای، دسترسی مشترک به داده‌ها با سازوکارهای مسدودکننده (Blocking) نظیر Mutex یا Spinlock محافظت می‌شود.

معایب ویرانگر قفل‌ها در HFT:

  • تعلیق نخ و سوئیچ کانتکست: اگر نخ دیگر قفل را نگه داشته باشد، نخ جاری توسط سیستم‌عامل به خواب رفته و تاخیر به میکروثانیه‌ها جهش می‌کند.
  • تاخیرهای صف‌بندی (Lock Contention): رقابت نخ‌ها بر سر تصاحب قفل باعث توقف پایپ‌لاین می‌شود.
  • خطر بن‌بست (Deadlock): توقف کامل سامانه.
  • پدیده معکوس شدن اولویت (Priority Inversion): حالتی فاجعه‌بار که در آن یک نخ با اولویت پایین (مثلاً نخ نوشتن لاگ) قفلی را در اختیار دارد؛ زمان‌بند سیستم‌عامل به دلیل ورود یک نخ با اولویت متوسط، اجرای نخ ضعیف را متوقف می‌کند؛ در نتیجه نخ حیاتی استراتژی با اولویت بالا ساعت‌ها پشت درِ بسته قفل معطل مانده و سیستم از معامله بازمی‌ماند!

اصول برنامه‌نویسی بدون قفل (Lock-Free)

رویکرد Lock-Free دسترسی همزمان چند نخ به داده‌ها را بدون مسدود شدن و بدون قفل ممکن می‌سازد:

  • دستورالعمل‌های اتمیک سخت‌افزاری: اجرای دستورات مستقیم CPU نظیر Compare-And-Swap (CAS) یا LOCK CMPXCHG در اسمبلی x86.
  • موانع حافظه (Memory Barriers / Fences): جلوگیری از بازآرایی دستورات خواندن و نوشتن توسط کامپایلر و پردازنده برای حفظ ترتیب ترتیبی عملیات.

ساختار صف حلقوی بدون قفل (Lock-Free Ring Buffer):

  • در این ساختار، تولیدکننده (Producer) و مصرف‌کننده (Consumer) در یک آرایه حلقوی با اندازه ثابت (معمولاً توان‌هایی از ۲ مانند ۱۰۲۴ تا با عملیات بیتی AND به جای ماژولو ایندکس‌گذاری شوند) بدون قفل کار می‌کنند.
  • تولیدکننده نشانگر last_write را با عملیات اتمیک جلو می‌برد.
  • مصرف‌کننده نشانگر last_read را دنبال می‌کند.
  • داده‌ها بدون کوچک‌ترین نیازی به Mutex با تاخیر چند نانوثانیه‌ای بین تردها منتقل می‌شوند.

چیدمان انواع صف‌های بدون قفل در اکوسیستم HFT:

  • صف SPSC (Single-Producer Single-Consumer): سریع‌ترین و کارآمدترین ساختار صف جهان؛ یک فرآیند منحصراً می‌نویسد و یک فرآیند منحصراً می‌خواند. این ساختار در مسیر بحرانی (Critical Path) میان درگاه شبکه و موتور استراتژی استفاده می‌شود.
  • صف MPSC (Multi-Producer Single-Consumer): چندین درگاه دریافت خوراک دیتای بازار همزمان داده‌ها را درون صف واحد استراتژی می‌ریزند.
  • صف SPMC / MPMC (Multi-Producer Multi-Consumer): چندین تولیدکننده و چندین مصرف‌کننده برای وظایف با حساسیت کمتر نظیر توزیع داده‌های بازار، سرورهای ریسک و ذخیره لاگ‌ها.

۳. سلسله‌مراتب حافظه، پیش‌واکشی (Pre-fetching) و تخصیص اولیه

برای کاهش تاخیر دسترسی به داده‌ها، شناخت ساختار حافظه ضروری است:

  1. ثبات‌های پردازنده (Registers): دسترسی در ۱ چرخه کلاک (~ ۰.۳ نانوثانیه).
  2. کش L1: دسترسی در ~ ۰.۵ تا ۱ نانوثانیه.
  3. کش L2: دسترسی در ~ ۳ تا ۵ نانوثانیه.
  4. کش L3: دسترسی در ~ ۱۰ تا ۱۵ نانوثانیه.
  5. حافظه اصلی RAM: دسترسی در ~ ۶۰ تا ۱۰۰ نانوثانیه.

فرمول میانگین زمان دسترسی به حافظه (Average Access Time - AAT)

$$\text{AAT} = \text{Hit Time} + (\text{Miss Rate} \times \text{Miss Penalty})$$

مثال عددی کتاب:

فرض کنید دسترسی به RAM برابر ۶۰ نانوثانیه باشد:

  • بدون کش: میانگین زمان دسترسی دقیقاً ۶۰ نانوثانیه است.
  • با کش L1 (زمان دسترسی ۰.۵ نانوثانیه و نرخ خطای ۱۰٪): $$\text{AAT} = 0.5 + (0.10 \times 60) = 6.5 \text{ نانوثانیه}$$
  • با ترکیب L1 و L2 و L3 (با خطای ۰.۱٪): میانگین زمان دسترسی به زیر ۱ نانوثانیه می‌رسد! این نشان می‌دهد که حفظ داده‌ها درون کش تا چه اندازه سرنوشت‌ساز است.

اصول مجاورت ارجاع (Locality of Reference):

  • مجاورت مکانی (Spatial Locality): قرار دادن بایت‌های داده در آدرس‌های فیزیکی مجاور در حافظه. در HFT ساختارهای داده پیوسته (مانند آرایه‌ها و بردارهای تخت) بر ساختارهای اشاره‌گری گسسته (مانند Linked List یا درخت‌ها) اولویت مطلق دارند تا با بارگذاری یک Cache Line، تمام مقادیر همسایه وارد کش شوند.
  • مجاورت زمانی (Temporal Locality): استفاده مجدد و پیاپی از داده‌هایی که اخیراً بارگذاری شده‌اند.

تکنیک‌های پیش‌واکشی (Pre-fetching) و حذف انشعابات غیرقابل‌پیش‌بینی:

  • پیش‌واکشی سخت‌افزاری: تشخیص الگوهای دسترسی خطی توسط مدار پردازنده.
  • پیش‌واکشی نرم‌افزاری: صدور مستقیم دستور __builtin_prefetch در ++C برای بارگذاری لایه‌های عمیق‌تر دفترچه سفارشات پیش از نیاز به محاسبه:
__builtin_prefetch(&order_book[next_price_level], 0, 3);
  • اجتناب از انشعاب‌های غیرقابل‌پیش‌بینی (Unpredictable Branches): پرش‌های شرطی تصادفی (if/elseهای غیرقابل پیش‌بینی) مانع پیش‌واکشی شده و پایپ‌لاین پردازنده را فلج می‌کنند؛ در کد HFT باید از عبارات بدون شاخه (Branchless Programming) استفاده شود.

۴. معضلات تخصیص پویای حافظه (Dynamic Memory Allocation)

مدیریت حافظه پویا با توابع malloc، free و عملگرهای new و delete در زمان اجرای زنده بازار اکیداً ممنوع است:

  • سیستم‌عامل بلوک‌های آزاد هیپ را در دو لیست پیوندی (Freed list و Allocated list) نگهداری می‌کند. جستجوی بلوک حافظه در میان این لیست‌ها روندی غیرقطعی و به شدت زمان‌بر است.
  • ایجاد پدیده پاشیدگی و تکه‌تکه شدن حافظه (Memory Fragmentation).
  • نیاز به فراخوان‌های سیستمی هسته نظیر brk و sbrk.

راهکارهای طلایی مهندسی حافظه در HFT:

  1. تخصیص روی پشته (Stack Allocation): ترجیح متغیرهای محلی روی پشته به جای هیپ.
  2. مخازن حافظه از پیش تخصیص‌یافته (Memory Pools / Pre-allocation):
    • کلیه فضاهای مورد نیاز برای میلیون‌ها پیام و رکورد در زمان راه‌اندازی برنامه (پیش از آغاز روز معاملاتی) به صورت یکپارچه تخصیص داده می‌شوند.
    • در زمان ترید زنده، تخصیص حافظه صرفاً یک حرکت ساده ایندکس در آرایه از پیش ساخته‌شده با زمان ثابت $O(1)$ خواهد بود.
  3. قفل کردن فضای آدرس در رم با mlockall: جلوگیری قطعی از سواپ شدن حافظه برنامه معاملاتی به حافظه دیسک توسط سیستم‌عامل لینوکس:
mlockall(MCL_CURRENT | MCL_FUTURE);

خلاصه و جمع‌بندی فصل ششم (Summary)

در این فصل، بنیادی‌ترین اصول کاهش تاخیر سیستمی را فراگرفتیم:

  1. حذف کانتکست سوئیچ از طریق ایزوله‌سازی هسته‌ها (isolcpus)، پین کردن فرآیندها (CPU Pinning) و کرنل بدون تیک (NO_HZ_FULL).
  2. پیاده‌سازی صف‌های حلقوی بدون قفل (SPSC Lock-Free Queues) و حذف خطرات Mutex و وارونگی اولویت.
  3. استفاده از پیش‌واکشی داده‌ها، احترام به خطوط کش ۶۴ بایتی، و ممنوعیت مطلق malloc در زمان اجرای زنده بازار به کمک Memory Pools و mlockall.

در فصل بعدی (07 - شتاب‌دهی کرنل، فیبر نوری و لاگینگ)، تکنیک‌های پیشرفته Kernel Bypass (با فناوری Solarflare)، فایل‌های نگاشت‌شده در حافظه (mmap)، فیبر نوری توخالی (Hollow Fiber) و امواج مایکروویو را موشکافی خواهیم کرد!

شتاب‌دهی شبکه، فیبر نوری و لاگینگ

HFT Optimization – Logging, Performance, and Networking

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۱۵۳ تا ۱۷۸ پایان بخش دوم کتاب: چگونه یک سیستم HFT را معماری کنیم؟ (Part 2)


مقدمه

در فصل ششم، تکنیک‌های سطح سیستم‌عامل و ساختارهای بدون قفل را بررسی کردیم. در این فصل، به بررسی پیشرفته‌ترین راهکارهای سخت‌افزاری و نرم‌افزاری برای شتاب‌دهی تبادل داده، حذف پشته شبکه کرنل، انتقال امواج در فضا و اندازه‌گیری زمان در مقیاس نانوثانیه می‌پردازیم.

مباحث محوری این فصل عبارتند از:

  • مقایسه عملکردی فضای کاربر و هسته (Kernel Space vs User Space)
  • تکنولوژی انقلابی دور زدن کرنل (Kernel Bypass) و کارت‌های شبکه فوق‌سریع
  • فایل‌های نگاشت‌شده در حافظه (Memory-Mapped Files / mmap) و کاربرد در IPC
  • تکامل کابل‌ها: از فیبر نوری شیشه‌ای تا فیبر توخالی (Hollow Fiber) و امواج مایکروویو
  • معماری لاگ‌گیری و محاسبات آماری بلادرنگ بدون افت سرعت در مسیر بحرانی
  • روش‌های سنجش دقیق تاخیر زمانی (Tick-to-Trade) با دستورات پردازنده و تایم‌استمپ‌های مسیر رفت‌وبرگشت

۱. مقایسه فضای هسته و فضای کاربر (Kernel Space vs User Space)

هسته سیستم‌عامل (Kernel) کنترل تمام منابع فیزیکی سخت‌افزار، حافظه و دستگاه‌ها را در اختیار دارد. کدهای کرنل باید به شدت پایدار و قابل‌اعتماد باشند. در مقابل، فرآیندهای عادی نرم‌افزاری در فضای کاربر (User Space) با دسترسی‌های محدود اجرا می‌شوند:

معضل عملکردی پشته استاندارد شبکه لینوکس:

هنگامی که یک بسته داده از صرافی به کارت شبکه می‌رسد:

  1. ابتدا یک وقفه سخت‌افزاری (Interrupt) به پردازنده فرستاده می‌شود.
  2. پردازنده وارد حالت کرنل (Kernel Mode) شده و تعویض زمینه صورت می‌گیرد.
  3. درایور بسته را از کارت شبکه به بافرهای کرنل (sk_buff) کپی می‌کند.
  4. بسته از لایه‌های پروتکلی متعدد TCP/IP لینوکس عبور می‌کند.
  5. برنامه معاملاتی با فراخوانی تابع recv() بسته را مجدداً از فضای کرنل به فضای کاربر کپی می‌کند. این کپی‌های پی‌درپی حافظه و سوئیچ‌های مکرر بین فضای کاربر و کرنل، بین ۱.۵ تا ۱۰ میکروثانیه زمان تلف می‌کنند که در دنیای HFT غیرقابل قبول است!

۲. فناوری انقلابی دور زدن کرنل (Kernel Bypass)

برای رهایی از تاخیرهای مرگبار پشته شبکه لینوکس، راهکار طلایی صنعت HFT استفاده از Kernel Bypass است. این تکنیک کارت شبکه را مستقیماً به برنامه معاملاتی در فضای کاربر متصل می‌کند و پشته کرنل را کاملاً دور می‌زند!

دو پایه بنیادین معماری Kernel Bypass:

  1. کپی صفر (Zero-Copy): با بهره‌گیری از قابلیت Direct Memory Access (DMA)، کارت شبکه بسته‌های داده را مستقیماً در بافر حافظه نرم‌افزار معاملاتی در فضای کاربر می‌نویسد؛ هیچ کپی واسطه‌ای رخ نمی‌دهد.
  2. پیمایش فعال پردازنده (User-Space Polling / Busy-Waiting): به جای تکیه بر وقفه‌های کرنل، یک هسته اختصاصی پردازنده به طور مداوم و حلقه‌وار کارت شبکه را بررسی می‌کند (Polling) تا به محض دریافت اولین بایت بسته، آن را در کسری از نانوثانیه پردازش کند.

مقایسه آماری تاخیر با و بدون Kernel Bypass:

  • ارسال و دریافت بسته‌های UDP معمولی با کرنل لینوکس: ۱.۵ تا ۱۰ میکروثانیه.
  • ارسال و دریافت بسته‌ها با فناوری Kernel Bypass: تنها ۰.۵ تا ۱.۵ میکروثانیه! این به معنای کاهش تا ۷۰ الی ۹۰ درصدی تاخیر و حذف کامل نوسان تاخیر (Jitter) است.

فناوری‌ها و استانداردهای پیشرو در صنعت:

  • Solarflare OpenOnload و EF_VI: استاندارد طلایی وال‌استریت بر روی کارت‌های شبکه سری XtremeScale سولارفلر (AMD). با کتابخانه OpenOnload، بدون نیاز به تغییر کدهای سوکت برنامه، تمام ارتباطات شبکه مستقیماً در سطح سخت‌افزار شتاب‌دهی می‌شوند.
  • DPDK (Data Plane Development Kit): فریم‌ورک متن‌باز ارائه‌شده توسط اینتل برای پردازش سریع بسته‌های شبکه در فضای کاربر.

۳. فایل‌های نگاشت‌شده در حافظه (Memory-Mapped Files - mmap)

در سیستم‌های معمولی، کار با فایل از طریق فراخوان‌های سیستمی read() و write() انجام می‌شود که داده را میان دیسک و بافرهای کرنل جابه‌جا می‌کند. با استفاده از فراخوان سیستمی mmap()، فایل مستقیماً به عنوان یک آرایه در فضای آدرس مجازی برنامه مپ می‌شود.

انواع فایل‌های نگاشت‌شده در حافظه:

  1. نگاشت‌های پایدار (Persisted Memory-Mapped Files): تغییرات ایجادشده در حافظه رم، در پس‌زمینه توسط سیستم‌عامل روی دیسک فیزیکی ذخیره می‌شوند.
  2. نگاشت‌های ناپایدار (Non-Persisted Memory Maps): فایلی روی دیسک ایجاد نمی‌شود؛ بلکه صرفاً تکه‌ای از رم مشترک میان چند فرآیند مپ می‌شود که سریع‌ترین بستر برای ارتباطات بین‌فرآیندی (IPC - Inter-Process Communication) بدون نیاز به سوکت‌های شبکه یا لوله‌ها (Pipes) است.

مزایای mmap در HFT:

  • دسترسی تصادفی سریع (Fast Random Access): دسترسی به هر نقطه از داده با سرعت دسترسی به حافظه رم بدون نیاز به عملیات سنگین Seek دیسک.
  • بارگذاری تنبل (Lazy Loading): صفحات داده تنها زمانی از دیسک خوانده می‌شوند که برنامه به آن‌ها ارجاع دهد.

۴. رقابت برای سرعت نور: فیبر نوری، فیبر توخالی و مایکروویو

در فواصل میان‌شهری (مثلاً فاصله ۱۲۰۰ کیلومتری میان بورس سهام نیویورک در نیوجرسی و بورس مشتقات شیکاگو CME)، تفاوت میلی‌ثانیه‌ها تعیین‌کننده برنده است:

۱. کابل‌های فیبر نوری استاندارد (Standard Glass Fiber)

  • نور درون رشته‌های شیشه‌ای سیلیس حرکت می‌کند. به دلیل ضریب شکست شیشه ($n \approx 1.5$)، سرعت حرکت نور در شیشه حدود ۲۰۰٬۰۰۰ کیلومتر بر ثانیه است (حدود ۳۰٪ کندتر از سرعت نور در خلاء!).

۲. کابل‌های فیبر نوری توخالی (Hollow-Core Fiber)

  • یکی از جدیدترین نوآوری‌ها در فواصل کوتاه (چند صد متری دیتاسنتر تا دکل‌ها). نور درون کانال هوای مرکزی فیبر حرکت می‌کند. ضریب شکست هوا بسیار نزدیک به ۱ است و سرعت نور به ۹۹.۷٪ سرعت نور در خلاء (نزدیک به ۳۰۰٬۰۰۰ کیلومتر بر ثانیه) می‌رسد که صدها نانوثانیه تاخیر را حذف می‌کند.

۳. شبکه‌های مایکروویو (Microwave & Millimeter Wave)

  • امواج رادیویی در خط دید مستقیم (Line of Sight) میان دکل‌های مخابراتی در هوا با سرعت نور در خلاء منتشر می‌شوند.
  • مسیر نیویورک به شیکاگو که با فیبر نوری حدود ۱۳ میلی‌ثانیه زمان رفت‌وبرگشت (RTT) داشت، با احداث دکل‌های مایکروویو اختصاصی توسط شرکت‌های HFT به زیر ۸ میلی‌ثانیه کاهش یافت!
چالش‌های امواج مایکروویو

پهنای باند امواج مایکروویو به شدت محدود است و در اثر بارندگی و طوفان دچار میرایی و افت سیگنال می‌شود. به همین دلیل سیستم‌های HFT منحصراً بسته‌های کوچک و سفارش‌های فوق حیاتی را روی مایکروویو ارسال کرده و دیتاهای حجیم‌تر را روی فیبر نوری نگه می‌دارند.


۵. معماری لاگ‌گیری و محاسبات آماری بلادرنگ

لاگ‌گیری و ثبت رخدادها برای عیب‌یابی و انطباق قانونی ضروری است؛ اما نوشتن لاگ روی دیسک یا کنسول به شدت کند است و اگر در مسیر تصمیم‌گیری ترید قرار گیرد، سیستم را زمین‌گیر می‌کند.

راهکار معماری لاگ‌گیری کم‌تاخیر در HFT:

  1. عدم مسدودسازی مسیر بحرانی (Non-Blocking Logging): نخ معاملاتی پیام لاگ را به یک صف حلقوی بدون قفل (SPSC Lock-Free Queue) در رم تحویل می‌دهد و فوراً به کار ترید بازمی‌گردد.
  2. نخ اختصاصی لاگ در پس‌زمینه (Dedicated Logging Thread): یک ترد مجزا که روی هسته‌ای غیربحرانی پین شده است، پیام‌ها را از صف برداشته و آن‌ها را به صورت دسته‌ای (Batch) در فایل یا دیتابیس می‌نویسد.
  3. محاسبات آماری آنلاین (Online Statistics): محاسبه میانگین تاخیرها، نرخ اجرای سفارش‌ها و سود/زیان لحظه‌ای سبد سهام.

⏱ ۶. روش‌ها و ابزارهای سنجش کارایی در HFT

ابزارهای اندازه‌گیری کارایی در HFT باید خود دارای کمترین سربار محاسباتی (Near-Zero Overhead) و بیشترین دقت نانوثانیه‌ای باشند.

ابزارهای لینوکس:

  • دستور time: محاسبه زمان CPU، زمان سیستم و زمان کاربر.
  • ابزار perf: استفاده از شمارنده‌های سخت‌افزاری پردازنده (PMU) برای سنجش چرخه‌های CPU و بررسی خطاهای کش (Cache Misses) و پیش‌بینی انشعاب (Branch Mispredictions).
  • ابزارهای valgrind و cachegrind: شبیه‌سازی کش پردازنده در محیط توسعه.
  • سامانه LTTng: ردیابی بلادرنگ رویدادهای کرنل لینوکس.

شرایط ایزوله‌سازی محیط بنچمارک HFT:

  • خاموش کردن Hyper-Threading برای جلوگیری از تقسیم منابع هسته.
  • غیرفعال‌سازی صرفه‌جویی انرژی پردازنده: غیرفعال کردن حالات C-States و P-States در لینوکس و قفل کردن پردازنده روی بالاترین فرکانس توربو به صورت ثابت.
  • خاموش کردن ASLR: غیرفعال‌سازی موقت تصادفی‌سازی چیدمان حافظه (Address Space Layout Randomization) در زمان تست برای تضمین رفتار قطعی و تکرارپذیر آدرس‌ها.
  • دستور مستقیم پردازنده rdtsc: استفاده از دستور اسمبلی x86 برای خواندن مستقیم شمارنده چرخه‌های کلاک پردازنده (Time Stamp Counter) با کمترین سربار، در کنار هدر <chrono> در مدرن ++C.

سامانه سنجش تاخیر رفت‌وبرگشت (Tick-to-Trade Measurement System)

تصاویر زیر معماری استاندارد اندازه‌گیری تاخیر نقطه به نقطه در یک اکوسیستم کامل HFT را نشان می‌دهند:

کالبدشکافی تایم‌استمپ‌های مسیر بحرانی ($t_1$ تا $t_{10}$):

  • $t_1$: خروج بسته داده بازار از سوئیچ صرافی
  • $t_2$: ورود بسته به سوئیچ شبکه شرکت معاملاتی
  • $t_3$: ورود بسته به کارت شبکه سرور HFT (ثبت توسط Hardware Timestamping در پورت کارت شبکه)
  • $t_4$: دریافت بسته توسط درگاه با تکنولوژی Kernel Bypass
  • $t_5$: پردازش در دفترچه‌ساز (Book Builder) و به‌روزرسانی دفترچه
  • $t_6$: تصمیم‌گیری در موتور استراتژی و صدور سیگنال معامله
  • $t_7$: اعتبارسنجی ریسک در OMS و تحویل به درگاه سفارشات
  • $t_8$: خروج بسته سفارش از پورت فیزیکی کارت شبکه به سمت بورس
  • $t_9$: رسیدن سفارش به سوئیچ صرافی
  • $t_{10}$: ورود سفارش به موتور تطبیق صرافی (Matching Engine)

تحلیل تفکیکی تاخیرها:

  • تاخیر نرم‌افزاری خالص در سرور: $\Delta t_{software} = t_7 - t_4$
  • تاخیر کارت شبکه و درایور: $\Delta t_{nic} = (t_4 - t_3) + (t_8 - t_7)$
  • تاخیر فیزیکی کابل و شبکه بیرونی: $\Delta t_{wire} = (t_3 - t_1) + (t_{10} - t_8)$
  • کل تاخیر رفت‌وبرگشت (Tick-to-Trade RTT): $\text{TTT} = t_{10} - t_1$

خلاصه و جمع‌بندی فصل هفتم (Summary)

در این فصل، مباحث حیاتی معماری و شتاب‌دهی را به پایان رساندیم:

  1. استفاده از Kernel Bypass (Solarflare / OpenOnload) برای رساندن تاخیر شبکه به زیر ۱ میکروثانیه.
  2. بهره‌گیری از فایل‌های مپ‌شده در رم (mmap) برای سریع‌ترین IPC ممکن.
  3. تکامل خطوط ارتباطی با فیبرهای توخالی (Hollow-Core) و امواج مایکروویو میان دیتاسنترها.
  4. جداسازی مسیر لاگ‌گیری از مسیر بحرانی ترید به کمک صف‌های بدون قفل.
  5. استقرار زیرساخت سنجش نانوثانیه‌ای Tick-to-Trade با ثبت زمان‌های $t_1$ تا $t_{10}$.

با پایان فصل هفتم، «بخش دوم کتاب» (معماری سیستم‌های HFT) با موفقیت کامل به پایان رسید.

در بخش سوم کتاب (Implementation of an HFT System)، وارد هیجان‌انگیزترین مرحله یعنی کدنویسی واقعی با ++C، جاوا، پایتون و تراشه‌های سخت‌افزاری FPGA خواهیم شد!

سی‌پلاس‌پلاس و تاخیر میکروثانیه

C++ – The Quest for Microsecond Latency

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۱۸۱ تا ۲۱۸ بخش سوم کتاب: پیاده‌سازی و کدنویسی سیستم‌های HFT (Part 3)


مقدمه

سی‌پلاس‌پلاس مدرن (++C11/14/17/20) زبان بدون رقیب سیستم‌های معاملات فرکانس بالا (HFT) است. در این فصل، بر ویژگی‌ها و ساختارهایی از این زبان تمرکز می‌کنیم که برای توسعه، نگهداری و شتاب‌بخشی به سیستم‌های چندنخی بلادرنگ و دستیابی به تاخیرهای زیر چند میکروثانیه ضروری هستند.

مباحث محوری این فصل عبارتند از:

  • مدل حافظه مدرن ++C (C++ Memory Model) و رژیم‌های دسترسی حافظه
  • حذف تصمیمات زمان اجرا (Removing Runtime Decisions)، هزینه‌های سنگین توابع مجازی و جایگزینی آن با الگوی CRTP
  • تخصیص حافظه پویا، استفاده حرفه‌ای از constexpr و خطرات استثناها (Exceptions)
  • قدرت و خطرات قالب‌ها (Templates)، فرابرنامه‌نویسی و کانتینرهای STL
  • تحلیل ایستای کد (Static Analysis) با ابزارهای مدرن
  • مطالعه موردی صنعتی: توسعه سیستم معاملاتی ارز خارجی (FX) و تکنیک طلایی گرم نگه‌داشتن کش (Cache Warming)

۱. مدل حافظه مدرن سی‌پلاس‌پلاس (C++ Memory Model)

یک مدل حافظه (Memory Model) قواعد مجاز و مورد انتظار برای خواندن و نوشتن حافظه میان پردازنده و کامپایلر را مشخص می‌کند. در یک سیستم تک‌نخی، بازآرایی دستورات توسط کامپایلر مشکلی ایجاد نمی‌کند؛ اما در سیستم‌های چندنخی که روی پردازنده‌های چندهسته‌ای NUMA اجرا می‌شوند، بازآرایی دستورالعمل‌ها (Instruction Reordering) توسط پردازنده یا کامپایلر منجر به خطاهای مرگبار همزمانی (Race Conditions) می‌شود.

اتمیسیته و std::atomic در مدرن ++C

برای جلوگیری از تداخل نخ‌ها در متغیرهای مشترک، از هدر <atomic> استفاده می‌شود:

  • متدهای پایه: load(), store(), exchange(), compare_exchange_weak(), compare_exchange_strong().
  • متدهای حسابی و بیتی ویژه اعداد صحیح: fetch_add(), fetch_sub(), fetch_and(), fetch_or(), fetch_xor().

حالات چهارگانه ترتیب حافظه (Memory Order Modes)

تصویر زیر ساختار ترتیبی و تگ‌های مدل حافظه ++C را نشان می‌دهد:

  1. سازگاری ترتیبی (Sequential Consistency - std::memory_order_seq_cst):
    • حالت پیش‌فرض در ++C؛ تضمین می‌کند که تمامی نخ‌ها بر سر ترتیب دقیق و واحد تمام عملیات حافظه به توافق برسند.
    • بیشترین جریمه عملکردی: کامپایلر و CPU تمام بهینه‌سازی‌های خط لوله را متوقف کرده و موانع حافظه سنگین (Memory Fences) صادر می‌کنند.
  2. ترتیب آزاد (Relaxed Ordering - std::memory_order_relaxed):
    • نقطه مقابل حالت ترتیبی؛ تنها اتمیک بودن همان عملیات را تضمین می‌کند و هیچ مانع یا ترتیبی برای دستورات قبل و بعد اعمال نمی‌کند.
    • بالاترین سرعت ممکن: برای متغیرهایی که نیازی به همگام‌سازی سایر بخش‌های حافظه ندارند (نظیر شمارنده‌های آمار یا شناسه‌های ترتیبی).
  3. همگام‌سازی رهاسازی-اکتساب (Release-Acquire):
    • استاندارد طلایی در سیستم‌های HFT: یک همگام‌سازی دوطرفه فوق‌العاده سریع میان نخ فرستنده و نخ گیرنده:
    • memory_order_release (سمت نویسنده): تضمین می‌کند تمام عملیات حافظه قبل از این نقطه، پیش از انتشار پرچم در حافظه تثبیت شوند.
    • memory_order_acquire (سمت خواننده): تضمین می‌کند خواندن‌های بعد از این پرچم، مقادیر جدید نوشته‌شده توسط نخ دیگر را ببینند.
  4. رهاسازی-مصرف (Release-Consume - std::memory_order_consume):
    • گونه سبک‌تری از Acquire که تنها متغیرهایی را که وابستگی مستقیم داده‌ای دارند همگام می‌کند.

۲. حذف تصمیمات زمان اجرا (Removing Runtime Decisions)

قانون بنیادین بهینه‌سازی HFT

هر تصمیمی که بتوان آن را در زمان کامپایل (Compile-Time) حل‌وفصل کرد، باید فوراً از مسیر بحرانی زمان اجرا (Runtime) حذف شود.

خطرات و هزینه‌های فاجعه‌بار توابع مجازی (Virtual Functions)

در شیءگرایی سنتی، پلی‌مورفیسم با کلمه کلیدی virtual پیاده‌سازی می‌شود:

هر کلاس دارای متد مجازی، یک جدول از اشاره‌گرهای توابع به نام vtable در حافظه دارد و هر شیء یک اشاره‌گر پنهان به نام vptr حمل می‌کند:

چرا توابع مجازی برای سیستم‌های کم‌تاخیر سم هستند؟

  1. ارجاع غیرمستقیم دوگانه (Double Indirection): برای فراخوانی متد، پردازنده ابتدا باید vptr را بخواند، سپس به vtable مراجعه کند و سپس به آدرس تابع بپرد (اتلاف ده‌ها چرخه کلاک).
  2. فلج شدن پیش‌بینی‌کننده انشعاب (Branch Predictor): پردازنده نمی‌تواند حدس بزند کدام تابع اجرا خواهد شد؛ در نتیجه پایپ‌لاین دستورات پاک می‌شود (Pipeline Flush).
  3. خطای کش فاجعه‌بار (Cache Misses): همان‌طور که در شکل ۸.۳ مشاهده می‌شود، اشیاء مشتق‌شده و جداول vtable در نقاط متفاوتی از رم قرار دارند که باعث تخلیه خطوط کش L1 Data و L1 Instruction می‌شود.
  4. عدم امکان درون‌خطی کردن (Inlining): کامپایلر هرگز نمی‌تواند یک تابع مجازی را Inline کند.

راهکار نخبگان HFT: چندریختی ایستا با الگوی CRTP

الگوی Curiously Recurring Template Pattern (CRTP) به ما امکان می‌دهد رفتار چندریختی را بدون حتی یک بایت هزینه زمان اجرا، بدون vptr و بدون vtable پیاده‌سازی کنیم:

// کلاس پایه تمپلیت که کلاس فرزند را به عنوان پارامتر دریافت می‌کند
template <typename Derived>
class OrderBookBase {
public:
    inline void process_order(int price, int qty) {
        // فراخوانی متد فرزند در زمان کامپایل بدون جدول مجازی!
        static_cast<Derived*>(this)->on_order_impl(price, qty);
    }
};

// کلاس مشتق‌شده اختصاصی
class FastOrderBook : public OrderBookBase<FastOrderBook> {
public:
    inline void on_order_impl(int price, int qty) {
        // منطق به‌روزرسانی دفترچه سفارشات با قابلیت کامل Inlining
    }
};

در این الگو، تمام پیوندها در زمان کامپایل حل می‌شوند، بدنه تابع مستقیماً Inline شده و پرش حافظه به صفر می‌رسد.


خاموش کردن RTTI

قابلیت Run-Time Type Information و دستور typeid باعث مصرف حافظه و کندی سیستم می‌شوند. در سیستم‌های HFT این قابلیت در فلگ‌های کامپایلر غیرفعال می‌شود:

g++ -O3 -fno-rtti -fno-exceptions ...

۳. مدیریت حافظه، قدرت constexpr و استثناها

حذف تخصیص پویا در مسیر بحرانی (Zero Dynamic Allocation)

توابع malloc و عملگر new به دلیل نیاز به پیمایش لیست‌های پیوندی آزاد هیپ در کرنل، تاخیرهای کاملاً تصادفی و غیرقطعی ایجاد می‌کنند. تمام اشیاء باید پیش از آغاز بازار در مخازن حافظه (Memory Pools) آماده شده باشند.


معجزه محاسبات زمان کامپایل با constexpr

کلمه کلیدی constexpr (و در C++17/20 consteval) پردازش‌ها را به زمان کامپایل منتقل می‌کند:

// محاسبه مقادیر پیپ، فاکتورهای ریسک و جداول ریاضی در زمان کامپایل
constexpr double calculate_tick_factor(int precision) {
    double factor = 1.0;
    for(int i = 0; i < precision; ++i) factor /= 10.0;
    return factor;
}
constexpr double USD_TICK = calculate_tick_factor(4); // مقدار نهایی در باینری ثبت می‌شود

هزینه سهمگین استثناها (Exceptions) در HFT

  • مدل استثنای بدون هزینه (Zero-cost Model): در شرایط عادی که خطایی رخ ندهد، کدهای try/catch سرباری ندارند.
  • فاجعه در زمان پرتاب (throw): به محض پرتاب یک استثناء، فرآیند باز کردن پشته (Stack Unwinding) فعال شده و هزاران چرخه کلاک پردازنده صرف جستجوی جدول توابع و مدیریت پشته می‌شود!
  • قانون HFT: در مسیر بحرانی ترید، استثناها کاملاً ممنوع هستند و به جای آن از کدهای وضعیت، پرچم‌های بولی یا ساختارهایی نظیر std::optional و std::expected استفاده می‌شود.

۴. شتاب‌دهی با قالب‌ها (Templates) و ظرایف کانتینرهای STL

قالب‌های سی‌پلاس‌پلاس کدهای عمومی را بدون هیچ افت سرعتی در زمان اجرا، به کدهای اختصاصی برای هر نوع داده تبدیل می‌کنند (Compile-time Substitution):

  • تخصیص ویژه قالب (Template Specialization): نوشتن نسخه‌های سفارشی بهینه‌شده برای یک نوع داده خاص.
  • فرابرنامه‌نویسی قالب‌ها (Template Metaprogramming): تولید کدهای بهینه در زمان ساخت باینری.

ملاحظات کانتینرهای STL در سیستم‌های کم‌تاخیر:

  • std::vector (پادشاه کانتینرها): به دلیل نگهداری داده‌ها در بلوک‌های حافظه پیوسته، حداکثر سازگاری را با خطوط کش ۶۴ بایتی پردازنده دارد و سریع‌ترین کانتینر برای HFT است.
  • std::map و std::set (ممنوع در مسیر بحرانی): این کانتینرها بر اساس درخت‌های قرمز-سیاه (Red-Black Trees) ساخته شده‌اند؛ هر گره حافظه در نقطه‌ای تصادفی از هیپ تخصیص یافته که باعث افت فاحش عملکرد و Cache Miss های پیاپی می‌شود.
  • std::unordered_map: با وجود دسترسی $O(1)$، به دلیل برخورد هش‌ها و تخصیص نودهای باکت، در مسیرهای فوق‌سریع نانوثانیه‌ای استفاده نمی‌شود و توسعه‌دهندگان HFT از Flat Hash Maps (جدول‌های هش مسطح مبتنی بر آرایه پیوسته) استفاده می‌کنند.

۵. تحلیل ایستای کد (Static Analysis)

تحلیل ایستا فرآیند بازبینی خودکار کدهای منبع بدون اجرای آن‌ها برای کشف خطاهای حافظه، دسترسی‌های همزمانی ناامن، نشت حافظه و نقض استانداردهای مهندسی است:

  • ابزارهای برتر HFT:
    • Clang Static Analyzer: تحلیلگر مبتنی بر مسیر در کامپایلر Clang.
    • PVS-Studio: ابزار صنعتی قدرتمند برای کشف باگ‌های ظریف محاسباتی و همزمانی در ++C.
    • Coverity و Cppcheck.

۶. مطالعه موردی: پیاده‌سازی سیستم معاملاتی FX و تکنیک Cache Warming

در انتهای فصل، نویسندگان به یک نکته فوق‌العاده حساس در پیاده‌سازی زنده سیستم معاملاتی ارز خارجی (FX) اشاره می‌کنند:

پدیده سرد شدن کش در مسیر ارسال سفارش (Cache Eviction on Critical Path)

در هر سیستم معاملاتی، تعداد تغییرات و پیام‌های دیتای بازار ورودی، هزاران برابر تعداد سفارش‌هایی است که ارسال می‌شوند. در نتیجه، مسیر مربوط به دیتای بازار مدام در کش پردازنده اجرا می‌شود، اما مسیر مربوط به «ارسال سفارش» به ندرت فعال می‌گردد. در لحظه‌ای که استراتژی پس از دقایق طولانی تصمیم به ارسال یک سفارش فوری می‌گیرد، کدهای ماژول سفارش از کش L1 و L2 اخراج شده‌اند و سیستم دچار تاخیر ناگهانی (Cache Miss) می‌شود!

راهکار طلایی نویسندگان: تکنیک گرم نگه‌داشتن کش (Cache Warming / Dummy Path)

سیستم در زمان‌های بیکاری، به صورت دوره‌ای سفارش‌های ساختگی و پوچ (Dummy Orders) را از درون کل ساختار سیستم تا آستانه ارسال عبور می‌دهد (بدون خروج به بورس)؛ با این کار:

  • کش داده (Data Cache) و کش دستورالعمل (Instruction Cache) پردازنده همواره گرم و آماده (Primed) می‌مانند.
  • پیش‌بینی‌کننده انشعاب (Branch Predictor) در آماده‌باش کامل قرار می‌گیرد.
  • به محض صدور سیگنال واقعی معامله، سفارش در کمترین نانوثانیه‌های ممکن شلیک می‌شود!

خلاصه و جمع‌بندی فصل هشتم (Summary)

در این فصل، پیشرفته‌ترین ابزارهای بهینه‌سازی سی‌پلاس‌پلاس را آموختیم:

  1. استفاده از مدل‌های حافظه Release-Acquire در همگام‌سازی‌های بدون قفل.
  2. حذف توابع مجازی و vtable با الگوی قدرتمند CRTP.
  3. بهره‌گیری از constexpr برای محاسبات زمان کامپایل و حذف استثناها از مسیر بحرانی.
  4. رعایت سخت‌گیرانه چیدمان حافظه با std::vector و جداول هش مسطح.
  5. تکنیک حیاتی گرم نگه داشتن کش (Cache Warming) برای جلوگیری از شوک تاخیر در شلیک سفارش‌ها.

در فصل بعدی (09 - جاوا و معماری Low-Latency با JVM)، به سراغ دنیای زبان جاوا خواهیم رفت و چگونگی بهینه‌سازی ماشین مجازی جاوا (JVM)، رام کردن Garbage Collector و پیاده‌سازی معماری افسانه‌ای LMAX Disruptor را بررسی خواهیم کرد!

جاوا و معماری Low-Latency با ماشین مجازی

(Java and JVM for Low-Latency Systems)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۲۱۹ تا ۲۴۸


مقدمه

هنگامی که سخن از معاملات فرکانس بالا (HFT) به میان می‌آید، معمولاً زبان جاوا اولین گزینه‌ای نیست که به ذهن خطور می‌کند. دوره طولانی گرم شدن ماشین مجازی (JVM Warm-up)، لایه انتزاعی ماشین مجازی و از همه بدنام‌تر، پدیده توقف‌های ناگهانی زباله‌روب (Garbage Collector) همواره موانعی بزرگ برای برنامه‌نویسان سیستم‌های کم‌تاخیر تلقی شده‌اند.

با این وجود، اگر توسعه‌دهنده به درستی سازوکارهای درونی JVM را درک کرده و هوشمندانه کدنویسی کند، جاوا می‌تواند در محیط‌های با تاخیر میکروثانیه عملکردی شگفت‌انگیز داشته باشد. در این فصل می‌آموزیم:

  • معماری لایه‌های حافظه در JVM و زنجیره کامپایل بایت‌کد
  • مهار زباله‌روب (GC)، جلوگیری از پدیده Stop-the-World و برنامه‌نویسی بدون تخصیص حافظه (Zero-Allocation)
  • کامپایل چندلایه (Tiered Compilation) و تکنیک‌های گرم کردن JVM
  • بنچمارک دقیق با JMH و مدیریت تردها با کتابخانه Java-Thread-Affinity
  • معماری انقلابی LMAX Disruptor و صف‌های حلقوی بدون قفل
  • لاگ‌گیری ناهمگام و اتصال به دیتابیس بدون مسدودسازی مسیر بحرانی

۱. مبانی معماری جاوا و ماشین مجازی (JVM)

تصویر زیر زنجیره استاندارد کامپایل و اجرای برنامه‌های جاوا را نشان می‌دهد:

کامپایلر جاوا (javac) بر خلاف ++C مستقیماً فایل اجرایی باینری ماشین تولید نمی‌کند، بلکه کدهای منبع را به بایت‌کد (Bytecode) مستقل از بستر سخت‌افزاری تبدیل می‌نماید. ماشین مجازی جاوا (JVM) مسئولیت اجرای این بایت‌کد را روی هر سیستم‌عامل بر عهده دارد.


تقسیم‌بندی فضاهای حافظه در JVM

تصاویر زیر ساختار درونی نواحی حافظه ماشین مجازی جاوا را به تصویر کشیده‌اند:

نواحی کلیدی حافظه:

  1. حافظه پشته (JVM Stacks): برای هر نخ (Thread) یک پشته مجزا تخصیص داده می‌شود که فریم‌های فراخوانی توابع و متغیرهای محلی بدوی (Primitives) را با سرعت فوق‌العاده بالا نگهداری می‌کند.
  2. ناحیه متدها و متاسپیس (Metaspace / Method Area): ذخیره بایت‌کد کلاس‌ها و تعاریف متادیتا.
  3. حافظه هیپ (JVM Heap): تمام اشیاء و کانتینرهای داینامیک در هیپ تخصیص می‌یابند و هدف اصلی زباله‌روب (GC) هستند:
    • نسل جوان (Young Generation): شامل بخش ورود اولیه اشیاء به نام Eden و دو بخش بازماندگان به نام‌های Survivor 0 (S0) و Survivor 1 (S1).
    • نسل مسن (Old / Tenured Generation): اشیایی که از چرخه‌های متعدد زباله‌روبی جان سالم به در برده‌اند به این بخش منتقل می‌شوند.

۲. مهار زباله‌روب و کدنویسی بدون زباله (Zero-Allocation)

هنگامی که جاوا در سال ۱۹۹۶ معرفی شد، وعده بزرگ آن پایان دادن به خطای وحشتناک Segmentation Fault بود که توسعه‌دهندگان C/C++ مدام با آن دست به گریبان بودند. جاوا مدیریت اشاره‌گرها و آزادسازی حافظه را از دست برنامه‌نویس خارج کرد و به زباله‌روب (Garbage Collector) سپرد.

کابوس HFT: توقف‌های Stop-the-World (STW)

در حین اجرای فرآیند پاکسازی حافظه در زباله‌روب‌های سنتی، سیستم‌عامل مجبور است تمام تردهای پردازشی برنامه معاملاتی را کاملاً متوقف (Freeze) کند تا نخ‌های تمیزکننده حافظه بتوانند ریشه‌های فعال (Live Roots) را بررسی کنند. یک عملیات Major GC می‌تواند به ازای هر گیگابایت رم، صدها میلی‌ثانیه یا حتی چند ثانیه برنامه را تعلیق کند؛ اتفاقی که در بازارهای مالی به معنای ضررهای میلیون دلاری است!


الگوریتم‌های مدرن GC در جاوا:

  • Parallel GC: برای سیستم‌های با توان عملیاتی پردازشی بالا، اما همراه با توقف‌های طولانی.
  • G1 GC و CMS: تلاش برای تقسیم کار زباله‌روبی به بلوک‌های کوچک‌تر.
  • ZGC و Shenandoah GC: نسل نوین زباله‌روب‌های فوق کم‌تاخیر در نسخه‌های جدید جاوا که توقف‌های STW را به کمتر از ۱ میلی‌ثانیه رسانده‌اند.
  • Azul Zing JVM (C4 Algorithm): ماشین مجازی تجاری و تخصصی وال‌استریت با قابلیت Pauseless GC که بدون حتی ۱ میلی‌ثانیه توقف، زباله‌روبی را به طور کاملاً همزمان با ترید انجام می‌دهد.

قوانین طلایی کدنویسی Zero-Allocation در جاوا برای HFT:

  1. پرهیز از اتوباکسینگ (Avoid Autoboxing): تبدیل خودکار میان نوع‌های بدوی (int, long, double) و اشیاء معادل آن‌ها (Integer, Long, Double) هزاران شیء زائد موقت در ثانیه تولید می‌کند. در کدهای HFT باید منحصراً از تایپ‌های Primitive استفاده شود.
  2. استفاده از مخازن اشیاء (Object Pooling): هرگز در مسیر بحرانی ترید نباید عملگر new Order() اجرا شود؛ بلکه اشیاء سفارش از قبل به تعداد معین ساخته شده و تنها فیلدهای آن‌ها بازنویسی می‌شوند.
  3. تخصیص حافظه خارج از هیپ (Off-Heap Memory): استفاده از بافرهای مستقیم حافظه رم با ByteBuffer.allocateDirect() یا فراخوانی‌های مستقیم از طریق sun.misc.Unsafe؛ این حافظه‌ها در فضای خارج از دیدرس JVM تخصیص می‌یابند و زباله‌روب هرگز به آن‌ها کاری ندارد!


۳. کامپایل لایه‌ای (Tiered Compilation) و گرم کردن JVM

جاوا از کامپایلرهای پویا و درجا (JIT - Just-In-Time) بهره می‌برد:

  • کامپایلر C1 (Client Compiler): کامپایل بسیار سریع با بهینه‌سازی‌های پایه.
  • کامپایلر C2 (Server Compiler): کامپایل پیشرفته با بهینه‌سازی‌های عمیق، درون‌خطی کردن کدهای داغ (Inlining) و تبدیل به کد ماشین فوق بهینه.

تصاویر زیر معماری ۵ لایه کامپایل چندسطحی در JVM را نشان می‌دهند:

  • سطح ۰: تفسیر خالص بایت‌کد (Interpreted).
  • سطوح ۱ تا ۳: کامپایل بایت‌کد با کامپایلر C1 با مقادیر مختلف مانیتورینگ کارایی (Profiling).
  • سطح ۴: کامپایل نهایی با کامپایلر فوق‌بهینه C2.

چالش پرفورمنس در شروع ترید و تکنیک Code Warmer:

در ابتدای شروع برنامه، کدها هنوز تفسیر می‌شوند یا در سطوح پایین C1 قرار دارند و سیستم به شدت کند است. برای اینکه از نخستین میلی‌ثانیه باز شدن بازار به بالاترین کارایی C2 دست یابیم:

  1. غیرفعال‌سازی سطوح میانی: با پارامتر -XX:-TieredCompilation متدها پس از رسیدن به آستانه، مستقیماً وارد سطح فوق بهینه C2 می‌شوند.
  2. کد گرم‌کننده (Code Warmer): نوشتن روتین‌های تست که در زمان پیش‌گشایش بازار، هزاران تیک و سفارش ساختگی را از درون توابع استراتژی عبور می‌دهند تا JVM پیش از آغاز واقعی بازار، تمام متدها را به کدهای سطح ۴ کامپایل کند!
  3. فناوری GraalVM AOT: کامپایل پیش از اجرای برنامه به فایل باینری نیتیو.

بنچمارک علمی با JMH (Java Microbenchmark Harness)

اندازه‌گیری تاخیر در جاوا بسیار فریبنده است؛ زیرا بهینه‌ساز JIT ممکن است کدهای تستی را که نتیجه آن‌ها استفاده نمی‌شود، کلاً حذف کند (Dead Code Elimination). چارچوب رسمی OpenJDK بنام JMH با ایجاد Blackhole مانع این بهینه‌سازی‌های کاذب شده و تاخیرهای نانوثانیه‌ای را دقیق می‌سنجد.


۴. مدیریت تردها و پین کردن به هسته‌ها در جاوا

افزودن بی‌رویه تردها به سیستم معاملاتی که پردازنده‌محور (CPU-bound) است، تنها باعث افزایش کانتکست سوئیچ و کندی سیستم می‌شود:

پین کردن تردهای جاوا به هسته CPU (Java-Thread-Affinity):

جاوا به صورت بومی متدی برای الصاق ترد به هسته فیزیکی ندارد. غول‌های HFT از کتابخانه متن‌باز Java-Thread-Affinity (توسعه‌یافته توسط Peter Lawrey در OpenHFT) استفاده می‌کنند تا نخ‌های جاوا مستقیماً به هسته‌های اختصاصی پین شوند:

try (AffinityLock al = AffinityLock.acquireLock()) {
    // اجرای حلقه حیاتی پردازش مارکت دیتا منحصراً روی یک هسته ایزوله‌شده
    while (running) {
        processNextMarketUpdate();
    }
}

۵. صف‌های وظایف فوق‌سریع و معماری افسانه‌ای LMAX Disruptor

صف‌های استاندارد همزمانی جاوا نظیر ArrayBlockingQueue برای سیستم‌های کم‌تاخیر ناکارآمد هستند؛ زیرا از Mutex و قفل‌های سنگین بر سر و ته صف استفاده می‌کنند.

بورس مشتقات LMAX و پیدایش Disruptor:

در سال ۲۰۱۱، صرافی LMAX لندن برای رفع مشکل تاخیر پلتفرم معاملاتی خود، فریم‌ورک Disruptor را خلق کرد. این سامانه قادر است بیش از ۶ میلیون سفارش در ثانیه را با تاخیر زیر ۱ میکروثانیه در بستر جاوا پردازش کند!

graph LR
    P["تولیدکننده (Gateway)"] -->|"افزایش Sequence بدون قفل"| RB["Ring Buffer از پیش تخصیص‌یافته"]
    RB -->|"مصرف همزمان"| C1["موتور ژورنال‌سازی"]
    RB -->|"مصرف همزمان"| C2["موتور ریسک"]
    C1 --> C3["موتور تطبیق (Matching Engine)"]
    C2 --> C3

اسرار مهندسی معماری Disruptor:

  1. صف حلقوی پیوسته (Ring Buffer): آرایه‌ای با اندازه ثابت توان دو که تمام اشیاء رویدادها در زمان استارت سیستم درون آن تخصیص یافته‌اند (Zero Allocation).
  2. شمارنده‌های توالی اتمیک (Sequences): هر تولیدکننده و مصرف‌کننده یک شمارنده عددی ۶۴ بیتی مستقل دارد که با عملیات اتمیک پردازنده جلو می‌رود و نیاز به قفل ندارد.
  3. جلوگیری از اشتراک کاذب کش (False Sharing Prevention):
    • هنگامی که دو متغیر مستقل متعلق به دو ترد مختلف درون یک خط کش ۶۴ بایتی مشترک بنشینند، تغییر یکی باعث بی‌اعتبار شدن کل خط کش در پردازنده دیگر می‌شود.
    • دیسراپتور با افزودن بایت‌های خالی پرکننده (Cache-Line Padding) در اطراف متغیرها تضمین می‌کند که هر متغیر حیاتی منحصراً روی یک خط کش ۶۴ بایتی مستقل بنشیند!

۶. لاگ‌گیری و دسترسی به دیتابیس در جاوا

هرگز از سیستم پیش‌فرض java.util.logging استفاده نکنید زیرا بافربندی مناسبی ندارد.

  • راهکار استاندارد: استفاده از فریم‌ورک Log4j2 در حالت کاملاً ناهمگام (Async Logging) که در هسته درونی خود مستقیماً از LMAX Disruptor برای انتقال نانوثانیه‌ای لاگ‌ها به حافظه رم استفاده می‌کند.
  • جداسازی پایگاه داده: کارهای دیتابیس و لاگ‌های سنگین از طریق سوکت‌های IPC به فرآیندهای مجزا در هسته‌های دیگر سپرده می‌شوند تا برنامه معاملاتی هرگز منتظر دیسک نماند.

خلاصه و جمع‌بندی فصل نهم (Summary)

در این فصل آموختیم:

  1. رام کردن زباله‌روب جاوا با رعایت اصول Zero-Allocation، پرهیز از Autoboxing و استفاده از Off-Heap Memory.
  2. مهار زمان‌بندی JIT و گرم کردن کدهای بحرانی به سطح ۴ کامپایلر C2 قبل از آغاز ترید.
  3. پین کردن تردهای جاوا به هسته‌های ایزوله‌شده پردازنده با کتابخانه Java-Thread-Affinity.
  4. شاهکار مهندسی LMAX Disruptor برای انتقال بدون قفل و چند میلیونی سفارشات با پر کردن خطوط کش (Cache-Line Padding).

در فصل بعدی (10 - پایتون در تحلیل و ترکیب با سی‌پلاس‌پلاس)، به بررسی نقش استراتژیک پایتون در HFT، چرایی کندی آن و نحوه اتصال فوق‌سریع آن به کدهای ++C با ابزارهای Ctypes، CFFI، Boost.Python و Cython خواهیم پرداخت!

پایتون در تحلیل و اتصال به ++C

(Python – Interpreted but Open to High Performance)

مشخصات فصل

مرجع اصلی: کتاب Developing High-Frequency Trading Systems (انتشارات Packt) نویسندگان: سباستین دونادیو، سوراو گوش، جان ریزو، رومن روسیه محدوده صفحات در کتاب: صفحات ۲۴۹ تا ۲۶۴ بخش سوم کتاب: پیاده‌سازی و کدنویسی سیستم‌های HFT (Part 3)


مقدمه

ورود به دنیای معاملات فرکانس بالا (HFT) با زبان پایتون در نگاه نخست امری متناقض به نظر می‌رسد؛ زیرا پایتون هرگز برای سرعت بالا و تاخیر کم طراحی نشده است. اما پایتون محبوب‌ترین زبان برنامه‌نویسی جهان در حوزه علوم داده، یادگیری ماشین و تحلیل‌های مالی است (بیش از یک‌سوم کدهای جدید جهان با پایتون نوشته می‌شوند) و غنی‌ترین اکوسیستم کتابخانه‌ای را در اختیار معامله‌گران قرار می‌دهد.

آیا می‌توان از پایتون در معاملات فرکانس بالا استفاده کرد؟ پاسخ مثبت است، اما از طریق یک «معماری هیبریدی و هوشمندانه»: تحلیل‌های عمیق، مدل‌سازی‌های هوش مصنوعی و مدیریت کلان در پایتون انجام می‌شوند و مسیر بحرانی با تاخیر میکروثانیه‌ای به کتابخانه‌های ++C واگذار می‌گردد!

در این فصل مباحث زیر تشریح می‌شوند:

  • نقش پایتون در تحلیل داده‌های مالی و گام‌های ۶ گانه خلق استراتژی معاملاتی
  • دلایل فنی کندی پایتون: مفسر PVM، اشیاء سنگین PyObject و قفل سراسری مفسر (GIL)
  • بررسی کتابخانه‌های کلیدی: NumPy، Pandas، SciPy و Scikit-Learn
  • پل‌های ارتباطی ۴ گانه برای اتصال پایتون به ++C: بایندینگ‌های Boost.Python، کدهای Cython، کتابخانه‌های ctypes/CFFI و مولد خودکار SWIG
  • معماری تعامل پایتون و ++C و موازی‌سازی چندپروسسی

۱. جایگاه پایتون در تحلیل‌های مالی و توسعه استراتژی

پایتون زبان اول معامله‌گران کمی (Quants) برای کشف الگوها و آزمودن فرضیه‌های بازار است. تصویر زیر گام‌های استاندارد ساخت یک استراتژی معاملاتی را نمایش می‌دهد:

مراحل طراحی استراتژی:

  1. گردآوری داده‌های بازار (Market Data Collection): خواندن فیدها و ذخیره تیک‌ها.
  2. تحلیل اکتشافی داده‌ها (EDA): پاکسازی و مصورسازی رفتار قیمت با پانداس و مت‌پلات‌لیب.
  3. تولید ویژگی‌ها و سیگنال‌ها (Signal Generation): محاسبه میانگین‌های متحرک، شاخص‌های آماری و واگرایی‌ها.
  4. مدل‌سازی پیش‌بین با یادگیری ماشین (Machine Learning): استفاده از کتابخانه Scikit-Learn برای مدل‌سازی رگرسیون و کشف روابط همبستگی میان دارایی‌ها (مانند استراتژی آربیتراژ آماری).
  5. بک‌تست‌گیری (Backtesting): سنجش بازدهی، ضریب شارپ (Sharpe Ratio) و حداکثر افت سرمایه (Drawdown) روی داده‌های تاریخی.
  6. اجرای زنده (Live Execution): اتصال استراتژی به سیستم معاملاتی جهت ارسال سفارش به بورس.

۲. چرا پایتون کند است؟ (Why is Python Slow?)

برای درک محدودیت‌های پایتون، باید زنجیره اجرای آن را شناخت:

کدهای منبع پایتون (.py) ابتدا توسط مفسر به بایت‌کد (.pyc) تبدیل شده و سپس ماشین مجازی پایتون (PVM - Python Virtual Machine) در محیط زمان اجرا (Runtime) این بایت‌کدها را خط‌به‌خط تفسیر و اجرا می‌کند.

۵ عامل بنیادین کندی زبان پایتون در HFT:

  1. تفسیر خط‌به‌خط در زمان اجرا (Interpreted Language): بر خلاف زبان‌های بومی نظیر ++C که مستقیماً به دستورالعمل‌های اسمبلی و باینری بهینه پردازنده کامپایل می‌شوند، پایتون کدها را در لحظه تفسیر می‌کند که صدها برابر کندتر است.
  2. نوع‌گذاری پویا (Dynamically Typed): پایتون در زمان کامپایل از نوع متغیرها اطلاعی ندارد. در هر عملیات ریاضی ساده (مانند جمع دو عدد)، مفسر باید بررسی کند که آیا متغیرها عدد هستند، رشته هستند یا شیء؛ این ارزیابی‌های مداوم چرخه‌های پردازنده را تلف می‌کنند.
  3. اشیای بسیار سنگین حافظه (PyObject): در ++C، یک عدد صحیح uint8_t تنها ۱ بایت و یک int تنها ۴ بایت فضا در رم می‌گیرد. اما در پایتون، یک عدد صحیح ساده یک شیء کامل در هیپ است که حداقل ۲۸ بایت حافظه مصرف می‌کند (شامل شمارنده ارجاع، اشاره‌گر نوع شیء و مقدار)!
  4. قفل سراسری مفسر (GIL - Global Interpreter Lock): بزرگ‌ترین مانع موازی‌سازی در CPython؛ قفل GIL تضمین می‌کند که در هر لحظه تنها یک ترد می‌تواند مفسر پایتون را اجرا کند. این یعنی حتی اگر یک سرور ۶۴ هسته‌ای غول‌پیکر داشته باشید، تردهای پایتون نمی‌توانند به طور همزمان از چند هسته برای پردازش موازی استفاده کنند!
  5. آلودگی کش و پراکندگی حافظه: به دلیل تخصیص مداوم اشیاء در نقاط گوناگون هیپ، داده‌ها در خطوط کش ۶۴ بایتی کنار هم قرار نمی‌گیرند و سیستم با سیلاب Cache Miss روبه‌رو می‌شود.

۳. کتابخانه‌های کلیدی پایتون در اکوسیستم مالی

  • NumPy: ستون فقرات پردازش‌های محاسباتی پایتون؛ استفاده از آرایه‌های پیوسته فشرده در زبان C با قابلیت محاسبات برداری بر روی خطوط کش پردازنده.
  • Pandas: قوی‌ترین ابزار برای پردازش سری‌های زمانی مالی و تحلیل دیتافریم‌های معاملات.
  • SciPy: جعبه‌ابزار محاسبات علمی، فیت کردن توزیع‌های آماری دنباله‌پهن (Fat-tail) و محاسبات ماتریسی.
  • Scikit-Learn: پیاده‌سازی سریع مدل‌های هوش مصنوعی و یادگیری ماشین.
  • Scrapy و BeautifulSoup: ابزارهای وب‌اسکرپینگ برای استخراج اخبار اقتصادی و داده‌های فاندامنتال.

۴. پل‌های ارتباطی ۴ گانه برای اتصال پایتون به ++C

برای ترکیب انعطاف‌پذیری پایتون با سرعت نانوثانیه‌ای ++C، از ابزارهای ایجاد واسط (Bindings) استفاده می‌شود:

۱. کتابخانه Boost.Python

این کتابخانه بخشی از مجموعه معتبر Boost است که امکان دسترسی مستقیم پایتون به کلاس‌ها، اشیاء و توابع ++C را فراهم می‌سازد:

// کدهای C++
#include <boost/python.hpp>
int add(int a, int b) { return a + b; }

BOOST_PYTHON_MODULE(math_ext) {
    using namespace boost::python;
    def("add", add);
}

پس از کامپایل به عنوان یک کتابخانه اشتراکی (.so در لینوکس)، مستقیماً در پایتون ایمپورت می‌شود:

import math_ext
result = math_ext.add(1, 2) # با سرعت بومی C++ اجرا می‌شود

۲. فریم‌ورک قدرتمند Cython (انتخاب اول حرفه‌ای‌ها)

سایکلون زبانی است که کدهای شبه‌پایتونی را با افزودن تایپ‌های استاتیک C مستقیماً به کدهای بهینه C/C++ کامپایل می‌کند:

# فایل add.pyx
def int add_fast(int a, int b):
    return a + b

با اجرای cythonize، این کد به یک اکستنشن باینری فوق‌سریع تبدیل می‌شود که سرعت اجرای آن تا ۱۰۰ برابر بیشتر از پایتون خالص است.


۳. کتابخانه‌های ctypes و CFFI

  • کتابخانه استاندارد ctypes: مزیت بزرگ آن حضور پیش‌فرض در کتابخانه استاندارد پایتون بدون نیاز به نصب هیچ ابزار خارجی است:
import ctypes
# بارگذاری مستقیم فایل اشتراکی C
lib = ctypes.CDLL("./libtrading.so")
lib.process_packet.argtypes = [ctypes.c_char_p, ctypes.c_int]
lib.process_packet(b"8=FIX.4.4...", 100)
  • کتابخانه CFFI (C Foreign Function Interface): واسط مدرن‌تری که با دریافت کدهای هدر C (.h) کار می‌کند و با موتور PyPy سازگاری بی‌نظیری دارد.

۴. ابزار خودکار SWIG (Simplified Wrapper and Interface Generator)

ابزاری مناسب برای پروژه‌های بزرگ صنعتی؛ با نوشتن یک فایل رابط (math.i)، کدهای فراخوانی را به صورت خودکار برای پایتون تولید می‌کند.


۵. معماری هیبریدی شتاب‌دهی پایتون در HFT

تصویر زیر الگوی تعامل میان پایتون و کتابخانه‌های کم‌تاخیر ++C را نشان می‌دهد:

نحوه عملکرد سیستم هیبریدی:

  1. پایتون به عنوان کنترل‌کننده (High-Level Controller):
    • بارگذاری مدل‌ها و ضرایب بهینه‌شده آماری.
    • ارتباط با دیتابیس‌ها و لاگ‌های غیربحرانی.
    • رابط کاربری و مانیتورینگ.
  2. هسته ++C در کتابخانه اشتراکی (.so):
    • اتصال به کارت شبکه با فناوری Kernel Bypass.
    • به‌روزرسانی دفترچه سفارشات و پردازش پکت‌های باینری.
    • شلیک مستقیم سفارش‌ها به بورس در کسری از میکروثانیه بدون دخالت پایتون!
  3. دور زدن قفل GIL در پردازش داده‌ها: استفاده از کتابخانه‌های multiprocessing یا joblib.Parallel به جای تردینگ پایتون؛ اجرای چند فرآیند مجزا با مفسرهای مستقل روی هسته‌های گوناگون پردازنده.

خلاصه و جمع‌بندی فصل دهم (Summary)

در این فصل آموختیم:

  1. پایتون به دلیل ماهیت مفسری، اشیاء سنگین هیپ، و قفل GIL به تنهایی توانایی رقابت در سرعت‌های میکروثانیه‌ای را ندارد.
  2. بهترین راهبرد در HFT، استفاده از معماری هیبریدی (ترکیب پایتون و ++C) است.
  3. تسلط بر ابزارهای Cython و ctypes/CFFI برای اتصال بدون تاخیر میان اسکریپت‌های تحلیلی و موتورهای معاملاتی کم‌تاخیر.

در فصل پایانی و یازدهم (11 - سخت‌افزارهای FPGA و سیستم‌های کریپتو)، به بررسی اوج فناوری HFT خواهیم پرداخت: برنامه‌نویسی تراشه‌های مدار مجتمع FPGA در مقیاس نانوثانیه و گسترش سیستم‌های HFT به بازارهای ۲۴/۷ رمزارزها (Cryptocurrency)!

سخت‌افزارهای FPGA و سیستم‌های کریپتو

(Chapter 11: High-Frequency FPGA and Crypto)


۱. مقدمه و افق‌های نوین HFT

به آخرین فصل از این کتاب جامع خوش آمدید. در فصول پیشین، نحوه بهینه‌سازی پشته‌های نرم‌افزاری سنتی را بررسی کردیم و دیدیم که چگونه با بهره‌گیری از تکنیک‌های پیشرفته در زبان‌های C++، جاوا و پایتون، می‌توان تاخیر رفت‌وبرگشت تیک-به-معامله (Tick-to-Trade) را تا مرز ۵ میکروثانیه پایین آورد.

اما در عرصه رقابت فوق‌سریع بازارهای مالی مدرن، جنگ بر سر نانوثانیه‌ها است. در این فصل، فراتر از مرزهای نرم‌افزار قدم گذاشته و وارد حیطه شتاب‌دهی سخت‌افزاری با استفاده از آرایه‌های گیت منطقی برنامه‌پذیر (FPGA) می‌شویم تا تاخیر سامانه را به زیر ۵۰۰ نانوثانیه کاهش دهیم.

سپس در بخش دوم فصل، ساختار بازارهای نوظهور ارزهای دیجیتال (Cryptocurrencies) را بررسی خواهیم کرد؛ بازاری ۲۴ ساعته با پویایی‌های نقدینگی، کارمزدها، و ساختارهای میکرومارکت کاملاً متفاوت نسبت به بازارهای سنتی سهام. در پایان، چگونگی پیاده‌سازی و استقرار زیرساخت‌های معاملاتی فرکانس بالا در بسترهای محاسبات ابری (Cloud Computing / CSPs) را به تفصیل تشریح می‌کنیم.


۲. طیف کارایی پردازنده‌ها: تفاوت CPU، ASIC و FPGA

برای درک جایگاه FPGA در معاملات الگوریتمی، باید طیف عملکرد پردازنده‌ها و تراشه‌های سیلیکونی را بررسی کنیم:

graph LR
    CPU["پردازنده‌های چندمنظوره (CPU)
انعطاف‌پذیری حداکثر | تاخیر میکروثانیه"]
    FPGA["آرایه گیت برنامه‌پذیر (FPGA)
سخت‌افزار موازی قابل برنامه‌ریزی | تاخیر نانوثانیه"]
    ASIC["مدارهای مجتمع با کاربرد خاص (ASIC)
سخت‌افزار ثابت سیلیکونی | سریع‌ترین، هزینه NRE سرسام‌آور"]
    
    CPU -->|کاهش تاخیر و افزایش تخصص| FPGA
    FPGA -->|حداکثر سرعت و عدم انعطاف| ASIC

۱. پردازنده‌های مرکزی چندمنظوره (CPUs)

  • مزایا: مجموعه دستورالعمل‌های همه‌منظوره (ISA نظیر x86_64 و ARM)، انعطاف‌پذیری فوق‌العاده در پیاده‌سازی انواع الگوریتم‌ها و امکان کامپایل سریع کدهای C++ و جاوا.
  • معایب در HFT: اجرای متوالی دستورات (Sequential Instruction Pipeline)، سربار وقفه‌ها (Hardware Interrupts)، سوئیچ زمینه (Context Switch)، پرش‌های شرطی خطا (Branch Misprediction) و نوسانات ناشی از حافظه کش (Cache Jitter). تاخیر حاصل در بهترین حالت در محدوده میکروثانیه‌ها باقی می‌ماند.

۲. مدارهای مجتمع با کاربرد خاص (ASICs)

  • مزایا: گیت‌های منطقی مستقیماً در کارخانه روی سیلیکون حک شده‌اند. بالاترین کارایی، کمترین مصرف توان و حداقل تاخیر ممکن در فیزیک سیلیکون.
  • معایب: عدم امکان بازبرنامه‌ریزی (Zero Flexibility). اگر در الگوریتم باگی کشف شود یا صرافی پروتکل شبکه خود را تغییر دهد، تراشه غیرقابل استفاده خواهد شد. همچنین هزینه‌های مهندسی اولیه (NRE) و فرآیند تولید ماسک سیلیکونی ماه‌ها یا سال‌ها طول کشیده و میلیون‌ها دلار هزینه دارد.

۳. آرایه‌های گیت برنامه‌پذیر میدانی (FPGAs)

  • نقطه تعادل طلایی میان سرعت سخت‌افزار ASIC و انعطاف‌پذیری نرم‌افزار CPU.
  • تراشه‌ای حاوی میلیون‌ها بلوک منطقی پیکربندی‌پذیر (CLBs)، جداول جستجو (LUTs)، فلیپ‌فلاپ‌ها، بلوک‌های حافظه داخلی (Block RAM) و ضرب‌کننده‌های دیجیتال (DSP Blocks) است که اتصالات الکتریکی داخلی آنها پس از ساخت و در محیط کاری توسط برنامه‌نویس قابل تغییر است.
  • نخستین FPGA تجاری در سال ۱۹۸۵ اختراع شد (توسط راس فریمن، بنیان‌گذار شرکت Xilinx). تراشه‌های مدرن امروزی از شرکت‌های بزرگی چون AMD (Xilinx)، Intel (Altera) و Achronix دارای میلیاردها ترانزیستور بوده و می‌توانند پیچیده‌ترین پایپ‌لاین‌های پردازش شبکه و ریاضی را به صورت بلادرنگ اجرا کنند.

۳. ویژگی‌های بنیادین معماری FPGA در HFT

۱. موازی‌سازی واقعی در سطح مدار سخت‌افزاری (Hardware-Level Parallelism)

برخلاف CPUها که دستورات را به صورت متوالی یا با تعداد محدودی هسته فیزیکی (Thread Concurrency) اجرا می‌کنند، FPGA منطق مدار را پیاده‌سازی می‌کند. شما می‌توانید ده‌ها پایپ‌لاین کاملاً مستقل بسازید که همگی در همان سیکل ساعت فیزیکی (Clock Cycle) فعال باشند. پارس کردن پکت‌های ورودی، بررسی فیلترهای ریسک و تصمیم‌گیری استراتژی می‌توانند در موازات صددرصد فیزیکی رخ دهند.

۲. قطعیت زمانی بی‌نقص (Zero-Jitter Determinism)

همان‌طور که در 04 - زیرساخت سخت‌افزار و OS توضیح داده شد، در پردازنده‌های سنتی تاخیر صدک‌های بالا ($p99$ و $p99.9$) به دلیل وقفه‌های هسته لینوکس و رفتارهای پیش‌بینی‌ناپذیر کش دچار پرش می‌شود. در FPGA، داده‌ها در خطوط لوله فیزیکی (Pipelines) حرکت می‌کنند. اگر پردازش یک پیام ۸ سیکل کلاک طول بکشد، این زمان در ۱۰۰٪ مواقع دقیقاً ۸ سیکل کلاک خواهد بود: $$p50 = p90 = p99 = p99.9 = \text{Constant Latency}$$

۳. حذف کامل سربار سیستم‌عامل (Bypassing OS & Kernel)

در طراحی FPGA، سیستم‌عاملی وجود ندارد. هیچ کرنل، لایه انتزاعی درایور، سوئیچ زمینه یا پشته بافرینگ میانی در کار نیست؛ بسته‌های شبکه مستقیماً از گیرنده‌های فیزیکی (SerDes / Transceivers) وارد گیت‌های منطقی می‌شوند.

۴. استک شبکه سخت‌افزاری (Hardware Network Stacks)

یکی از نخستین گام‌ها در شتاب‌دهی سامانه‌های معاملاتی، پیاده‌سازی لایه‌های شبکه روی FPGA است:

  • پردازش لایه فیزیکی فریم‌های Ethernet
  • فیلتر و باز کردن پکت‌های پروتکل اینترنت (IPv4/IPv6)
  • پردازش بی‌درنگ بسته‌های بدون اتصال UDP (پروتکل استاندارد توزیع فید بازار)
  • پیاده‌سازی پشته سخت‌افزاری TCP یا معماری‌های ترکیبی (Hybrid Stacks: ترافیک عادی استقرار توسط هاست و پکت‌های حیاتی سفارش‌گذاری مستقیماً توسط FPGA تولید و شلیک می‌شوند).

۴. اجزای سامانه معاملاتی مبتنی بر FPGA

یک سامانه معاملاتی FPGA معمولاً در معماری Bump-in-the-Wire یا به عنوان کارت شتاب‌دهنده PCIe متصل به هاست پیاده‌سازی می‌شود:

graph LR
    NIC["فیبر نوری مستقیم صرافی
(10GbE / 25GbE PHY)"] --> Parser["هندلر فید سخت‌افزاری
(FIX / FAST / ITCH / MDP3.0 Parser)"]
    Parser --> Book["موتور بازسازی بوک
(L2/L3 Order Book in BRAM)"]
    Book --> Alpha["محاسبه سیگنال آلفا
(DSP Math Engine)"]
    Alpha --> Risk["فیلتر ریسک پیش از معامله
(Pre-Trade Risk Checks)"]
    Risk --> OUCH["تولید پکت سفارش
(OUCH / Binary Order Injection)"]
    OUCH --> NIC
    
    Parser -.->|DMA Log| Host["حافظه رم هاست و پردازنده C++
(لاگینگ و پایش)"]

۱. پردازشگرهای فید داده بازار (Market Data Feed Handlers)

پروتکل‌های متداول فید بازار مانند NASDAQ ITCH، CME MDP 3.0، و یا فرمت‌های کدگذاری فشرده باینری (FAST/SBE)، مستقیماً در سطح گیت پارس می‌شوند. به‌محض ورود اولین بایت‌های پکت به پورت فیزیکی، میدان‌های پیام استخراج شده و بدون نیاز به ذخیره کامل فریم در رم، به مرحله بعد فرستاده می‌شوند.

۲. بازسازی اوردربوک در حافظه داخلی (Hardware Order Book)

دفترچه سفارشات سطح ۲ و ۳ با استفاده از جداول هش سخت‌افزاری و حافظه‌های دوپورت BRAM پیاده‌سازی می‌شود. به‌روزرسانی حجم‌ها و بهترین قیمت‌های خرید و فروش (Top of Book - BBO) در کمتر از ۱۰ تا ۳۰ نانوثانیه انجام می‌پذیرد.

۳. موتور استخراج سیگنال‌های معاملاتی (Trading Signals Engine)

سیگنال‌های ناهماهنگی قیمت، آربیتراژ میان‌نمادها یا عبور قیمت از آستانه‌های معین، به صورت محاسبات منطقی و ریاضیات نقطه ثابت (Fixed-Point Arithmetic) توسط بلوک‌های DSP تراشه ارزیابی می‌شوند.

۴. فیلترهای ریسک پیش از معامله و شلیک سفارش (Pre-Trade Risk & Execution)

الزامات رگولاتوری نظیر قاعده SEC 15c3-5 بررسی اعتبار حساب، محدودیت سقف تعداد سهام، بررسی عدم ارسال سفارش با قیمت خارج از باند مجاز (Fat-finger Prevention) را اجباری کرده‌اند. اجرای این بررسی‌ها در نرم‌افزار صدها نانوثانیه تاخیر تحمیل می‌کند؛ اما در FPGA، گیت‌های موازی تمام شروط ریسک را در ۱ یا ۲ سیکل ساعت (کمتر از ۵ نانوثانیه) اعتبارسنجی کرده و پکت خروجی سفارش (نظیر پروتکل OUCH) را مستقیماً به کابل فیبر نوری پمپ می‌کنند.


۵. مزایا و چالش‌های به‌کارگیری FPGA در HFT

مزایای کلیدی:

  1. سودآوری بالاتر از طریق تقدم صف (Higher Profits via Queue Priority): در مسابقه ارسال سفارش به هسته تطبیق، کسب اولویت در سر خط بوک (Top of Book) مستقیماً تعیین‌کننده برنده معاملات است.
  2. رعایت قوانین ریسک بدون جریمه تاخیر (Zero-Latency Risk Compliance): تضمین کنترل‌های ایمنی بدون از دست دادن مزیت سرعت.
  3. بهینه‌سازی مصرف انرژی و هزینه‌های نگهداری (Cheaper Maintenance & Space): یک برد شتاب‌دهنده FPGA پیشرفته می‌تواند کارایی ده‌ها سرور پردازشی سنتی را در خود جای داده و هزینه‌های برق، خنک‌سازی و اجاره یونیت‌های گران‌قیمت رک در دیتاسنترهای کولیکیشن را کاهش دهد.

چالش‌ها و معایب:

  1. هزینه‌های سخت‌افزاری بالا (Hardware Cost): بردهای سازمانی پیشرفته FPGA (نظیر AMD Alveo یا کارت‌های سولارفلر) بسیار گران‌قیمت هستند.
  2. پیچیدگی بالای توسعه و دیباگ (Development and Debugging):
    • نوشتن کد به زبان‌های توصیف سخت‌افزار مانند Verilog و VHDL بسیار دشوارتر از C++ یا پایتون است.
    • چرخه‌های سنتز و جایابی (Synthesis and Place-and-Route) ممکن است ساعت‌ها زمان ببرند.
    • ابزارهای شبیه‌سازی سطح گیت و عدم وجود لاگ‌های سنتی، رفع باگ را بسیار طاقت‌فرسا می‌سازد.
    • ابزارهای سنتز سطح بالا (HLS - High-Level Synthesis) نظیر Xilinx Vivado HLS / Vitis و Intel Quartus تا حدودی ورود به دنیای سخت‌افزار را با نوشتن C/C++ تسهیل کرده‌اند، اما بهینه‌سازی دستی در سطح RTL همواره سرعت بالاتری ارائه می‌دهد.
  3. ریسک سرکشی فاجعه‌بار سیستم (Catastrophic Trading Risk): یک باگ نرم‌افزاری در پردازنده معمولی ممکن است موجب کرش برنامه شود؛ اما یک باگ منطقی در تراشه FPGA با سرعت نانوثانیه‌ای خود می‌تواند ظرف چند میلی‌ثانیه هزاران سفارش اشتباه شلیک کرده و سرمایه کل شرکت را تا مرز ورشکستگی محو کند (مانند فاجعه معروف شرکت Knight Capital).
  4. محدودیت پیچیدگی استراتژی (Strategy Complexity Limits): الگوریتم‌های پیچیده یادگیری ماشین، تحلیل‌های رگرسیون غیرخطی سنگین یا منطق‌های چندمرحله‌ای بازار به راحتی در گیت‌های سخت‌افزاری گنجانده نمی‌شوند و منابع فیزیکی تراشه را پر می‌کنند.

۶. جهان معاملات فرکانس بالا در ارزهای دیجیتال (Cryptocurrencies)

بخش دوم کتاب به بررسی بازارهای رمزارز اختصاص دارد؛ حوزه‌ای که رفتارهای زیرساختی و تجاری آن تفاوت‌های شگرفی با صرافی‌های متمرکز وال‌استریت دارد.

عوامل محرک قیمت در بازار کریپتو

  • عرضه کل توکن‌ها، سرعت آزادسازی و مکانیزم‌های توکن‌سوزی (Burn Mechanics).
  • ارزش بازار (Market Capitalization) و عمق استخرها.
  • جو رسانه‌ای و احساسات اجتماعی (Social Media & Media Sentiment).
  • سهولت ادغام فنی توکن در اکوسیستم‌های پرداخت و دیفای.
  • رویدادهای قانونی، تصمیمات نهادهای ناظر (SEC) و هک‌های پروتکل‌های شبکه.

مقایسه قراردادهای آتی سنتی با فیوچرز دائمی (Perpetual Futures)

ویژگیقراردادهای آتی سنتی (Traditional Futures)قراردادهای دائمی رمزارز (Perpetual Futures)
تاریخ سررسید (Expiration Date)دارای تاریخ مشخص انقضا (ماهانه / فصلی)بدون تاریخ انقضا؛ موقعیت تا ابد باز می‌ماند
تسویه حساب (Settlement)در زمان سررسید با قیمت اسپات همگرا می‌شوداز طریق مکانیزم مستمر نرخ تأمین مالی (Funding Rate)
رول‌اوور (Rollover)نیاز به جابجایی دستی به قرارداد ماه بعدبدون نیاز به رول‌اوور

مکانیزم نرخ تأمین مالی (Funding Rate):

نرخ فاندینگ از دو جزء اصلی تشکیل می‌شود: نرخ بهره استقراض (Lending Rate) و شاخص حق بیمه (Premium Index): $$\text{Funding Rate} = \text{Interest Rate} + \text{Clamp}(\text{Premium Index} - \text{Interest Rate}, \dots)$$

  • اگر قیمت پرپچوال بالاتر از اسپات باشد: خریداران (Longs) به فروشندگان (Shorts) کارمزد فاندینگ پرداخت می‌کنند تا قیمت به اسپات نزدیک شود.
  • اگر قیمت پرپچوال پایین‌تر از اسپات باشد: فروشندگان به خریداران کارمزد می‌پردازند.

دسترسی به بازار، نقدینگی و کارمزدها

  1. معاملات ۲۴/۷ بدون توقف: بازارهای کریپتو بر خلاف بورس سهام هرگز تعطیل نمی‌شوند و پرحجم‌ترین ساعات در همپوشانی بازار شرق آسیا و غرب آمریکا رخ می‌دهد.
  2. کارمزدهای معاملاتی بالا: کارمزد معاملات در کریپتو اغلب ۲۰ تا ۳۰ برابر بالاتر از بورس‌های سنتی سهام است. به همین جهت، استراتژی‌های بازارگردانی به شدت به تخفیف کارمزد میکر (Maker Rebates) در صرافی‌هایی چون Binance و Huobi وابسته‌اند.
  3. شفافیت و دستکاری قیمت: به دلیل نبود قوانین سخت‌گیرانه افشای اطلاعات شرکت‌های عمومی، پدیده‌هایی نظیر سفارش‌های ساختگی (Spoofing) و معاملات خودبه‌خود (Wash Trading) در پلتفرم‌های بدون نظارت مشاهده می‌شود.

صرافی‌های متمرکز (CEX) در برابر صرافی‌های غیرمتمرکز (DEX)

  • CEX (Centralized Exchanges - نظیر Binance, Coinbase, Bybit): دارای هسته تطبیق مرکزی با کارایی بالا در فضای ابری؛ کانال‌های WebSocket و FIX ارائه می‌دهند و بستر اصلی HFT رمزارز هستند.
  • DEX (Decentralized Exchanges - نظیر Uniswap): مبتنی بر قراردادهای هوشمند، استخرهای نقدینگی و بازارساز خودکار (AMM) روی بلاک‌چین. تاخیر آنها تابع زمان تولید بلوک بلاک‌چین (چند ثانیه تا چند دقیقه) و کارمزد گس (Gas Fee) است و برای HFT سنتی کمتر مورد استفاده قرار می‌گیرند.

استراتژی‌های برتر HFT در کریپتو

  1. بازارگردانی (Crypto Market Making): ارائه مستمر قیمت خرید و فروش در هر دو طرف بوک با بهره‌مندی از تخفیف‌های ویژه VIP صرافی‌ها.
  2. آربیتراژ آماری بین‌صرافی (Cross-Exchange Arbitrage): شکار اختلاف قیمت‌های آنی یک رمزارز مشخص میان چند صرافی مختلف (مثلاً بایننس در برابر کوین‌بیس).
  3. مسیریابی هوشمند سفارش (Smart Order Routing - SOR): یافتن بهترین عمق نقدینگی در میان صرافی‌های مختلف برای خرد کردن سفارشات بزرگ نهادی.
  4. اسکالپینگ پرحجم (High-Volume Scalping): بهره‌برداری الگوریتمی از نوسانات کوچک قیمتی در کسری از ثانیه.

۷. معماری سامانه‌های معاملاتی کریپتو در فضای ابری (Cloud Computing)

برخلاف بورس‌های سنتی که سرورها باید در فیزیک دیتاسنتر بورس (Colocation) مستقر شوند، اکثر صرافی‌های رمزارز خود بر روی زیرساخت‌های ابری بزرگ نظیر AWS، Google Cloud (GCP) و Microsoft Azure میزبانی می‌شوند. بنابراین استقرار سیستم HFT در کلود، کارآمدترین و مقرون‌به‌صرفه‌ترین روش است.

هایپروایزرها و لایه مجازی‌سازی

شکل 11.1: مقایسه معماری هایپروایزرهای Type-1 (Bare-Metal) و Type-2 (Hosted)

  • هایپروایزر نوع ۱ (Bare-Metal): نرم‌افزارهای مجازی‌سازی نظیر VMware ESXi یا KVM که مستقیماً روی سخت‌افزار فیزیکی می‌نشینند. این ساختار کمترین تاخیر را ارائه داده و بستر اصلی ماشین‌های مجازی ابری در HFT است.
  • هایپروایزر نوع ۲ (Hosted): روی یک سیستم‌عامل دیگر به عنوان برنامه کاربردی اجرا می‌شوند (نظیر VirtualBox) و برای مقاصد غیرعملیاتی و تست روی لپ‌تاپ شخصی مناسب‌اند.

مناطق جغرافیایی و زون‌های دسترسی (Regions & Availability Zones)

شکل 11.2: ساختار Regions و Availability Zones در ارائه‌دهندگان کلود

برای کمینه‌سازی تاخیر رفت‌وبرگشت پکت‌ها در کلود، سرورهای معاملاتی باید دقیقاً در همان منطقه (Region) و حتی‌الامکان همان زون دسترسی (Availability Zone - AZ) که سرورهای تطبیق صرافی رمزارز مستقر هستند (مثلاً منطقه AWS Tokyo ap-northeast-1 یا AWS Dublin eu-west-1) مستقر شوند. این اقدام تاخیر شبکه را از ده‌ها میلی‌ثانیه به زیر ۱ میلی‌ثانیه کاهش می‌دهد.

اجزای کلیدی معماری سیستم معاملاتی در کلود

شکل 11.3: اجزای کلیدی معماری سامانه معاملاتی الگوریتمی و ارتباطات میان آنها

یک سامانه معاملاتی ابری شامل ۴ مولفه اساسی است:

  1. موتور معاملات الگوریتمی (Algorithmic Trading Engine): هسته مرکزی که استراتژی‌ها را اجرا کرده و هماهنگی میان سایر ماژول‌ها را مدیریت می‌کند.
  2. آداپتور داده‌های بازار (Market Data Adapter): فیدهای لحظه‌ای بازار و داده‌های تاریخی را گردآوری و استانداردسازی می‌کند.
  3. آداپتور صرافی/بروکر (Exchange/Broker Adapter): ارسال سفارشات، لغو، پیگیری وضعیت و مدیریت ارتباط با APIهای REST و WebSocket صرافی.
  4. مخزن داده امن و پایدار (Data Store): ذخیره‌سازی تیک‌ها، لاگ سفارشات و گزارش‌های ریسک در پایگاه‌های داده سری‌زمانی یا ذخیره‌سازهای ابری (S3 / Blob).

۸. پایپ‌لاین پیشرفته یادگیری ماشین و استقرار سیستم در کلود

شکل 11.4: چرخه کامل استخراج داده، آموزش مدل ML، بک‌تستینگ و اجرای زنده در پلتفرم ابری

شکل 11.4 معماری گام‌به‌گام یک سیستم معاملاتی رمزارز مدرن مبتنی بر هوش مصنوعی در ارائه‌دهندگان ابری را نشان می‌دهد:

  1. بارگذاری داده‌ها (Load Data - برچسب 1): دریافت داده‌های تاریخی کندل‌ها و تیک‌ها از صرافی و ذخیره‌سازی ایمن در مخازن ابری (Data Lake / S3).
  2. خط لوله مهندسی ویژگی‌ها (Data Pipeline ETL - برچسب 2): پردازش ویژگی‌ها، پالایش داده‌ها و تولید اندیکاتورهای ورودی.
  3. محیط آموزش مدل (ML Training Instance - برچسب 3): استفاده از نوتبوک‌های Jupyter در بسترهای مدیریت‌شده ML نظیر AWS SageMaker، Azure ML Studio یا Google Cloud Vertex AI.
  4. شبیه‌سازی و بک‌تستینگ (Backtesting Engine - برچسب 4): اجرای استراتژی بر روی داده‌های تاریخی ذخیره‌شده در فضای ابری و ارزیابی معیارهای عملکردی (شارپ ریشیو، حداکثر افت سرمایه).
  5. اتصال بلادرنگ به صرافی (Real-Time Ingestion - برچسب‌های 5، 6 و 7): برقراری اتصال اختصاصی WebSocket به صرافی کریپتو برای دریافت زنده تیک‌ها، اجرای مدل در موتور زنده C++/Python، و شلیک سریع سفارشات به آداپتور صرافی.
  6. پایش و لاگینگ بلادرنگ (Monitoring & Alerting - برچسب 8): استفاده از سرویس‌های مانیتورینگ ابری (AWS CloudWatch، Datadog یا Grafana) برای محاسبه لحظه‌ای سود و زیان (PnL)، ردیابی تاخیر، و ارسال هشدارهای فوری پیامکی یا بصری در صورت نقض آستانه‌های ریسک.

۹. جمع‌بندی نهایی کتاب: پایان یک سفر فنی

با اتمام این فصل، به پایان سفر ۱۱ فصلی خود در کتاب توسعه سیستم‌های معاملات فرکانس بالا (Developing High-Frequency Trading Systems) رسیدیم.

mindmap
  root((سیستم معاملاتی فرکانس بالا))
    مبانی و زیرساخت
      مفاهیم HFT و میکرومارکت
      معماری ماژولار هسته معامله
      داینامیک صرافی و مچینگ انجین
    سیستم و شتاب‌دهی
      معماری سخت‌افزار سرور و کش
      پروتکل‌های تبادل و فیبر نوری
      بهینه‌سازی کرنل و ساختار Lock-Free
      دور زدن کرنل با Solarflare
    پیاده‌سازی نرم‌افزاری
      سی‌پلاس‌پلاس تاخیر میکروثانیه
      معماری Low-Latency در جاوا JVM
      ترکیب پایتون و شتاب‌دهی هیبرید
    افق‌های آینده
      مدارهای نانوثانیه‌ای FPGA
      بازارهای کریپتو و فیوچرز دائمی
      معماری ابری و پایپ‌لاین‌های یادگیری ماشین

پیام نهایی نویسندگان:

رقابت بر سر سرعت و کارایی در بازارهای مالی از سال ۲۰۰۰ تاکنون بی‌وقفه در جریان بوده و پایانی برای آن متصور نیست. هرچند دستیابی به سریع‌ترین سخت‌افزارهای جهان مستلزم سرمایه‌گذاری‌های هنگفت مالی و تیمی است، اما درک عمیق از اصول بهینه‌سازی، ساختارهای داده بدون قفل، تحلیل دقیق داده‌ها و مدیریت هوشمندانه ریسک به هر مهندس مالی و معامله‌گری امکان می‌دهد تا حتی در سامانه‌های متواضع‌تر، استراتژی‌های پایدار و سودآوری خلق کند.

واژه‌نامه اصطلاحات تخصصی (Glossary)

مفاهیم بازار و نقدینگی

  • Limit Order Book (LOB - دفترچه سفارشات محدود): فهرست سازمان‌یافته‌ای از تمام سفارش‌های خرید و فروش در انتظار اجرا در سطوح مختلف قیمتی.

  • Market Maker (بازارساز): نهادی که همزمان سفارش خرید (Bid) و فروش (Ask) در بازار قرار می‌دهد تا نقدینگی فراهم کند و از اختلاف قیمت (Spread) سود ببرد.

  • Market Taker (بازارگیر): معامله‌گری که سفارش‌های آماده در دفترچه را فوری معامله می‌کند و نقدینگی را از بازار خارج می‌نماید.

  • Bid-Ask Spread (اسپرد قیمت خرید و فروش): تفاوت قیمتی میان بالاترین قیمت پیشنهادی خریدار (Best Bid) و پایین‌ترین قیمت پیشنهادی فروشنده (Best Ask).

  • Crossing the Spread (عبور از اسپرد): هنگامی که خریدار قیمتی معادل با بهترین فروشنده را قبول می‌کند (یا برعکس) تا فوراً معامله انجام شود.

  • Top of Book (بالای دفترچه): لایه اول دفترچه سفارشات شامل بهترین قیمت خرید و بهترین قیمت فروش.

  • Slippage (لغزش قیمت): اختلاف میان قیمت مورد انتظار برای انجام یک معامله و قیمتی که سفارش واقعاً در آن اجرا می‌شود.

  • Dark Pools (استخرهای تاریک): سامانه‌های معاملاتی خصوصی و خارج از بورس عمومی که سفارش‌های بسیار بزرگ نهادی در آن بدون نمایش در دفترچه عمومی انجام می‌شوند تا بازار شوکه نشود.


استراتژی‌های معاملاتی

  • Statistical Arbitrage (Stat Arb - آربیتراژ آماری): استراتژی داده‌محور که بر اساس مدل‌های ریاضی و انحرافات موقتی قیمت دارایی‌های همبسته از میانگین تاریخی سود می‌برد.

  • Latency Arbitrage (آربیتراژ تاخیر): بهره‌برداری از اختلاف قیمت یک دارایی در چند صرافی مختلف به لطف سرعت ارتباطی بالاتر در حد میکروثانیه.

  • Market Making Strategy (استراتژی بازارسازی): ثبت پیوسته دوطرفه سفارش‌های خرید و فروش با هدف به حداقل رساندن ریسک موجودی و کسب اسپرد.

  • Momentum Ignition (جرقه‌زنی مومنتوم): ثبت حجم سنگینی از سفارش‌ها برای شبیه‌سازی حرکت شدید روند و فریب الگوریتم‌های دیگر، سپس معامله در خلاف جهت.

  • Pinging (پینگینگ): ارسال سفارش‌های کوچک به بازارهای مختلف برای کشف وجود سفارش‌های مخفی یا نهادی پنهان.


مفاهیم فنی و زیرساخت (Low-Latency)

  • Latency (تاخیر زمانی): مدت زمانی که طول می‌کشد تا یک سیگنال یا سفارش از کامپیوتر تریدر به صرافی برسد، پردازش شود و پاسخ برگردد (معمولاً بر حسب میکروثانیه یا نانوثانیه).

  • Colocation (هم‌مکانی): قرار دادن فیزیکی سرورهای معاملاتی در همان مرکز داده‌ای (دیتاسنتر) که سرورهای صرافی قرار دارند برای به حداقل رساندن تاخیر فاصله.

  • Matching Engine (موتور تطبیق): هسته نرم‌افزاری صرافی که سفارش‌های خرید و فروش را طبق الگوریتم‌هایی مانند FIFO (اولین ورودی، اولین خروجی) جفت می‌کند.

  • Kernel Bypass: تکنیکی در لینوکس برای دور زدن پشته شبکه سیستم‌عامل (OS Network Stack) و ارتباط مستقیم کارت شبکه (NIC) با برنامه معاملاتی در فضای کاربر.

  • Lock-Free Programming (برنامه‌نویسی بدون قفل): طراحی ساختارهای داده با استفاده از عملیات اتمیک (Atomic) بدون متوقف کردن تردها با Mutex.