দুই দিকের মুভিং এভারেজ রিভার্সনের ট্রেডিং কৌশল

লেখক:চাওঝাং, তারিখঃ 2024-01-15 12:15:14
ট্যাগঃ

img

সারসংক্ষেপ

দ্বিপাক্ষিক চলমান গড় বিপরীত ট্রেডিং কৌশল হল মূল্যের গড় বিপরীত তত্ত্বের উপর নির্মিত একটি পরিমাণগত ট্রেডিং কৌশল। এই কৌশলটি একাধিক চলমান গড় স্থাপন করে মূল্য বিপরীত সুযোগগুলি ক্যাপচার করে এবং যখন দামটি চলমান গড় থেকে উল্লেখযোগ্যভাবে বিচ্যুত হয় তখন বাজারে প্রবেশ করে এবং যখন এটি ফিরে আসে তখন বেরিয়ে আসে।

কৌশলগত যুক্তি

এই কৌশলটির মূল ধারণা হ'ল মূল্যের গড় বিপরীতমুখী, যা পরামর্শ দেয় যে দামগুলি একটি গড় মানের চারপাশে পরিবর্তিত হয় এবং যখন তারা গড় থেকে খুব বেশি বিচ্যুত হয় তখন ফিরে যাওয়ার সম্ভাবনা বেশি থাকে। বিশেষত, এই কৌশলটি চলমান গড়ের তিনটি গোষ্ঠী স্থাপন করেঃ প্রবেশের চলমান গড়, প্রস্থান চলমান গড় এবং স্টপ-লস চলমান গড়। দামগুলি প্রবেশের চলমান গড়ের কাছে পৌঁছলে এটি সংশ্লিষ্ট দীর্ঘ বা সংক্ষিপ্ত অবস্থানগুলি খুলবে; দামগুলি প্রস্থান চলমান গড়ের কাছে পৌঁছলে অবস্থানগুলি বন্ধ করবে; এবং দামগুলি ফিরে না গিয়ে প্রবণতা অব্যাহত রাখার ক্ষেত্রে স্টপ-লস চলমান গড়ের সাথে ক্ষতি নিয়ন্ত্রণ করবে।

কোড লজিক দৃষ্টিকোণ থেকে, দুটি এন্ট্রি চলমান গড় রয়েছে - দীর্ঘ এবং সংক্ষিপ্ত - যথাক্রমে দ্রুত এবং ধীর চলমান গড়ের সমন্বয়ে গঠিত। তাদের এবং দামের মধ্যে বিচ্যুতি অবস্থান আকার নির্ধারণ করে। এছাড়াও, প্রস্থান চলমান গড় একটি পৃথক চলমান গড় যা অবস্থানগুলি বন্ধ করার সময় সংকেত দেয়। যখন দামগুলি এই লাইনে আঘাত করে, তখন বিদ্যমান অবস্থানগুলি সমতল হয়ে যাবে।

সুবিধা বিশ্লেষণ

দ্বিপাক্ষিক চলমান গড় রিভার্সনের কৌশলটির প্রধান সুবিধাগুলির মধ্যে রয়েছেঃ

  1. মূল্য বিপরীতমুখী, পরিসীমা সীমাবদ্ধ বাজারগুলির জন্য উপযুক্ত
  2. স্টপ লসের মাধ্যমে ঝুঁকি নিয়ন্ত্রণ
  3. অভিযোজনযোগ্যতার জন্য অত্যন্ত কাস্টমাইজযোগ্য পরামিতি
  4. বোঝার সহজ, প্যারামিটার অপ্টিমাইজেশান জন্য সুবিধাজনক

এই কৌশলটি কম অস্থিরতার যন্ত্রগুলির সাথে ভালভাবে কাজ করে যার তুলনামূলকভাবে ছোট দামের ওঠানামা রয়েছে, বিশেষত যখন ব্যাপ্তি-সীমাবদ্ধ চক্রগুলিতে প্রবেশ করা হয়। এটি সাময়িক মূল্য বিপরীতমুখী থেকে কার্যকরভাবে সুযোগগুলি ক্যাপচার করতে পারে। এদিকে, ঝুঁকি নিয়ন্ত্রণ ব্যবস্থাগুলি বেশ বিস্তৃত, দামগুলি ফিরে না আসা সত্ত্বেও যুক্তিসঙ্গত ব্যাপ্তির মধ্যে ক্ষতির সীমাবদ্ধতা।

ঝুঁকি বিশ্লেষণ

এই কৌশলটির সাথে কিছু ঝুঁকিও জড়িতঃ

  1. প্রবণতা অনুসরণ করা ঝুঁকিপূর্ণ। ধারাবাহিকভাবে নতুন পজিশন শক্তিশালী প্রবণতা চলাকালীন তরলীকরণের দিকে পরিচালিত করতে পারে।
  2. দামের অত্যধিক ওঠানামা ঝুঁকি। স্টপ লস বাড়তি অস্থিরতার দ্বারা আঘাত হতে পারে।
  3. প্যারামিটার অপ্টিমাইজেশান ঝুঁকি। অনুপযুক্ত প্যারামিটার সেটিংস উল্লেখযোগ্যভাবে underperformance হতে পারে।

উপরের ঝুঁকিগুলি হ্রাস করার কিছু উপায়গুলির মধ্যে রয়েছেঃ

  1. অতিরিক্ত লেনদেন এড়াতে নতুন এন্ট্রি সীমাবদ্ধ করা
  2. লিকুইডেশন ঝুঁকি সীমাবদ্ধ করার জন্য পজিশনের আকার হ্রাস করা
  3. চলমান গড় সময়ের মত প্যারামিটার অপ্টিমাইজ করা এবং প্রস্থান লাইন গুণক

অপ্টিমাইজেশান নির্দেশাবলী

এই কৌশলকে আরও উন্নত করার জন্যও পর্যাপ্ত সুযোগ রয়েছেঃ

  1. প্রবণতা অনুসরণ রোধ করার জন্য অতিরিক্ত এন্ট্রি লজিক যোগ করুন
  2. অস্থিরতার বিরুদ্ধে অভিযোজিত পজিশন সাইজিং অন্তর্ভুক্ত করুন
  3. বিভিন্ন ধরণের চলমান গড়ের সাথে পরীক্ষা
  4. স্বয়ংক্রিয় প্যারামিটার অপ্টিমাইজেশনের জন্য মেশিন লার্নিং
  5. আরও গতিশীল ঝুঁকি ব্যবস্থাপনার জন্য ট্রেলিং স্টপগুলি অন্তর্ভুক্ত করুন

সিদ্ধান্ত

দ্বি-পন্থী চলমান গড় বিপরীতমুখী ট্রেডিং কৌশলটি তার চলমান গড় স্তর থেকে উল্লেখযোগ্য বিচ্যুতির পরে মূল্য বিপরীতমুখী থেকে লাভ অর্জনের লক্ষ্য রাখে। যথাযথ ঝুঁকি নিয়ন্ত্রণ ব্যবস্থাগুলির সাথে, এটি পরামিতি টিউনিংয়ের মাধ্যমে ধারাবাহিক মুনাফা অর্জন করতে পারে। যদিও প্রবণতা অনুসরণ এবং অত্যধিক অস্থিরতার মতো ঝুঁকিগুলি এখনও বিদ্যমান রয়েছে, তবে এন্ট্রি লজিক উন্নত করে, অবস্থান আকার হ্রাস এবং আরও অনেক কিছুর মাধ্যমে এগুলি মোকাবেলা করা যেতে পারে। এই সহজ-অনুমোদিত কৌশলটি পরিমাণগত ব্যবসায়ীদের কাছ থেকে আরও গবেষণা এবং অপ্টিমাইজেশনের দাবি করে।


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

আরো