本策略基于布林带的双重均线进行趋势跟随的交易决策。其利用布林带上下轨的收敛和发散来判断趋势的变化,在布林带下轨附近买入,在上轨附近卖出,实现低买高卖,获利离场。
该策略同时应用布林带的简单布林带和增强布林带两个版本。
简单布林带使用收盘价的SMA计算中轨,增强布林带使用收盘价的EMA计算中轨。
上下轨均通过中轨±N倍标准差计算得到。
策略根据布林带上下轨之间的距离(spread)来判断趋势,当spread小于设定阈值时,表示正在进入趋势区间,可以进行趋势跟随交易。
具体来说,当价格接近下轨时买入做多,接近上轨时卖出平仓。止损方式为固定止损百分比,同时可选择启用追踪止损。
目标利润取决于选择在中轨或上轨附近平仓。
该策略还可选择只在确保盈利的情况下卖出,防止亏损。
该策略具有以下优势:
应用简单布林带和增强布林带,可以比较两种布林带的效果,选择更优版本,提高决策效率。
当布林带通道收窄时,表示进入趋势行情,这时跟随趋势交易胜率更高。
采用固定百分比止损以控制单笔损失。同时可选择中轨或上轨附近止盈,以及启用追踪止损来锁定更多利润。
只在确保盈利的情况下卖出,可以防止亏损的扩大。
该策略也存在以下风险:
跟随趋势交易本身存在一定回撤风险,需要承受连续亏损的心理压力。
当布林带通道较宽时,表示行情可能进入震荡,此时该策略交易效果不佳,需要暂停交易等待趋势重新形成。
固定百分比止损可能过于激进,需要调整为更温和的止损方式如ATR止损。
该策略可以从以下方面进行优化:
可以测试不同的均线参数、标准差倍数,找到更适合不同市场的布林带参数组合。
可在布林带信号基础上,加入如MACD、KD等指标的过滤,减少震荡市的交易。
可以测试不同的游动止损方式,或基于振幅、ATR等指标优化止损点。
优化每笔交易的仓位管理,并测试不同补仓策略。
本策略整合双重布林带指标的优势,根据布林带通道宽度判断趋势程度,在趋势期间进行低吸高抛的跟踪交易。同时设置科学的止损机制来控制风险。该策略可通过参数优化和结合其他指标过滤来进一步提高稳定性。
/*backtest start: 2023-10-01 00:00:00 end: 2023-10-31 00:00:00 period: 1h basePeriod: 15m 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/ // © JCGMarkets //@version=4 strategy("B.Bands | Augmented | Intra-range | Long-Only", shorttitle = "BB|A|IR|L", initial_capital=5000, commission_value=0.075, slippage = 1, overlay = true) //Technical Indicators Data show_simp = input(false, title="Trade on Simple Bollinger Bands ", type= input.bool, group="Select Strategy System") show_augm = input(true, title="Trade on Augmented Bollinger Bands", type= input.bool, group="Select Strategy System") periods = input(20, title="Periods for Moving Average", type =input.integer, minval = 2, step = 1, group="Technical Inputs") std = input(2, title="Std", type = input.float, minval=0.1 , step = 0.1, group="Technical Inputs") // Strategy data max_spread_bb = input(20000.0, title="Max Spread Tolerance Beetween Bands", type=input.float, step=0.1, group="Strategy Inputs") entry_source = input(close, title="Entry data source", type=input.source, group="Strategy Inputs") exit_source = input(high, title="Exit data source", type=input.source, group="Strategy Inputs") take_profit = input("middle", title = "Profit to band:", options = ["middle", "opposite"], group="Strategy Inputs") stop_loss = input(3.00, title="Stop Loss %", type=input.float, step=0.05, group="Strategy Inputs") trailing = input(false, title="Activate trailing stop?", type = input.bool, group="Strategy Inputs") stop_perc = input(6.00, title="Trailing %", type=input.float, step=0.125, group="Strategy Inputs") * 0.01 sell_profit = input(false, title="Only sell in profit (Stop Loss still active) ", type= input.bool, group="Strategy Inputs") var SL = 0.0 var SLT= 0.0 //Simple BB Calculation -> adapt if needed with different std for upper-lower, sma-ema, etc middle_sim = sma(close, periods) //Augmented BB Calculation -> adapt if needed with different std for upper lower, etc middle_augm = ema(close, periods) middle_upp = ema(high, periods) middle_low = ema(low, periods) //Multiplier dev = stdev(close, periods) * std //Upper & Lower Bands upper = (middle_sim + dev) lower = (middle_sim - dev) //Augmented Bands upper_augm = (middle_upp + dev) lower_augm = (middle_low - dev) //Bands Spread spread = upper - lower spread_augm = upper_augm - lower_augm //From date filter_from = input( true, title="===> From", group="Date Control") from_y = input( 2010, title = "from year", group="Date Control") from_m = input( 1, title = "from month", minval =1, maxval=12, group="Date Control") from_d = input( 1, title = "from day", minval=1, maxval=31, group="Date Control") //To date filter_to = input( true, title="===> To", group="Date Control") to_y = input( 2030, title = "To year", group="Date Control") to_m = input( 1, title = "To month", minval =1, maxval=12, group="Date Control") to_d = input( 1, title = "To day", minval=1, maxval=31, group="Date Control") // Date Condition In_date() => true in_position = strategy.position_size > 0 // Trailing stop SLT := if in_position and In_date() stop_inicial = entry_source * (1 - stop_perc) max(stop_inicial, SLT[1]) else 0 slts = (low <= SLT) and (trailing == true) //Essential Trade logics entry_long = (entry_source <= lower) and (spread < max_spread_bb) entry_long_augm = (entry_source <= lower_augm) and (spread_augm < max_spread_bb) // Simple Bollinger Conditions if (not in_position and show_simp and In_date()) if entry_long // Trigger buy order position_size = round( strategy.equity / close ) // All available equity for this strategy example strategy.entry("Entry", strategy.long, qty = position_size ) SL := close * (1 - (stop_loss / 100)) // You could determine wether or not implement stop loss with bool input and if condition here. if in_position and show_simp and not sell_profit and In_date() //Exits if not sell in profit if take_profit == "middle" strategy.exit("Target", "Entry", limit = middle_sim, stop = SL, comment="Exit") if take_profit == "opposite" strategy.exit("Target", "Entry", limit = upper, stop = SL, comment="Exit") if in_position and show_simp and sell_profit and In_date() //Exits if sell in profit if take_profit == "middle" strategy.exit("Target", "Entry", limit = (strategy.openprofit > 0 ? middle_sim: na), stop = SL, comment="Exit") if take_profit == "opposite" strategy.exit("Target", "Entry", limit = (strategy.openprofit > 0 ? upper: na), stop = SL, comment="Exit") if in_position and show_simp and slts and In_date() //Trailing activation strategy.close("Entry", comment="SLT") if not In_date() //Exit due out of date range strategy.close("Entry", comment="Out of date range") // Augmented Bollinger Conditions if (not in_position and show_augm and In_date()) if entry_long_augm // Trigger buy order position_size = round( strategy.equity / close ) strategy.entry("Entry_A", strategy.long, qty = position_size ) SL := close * (1 - (stop_loss / 100) ) if in_position and show_augm and not sell_profit and In_date() //Exits and not sell in profit if take_profit == "middle" strategy.exit("Target", "Entry_A", limit = middle_augm, stop = SL, comment="Exit") if take_profit == "opposite" strategy.exit("Target", "Entry_A", limit = upper_augm, stop = SL, comment="Exit") if in_position and show_augm and sell_profit and In_date() //Exit only in profit if take_profit == "middle" strategy.exit("Target", "Entry_A", limit = (strategy.openprofit > 0 ? middle_augm:na), stop = SL, comment="Exit") if take_profit == "opposite" strategy.exit("Target", "Entry_A", limit = (strategy.openprofit > 0 ? upper_augm: na) , stop = SL, comment="Exit") if in_position and show_augm and slts and In_date() //Trigger trailing strategy.close("Entry_A", comment="SLT") if not In_date() //Out of date trigger strategy.close("Entry_A", comment= "Out of date range") // Plotting plot(in_position ? SL > 0 ? SL : na : na , style = plot.style_circles, color = color.red, title = "Stop Loss") plot(in_position ? trailing ? SLT > 0 ? SLT : na : na : na , style = plot.style_circles, color = color.blue, title = "Trailing Stop" ) s = plot(show_simp ? upper : na , color = color.aqua) plot(show_simp ? middle_sim : na , color=color.red) i = plot(show_simp ? lower : na , color = color.aqua) fill(s,i, color=color.new(color.aqua,90)) plot(show_augm ? middle_augm : na , color=color.blue) s_a = plot( show_augm ? upper_augm : na, color=color.orange) i_a = plot( show_augm ? lower_augm : na, color= color.orange) fill(s_a,i_a, color=color.new(color.orange, 90))