这个策略实现了设置多个百分比止盈exit的功能。策略首先判断长短条件,入场做多做空。然后通过一个自定义的percentAsPoints函数把百分比转换成价格点数。程序按照设置的1%、2%、3%和4%的止盈百分比,设置了4个exit,同时也设置了一个通用的2%止损exit。这样就实现了多个百分比止盈的效果。
该策略主要通过sma均线的多空交叉来判断入场。具体来说,当快线sma(14)上穿慢线sma(28)时会入场做多;当快线sma(14)下穿慢线sma(28)时会入场做空。
那么问题来了,如何设置多个百分比止盈exit呢?这里使用了一个自定义的percentAsPoints函数把百分比转换成价格点数,函数逻辑是:
percentAsPoints(pcnt) =>
strategy.position_size != 0 ? round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)
该函数如果持仓量不为0,就使用百分比乘以持仓平均价格再除以最小价格跳动,得到价格点数。如果持仓为0就返回na。
有了这个函数我们就可以轻松转换百分比成点数了。然后程序就按照设置的1%、2%、3%和4%止盈,设置了4个exit:
lossPnt = percentAsPoints(2)
strategy.exit("x1", qty_percent = 25, profit = percentAsPoints(1), loss = lossPnt)
strategy.exit("x2", qty_percent = 25, profit = percentAsPoints(2), loss = lossPnt)
strategy.exit("x3", qty_percent = 25, profit = percentAsPoints(3), loss = lossPnt)
strategy.exit("x4", profit = percentAsPoints(4), loss = lossPnt)
同时所有exit都使用一个通用的2%止损loss。这样就实现了多个百分比止盈的效果。
这种多个百分比止盈的策略具有以下优势:
可以按部就班止盈,避免错过更大利润的机会。一般越靠后止盈幅度越大,风险也越大,这种策略可以平衡风险收益。
分批止盈可以归还本金,降低风险。例如设置25%批量,当盈利达到1%时就可以取回本金的1/4,后面仓位都是靠盈利操作。
防止异常行情止损,2%的止损可以避免极端行情带来的巨额亏损。
代码实现简单清晰,容易理解,便于修改和优化。自定义函数把百分比转换成点数,然后几行代码就可以设置多个止盈。
这种策略也存在一些风险:
百分比止盈容易形成横盘震荡,价格在止盈价格附近来回振荡。这时会频繁触发止盈止损,增加交易频率和手续费的负担。
分批止盈增加了交易次数,也增加了手续费的负担。如果手续费过高,反而会抵消部分止盈利润。
止盈点设置不当也会影响收益率。如果设置过于保守,则难以取得满意收益;而设置过于激进,则风险过大。
固定百分比止盈,没有考虑市场波动率和趋势性。在震荡行情中应降低止盈幅度,而在趋势行情中应该拉大止盈幅度。
考虑到上述风险,可以从以下几个方面继续优化:
优化止盈策略,使其能根据市场波动率和趋势自动调整。例如加入ATR止盈,在震荡时收紧止盈,在趋势中放宽止盈。
优化分批止盈的比例和幅度,实现风险收益的最优组合。加入参数优化功能找出最优参数。
减少止盈次数,避免过于频繁交易。例如设置价格缓冲区,只有超出一定幅度后才止盈。
考虑手续费因素,当预计止盈利润低于手续费时不止盈。或者按照手续费优化止盈幅度。
使用簿单止盈。根据深度优先止盈深度优先价格优先的offer,避免移动止盈价格。
这个策略实现了多个百分比止盈的效果,设置了1%、2%、3%和4%四个止盈exit,可以按部就班止盈,同时用2%止损来防止异常行情的巨额亏损。这种策略可以平衡风险收益,防止错过更大利润机会。但是也存在一定风险,如容易形成横盘震荡,增加交易频率等。这些建议都值得考虑加入策略进行优化,使其能够在更多市场中稳定运作。
/*backtest
start: 2023-10-31 00:00:00
end: 2023-11-30 00:00:00
period: 3h
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/
// © adolgov
//@version=4
strategy("Multiple %% profit exits example", overlay=false, default_qty_value = 10)
longCondition = crossover(sma(close, 14), sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = crossunder(sma(close, 14), sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
percentAsPoints(pcnt) =>
strategy.position_size != 0 ? round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)
lossPnt = percentAsPoints(2)
strategy.exit("x1", qty_percent = 25, profit = percentAsPoints(1), loss = lossPnt)
strategy.exit("x2", qty_percent = 25, profit = percentAsPoints(2), loss = lossPnt)
strategy.exit("x3", qty_percent = 25, profit = percentAsPoints(3), loss = lossPnt)
strategy.exit("x4", profit = percentAsPoints(4), loss = lossPnt)
profitPercent(price) =>
posSign = strategy.position_size > 0 ? 1 : strategy.position_size < 0 ? -1 : 0
(price - strategy.position_avg_price) / strategy.position_avg_price * posSign * 100
p1 = plot(profitPercent(high), style=plot.style_linebr, title = "open profit % upper bound")
p2 = plot(profitPercent(low), style=plot.style_linebr, title = "open profit % lower bound")
fill(p1, p2, color = color.red)