Bollinger Bands Breakout Strategy کے بعد قلیل مدتی رجحان

مصنف:چاؤ ژانگ، تاریخ: 2023-11-23 17:01:12
ٹیگز:

img

جائزہ

بولنگر بینڈز بریکآؤٹ حکمت عملی ایک قلیل مدتی رجحان کی پیروی کرنے والی حکمت عملی ہے جو کرپٹو ٹریڈنگ کے لئے موزوں ہے۔ یہ اچھی طرح سے قائم بولنگر بینڈز اشارے کو بنیادی سگنل جنریٹر کے طور پر استعمال کرتا ہے اور طویل اور مختصر پوزیشنیں لینے کے قابل ہے۔ جامع رسک مینجمنٹ میکانزم کے ساتھ ، یہ رجحان سازی کی منڈیوں کے لئے موزوں ایک مضبوط خودکار تجارتی نظام ہے۔

اس حکمت عملی میں اعلی سطح کی تشکیل کی اہلیت ہے ، جس میں بولنگر بینڈ پیرامیٹرز ، مختلف فلٹرز ، منافع / اسٹاپ نقصان کی ترتیبات اور زیادہ سے زیادہ دن کے اندر نقصان کی حد شامل ہے۔ یہ موافقت حکمت عملی کو مختلف مارکیٹ کے نظام میں قابل اعتماد کارکردگی حاصل کرنے کے قابل بناتی ہے۔

یہ کیسے کام کرتا ہے

حکمت عملی بولنگر بینڈ اشارے کے گرد مرکوز ہے ، جو ایک درمیانی بینڈ ، ایک اوپری بینڈ اور ایک نچلی بینڈ کا حساب لگاتا ہے جو قیمت کی اوسط اور اتار چڑھاؤ کی حدود کے لئے پراکسی کی حیثیت سے کام کرتا ہے۔ اوپری یا نچلی بینڈ پر قیمت کا عبور داخلہ سگنل generates طویل پیدا کرتا ہے جب قیمت اوپری بینڈ سے اوپر ٹوٹ جاتی ہے ، کم بینڈ سے نیچے ٹوٹ جاتی ہے۔

اس کے علاوہ، جھوٹے سگنل سے بچنے کے لئے متعدد فلٹرز لاگو ہوتے ہیں:

  1. رجحان فلٹر: چلتی اوسط سے اوپر طویل، چلتی اوسط سے نیچے مختصر

  2. اتار چڑھاؤ فلٹر: صرف تب ہی تجارت کریں جب اتار چڑھاؤ بڑھ جائے

  3. سمت فلٹر: صرف لمبی، صرف مختصر یا دونوں سمتوں کے لئے ترتیب دینے کے قابل

  4. شرح تبدیلی فلٹر: پچھلے بند سے کافی قیمت کی نقل و حرکت کی ضرورت ہے

  5. تاریخ فلٹر: بیک ٹسٹنگ ٹائم فریم کی تفصیلات

منافع حاصل کرنے ، نقصان کو روکنے اور نقصانات کو محدود کرنے کے لئے ٹریلنگ اسٹاپ میکانزم کے ذریعہ باہر نکلنے کا انتظام کیا جاتا ہے۔ زیادہ سے زیادہ دن کے اندر نقصان کی حد روزانہ ڈراؤنڈ تحفظ کی ایک اور پرت فراہم کرتی ہے۔

فوائد

اس حکمت عملی کے اہم فوائد میں شامل ہیں:

  1. بنیادی سگنل کے طور پر قابل اعتماد بولنگر بینڈ اشارے

  2. اپنی مرضی کے مطابق فلٹرز ناپسندیدہ تجارت کو روکتے ہیں

  3. سٹاپ نقصان/فائدہ حاصل کرنے کا جامع ڈیزائن

  4. زیادہ سے زیادہ دن کے اندر نقصانات کے خلاف تحفظات

  5. منافع کی صلاحیت کے ساتھ رجحان سازی مارکیٹوں میں ترقی کرتا ہے

خطرات

فوائد کے باوجود، کچھ خطرات باقی ہیں:

  1. بولنگر بینڈ کے ارد گرد وِپساؤ نقصانات کا باعث بن سکتا ہے

  2. بہت سخت فلٹرز رینج سے منسلک مارکیٹوں میں تجارت کو کم کرتے ہیں

  3. خلائی پیشگی طور پر پوزیشنوں کو روک سکتے ہیں

  4. انتہائی نقل و حرکت سے مکمل طور پر گریز نہیں کیا جا سکتا

تخفیف میں فلٹرز کو ایڈجسٹ کرنا، دستی مداخلت اور ٹویکڈ اسٹاپ شامل ہیں.

بہتر مواقع

اس حکمت عملی کے لئے ممکنہ اصلاحات:

  1. بہترین پیرامیٹر مجموعے کی تلاش

  2. موافقت پذیر اصلاح کے لئے مشین لرننگ متعارف کروائیں

  3. سٹاپ نقصان کے بہتر طریقوں کی تحقیق کریں مثلاً اتار چڑھاؤ کے سٹاپ

  4. صوابدیدی اقدامات کی رہنمائی کے لئے جذبات کو شامل کریں

  5. شماریاتی ثالثی کے لئے متعلقہ آلات کا استعمال کریں

نتیجہ

بولنگر بینڈز بریک آؤٹ حکمت عملی قلیل مدتی رجحان کی تجارت کے لئے ایک تجربہ کار نظام ہے۔ بولنگر بینڈز سگنل اور محتاط فلٹرز کی خوبیوں کو جوڑ کر ، یہ غلط سگنلز سے بچتے ہوئے رجحانات کے لئے معیاری اندراجات پیدا کرتا ہے۔ جامع رسک مینجمنٹ میکانزم میں بھی مؤثر طریقے سے ڈراؤونگ شامل ہیں۔ مسلسل بہتری کے ساتھ ، اس حکمت عملی میں ایک زبردست خودکار تجارتی نظام بننے کی صلاحیت ہے۔


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

مزید