यह रणनीति सुपरट्रेंड सूचक और एमएसीडी सूचक के संभावित रुझान उलट सिग्नल को आरएसआई सूचक के ओवरबॉट/ओवरसोल्ड सिग्नल के साथ मिलकर प्रवेश और निकास संकेतों के लिए अपेक्षाकृत स्थिर और कुशल प्रणाली का गठन करती है। रणनीति का नाम है
इस रणनीति का मूल तर्क सुपरट्रेंड संकेतक और एमएसीडी संकेतक के संयुक्त उपयोग में प्रवेश संकेतों के लिए मानदंड के रूप में निहित है।
सुपरट्रेंड भाग पर, रणनीति सुपरट्रेंड संकेतक की दिशा परिवर्तन को संभावित उलट संकेत के रूप में अपनाती है। जब सुपरट्रेंड दिशा ऊपर से नीचे की ओर मुड़ती है, तो एक खरीद संकेत उत्पन्न होता है। जब दिशा नीचे से ऊपर की ओर मुड़ती है, तो एक बिक्री संकेत उत्पन्न होता है।
एमएसीडी भाग पर, रणनीति संभावित उलट अवसरों की पहचान करने के लिए कम समय सीमा (दैनिक) पर एमएसीडी संकेतक के ढलान और शून्य रेखा क्रॉसओवर का उपयोग करती है। जब एमएसीडी ढलान पूर्ण मूल्य बड़ा (सीमा से ऊपर) होता है और ढलान ऊपर की ओर प्रवृत्ति बनाए रखता है, तो एक संकेत उत्पन्न होता है। यदि एमएसीडी रेखा शून्य रेखा को पार करती है, तो एक सहायक संकेत उत्पन्न होता है। एमएसीडी संकेत आमतौर पर सुपरट्रेंड के मुकाबले अधिक चिकनी होते हैं।
प्रवेश संकेतों के लिए, रणनीति के लिए सुपरट्रेंड संकेत और एमएसीडी संकेत को ट्रेडिंग ऑर्डर भेजने से पहले एक ही दिशा में होना आवश्यक है।
इसके अलावा, निकास संकेतों के लिए, रणनीति आरएसआई संकेतक से ओवरबॉट / ओवरसोल्ड संकेतों को भी अपनाती है। जब आरएसआई 80 से ऊपर जाता है, तो एक बिक्री संकेत उत्पन्न होता है। जब आरएसआई 20 से नीचे गिरता है, तो एक खरीद संकेत उत्पन्न होता है। ये उलट समय निर्धारित करने में मदद करते हैं।
इस रणनीति का सबसे बड़ा लाभ संकेतकों के संकेतों की विविधता है। विभिन्न संकेतकों से एक दूसरे का पूरक बन सकता है और समग्र संकेत को अधिक स्थिर और विश्वसनीय बना सकता है।
सुपरट्रेंड रिवर्सल सिग्नल अपेक्षाकृत मजबूत अल्पकालिक रुझानों को पकड़ सकते हैं; एमएसीडी ढलान झूठे उलटफेरों से भ्रमित होने से बचने के लिए मध्यम-लंबी अवधि की प्रवृत्ति की ताकत का न्याय कर सकता है; आरएसआई ओवरबॉट / ओवरसोल्ड स्तरों को इंगित करके रेंज-बाउंड बाजार में सबसे अच्छा प्रवेश और निकास समय प्रदान कर सकता है। कई संकेतकों से सिग्नल स्टैकिंग कुछ शोर ट्रेडों को फ़िल्टर कर सकता है और उच्च जीत दर प्राप्त कर सकता है।
इसके अतिरिक्त, समय सीमा डिजाइन भी उचित है। सुपरट्रेंड प्रति घंटे समय सीमा का उपयोग करता है जबकि एमएसीडी दैनिक समय सीमा का उपयोग करता है। यह ट्रेडिंग आवृत्ति और प्रवृत्ति निर्णय में स्थिरता दोनों सुनिश्चित करता है।
इस रणनीति का मुख्य जोखिम विभिन्न संकेतकों के बीच संकेतों को भ्रमित करने की उच्च संभावना है। उदाहरण के लिए, सुपरट्रेंड झूठी उलट दे सकता है जबकि एमएसीडी संकेत सिंक्रनाइज़ नहीं होता है। इससे अनावश्यक नुकसान हो सकता है।
इसके अतिरिक्त, बाहर निकलने के समय को निर्धारित करने के लिए आरएसआई भी बहुत जल्दी या बहुत देर से हो सकता है, जिससे अधिकतम होल्डिंग अवधि को रोका जा सकता है।
अंत में, अत्यधिक MACD ढलान सीमा भी कमजोर उलट अवसरों को याद कर सकती है।
इस रणनीति को निम्नलिखित पहलुओं से और अनुकूलित किया जा सकता हैः
स्टॉप लॉस तंत्र लागू करें। जब हानि एक निश्चित प्रतिशत से अधिक हो।
एमएसीडी ढलान निर्णय के लिए गतिशील सीमा जोड़ें। जब बाजार अस्थिरता अधिक हो, तो ढलान सीमा बढ़ाएं, और जब बाजार स्थिर हो, तो सीमा कम करें।
आरएसआई से बाहर निकलने के लिए पलकबैक की शर्त जोड़ें। बंद स्थिति पर विचार करने से पहले आरएसआई 80 से अधिक होने के बाद महत्वपूर्ण कॉलबैक की आवश्यकता होती है।
वॉल्यूम के साथ एमएसीडी का परीक्षण करें और देखें कि क्या यह संकेत विश्वसनीयता में सुधार करता है
इष्टतम सेटिंग्स खोजने के लिए स्वचालित पैरामीटर ट्यूनिंग का प्रयास करना
/*backtest start: 2022-12-19 00:00:00 end: 2023-12-25 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("SuperTrend.MACD Strategy", overlay=false, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=100000, pyramiding=5, process_orders_on_close=true) // ---------------- Utility Functions ---------------- getArrayValue(float[] arr, int ago) => if ago >= 0 array.get(arr, ago >= array.size(arr) ? na: array.size(arr) + -1 * ago -1) else na filterNA(float[] a, s, int y) => int x = 0 if not na(s[0]) array.push(a, s[0]) if array.size(a) > y array.shift(a) a pine_rsi(float[] x, int y) => x0 = getArrayValue(x, 0) x1 = getArrayValue(x, 1) u = math.max(x0 - x1, 0) // upward ta.change d = math.max(x1 - x0, 0) // downward ta.change rs = ta.rma(u, y) / ta.rma(d, y) res = 100 - 100 / (1 + rs) res turnAround(float[] arr) => int isTurnAround = 0 now = getArrayValue(arr, 0) p1 = getArrayValue(arr, 1) p2 = getArrayValue(arr, 2) if p1 > now and p1 > p2 isTurnAround := -1 else if p1 < now and p1 < p2 isTurnAround := 1 intergerizeSignal(i) => i>0 ? 1 : i<0 ? -1 : 0 linreg(float[] y, int n, int offset=0) => float slope = na float intercept = na int endcursor = offset + n - 1 if array.size(y) > endcursor float sumX = 0 float sumX2 = 0 float sumY = 0 float sumY2 = 0 float sumXY = 0 for i=offset to endcursor yv = array.get(y, i) sumY += yv sumY2 += math.pow(yv, 2) sumX += i sumX2 += math.pow(i, 2) sumXY += i*yv // Pearson correlation coefficient r = (n * sumXY - sumX * sumY) / math.sqrt((n * sumY2 - math.pow(sumY, 2)) * (n * sumX2 - math.pow(sumX, 2))) // Coefficient of determination r2 = math.pow(r, 2) meanX = sumX / n meanY = sumY / n slope := (n * sumXY - sumX * sumY) / (n * sumX2 - math.pow(sumX, 2)) intercept := meanY - slope * meanX [slope, intercept] isStartOfDay() => dayofweek != dayofweek[1] // ---------------- Variables ---------------- varip float st_signal = 0 varip float macd_signal = 0 varip float macd_close_signal = 0 varip float histo_signal = 0 var int openSignal = 0 var int closeSignal = 0 // -------------------------------- Supertrend Signal (Open) -------------------------------- // ST calculation atrPeriod = input(10, "Supertrend ATR Length") factor = input.float(2.0, "Supertrend Factor", step = 0.01) [_, direction] = ta.supertrend(factor, atrPeriod) st_direction_change = ta.change(direction) if st_direction_change < 0 st_signal := 4 if st_direction_change > 0 st_signal := -4 // -------------------------------- MACD Signal (Open + Close) -------------------------------- // MACD Calculation fastLength = input(12, title="MACD Fast Length") slowLength = input(26, title="MACD Slow Length") signalLength = input(9, title="MACD Signal Length") macdSlowTimeframe = input.timeframe("D", "MACD Timeframe") macdSlopeLookbackOpen = input(7, title="MACD Slope Lookback - Open") macdSlopeLookbackClose = input(3, title="MACD Slope Lookback - Close") dailyClose = request.security(syminfo.tickerid, macdSlowTimeframe, close, barmerge.gaps_on) [macdLine, signalLine, _] = ta.macd(dailyClose, fastLength, slowLength, signalLength) // MACD Slope calculation varip macdHistory = array.new<float>(0) varip macdSlowSlopeArr = array.new<float>(0) varip float macdSlowSlope = na varip float macdCloseSlope = na if not na(macdLine[0]) array.push(macdHistory, macdLine[0]) if array.size(macdHistory) > macdSlopeLookbackOpen array.shift(macdHistory) [s1, _] = linreg(macdHistory, macdSlopeLookbackOpen) macdSlowSlope := s1 array.push(macdSlowSlopeArr, macdSlowSlope) if array.size(macdSlowSlopeArr) > macdSlopeLookbackClose array.shift(macdSlowSlopeArr) [s2, _] = linreg(macdSlowSlopeArr, macdSlopeLookbackClose) macdCloseSlope := s2 // MACD Signal Calculation // > open signal threshold_macdSlowSlope = input.float(0.75, "MACD Slope Open Threshold", step = 0.05) macdSlowSlopeOverThreshold = math.abs(macdSlowSlope) >= threshold_macdSlowSlope macdSlowSlopeTrend = macdSlowSlope - getArrayValue(macdSlowSlopeArr, 1) macdSlowSlopeTrendConfirm = macdSlowSlope*macdSlowSlopeTrend >0 if (macdSlowSlopeOverThreshold and macdSlowSlopeTrendConfirm) macd_signal := 3*macdSlowSlope/math.abs(macdSlowSlope) else macd_signal := 0 // > close signal int macdCloseSignal = 0 macdCloseSignal := intergerizeSignal(macdCloseSlope) // Histogram signal Calculation histSlow = macdLine - signalLine if (ta.crossover(histSlow, 0)) histo_signal := 2 if (ta.crossunder(histSlow, 0)) histo_signal := -2 // -------------------------------- RSI Signal (Close) -------------------------------- int rsiCloseSignal = 0 varip float rsiSlow = na rsiPeriod = input(14, title="RSI Period") varip dailyCloseRSIFilter = array.new_float() // rewrite pine_rsi to remove NaN value from series at calculation dailyCloseRSIFilter := filterNA(dailyCloseRSIFilter, dailyClose, rsiPeriod) if not na(dailyClose[0]) rsiSlow := pine_rsi(dailyCloseRSIFilter, rsiPeriod) if rsiSlow > 80 rsiCloseSignal := -1 else if rsiSlow < 20 rsiCloseSignal := 1 else rsiCloseSignal := 0 // -------------------------------- Overall Signal -------------------------------- // Close signal closeSignals = array.from(macdCloseSignal, rsiCloseSignal) closeSignal := array.includes(closeSignals, 1) ? 1 : array.includes(closeSignals, -1) ? -1 : 0 closeSignal := closeSignal * 5 // Open signal if (macd_signal * st_signal > 0) and (macd_signal * macd_close_signal >= 0) openSignal := intergerizeSignal(st_signal) openSignal := openSignal * 6 else openSignal := 0 // -------------------------------- Order -------------------------------- // if strategy.position_size == 0 if openSignal * closeSignal >=0 if openSignal > 0 strategy.entry("Long Entry", strategy.long) else if openSignal < 0 strategy.entry("Short Entry", strategy.short) if strategy.position_size != 0 if closeSignal < 0 strategy.close("Long Entry") if closeSignal > 0 strategy.close("Short Entry") // -------------------------------- Plot -------------------------------- plot(closeSignal, title="Close Signal", color=color.red, linewidth = 1, style=plot.style_area) plot(openSignal, title="Open Signal", color=color.green, linewidth = 1, style=plot.style_area) plot(st_signal, title="ST Signal", color=color.black, linewidth = 1, style=plot.style_circles) plot(macd_signal, title="MACD Signal", color=color.blue, linewidth = 1, style=plot.style_circles) // plot(macdSlowSlope, title="macd slow slope", color=color.purple, linewidth = 1, style=plot.style_line) // plot(macdCloseSlope, title="macd slow slope", color=color.lime, linewidth = 1, style=plot.style_line) hline(0, "Zero Line", color=color.gray)