এই নিবন্ধে একটি পরিমাণগত ট্রেডিং কৌশল বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে যা একাধিক প্রযুক্তিগত সূচককে একত্রিত করে। বিভিন্ন সূচক থেকে সংকেত সংশ্লেষণ করে এটি কার্যকর ঝুঁকি নিয়ন্ত্রণ অর্জন করে।
I. কৌশলগত যুক্তি
কৌশলটি প্রধানত নিম্নলিখিত উপাদানগুলি অন্তর্ভুক্ত করেঃ
(১) ট্রেন্ডের দিকনির্দেশনা নির্ধারণ এবং মৌলিক ক্রয়/বিক্রয় সংকেত উৎপন্ন করার জন্য পিএসএআর।
(2) সিগন্যালের দিকনির্দেশনা নিশ্চিত করার জন্য জিগজ্যাগ।
(3) ব্রেকআউট সনাক্ত করে সংকেত যাচাই করার জন্য বোলিংজার ব্যান্ড।
(4) সিগন্যালগুলিকে আরও বৈধ করতে এবং নির্ভুলতা উন্নত করতে MACD।
(5) ট্রেড প্রতি ঝুঁকি নিয়ন্ত্রণের জন্য গতিশীল স্টপ লস গণনা করার জন্য ATR।
(৬) সংশ্লেষিত সংকেত ও মানদণ্ডের উপর ভিত্তি করে ট্রেড শুরু করা।
সমস্ত সূচক একমত হলেই ট্রেড করা হয়, যা মিথ্যা সংকেতগুলি ফিল্টার করে এবং নির্ভুলতা উন্নত করে। এটিআর-ভিত্তিক স্টপ লস এছাড়াও প্রতিটি ট্রেডের জন্য ঝুঁকি নিয়ন্ত্রণ নিশ্চিত করে।
২. কৌশলটির সুবিধা
সবচেয়ে বড় সুবিধা হল একাধিক সূচক দিয়ে সংকেত যাচাই করা, একক সূচকগুলির সীমাবদ্ধতা এড়ানো এবং নির্ভরযোগ্যতা উন্নত করা।
এছাড়াও, গতিশীল স্টপ লস পদ্ধতিটিও একটি প্রধান সুবিধা। এটি প্রাকটিক্যাল ঝুঁকি নিয়ন্ত্রণের জন্য বাজারের অস্থিরতার উপর ভিত্তি করে যুক্তিসঙ্গত স্টপ লস স্তর নির্ধারণ করে।
অবশেষে, একাধিক সূচক সংমিশ্রণ কৌশল দক্ষতা আরও উন্নত করার জন্য সমৃদ্ধ পরামিতি সুরক্ষা স্থান প্রদান করে।
III. সম্ভাব্য ঝুঁকি
যাইহোক, নিম্নলিখিত ঝুঁকিগুলিও লক্ষ্য করা উচিতঃ
প্রথমত, একাধিক সূচকগুলির জটিলতা অপ্টিমাইজেশান অসুবিধা বৃদ্ধি করে। ভুল সেটিংস ওভারফিটিং হতে পারে।
দ্বিতীয়ত, স্টপ লস সেট করা খুব কাছাকাছি হলে ঝুঁকি থাকে যে, স্টপ লসটি অকাল বন্ধ হয়ে যাবে এবং ক্ষতি বাড়বে।
অবশেষে, সূচক সংকেতগুলির মধ্যে অসঙ্গতি দেখা দিতে পারে, যার জন্য স্পষ্ট অগ্রাধিকার নিয়ম প্রয়োজন।
IV. সংক্ষিপ্ত বিবরণ
সংক্ষেপে, এই নিবন্ধটি মাল্টি-ইন্ডিকেটর নিশ্চিতকরণ এবং ঝুঁকি নিয়ন্ত্রণ ব্যবহার করে একটি পরিমাণগত ট্রেডিং কৌশল ব্যাখ্যা করেছে। এটি বুদ্ধিমানভাবে যাচাইকরণ এবং ঝুঁকি ব্যবস্থাপনার জন্য সূচকগুলিকে একত্রিত করে। তবে প্যারামিটার অপ্টিমাইজেশনের অসুবিধা সম্পূর্ণরূপে স্বীকৃত হওয়া উচিত এবং খুব শক্ত হওয়ার ঝুঁকি প্রতিরোধ করা উচিত। সামগ্রিকভাবে, এটি একটি অপেক্ষাকৃত শক্তিশালী পরিমাণগত ট্রেডিং পদ্ধতি সরবরাহ করে।
/*backtest start: 2023-09-06 00:00:00 end: 2023-09-08 09:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © Rolan_Kruger //@version=5 strategy("PSAR BBPT ZLSMA","PBZ", overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100) /////////////////////////////////////////////////////////////////////////////////////////////////////// // PSAR BUY/SELL start = input.float(title='Start', step=0.00005, defval=0.05, group = "PSAR") increment = input.float(title='Increment', step=0.00005, defval=0.05, group = "PSAR") maximum = input.float(title='Maximum', step=0.01, defval=0.13, group = "PSAR") width = input.int(title='Point Width', minval=1, defval=20, group = "PSAR") highlightStartPoints = input(title='Highlight Start Points ?', defval=false, group = "PSAR") psar = ta.sar(start, increment, maximum) dir = psar < close ? 1 : -1 psarColor = psar < close ? #3388bb : #fdcc02 plotshape(dir == 1 and dir[1] == -1 and highlightStartPoints ? psar : na, title='Buy', style=shape.labelup, location=location.absolute, size=size.normal, text='Buy', textcolor=color.new(color.white, 0), color=color.new(color.green, 0)) plotshape(dir == -1 and dir[1] == 1 and highlightStartPoints ? psar : na, title='Sell', style=shape.labeldown, location=location.absolute, size=size.normal, text='Sell', textcolor=color.new(color.white, 0), color=color.new(color.red, 0)) barcolor(dir == 1 ? color.green : color.red, display = display.none) PSAR_Buy = dir == 1 and dir[1] == -1 PSAR_Sell = dir == -1 and dir[1] == 1 //////////////////////////////////////////////////////////////////////////////////////////////////////// // ZLSMA length = input(title='Length', defval=50,group = "ZLSMA") offset = input(title='Offset', defval=0,group = "ZLSMA") src = input(close, title='Source',group = "ZLSMA") lsma = ta.linreg(src, length, offset) lsma2 = ta.linreg(lsma, length, offset) eq = lsma - lsma2 zlsma = lsma + eq plot(zlsma, color=color.new(color.yellow, 0), linewidth=3) ZLSMA_Buy = close > zlsma and open > zlsma and low > zlsma and high > zlsma ZLSMA_Sell = close < zlsma and open < zlsma and low < zlsma and high < zlsma //////////////////////////////////////////////////////////////////////////////////////////////////////// // BBPT // switch_bbpt = input.bool(false, "Switch BBPT conditionals",group ="Bull Bear Power Trend") length1 = 8 // BullTrend_hist = 0.0 BearTrend_hist = 0.0 BullTrend = (close - ta.lowest(low, 50)) / ta.atr(5) BearTrend = (ta.highest(high, 50) - close) / ta.atr(5) BearTrend2 = -1 * BearTrend Trend = BullTrend - BearTrend if BullTrend < 2 BullTrend_hist := BullTrend - 2 BullTrend_hist if BearTrend2 > -2 BearTrend_hist := BearTrend2 + 2 BearTrend_hist //alexgrover-Regression Line Formula x = bar_index y = Trend x_ = ta.sma(x, length1) y_ = ta.sma(y, length1) mx = ta.stdev(x, length1) my = ta.stdev(y, length1) c = ta.correlation(x, y, length1) slope = c * (my / mx) inter = y_ - slope * x_ reg_trend = x * slope + inter // BBPT_Buy = BearTrend_hist BBPT_Sell = BullTrend_hist if switch_bbpt BBPT_Buy := BullTrend_hist BBPT_Sell := BearTrend_hist /////////////////////////////////////////////////////////////////////////////////////////////////////// // Sessions enable_sessions = input.bool(false, "Enable Sessions for strategy", group = "Sessions") bgColor = input.bool(false, "Activate High/Low View", group = "Sessions") LondonColor = color.new(color.green, 90) NYColor = color.new(color.red, 90) AsiaColor = color.new(color.yellow, 90) SydneyColor = color.new(color.blue, 90) ///Sessions res = input.timeframe("D", "Resolution", ["D","W","M"], group = "Sessions") london = input("0300-1200:1234567", "London Session", group = "Sessions") ny = input("0800-1700:1234567", "New York Session", group = "Sessions") tokyo = input("2000-0400:1234567", "Tokyo Session", group = "Sessions") sydney = input("1700-0200:1234567", "Sydney Session", group = "Sessions") //Bars is_newbar(sess) => t = time(res, sess, "America/New_York") na(t[1]) and not na(t) or t[1] < t is_session(sess) => not na(time(timeframe.period, sess, "America/New_York")) //London London = input.bool(false, "London Session") londonNewbar = is_newbar(london) londonSession = is_session(london) float londonLow = na londonLow := if londonSession if londonNewbar low else math.min(londonLow[1],low) else londonLow float londonHigh = na londonHigh := if londonSession if londonNewbar high else math.max(londonHigh[1],high) else londonHigh plotLL = plot(londonLow, color=color.new(#000000, 100)) plotLH = plot(londonHigh, color=color.new(#000000, 100)) fill(plotLL, plotLH, color = londonSession and London and bgColor ? LondonColor : na) bgcolor(londonSession and London and not bgColor ? LondonColor : na) //New York NY = input.bool(false, "New York Session") nyNewbar = is_newbar(ny) nySession = is_session(ny) float nyLow = na nyLow := if nySession if nyNewbar low else math.min(nyLow[1],low) else nyLow float nyHigh = na nyHigh := if nySession if nyNewbar high else math.max(nyHigh[1],high) else nyHigh plotNYL = plot(nyLow, color=color.new(#000000, 100)) plotNYH = plot(nyHigh, color=color.new(#000000, 100)) fill(plotNYL, plotNYH, color = nySession and NY and bgColor ? NYColor : na) bgcolor(nySession and NY and not bgColor ? NYColor : na) //Tokyo Tokyo = input.bool(false, "Tokyo Session") tokyoNewbar = is_newbar(tokyo) tokyoSession = is_session(tokyo) float tokyoLow = na tokyoLow := if tokyoSession if tokyoNewbar low else math.min(tokyoLow[1],low) else tokyoLow float tokyoHigh = na tokyoHigh := if tokyoSession if tokyoNewbar high else math.max(tokyoHigh[1],high) else tokyoHigh plotTL = plot(tokyoLow, color=color.new(#000000, 100)) plotTH = plot(tokyoHigh, color=color.new(#000000, 100)) fill(plotTL, plotTH, color = tokyoSession and Tokyo and bgColor ? AsiaColor : na) bgcolor(tokyoSession and Tokyo and not bgColor ? AsiaColor : na) //Sydney Sydney = input.bool(false, "Sydney Session") sydneyNewbar = is_newbar(sydney) sydneySession = is_session(sydney) float sydneyLow = na sydneyLow := if sydneySession if sydneyNewbar low else math.min(sydneyLow[1],low) else sydneyLow float sydneyHigh = na sydneyHigh := if sydneySession if sydneyNewbar high else math.max(sydneyHigh[1],high) else sydneyHigh plotSL = plot(sydneyLow, color=color.new(#000000, 100)) plotSH = plot(sydneyHigh, color=color.new(#000000, 100)) fill(plotSL, plotSH, color = sydneySession and Sydney and bgColor ? SydneyColor : na) bgcolor(sydneySession and Sydney and not bgColor ? SydneyColor : na) London_ok = London and londonSession NY_ok = NY and nySession Tokyo_ok = Tokyo and tokyoSession Sydney_ok = Sydney and sydneySession in_session = true if London_ok or NY_ok or Tokyo_ok or Sydney_ok and enable_sessions in_session := true else if enable_sessions == true in_session := false /////////////////////////////////////////////////////////////////////////////////////////////////////// // EMA Filter ema_filter = input.bool(false, "Enable EMA filter", group = "EMA") ema_lenght = input.int(50, "EMA lenght", group = "EMA") ema1 = ta.ema(close, ema_lenght) plot(ema1, "EMA", color.white, 3) EMA_Buy = true EMA_Sell = true if ema_filter == true EMA_Buy := close > ema1 EMA_Sell := ema1 > close /////////////////////////////////////////////////////////////////////////////////////////////////////// // ZLSMA angle calc zlsma_angle_filter = input.bool(true, "ZLSMA angle filter", group = "ZLSMA") ZLSMA_Up = true ZLSMA_Down = true if zlsma_angle_filter == true ZLSMA_Up := 1 < (zlsma - zlsma[1]) ZLSMA_Down := -1 > (zlsma - zlsma[1]) /////////////////////////////////////////////////////////////////////////////////////////////////////// // SL/TP // Assumes quote currency is FIAT as with BTC/USDT pair max_sl = input.float(0.2, "Max SL size in %", group = "SL/TP", minval = 0.1, tooltip = "Cancels trade if SL is too big" ) zlsma_offset = input.float(0.02, title="ZLSMA SL offset in %", group = "SL/TP",maxval = 1) tp1_multi = input.float(1, title="TP 1 multiplier", group = "SL/TP") tp2_multi = input.float(2, title="TP 2 multiplier", group = "SL/TP") tp1_persentage = input.float(0.001, "Persentage of trade close on TP1", group ="SL/TP", maxval = 100, minval = 0.001) // SL too big check sl_check = ((math.abs(close - zlsma))/close * 100) + zlsma_offset sl_ok = true if sl_check > max_sl sl_ok := false // ZLSMA SL and TP not_in_trade = strategy.position_size == 0 check_if_long = PSAR_Buy and ZLSMA_Buy and BBPT_Buy and EMA_Buy and ZLSMA_Up and sl_ok and in_session check_if_short = PSAR_Sell and ZLSMA_Sell and BBPT_Sell and EMA_Sell and ZLSMA_Down and sl_ok and in_session var float sl = 0.0 var float tp1 = 0.0 var float tp2 = 0.0 if check_if_long and not_in_trade sl := ((close - zlsma)/close * 100) + zlsma_offset tp1 := (((close - zlsma)/close * 100) + zlsma_offset)*tp1_multi tp2 := (((close - zlsma)/close * 100) + zlsma_offset)*tp2_multi if check_if_short and not_in_trade sl := ((zlsma - close)/close * 100) + zlsma_offset tp1 := (((zlsma - close)/close * 100) + zlsma_offset)*tp1_multi tp2 := (((zlsma - close)/close * 100) + zlsma_offset)*tp2_multi // FUNCTIONS // Stochastic f_stochastic() => stoch = ta.stoch(close, high, low, 14) stoch_K = ta.sma(stoch, 3) stoch_D = ta.sma(stoch_K, 3) stRD = ta.crossunder(stoch_K, stoch_D) stGD = ta.crossover(stoch_K, stoch_D) [stoch_K, stoch_D, stRD, stGD] // VARIABLES [bbMiddle, bbUpper, bbLower] = ta.bb(close, 20, 2) [stoch_K, stoch_D, stRD, stGD] = f_stochastic() // ORDERS // Active Orders // Check if strategy has open positions inLong = strategy.position_size > 0 inShort = strategy.position_size < 0 // Check if strategy reduced position size in last bar longClose = strategy.position_size < strategy.position_size[1] shortClose = strategy.position_size > strategy.position_size[1] // Entry Conditions // Enter long when during last candle these conditions are true: // Candle high is greater than upper Bollinger Band // Stochastic K line crosses under D line and is oversold longCondition = PSAR_Buy and ZLSMA_Buy and BBPT_Buy and EMA_Buy and ZLSMA_Up and sl_ok and in_session // Enter short when during last candle these conditions are true: // Candle low is lower than lower Bollinger Band // Stochastic K line crosses over D line and is overbought shortCondition = PSAR_Sell and ZLSMA_Sell and BBPT_Sell and EMA_Sell and ZLSMA_Down and sl_ok and in_session // Exit Conditions // Calculate Take Profit longTP1 = strategy.position_avg_price * ((100 + tp1)/100) longTP2 = strategy.position_avg_price * ((100 + tp2)/100) shortTP1 = strategy.position_avg_price * ((100 - tp1)/100) shortTP2 = strategy.position_avg_price * ((100 - tp2)/100) // Calculate Stop Loss // Initialise variables var float longSL = 0.0 var float shortSL = 0.0 // When not in position, set stop loss using close price which is the price used during backtesting // When in a position, check to see if the position was reduced on the last bar // If it was, set stop loss to position entry price. Otherwise, maintain last stop loss value longSL := if inLong and ta.barssince(longClose) < ta.barssince(longCondition) strategy.position_avg_price else if inLong longSL[1] else close * ((100 - sl)/100) shortSL := if inShort and ta.barssince(shortClose) < ta.barssince(shortCondition) strategy.position_avg_price else if inShort shortSL[1] else close * ((100 + sl)/100) //////////////////////////////////////////////////////////////////////////////////////////////////////// // STRATEGY EXECUTION // Manage positions if not_in_trade and longCondition strategy.entry("Long", strategy.long) strategy.exit("TP1/SL", from_entry="Long", qty_percent=tp1_persentage, limit=longTP1, stop=longSL) strategy.exit("TP2/SL", from_entry="Long", limit=longTP2, stop=longSL) if not_in_trade and shortCondition strategy.entry("Short", strategy.short) strategy.exit("TP1/SL", from_entry="Short", qty_percent=tp1_persentage, limit=shortTP1, stop=shortSL) strategy.exit("TP2/SL", from_entry="Short", limit=shortTP2, stop=shortSL)