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