सुपरट्रेंड एमएसीडी मात्रात्मक रणनीति

लेखक:चाओझांग, दिनांकः 2023-12-26 11:13:24
टैगः

img

अवलोकन

यह रणनीति सुपरट्रेंड सूचक और एमएसीडी सूचक के संभावित रुझान उलट सिग्नल को आरएसआई सूचक के ओवरबॉट/ओवरसोल्ड सिग्नल के साथ मिलकर प्रवेश और निकास संकेतों के लिए अपेक्षाकृत स्थिर और कुशल प्रणाली का गठन करती है। रणनीति का नाम है सुपरट्रेंड एमएसीडी मात्रात्मक रणनीति

रणनीति तर्क

इस रणनीति का मूल तर्क सुपरट्रेंड संकेतक और एमएसीडी संकेतक के संयुक्त उपयोग में प्रवेश संकेतों के लिए मानदंड के रूप में निहित है।

सुपरट्रेंड भाग पर, रणनीति सुपरट्रेंड संकेतक की दिशा परिवर्तन को संभावित उलट संकेत के रूप में अपनाती है। जब सुपरट्रेंड दिशा ऊपर से नीचे की ओर मुड़ती है, तो एक खरीद संकेत उत्पन्न होता है। जब दिशा नीचे से ऊपर की ओर मुड़ती है, तो एक बिक्री संकेत उत्पन्न होता है।

एमएसीडी भाग पर, रणनीति संभावित उलट अवसरों की पहचान करने के लिए कम समय सीमा (दैनिक) पर एमएसीडी संकेतक के ढलान और शून्य रेखा क्रॉसओवर का उपयोग करती है। जब एमएसीडी ढलान पूर्ण मूल्य बड़ा (सीमा से ऊपर) होता है और ढलान ऊपर की ओर प्रवृत्ति बनाए रखता है, तो एक संकेत उत्पन्न होता है। यदि एमएसीडी रेखा शून्य रेखा को पार करती है, तो एक सहायक संकेत उत्पन्न होता है। एमएसीडी संकेत आमतौर पर सुपरट्रेंड के मुकाबले अधिक चिकनी होते हैं।

प्रवेश संकेतों के लिए, रणनीति के लिए सुपरट्रेंड संकेत और एमएसीडी संकेत को ट्रेडिंग ऑर्डर भेजने से पहले एक ही दिशा में होना आवश्यक है।

इसके अलावा, निकास संकेतों के लिए, रणनीति आरएसआई संकेतक से ओवरबॉट / ओवरसोल्ड संकेतों को भी अपनाती है। जब आरएसआई 80 से ऊपर जाता है, तो एक बिक्री संकेत उत्पन्न होता है। जब आरएसआई 20 से नीचे गिरता है, तो एक खरीद संकेत उत्पन्न होता है। ये उलट समय निर्धारित करने में मदद करते हैं।

लाभ विश्लेषण

इस रणनीति का सबसे बड़ा लाभ संकेतकों के संकेतों की विविधता है। विभिन्न संकेतकों से एक दूसरे का पूरक बन सकता है और समग्र संकेत को अधिक स्थिर और विश्वसनीय बना सकता है।

सुपरट्रेंड रिवर्सल सिग्नल अपेक्षाकृत मजबूत अल्पकालिक रुझानों को पकड़ सकते हैं; एमएसीडी ढलान झूठे उलटफेरों से भ्रमित होने से बचने के लिए मध्यम-लंबी अवधि की प्रवृत्ति की ताकत का न्याय कर सकता है; आरएसआई ओवरबॉट / ओवरसोल्ड स्तरों को इंगित करके रेंज-बाउंड बाजार में सबसे अच्छा प्रवेश और निकास समय प्रदान कर सकता है। कई संकेतकों से सिग्नल स्टैकिंग कुछ शोर ट्रेडों को फ़िल्टर कर सकता है और उच्च जीत दर प्राप्त कर सकता है।

इसके अतिरिक्त, समय सीमा डिजाइन भी उचित है। सुपरट्रेंड प्रति घंटे समय सीमा का उपयोग करता है जबकि एमएसीडी दैनिक समय सीमा का उपयोग करता है। यह ट्रेडिंग आवृत्ति और प्रवृत्ति निर्णय में स्थिरता दोनों सुनिश्चित करता है।

जोखिम विश्लेषण

इस रणनीति का मुख्य जोखिम विभिन्न संकेतकों के बीच संकेतों को भ्रमित करने की उच्च संभावना है। उदाहरण के लिए, सुपरट्रेंड झूठी उलट दे सकता है जबकि एमएसीडी संकेत सिंक्रनाइज़ नहीं होता है। इससे अनावश्यक नुकसान हो सकता है।

इसके अतिरिक्त, बाहर निकलने के समय को निर्धारित करने के लिए आरएसआई भी बहुत जल्दी या बहुत देर से हो सकता है, जिससे अधिकतम होल्डिंग अवधि को रोका जा सकता है।

अंत में, अत्यधिक MACD ढलान सीमा भी कमजोर उलट अवसरों को याद कर सकती है।

अनुकूलन दिशाएँ

इस रणनीति को निम्नलिखित पहलुओं से और अनुकूलित किया जा सकता हैः

  1. स्टॉप लॉस तंत्र लागू करें। जब हानि एक निश्चित प्रतिशत से अधिक हो।

  2. एमएसीडी ढलान निर्णय के लिए गतिशील सीमा जोड़ें। जब बाजार अस्थिरता अधिक हो, तो ढलान सीमा बढ़ाएं, और जब बाजार स्थिर हो, तो सीमा कम करें।

  3. आरएसआई से बाहर निकलने के लिए पलकबैक की शर्त जोड़ें। बंद स्थिति पर विचार करने से पहले आरएसआई 80 से अधिक होने के बाद महत्वपूर्ण कॉलबैक की आवश्यकता होती है।

  4. वॉल्यूम के साथ एमएसीडी का परीक्षण करें और देखें कि क्या यह संकेत विश्वसनीयता में सुधार करता है

  5. इष्टतम सेटिंग्स खोजने के लिए स्वचालित पैरामीटर ट्यूनिंग का प्रयास करना

निष्कर्ष

सुपरट्रेंड एमएसीडी मात्रात्मक रणनीति प्रवेश और निकास संकेत प्रदान करने के लिए कई संकेतकों के संकेतों को जोड़ती है। इसके फायदे स्थिर संकेतों और अपेक्षाकृत उच्च जीत दर में निहित हैं। पैरामीटर अनुकूलन के माध्यम से आगे के सुधार प्राप्त किए जा सकते हैं। जोखिम और अनुकूलन दिशाएं मुख्य रूप से पैरामीटर ओवरफिटिंग मुद्दों के आसपास केंद्रित हैं। कुल मिलाकर, इस रणनीति का लाइव ट्रेडिंग के लिए मजबूत व्यावहारिक मूल्य है।


/*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)


अधिक