本策略基于日线确定趋势方向,再利用15分钟K线形成的新的高点或低点作为止损位或追踪止损位,实现动态调整止损来锁定更多利润的策略。
利用日K线收盘价和前一日的最高价最低价比较,判断趋势方向。如果收盘价高于前一日的最高价,定义为上涨趋势;如果收盘价低于前一日的最低价,定义为下跌趋势。
在上涨趋势中,当15分钟K线收盘价高于前一个15分钟K线的最高价时,做多;在下跌趋势中,当15分钟K线收盘价低于前一个15分钟K线的最低价时,做空。
做多后,以前一个15分钟K线的最低价作为止损位。做空后,以前一个15分钟K线的最高价作为止损位。
当15分钟K线再次创出新的高点或低点时,调整止损位。做多时调整为新的低点,做空时调整为新的高点,实现动态追踪止损。
本策略最大的优势在于可以动态调整止损位,在保证了风险控制的同时,最大程度地锁定利润,降低止损被冲击的概率。
具体优势如下:
基于趋势运算,能够及时判断市场走势并选择正确的交易方向。
15分钟级别的交易,可以频繁进出场,捕捉较多机会。
动态调整止损策略,可以根据新高或新低来降低止损被冲击的风险。
止损位置设置合理,最大程度避免无谓损失。
本策略的主要风险来自于趋势判断上的错误。具体风险点如下:
日线趋势判断发生错误,可能导致交易方向错误。
行情短期内发生剧烈波动,15分钟止损位被突破的概率较大。
趋势转折点识别不当,可能导致亏损。
对应解决方法如下:
增加其他时间周期指标进行综合判断,避免仅凭单一周期产生错误。
评估市场波动性,在波动较大时适当放宽止损范围。
增加趋势转折点判断机制,在转折前及时平仓。
本策略仍有进一步优化的空间:
增加其他周期指标判断,优化趋势掌握。
测试不同止损比例设置,选取最优参数。
增加量能指标,避免量能背离产生错误交易。
增设趋势转折机制,优化 Exit 点。
评估增加 Trailing Stop 区间值,进一步减少止损被冲击概率。
本策略总体运行效果良好,思路清晰易于理解,具有止损动态调整、频繁交易、顺势而为等优点,能够有效控制风险并锁定利润,值得进一步测试与优化应用。但也存在一定改进空间,建议从多角度综合判断、优化参数设置、增加趋势转折判别等方面入手,以进一步增强策略的稳定性与收益率。
/*backtest
start: 2023-12-13 00:00:00
end: 2023-12-15 02:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Anand's Strategy", overlay=true)
// Get the high and low of the previous day's candle
prev_high = request.security(syminfo.tickerid, "D", high[2])
prev_low = request.security(syminfo.tickerid, "D", low[2])
// var float prev_high = na
// var float prev_low = na
prev_close = request.security(syminfo.tickerid, "D", close[1])
getDayIndexedHighLow(_bar) =>
_indexed_high = request.security(syminfo.tickerid, "D", high[_bar])
_indexed_low = request.security(syminfo.tickerid, "D", low[_bar])
[_indexed_high, _indexed_low]
var index = 2
while index >= 0
[indexed_high_D, indexed_low_D] = getDayIndexedHighLow(index)
if prev_close > indexed_high_D or prev_close < indexed_low_D
prev_high := indexed_high_D
prev_low := indexed_low_D
break
// Decrease the index to move to the previous 15-minute candle
index := index - 1
// Determine the trade direction based on the candle criterion
trade_direction = prev_close > prev_high ? 1 : (prev_close < prev_low ? -1 : 0)
// Get the current close from 15-minute timeframe
current_close = request.security(syminfo.tickerid, "15", close[1])
prev_high_15m = request.security(syminfo.tickerid, "15", high[2])
prev_low_15m = request.security(syminfo.tickerid, "15", low[2])
// var float prev_high_15m = na
// var float prev_low_15m = na
getIndexedHighLow(_bar) =>
_indexed_high = request.security(syminfo.tickerid, "15", high[_bar])
_indexed_low = request.security(syminfo.tickerid, "15", low[_bar])
[_indexed_high, _indexed_low]
// Loop through previous 15-minute candles until the condition is met
var i = 2
while i >= 2
[indexed_high_15m, indexed_low_15m] = getIndexedHighLow(i)
if current_close > indexed_high_15m or current_close < indexed_low_15m
prev_high_15m := indexed_high_15m
prev_low_15m := indexed_low_15m
break
// Decrease the index to move to the previous 15-minute candle
i := i - 1
buy_condition = trade_direction == 1 and current_close > prev_high_15m
stop_loss_buy = prev_low_15m
// Sell Trade Criteria in Negative Trend
sell_condition = trade_direction == -1 and current_close < prev_low_15m
stop_loss_sell = prev_high_15m
// Trailing Stop Loss for Buy Trade
// Custom Trailing Stop Function for Buy Trade
var float trail_stop_buy = na
trailing_buy_condition = buy_condition and current_close > trail_stop_buy
if trailing_buy_condition
trail_stop_buy := current_close
// Custom Trailing Stop Function for Sell Trade
var float trail_stop_sell = na
trailing_sell_condition = sell_condition and current_close < trail_stop_sell
if trailing_sell_condition
trail_stop_sell := current_close
// Take Buy Trade with Stop Loss
if (buy_condition)
strategy.entry("Buy", strategy.long)
strategy.exit("Buy Stop Loss", "Buy", stop=stop_loss_buy)
// Take Sell Trade with Stop Loss
if (sell_condition)
strategy.entry("Sell", strategy.short)
strategy.exit("Sell Stop Loss", "Sell", stop=stop_loss_sell)
// Set the background color based on the trade direction
bgcolor(trade_direction == 1 ? color.new(color.green, 90) : trade_direction == -1 ? color.new(color.red, 90) : na)