डबल मूविंग एवरेज रिवर्सन रणनीति एक विशिष्ट अल्पकालिक औसत रिवर्सन ट्रेडिंग रणनीति है। यह रणनीति विभिन्न पैरामीटर सेटिंग्स के साथ दो मूविंग एवरेज द्वारा ट्रेडिंग सिग्नल उत्पन्न करती है। इसका उद्देश्य ट्रेंड रिवर्स होने पर मुनाफा कमाना है।
रणनीति ट्रेडिंग सिग्नल उत्पन्न करने के लिए दो चलती औसत का उपयोग करती है। पहली एमए माओपनिंग का उपयोग प्रवृत्ति की दिशा निर्धारित करने के लिए किया जाता है। दूसरी एमए मैक्लोसिंग का उपयोग ट्रेडिंग सिग्नल उत्पन्न करने के लिए किया जाता है।
जब maopening ऊपर जाता है, तो यह इंगित करता है कि वर्तमान बाजार एक अपट्रेंड में है। जब maopening नीचे जाता है, तो यह इंगित करता है कि वर्तमान बाजार एक डाउनट्रेंड में है। maclosing को 1 से अधिक गुणांक से गुणा किया जाता है ताकि इसे प्रारंभिक उलट संकेत उत्पन्न करने के लिए अधिक संवेदनशील बनाया जा सके।
विशेष रूप से, जब maopening ऊपर जाता है और maclosing maopening के नीचे पार करता है, तो यह एक प्रवृत्ति उलट का संकेत देता है। रणनीति छोटी स्थिति खोलेगी। जब maopening नीचे जाता है और maclosing maopening के ऊपर पार करता है, तो यह एक प्रवृत्ति उलट का संकेत देता है। रणनीति लंबी स्थिति खोलेगी।
रणनीति के मापदंडों में एमए प्रकार, लंबाई, डेटा स्रोत आदि शामिल हैं। इन मापदंडों को समायोजित करके ट्रेडिंग प्रदर्शन को अनुकूलित किया जा सकता है। कुछ कॉन्फ़िगर करने योग्य विकल्प जैसे प्रवेश नियम, स्टॉप लॉस आदि भी हैं।
दोहरे एमए रिवर्सन रणनीति के मुख्य लाभ निम्नलिखित हैंः
लघु ड्रॉडाउन, अल्पकालिक व्यापार के लिए उपयुक्त है। तेजी से चलती औसत छोटे ड्रॉडाउन के साथ अल्पकालिक उलटफेर को जल्दी से पकड़ सकती है।
लागू करने में सरल और समझने में आसान। दो एमए का क्रॉसओवर स्पष्ट ट्रेडिंग सिग्नल उत्पन्न करता है।
कई समायोज्य मापदंडों के साथ अत्यधिक विन्यास योग्य। दो एमए और गुणांक के मापदंडों को अनुकूलित किया जा सकता है।
स्पष्ट तर्क प्रवाह के साथ स्वचालित करने में आसान। सरल तर्क और उच्च आवृत्ति व्यापार इसे स्वचालित व्यापार के लिए बहुत उपयुक्त बनाते हैं।
स्टॉप लॉस तंत्र के साथ नियंत्रित जोखिम। चलती स्टॉप लॉस या मूल्य स्टॉप लॉस एकल व्यापार के नुकसान को सीमित कर सकता है।
इस रणनीति के कुछ जोखिम भी हैंः
एमए क्रॉसओवर सिग्नल का लेगिंग। एमए खुद कीमत से पीछे हैं। कुछ समय के लिए प्रवृत्ति उलट जाने के बाद क्रॉसओवर हो सकता है।
व्हीपसॉ ट्रेडों का जोखिम। उलटा रुझान जल्दी से फिर से उलटा हो सकता है, जिससे लगातार नुकसान हो सकता है।
ड्रॉडाउन अभी भी मौजूद है. हालांकि स्टॉप लॉस एकल हानि को सीमित करता है, लगातार स्टॉप लॉस अभी भी बड़े ड्रॉडाउन का कारण बन सकता है.
ओवरफिटिंग जोखिमः अत्यधिक पैरामीटर अनुकूलन से ओवरफिटिंग और लाइव ट्रेडिंग में खराब प्रदर्शन हो सकता है।
समाधानों में शामिल हैंः
तेजी से एमए खोजने के लिए मापदंडों का अनुकूलन करें.
वाइपसा ट्रेडों से बचने के लिए वॉल्यूम और अस्थिरता संकेतकों जैसे फ़िल्टर जोड़ें।
लगातार स्टॉप लॉस की संभावना को कम करने के लिए स्टॉप लॉस की स्थिति को समायोजित करें।
ओवरफिटिंग जोखिमों का आकलन करने के लिए पैरामीटर सेटों की मजबूती परीक्षण।
इस रणनीति को निम्नलिखित पहलुओं में और अधिक अनुकूलित किया जा सकता हैः
विभिन्न प्रकार के एमए का परीक्षण अधिक संवेदनशीलों को खोजने के लिए किया जाता है, जैसे कि कामा, ज़्लेमा आदि।
इष्टतम संयोजन खोजने के लिए एमए लंबाई का अनुकूलन करें। आमतौर पर कम अवधि में बेहतर प्रदर्शन होता है।
विभिन्न डेटा स्रोतों का परीक्षण करें, जैसे कि बंद, मध्य मूल्य, विशिष्ट मूल्य आदि।
Donchian Channel जैसे अनुचित रिवर्स सिग्नल से बचने के लिए ट्रेंड फिल्टर जोड़ें।
पुष्टि के लिए अन्य संकेतक जोड़ें, जैसे एमएसीडी, ओबीवी आदि।
जोखिम प्रबंधन तंत्र जैसे स्टॉप लॉस, अधिकतम खाता हानि आदि को बढ़ाना।
इष्टतम परिसंपत्ति आवंटन खोजने के लिए पोर्टफोलियो अनुकूलन।
ओवरफिटिंग जोखिमों का आकलन करने के लिए मापदंडों की मजबूती का परीक्षण।
ड्यूल एमए रिवर्सन एक सरल और व्यावहारिक अल्पकालिक ट्रेडिंग रणनीति है। यह मात्रात्मक ट्रेडिंग के साथ अल्पकालिक उलटफेर को पकड़ने के लिए उपयुक्त है। हालांकि, लेगिंग और व्हिपसा ट्रेड जैसे जोखिम मौजूद हैं। रणनीति को पैरामीटर अनुकूलित करके, फिल्टर जोड़कर, जोखिम नियंत्रण आदि को बढ़ाने के लिए एक स्थिर और कुशल रणनीति विकसित करने के लिए बेहतर बनाया जा सकता है।
/*backtest start: 2023-10-17 00:00:00 end: 2023-11-16 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title = "hamster-bot MRS 2", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 9, commission_value = 0.045, backtest_fill_limits_assumption = 1) info_options = "Options" on_close = input(false, title = "Entry on close", inline=info_options, group=info_options) OFFS = input.int(0, minval = 0, maxval = 1, title = "| Offset View", inline=info_options, group=info_options) trade_offset = input.int(0, minval = 0, maxval = 1, title = "Trade", inline=info_options, group=info_options) use_kalman_filter = input.bool(false, title="Use Kalman filter", group=info_options) //MA Opening info_opening = "MA Opening" maopeningtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening, group=info_opening) maopeningsrc = input.source(ohlc4, title = "", inline=info_opening, group=info_opening) maopeninglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_opening, group=info_opening) //MA Closing info_closing = "MA Closing" maclosingtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_closing, group=info_closing) maclosingsrc = input.source(ohlc4, title = "", inline=info_closing, group=info_closing) maclosinglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_closing, group=info_closing) maclosingmul = input.float(1, step = 0.005, title = "mul", inline=info_closing, group=info_closing) long1on = input(true, title = "", inline = "long1") long1shift = input.float(0.96, step = 0.005, title = "Long", inline = "long1") long1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "long1") short1on = input(true, title = "", inline = "short1") short1shift = input.float(1.04, step = 0.005, title = "short", inline = "short1") short1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "short1") startTime = input(timestamp("01 Jan 2010 00:00 +0000"), "Start date", inline = "period") finalTime = input(timestamp("31 Dec 2030 23:59 +0000"), "Final date", inline = "period") HMA(_src, _length) => ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length))) EHMA(_src, _length) => ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length))) THMA(_src, _length) => ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length) tema(sec, length)=> tema1= ta.ema(sec, length) tema2= ta.ema(tema1, length) tema3= ta.ema(tema2, length) tema_r = 3*tema1-3*tema2+tema3 donchian(len) => math.avg(ta.lowest(len), ta.highest(len)) ATR_func(_src, _len)=> atrLow = low - ta.atr(_len) trailAtrLow = atrLow trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1] supportHit = _src <= trailAtrLow trailAtrLow := supportHit ? atrLow : trailAtrLow trailAtrLow f_dema(src, len)=> EMA1 = ta.ema(src, len) EMA2 = ta.ema(EMA1, len) DEMA = (2*EMA1)-EMA2 f_zlema(src, period) => lag = math.round((period - 1) / 2) ema_data = src + (src - src[lag]) zl= ta.ema(ema_data, period) f_kalman_filter(src) => float value1= na float value2 = na value1 := 0.2 * (src - src[1]) + 0.8 * nz(value1[1]) value2 := 0.1 * (ta.tr) + 0.8 * nz(value2[1]) lambda = math.abs(value1 / value2) alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8 value3 = float(na) value3 := alpha * src + (1 - alpha) * nz(value3[1]) //SWITCH ma_func(modeSwitch, src, len, use_k_f=true) => modeSwitch == "SMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.sma(src, len)) : ta.sma(src, len) : modeSwitch == "RMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.rma(src, len)) : ta.rma(src, len) : modeSwitch == "EMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.ema(src, len)) : ta.ema(src, len) : modeSwitch == "TEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(tema(src, len)) : tema(src, len): modeSwitch == "DEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_dema(src, len)) : f_dema(src, len): modeSwitch == "ZLEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_zlema(src, len)) : f_zlema(src, len): modeSwitch == "WMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.wma(src, len)) : ta.wma(src, len): modeSwitch == "VWMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.vwma(src, len)) : ta.vwma(src, len): modeSwitch == "Hma" ? use_kalman_filter and use_k_f ? f_kalman_filter(HMA(src, len)) : HMA(src, len): modeSwitch == "Ehma" ? use_kalman_filter and use_k_f ? f_kalman_filter(EHMA(src, len)) : EHMA(src, len): modeSwitch == "Thma" ? use_kalman_filter and use_k_f ? f_kalman_filter(THMA(src, len/2)) : THMA(src, len/2): modeSwitch == "ATR" ? use_kalman_filter and use_k_f ? f_kalman_filter(ATR_func(src, len)): ATR_func(src, len) : modeSwitch == "L" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.lowest(len)): ta.lowest(len) : modeSwitch == "H" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.highest(len)): ta.highest(len) : modeSwitch == "DMA" ? donchian(len) : na //Var sum = 0.0 maopening = 0.0 maclosing = 0.0 os = maopeningsrc cs = maclosingsrc pos = strategy.position_size p = 0.0 p := pos == 0 ? (strategy.equity / 100) / close : p[1] truetime = true loss = 0.0 maxloss = 0.0 equity = 0.0 //MA Opening maopening := ma_func(maopeningtyp, maopeningsrc, maopeninglen) //MA Closing maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * long1shift short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * short1shift //Colors maopeningcol = maopening == 0 ? na : color.blue maclosingcol = maclosing == 0 ? na : color.fuchsia long1col = long1 == 0 ? na : color.green short1col = short1 == 0 ? na : color.red //Lines plot(maopening, offset = OFFS, color = maopeningcol) plot(maclosing, offset = OFFS, color = maclosingcol) long1line = long1 == 0 ? close : long1 short1line = short1 == 0 ? close : short1 plot(long1line, offset = OFFS, color = long1col) plot(short1line, offset = OFFS, color = short1col) //Lots lotlong1 = p * long1lot lotshort1 = p * short1lot //Entry if maopening > 0 and maclosing > 0 and truetime //Long sum := 0 strategy.entry("L", strategy.long, lotlong1, limit = on_close ? na : long1, when = long1 > 0 and pos <= sum and (on_close ? close <= long1[trade_offset] : true)) sum := lotlong1 //Short sum := 0 pos := -1 * pos strategy.entry("S", strategy.short, lotshort1, limit = on_close ? na : short1, when = short1 > 0 and pos <= sum and (on_close ? close >= short1[trade_offset] : true)) sum := lotshort1 strategy.exit("Exit", na, limit = maclosing) if time > finalTime strategy.close_all()