ডাবল মুভিং এভারেজ রিভার্সন কৌশল একটি সাধারণ স্বল্পমেয়াদী গড় রিভার্সন ট্রেডিং কৌশল। কৌশলটি বিভিন্ন পরামিতি সেটিং সহ দুটি চলমান গড় দ্বারা ট্রেডিং সংকেত উত্পন্ন করে। এটি প্রবণতা বিপরীত হওয়ার সময় মুনাফা অর্জনের লক্ষ্য রাখে।
কৌশলটি ট্রেডিং সংকেত তৈরি করতে দুটি চলমান গড় ব্যবহার করে। প্রথম এমএ ম্যাপেনিং প্রবণতা দিক নির্ধারণ করতে ব্যবহৃত হয়। দ্বিতীয় এমএ ম্যাক্লোসিং ট্রেডিং সংকেত তৈরি করতে ব্যবহৃত হয়।
যখন ম্যাকোপেনিং উপরে যায়, তখন এটি বর্তমান বাজারকে একটি আপট্রেন্ডে নির্দেশ করে। যখন ম্যাকোপেনিং নিচে যায়, তখন এটি বর্তমান বাজারকে একটি ডাউনট্রেন্ডে নির্দেশ করে। ম্যাক্লোসিং 1 এর চেয়ে বড় একটি সহগ দ্বারা গুণিত হয় যাতে এটি প্রাথমিক বিপরীত সংকেত তৈরির জন্য আরও সংবেদনশীল হয়।
বিশেষত, যখন ম্যাপেনিং উপরে যায় এবং ম্যাপেনিং নীচে ক্রস করে, এটি একটি প্রবণতা বিপরীত নির্দেশ করে। কৌশলটি শর্ট পজিশন খুলবে। যখন ম্যাপেনিং নীচে যায় এবং ম্যাপেনিং ম্যাপেনিংয়ের উপরে ক্রস করে, এটি একটি প্রবণতা বিপরীত নির্দেশ করে। কৌশলটি দীর্ঘ অবস্থান খুলবে।
কৌশলটির পরামিতিগুলির মধ্যে এমএ প্রকার, দৈর্ঘ্য, ডেটা উত্স ইত্যাদি অন্তর্ভুক্ত রয়েছে। এই পরামিতিগুলি সামঞ্জস্য করে ট্রেডিং পারফরম্যান্স অপ্টিমাইজ করা যায়। এন্ট্রি রুল, স্টপ লস ইত্যাদির মতো কিছু কনফিগারযোগ্য বিকল্পও রয়েছে।
ডাবল এমএ রিভার্সন স্ট্র্যাটেজির প্রধান সুবিধাগুলি হলঃ
ছোট ড্রডাউন, স্বল্পমেয়াদী ট্রেডিংয়ের জন্য উপযুক্ত। দ্রুত চলমান গড়গুলি ছোট ড্রডাউন সহ স্বল্পমেয়াদী বিপরীতগুলি দ্রুত ধরতে পারে।
বাস্তবায়ন সহজ এবং সহজেই বোঝা যায়। দুটি এমএ এর ক্রসওভার স্পষ্ট ট্রেডিং সংকেত তৈরি করে।
একাধিক সামঞ্জস্যযোগ্য পরামিতি সহ অত্যন্ত কনফিগারযোগ্য। দুটি এমএ এবং সহগগুলির পরামিতিগুলি অনুকূলিত করা যেতে পারে।
স্বয়ংক্রিয় ট্রেডিংয়ের জন্য সহজ লজিক এবং উচ্চ ফ্রিকোয়েন্সি ট্রেডিং খুব উপযুক্ত।
স্টপ লস প্রক্রিয়া সহ নিয়ন্ত্রিত ঝুঁকি। স্টপ লস বা মান স্টপ লস সরানো একক ব্যবসায়ের ক্ষতি সীমিত করতে পারে।
এই কৌশলটির কিছু ঝুঁকিও রয়েছেঃ
এমএ ক্রসওভার সংকেতগুলির বিলম্ব। এমএগুলি নিজেই দামের পিছনে রয়েছে। ক্রসওভারটি কিছু সময়ের জন্য প্রবণতা বিপরীত হওয়ার পরে ঘটতে পারে।
হুইপসা ট্রেডের ঝুঁকি। বিপরীত প্রবণতা দ্রুত আবার বিপরীত হতে পারে, যা পরপর ক্ষতির কারণ হতে পারে।
যদিও স্টপ লস একক ক্ষতি সীমাবদ্ধ করে, ধারাবাহিক স্টপ লস এখনও বড় ড্রডাউন হতে পারে।
ওভারফিটিং ঝুঁকি: অত্যধিক প্যারামিটার অপ্টিমাইজেশান লাইভ ট্রেডিংয়ে ওভারফিটিং এবং দুর্বল পারফরম্যান্সের দিকে পরিচালিত করতে পারে।
সমাধানগুলির মধ্যে রয়েছেঃ
দ্রুততম এমএ খুঁজে পেতে প্যারামিটার অপ্টিমাইজ করুন।
ভলিউম এবং অস্থিরতার সূচকগুলির মতো ফিল্টার যুক্ত করুন, উইপসা ট্রেডগুলি এড়াতে।
ধারাবাহিক স্টপ লস হওয়ার সম্ভাবনা কমাতে স্টপ লস পজিশন সামঞ্জস্য করুন।
অতিরিক্ত ফিটিং ঝুঁকি মূল্যায়নের জন্য প্যারামিটার সেটগুলির দৃঢ়তা পরীক্ষা।
কৌশলটি নিম্নলিখিত দিকগুলিতে আরও অনুকূলিত করা যেতে পারেঃ
বিভিন্ন ধরনের এমএ পরীক্ষা করে আরও সংবেদনশীলদের খুঁজে বের করুন, যেমন কামা, জেলেমা ইত্যাদি।
সর্বোত্তম সমন্বয় খুঁজে পেতে এমএ দৈর্ঘ্য অপ্টিমাইজ করুন। সাধারণত স্বল্প সময়কাল ভাল কর্মক্ষমতা আছে।
বিভিন্ন তথ্য উৎস পরীক্ষা করুন, যেমন বন্ধ, মধ্যম মূল্য, আদর্শ মূল্য ইত্যাদি।
ডনচিয়ান চ্যানেলের মত অনুপযুক্ত বিপরীত সংকেত এড়াতে প্রবণতা ফিল্টার যুক্ত করুন।
ম্যাকড, ওবিভি ইত্যাদির মতো নিশ্চিতকরণের জন্য অন্যান্য সূচক যুক্ত করুন।
ঝুঁকি ব্যবস্থাপনা ব্যবস্থা যেমন স্টপ লস, সর্বোচ্চ অ্যাকাউন্ট লস ইত্যাদির উন্নতি করা।
সর্বোত্তম সম্পদ বরাদ্দ খুঁজে পেতে পোর্টফোলিও অপ্টিমাইজেশান।
অতিরিক্ত ফিটিং ঝুঁকি মূল্যায়ন করার জন্য পরামিতিগুলির দৃঢ়তা পরীক্ষা।
ডুয়াল এমএ রিভার্সন একটি সহজ এবং ব্যবহারিক স্বল্পমেয়াদী ট্রেডিং কৌশল। এটি পরিমাণগত ট্রেডিংয়ের সাথে স্বল্পমেয়াদী বিপরীততা ক্যাপচার করার জন্য উপযুক্ত। তবে, পিছিয়ে যাওয়া এবং উইপসো ট্রেডগুলির মতো ঝুঁকি রয়েছে। কৌশলটি প্যারামিটারগুলি অনুকূল করে, ফিল্টার যুক্ত করে, ঝুঁকি নিয়ন্ত্রণকে উন্নত করে ইত্যাদি উন্নত করা যেতে পারে যাতে ভাল বাস্তব ট্রেডিং পারফরম্যান্স সহ একটি স্থিতিশীল এবং দক্ষ কৌশল বিকাশ করা যায়।
/*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()