
你知道吗?这个策略就像一个超级谨慎的投资老司机!它不会盲目追涨杀跌,而是先用”望远镜”(多时间框架市场结构分析)观察大趋势,确认方向没问题后,才会用唐奇安通道突破作为入场信号。简单说就是:看准大方向,抓住小突破! 📈
最有趣的是,它还会”分批建仓”——就像你买菜时先尝一个,觉得好吃再多买几个的逻辑。当价格朝着有利方向移动时,它会根据ATR(平均真实波幅)智能加仓,让盈利跑得更远!
划重点! 这个策略有三个超级厉害的地方:
1. 多时间框架结构过滤 🕐 就像开车前先看导航确认大方向一样,策略会先分析更大周期的市场结构。只有当大趋势向上时才做多,大趋势向下时才做空。这样可以避免在震荡市中被来回打脸!
2. ATR动态加仓系统 📊 传统策略要么一把梭,要么固定加仓。这个策略聪明多了!它根据市场波动性(ATR)来决定加仓时机和止损位置。市场波动大时,给更多空间;波动小时,控制更严格。
3. 反向信号平仓 🔄 最酷的是平仓逻辑:不是等到止损或者固定目标,而是当反向入场信号出现时就全部平仓。这样既能抓住趋势的大部分利润,又能在趋势转换时及时撤退!
避坑指南来了!
这个策略最适合什么时候用呢?
最佳使用场景: - 趋势性较强的品种(比如加密货币、商品期货) - 有明显方向性的市场环境 - 你有足够耐心等待高质量信号的时候
不适合的情况: - 横盘震荡市(会被来回打脸) - 消息面变化频繁的时期 - 你想要高频交易的时候
记住:这是个”慢工出细活”的策略,不是让你一夜暴富的神器,而是帮你在趋势中稳稳赚钱的好帮手! 🚀
/*backtest
start: 2025-11-11 00:00:00
end: 2025-12-10 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"ZEC_USDT"}]
*/
//@version=6
strategy("Trend $ZEC", shorttitle="$ZEC 1/15m", overlay=true,
initial_capital=10000,
default_qty_type=strategy.cash,
default_qty_value=5000,
commission_type=strategy.commission.percent,
commission_value=0.06,
slippage=0,
max_lines_count=500,
max_labels_count=500)
// ========== 參數設定 ==========
// 唐奇安通道參數
entry_period = input.int(20, "進場通道週期", minval=1, group="通道設定")
exit_period = input.int(10, "出場通道週期", minval=1, group="通道設定")
// ATR 參數
atr_period = input.int(20, "ATR 週期", minval=1, group="ATR 設定")
atr_stop_mult = input.float(2.0, "止損 ATR 倍數", minval=0.1, step=0.1, group="ATR 設定")
atr_add_mult = input.float(0.5, "加倉 ATR 倍數", minval=0.1, step=0.1, group="ATR 設定")
// 多空結構參數 - 加入多時間框架
swing_length = input.int(160, "結構擺動長度", minval=1, group="📊 多空結構過濾")
structure_timeframe = input.timeframe("1", "結構時間框架", group="📊 多空結構過濾", tooltip="選擇結構判斷的時間週期,空白=當前圖表,D=日線,W=週線")
show_structure_lines = input.bool(false, "顯示結構線", group="📊 多空結構過濾")
show_structure_labels = input.bool(false, "顯示結構標籤", group="📊 多空結構過濾")
// 加倉設定
max_units = input.int(2, "最大單位數(含首次)", minval=1, maxval=10, group="倉位管理")
position_size = input.int(5000, "每單位資金(USD)", minval=100, group="倉位管理", tooltip="10000U本金分2次進場,每次5000U")
// 顯示設定
show_channels = input.bool(false, "顯示通道", group="顯示設定")
show_atr_lines = input.bool(false, "顯示 ATR 線", group="顯示設定")
show_labels = input.bool(true, "顯示標籤", group="顯示設定")
show_table = input.bool(false, "顯示資訊面板", group="顯示設定")
label_distance = input.float(2.5, "標籤距離 K 棒倍數", minval=0.1, step=0.1, group="顯示設定", tooltip="標籤距離K棒的ATR倍數")
show_label_lines = input.bool(false, "顯示標籤連線", group="顯示設定")
// ========== 計算唐奇安通道 ==========
entry_upper = ta.highest(high, entry_period)
entry_lower = ta.lowest(low, entry_period)
exit_upper = ta.highest(high, exit_period)
exit_lower = ta.lowest(low, exit_period)
// ========== 計算 ATR (N值) ==========
N = ta.atr(atr_period)
// ========== 多時間框架多空結構判斷 ==========
// 計算結構的函數
f_calculate_structure() =>
var int trend = 0
var float lastHigh = na
var float lastLow = na
swingHigh = ta.pivothigh(high, swing_length, swing_length)
swingLow = ta.pivotlow(low, swing_length, swing_length)
if not na(swingHigh)
lastHigh := swingHigh
if not na(swingLow)
lastLow := swingLow
if not na(lastHigh) and close > lastHigh and trend != 1
trend := 1
if not na(lastLow) and close < lastLow and trend != -1
trend := -1
[trend, lastHigh, lastLow]
// 獲取指定時間框架的結構
[structure_trend_mtf, last_structure_high_mtf, last_structure_low_mtf] = request.security(syminfo.tickerid, structure_timeframe, f_calculate_structure(), lookahead=barmerge.lookahead_off)
// 使用多時間框架的結構趨勢
structure_trend = structure_trend_mtf
last_structure_high = last_structure_high_mtf
last_structure_low = last_structure_low_mtf
// 檢測結構變化(用於繪製標籤)
var int prev_structure_trend = 0
bool bull_break = structure_trend == 1 and prev_structure_trend != 1
bool bear_break = structure_trend == -1 and prev_structure_trend != -1
prev_structure_trend := structure_trend
// 繪製結構突破標籤
if show_structure_labels
if bull_break
label.new(bar_index, low, "多方結構", style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, size=size.small)
if bear_break
label.new(bar_index, high, "空方結構", style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, size=size.small)
// ========== 持倉狀態追蹤 ==========
var float entry_price = na
var float[] add_prices = array.new_float(0)
var int position = 0
var int units = 0
var float stop_loss = na
// ========== 進場訊號 (加入結構過濾) ==========
long_entry_signal = close > entry_upper[1] and structure_trend == 1
short_entry_signal = close < entry_lower[1] and structure_trend == -1
long_entry = long_entry_signal and position != 1
short_entry = short_entry_signal and position != -1
// ========== 加倉訊號 ==========
long_add = false
short_add = false
if position == 1 and units < max_units
if array.size(add_prices) > 0
last_add_price = array.get(add_prices, array.size(add_prices) - 1)
long_add := close >= last_add_price + (atr_add_mult * N)
else
long_add := close >= entry_price + (atr_add_mult * N)
if position == -1 and units < max_units
if array.size(add_prices) > 0
last_add_price = array.get(add_prices, array.size(add_prices) - 1)
short_add := close <= last_add_price - (atr_add_mult * N)
else
short_add := close <= entry_price - (atr_add_mult * N)
// ========== 出場訊號 (改為反向訊號出場) ==========
// 多單出場:當空單進場訊號觸發時
long_exit = (position == 1) and short_entry_signal
// 空單出場:當多單進場訊號觸發時
short_exit = (position == -1) and long_entry_signal
// ========== 更新持倉狀態 ==========
if long_entry
position := 1
units := 1
entry_price := close
array.clear(add_prices)
array.push(add_prices, close)
stop_loss := close - (atr_stop_mult * N)
alert_msg = timeframe.period + " 做多 EP:" + str.tostring(close, "#.##")
strategy.entry("多單1", strategy.long, qty=position_size/close, comment=alert_msg, alert_message=alert_msg)
else if short_entry
position := -1
units := 1
entry_price := close
array.clear(add_prices)
array.push(add_prices, close)
stop_loss := close + (atr_stop_mult * N)
alert_msg = timeframe.period + " 做空 EP:" + str.tostring(close, "#.##")
strategy.entry("空單1", strategy.short, qty=position_size/close, comment=alert_msg, alert_message=alert_msg)
else if long_add
units := units + 1
array.push(add_prices, close)
stop_loss := close - (atr_stop_mult * N)
alert_msg = timeframe.period + " 加倉多 " + str.tostring(units) + "/" + str.tostring(max_units) + " EP:" + str.tostring(close, "#.##")
strategy.entry("多單" + str.tostring(units), strategy.long, qty=position_size/close, comment=alert_msg, alert_message=alert_msg)
else if short_add
units := units + 1
array.push(add_prices, close)
stop_loss := close + (atr_stop_mult * N)
alert_msg = timeframe.period + " 加倉空 " + str.tostring(units) + "/" + str.tostring(max_units) + " EP:" + str.tostring(close, "#.##")
strategy.entry("空單" + str.tostring(units), strategy.short, qty=position_size/close, comment=alert_msg, alert_message=alert_msg)
else if long_exit or short_exit
if long_exit
alert_msg = timeframe.period + " 平多 反向訊號"
strategy.close_all(comment=alert_msg, alert_message=alert_msg)
if short_exit
alert_msg = timeframe.period + " 平空 反向訊號"
strategy.close_all(comment=alert_msg, alert_message=alert_msg)
position := 0
units := 0
entry_price := na
array.clear(add_prices)
stop_loss := na
// ========== 繪製通道 ==========
plot(show_channels ? entry_upper : na, "進場上軌", color=color.new(color.red, 0), linewidth=2)
plot(show_channels ? entry_lower : na, "進場下軌", color=color.new(color.green, 0), linewidth=2)
plot(show_channels ? exit_upper : na, "出場上軌", color=color.new(color.orange, 50), linewidth=1, style=plot.style_circles)
plot(show_channels ? exit_lower : na, "出場下軌", color=color.new(color.blue, 50), linewidth=1, style=plot.style_circles)
// 繪製結構高低點
plot(show_structure_lines ? last_structure_high : na, "結構高點", color=color.new(color.red, 70), linewidth=2, style=plot.style_stepline)
plot(show_structure_lines ? last_structure_low : na, "結構低點", color=color.new(color.green, 70), linewidth=2, style=plot.style_stepline)
// ========== 繪製 ATR 線 ==========
plot(show_atr_lines and position != 0 ? stop_loss : na, "止損線", color=color.new(color.red, 0), linewidth=2, style=plot.style_cross)
var float next_add_long = na
if position == 1 and units < max_units
next_add_long := array.size(add_prices) > 0 ? array.get(add_prices, array.size(add_prices) - 1) + (atr_add_mult * N) : entry_price + (atr_add_mult * N)
else
next_add_long := na
plot(show_atr_lines and position == 1 and units < max_units ? next_add_long : na, "下次加倉(多)", color=color.new(color.yellow, 30), linewidth=1, style=plot.style_stepline)
var float next_add_short = na
if position == -1 and units < max_units
next_add_short := array.size(add_prices) > 0 ? array.get(add_prices, array.size(add_prices) - 1) - (atr_add_mult * N) : entry_price - (atr_add_mult * N)
else
next_add_short := na
plot(show_atr_lines and position == -1 and units < max_units ? next_add_short : na, "下次加倉(空)", color=color.new(color.yellow, 30), linewidth=1, style=plot.style_stepline)