置)。
2、trail_offset
参数:执行跟踪止损止盈行为之后,放置的平仓单距离最高价(做多时)或者最低价(做空时)的距离。
3、trail_points
参数:如同trail_price
参数,只不过是以盈利点数为指定位置。
是不是不容易理解,没关系!我们来通过一个策略回测场景来理解学习,其实很简单的。
/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("test", overlay = true)
varip a = na
varip highPrice = na
varip isTrade = false
varip offset = 30
if not barstate.ishistory and not isTrade
strategy.entry("test 1", strategy.long, 1)
strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
a := close + offset
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close)
isTrade := true
if close > a and not barstate.ishistory
highPrice := na(highPrice) ? close : highPrice
highPrice := close > highPrice ? close : highPrice
plot(a, "trail_price 触发线")
plot(strategy.position_size>0 ? highPrice : na, "当前最高价")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "移动止损触发线")
策略开始执行时立即多头入场,然后立即下一个strategy.exit
出场订单(指定了跟踪止损止盈参数),当行情变动价格上涨超过trail_price触发线时,开始执行跟踪止损止盈逻辑,止损止盈线(蓝色)开始跟随最高价动态调整,蓝色线位置就是止损止盈触发平仓的价位,最后当行情变动价格跌破蓝色线即触发平仓。这样结合图表上画出的线是不是就很容易理解了。
那么我们使用这个功能来优化一种超级趋势策略,我们只用给策略入场订单指定一个strategy.exit
出场计划单,就可以增加这种跟踪止损止盈功能。
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
完整的策略代码:
/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
if strategy.position_size == 0
trail_price := na
state := 0
[superTrendPrice, dir] = ta.supertrend(input(2, "atr系数"), input(20, "atr周期"))
if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.long, 1)
state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.short, 1)
state := 1
// 反向信号,全平
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,多头全平")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,空头全平")
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)