روند کلی به این صورت است که قرارداد اول به عنوان پوزیشن خرید محسوب می شود و از OptonSE برای دسترسی به اطلاعات قراردادهای بعد یا قبل استفاده می شود که پوزیشن های فروش را نمایش می دهد
سادهترین فرمولنویسی برای ایجاد ستون اسپرد
// تعریف متغیرهای اولیه برای ذخیره نتایج و شمارنده
let result = '';
let index = 0;
// حلقه برای بررسی تمام اختیارات موجود
while ( OptionSE(++index) != undefined ){
// محاسبه سرمایه درگیر: (قیمت فروش اختیار اول - قیمت خرید اختیار دوم) × اندازه قرارداد
let debit = (Option.TI.Sell_1_Price - OptionSE(index).TI.Buy_1_Price) * Option.Size;
// محاسبه سود: ((قیمت اعمال اختیار دوم - قیمت اعمال اختیار اول) × اندازه قرارداد) - سرمایه درگیر
let profit = ((OptionSE(index).Strike - Option.Strike) * Option.Size) - debit;
// محاسبه درصد بازده سرمایه با یک رقم اعشار
let yCapital = ((profit / debit) * 100).toFixed(1);
// بررسی معتبر بودن قیمتها و اضافه کردن به نتیجه
if (Option.TI.Sell_1_Price > 0 && OptionSE(index).TI.Buy_1_Price > 0)
result += ShowDetail(OptionSE(index).Namad) + ': ' + yCapital + ' / ';
}
// برگرداندن نتیجه نهایی
result;ستون اسپرد با وجه تضمین و ایکن نمودار
// تعریف متغیر برای ذخیره نتیجه نهایی
let result = '';
// متغیر شمارنده برای پیمایش اختیارات
let index = 0;
// متغیر برای محاسبه تعداد ماههای باقیمانده تا سررسید
var month = 1;
// بررسی اگر روزهای باقیمانده تا سررسید بیشتر از 30 روز است
if (Option.DaysUntilMaturity > 30)
// تبدیل روزها به ماه
month = (Option.DaysUntilMaturity / 30);
// گرد کردن تعداد ماهها به یک رقم اعشار
month = month.toFixed(1);
// حلقه برای بررسی تمام اختیارات موجود
while ( OptionSE(++index) != undefined ){
// محاسبه هزینه ورود به موقعیت: (قیمت فروش اختیار اول - قیمت خرید اختیار دوم) × اندازه قرارداد
let debit = (Option.TI.Sell_1_Price - OptionSE(index).TI.Buy_1_Price) * Option.Size;
// محاسبه کل سرمایه مورد نیاز: وجه تضمین لازم + (قیمت فروش اختیار اول × اندازه قرارداد)
let capital = OptionSE(index).Required_Margin + (Option.TI.Sell_1_Price * Option.Size);
// محاسبه سود: ((قیمت اعمال اختیار دوم - قیمت اعمال اختیار اول) × اندازه قرارداد) - هزینه ورود
let profit = ((OptionSE(index).Strike - Option.Strike) * Option.Size) - debit;
// محاسبه درصد بازده ماهانه سرمایه با یک رقم اعشار
let yCapital = (((profit / capital) * 100)/month).toFixed(1);
// اگر بازده بیشتر از 5 درصد باشد و قیمتها معتبر باشند
if (yCapital >= 5 && Option.TI.Sell_1_Price > 0 && OptionSE(index).TI.Buy_1_Price > 0){
// افزودن موقعیت خرید برای اختیار اول
pos.Add('buy', Option.Namad, 1, 'sell');
// افزودن موقعیت فروش برای اختیار دوم
pos.Add('sell', OptionSE(index).Namad, 1, 'buy');
// ایجاد استراتژی اسپرد با نام مناسب
let startegy = pos.Build('اسپرد ' + NamadNo(Option.Namad) + ' - ' + NamadNo(OptionSE(index).Namad));
// افزودن اطلاعات اختیار به نتیجه نهایی
result += '[ ' + ShowDetail(OptionSE(index).Namad, '#') + ': ' + yCapital + startegy + '] ';
}
}
// برگرداندن نتیجه نهایی
result;
فیلتر ساده بر اساس بازده ماهانه اسپرد
// تعریف متغیر نتیجه برای ذخیره وضعیت نهایی معامله - پیشفرض false به معنای عدم سودآوری
let result = false;
// تعریف شمارنده برای حرکت بین آپشنهای مختلف در بازار - شروع از صفر
let index = 0;
// حلقه بررسی تمام آپشنهای موجود در بازار تا زمانی که آپشن بعدی وجود داشته باشد
while ( OptionSE(++index) != undefined ){
// محاسبه هزینه اولیه معامله (دبیت) - اختلاف قیمت فروش آپشن اول و قیمت خرید آپشن دوم ضربدر اندازه قرارداد
let debit = (Option.TI.Sell_1_Price - OptionSE(index).TI.Buy_1_Price) * Option.Size;
// محاسبه سود خالص معامله - تفاوت قیمتهای اعمال ضربدر اندازه قرارداد منهای هزینه اولیه (دبیت)
let profit = ((OptionSE(index).Strike - Option.Strike) * Option.Size) - debit;
// تعریف متغیر ماه برای محاسبه دوره زمانی - پیشفرض یک ماه
let month = 1;
// تبدیل روزهای باقیمانده به ماه اگر بیش از 30 روز باشد - برای محاسبه دقیقتر نرخ بازده
if (Option.DaysUntilMaturity > 30)
month = (Option.DaysUntilMaturity / 30);
// محاسبه بازده سرمایه سالانه به درصد - نسبت سود به هزینه اولیه ضربدر 100 با یک رقم اعشار
let yCapital = ((profit / debit) * 100).toFixed(1);
// محاسبه نرخ بازده ماهانه - تقسیم بازده سالانه بر تعداد ماههای دوره با یک رقم اعشار
let rate = (yCapital / month).toFixed(1);
// بررسی شرایط سودآوری: نرخ بازده بیشتر از 10٪ و معتبر بودن قیمتهای خرید و فروش (بزرگتر از صفر)
if (rate > 10 && Option.TI.Sell_1_Price > 0 && OptionSE(index).TI.Buy_1_Price > 0){
result = true;
break;
}
}
// برگرداندن نتیجه نهایی: true در صورت یافتن موقعیت سودآور، false در غیر این صورت
result;
ستون اسپرد با جزئیات کامل
اسپرد با وثیقه شدن قرارداد کال
// متغیرهای تنظیمات نمایش
let rewRiskShow = 1; // برای نمایش نسبت سود به ضرر (1: نمایش، 0: عدم نمایش)
let pointShow = 1; // برای نمایش نقاط فاصله بین نماد پایه و قیمتهای اعمال
// متغیرهای اصلی
let result = ''; // رشته خروجی نهایی
let index = 0; // شمارنده حلقه
// شرطهای فیلتر کردن از ورودی کاربر
let condition1 = _var1 != '' ? _var1 : 10;
let condition2 = _var2 != "" ? _var2 : "";
let size = Option.Size;
// آرایه برای ذخیره موقعیتها
let positions = new Array();
// حلقه اصلی برای بررسی اختیارات
while (OptionSE(++index) != undefined) {
if (OptionSE(index).TI.Buy_1_Volume == 0 || Option.TI.Sell_1_Volume == 0 ||
OptionSE(index).TI.Buy_1_Price < 10)
continue;
let position = new Object();
position.debit = (Option.TI.Sell_1_Price - OptionSE(index).TI.Buy_1_Price) * Option.Size;
let profit = ((OptionSE(index).Strike - Option.Strike) * Option.Size) - position.debit;
position.mCapital = MP(((profit / position.debit) * 100), Option.DaysUntilMaturity);
position.BE = Option.Strike + (Option.TI.Sell_1_Price - OptionSE(index).TI.Buy_1_Price);
position.disBE = CalcRateChange(UA.TI.LastPrice, position.BE);
position.strike = OptionSE(index).Strike;
position.disStrike = CalcRateChange(UA.TI.LastPrice, position.strike);
position.strike1 = CalcRateChange(UA.TI.LastPrice, Option.Strike);
position.strike2 = CalcRateChange(UA.TI.LastPrice, position.strike);
position.namad = OptionSE(index).Namad;
position.namadNo = NamadNo(OptionSE(index).Namad);
position.maxProfit = profit/size;
position.maxLoss = position.debit/size;
position.rewRisk = Math.abs(profit/position.debit).toFixed(2);
let current = ((UA.TI.LastPrice - position.BE) / position.debit) * Option.Size;
position.mCurrent = MP(current * 100, Option.DaysUntilMaturity);
if (_var2 == 1) {
position.point1 = 0;
position.point2 = Option.Strike;
}
else if (_var2 == 2) {
position.point1 = Option.Strike;
position.point2 = position.BE;
}
else if (_var2 == 3) {
position.point1 = position.BE;
position.point2 = OptionSE(index).Strike;
}
else if (_var2 == 4) {
position.point1 = OptionSE(index).Strike;
position.point2 = UA.TI.LastPrice * 100;
position.mCurrent = position.mCapital;
}
else condition2 = ""
if (position.mCapital >= condition1 && Option.Type == 'call' &&
(condition2 == "" || (UA.TI.LastPrice >= position.point1 && UA.TI.LastPrice < position.point2)))
positions.push(position);
}
positions = SortObject(positions, "mCapital");
positions = positions.reverse();
positions.forEach(function(position, posIndex) {
let bgP2, bgP3, bgP4;
if (UA.TI.LastPrice < Option.Strike) {
bgP2 = '#f87878';
position.mCurrent = -100;
}
else if (UA.TI.LastPrice <= position.BE)
bgP2 = "#FFC0CB";
else if (UA.TI.LastPrice > position.BE && UA.TI.LastPrice < position.strike)
bgP3 = "#B0E0E6";
else if (UA.TI.LastPrice >= position.strike)
bgP4 = "#ADFF2F";
pos.Add('buy', Option.Namad, 1, 'sell');
pos.Add('sell', position.namad, 1, 'buy', false);
result += ShowDetail(position.namad, position.namadNo);
result += "[" + Style(position.maxProfit + " (" + position.mCapital + "%)", 'black', '', 'بیشترین سود', true) + " ~" +
Style(position.mCurrent + '%', position.mCurrent >= 0 ? 'green' : 'red', '', 'موقعیت کنونی') + " ~ " +
Style(position.maxLoss, 'red', '', 'بیشترین ضرر') + "]";
if (rewRiskShow)
result += Style(+position.rewRisk, 'blue', '', 'سود/ضرر');
if (pointShow)
result += "<span title='نقاط - درصد فاصله نماد پایه با اعمال اول سربه سری و اعمال دوم'> P%[" +
Style(position.strike1, '', bgP2, 'اعمال اول-قیمت%') + '<i ></i>' +
Style(position.disBE, '', bgP3, 'سر به سری-قیمت%') + '<i ></i>' +
Style(position.strike2, '', bgP4, 'اعمال دوم-قیمت%') + "<span >]</span>";
result += pos.Build('اسپرد ' + Option.Namad);
if (posIndex == 0)
result = '<span style="display:none !important">{0}</span>'.format(position.mCapital) + result;
});
result;
- حداکثر سود
- حداکثر زیان
- درصد فاصله قیمت سهم از اعمال قرارداد کال فروخته شده(اعمال دوم)
- درصد فاصله قیمت سهم از اعمال قرارداد کال خریداری شده(اعمال اول)
- درصد فاصله قیمت سهم از سر به سری
- نسبت حداکثر سود به حداکثرزیان (Reward/Risk)
توابع استفاده شده در کد
| نام تابع | توضیحات |
|---|---|
OptionSE |
این تابع به شما اجازه میدهد به دادههای مختلف قراردادها دسترسی پیدا کنید. |
ShowDetail |
این تابع اطلاعات جزئیات مربوط به هر نماد را نمایش میدهد، شامل نام و شماره نماد، و سایر اطلاعات مرتبط. |
pos.Build،pos.Add |
این تابع برای رسم نمودارهای مرتبط با موقعیتهای معاملاتی استفاده میشود و به نمایش اطلاعات در یک نمودار کمک میکند. |
MP |
تابع MP برای محاسبه بازده ماهاننه استفاده میشود. |
CalcRateChange |
این تابع برای محاسبه درصد تغییرات قیمت بین دو مقدار استفاده میشود و به تجزیه و تحلیل تحلیلی کمک میکند. |
NamadNo |
این تابع شماره مربوط به هر نماد خاص را برمیگرداند و به شناسایی کرات نمادها کمک میکند. |
Style |
این تابع برای تعیین استایل و فرمتدهی به رشتههای خروجی استفاده میشود و به زیبایی دادهها در خروجی کمک میکند. |
برای مشاهده توضیحات کاملتر به راهنمای فرمول نویسی مراجعه کنید.
در کدهای اماده فرمول های مربوط به ایجاد ستون و فیلتر استراتژی اسپرد به صورت ویژوال در دسترس می باشد اموزش های موجود در صورت تمایل به تغییر و شخصی سازی فرمول ها کمک کننده می باشند