द्विदिशात्मक चलती औसत प्रतिवर्तन ट्रेडिंग रणनीति मूल्य औसत प्रतिवर्तन के सिद्धांत पर निर्मित एक मात्रात्मक ट्रेडिंग रणनीति है। यह रणनीति कई चलती औसत स्थापित करके मूल्य प्रतिवर्तन के अवसरों को पकड़ती है और जब कीमत चलती औसत से महत्वपूर्ण रूप से विचलित होती है तो बाजार में प्रवेश करती है, और जब यह वापस लौटती है तो बाहर निकलती है।
इस रणनीति का मूल विचार मूल्य औसत प्रतिगमन है, जो सुझाव देता है कि कीमतें एक औसत मूल्य के आसपास उतार-चढ़ाव करती हैं, और जब वे औसत से बहुत दूर हट जाती हैं तो वापस लौटने की अधिक संभावना होती है। विशेष रूप से, यह रणनीति चलती औसत के तीन समूहों को स्थापित करती हैः प्रवेश चलती औसत, निकास चलती औसत, और स्टॉप-लॉस चलती औसत। जब कीमतें प्रवेश चलती औसत तक पहुंचती हैं तो यह संबंधित लंबी या छोटी स्थिति खोलती है; जब कीमतें निकास चलती औसत तक पहुंचती हैं तो स्थिति बंद हो जाती है; और स्टॉप-लॉस चलती औसत के साथ नियंत्रण नुकसान होता है यदि कीमतें वापस न लौटने के बिना प्रवृत्ति जारी रखती हैं।
कोड लॉजिक परिप्रेक्ष्य से, दो प्रवेश चलती औसत हैं - लंबी और छोटी - जिनमें क्रमशः तेज़ और धीमी गति से चलती औसत शामिल हैं। उनके और मूल्य के बीच विचलन स्थिति का आकार निर्धारित करता है। इसके अलावा, निकास चलती औसत एक अलग चलती औसत है जो संकेत देता है कि पदों को कब बंद करना है। जब कीमतें इस रेखा को छूती हैं, तो मौजूदा पद समतल हो जाएंगे।
द्विदिशात्मक चलती औसत प्रतिगमन रणनीति के मुख्य लाभों में शामिल हैंः
यह रणनीति कम अस्थिरता वाले साधनों के साथ अच्छी तरह से काम करती है जिनके पास अपेक्षाकृत छोटे मूल्य उतार-चढ़ाव होते हैं, खासकर जब सीमा-बंद चक्रों में प्रवेश करते हैं। यह अस्थायी मूल्य उलट से प्रभावी ढंग से अवसरों को पकड़ सकता है। इस बीच, जोखिम नियंत्रण उपाय काफी व्यापक हैं, उचित सीमाओं के भीतर नुकसान को कैप करते हैं, भले ही कीमतें वापस न लौटें।
इस रणनीति से जुड़े कुछ जोखिम भी हैंः
उपरोक्त जोखिमों को कम करने के कुछ तरीकों में शामिल हैंः
इस रणनीति को और अधिक अनुकूलित करने के लिए भी काफी जगह हैः
द्विदिशात्मक चलती औसत प्रतिगमन ट्रेडिंग रणनीति का उद्देश्य अपने चलती औसत स्तरों से महत्वपूर्ण विचलन के बाद मूल्य उलटों से लाभ प्राप्त करना है। उचित जोखिम नियंत्रण उपायों के साथ, यह पैरामीटर ट्यूनिंग के माध्यम से लगातार लाभ प्राप्त कर सकता है। जबकि रुझानों का पीछा करने और अत्यधिक अस्थिरता जैसे जोखिम अभी भी मौजूद हैं, उन्हें प्रवेश तर्क में सुधार, स्थिति के आकार को कम करने और अधिक के माध्यम से संबोधित किया जा सकता है। यह समझने में आसान रणनीति मात्रात्मक व्यापारियों से आगे के शोध और अनुकूलन का हकदार है।
/*backtest start: 2023-12-15 00:00:00 end: 2024-01-14 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 = 30, pyramiding = 1, commission_value = 0.1, 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 Long" maopeningtyp_l = 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_l = input.source(ohlc4, title = "", inline=info_opening, group=info_opening) maopeninglen_l = input.int(3, minval = 1, title = "", inline=info_opening, group=info_opening) 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") info_opening_s = "MA Opening Short" maopeningtyp_s = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening_s, group=info_opening_s) maopeningsrc_s = input.source(ohlc4, title = "", inline=info_opening_s, group=info_opening_s) maopeninglen_s = input.int(3, minval = 1, title = "", inline=info_opening_s, group=info_opening_s) 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") //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) 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_l = 0.0 maopening_s = 0.0 maclosing = 0.0 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_l := ma_func(maopeningtyp_l, maopeningsrc_l, maopeninglen_l) maopening_s := ma_func(maopeningtyp_s, maopeningsrc_s, maopeninglen_s) //MA Closing maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening_l == 0 ? 0 : maopening_l * long1shift short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening_s == 0 ? 0 : maopening_s * short1shift //Colors long1col = long1 == 0 ? na : color.green short1col = short1 == 0 ? na : color.red //Lines // plot(maopening_l, offset = OFFS, color = color.new(color.green, 50)) // plot(maopening_s, offset = OFFS, color = color.new(color.red, 50)) plot(maclosing, offset = OFFS, color = color.fuchsia) 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 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()