من می‌خواهم برای «دیده‌بان اختیار معامله» در پلتفرم آپشن‌باز یک فرمول بنویسم. مرجع کامل زیر را بخوان و بر اساس آن، فقط با همین نام‌ها، کد را برایم بنویس. قواعدی که باید رعایت کنی: - زبان جاوااسکریپت (ES6) است و خروجی با return برگردانده می‌شود. - فقط از فیلدها و توابعی استفاده کن که در همین متن آمده‌اند. اسم فیلد را حدس نزن: موتور برای نام ناشناخته خطا نمی‌دهد، ستون را خالی برمی‌گرداند، پس اشتباهت دیده نمی‌شود. - اگر چیزی که لازم داری در این مرجع نیست، بگو در دسترس نیست؛ جایگزین از خودت نساز. - هر مقداری که کاربر ممکن است بخواهد عوض کند را به‌جای عدد ثابت، به شکل یکی از ثابت‌های تنظیمات ویژوال (FILTER_ / SETTING_ / SHOW_) بالای فرمول تعریف کن. - کنار کد، در چند خط فارسی توضیح بده هر بخش چه می‌کند. نسخهٔ همیشه‌به‌روزِ این مرجع: https://optionbaaz.ir/option/formula-prompt.txt ## بخش 1 — قوانین موتور فرمول ### ساختار فرمول و قوانین return هر فرمول بدنه یک تابع جاوااسکریپت است که به‌ازای هر سطر جدول یک‌بار اجرا می‌شود. اگر کل فرمول یک خط باشد، موتور به‌طور خودکار return به ابتدای آن اضافه می‌کند و نوشتن return لازم نیست. اگر فرمول بیش از یک خط باشد (متغیر، شرط، حلقه)، حتماً باید حداقل یک return داشته باشد؛ در غیر این صورت ستون پیام «⚠ return ندارد» نشان می‌دهد. در فیلتر چندخطی هم return true/false الزامی است، وگرنه خروجی undefined معادل false در نظر گرفته می‌شود و همه سطرها حذف می‌شوند. می‌توان در هر شاخه if یک return گذاشت؛ اولین return که اجرا شود خروجی نهایی است. ```js option.ti.lastPrice * option.size ``` ```js let profit = option.ti.buy1Price / ua.ti.lastPrice * 100; return roundNumber(ytmProfit(profit, option.daysUntilMaturity), 1) + '%'; ``` ```js if (!option.ti.volume) return ''; if (option.type == 'call') return style('C', '#3b82f6'); return style('P', '#f97316'); ``` ### سه نوع فرمول: ستون، فیلتر، تابع هر آیتم فرمول یکی از سه نوع است. ستون (column): خروجی‌اش در یک ستون سفارشی دیده‌بان نمایش داده می‌شود و می‌تواند عدد، متن یا HTML باشد. فیلتر (filter): باید true یا false برگرداند؛ سطرهایی که false بگیرند از جدول حذف می‌شوند. تابع (function): در جدول نمایش داده نمی‌شود و فقط یک تابع کمکی است که قبل از اجرای ستون‌ها و فیلترها داخل scope تزریق می‌شود. ### ستون محاسباتی و خروجی HTML ستون محاسباتی یک ستون سفارشی در دیده‌بان است و مقدار برگشتی فرمول در آن نمایش داده می‌شود. خروجی می‌تواند عدد، متن ساده یا HTML باشد. برای رنگ‌بندی، tooltip یا ترکیب چند مقدار در یک ستون از تابع style استفاده کنید و چند style را با + به هم بچسبانید. برای رنگ شرطی بر اساس حد پایین/بالا از colorCondition و برای رنگ‌بندی بازه‌ای از colorRange استفاده کنید. ```js style(option.state, option.state=='ITM'?'green':'red') + ' | ' + style(roundNumber(intrinsic(),0), '#888') ``` ```js let d = calcBS().delta; return colorCondition(d, 0.3, 'red', 0.5, 'green', 'color', false); ``` ### فیلتر و شرط‌نویسی فرمول از نوع فیلتر باید یک مقدار منطقی برگرداند: true یعنی سطر بماند و false یعنی حذف شود. فیلتر تک‌خطی نیازی به return ندارد ولی فیلتر چندخطی حتماً باید return true/false داشته باشد. خروجی undefined یا null معادل false است، پس فراموش‌کردن return باعث خالی‌شدن کل جدول می‌شود. فعال و غیرفعال کردن فیلترها از پنل فیلترهای نوار ابزار انجام می‌شود و نیازی به ویرایش کد نیست. ```js option.state == 'ITM' && leverage() >= 4 ``` ```js let iv = calcBS().iv; let hv = ua.hv; if (!iv || !hv) return false; return iv > hv; ``` ### حالت دوگانه: یک فرمول هم ستون هم فیلتر (FILTER_RESULT و FILTER_SHOW) با نوشتن const FILTER_RESULT = false; در ابتدای فرمول، همان یک کد هم مقدار ستون را نمایش می‌دهد و هم به‌عنوان فیلتر عمل می‌کند. مقدار واقعی FILTER_RESULT را موتور در زمان اجرا تعیین می‌کند: در حالت نمایش ستون false و در حالت فیلتر true. ثابت اختیاری FILTER_SHOW کنترل می‌کند مقدار ستون نمایش داده شود یا نه، بدون آنکه فیلتر غیرفعال شود: true یعنی نمایش مقدار و false یعنی خروجی خالی. الگوی رایج این است که وقتی FILTER_RESULT برقرار است شرط برگردانده شود و در غیر این صورت خروجی نمایشی ستون. ```js const FILTER_RESULT = false; const FILTER_SHOW = true; let lev = leverage(); if (FILTER_RESULT) return lev >= 3; return style(roundNumber(lev, 1), lev >= 3 ? 'green' : '#888', '', 'اهرم'); ``` ### آبجکت‌های option و ua و نقش ti هر فرمول به دو آبجکت اصلی سطر جاری دسترسی دارد. آبجکت option مربوط به خود قرارداد اختیار است (مثلاً ضخود) و فیلدهایی مثل strike، type، daysUntilMaturity، state و openInterest دارد. آبجکت ua مربوط به دارایی پایه همان قرارداد است (مثلاً خودرو) و فیلدهایی مثل namad، hv، ivRank و ivPercentile دارد. قیمت‌ها و اطلاعات لحظه‌ای هر دو زیر پسوند ti قرار دارند: option.ti.lastPrice برای قیمت قرارداد و ua.ti.lastPrice برای قیمت پایه. مجموعه فیلدهای ti برای هر دو آبجکت یکسان است. ```js option.ti.lastPrice ``` ```js ua.ti.lastPrice ``` ### سطر جاری: فرمول روی کدام قرارداد اجرا می‌شود فرمول هرگز روی «یک قرارداد انتخاب‌شده» اجرا نمی‌شود؛ موتور آن را برای تک‌تک سطرهای جدول، هر بار جداگانه، اجرا می‌کند. در هر اجرا آبجکت option همان قرارداد سطری است که در آن لحظه پردازش می‌شود و ua دارایی پایه همان سطر. یعنی «قرارداد اصلی» چیزی نیست که کاربر انتخاب کند؛ به‌ازای هر سطر، خودِ آن سطر قرارداد اصلی است. بنابراین هیچ‌وقت نباید پرسید فرمول روی کدام ردیف نوشته شود؛ فرمول همیشه از دید سطر جاری نوشته می‌شود. برای رسیدن به بقیه قراردادها همیشه نسبت به سطر جاری حرکت کنید: optionSE(n) قرارداد هم‌سررسید با n استرایک بالاتر (n>=0) یا پایین‌تر (n<0)، optionSE(0, "os") قرارداد طرف مقابل با همان استرایک، optionSU سررسیدهای دیگر همان پایه، و getOptionByNamad وقتی نماد دقیق را می‌دانید. خودِ optionSE(0) همان سطر جاری است، پس اولین استرایک بالاتر optionSE(1) و دومی optionSE(2) است. این توابع برای سطرهای لبه زنجیره undefined برمی‌گردانند، پس قبل از استفاده حتماً بررسی کنید وگرنه ستون خطا می‌دهد. ```js option.strike ``` ```js let next = optionSE(1); if (!next) return ''; return next.strike - option.strike; ``` ### استراتژی چندپایه: نوشتن فرمول از دید یک پا استراتژی چندپایه یک فرمول از نوع ستون است و مثل هر ستون دیگری روی همه سطرها اجرا می‌شود؛ نوع جداگانه‌ای برای استراتژی وجود ندارد. الگو همیشه یکی است: سطر جاری را پای مبنا بگیرید، بقیه پاها را با optionSE نسبت به همان سطر پیدا کنید، اگر یکی از آن‌ها نبود خروجی خالی بدهید، و در آخر پاها را با pos.add اضافه کرده و با pos.build دکمه نمودار را برگردانید. انتخاب پای مبنا یک قرارداد داخلی است و به کاربر ربطی ندارد: پایین‌ترین استرایک را پای مبنا بگیرید تا بقیه پاها با اندیس مثبت پیدا شوند. در نتیجه ستون فقط روی سطرهایی مقدار می‌گیرد که ساختار کامل از آن‌ها شروع می‌شود و بقیه سطرها خالی می‌مانند؛ این درست است و نباید با فیلتر عوض شود. نوع قرارداد را هم صریح بررسی کنید، چون فرمول روی سطرهای پوت هم اجرا می‌شود. فاصله استرایک بین پاها را به‌جای عدد ثابت با یک ثابت SETTING_ بنویسید تا کاربر بدون دست زدن به کد عوضش کند. ```js const SETTING_STEP = 1; // فاصله استرایک بین پاها if (option.type != 'call') return ''; // سطر جاری همان K1 است: پایی که خریداری می‌شود let k2 = optionSE(SETTING_STEP); let k3 = optionSE(SETTING_STEP * 2); if (!k2 || !k3) return ''; pos.add('buy', option.namad, 1, 'sell'); pos.add('sell', k2.namad, 1, 'buy'); pos.add('sell', k3.namad, 1, 'buy'); return pos.build('کال لدر صعودی'); ``` ### تابع عمومی و scope مشترک فرمول‌ها آیتم‌هایی که با نوع «تابع» ذخیره می‌شوند در جدول نمایش داده نمی‌شوند، اما موتور آن‌ها را قبل از اجرای همه ستون‌ها و فیلترها داخل scope همان worker تزریق می‌کند. بنابراین یک محاسبه تکراری را یک‌بار تعریف می‌کنید و در چند ستون و فیلتر استفاده می‌کنید. تابع عمومی باید با کلیدواژه function تعریف شود و خودش مقدار را با return برگرداند. داخل تابع عمومی هم به option و ua و همه توابع آماده دسترسی دارید. ```js function bsDiff() { return calcRateChange(calcBS().bs, option.ti.sell1Price, 1); } ``` ```js style(bsDiff() + '%', Math.abs(bsDiff()) <= 10 ? 'green' : 'red') ``` ```js bsDiff() >= -10 && bsDiff() <= 10 ``` ### ساخت استراتژی و نمودار سود و زیان با pos آبجکت pos برای ساخت استراتژی و نمایش دکمه نمودار سود و زیان در ستون دیده‌بان است. جریان کار: ابتدا با pos.add پاهای استراتژی را اضافه کنید، سپس با pos.build خروجی HTML دکمه نمودار را برگردانید. با کلیک روی آن دکمه پنل استراتژی باز می‌شود و همان پاها روی نمودار سود و زیان بارگذاری می‌شوند. با pos.clear می‌توان لیست پاهای موقت را بدون ساخت نمودار خالی کرد. pos یک نوع فرمول جداگانه نیست: همیشه داخل یک فرمول از نوع ستون نوشته می‌شود و پاها نسبت به قرارداد سطر جاری پیدا می‌شوند. ```js pos.add('buy', option.namad, 1, 'sell'); pos.add('sell', optionSE(1).namad, 1, 'buy'); return pos.build('اسپرد صعودی'); ``` ### بلک‌شولز و یونانی‌ها با calcBS تابع calcBS قیمت تئوری بلک‌شولز و یونانی‌های قرارداد را محاسبه می‌کند. خروجی یک آبجکت شامل bs، delta، gamma، vega، theta، rho و iv است. بدون آرگومان روی قرارداد سطر جاری اجرا می‌شود؛ با نام نماد روی همان قرارداد و با آبجکت override روی مفروضات دلخواه. فیلد آماده option.blackSholesHV قیمت بلک‌شولز با نوسان تاریخی پایه (ua.hv) است و از پیش محاسبه شده، پس برای مقایسه پرمیوم با قیمت منصفانه نیازی به calcBS ندارد. ```js roundNumber(calcBS().delta, 2) ``` ```js let iv = calcBS().iv; let hv = ua.hv; if (!iv || !hv) return ''; return roundNumber((iv - hv) * 100, 1) + '%'; ``` ### جاوااسکریپت پرکاربرد در فرمول از let برای متغیرهای میانی و از if / else if / else برای منطق چندشاخه‌ای استفاده کنید. شرط کوتاه (ternary) با ? : برای انتخاب بین دو مقدار مناسب فرمول تک‌خطی است. رشته قالب‌بندی‌شده با backtick و ${} برای ترکیب متن ثابت با مقدار محاسباتی به کار می‌رود. بسیاری از فیلدها می‌توانند null یا صفر باشند؛ قبل از محاسبه با if بررسی کنید یا از ?? استفاده کنید. توابع ریاضی استاندارد جاوااسکریپت مثل Math.abs، Math.round، Math.floor، Math.ceil، Math.max و Math.min در دسترس هستند. ```js option.type == 'call' ? style('Call', 'blue') : style('Put', 'orange') ``` ```js if (!option.ti.lastPrice) return ''; return option.ti.lastPrice * option.size; ``` ```js (option.iv ?? 0) * 100 + '%' ``` ### عملگرهای مقایسه و منطقی ### مبنای قیمت دیده‌بان و تابع basePrice نوار ابزار دیده‌بان یک «مبنای قیمت» دارد که تعیین می‌کند محاسبات بر اساس کدام قیمت انجام شود. تابع basePrice همان مبنای انتخابی کاربر را برمی‌گرداند و هر آبجکت دارای ti را می‌پذیرد: basePrice(option) و basePrice(ua). اگر می‌خواهید مستقل از تنظیم کاربر روی قیمت مشخصی حساب کنید، مستقیم از فیلد استفاده کنید؛ مثلاً option.ti.buy1Price برای بهترین تقاضا یا option.ti.sell1Price برای بهترین عرضه. امضای قدیمی ScalePrice و scalePrice(option.ti) منسوخ است و موقع ذخیره به basePrice تبدیل می‌شود. ```js basePrice(option) ``` ```js basePrice(ua) ``` ### تنظیمات ویژوال: پارامترهای قابل تغییر بدون ویرایش کد اگر در فرمول ثابتی با یکی از این پیشوندها تعریف شود، کنار نام ستون در سرستون جدول یک آیکون تنظیمات ظاهر می‌شود و کاربر می‌تواند مقدار را از رابط گرافیکی عوض کند؛ مقدار جدید مستقیماً در همان خط کد نوشته می‌شود و کاربر لازم نیست کد را دست بزند. پیشوندها و دسته‌بندی‌شان: FILTER_ برای فیلترها، SHOW_ برای انتخاب اینکه چه چیزی در خروجی نمایش داده شود، SETTING_ برای تنظیمات محاسباتی، و SORT_BY و SORT_DIR برای مرتب‌سازی. کامنت جلوی همان خط، شکل کنترل را می‌سازد: متن ابتدای کامنت برچسب کنترل است، عبارت title= تولتیپ می‌سازد، هر [مقدار=برچسب] یک گزینه در فهرست انتخابی است، و کلمه multi آن را چندانتخابی می‌کند. نوع کنترل خودکار تشخیص داده می‌شود: مقدار true/false چک‌باکس، عدد ورودی عددی، وجود گزینه‌ها فهرست انتخابی، و در غیر این صورت ورودی متنی. اگر نام ثابت شامل MIN_ یا MAX_ یا PERCENT یا RETURN یا RISK یا FEE یا STRIKE باشد، حتی با مقدار اولیه خالی هم ورودی عددی ساخته می‌شود؛ به همین دلیل نام‌گذاری درست مهم است. دو ثابت FILTER_RESULT و FILTER_SHOW استثنا هستند و همیشه به شکل کلید روشن/خاموش نمایش داده می‌شوند. اگر آرایه‌ای به نام displayOrder تعریف شود، ترتیب نمایش بخش‌های SHOW_ را همان تعیین می‌کند و کاربر می‌تواند با کشیدن و رها کردن جابه‌جایشان کند. نوشتن //link= در یکی از دو خط اول فرمول، دکمه راهنما را به آن آدرس وصل می‌کند. قاعده مهم: هر مقداری که کاربر ممکن است بخواهد عوض کند (حد سود، حداقل حجم، تعداد روز) را به‌جای عدد ثابت داخل فرمول، به شکل یکی از این ثابت‌ها در بالای فرمول تعریف کن تا قابل تنظیم شود. ```js const FILTER_MIN_MONTHLY_PROFIT = ''; // حداقل سود ماهانه title=درصد سود به‌ازای هر ماه const FILTER_MAX_DAYS = 60; // حداکثر روز تا سررسید const SETTING_PRICE_MODE = 'last'; // مبنای قیمت [last=آخرین] [buy1=تقاضا] [sell1=عرضه] const SHOW_LEVERAGE = true; // نمایش اهرم let profit = monthlyProfit(calcRateChange(option.ti.buy1Price, ua.ti.lastPrice), option.daysUntilMaturity); if (FILTER_MIN_MONTHLY_PROFIT !== '' && profit < FILTER_MIN_MONTHLY_PROFIT) return ''; if (option.daysUntilMaturity > FILTER_MAX_DAYS) return ''; return SHOW_LEVERAGE ? roundNumber(leverage(), 1) : roundNumber(profit, 1); ``` ```js const displayOrder = [ 'SHOW_LEVERAGE', 'SHOW_BREAKEVEN' ]; ``` ### فیلترهای آماده نوار ابزار دیده‌بان بخشی از فیلترها اصلاً به فرمول‌نویسی نیاز ندارند و از پنل فیلترهای نوار ابزار دیده‌بان انتخاب می‌شوند. این فیلترهای آماده عبارت‌اند از: انتخاب یا حذف دارایی‌های پایه، انتخاب یا حذف زنجیره‌ها، نوع قرارداد (کال یا پوت)، وضعیت قرارداد (در سود، سر به سر، خارج از سود)، حداقل ارزش معاملات، کمینه و بیشینه روز تا سررسید، ماه سررسید، و نمایش فقط زنجیره‌های کاملاً باز. ترتیب اجرا: اول فیلترهای آماده اعمال می‌شوند و بعد فیلترهای فرمولی روی سطرهای باقی‌مانده. قاعده مهم: اگر خواسته کاربر با یکی از این فیلترهای آماده برآورده می‌شود، به‌جای نوشتن فرمول همان را پیشنهاد بده؛ نوشتن فرمول برای کاری که یک تیک ساده انجامش می‌دهد کار را پیچیده‌تر می‌کند. ## بخش 2 — فیلدهای آبجکت option (قرارداد اختیارِ سطر جاری) - option.namad (string): نماد اختیار — کد نماد اختیار معامله (مثال: ضبهمن1403) - option.name (string): نام اختیار — نام کامل نماد اختیار - option.code (string): کد اختیار — کد داخلی نماد اختیار - option.strike (number): قیمت اعمال — Strike price — قیمت اعمال اختیار - option.type (string): نوع: call | put — "call" برای خرید, "put" برای فروش - option.sarresid (string): سررسید — تاریخ سررسید اختیار به فرمت رشته - option.daysUntilMaturity (number): روز تا سررسید — تعداد روز کالندری تا سررسید - option.dayTradesUntilMaturity (number): روز معاملاتی تا سررسید — تعداد جلسه‌های معاملاتی باقی‌مانده؛ جلسهٔ خودِ روز سررسید هم شمرده می‌شود، پس در روز سررسید 1 است - option.size (number): اندازه قرارداد — تعداد سهم در هر قرارداد اختیار - option.state (string): وضعیت: ITM | ATM | OTM — وضعیت اختیار: در سود / در سر به سر / خارج از سود - option.openInterest (number): موقعیت باز — تعداد کل موقعیت‌های باز در بازار - option.openInterestPC (number): تغییر موقعیت باز (%) — درصد تغییر موقعیت باز نسبت به روز قبل - option.volumeAvg (number): میانگین حجم — میانگین حجم معاملات روزانه اختیار - option.iv (number): نوسان پذیری ضمنی — Implied Volatility — نوسان‌پذیری ضمنی (0 تا 1) - option.blackSholesHV (number): قیمت BS با HV — قیمت نظری بلک‌شولز از پیش‌محاسبه‌شده با ua.hv و نرخ بهره تنظیمات — معادل calcBS({ volatility: ua.hv }).bs - option.wivSe (number): WIV (وزنی سررسید) — نوسان‌پذیری ضمنی وزنی بر اساس سررسید - option.wiv (number): WIV — Weighted Implied Volatility - option.requiredMargin (number): مارجین مورد نیاز — مارجین مورد نیاز برای فروش این اختیار - option.minimumMargin (number): حداقل مارجین — حداقل مارجین قابل قبول - option.uaSymbolNamad (string): نماد دارایی پایه — نماد سهم پایه مرتبط با این اختیار - option.chainOpen (boolean): وضعیت باز بودن زنجیره — true فقط وقتی وضعیت زنجیره کاملا باز باشد (نه سقف‌خورده/بسته/در انتظار بازگشایی) - option.chainFill (number): درصد پرشدن سقف زنجیره — درصد پرشدن سقف OI زنجیره (می‌تواند بیشتر از 100 باشد) - option.fee (number): کارمزد خرید/فروش — نرخ کارمزد خرید و فروش قرارداد اختیار - option.buyExerciseFee (number): کارمزد اعمال خرید — نرخ کارمزد اعمال خرید - option.writeExerciseFee (number): کارمزد اعمال فروش — نرخ کارمزد اعمال فروش (صندوق: 0.0005، سهام: 0.0055) ## بخش 3 — فیلدهای آبجکت ua (دارایی پایهٔ همان سطر) - ua.namad (string): نماد دارایی پایه — کد نماد سهم پایه (مثال: وبهمن) - ua.name (string): نام دارایی پایه — نام کامل سهم پایه - ua.code (string): کد دارایی پایه — کد داخلی سهم پایه - ua.hv (number): نوسان تاریخی (HV) — Historical Volatility — نوسان‌پذیری تاریخی سهم پایه (0 تا 1) - ua.ivRank (number): IV Rank (رتبه IV) — رتبه نوسان‌پذیری ضمنی نسبت به یک سال گذشته — ua.ivRank، مقیاس 0 تا 100؛ null اگر تاریخچه کافی نباشد - ua.ivPercentile (number): IV Percentile (درصد IV) — درصد روزهایی که WIV کمتر از مقدار فعلی بوده — ua.ivPercentile، مقیاس 0 تا 100؛ null اگر تاریخچه کافی نباشد - ua.isEtf (boolean): آیا صندوق است — true اگر دارایی پایه صندوق (ETF) باشد، در غیر این صورت false - ua.volumeAvg (number): میانگین حجم پایه — میانگین حجم معاملات روزانه سهم پایه - ua.buyFee (number): کارمزد خرید پایه — نرخ کارمزد خرید دارایی پایه بر اساس بازار و نوع - ua.sellFee (number): کارمزد فروش پایه — نرخ کارمزد فروش دارایی پایه بر اساس بازار و نوع ## بخش 4 — فیلدهای معاملاتی ti این فیلدها هم روی option.ti و هم روی ua.ti در دسترس‌اند (مثال: option.ti.lastPrice و ua.ti.lastPrice). - ti.lastPrice (number): آخرین قیمت — آخرین قیمت معامله‌شده - ti.lastPC (number): تغییر آخرین قیمت (%) — درصد تغییر آخرین قیمت نسبت به دیروز - ti.endPrice (number): قیمت پایانی — قیمت پایانی (تعدیل‌شده) - ti.endPC (number): تغییر قیمت پایانی (%) — درصد تغییر قیمت پایانی - ti.volume (number): حجم — حجم معاملات امروز - ti.tValue (number): ارزش معاملات — ارزش ریالی کل معاملات امروز - ti.lastDayPrice (number): قیمت پایانی روز قبل — قیمت پایانی روز معاملاتی قبل — مبنای محاسبه درصد تغییر - ti.lastDayLastPrice (number): آخرین قیمت روز قبل — آخرین قیمت معامله‌شده در روز معاملاتی قبل - ti.lastDayVolume (number): حجم روز قبل — حجم معاملات روز معاملاتی قبل - ti.lastDayTValue (number): ارزش معاملات روز قبل — ارزش ریالی معاملات روز معاملاتی قبل - ti.transactions (number): تعداد معاملات — تعداد دفعات معامله امروز - ti.lastTransaction (string): زمان آخرین معامله — زمان آخرین معامله؛ وقتی معامله‌ای نبوده null است - ti.min (number): کمترین قیمت — کمترین قیمت معامله‌شده امروز - ti.max (number): بیشترین قیمت — بیشترین قیمت معامله‌شده امروز - ti.dailyPriceLow (number): حد پایین دامنه نوسان — پایین‌ترین حد مجاز قیمت روزانه - ti.dailyPriceHigh (number): حد بالای دامنه نوسان — بالاترین حد مجاز قیمت روزانه - ti.buy1Price (number): قیمت خرید 1 — بهترین قیمت خرید (ردیف اول تقاضا) - ti.buy2Price (number): قیمت خرید 2 — دومین قیمت خرید - ti.buy3Price (number): قیمت خرید 3 — سومین قیمت خرید - ti.buy4Price (number): قیمت خرید 4 — چهارمین قیمت خرید - ti.buy5Price (number): قیمت خرید 5 — پنجمین قیمت خرید - ti.buy1Volume (number): حجم خرید 1 — حجم بهترین سفارش خرید - ti.buy2Volume (number): حجم خرید 2 — حجم دومین سفارش خرید - ti.buy3Volume (number): حجم خرید 3 — حجم سومین سفارش خرید - ti.buy4Volume (number): حجم خرید 4 — حجم چهارمین سفارش خرید - ti.buy5Volume (number): حجم خرید 5 — حجم پنجمین سفارش خرید - ti.buy1Count (number): تعداد سفارش خرید 1 — تعداد سفارش‌های تجمیع‌شده در بهترین ردیف تقاضا - ti.buy2Count (number): تعداد سفارش خرید 2 — تعداد سفارش‌های دومین ردیف تقاضا - ti.buy3Count (number): تعداد سفارش خرید 3 — تعداد سفارش‌های سومین ردیف تقاضا - ti.buy4Count (number): تعداد سفارش خرید 4 — تعداد سفارش‌های چهارمین ردیف تقاضا - ti.buy5Count (number): تعداد سفارش خرید 5 — تعداد سفارش‌های پنجمین ردیف تقاضا - ti.sell1Price (number): قیمت فروش 1 — بهترین قیمت فروش (ردیف اول عرضه) - ti.sell2Price (number): قیمت فروش 2 — دومین قیمت فروش - ti.sell3Price (number): قیمت فروش 3 — سومین قیمت فروش - ti.sell4Price (number): قیمت فروش 4 — چهارمین قیمت فروش - ti.sell5Price (number): قیمت فروش 5 — پنجمین قیمت فروش - ti.sell1Volume (number): حجم فروش 1 — حجم بهترین سفارش فروش - ti.sell2Volume (number): حجم فروش 2 — حجم دومین سفارش فروش - ti.sell3Volume (number): حجم فروش 3 — حجم سومین سفارش فروش - ti.sell4Volume (number): حجم فروش 4 — حجم چهارمین سفارش فروش - ti.sell5Volume (number): حجم فروش 5 — حجم پنجمین سفارش فروش - ti.sell1Count (number): تعداد سفارش فروش 1 — تعداد سفارش‌های تجمیع‌شده در بهترین ردیف عرضه - ti.sell2Count (number): تعداد سفارش فروش 2 — تعداد سفارش‌های دومین ردیف عرضه - ti.sell3Count (number): تعداد سفارش فروش 3 — تعداد سفارش‌های سومین ردیف عرضه - ti.sell4Count (number): تعداد سفارش فروش 4 — تعداد سفارش‌های چهارمین ردیف عرضه - ti.sell5Count (number): تعداد سفارش فروش 5 — تعداد سفارش‌های پنجمین ردیف عرضه - ti.realBuyCount (number): تعداد خریدار حقیقی — تعداد معاملات خرید حقیقی امروز - ti.coBuyCount (number): تعداد خریدار حقوقی — تعداد معاملات خرید حقوقی امروز - ti.realSellCount (number): تعداد فروشنده حقیقی — تعداد معاملات فروش حقیقی امروز - ti.coSellCount (number): تعداد فروشنده حقوقی — تعداد معاملات فروش حقوقی امروز - ti.realBuyVolume (number): حجم خرید حقیقی — حجم خرید حقیقی‌ها امروز - ti.coBuyVolume (number): حجم خرید حقوقی — حجم خرید حقوقی‌ها امروز - ti.realSellVolume (number): حجم فروش حقیقی — حجم فروش حقیقی‌ها امروز - ti.coSellVolume (number): حجم فروش حقوقی — حجم فروش حقوقی‌ها امروز ## بخش 5 — توابع آماده - intrinsic() — ارزش ذاتی اختیار. ارزش ذاتی: برای call: ua.ti.lastPrice - option.strike، برای put: option.strike - ua.ti.lastPrice - timeValue() — ارزش زمانی اختیار. ارزش زمانی = قیمت اختیار - ارزش ذاتی - isITM() — آیا اختیار در سود است؟. برمی‌گرداند true اگر intrinsic() > 0 باشد - breakeven() — نقطه سر به سر. call: strike + قیمت اختیار | put: strike - قیمت اختیار (بر اساس مبنای قیمت) - leverage() — اهرم ساده. ua.ti.lastPrice / option.ti.lastPrice — بدون دلتا؛ ستون «اهرم» در دیده‌بان اهرم مؤثر (effectiveLeverage) را نشان می‌دهد - effectiveLeverage() — اهرم مؤثر (با دلتا). leverage() × |calcBS().delta| — همان مقداری که ستون «اهرم» در دیده‌بان نشان می‌دهد - askBidSpread() — اسپرد خرید-فروش (%). اختلاف بهترین خرید و فروش به درصد از آخرین قیمت - calcBS(namad?) | calcBS(overrides?) — محاسبه Black-Scholes. برمی‌گرداند { bs, delta, gamma, vega, theta, rho, iv } namad: محاسبه برای قرارداد مشخص overrides: { uaPrice, strike, days, volatility, premium, type, riskFree } - probOfProfit(bePrice, currentPrice, iv, daysToMaturity) — احتمال سود (%). احتمال سود بر اساس توزیع لاگ-نرمال - popWithIV(currentPrice, breakEven, iv, daysToMaturity) — احتمال سود با IV (%). احتمال سود بر پایه نوسان‌پذیری ضمنی. ترتیب آرگومان‌ها برعکس probOfProfit است: اول قیمت فعلی، بعد سربه‌سر. وقتی iv صفر یا نامعتبر باشد رشته خالی برمی‌گرداند. - uaDailyRange() — دامنه نوسان نماد پایه. کف و سقف مجاز امروز نماد پایه: { base, low, high, upPct, downPct }. مبنا قیمت پایانی دیروز است. برای قرارداد اختیار و بازار کالا دامنه منتشر نمی‌شود و خروجی null است. - uaPriceRange(days) — رنج قیمت پایه در چند روز. قیمتی که نماد پایه با صف خرید (سقف) یا صف فروش (کف) پشت سر هم در days روز معاملاتی می‌تواند به آن برسد: { base, days, low, high, upPct, downPct }. بدون آرگومان، روزهای معاملاتی مانده تا سررسید همان قرارداد. null وقتی دامنه معتبر نباشد. - ytmProfit(r, t) — بازده سالانه تا سررسید. bازده سالانه: r = نرخ بازده، t = روز تا سررسید - formatNumber(x, fixed?) — فرمت عدد (K/M/B). نمایش عدد با پسوند K/M/B برای اعداد بزرگ - showNo(val, fixed?, comma?) — نمایش عدد با اعشار ثابت. عدد را با تعداد اعشار مشخص (پیش‌فرض 1) نشان می‌دهد؛ با comma=true جداکننده هزارگان هم می‌گذارد. ورودی خالی رشته خالی برمی‌گرداند. - commaSeparator(val, fixed?) — جداکننده هزارگان. نمایش عدد با کاما (مثال: 1,234,567) - roundNumber(number, maxDecimals?) — گردکردن عدد. گرد کردن عدد به تعداد اعشار مشخص - style(value, color, bg?, title?, bold?, leftMargin?, rightMargin?) — متن رنگی با ابزارک (tooltip) و استایل. برمی‌گرداند یک span اچ‌تی‌ام‌ال برای نمایش در ستون: رنگ متن، پس‌زمینه، title به‌عنوان tooltip، bold، حاشیه چپ/راست (کلاس‌های me-/ms-) - colorCondition(value, min, minColor, max, maxColor, mode?, comma?) — رنگ شرطی بر اساس حد پایین/بالا. اگر value کمتر از min باشد minColor و اگر بزرگ‌تر یا مساوی max باشد maxColor اعمال می‌شود. mode="color" رنگ متن است و هر مقدار دیگر پس‌زمینه را رنگ می‌کند. - colorRange(val, ranges) — رنگ‌بندی بازه‌ای عدد با تگ span. مقدار عددی را بر اساس آرایه‌ای از بازه‌ها رنگ‌بندی و استایل‌دهی می‌کند. هر بازه شامل {min, max, color?, bg?, size?, bold?} است. - copyToClipboard(value) — خروجی قابل کپی با کلیک. مقدار متنی یا HTML را در یک خروجی قابل کلیک قرار می‌دهد تا متن نمایش‌داده‌شده در کلیپ‌بورد کپی شود. - rnwc(x, fixed?, fixedB?, isCurrency?, wordifyTitleSpan?, unitEnglish?, showZero?, fixK?, fixM?) — عدد با پسوند K/M/B و ابزارک فارسی. فرمت عدد با هزار/میلیون/میلیارد؛ امکان واحد فارسی (هزار/میلیون/میلیارد)، tooltip با ارقام فارسی، نمایش صفر اختیاری. - rnWordify(val, fromTable?) — عدد به حروف فارسی (برای tooltip یا نمایش). fromTable=0 یعنی اول با rnwc فرمت شود؛ خروجی فقط حروف فارسی. - wordifyfa(num) — تبدیل عدد به حروف فارسی. عدد یا رشته را به حروف فارسی برمی‌گرداند (بدون واحد ریال/تومان). - monthlyProfit(profit, days) — سود ماهانه (درصد یا مبلغ به‌ازای هر ماه). محاسبه سود به‌ازای یک ماه بر اساس روز: profit / (days/30). برای درصد سود تا سررسید بر اساس روزهای باقی‌مانده استفاده می‌شود. - basePrice(item) — قیمت بر اساس مبنای دیده‌بان. همان «مبنای قیمت» toolbar. option، ua یا هر آبجکت دارای ti را می‌پذیرد. برای تقاضا/عرضه ثابت: item.ti.buy1Price یا item.ti.sell1Price - calcRateChange(n1, n2, fix?) — درصد تغییر از n1 به n2. محاسبه درصد تغییر: ((n2 - n1) / n1) * 100. fix تعداد اعشار (پیش‌فرض 1). اگر نتیجه نزدیک عدد صحیح باشد بدون اعشار برمی‌گرداند. - showDetail(optionName, title?) — نمایش دکمه/لینک جزئیات اختیار. یک تگ span تولید می‌کند که با کلیک روی آن جزئیات اختیار باز می‌شود. - namadNo(namad) — استخراج شماره نماد. استخراج قسمت عددی نماد (مثل عدد 1403 از ضبهمن1403) - getOptionByNamad(namad) — دریافت اختیار با نماد. دریافت داده اختیار معامله بر اساس نماد - getUaByNamad(namad) — دریافت پایه با نماد. دریافت داده دارایی پایه بر اساس نماد - getOptionsByChain(uaNamad, type?, days?) — دریافت زنجیره اختیار. دریافت لیست اختیارها بر اساس دارایی پایه، نوع (call/put) و روز تا سررسید - optionSE(strikeNo?, type?) — اختیار هم‌سررسید. اختیار با همان سررسید، ردیف strikeNo بالا/پایین استرایک فعلی - optionSU(namad?, type?) — تمام اختیارهای یک پایه. لیست تمام اختیارهای یک دارایی پایه، مرتب‌شده بر اساس سررسید و استرایک - getOptionByParam(type?, strike?, days?, baseNamad?) — جستجوی اختیار با پارامتر. فیلتر اختیارها بر اساس نوع، استرایک، روز تا سررسید و نماد پایه - createPriceLine({ width, points, currentPrice, marginPercent? }) — ساخت نمودار خطی قیمت در ستون. خروجی HTML برای نمایش نقاط مهم قیمتی (مثل اعمال/سر به سر) روی یک نوار. - sortAndFormatResults(items, sortBy, sortDir?, displayInline?) — مرتب‌سازی و نمایش چند خروجی در یک ستون. items باید شامل فیلد sortBy (عدد) و output (HTML string) باشد. ### ساخت استراتژی و نمودار سود و زیان - pos.add(position, namad, count?, price?, cashBlock?) — افزودن پای استراتژی. position: 'buy' | 'sell'. namad: option.namad یا ua.namad. price: 'buy' | 'sell' | 'last' | 'end' یا عدد ثابت. - pos.build(name, tradingFee?, exerciseFee?) — ساخت دکمه نمودار سود/زیان. پس از pos.add، خروجی HTML دکمه نمودار سود و زیان را برمی‌گرداند. exerciseFee: 'not' | 'all' | 'itm-only' - pos.clear() — پاک کردن لیست پاهای موقت. لیست pos.add را بدون ساخت نمودار خالی می‌کند. ## درخواست من [اینجا بنویسید چه فرمولی می‌خواهید — هرچه دقیق‌تر، خروجی دقیق‌تر. بگویید خروجی ستون است یا فیلتر، شرط‌ها چیست، و اعداد را صریح بنویسید.]