🚀 بهترین برنامه نویس و طراح ربات معامله گر فارکس و سفارش ربات و اکسپرت معامله گر متاتریدر به زبان MQL4 و MQL5 | متااکسپرت

ربات Low Frequency Trading

ربات Low Frequency Trading

Meta Description:
آشنایی کامل با ربات معاملات کم‌بسامد (Low Frequency Trading Bot) برای برنامه‌نویسان و فعالان بازارهای مالی؛ از تعریف و تفاوت با HFT تا معماری، دیتافید، بک‌تست، مدیریت ریسک، اجرای سفارش، زیرساخت، زبان‌ها و فریم‌ورک‌ها، مانیتورینگ، امنیت، خطاهای رایج، استراتژی‌های نمونه و معیارهای ارزیابی، همراه با ملاحظات حقوقی و اخلاقی.

Slug پیشنهادی:
low-frequency-trading-bot

ربات معاملات کم‌بسامد (Low Frequency Trading Bot) چیست؟

ربات معاملات کم‌بسامد (Low Frequency Trading Bot) سامانه‌ای نرم‌افزاری است که تصمیم‌های معاملاتی را در بازه‌های زمانی نسبتاً بلندتر از معاملات پرفرکانس (High Frequency Trading / HFT) می‌گیرد و اجرا می‌کند. در عمل، «کم‌بسامد» بودن به این معنا نیست که ربات کند یا ساده است؛ بلکه یعنی افق تصمیم‌گیری، تناوب داده‌برداری، و تعداد سفارش‌ها معمولاً در حد ثانیه، دقیقه، ساعت یا حتی روزهاست، نه در مقیاس میلی‌ثانیه و میکروثانیه. این تفاوت از منظر طراحی بسیار مهم است، چون در LFT کیفیت مدل، مدیریت داده، کنترل ریسک و استحکام سیستم اغلب اهمیت بیشتری از رقابت زیرساختی برای چند میکروثانیه دارد. برای یک برنامه‌نویس یا فعال بازار، ربات معاملات کم‌بسامد می‌تواند پلی میان پژوهش کمی، مهندسی نرم‌افزار و اجرای عملی در بازار باشد، اما این پل زمانی قابل اتکا است که به‌صورت ماژولار، قابل‌تست و قابل‌پایش طراحی شود.

در Low Frequency Trading معمولاً از سیگنال‌هایی استفاده می‌شود که نویز لحظه‌ای بازار کمتر روی آن‌ها اثر می‌گذارد: میانگین‌های متحرک، انحراف از ارزش منصفانه، شکست سطوح، بازگشت به میانگین، عوامل بنیادی، یا همبستگی‌های آماری بلندتر. در این فضا، ربات نه‌فقط «ارسال‌کننده سفارش»، بلکه یک سامانه کامل شامل دریافت داده (Data Feed)، تولید سیگنال (Signal Generation)، مدیریت پرتفوی (Portfolio Management)، مدیریت ریسک (Risk Management)، اجرای سفارش (Order Execution)، ثبت رویدادها (Logging) و مانیتورینگ (Monitoring) است. اگر این اجزا از ابتدا درست طراحی شوند، ربات می‌تواند در بازارهای سهام، آتی، فارکس، رمزارز یا حتی بازارهای چنددارایی به‌صورت منظم کار کند، هرچند هیچ تضمینی برای سودآوری وجود ندارد و نتیجه به کیفیت داده، هزینه‌ها، لغزش قیمت، محدودیت‌های کارگزاری و شرایط بازار وابسته است.

تفاوت LFT با HFT

مهم‌ترین تفاوت LFT و HFT در افق زمانی، نوع مزیت رقابتی و میزان حساسیت به زیرساخت است. در HFT، مزیت می‌تواند از سرعت شبکه، محل استقرار سرور، بهینه‌سازی سطح پایین کد و دسترسی سریع به Order Book به دست آید. اما در LFT، مزیت بیشتر از کیفیت ایده، نظم آماری، مدیریت ریسک، فیلتر کردن نویز، و انطباق درست با ساختار بازار حاصل می‌شود. این تفاوت باعث می‌شود که معماری ربات کم‌بسامد معمولاً انعطاف‌پذیرتر باشد و بتواند با هزینه زیرساختی کمتر از HFT وارد فاز تولید شود.

در HFT، حتی اختلاف چند میلی‌ثانیه ممکن است نتیجه را عوض کند، اما در LFT تصمیم‌ها معمولاً بر اساس داده‌های کندتر و سیگنال‌های کمتر هیجانی گرفته می‌شوند. به همین دلیل، بسیاری از خطاهای رایج در Low Frequency Trading Bot نه از تأخیر شبکه، بلکه از داده آلوده، مدل‌سازی ضعیف، بک‌تست غیرواقع‌گرایانه، یا نادیده گرفتن هزینه‌های معاملاتی ناشی می‌شود. همچنین در LFT گاهی می‌توان از تایم‌فریم‌های ۵ دقیقه، ۱۵ دقیقه، ۱ ساعته یا روزانه استفاده کرد و حتی اجرای سفارش را به‌صورت تدریجی انجام داد تا اثر بازار کاهش یابد. بنابراین اگرچه سرعت هنوز مهم است، اما اهمیت آن در سطحی متفاوت با HFT قرار می‌گیرد.

مقایسه عملی در یک نگاه

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

این تفاوت‌ها از آن جهت مهم‌اند که بسیاری از تیم‌ها تلاش می‌کنند یک ربات معاملات کم‌بسامد را با ذهنیت HFT بسازند؛ نتیجه معمولاً سامانه‌ای پرهزینه، شکننده و بیش‌ازحد پیچیده است که مزیت واقعی ندارد. در مقابل، یک معماری کم‌بسامد خوب باید اول «قابل‌اعتماد» باشد و بعد «سریع». در LFT اگر ربات شما یک دقیقه دیرتر واکنش دهد اما سیگنال را درست، با ریسک کنترل‌شده و بدون خطا اجرا کند، ممکن است از یک سامانه سریع اما ناپایدار بهتر عمل کند.

معماری ربات معاملات کم‌بسامد

معماری مناسب برای ربات معاملات کم‌بسامد (Low Frequency Trading Bot) باید از ابتدا ماژولار، رویدادمحور و قابل‌آزمایش باشد. بهترین رویکرد این است که ربات را به چند لایه مستقل تقسیم کنیم: لایه داده، لایه سیگنال، لایه تصمیم‌گیری، لایه اجرا، لایه نظارت و لایه ذخیره‌سازی. این تفکیک باعث می‌شود هر بخش به‌صورت جداگانه توسعه و ارزیابی شود و در صورت خطا، کل سیستم از کار نیفتد. همچنین برای بازارهای مختلف یا استراتژی‌های متفاوت، می‌توان همان زیرساخت را با ماژول‌های تحلیلی متفاوت به کار برد.

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

یک ربات معاملات کم‌بسامد حرفه‌ای معمولاً از event-driven architecture بهره می‌برد. در این الگو، ورود هر رویداد – مانند رسیدن یک کندل جدید، تغییر شدید قیمت، یا دریافت خبر – زنجیره‌ای از واکنش‌ها را فعال می‌کند. این روش نسبت به حلقه‌های ساده و سراسری مزیت دارد، چون هم خواناتر است و هم توسعه‌پذیرتر. علاوه‌براین، برای پژوهش و تولید، بهتر است محیط Backtest، Paper Trading و Live Trading از نظر کد تا حد ممکن مشترک باشند تا اختلاف رفتار سیستم کاهش یابد.

اجزای کلیدی معماری

  • Data Ingestion برای دریافت داده از API، فایل، یا فید زنده
  • Feature Engineering برای ساخت شاخص‌ها و ورودی‌های مدل
  • Strategy Engine برای تولید سیگنال
  • Risk Engine برای مدیریت اندازه موقعیت و محدودیت‌ها
  • Execution Engine برای ثبت و پیگیری سفارش
  • State Store برای نگهداری وضعیت ربات و معاملات
  • Monitoring & Alerting برای هشدار و ثبت سلامت سیستم

طراحی درست این اجزا باعث می‌شود ربات شما قابل‌تغییر و مقاوم باشد. برای نمونه، اگر بخواهید استراتژی میانگین متحرک (Moving Average) را با بازگشت به میانگین (Mean Reversion) عوض کنید، نباید مجبور شوید کل سیستم را بازنویسی کنید؛ فقط ماژول تولید سیگنال باید تغییر کند. این نوع تفکر مهندسی، تفاوت یک اسکریپت آزمایشی با یک ربات معاملات کم‌بسامد تولیدی را مشخص می‌کند.

دیتافید و کیفیت داده

دیتافید (Data Feed) قلب تصمیم‌گیری در هر سامانه معاملاتی است. اگر داده‌ها ناقص، تأخیردار، نامنظم یا آلوده باشند، حتی بهترین استراتژی هم می‌تواند خروجی‌های ضعیف تولید کند. در LFT اگرچه حساسیت به چند میکروثانیه کمتر است، اما کیفیت داده همچنان حیاتی است. داده باید هم از نظر زمانی هم‌تراز، هم از نظر ساختاری استاندارد و هم از نظر محتوایی معتبر باشد. برای نمونه، داده‌های کندلی ممکن است اسپایک‌های مصنوعی، شکاف‌های ناشی از تعطیلی بازار، یا خطاهای ناشی از API داشته باشند که باید قبل از استفاده پاک‌سازی شوند.

در طراحی Low Frequency Trading Bot باید مشخص کنید داده از چه منبعی می‌آید: API کارگزاری، سرویس داده بازار، فایل‌های تاریخی، یا ترکیبی از این‌ها. هر منبع ویژگی‌های خاص خود را دارد. برخی APIها محدودیت نرخ دارند، برخی داده‌ها را با تأخیر می‌دهند، و برخی ممکن است در ساعات شلوغی ناپایدار شوند. همچنین داده خام معمولاً نیاز به نرمال‌سازی دارد: هم‌ترازسازی تایم‌زون‌ها، اصلاح داده‌های گمشده، تبدیل واحدها، محاسبه بازده‌ها، و یکسان‌سازی نمادها. اگر این مرحله به‌درستی انجام نشود، بک‌تست شما ممکن است بسیار خوش‌بینانه یا کاملاً گمراه‌کننده باشد.

از منظر عملی، بهتر است لایه داده از منطق استراتژی جدا باشد. یک Data Adapter می‌تواند داده‌های مختلف را به قالب داخلی مشترک تبدیل کند. این کار به شما اجازه می‌دهد از منابع چندگانه استفاده کنید و در صورت خرابی یک منبع، منبع جایگزین داشته باشید. همچنین برای بسیاری از بازارها، ذخیره‌سازی محلی داده‌های تاریخی با قالب‌های فشرده مانند Parquet یا Feather می‌تواند هم سرعت تحلیل را بالا ببرد و هم هزینه را کاهش دهد. در هر حال، در ربات معاملات کم‌بسامد باید فرض کنید داده همیشه کامل نیست؛ بنابراین معماری باید برای داده گمشده، تأخیر، تکرار و خطای API آماده باشد.

نکات مهم در کیفیت داده

  • هم‌ترازی زمانی (Time Alignment) بین منابع مختلف
  • پاک‌سازی داده‌های پرت و اسپایک‌های مشکوک
  • اصلاح شکاف‌ها و داده‌های گمشده
  • اعتبارسنجی نمادها و قراردادها
  • تفکیک داده‌های قابل‌معامله از داده‌های صرفاً تحلیلی
  • درنظرگرفتن تاخیر واقعی فید در بک‌تست و لایو

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

بک‌تست، اعتبارسنجی و جلوگیری از خطاهای آماری

بک‌تست (Backtest) مهم‌ترین ابزار ارزیابی اولیه برای ربات معاملات کم‌بسامد است، اما اگر درست انجام نشود می‌تواند خطرناک‌تر از مفید بودن باشد. دلیلش این است که بک‌تست‌های نادرست اغلب تصویری بیش‌ازحد خوب از عملکرد استراتژی می‌سازند. خطاهایی مانند look-ahead bias، survivorship bias، نادیده گرفتن slippage، کارمزد غیرواقعی، یا فرض اجرای کامل در بهترین قیمت، همگی می‌توانند نتایج را تحریف کنند. بنابراین هدف بک‌تست صرفاً «زیبا شدن نمودار» نیست؛ هدف این است که مشخص شود آیا ایده شما در شرایط نزدیک به واقعیت هم پایدار است یا خیر.

برای اعتبارسنجی بهتر، باید داده را به سه بخش تقسیم کرد: آموزش، اعتبارسنجی و آزمون نهایی. در استراتژی‌های مبتنی بر پارامتر، بهینه‌سازی کورکورانه روی کل داده بسیار خطرناک است، چون منجر به overfitting می‌شود. رویکردهای walk-forward analysis، rolling window و آزمون‌های برون‌نمونه می‌توانند کمک کنند تا مدل یا قانون معاملاتی در دوره‌های مختلف بازار ارزیابی شود. در LFT چون افق زمانی بلندتر است، ممکن است تعداد نمونه‌های معاملاتی کمتر باشد؛ به همین دلیل، ارزیابی آماری باید با احتیاط بیشتری انجام شود و از نتیجه‌گیری شتاب‌زده پرهیز شود.

از سوی دیگر، باید هزینه‌های واقعی را وارد بک‌تست کنید: کارمزد، اسپرد، لغزش، تأخیر اجرا، محدودیت حجم، رد شدن سفارش، و حتی اثر بازار در صورت بزرگ بودن سفارش نسبت به نقدشوندگی. اگر استراتژی شما روی کاغذ سودآور است اما با افزودن یک کارمزد کوچک از بین می‌رود، آن استراتژی در عمل ارزش کمی دارد. همچنین بهتر است نتایج را فقط با سود تجمعی نسنجید؛ معیارهایی مانند Sharpe Ratio، Sortino Ratio، Max Drawdown، Profit Factor، Win Rate، Expectancy و Calmar Ratio تصویر دقیق‌تری می‌دهند.

خطاهای رایج در بک‌تست

  • استفاده از داده‌ای که در زمان تصمیم‌گیری در دسترس نبوده است
  • نادیده گرفتن تأخیر ارسال و پر شدن سفارش
  • فرض کردن قیمت‌های اجرایی غیرواقعی
  • بهینه‌سازی بیش‌ازحد پارامترها
  • نادیده گرفتن رژیم‌های مختلف بازار
  • استفاده از نمونه‌های بسیار محدود و نتیجه‌گیری قطعی

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

for each bar in historical_data:
    update_features(bar)
    signal = strategy(features)
    target_position = risk_manager(signal, portfolio_state)
    order = execution_model(target_position, market_state)
    fill = simulate_fill(order, bar, slippage, fees)
    portfolio_state = update_portfolio(fill)
    log_state(portfolio_state)

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

مدیریت ریسک در ربات معاملات کم‌بسامد

در یک ربات معاملات کم‌بسامد (Low Frequency Trading Bot)، مدیریت ریسک (Risk Management) باید بخشی مرکزی از طراحی باشد، نه افزونه‌ای بعدی. بسیاری از تیم‌ها ابتدا استراتژی را می‌سازند و بعد به‌دنبال «اضافه کردن» ریسک‌منیجمنت می‌روند، در حالی‌که اندازه موقعیت، حد ضرر، محدودیت تمرکز، و قواعد توقف باید از همان ابتدا در منطق سیستم لحاظ شوند. ریسک فقط ریسک قیمت نیست؛ ریسک اجرای ناقص، ریسک داده، ریسک مدل، ریسک عملیاتی، ریسک طرف مقابل، ریسک نقدشوندگی و ریسک قانونی هم وجود دارد.

در LFT معمولاً می‌توان از قواعد ساده اما مؤثر استفاده کرد: سقف اندازه موقعیت، سقف زیان روزانه، توقف معامله بعد از چند خطای پیاپی، محدودیت بر تعداد معاملات باز، و محدودیت بر exposure هر دارایی یا هر صنعت. همچنین بهتر است Risk Engine مستقل از Strategy Engine باشد تا اگر استراتژی دچار خطا شد، ریسک‌منیجمنت همچنان بتواند جلوی رفتارهای خطرناک را بگیرد. برای نمونه، ممکن است استراتژی شما سیگنال خرید قوی بدهد اما موجودی نقد کافی نباشد یا نوسان اخیر بازار بیش از حد مجاز باشد؛ در این حالت لایه ریسک باید تصمیم را تعدیل یا رد کند.

ابزارهای رایج مدیریت ریسک

  • Position Sizing بر اساس نوسان یا سرمایه
  • Stop Loss و Take Profit با توجه به افق زمانی
  • Trailing Stop در شرایط مناسب
  • Exposure Limits برای نماد، صنعت یا کلاس دارایی
  • Portfolio Constraints برای همبستگی و تمرکز
  • Circuit Breaker برای توقف خودکار در شرایط بحرانی

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

اجرای سفارش و مسئله لغزش

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

Slippage یا لغزش قیمت، تفاوت بین قیمت مورد انتظار و قیمت اجرای واقعی است. این پدیده در بازارهای کم‌عمق، زمان‌های پرنوسان یا هنگام ارسال سفارش‌های بزرگ بیشتر دیده می‌شود. برای Low Frequency Trading Bot بهتر است مدل اجرای سفارش حداقل سه چیز را بشناسد: عمق بازار، اسپرد فعلی، و حجم قابل‌معامله در افق کوتاه. اگر استراتژی شما بر اساس کندل ۱ ساعته طراحی شده باشد، اما سفارش را به‌صورت یک‌باره در لحظه بزنید، ممکن است اثر بازار عملکرد را تخریب کند. بنابراین گاهی سفارش‌گذاری مرحله‌ای، iceberg-like logic یا توزیع زمانی سفارش‌ها مفید است.

در محیط‌های واقعی، ربات باید بتواند پاسخ کارگزار یا صرافی را مدیریت کند: سفارش ثبت شد، بخشی پر شد، رد شد، لغو شد یا در صف ماند. هر کدام از این وضعیت‌ها باید در state machine سیستم تعریف شوند. اگر وضعیت سفارش‌ها مبهم بماند، ممکن است ربات به‌طور ناخواسته موقعیت مضاعف بگیرد یا موقعیت را ناصحیح ببندد. ازاین‌رو، Order Management System (OMS) یکی از بخش‌های جدی هر ربات معاملات کم‌بسامد است.

شبه‌کد اجرای سفارش

if signal == BUY and risk_ok:
    if spread < max_spread and volume > min_volume:
        place_limit_buy(price=best_bid + tick)
    else:
        wait_or_reduce_size()

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

زیرساخت فنی و انتخاب زبان‌ها و فریم‌ورک‌ها

برای ساخت ربات معاملات کم‌بسامد، انتخاب زبان برنامه‌نویسی و فریم‌ورک باید با نیاز پروژه هم‌راستا باشد. اگر هدف شما پژوهش، نمونه‌سازی سریع و تحلیل داده است، Python معمولاً بهترین انتخاب اولیه است، چون اکوسیستم قدرتمندی برای تحلیل عددی، داده و بک‌تست دارد. کتابخانه‌هایی مانند pandas، NumPy، SciPy، statsmodels، scikit-learn، vectorbt و backtrader برای کارهای کم‌بسامد بسیار مفیدند. اگر به عملکرد بالاتر یا کنترل بیشتر نیاز باشد، می‌توان بخش‌هایی را با C++، Rust یا Go پیاده‌سازی کرد و لایه پژوهش را در پایتون نگه داشت.

در معماری‌های مدرن، استفاده از Docker، Kubernetes، صف پیام مانند RabbitMQ یا Kafka، و پایگاه داده مناسب برای زمان‌سری یا رویدادها، مزیت بزرگی دارد. برای ذخیره‌سازی معاملات و رویدادها می‌توان از PostgreSQL، TimescaleDB، ClickHouse یا حتی دیتاستورهای فایل‌محور استفاده کرد. اگر سیستم شما چند ماژول دارد، ارتباط میان آن‌ها بهتر است از طریق APIهای داخلی یا پیام‌رسانی رویدادمحور انجام شود تا وابستگی مستقیم کاهش یابد. همچنین برای استقرار، استفاده از CI/CD و تست خودکار اهمیت زیادی دارد، زیرا خطای یک commit می‌تواند به‌صورت مستقیم روی سرمایه اثر بگذارد.

زبان‌ها و کاربردها

  • Python: نمونه‌سازی سریع، تحلیل داده، بک‌تست، مدل‌سازی
  • C++: سرعت بالا، اجزای حساس به عملکرد
  • Rust: ایمنی حافظه، کارایی خوب، سیستم‌های حساس
  • Go: سرویس‌های شبکه‌ای و عملیات سبک
  • Java / C#: سامانه‌های سازمانی و ساختارمند

در عمل بسیاری از تیم‌ها از ترکیب چند زبان استفاده می‌کنند. مثلاً هسته پژوهش در Python، سرویس اجرای سفارش در Go یا Rust، و ذخیره‌سازی در PostgreSQL. این ترکیب اگرچه پیچیدگی را افزایش می‌دهد، اما در مقیاس جدی می‌تواند تعادل مناسبی بین سرعت توسعه و قابلیت اتکا ایجاد کند. با این حال، برای یک Low Frequency Trading Bot تک‌نفره یا تیم کوچک، سادگی معمولاً ارزشمندتر از چندزبانه کردن سیستم است.

مانیتورینگ، ثبت وقایع و هشدار

مانیتورینگ (Monitoring) در ربات معاملات کم‌بسامد یک ضرورت عملیاتی است، نه یک قابلیت تزئینی. چون حتی اگر استراتژی درست باشد، خرابی API، قطعی شبکه، انحراف داده، یا مشکل در حساب کارگزاری می‌تواند کل عملکرد را مختل کند. برای همین باید وضعیت سیستم، وضعیت سفارش‌ها، سلامت اتصال، تأخیر داده، خطاهای استثنا، و شاخص‌های عملکردی به‌طور پیوسته پایش شوند. همچنین Logging دقیق و ساخت‌یافته لازم است تا بتوان بعداً رفتار سیستم را بازسازی و تحلیل کرد.

هشدارها باید معنی‌دار باشند. هشدار زیاد و بی‌هدف باعث alert fatigue می‌شود و در نهایت تیم به هشدارها بی‌تفاوت می‌گردد. بهتر است آستانه‌های هشدار بر اساس اهمیت تعریف شوند: قطع داده زنده، رد شدن چند سفارش پیاپی، اختلاف شدید بین state داخلی و موجودی واقعی، افت غیرعادی کیفیت داده، یا انحراف محسوس از ریسک مجاز. در Low Frequency Trading چون تصمیم‌ها سریع‌السیر نیستند، فرصت کافی برای تشخیص و اصلاح بسیاری از خطاها وجود دارد، اما این فقط در صورتی مفید است که مانیتورینگ به‌موقع و دقیق باشد.

شاخص‌های مانیتورینگ

  • تأخیر دریافت داده
  • نرخ خطاهای API
  • وضعیت موجودی و موقعیت
  • تعداد سفارش‌های باز
  • اختلاف پرتفوی داخلی با پرتفوی واقعی
  • افت عملکرد نسبت به انتظار
  • میزان استفاده از CPU، RAM و دیسک
  • سلامت سرویس‌ها و اتصال‌ها

برای تیم‌های حرفه‌ای، داشبوردهای زنده در ابزارهایی مثل Grafana یا سامانه‌های مشابه می‌توانند بسیار مفید باشند. همچنین نگهداری audit trail برای ردیابی تصمیم‌ها، داده‌های ورودی و تغییرات کد اهمیت دارد. اگر یک ربات معاملات کم‌بسامد در حالت live رفتاری غیرعادی نشان دهد، شما باید بتوانید بفهمید این رفتار از داده، استراتژی، اجرا یا عملیات آمده است.

امنیت، دسترسی و حفاظت از سرمایه

امنیت در ربات معاملات کم‌بسامد فقط به حفاظت از کلید API محدود نمی‌شود. باید به امنیت کل زنجیره فکر کرد: سرور، رمزها، سطح دسترسی، لاگ‌ها، پشتیبان‌ها، و فرآیند استقرار. اگر کسی به کلیدهای API، توکن‌ها یا دسترسی به حساب کارگزاری دست پیدا کند، می‌تواند سفارش‌های ناخواسته ثبت کند یا داده‌ها را آلوده کند. برای همین، استفاده از secret management، رمزنگاری، محدودسازی IP، احراز هویت چندمرحله‌ای و اصل کمترین دسترسی ضروری است.

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

توصیه‌های امنیتی

  • نگهداری کلیدها در Vault یا سامانه‌های امن
  • محدودسازی دسترسی شبکه و IP
  • جداسازی محیط dev / staging / production
  • استفاده از لاگ‌های امن و بدون افشای اطلاعات حساس
  • بررسی دوره‌ای مجوزهای API
  • پشتیبان‌گیری منظم از تنظیمات و داده‌ها

یک نکته مهم دیگر، امنیت زنجیره تأمین نرم‌افزار است. اگر از بسته‌های متن‌باز استفاده می‌کنید، باید به نسخه‌ها، آسیب‌پذیری‌ها و وابستگی‌ها توجه داشته باشید. در Python این موضوع به‌ویژه مهم است، چون اکوسیستم بسیار گسترده‌ای دارد. برای یک Low Frequency Trading Bot که به سرمایه واقعی متصل است، به‌روزرسانی بدون آزمون می‌تواند خطرناک باشد.

استراتژی‌های نمونه برای LFT

استراتژی در ربات معاملات کم‌بسامد باید با افق زمانی و هزینه‌های اجرایی هم‌خوان باشد. هر استراتژی لزوماً مناسب همه بازارها نیست، اما چند خانواده از ایده‌ها در LFT بسیار رایج‌اند: میانگین متحرک (Moving Average)، بازگشت به میانگین (Mean Reversion)، شکست (Breakout) و آربیتراژ آماری با فرکانس پایین (Low-Frequency Statistical Arbitrage). مهم این است که این‌ها را نه به‌عنوان فرمول جادویی، بلکه به‌عنوان چارچوب‌هایی برای آزمایش در نظر بگیریم.

میانگین متحرک

در استراتژی میانگین متحرک (Moving Average)، ربات با عبور قیمت از میانگین یا تقاطع دو میانگین تصمیم می‌گیرد. برای مثال، اگر میانگین کوتاه‌مدت از میانگین بلندمدت بالاتر برود، می‌توان آن را به‌عنوان سیگنال صعودی تفسیر کرد. در LFT این استراتژی بیشتر در تایم‌فریم‌های روزانه یا ساعتی کاربرد دارد تا نویز کم شود. مزیت این روش سادگی و قابلیت توضیح است، اما در بازارهای رِنج یا پرنوسان ممکن است سیگنال‌های اشتباه تولید کند.

import pandas as pd

df["fast"] = df["close"].rolling(10).mean()
df["slow"] = df["close"].rolling(30).mean()
df["signal"] = 0
df.loc[df["fast"] > df["slow"], "signal"] = 1
df.loc[df["fast"] < df["slow"], "signal"] = -1

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

بازگشت به میانگین

در بازگشت به میانگین (Mean Reversion) فرض می‌شود که قیمت یا spread پس از انحراف از سطح تعادلی، تمایل به بازگشت دارد. این استراتژی معمولاً به‌وسیله z-score، باندهای آماری یا فاصله از یک میانگین پویا پیاده‌سازی می‌شود. در ربات معاملات کم‌بسامد این ایده می‌تواند روی دارایی‌های همبسته، جفت‌معامله‌ها یا حتی روی قیمت یک دارایی نسبت به میانگین تاریخی خودش استفاده شود. البته باید دقت کرد که بازگشت به میانگین همیشه رخ نمی‌دهد و در زمان‌های شکست ساختاری، این فرض می‌تواند زیان‌زا باشد.

شکست

استراتژی شکست (Breakout) روی خروج قیمت از یک محدوده، سقف/کف تاریخی، یا الگوی تراکمی تمرکز می‌کند. در LFT این استراتژی معمولاً نیازمند فیلتر حجم یا نوسان است تا شکست‌های کاذب کاهش یابد. برای نمونه، خروج قیمت از سقف ۲۰ روزه به‌همراه افزایش حجم می‌تواند سیگنال قوی‌تری نسبت به شکست صرفاً قیمتی باشد. با این حال، شکست در بازارهای بسیار نویزی ممکن است به‌سرعت به برگشت تبدیل شود، بنابراین اجرای سفارش باید هوشمندانه باشد.

آربیتراژ آماری با فرکانس پایین

آربیتراژ آماری با فرکانس پایین (Low-Frequency Statistical Arbitrage) بر روابط آماری میان چند دارایی تکیه می‌کند؛ مثلاً اسپردهای تاریخی، همبستگی‌ها، یا نسبت‌های قیمتی. در اینجا هدف بهره‌برداری از انحراف موقت از رابطه تاریخی است، نه پیش‌بینی جهت مطلق بازار. این نوع استراتژی در LFT به دلیل افق زمانی طولانی‌تر، نیاز به داده تمیز، آزمون پایداری و مدیریت ریسک همبستگی دارد. اگر رابطه آماری در رژیم جدید بازار از بین برود، استراتژی هم باید خود را تطبیق دهد یا متوقف شود.

معیارهای ارزیابی عملکرد

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

معیارهای اصلی

  • CAGR یا رشد سالانه مرکب
  • Sharpe Ratio برای بازده تعدیل‌شده با ریسک
  • Sortino Ratio برای تمرکز بر ریسک نزولی
  • Max Drawdown برای افت سرمایه
  • Calmar Ratio
  • Profit Factor
  • Hit Rate / Win Rate
  • Expectancy
  • Turnover و اثر هزینه‌ها
  • Capacity یا توان جذب سرمایه

در LFT معیارهایی مانند Max Drawdown و stability across regimes بسیار مهم‌اند. ممکن است یک استراتژی در دوره‌ای خاص عملکرد خوبی داشته باشد اما در دوره دیگر به‌کلی تضعیف شود. بنابراین بهتر است نتایج را در بازه‌های زمانی مختلف، بازارهای مختلف و سناریوهای متفاوت بررسی کنید. همچنین اگر backtest فقط روی یک دوره صعودی یا نزولی انجام شود، ممکن است تصویر ناقصی ایجاد کند. آزمون در دوره‌های با نوسان متفاوت، برای قضاوت واقع‌بینانه ضروری است.

یک چارچوب ارزیابی بهتر

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

اگر پاسخ این پرسش‌ها مثبت نباشد، ممکن است استراتژی ظاهراً جذاب باشد اما برای Low Frequency Trading Bot عملی نباشد.

زبان شبه‌کد و منطق تصمیم‌گیری

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

if new_market_data:
    features = build_features(data)
    raw_signal = strategy(features)

    if raw_signal != NO_TRADE:
        size = risk_manager.calculate_size(raw_signal, portfolio)
        order = executor.create_order(raw_signal, size)

        if compliance.check(order) and risk_manager.approve(order):
            executor.send(order)
        else:
            log("order blocked")

این الگو ساده به نظر می‌رسد، اما در عمل هر تابع می‌تواند چندین شرط، استثنا و حالت داشته باشد. برای مثال، calculate_size باید به نوسان، موجودی، ریسک مجاز، همبستگی با سایر موقعیت‌ها و محدودیت‌های کارگزار توجه کند. send نیز باید پاسخ‌های مختلف API را مدیریت کند. بنابراین زیبایی یک Low Frequency Trading Bot خوب در این است که منطق پیچیده را در لایه‌های تمیز و قابل‌فهم پنهان نکند، بلکه آن را قابل‌ردیابی و آزمون‌پذیر نگه دارد.

خطاهای رایج در طراحی و استقرار

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

اشتباه مهم دیگر، فقدان تفکیک بین لایه‌هاست. اگر کد استراتژی، اجرا و مانیتورینگ در هم ادغام شوند، عیب‌یابی دشوار می‌شود. همچنین برخی ربات‌ها به دلیل وابستگی شدید به یک API خاص شکننده‌اند؛ کافی است API تغییر جزئی کند یا نرخ محدود شود تا سیستم از کار بیفتد. در کنار این‌ها، خطاهای انسانی مثل تغییر پارامتر بدون ثبت، استقرار نسخه نادرست، یا استفاده از داده آلوده هم بسیار رایج‌اند.

چند خطای متداول

  • بک‌تست غیرواقعی و خوش‌بینانه
  • عدم درنظرگرفتن کارمزد و لغزش
  • overfitting
  • وابستگی شدید به یک منبع داده
  • نبود مانیتورینگ و alert مناسب
  • نداشتن محدودیت ریسک سراسری
  • ناهماهنگی بین موجودی واقعی و state داخلی
  • تست نکردن سناریوهای خرابی

برای کاهش این خطاها، بهتر است فرآیند توسعه شما شامل unit test، integration test، replay test و در صورت امکان paper trading باشد. هر مرحله بخشی از خطر را کم می‌کند و کمک می‌کند اشکال‌ها قبل از ورود به حساب واقعی شناسایی شوند.

ملاحظات حقوقی و اخلاقی

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

از نظر اخلاقی نیز مهم است که ربات شما رفتارهای مخرب، گمراه‌کننده یا دستکاری‌گر نداشته باشد. برای مثال، ارسال الگوهای سفارش جعلی یا تلاش برای ایجاد سیگنال‌های مصنوعی می‌تواند نه‌تنها غیراخلاقی، بلکه غیرقانونی باشد. در Low Frequency Trading معمولاً تمرکز بر تحلیل و اجرای منظم است، نه بهره‌برداری از خلأهای مشکوک. همچنین اگر ربات برای مشتری یا سازمانی دیگر توسعه می‌یابد، شفافیت درباره ریسک‌ها، محدودیت‌ها و شرایط عملکرد اهمیت زیادی دارد. این مقاله توصیه سرمایه‌گذاری نیست و هر تصمیم عملی باید با توجه به قوانین محلی، وضعیت مالی، و ارزیابی مستقل اتخاذ شود.

نمونه معماری عملی برای تیم‌های فنی

یک تیم فنی که قصد ساخت ربات معاملات کم‌بسامد (Low Frequency Trading Bot) دارد، می‌تواند از معماری زیر الهام بگیرد: داده‌های بازار از API دریافت می‌شوند، در یک صف پیام یا پایگاه داده ذخیره می‌شوند، یک سرویس تحلیل ویژگی‌ها را محاسبه می‌کند، سرویس استراتژی سیگنال می‌سازد، موتور ریسک آن را غربال می‌کند، و سرویس اجرا سفارش را ثبت و پیگیری می‌کند. داشبورد مانیتورینگ همه رویدادها را نشان می‌دهد و لاگ‌ها برای بازبینی و تحلیل نگهداری می‌شوند. این ساختار هم برای توسعه داخلی و هم برای استقرار در محیط واقعی مناسب است.

در این مدل، بهتر است هر سرویس contract مشخصی داشته باشد. مثلاً ورودی و خروجی استراتژی باید ساختار داده ثابت داشته باشد؛ موتور اجرا فقط با سفارش‌های معتبر کار کند؛ و مانیتورینگ بتواند رویدادها را به‌صورت زمان‌سنجی‌شده دریافت کند. اگر از Python استفاده می‌کنید، می‌توانید لایه پژوهش را با notebook و اسکریپت‌های تحلیلی توسعه دهید و لایه تولید را با سرویس‌های مستقل بسازید. اگر نیاز به مقیاس و اطمینان بیشتر دارید، می‌توان از FastAPI برای API داخلی، Redis برای کش و صف سبک، و PostgreSQL برای داده‌های ساختاریافته بهره برد. مهم این است که هر انتخاب فنی باید از نیاز واقعی، نه صرفاً سلیقه، ناشی شود.

الگوی پیشنهادی ماژول‌ها

  • data_service برای دریافت و پاک‌سازی داده
  • strategy_service برای سیگنال‌دهی
  • risk_service برای کنترل حجم و محدودیت‌ها
  • execution_service برای ارسال و پیگیری سفارش
  • monitoring_service برای هشدار و سلامت
  • storage_service برای آرشیو و تحلیل تاریخی

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

جمع‌بندی

ربات معاملات کم‌بسامد (Low Frequency Trading Bot) یک سامانه میان‌رشته‌ای است که به ترکیب دقیق مهندسی نرم‌افزار، تحلیل داده، مدیریت ریسک و درک ساختار بازار نیاز دارد. تفاوت اصلی آن با HFT در این است که مزیت رقابتی بیشتر از کیفیت استراتژی، استحکام بک‌تست، مدیریت هزینه‌ها و قابلیت اجرای پایدار می‌آید تا از سرعت خام زیرساخت. برای ساخت چنین رباتی باید از همان ابتدا به دیتافید (Data Feed)، بک‌تست (Backtest)، مدیریت ریسک (Risk Management)، اجرای سفارش (Order Execution)، مانیتورینگ (Monitoring) و امنیت به‌صورت یکپارچه نگاه کرد. همچنین انتخاب زبان‌ها و فریم‌ورک‌ها، معماری ماژولار، ثبت وقایع، و کنترل خطاها نقش تعیین‌کننده‌ای در کیفیت نهایی دارند.

برای برنامه‌نویسان و فعالان بازارهای مالی، جذابیت Low Frequency Trading در این است که امکان ساخت سیستم‌هایی شفاف‌تر و کم‌هزینه‌تر از HFT را فراهم می‌کند؛ با این حال، این مزیت فقط زمانی محقق می‌شود که از خطاهای آماری، بک‌تست غیرواقعی، overfitting و بی‌توجهی به اجرای واقعی پرهیز شود. استراتژی‌هایی مانند میانگین متحرک (Moving Average)، بازگشت به میانگین (Mean Reversion)، شکست (Breakout) و آربیتراژ آماری با فرکانس پایین (Low-Frequency Statistical Arbitrage) می‌توانند نقطه شروع خوبی باشند، اما هیچ‌کدام بدون آزمون دقیق، ریسک‌سنجی و انطباق با هزینه‌های واقعی قابل اتکا نیستند. در نهایت، یک ربات معاملات کم‌بسامد موفق معمولاً رباتی است که نه فقط سیگنال تولید می‌کند، بلکه در شرایط واقعی بازار، با انضباط، شفافیت و قابلیت پیگیری عمل می‌کند.

FAQ

ربات معاملات کم‌بسامد دقیقاً چه تفاوتی با ربات HFT دارد؟

ربات معاملات کم‌بسامد (Low Frequency Trading Bot) در بازه‌های زمانی کندتر تصمیم می‌گیرد و معمولاً بر کیفیت سیگنال، مدیریت ریسک و اجرای قابل‌اعتماد تکیه دارد، در حالی که HFT بیش از هر چیز به سرعت و زیرساخت کم‌تاخیر وابسته است.

آیا ساخت ربات Low Frequency Trading فقط با Python ممکن است؟

خیر. Python برای پژوهش و بک‌تست بسیار مناسب است، اما بسته به نیاز می‌توان از C++، Rust، Go یا Java نیز استفاده کرد. بسیاری از تیم‌ها از ترکیب چند زبان بهره می‌برند.

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

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

آیا بک‌تست خوب تضمین‌کننده موفقیت است؟

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

برای شروع، کدام استراتژی‌ها مناسب‌ترند؟

برای شروع معمولاً میانگین متحرک (Moving Average)، بازگشت به میانگین (Mean Reversion)، شکست (Breakout) و نسخه‌های ساده از آربیتراژ آماری با فرکانس پایین نقطه شروع مناسبی هستند، البته نه به‌صورت قطعی و بدون آزمون.

آیا باید در ربات کم‌بسامد از مانیتورینگ استفاده کرد؟

بله، Monitoring و Logging حیاتی‌اند. بدون آن‌ها تشخیص خطا، کنترل ریسک و عیب‌یابی در محیط واقعی بسیار دشوار می‌شود.

آیا این مقاله توصیه سرمایه‌گذاری است؟

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

دیدگاه‌ها (0)

  • نظرات نامربوط به محتوا تأیید نخواهند شد.
  • لطفاً از افزودن نظرات تکراری خودداری کنید.
  • نظرات مربوط به دوره‌ها فقط برای خریداران محصول است.

*
*