معماری پایپ‌لاین OHLCV: طراحی Feature Registry و Cache برای سیستم‌های معاملاتی مقیاس‌پذیر
مقاله حسین نریمانی ۱۴۰۵/۰۵/۰۷ Quant System Design

معماری پایپ‌لاین OHLCV: طراحی Feature Registry و Cache برای سیستم‌های معاملاتی مقیاس‌پذیر

بیشتر سیستم‌های معاملاتی با مشکل مدل شروع نمی‌کنند. با داده‌ای شروع می‌کنند که هر بخش سیستم آن را متفاوت تفسیر می‌کند.وقتی یک feature در بک‌تست یک مقدار دارد و در اجرای زنده مقدار دیگری، مسئله «هوش مدل» نیست. مسئله...

بیشتر سیستم‌های معاملاتی با مشکل مدل شروع نمی‌کنند. با داده‌ای شروع می‌کنند که هر بخش سیستم آن را متفاوت تفسیر می‌کند.

وقتی یک feature در بک‌تست یک مقدار دارد و در اجرای زنده مقدار دیگری، مسئله «هوش مدل» نیست. مسئله معماری است.

مسئله واقعی در پایپ‌لاین OHLCV چیست؟

داده‌های OHLCV شامل Open، High، Low، Close و Volume هستند. این داده‌ها ساده به نظر می‌رسند، اما پایه تصمیم‌های معاملاتی، بک‌تست، مدیریت ریسک و مانیتورینگ عملیاتی‌اند.

اشتباه رایج این است که تیم‌ها OHLCV را صرفاً یک فایل CSV یا یک API response می‌بینند. در عمل، OHLCV یک منبع داده عملیاتی است که باید نسخه‌پذیر، قابل بازتولید و قابل ممیزی باشد.

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

یک سیستم معاملاتی قابل مقیاس، ابتدا تعریف feature را تثبیت می‌کند؛ سپس مدل را آموزش می‌دهد.

تعریف پایپ‌لاین Feature در معاملات

پایپ‌لاین feature، ساختاری برای تبدیل داده خام بازار به متغیرهای قابل استفاده در تصمیم‌گیری است. این ساختار باید همان خروجی را در بک‌تست، paper trading و live trading تولید کند.

ورودی‌های خام

ورودی معمولاً شامل کندل‌های OHLCV، corporate actions، داده قراردادها، وضعیت بازار و گاهی داده‌های جایگزین است. نقطه مهم این است که هر منبع باید زمان دریافت، زمان رخداد و کیفیت داده مشخصی داشته باشد.

مثلاً close یک کندل پنج‌دقیقه‌ای تا پایان همان بازه قابل استفاده نیست. استفاده زودتر از آن، look-ahead bias ایجاد می‌کند.

لایه نرمال‌سازی

در این لایه، timezone، نمادها، intervalها، داده‌های تکراری و کندل‌های ناقص مدیریت می‌شوند. این بخش جذاب نیست، اما بیشترین سهم را در جلوگیری از خطاهای پنهان دارد.

نماد BTC/USDT در دو صرافی الزاماً یک دارایی عملیاتی یکسان نیست. نقدشوندگی، volume و حتی زمان‌بندی کندل‌ها ممکن است تفاوت داشته باشند.

لایه تولید Feature

در این لایه، داده خام به featureهای مشتق‌شده تبدیل می‌شود. بازده لگاریتمی، ATR، VWAP، rolling volatility، volume imbalance و regime labels نمونه‌هایی از این featureها هستند.

هر feature باید یک قرارداد روشن داشته باشد: ورودی‌ها، window، روش محاسبه، latency مجاز، نسخه و مالک آن.

Feature Registry چیست؟

Feature Registry یک کاتالوگ عملیاتی برای تعریف و کنترل featureها است. این registry فقط یک لیست نام‌ها نیست؛ قرارداد داده‌ای سیستم است.

هر feature در registry باید مشخص کند چه چیزی محاسبه می‌شود، از کدام داده ساخته می‌شود، چه زمانی معتبر است و کدام نسخه در production استفاده می‌شود.

حداقل مشخصات هر Feature

  • نام یکتا: مانند realized_volatility_20_v2
  • تعریف محاسباتی: فرمول، window و نوع aggregation
  • منبع داده: exchange، dataset، timeframe و نوع قیمت
  • زمان اعتبار: event time، available time و latency
  • نسخه: برای جلوگیری از تغییر خاموش در نتایج
  • مالک: فرد یا تیم مسئول کیفیت و تغییرات
  • تست‌ها: اعتبارسنجی داده، محدوده منطقی و سازگاری زمانی

چرا Feature Registry از Feature Store مهم‌تر است؟

Feature Store معمولاً روی ذخیره‌سازی و ارائه feature تمرکز دارد. Feature Registry روی تعریف، lineage و governance تمرکز می‌کند.

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

بخشFeature RegistryFeature Store یا Cache
هدف اصلیتعریف، نسخه‌بندی و lineageدسترسی سریع به feature محاسبه‌شده
پرسش کلیدیاین feature دقیقاً چیست؟آخرین مقدار معتبر کجاست؟
ریسک اصلیتغییر خاموش در منطقداده کهنه یا ناسازگار
مالکیتResearch و platform engineeringTrading infrastructure و runtime systems

معماری پیشنهادی پایپ‌لاین OHLCV

معماری خوب پیچیدگی را حذف نمی‌کند. پیچیدگی را به لایه‌های قابل کنترل منتقل می‌کند.

لایه اول: Immutable Raw Data

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

این تصمیم فضای ذخیره‌سازی بیشتری مصرف می‌کند. اما در زمان بررسی اختلاف بک‌تست و اجرای زنده، ارزش آن چند برابر است.

لایه دوم: Canonical Bars

کندل استانداردشده باید تعریف واحدی از نماد، timeframe، timezone و session داشته باشد. همه featureها باید از این قرارداد استفاده کنند.

اگر یک ماژول از UTC و ماژول دیگر از timezone صرافی استفاده کند، حتی بهترین مدل‌ها هم خروجی متناقض می‌دهند.

لایه سوم: Deterministic Feature Jobs

محاسبه feature باید deterministic باشد. یعنی با ورودی، نسخه و timestamp یکسان، خروجی یکسان تولید کند.

از وابستگی پنهان به ساعت سیستم، داده آینده یا state ناشناخته پرهیز کنید. این وابستگی‌ها بازتولیدپذیری را نابود می‌کنند.

لایه چهارم: Registry-Controlled Publication

هیچ feature جدیدی نباید مستقیم وارد live trading شود. ابتدا باید در registry ثبت شود، تست بگیرد و وضعیت انتشار مشخص داشته باشد.

یک workflow ساده شامل draft، validated، shadow، production و deprecated است. همین ساختار ساده، تغییرات بی‌صدا را سخت می‌کند.

لایه پنجم: Online Cache

cache محل حقیقت نیست. cache مسیر سریع تصمیم‌گیری است.

سیستم live trading باید آخرین featureهای معتبر را با latency پایین بخواند، اما بتواند در هر زمان منبع اصلی و lineage آن‌ها را بازیابی کند.

طراحی Cache برای تصمیم معاملاتی

Cache در سیستم معاملاتی فقط برای سرعت نیست. برای کنترل latency، کاهش هزینه محاسبه و جلوگیری از محاسبات تکراری است.

اما cache اشتباه می‌تواند تصمیم‌های قدیمی را با ظاهر تصمیم‌های تازه وارد بازار کند.

کلید Cache را درست طراحی کنید

کلید cache باید حداقل شامل symbol، venue، timeframe، feature version و event timestamp باشد. فقط استفاده از نام feature و symbol کافی نیست.

برای نمونه، BTCUSDT:binance:5m:atr_14_v2:2026-07-29T10:25:00Z معنای عملیاتی بسیار روشن‌تری از BTCUSDT:atr دارد.

TTL به‌تنهایی کافی نیست

Time-to-live یا TTL از انباشته‌شدن داده کهنه جلوگیری می‌کند. اما تضمین نمی‌کند که داده موجود با آخرین کندل بسته‌شده سازگار باشد.

برای featureهای معاملاتی، علاوه بر TTL باید freshness watermark داشته باشید. سیستم باید بداند آخرین event time پردازش‌شده چیست.

Invalidation باید مبتنی بر رویداد باشد

وقتی یک کندل اصلاح می‌شود یا داده تاریخی دوباره دریافت می‌شود، cache باید بر اساس event invalidation پاک‌سازی شود. پاک‌سازی سراسری ساده‌تر است، اما در مقیاس هزینه‌ساز می‌شود.

این‌جا trade-off روشن است: invalidation دقیق پیچیده‌تر است؛ invalidation خشن سریع‌تر ساخته می‌شود، اما بار محاسباتی بیشتری ایجاد می‌کند.

یک مثال عملی: Feature نوسان‌پذیری ۲۰ دوره‌ای

فرض کنید می‌خواهید realized volatility بیست کندل اخیر را برای یک استراتژی momentum محاسبه کنید. تعریف ناقص می‌تواند به‌راحتی نتیجه را تحریف کند.

  1. منبع داده را مشخص کنید: close کندل‌های پنج‌دقیقه‌ای Binance برای BTC/USDT
  2. تأیید کنید فقط کندل‌های بسته‌شده وارد محاسبه می‌شوند
  3. بازده لگاریتمی را از closeهای متوالی محاسبه کنید
  4. انحراف معیار rolling بیست بازده را محاسبه کنید
  5. نسخه feature را ثبت کنید؛ مثلاً realized_volatility_20_v1
  6. event time آخرین کندل و زمان محاسبه را همراه خروجی ذخیره کنید
  7. خروجی را در cache منتشر کنید، فقط اگر freshness شرط‌شده برقرار است

اگر بعداً روش annualization را تغییر دهید، feature جدید بسازید. نسخه قبلی را بازنویسی نکنید.

آنچه بیشتر تیم‌ها اشتباه می‌گیرند

استفاده از یک کد مشترک بدون قرارداد مشترک

استفاده از یک repository برای research و production مفید است. اما بدون قرارداد داده و کنترل نسخه، فقط یک محل مشترک برای خطا می‌سازید.

کد مشترک جای architecture مشترک را نمی‌گیرد.

اتکا به DataFrame به‌عنوان مرز سیستم

DataFrame ابزار تحلیل است، نه قرارداد عملیاتی. وقتی featureها فقط در DataFrameهای موقت تعریف می‌شوند، lineage و نسخه‌بندی مبهم می‌ماند.

خروجی هر job باید یک schema و metadata مشخص داشته باشد.

نادیده‌گرفتن اصلاح داده‌های بازار

داده بازار گاهی اصلاح می‌شود. کندل‌های ناقص، reconnect شدن websocket و تفاوت snapshot و trade stream واقعیت‌های عملیاتی هستند.

سیستمی که برای correction برنامه ندارد، دیر یا زود با اختلاف غیرقابل توضیح بین research و production مواجه می‌شود.

محاسبه مجدد همه‌چیز در هر درخواست

این روش برای prototype قابل قبول است. برای سیستم live، latency و هزینه را بدون دلیل بالا می‌برد.

cache باید از محاسبه تکراری جلوگیری کند، نه اینکه حقیقت داده را پنهان کند.

واقعیت عملیاتی و Trade-offها

معماری feature registry و cache هزینه دارد. باید schema تعریف کنید، تست بنویسید، metadata نگه دارید و مسیر انتشار بسازید.

اما جایگزین آن معمولاً ارزان نیست؛ اختلاف‌های پنهان، بک‌تست‌های غیرقابل اعتماد و تصمیم‌هایی که بعداً قابل توضیح نیستند.

انتخابمزیتهزینهزمان مناسب
محاسبه مستقیم در strategyشروع سریعتکرار منطق و خطای بالاPrototype کوتاه‌مدت
Feature pipeline سادهبازاستفاده و تست بهترنیاز به قرارداد دادهاولین نسخه production
Registry و cache مستقلمقیاس، governance و قابلیت ممیزیپیچیدگی عملیاتی بیشترچند strategy یا چند تیم

چارچوب تصمیم‌گیری برای Founderها

برای انتخاب سطح معماری، این سؤال را بپرسید: اگر فردا یک نتیجه معاملاتی غیرعادی دیدیم، آیا می‌توانیم دقیقاً بازسازی کنیم که سیستم با چه داده و چه feature versionی تصمیم گرفت؟

اگر پاسخ منفی است، قبل از افزودن مدل جدید، مسیر داده را اصلاح کنید.

اگر فقط یک Strategy دارید

با canonical OHLCV، چند feature versioned و یک cache محدود شروع کنید. registry می‌تواند ابتدا یک فایل version-controlled با schema مشخص باشد.

اگر چند Strategy یا چند بازار دارید

feature registry را به یک سرویس یا ماژول مستقل تبدیل کنید. ownership، deprecation و validation را رسمی کنید.

اگر به مشتری SaaS سرویس می‌دهید

tenant isolation، rate limiting، data lineage و audit trail دیگر جزئیات فنی نیستند. آن‌ها بخشی از محصول شما هستند.

راهنمای پیاده‌سازی

  • ابتدا schema استاندارد برای OHLCV تعریف کنید؛ symbol، venue، timeframe، event time، ingestion time و کیفیت داده را اجباری کنید
  • هر feature را با یک نام نسخه‌دار و metadata قابل جست‌وجو ثبت کنید
  • برای هر feature، تست look-ahead bias و تست determinism اضافه کنید
  • cache را با event time و feature version کلیدگذاری کنید
  • freshness watermark را در runtime بررسی کنید
  • قبل از انتشار live، feature جدید را در shadow mode اجرا کنید
  • همیشه مسیر بازتولید خروجی از raw data تا تصمیم نهایی را حفظ کنید

نکات کلیدی

  • OHLCV داده ساده‌ای نیست؛ پایه تصمیم‌گیری سیستم معاملاتی است
  • Feature Registry قرارداد تعریف، نسخه و lineage featureهاست
  • Cache برای سرعت است، نه برای تعیین حقیقت داده
  • event time مهم‌تر از زمان دریافت داده است
  • نسخه feature را بازنویسی نکنید؛ نسخه جدید منتشر کنید
  • اگر تصمیم قابل بازتولید نیست، سیستم آماده مقیاس نیست

پرسش‌های متداول

OHLCV چیست؟

OHLCV مجموعه داده‌ای شامل قیمت بازشدن، بالاترین قیمت، پایین‌ترین قیمت، قیمت بسته‌شدن و حجم معامله در یک بازه زمانی مشخص است.

Feature Registry در سیستم معاملاتی چه کاری انجام می‌دهد؟

Feature Registry تعریف، نسخه، منبع داده، منطق محاسبه، زمان اعتبار و مالک هر feature را ثبت می‌کند تا خروجی‌ها قابل بازتولید و قابل ممیزی بمانند.

تفاوت Feature Registry و Cache چیست؟

Registry مشخص می‌کند یک feature چیست و چگونه ساخته می‌شود. Cache آخرین خروجی معتبر آن feature را برای دسترسی سریع نگه می‌دارد.

چرا نسخه‌بندی featureها ضروری است؟

نسخه‌بندی جلوی تغییر خاموش در منطق محاسبه را می‌گیرد. همچنین امکان مقایسه نتایج، rollback و بازتولید تصمیم‌های گذشته را فراهم می‌کند.

آیا برای یک strategy ساده هم به Feature Registry نیاز دارم؟

بله، اما لازم نیست از روز اول یک پلتفرم پیچیده بسازید. یک schema روشن و یک فایل version-controlled برای تعریف featureها نقطه شروع کافی است.


مدل معاملاتی فقط به اندازه سیستم داده‌ای پشت آن قابل اعتماد است.

ساختار درست، سرعت را قربانی نمی‌کند. سرعت را قابل اعتماد می‌کند.

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

نظرات (0)

اولین نفری باشید که نظر می‌دهد.
ورود / ثبت‌نام