
یہ ایک اعلی درجے کی مقداری تجارت کی حکمت عملی ہے جس میں پانچ اپنی مرضی کے مطابق چلنے والی اوسط ، ایک کثیر پرت فلٹر اور تصدیق کے طریقہ کار کو مربوط کیا گیا ہے تاکہ مارکیٹ میں جاری رجحانات کی نشاندہی اور ان کا فائدہ اٹھایا جاسکے۔ اس حکمت عملی میں روایتی چلنے والی اوسط کے بجائے بنیادی ہموار ٹیکنالوجی کا استعمال کیا گیا ہے ، جس سے مارکیٹ کے مختلف حالات اور ٹائم فریموں کے مطابق زیادہ لچکدار ہموار اور خود کار طریقے سے موافقت پیدا ہوسکتی ہے۔
اس کے بنیادی افعال میں شامل ہیں: موجودہ مارکیٹ کے رجحانات کو ظاہر کرنے کے لئے پانچ چلتی اوسطوں پر مشتمل “مساوی لائن بینڈ” کی نمائش۔ آر ایس آئی فلٹرز ، رجحان کی طاقت کے فلٹرز اور رجحان کی تصدیق کی مدت کے ذریعہ شور اور جھوٹے سگنل کو کم کریں۔ صرف مخصوص شرائط پوری ہونے پر انٹری سگنل کو متحرک کریں۔ اور خطرے کو منظم کرنے اور منافع کو بچانے کے لئے متعدد باہر نکلنے کے اختیارات (جیسے فیصد ٹریکنگ اسٹاپ ، اے ٹی آر ٹریکنگ اسٹاپ ، اے ٹی آر منافع کے اہداف اور ہارڈ اسٹاپ) ۔
اس حکمت عملی کی بنیادی منطق مندرجہ ذیل اہم اجزاء کے گرد گھومتی ہے۔
نیوکلئس سست حرکت پذیری اوسطحکمت عملی: اسٹینڈرڈ مووینگ اوسط کے بجائے نیوکلیئر ہموار کرنے کی تکنیک کا استعمال کرتے ہوئے ، روایتی ایم اے کے مقابلے میں زیادہ لچکدار اور خود سے مطابقت پذیر ہموار اثر فراہم کرتا ہے۔ تین قسم کے نیوکلیئر کی حمایت کرتا ہے:
alphaاورbetaپیرامیٹرز کو آزادانہ طور پر مثبت اور منفی تاخیر سے کنٹرول کیا جاتا ہے ، جس کی وجہ سے ایم اے کی قیمتوں میں اضافے اور کمی کی رفتار مختلف ہوتی ہے۔bandwidthپیرامیٹرز گھڑی کی شکل کی چوڑائی کو کنٹرول کرتی ہیں۔bandwidthپیرامیٹرزیکساں لکیری بینڈ: پانچ ایم اے چارٹ پر “مساوی لائن بینڈ” بناتے ہیں ، ان کی ترتیب اور متعلقہ پوزیشن رجحان کی طاقت اور سمت کی بصری نشاندہی فراہم کرتی ہے۔
کراس ٹیسٹنگ: حکمت عملی کی نگرانی مساوی لائن بینڈ میں مسلسل ایم اے کے درمیان کراسنگ، صارف کو ممکنہ سگنل پیدا کرنے کے لئے ضروری کراسنگ کی تعداد کی وضاحت کر سکتے ہیں.
RSI فلٹر: مارکیٹ میں زیادہ توسیع کی صورت میں داخلے سے بچنے میں مدد کریں۔ ملٹی ہیڈ داخلے پر ، آر ایس آئی کو اوور سیل سطح سے کم ہونا چاہئے۔ خالی ہیڈ داخلے پر ، اوور بلڈ سطح سے اوپر ہونا چاہئے۔
رجحان کی طاقت فلٹر: رجحان کی طاقت کی پیمائش کرنے کے لئے ایک چلتی اوسط کے RSI کا استعمال کریں ، اور مضبوط ، قائم رجحان کی سمت میں تجارت کو یقینی بنائیں۔
رجحانات کی تصدیق: جعلی سگنل کو مزید کم کرنے کے لئے ، داخلے کی شرائط کی ضرورت ہوتی ہے ((MA کراس ، RSI اور رجحان کی طاقت) تجارت کو عملی طور پر متحرک کرنے سے پہلے K لائنوں کی ایک مخصوص تعداد کو مسلسل پورا کرنا ہوگا۔
منطق سے باہر نکلیںاس حکمت عملی میں مندرجہ ذیل ترتیب میں باہر نکلنے کو ترجیح دی گئی ہے: ہارڈ اسٹاپ ، ٹریکنگ اسٹاپ (فیصد یا اے ٹی آر پر مبنی) اور منافع (اے ٹی آر پر مبنی) ۔ اس سے نقصان کو کم سے کم کرنے اور منافع کی حفاظت کو یقینی بنایا جاسکتا ہے۔
اونچائی اپنی مرضی کے مطابق بنیادی ہموار: نیوکلیئر ہموار کا استعمال کرتے ہوئے (خاص طور پر بیٹا نیوکلیئر) ایم اے کے لئے ذمہ دارانہ کنٹرول کی سطح فراہم کرتا ہے ، جو معیاری ایم اے میں دستیاب نہیں ہے۔ اس سے رجحانات کی نگرانی کے لئے زیادہ موافقت پذیر اور باریک بینی سے متعلق نقطہ نظر کی اجازت ملتی ہے۔
رجحان کی طاقت اور تصدیق کے ساتھ مل کر: رجحان کی طاقت کا فلٹر ((MA کا استعمال کرتے ہوئے RSI) اور رجحان کی تصدیق کی مدت کا مجموعہ ایک طاقتور فلٹرنگ میکانزم فراہم کرتا ہے ، جو سادہ MA کراس یا RSI پڑھنے سے آگے ہے۔ اس سے کمزور رجحانات اور ہلچل کی صورتحال کو فلٹر کرنے میں مدد ملتی ہے۔
متعدد ترجیحات سے باہر نکلنے کے اختیارات: حکمت عملی کا باہر نکلنے کا منطق بہت پیچیدہ ہے ، جس میں فکسڈ اور متحرک اسٹاپ نقصان اور منافع کی سطح کا ایک مجموعہ فراہم کیا گیا ہے۔ سب سے زیادہ قدامت پسند باہر نکلنے کو یقینی بنانے کو ترجیح دیں (سخت اسٹاپ نقصان) سب سے پہلے ٹرگر ، اس کے بعد اسٹاپ نقصان کا سراغ لگانا ، اور آخر میں منافع کا ہدف۔
مکمل ان پٹ گروپ بندی: تمام ان پٹ کو کنٹرول پالیسی کے مخصوص پہلوؤں کے گروپوں میں درجہ بندی کیا گیا ہے ، اور صارف آسانی سے ان پٹ کو تیزی سے تلاش اور ایڈجسٹ کرسکتا ہے۔
ٹریڈنگ سمت کنٹرولیہ حکمت عملی بہت سی حکمت عملیوں کے برعکس ہے، جو کہ ایک ہی وقت میں ایک سے زیادہ اور خالی ٹرانزیکشنز کو فعال یا غیر فعال کرنے کی اجازت دیتی ہے۔
جامع رجحان نظامیہ اشارے تجارت کے لئے درکار تمام پہلوؤں کو یکجا کرتا ہے: انٹری سگنل، سٹاپ نقصان اور منافع کا حساب کتاب۔
پیرامیٹرز کو بہتر بنانے کے چیلنج: حکمت عملی میں بہت سارے پیرامیٹرز ہونے کی وجہ سے ، اس میں اوور فٹ ہونے کا خطرہ ہوسکتا ہے۔ پیرامیٹرز کو بہت زیادہ ٹھیک سے ایڈجسٹ کرنے سے حکمت عملی کو ریٹرننگ میں اچھی کارکردگی کا مظاہرہ کرنے کا سبب بن سکتا ہے ، لیکن حقیقی تجارت میں ناکام ہوجاتا ہے۔ اس بات کا یقین کرنے کے لئے کہ پیرامیٹرز کی ترتیب عالمگیر ہے اس کے لئے ٹھوس کراس ویلیڈنگ اور آؤٹ سیمپل ٹیسٹنگ کی سفارش کی جاتی ہے۔
رجحانات میں ردعمل میں تاخیر: اگرچہ حکمت عملی کا مقصد مستقل رجحانات کی نشاندہی کرنا ہے ، لیکن مارکیٹ میں تیزی سے الٹ جانے پر اس کا رد عمل کافی تیزی سے نہیں ہوسکتا ہے ، جس کی وجہ سے اس میں کچھ پیچھے ہٹنا پڑتا ہے۔ ایم اے کی لمبائی اور بنیادی پیرامیٹرز کو ایڈجسٹ کرکے رجحانات میں تبدیلی کی حساسیت اور شور کو فلٹر کرنے کی صلاحیت کو متوازن کیا جاسکتا ہے۔
MA کراس جھوٹا سگنل: یہاں تک کہ اگر فلٹرنگ کی ایک سے زیادہ پرتیں موجود ہیں تو بھی ، اتار چڑھاؤ کی منڈیوں میں جھوٹے سگنل پیدا ہوسکتے ہیں۔ یہ حکمت عملی تجویز کی جاتی ہے کہ رجحان سازی کی منڈیوں میں اس حکمت عملی کا استعمال کیا جائے ، یا جھوٹے سگنل کو کم کرنے کے لئے رجحان کی تصدیق کی مدت میں اضافہ کیا جائے۔
روک تھام کے ٹرگر بہت جلد: بڑے اتار چڑھاؤ والے بازاروں میں ، اسٹاپ نقصانات کو بہت جلد متحرک کیا جاسکتا ہے ، جس کے نتیجے میں قیمتوں میں بعد کی اصلاح اور رجحان کی بحالی کی کمی واقع ہوتی ہے۔ اے ٹی آر پر مبنی اسٹاپ نقصانات پر غور کیا جاسکتا ہے اور مارکیٹ میں اتار چڑھاؤ کو ایڈجسٹ کرنے کے لئے مناسب ایڈجسٹمنٹ کی جاسکتی ہے۔
پیچیدگی کا خطرہ: حکمت عملی کی پیچیدگی سے خرابیوں کا سراغ لگانا اور اصل وقت کی نگرانی مشکل ہوسکتی ہے۔ یہ تجویز کی جاتی ہے کہ سادہ ترتیب سے شروع کریں اور ہر جزو کے کردار کو پوری طرح سے سمجھنے کو یقینی بنانے کے لئے آہستہ آہستہ پیچیدہ افعال شامل کریں۔
ٹائم فریم کی موافقت: موجودہ حکمت عملی کو مزید بہتر بنایا جاسکتا ہے تاکہ وہ مختلف ٹائم فریموں کے مطابق پیرامیٹرز کو خود بخود ایڈجسٹ کرسکے۔ مثال کے طور پر ، ٹائم فریم پر مبنی خودکار پیرامیٹر ایڈجسٹمنٹ کی خصوصیت شامل کی جاسکتی ہے ، تاکہ حکمت عملی دن کی لکیر ، گھنٹہ کی لکیر یا منٹ کی لکیر کے چارٹ پر موثر طریقے سے کام کرسکے۔
مارکیٹ کے ماحول کا پتہ لگانا: مارکیٹ کے ماحول ((رجحان ، وقفہ یا اعلی اتار چڑھاؤ) کا خود کار طریقے سے پتہ لگانے کا طریقہ کار شامل کریں ، اور پتہ لگانے کے نتائج کے مطابق تجارتی پیرامیٹرز کو ایڈجسٹ کریں۔ مثال کے طور پر ، وقفہ مارکیٹ میں فلٹرنگ کی شدت میں اضافہ یا منافع بخش اہداف کو ایڈجسٹ کریں ، رجحان مارکیٹ میں فلٹرنگ کے حالات کو نرم کریں۔
متحرک آر ایس آئی کی حدآر ایس آئی کی اوورلوڈ اوورلوڈ ٹریول ویلیو کو متحرک کے بجائے جامد ڈیزائن کیا گیا ہے ، جو مارکیٹ میں حالیہ اتار چڑھاؤ کے مطابق خود بخود ایڈجسٹ ہوتا ہے۔ اس سے حکمت عملی کو مختلف مارکیٹ کے حالات میں بہتر طور پر اپنانے میں مدد مل سکتی ہے۔
انٹیگریٹڈ کوانٹومیٹڈ فلوٹیشن انڈیکس: حکمت عملی کو اتار چڑھاؤ کے اشارے (جیسے بولنگر بینڈوڈتھ) کے ساتھ مربوط کریں تاکہ اعلی اتار چڑھاؤ والے ماحول میں اسٹاپ نقصان اور منافع کے اہداف کو ایڈجسٹ کیا جاسکے ، تاکہ موثر رجحانات کو ختم کرنے کا خطرہ کم کیا جاسکے۔
ملٹی ٹائم فریم تصدیق: اعلی ٹائم فریم کے رجحان کی تصدیق کو شامل کریں ، اس بات کو یقینی بنائیں کہ تجارت کی سمت بڑے رجحانات کے ساتھ مطابقت رکھتی ہے۔ مثال کے طور پر ، صرف اس وقت تجارت کریں جب دن کی لکیر کی سمت گھڑی کی لکیر کی سمت سے مطابقت رکھتی ہو۔
کارکردگی کی نگرانی اور موافقت: حکمت عملی کی کارکردگی کے لئے ایک حقیقی وقت کی نگرانی کا نظام، کامیابی کی شرح، جیت کی شرح اور زیادہ سے زیادہ واپسی جیسے اشارے کو ٹریک کرنے کے لئے، خود کار طریقے سے پیرامیٹرز کو ایڈجسٹ کرنے یا ٹریڈنگ کو روکنے کے لئے جب کارکردگی کے اشارے پہلے سے طے شدہ حد سے نیچے گر جاتے ہیں.
مشین سیکھنے میں اضافہ: مشین لرننگ الگورتھم کو پیرامیٹرز کی اصلاح کے عمل میں ضم کرنے کی تلاش ، حکمت عملی کو تاریخی اعداد و شمار سے بہترین پیرامیٹرز کا مجموعہ سیکھنے اور نئے اعداد و شمار کے جمع ہونے کے ساتھ بہتر بنانے کے قابل بناتا ہے۔
کثیر میڈینز پر مبنی ایڈجسٹ ٹرینڈ ٹریکنگ سسٹم ایک طاقتور اور لچکدار ٹرینڈ ٹریکنگ ٹول ہے ، جو حرکت پذیر اوسط بینڈ کی بصری وضاحت کو اعلی درجے کی فلٹرنگ اور رسک مینجمنٹ کی صلاحیتوں کے ساتھ جوہری ہموار ، آر ایس آئی ، رجحان کی طاقت اور ایک سے زیادہ باہر نکلنے کے اختیارات کے ساتھ جوڑتا ہے۔ یہ خاص طور پر ان تاجروں کے لئے ڈیزائن کیا گیا ہے جو مستقل مارکیٹ کے رجحانات کی نشاندہی اور تجارت کے لئے اپنی مرضی کے مطابق اور طاقتور ٹولز چاہتے ہیں۔
اس حکمت عملی کا سب سے بڑا فائدہ یہ ہے کہ اس کی انتہائی تخصیص اور خود کو اپنانے کی صلاحیت ہے ، جس سے یہ مارکیٹ کے مختلف حالات کے مطابق ڈھال لیتا ہے۔ اس کی بنیادی ہموار ٹیکنالوجی کے ذریعہ ، یہ روایتی منتقل اوسط سے کہیں زیادہ ٹھیک ٹھیک کنٹرول فراہم کرتی ہے ، جبکہ متعدد فلٹرنگ اور تصدیق کے میکانزم جعلی سگنل کو کم کرنے میں معاون ہیں۔ اس کے علاوہ ، ایک جامع رسک مینجمنٹ سسٹم متعدد خارجی حکمت عملی فراہم کرتا ہے ، جس سے نقصانات کو کم سے کم کرنے اور منافع کو محفوظ رکھنے کو یقینی بنایا جاتا ہے۔
تاہم ، صارفین کو پیرامیٹرز کو بہتر بنانے کی چیلنجوں پر دھیان دینا چاہئے ، ضرورت سے زیادہ فٹ ہونے سے گریز کرنا چاہئے ، اور حکمت عملی کو مخصوص مارکیٹ کے حالات کے مطابق ڈھالنا چاہئے۔ مناسب بیک اپ اور فارورڈ ٹیسٹنگ کی سفارش کی جاتی ہے تاکہ یہ یقینی بنایا جاسکے کہ حکمت عملی مارکیٹ کے مختلف حالات میں مستحکم کام کرتی ہے۔ باقاعدگی سے جائزہ لینے اور اصلاح کے ساتھ ، اس حکمت عملی میں کامیاب رجحان ساز تاجروں کے ٹول کٹ میں ایک قیمتی اثاثہ بننے کی صلاحیت ہے۔
/*backtest
start: 2024-03-28 00:00:00
end: 2025-03-27 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy("B4100 - NW Trend Ribbon Strategy", overlay=true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.02)
// === Optimized Functions ===
f_calculate_beta_kernel(length, alpha, beta) =>
kernel = array.new_float(length, 0)
sum = 0.0
for i = 0 to length - 1
x = i / (length - 1)
w = math.pow(x, alpha - 1) * math.pow(1 - x, beta - 1)
array.set(kernel, i, w)
sum += w
for i = 0 to length - 1
array.set(kernel, i, array.get(kernel, i) / sum)
kernel
f_calculate_gaussian_kernel(length, bandwidth) =>
kernel = array.new_float(length, 0)
sum = 0.0
for i = 0 to length - 1
x = i / (length - 1)
w = math.exp(-0.5 * math.pow((x - 0.5) / bandwidth, 2))
array.set(kernel, i, w)
sum += w
for i = 0 to length - 1
array.set(kernel, i, array.get(kernel, i) / sum)
kernel
f_calculate_epanechnikov_kernel(length, bandwidth) =>
kernel = array.new_float(length, 0)
sum = 0.0
for i = 0 to length - 1
x = i / (length - 1)
w = math.max(0.0, 1 - math.pow((x - 0.5) / bandwidth, 2))
array.set(kernel, i, w)
sum += w
for i = 0 to length - 1
array.set(kernel, i, array.get(kernel, i) / sum)
kernel
f_apply_kernel_ma(src, kernel, length) =>
sum = 0.0
for i = 0 to length - 1
sum += src[i] * array.get(kernel, i)
sum
f_trend_strength(ma, length) =>
ts = ta.rsi(ma, length) / 100
ts
// === Inputs ===
src = input.source(close, title="Price Source", tooltip="Select the price data used for calculations. 'Close' is the most common, but you can also use 'Open', 'High', 'Low', 'HL2' (typical price), etc.")
// MA Parameters
maGroup = "Moving Average Settings"
maCrossoverGroup = "Moving Average Crossover Settings"
rsiFilterGroup = "RSI Filter Settings"
trendStrengthGroup = "Trend Strength Filter Settings"
trendConfirmGroup = "Trend Confirmation Settings"
trailingStopGroup = "Trailing Stop Settings"
atrTrailingStopGroup = "ATR Trailing Stop Settings"
atrTakeProfitGroup = "ATR Take Profit Settings"
hardStopGroup = "Hard Stop Loss Settings"
tradeDirectionGroup = "Trade Direction Control"
length1 = input.int(20, title="MA1 Length", minval=1, tooltip="Number of bars used to calculate the first Moving Average.", group=maGroup)
kernelType1 = input.string(title="MA1 Kernel Type", defval="Beta", options=["Beta", "Gaussian", "Epanechnikov"], tooltip="Select the type of smoothing kernel for MA1. 'Beta' allows for lag adjustment. 'Gaussian' and 'Epanechnikov' use a bandwidth.", group=maGroup)
alpha1 = input.float(3.0, title="MA1 Beta Kernel +Lag", minval=1, maxval=10, tooltip="For Beta kernel only: Higher values increase *positive* lag (MA reacts *slower* to price increases).", group=maGroup)
beta1 = input.float(3.0, title="MA1 Beta Kernel -Lag", minval=1, maxval=10, tooltip="For Beta kernel only: Higher values increase *negative* lag (MA reacts *slower* to price decreases).", group=maGroup)
bandwidth1 = input.float(0.3, title="MA1 Bandwidth", minval=0.1, maxval=10.0, tooltip="For Gaussian/Epanechnikov kernels: Smaller values create a *tighter* fit to the price (more sensitive). Larger values create a *smoother*, less sensitive MA.", group=maGroup)
length2 = input.int(100, title="MA2 Length", minval=1, tooltip="Number of bars for the second Moving Average.", group=maGroup)
kernelType2 = input.string(title="MA2 Kernel Type", defval="Gaussian", options=["Beta", "Gaussian", "Epanechnikov"], tooltip="Kernel type for MA2 (see MA1 Kernel Type for details).", group=maGroup)
alpha2 = input.float(3.0, title="MA2 Beta Kernel +Lag", minval=1, maxval=10, tooltip="Beta kernel positive lag for MA2 (see MA1 Beta Kernel +Lag for details).", group=maGroup)
beta2 = input.float(3.0, title="MA2 Beta Kernel -Lag", minval=1, maxval=10, tooltip="Beta kernel negative lag for MA2 (see MA1 Beta Kernel -Lag for details).", group=maGroup)
bandwidth2 = input.float(0.3, title="MA2 Bandwidth", minval=0.1, maxval=10.0, tooltip="Bandwidth for MA2 (see MA1 Bandwidth for details).", group=maGroup)
length3 = input.int(150, title="MA3 Length", minval=1, tooltip="Number of bars for the third Moving Average.", group=maGroup)
kernelType3 = input.string(title="MA3 Kernel Type", defval="Epanechnikov", options=["Beta", "Gaussian", "Epanechnikov"], tooltip="Kernel type for MA3.", group=maGroup)
alpha3 = input.float(3.0, title="MA3 Beta Kernel +Lag", minval=1, maxval=10, tooltip="Beta kernel positive lag for MA3.", group=maGroup)
beta3 = input.float(3.0, title="MA3 Beta Kernel -Lag", minval=1, maxval=10, tooltip="Beta kernel negative lag for MA3.", group=maGroup)
bandwidth3 = input.float(0.3, title="MA3 Bandwidth", minval=0.1, maxval=10.0, tooltip="Bandwidth for MA3.", group=maGroup)
length4 = input.int(200, title="MA4 Length", minval=1, tooltip="Number of bars for the fourth Moving Average.", group=maGroup)
kernelType4 = input.string(title="MA4 Kernel Type", defval="Beta", options=["Beta", "Gaussian", "Epanechnikov"], tooltip="Kernel type for MA4.", group=maGroup)
alpha4 = input.float(3.0, title="MA4 Beta Kernel +Lag", minval=1, maxval=10, tooltip="Beta kernel positive lag for MA4.", group=maGroup)
beta4 = input.float(3.0, title="MA4 Beta Kernel -Lag", minval=1, maxval=10, tooltip="Beta kernel negative lag for MA4.", group=maGroup)
bandwidth4 = input.float(0.3, title="MA4 Bandwidth", minval=0.1, maxval=10.0, tooltip="Bandwidth for MA4.", group=maGroup)
length5 = input.int(250, title="MA5 Length", minval=1, tooltip="Number of bars for the fifth Moving Average.", group=maGroup)
kernelType5 = input.string(title="MA5 Kernel Type", defval="Gaussian", options=["Beta", "Gaussian", "Epanechnikov"], tooltip="Kernel type for MA5.", group=maGroup)
alpha5 = input.float(3.0, title="MA5 Beta Kernel +Lag", minval=1, maxval=10, tooltip="Beta kernel positive lag for MA5.", group=maGroup)
beta5 = input.float(3.0, title="MA5 Beta Kernel -Lag", minval=1, maxval=10, tooltip="Beta kernel negative lag for MA5.", group=maGroup)
bandwidth5 = input.float(0.3, title="MA5 Bandwidth", minval=0.1, maxval=10.0, tooltip="Bandwidth for MA5.", group=maGroup)
// Entry Logic
maCrossoversRequired = input.int(3, title="MA Crossovers Required", minval=1, maxval=5, tooltip="How many moving averages must cross each other to generate a potential trade signal. A higher number means a stronger (but potentially later) signal.", group=maCrossoverGroup)
useRsiFilter = input.bool(true, title="Use RSI Filter", tooltip="If enabled, the RSI must also be in overbought/oversold territory for a signal to be valid.", group=rsiFilterGroup)
rsiLength = input.int(7, title="RSI Length", minval=2, tooltip="Number of bars used to calculate the RSI.", group=rsiFilterGroup)
rsiOverbought = input.int(60, title="RSI Overbought", minval=50, maxval=100, tooltip="RSI level considered overbought (for short entries).", group=rsiFilterGroup)
rsiOversold = input.int(40, title="RSI Oversold", minval=0, maxval=50, tooltip="RSI level considered oversold (for long entries).", group=rsiFilterGroup)
// Trend Strength Filter
useTrendStrengthFilter = input.bool(true, title="Use Trend Strength Filter", tooltip="If enabled, the trend strength (measured by the RSI of a selected MA) must be above/below a threshold.", group=trendStrengthGroup)
trendStrengthLength = input.int(7, title="Trend Strength Length", minval=1, tooltip="Number of bars for the trend strength calculation (RSI of the selected MA).", group=trendStrengthGroup)
trendStrengthMa = input.int(1, title="Trend Strength MA", minval=1, maxval=5, tooltip="Which moving average (1-5) to use for calculating trend strength. 1 = MA1, 2 = MA2, etc.", group=trendStrengthGroup)
minTrendStrength = input.float(0.5, title="Min Trend Strength (Longs)", minval=0.0, maxval=1.0, step=0.01, tooltip="Minimum trend strength (0.0 - 1.0) required for long entries. 0.5 means the selected MA's RSI must be above 50.", group=trendStrengthGroup)
maxTrendStrength = input.float(0.5, title="Max Trend Strength (Shorts)", minval=0.0, maxval=1.0, step=0.01, tooltip="Maximum trend strength (0.0 - 1.0) required for short entries. 0.5 means the selected MA's RSI must be below 50.", group=trendStrengthGroup)
// Trend Confirmation
trendConfirmationPeriod = input.int(4, title="Trend Confirmation Period", minval=1, tooltip="Number of consecutive bars the entry conditions must be met before a trade is taken. This helps filter out false signals.", group=trendConfirmGroup)
// Exit Logic
useTrailingStop = input.bool(true, title="Use Percentage Trailing Stop", tooltip="Enable a percentage-based trailing stop loss.", group=trailingStopGroup)
trailingStopActivationPercent = input.float(2.0, title="Activation (%)", minval=0.1, step=0.1, tooltip="Percentage above/below the entry price at which the trailing stop activates.", group=trailingStopGroup) / 100
trailingStopOffsetPercent = input.float(1.0, title="Offset (%)", minval=0.1, step=0.1, tooltip="Percentage offset from the highest/lowest price reached since entry. This determines how tightly the stop trails the price.", group=trailingStopGroup) / 100
useAtrTrailingStop = input.bool(true, title="Use ATR Trailing Stop", tooltip="Enable a trailing stop based on the Average True Range (ATR).", group=atrTrailingStopGroup)
atrTrailingStopLength = input.int(1, title="ATR Length", minval=1, tooltip="Number of bars used to calculate the ATR.", group=atrTrailingStopGroup)
atrTrailingStopMult = input.float(200.0, title="ATR Multiplier", minval=0.1, tooltip="Multiplier for the ATR value. A larger multiplier creates a wider stop.", group=atrTrailingStopGroup)
useAtrTakeProfit = input.bool(false, title="Use ATR Take Profit", tooltip="Enable a take profit level based on the Average True Range (ATR).", group=atrTakeProfitGroup)
atrTakeProfitLength = input.int(14, title="ATR Length", minval=1, tooltip="Number of bars used to calculate the ATR for take profit.", group=atrTakeProfitGroup)
atrTakeProfitMultiplier = input.float(3.0, title="ATR Multiplier", minval=0.1, tooltip="Multiplier for the ATR value. A larger multiplier sets a further take profit target.", group=atrTakeProfitGroup)
useHardStopLoss = input.bool(false, title="Use Hard Stop Loss", tooltip="Enable a fixed stop loss.", group=hardStopGroup)
hardStopLossPercent = input.float(0.0, title="Hard Stop Loss (%)", minval=0.0, step=0.1, tooltip="Percentage below (long) or above (short) the entry price for the hard stop loss.", group=hardStopGroup) / 100
useAtrHardStopLoss = input.bool(false, title="Use ATR Hard Stop Loss", tooltip="Use ATR to calculate hard stop loss", group=hardStopGroup)
atrHardStopLossLength = input.int(14, title="ATR Hard Stop Loss Length", minval=1, tooltip="Length of the ATR for the hard stop loss", group=hardStopGroup)
atrHardStopLossMult = input.float(1.5, title="ATR Hard Stop Loss Multiplier", minval=0.1, tooltip="Multiplier of ATR for the hard stop loss", group=hardStopGroup)
// *** Trade Direction Control ***
enableLongs = input.bool(true, title="Enable Long Trades", group=tradeDirectionGroup)
enableShorts = input.bool(true, title="Enable Short Trades", group=tradeDirectionGroup)
// === Pre-calculate kernels (do this only once) ===
var kernel1 = array.new_float(length1, 0.0)
var kernel2 = array.new_float(length2, 0.0)
var kernel3 = array.new_float(length3, 0.0)
var kernel4 = array.new_float(length4, 0.0)
var kernel5 = array.new_float(length5, 0.0)
if barstate.isfirst
if kernelType1 == "Beta"
kernel1 := f_calculate_beta_kernel(length1, alpha1, beta1)
else if kernelType1 == "Gaussian"
kernel1 := f_calculate_gaussian_kernel(length1, bandwidth1)
else // Epanechnikov
kernel1 := f_calculate_epanechnikov_kernel(length1, bandwidth1)
if kernelType2 == "Beta"
kernel2 := f_calculate_beta_kernel(length2, alpha2, beta2)
else if kernelType2 == "Gaussian"
kernel2 := f_calculate_gaussian_kernel(length2, bandwidth2)
else // Epanechnikov
kernel2 := f_calculate_epanechnikov_kernel(length2, bandwidth2)
if kernelType3 == "Beta"
kernel3 := f_calculate_beta_kernel(length3, alpha3, beta3)
else if kernelType3 == "Gaussian"
kernel3 := f_calculate_gaussian_kernel(length3, bandwidth3)
else // Epanechnikov
kernel3 := f_calculate_epanechnikov_kernel(length3, bandwidth3)
if kernelType4 == "Beta"
kernel4 := f_calculate_beta_kernel(length4, alpha4, beta4)
else if kernelType4 == "Gaussian"
kernel4 := f_calculate_gaussian_kernel(length4, bandwidth4)
else // Epanechnikov
kernel4 := f_calculate_epanechnikov_kernel(length4, bandwidth4)
if kernelType5 == "Beta"
kernel5 := f_calculate_beta_kernel(length5, alpha5, beta5)
else if kernelType5 == "Gaussian"
kernel5 := f_calculate_gaussian_kernel(length5, bandwidth5)
else // Epanechnikov
kernel5 := f_calculate_epanechnikov_kernel(length5, bandwidth5)
// === Apply pre-calculated kernels to data ===
nw_ma1 = f_apply_kernel_ma(src, kernel1, length1)
nw_ma2 = f_apply_kernel_ma(src, kernel2, length2)
nw_ma3 = f_apply_kernel_ma(src, kernel3, length3)
nw_ma4 = f_apply_kernel_ma(src, kernel4, length4)
nw_ma5 = f_apply_kernel_ma(src, kernel5, length5)
// MA Array for easier iteration
ma_array = array.new_float(5)
array.set(ma_array, 0, nw_ma1)
array.set(ma_array, 1, nw_ma2)
array.set(ma_array, 2, nw_ma3)
array.set(ma_array, 3, nw_ma4)
array.set(ma_array, 4, nw_ma5)
// Calculate ATR values *unconditionally*
atrTrailingValue = ta.atr(atrTrailingStopLength)
atrTakeProfitValue = ta.atr(atrTakeProfitLength)
atrHardStopLossValue = ta.atr(atrHardStopLossLength)
// Calculate Trend Strength *unconditionally* (and only once)
trendStrengthValue = useTrendStrengthFilter ? f_trend_strength(array.get(ma_array, trendStrengthMa - 1), trendStrengthLength) : 0.0
// === Entry Logic ===
// MA Crossovers
longMaCrossovers = 0
shortMaCrossovers = 0
for i = 0 to 3
if array.get(ma_array, i) > array.get(ma_array, i + 1)
longMaCrossovers := longMaCrossovers + 1
if array.get(ma_array, i) < array.get(ma_array, i + 1)
shortMaCrossovers := shortMaCrossovers + 1
longCrossoverCondition = longMaCrossovers >= maCrossoversRequired
shortCrossoverCondition = shortMaCrossovers >= maCrossoversRequired
// RSI Filter
rsiValue = ta.rsi(src, rsiLength)
longRsiCondition = not useRsiFilter or (rsiValue < rsiOversold)
shortRsiCondition = not useRsiFilter or (rsiValue > rsiOverbought)
// Trend Strength Filter - Simplified Logic
longTrendStrengthCondition = not useTrendStrengthFilter or trendStrengthValue >= minTrendStrength
shortTrendStrengthCondition = not useTrendStrengthFilter or trendStrengthValue <= maxTrendStrength
// --- Trend Confirmation Logic ---
var int long_confirm_count = 0
var int short_confirm_count = 0
var bool confirmedLong = false
var bool confirmedShort = false
// Update confirmation counters
if longCrossoverCondition and longRsiCondition and longTrendStrengthCondition
long_confirm_count := long_confirm_count + 1
short_confirm_count := 0 // Reset opposite counter
else
long_confirm_count := 0
if shortCrossoverCondition and shortRsiCondition and shortTrendStrengthCondition
short_confirm_count := short_confirm_count + 1
long_confirm_count := 0 // Reset opposite counter
else
short_confirm_count := 0
// Check for confirmed trend
confirmedLong := long_confirm_count >= trendConfirmationPeriod
confirmedShort := short_confirm_count >= trendConfirmationPeriod
// Combined Entry Conditions (using confirmed trend)
longCondition = confirmedLong and enableLongs // Added trade direction check
shortCondition = confirmedShort and enableShorts // Added trade direction check
// === Exit Logic ===
var float longTrail = na
var float shortTrail = na
var float longTakeProfitPrice = na
var float shortTakeProfitPrice = na
var float longHardStopLossPrice = na
var float shortHardStopLossPrice = na
// Hard Stop Loss and Take Profit calculation on entry
if longCondition or shortCondition
// Calculate Hard Stop Loss
if useHardStopLoss
if useAtrHardStopLoss
longHardStopLossPrice := close - (atrHardStopLossValue * atrHardStopLossMult)
shortHardStopLossPrice := close + (atrHardStopLossValue * atrHardStopLossMult)
else
longHardStopLossPrice := close * (1 - hardStopLossPercent)
shortHardStopLossPrice := close * (1 + hardStopLossPercent)
else
longHardStopLossPrice := na
shortHardStopLossPrice := na
// Calculate Take Profit
if useAtrTakeProfit
longTakeProfitPrice := close + (atrTakeProfitValue * atrTakeProfitMultiplier)
shortTakeProfitPrice := close - (atrTakeProfitValue * atrTakeProfitMultiplier)
else
longTakeProfitPrice := na
shortTakeProfitPrice := na
// Trailing Stop Logic - updated for each bar
if strategy.position_size > 0
// Calculate trailing stop
float tempTrail = na
if useTrailingStop
if close > strategy.position_avg_price * (1 + trailingStopActivationPercent)
tempTrail := close * (1 - trailingStopOffsetPercent)
if na(longTrail) or tempTrail > longTrail
longTrail := tempTrail
if useAtrTrailingStop
float atrTrail = close - (atrTrailingValue * atrTrailingStopMult)
if na(longTrail) or atrTrail > longTrail
longTrail := atrTrail
if strategy.position_size < 0
// Calculate trailing stop
float tempTrail = na
if useTrailingStop
if close < strategy.position_avg_price * (1 - trailingStopActivationPercent)
tempTrail := close * (1 + trailingStopOffsetPercent)
if na(shortTrail) or tempTrail < shortTrail
shortTrail := tempTrail
if useAtrTrailingStop
float atrTrail = close + (atrTrailingValue * atrTrailingStopMult)
if na(shortTrail) or atrTrail < shortTrail
shortTrail := atrTrail
// === Strategy Execution ===
if longCondition
strategy.entry("Long", strategy.long)
longTrail := na // Reset on new entry
shortTrail := na // Reset on new entry
if shortCondition
strategy.entry("Short", strategy.short)
shortTrail := na // Reset on new entry
longTrail := na // Reset on new entry
// Unified exit logic with proper ordering
if strategy.position_size > 0
// Define effective stop level (combining hard stop and trailing stop)
float effectiveStopLevel = na
if not na(longHardStopLossPrice) and useHardStopLoss
effectiveStopLevel := longHardStopLossPrice
if not na(longTrail) and (useTrailingStop or useAtrTrailingStop)
if na(effectiveStopLevel) or longTrail > effectiveStopLevel
effectiveStopLevel := longTrail
// Combined exit strategy with proper parameters
strategy.exit("Long Exit", "Long",
limit = useAtrTakeProfit ? longTakeProfitPrice : na,
stop = effectiveStopLevel)
if strategy.position_size < 0
// Define effective stop level (combining hard stop and trailing stop)
float effectiveStopLevel = na
if not na(shortHardStopLossPrice) and useHardStopLoss
effectiveStopLevel := shortHardStopLossPrice
if not na(shortTrail) and (useTrailingStop or useAtrTrailingStop)
if na(effectiveStopLevel) or shortTrail < effectiveStopLevel
effectiveStopLevel := shortTrail
// Combined exit strategy with proper parameters
strategy.exit("Short Exit", "Short",
limit = useAtrTakeProfit ? shortTakeProfitPrice : na,
stop = effectiveStopLevel)
// === Plotting ===
plotColorMa1 = nw_ma1 > nw_ma1[1] ? color.rgb(100, 250, 120) : color.rgb(255, 100, 120)
plotColorMa2 = nw_ma2 > nw_ma2[1] ? color.rgb(100, 250, 120) : color.rgb(255, 100, 120)
plotColorMa3 = nw_ma3 > nw_ma3[1] ? color.rgb(100, 250, 120) : color.rgb(255, 100, 120)
plotColorMa4 = nw_ma4 > nw_ma4[1] ? color.rgb(100, 250, 120) : color.rgb(255, 100, 120)
plotColorMa5 = nw_ma5 > nw_ma5[1] ? color.rgb(100, 250, 120) : color.rgb(255, 100, 120)
plot(nw_ma1, title="NW MA 1", color=plotColorMa1, linewidth=2)
plot(nw_ma2, title="NW MA 2", color=plotColorMa2, linewidth=2)
plot(nw_ma3, title="NW MA 3", color=plotColorMa3, linewidth=2)
plot(nw_ma4, title="NW MA 4", color=plotColorMa4, linewidth=2)
plot(nw_ma5, title="NW MA 5", color=plotColorMa5, linewidth=2)