
বুলিং-ব্রেকিং কৌশলটি একটি বুলিং-ব্রেকিং সূচকের উপর ভিত্তি করে একটি স্বল্পমেয়াদী প্রবণতা-অনুসরণকারী কৌশল। এটি একাধিক এবং শূন্যপদ উভয় দিকের অপারেশন সম্পাদন করতে পারে। এটি নগদ এবং স্থায়ী চুক্তির জন্য প্রযোজ্য, বিশেষত প্রবণতার ক্ষেত্রে।
এই কৌশলটি অত্যন্ত কনফিগারযোগ্য, যা ব্যবহারকারীকে ব্রেন্ডের প্যারামিটার সময়কাল এবং বিচ্যুতি, প্রবণতা ফিল্টার, অস্থিরতা ফিল্টার, লেনদেনের দিকনির্দেশ ফিল্টার, পরিবর্তন হার ফিল্টার এবং তারিখ ফিল্টার ইত্যাদি সেট করতে দেয়। উপরন্তু, এটি মাল্টি-হেড এবং খালি-হেড পজিশনের জন্য স্টপ লস, স্টপ লস এবং ট্র্যাকিং স্টপ লস সেট করে, যা একটি বিস্তৃত ঝুঁকি ব্যবস্থাপনার পদ্ধতি নিশ্চিত করে। প্রতিদিনের সর্বাধিক ক্ষতির সাথে যুক্ত হওয়া আরও একটি স্তর সুরক্ষা সরবরাহ করে, এটি একটি নির্ভরযোগ্য পেশাদার স্ব-অনুশীলিত ট্রেডিং সিস্টেম করে।
এই কৌশলটির কেন্দ্রীয় সূচক হ’ল বুলিন ব্যান্ড। বুলিন ব্যান্ডটি মধ্যম, উপরের এবং নীচের ট্র্যাকের তিনটি রেখার সমন্বয়ে গঠিত, যা দামের গড় রেখা, ওঠানামা এবং ওঠানামার নীচের সীমাকে উপস্থাপন করে। যখন দাম উর্ধ্বমুখী হয়, তখন বেশি করুন; যখন দাম নীচের দিকে যায়, তখন খালি করুন।
নয়েজ লেনদেন এড়ানোর জন্য নীতিটি বেশ কয়েকটি সহায়ক ফিল্টারও সেট করেছে। এই ফিল্টারগুলির মধ্যে রয়েছেঃ
প্রবণতা ফিল্টারঃ মুভিং এভারেজের উপরে দাম বেশি, মুভিং এভারেজের নিচে দাম কম;
অস্থিরতা ফিল্টারঃ শুধুমাত্র যখন অস্থিরতা বৃদ্ধি পায় তখনই ট্রেড করুন;
ট্রেডিং দিকনির্দেশনা ফিল্টারঃ ট্রেডিং-এ-অধিক, ট্রেডিং-এ-খুব কম বা দ্বি-মুখী ট্রেডিংয়ের বিকল্পগুলি চিহ্নিতকরণের বৈশিষ্ট্য অনুসারে;
পরিবর্তনের হার ফিল্টারঃ যখন পূর্ববর্তী ট্রেডিং দিনের শেষের দামের তুলনায় দামের পরিবর্তনের হার একটি নির্দিষ্ট স্তরে পৌঁছে যায় তখনই প্রবেশ করা হয়;
তারিখ ফিল্টারঃ পুনরুদ্ধারের সময়সীমা সেট করুন।
সমস্ত ফিল্টার শর্ত পূরণ হলে ট্রেডিং সিগন্যাল উৎপন্ন করা হয়। স্টপ, স্টপ লস এবং ট্র্যাকিং স্টপ লস ঝুঁকি ব্যবস্থাপনা নিশ্চিত করে। এছাড়াও, সর্বোচ্চ দৈনিক ক্ষতির সেটিংটি এক দিনের মধ্যে ব্যাপক প্রত্যাহার এড়াতে পারে।
এই কৌশলটির সুবিধাগুলো হলঃ
এই প্রাপ্তবয়স্ক সূচকটি ব্রিন ব্যান্ডকে কেন্দ্রীয় ট্রেডিং সিগন্যাল হিসেবে ব্যবহার করে, যা অত্যন্ত নির্ভরযোগ্য।
মাল্টি-ফিল্টার ডিজাইনটি ভুল লেনদেন এড়াতে এবং কনফিগারযোগ্য;
স্টপ, স্টপ লস এবং ট্র্যাকিং স্টপ লস ব্যাপক এবং নমনীয়;
সর্বোচ্চ দৈনিক ক্ষতি সেট করুন কার্যকর নিয়ন্ত্রণ ওয়ান ডে প্রত্যাহার
ট্রেন্ডিং মার্কেটের জন্য উপযুক্ত, লাভের সম্ভাবনা অনেক বেশি।
এই কৌশলটি কিছু ঝুঁকি নিয়েও এসেছেঃ
ব্রিন ব্রেন্ডের ব্রেকডাউনগুলি মাথা এবং নীচের ব্রেকডাউনগুলির জন্য সহজ, যা ক্ষতির কারণ হতে পারে;
মার্কেটে, ফিল্টারগুলি খুব কঠোর হতে পারে এবং ট্রেডিংয়ের সুযোগগুলি মিস করতে পারে।
বড় ধরনের উড়োজাহাজের ক্ষতি হতে পারে, যা সরাসরি স্টপ লিনিয়ার অতিক্রম করতে পারে;
এই ধরনের পরিস্থিতিতে, বিপুল পরিমাণ ক্ষতি সম্পূর্ণরূপে এড়ানো সম্ভব নয়।
উপরোক্ত ঝুঁকির জন্য, ফিল্টারিংয়ের শর্তগুলি যথাযথভাবে শিথিল করা যেতে পারে, বা কিছু পজিশন বন্ধ করতে, স্টপ লস দূরত্ব হ্রাস করতে ইত্যাদি হস্তক্ষেপ করা যেতে পারে।
এই কৌশলটি নিম্নলিখিত দিকগুলি থেকে অপ্টিমাইজ করা যেতে পারেঃ
বিভিন্ন প্যারামিটার সমন্বয় চেষ্টা করুন এবং সর্বোত্তম প্যারামিটার ব্যাপ্তি খুঁজুন।
মেশিন লার্নিং মডেল যুক্ত করা, প্যারামিটারগুলির গতিশীল অপ্টিমাইজেশন করা;
সময় ও ভোল্টেজ ক্ষতির মতো আরও কার্যকর পদ্ধতির উপর গবেষণা করা;
তিনি বলেন, “এটি এমন একটি বিষয় যে, আমরা আমাদের দেশের জনগণের জন্য কিছু করতে পারি।
পরিসংখ্যানগত অ্যারেটেজ, সংশ্লিষ্ট পণ্যের সাথে মিলিত।
বুলিন ব্রেড ব্রেকিং কৌশলটি একটি পরিপক্ক এবং নির্ভরযোগ্য সংক্ষিপ্ত লাইন ট্রেন্ড অনুসরণ কৌশল। এটি বুলিন ব্রেড সূচককে সংকেত হিসাবে গ্রহণ করে এবং একাধিক ফিল্টার সেট করে যা সংকেতের নির্ভরযোগ্যতা নিশ্চিত করে। একই সাথে, একটি বিস্তৃত স্টপ লস এবং ঝুঁকি নিয়ন্ত্রণ ব্যবস্থা ঝুঁকি নিয়ন্ত্রণ করে। এই কৌশলটি সক্রিয় ট্রেন্ডিং বাজারের জন্য উপযুক্ত, ভাল আয় সম্ভাবনা রয়েছে। ক্রমাগত অপ্টিমাইজেশনের মাধ্যমে, এটি একটি শক্তিশালী পরিমাণযুক্ত ট্রেডিং সিস্টেম হওয়ার সম্ভাবনা রয়েছে।
/*backtest
start: 2022-11-22 00:00:00
end: 2023-11-04 05:20:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Bollinger Bands - Breakout Strategy",overlay=true
)
// Define the length of the Bollinger Bands
bbLengthInput = input.int (15,title="Length", group="Bollinger Bands", inline="BB")
bbDevInput = input.float (2.0,title="StdDev", group="Bollinger Bands", inline="BB")
// Define the settings for the Trend Filter
trendFilterInput = input.bool(false, title="Above/Below", group = "Trend Filter", inline="Trend")
trendFilterPeriodInput = input(223,title="", group = "Trend Filter", inline="Trend")
trendFilterType = input.string (title="", defval="EMA",options=["EMA","SMA","RMA", "WMA"], group = "Trend Filter", inline="Trend")
volatilityFilterInput = input.bool(true,title="StdDev", group = "Volatility Filter", inline="Vol")
volatilityFilterStDevLength = input(15,title="",group = "Volatility Filter", inline="Vol")
volatilityStDevMaLength = input(15,title=">MA",group = "Volatility Filter", inline="Vol")
// ROC Filter
// f_security function by LucF for PineCoders available here: https://www.tradingview.com/script/cyPWY96u-How-to-avoid-repainting-when-using-security-PineCoders-FAQ/
f_security(_sym, _res, _src, _rep) => request.security(_sym, _res, _src[not _rep and barstate.isrealtime ? 1 : 0])[_rep or barstate.isrealtime ? 0 : 1]
high_daily = f_security(syminfo.tickerid, "D", high, false)
roc_enable = input.bool(false, "", group="ROC Filter from CloseD", inline="roc")
roc_threshold = input.float(1, "Treshold", step=0.5, group="ROC Filter from CloseD", inline="roc")
closed = f_security(syminfo.tickerid,"1D",close, false)
roc_filter= roc_enable ? (close-closed)/closed*100 > roc_threshold : true
// Trade Direction Filter
// tradeDirectionInput = input.string("Auto",options=["Auto", "Long&Short","Long Only", "Short Only"], title="Trade", group="Direction Filter", tooltip="Auto: if a PERP is detected (in the symbol description), trade long and short\n Otherwise as per user-input")
// tradeDirection = switch tradeDirectionInput
// "Auto" => str.contains(str.lower(syminfo.description), "perp") or str.contains(str.lower(syminfo.description), ".p") ? strategy.direction.all : strategy.direction.long
// "Long&Short" => strategy.direction.all
// "Long Only" => strategy.direction.long
// "Short Only" => strategy.direction.short
// => strategy.direction.all
// strategy.risk.allow_entry_in(tradeDirection)
// Calculate and plot the Bollinger Bands
[bbMiddle, bbUpper, bbLower] = ta.bb (close, bbLengthInput, bbDevInput)
plot(bbMiddle, "Basis", color=color.orange)
bbUpperPlot = plot(bbUpper, "Upper", color=color.blue)
bbLowerrPlot = plot(bbLower, "Lower", color=color.blue)
fill(bbUpperPlot, bbLowerrPlot, title = "Background", color=color.new(color.blue, 95))
// Calculate and view Trend Filter
float tradeConditionMa = switch trendFilterType
"EMA" => ta.ema(close, trendFilterPeriodInput)
"SMA" => ta.sma(close, trendFilterPeriodInput)
"RMA" => ta.rma(close, trendFilterPeriodInput)
"WMA" => ta.wma(close, trendFilterPeriodInput)
// Default used when the three first cases do not match.
=> ta.wma(close, trendFilterPeriodInput)
trendConditionLong = trendFilterInput ? close > tradeConditionMa : true
trendConditionShort = trendFilterInput ? close < tradeConditionMa : true
plot(trendFilterInput ? tradeConditionMa : na, color=color.yellow)
// Calculate and view Volatility Filter
stdDevClose = ta.stdev(close,volatilityFilterStDevLength)
volatilityCondition = volatilityFilterInput ? stdDevClose > ta.sma(stdDevClose,volatilityStDevMaLength) : true
bbLowerCrossUnder = ta.crossunder(close, bbLower)
bbUpperCrossOver = ta.crossover(close, bbUpper)
bgcolor(volatilityCondition ? na : color.new(color.red, 95))
// Date Filter
start = input(timestamp("2017-01-01"), "Start", group="Date Filter")
finish = input(timestamp("2050-01-01"), "End", group="Date Filter")
date_filter = true
// Entry and Exit Conditions
entryLongCondition = bbUpperCrossOver and trendConditionLong and volatilityCondition and date_filter and roc_filter
entryShortCondition = bbLowerCrossUnder and trendConditionShort and volatilityCondition and date_filter and roc_filter
exitLongCondition = bbLowerCrossUnder
exitShortCondition = bbUpperCrossOver
// Orders
if entryLongCondition
strategy.entry("EL", strategy.long)
if entryShortCondition
strategy.entry("ES", strategy.short)
if exitLongCondition
strategy.close("EL")
if exitShortCondition
strategy.close("ES")
// Long SL/TP/TS
xl_ts_percent = input.float(2,step=0.5, title= "TS", group="Exit Long", inline="LTS", tooltip="Trailing Treshold %")
xl_to_percent = input.float(0.5, step=0.5, title= "TO", group="Exit Long", inline="LTS", tooltip="Trailing Offset %")
xl_ts_tick = xl_ts_percent * close/syminfo.mintick/100
xl_to_tick = xl_to_percent * close/syminfo.mintick/100
xl_sl_percent = input.float (2, step=0.5, title="SL",group="Exit Long", inline="LSLTP")
xl_tp_percent = input.float(9, step=0.5, title="TP",group="Exit Long", inline="LSLTP")
xl_sl_price = strategy.position_avg_price * (1-xl_sl_percent/100)
xl_tp_price = strategy.position_avg_price * (1+xl_tp_percent/100)
strategy.exit("XL+SL/TP", "EL", stop=xl_sl_price, limit=xl_tp_price, trail_points=xl_ts_tick, trail_offset=xl_to_tick,comment_loss= "XL-SL", comment_profit = "XL-TP",comment_trailing = "XL-TS")
// Short SL/TP/TS
xs_ts_percent = input.float(2,step=0.5, title= "TS",group="Exit Short", inline ="STS", tooltip="Trailing Treshold %")
xs_to_percent = input.float(0.5, step=0.5, title= "TO",group="Exit Short", inline ="STS", tooltip="Trailing Offset %")
xs_ts_tick = xs_ts_percent * close/syminfo.mintick/100
xs_to_tick = xs_to_percent * close/syminfo.mintick/100
xs_sl_percent = input.float (2, step=0.5, title="SL",group="Exit Short", inline="ESSLTP", tooltip="Stop Loss %")
xs_tp_percent = input.float(9, step=0.5, title="TP",group="Exit Short", inline="ESSLTP", tooltip="Take Profit %")
xs_sl_price = strategy.position_avg_price * (1+xs_sl_percent/100)
xs_tp_price = strategy.position_avg_price * (1-xs_tp_percent/100)
strategy.exit("XS+SL/TP", "ES", stop=xs_sl_price, limit=xs_tp_price, trail_points=xs_ts_tick, trail_offset=xs_to_tick,comment_loss= "XS-SL", comment_profit = "XS-TP",comment_trailing = "XS-TS")
max_intraday_loss = input.int(10, title="Max Intraday Loss (Percent)", group="Risk Management")
//strategy.risk.max_intraday_loss(max_intraday_loss, strategy.percent_of_equity)
// Monthly Returns table, modified from QuantNomad. Please put calc_on_every_tick = true to plot it.
monthly_table(int results_prec, bool results_dark) =>
new_month = month(time) != month(time[1])
new_year = year(time) != year(time[1])
eq = strategy.equity
bar_pnl = eq / eq[1] - 1
cur_month_pnl = 0.0
cur_year_pnl = 0.0
// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 :
(1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1
// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 :
(1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
// Arrays to store Yearly and Monthly P&Ls
var month_pnl = array.new_float(0)
var month_time = array.new_int(0)
var year_pnl = array.new_float(0)
var year_time = array.new_int(0)
last_computed = false
if (not na(cur_month_pnl[1]) and (new_month or barstate.islast))
if (last_computed[1])
array.pop(month_pnl)
array.pop(month_time)
array.push(month_pnl , cur_month_pnl[1])
array.push(month_time, time[1])
if (not na(cur_year_pnl[1]) and (new_year or barstate.islast))
if (last_computed[1])
array.pop(year_pnl)
array.pop(year_time)
array.push(year_pnl , cur_year_pnl[1])
array.push(year_time, time[1])
last_computed := barstate.islast ? true : nz(last_computed[1])
// Monthly P&L Table
var monthly_table = table(na)
cell_hr_bg_color = results_dark ? #0F0F0F : #F5F5F5
cell_hr_text_color = results_dark ? #D3D3D3 : #555555
cell_border_color = results_dark ? #000000 : #FFFFFF
// ell_hr_bg_color = results_dark ? #0F0F0F : #F5F5F5
// cell_hr_text_color = results_dark ? #D3D3D3 : #555555
// cell_border_color = results_dark ? #000000 : #FFFFFF
if (barstate.islast)
monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, bgcolor=cell_hr_bg_color,border_width=1,border_color=cell_border_color)
table.cell(monthly_table, 0, 0, syminfo.tickerid + " " + timeframe.period, text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 1, 0, "Jan", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 2, 0, "Feb", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 3, 0, "Mar", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 4, 0, "Apr", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 5, 0, "May", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 6, 0, "Jun", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 7, 0, "Jul", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 8, 0, "Aug", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 9, 0, "Sep", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 10, 0, "Oct", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 11, 0, "Nov", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 12, 0, "Dec", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
table.cell(monthly_table, 13, 0, "Year", text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
for yi = 0 to array.size(year_pnl) - 1
table.cell(monthly_table, 0, yi + 1, str.tostring(year(array.get(year_time, yi))), text_color=cell_hr_text_color, bgcolor=cell_hr_bg_color)
y_color = array.get(year_pnl, yi) > 0 ? color.lime : array.get(year_pnl, yi) < 0 ? color.red : color.gray
table.cell(monthly_table, 13, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100, results_prec)), bgcolor = y_color)
for mi = 0 to array.size(month_time) - 1
m_row = year(array.get(month_time, mi)) - year(array.get(year_time, 0)) + 1
m_col = month(array.get(month_time, mi))
m_color = array.get(month_pnl, mi) > 0 ? color.lime : array.get(month_pnl, mi) < 0 ? color.red : color.gray
table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100, results_prec)), bgcolor = m_color)
results_prec = input(2, title = "Precision", group="Results Table")
results_dark = input.bool(defval=true, title="Dark Mode", group="Results Table")
monthly_table(results_prec, results_dark)