如何实现Take Profit触发后仍可按条件开新单的Pine Script策略优化
VortexStrategyEMA策略优化:止盈后重新开仓实现
需求说明
我用Pine Script编写了VortexStrategyEMA策略,已配置止盈和止损规则,当前在SOLUSDT 30分钟周期测试。需要实现:当止盈触发平仓后,若多/空开仓条件仍满足,允许策略开立新单再次获取止盈。
原始策略代码
//@version=5 strategy("VortexStrategyEMA", overlay=true, initial_capital = 1000, default_qty_type=strategy.percent_of_equity, default_qty_value=100) AlerteBuy = input("Alerte BUY") AlerteSell = input("Alerte SELL") AlerteCloseBuy = input("Alerte CLOSE BUY") AlerteCloseSell = input("Alerte CLOSE SELL") //EMA longer = ta.ema(close, 100) longest = ta.ema(close, 200) plot(longer, title="EMA100", color=#2962FF) plot(longest,title="EMA200", color=#E91E63) emahigh = ta.ema(high,14) emalow = ta.ema(low,14) //Vortex period_ = input.int(200, title="Length", minval=2) VMP = math.sum( math.abs( emahigh - emalow[1]), period_ ) VMM = math.sum( math.abs( emalow - emahigh[1]), period_ ) STR = math.sum( ta.atr(1), period_ ) VIP = VMP / STR VIM = VMM / STR emaVIP = ta.ema(VIP, 14) emaVIM = ta.ema(VIM, 14) plot(VIP, title="VI +", color=#2962FF) plot(VIM, title="VI -", color=#E91E63) //ConditionsLONG EMALONG = longer > longest VortexLONG = ta.crossover(VIP,VIM) LONG = VortexLONG and EMALONG //ConditionsSHORT EMASHORT = longer < longest VortexSHORT = ta.crossunder(VIP,VIM) SHORT = VortexSHORT and EMASHORT //Strategy strategy.entry("Long", strategy.long, when=LONG, comment="Long" , alert_message = AlerteBuy) strategy.entry("Short", strategy.short, when=SHORT, comment="Short" , alert_message = AlerteSell) stopPer = input(5, title='Stop Loss %') / 100 takePer = input(10, title='Take Profit %') / 100 // Determine where you've entered and in what direction shortStop = strategy.position_avg_price * (1 + stopPer) shortTake = strategy.position_avg_price * (1 - takePer) longStop = strategy.position_avg_price * (1 - stopPer) longTake = strategy.position_avg_price * (1 + takePer) if strategy.position_size < 0 strategy.exit(id='Close Short', stop=shortStop, limit=shortTake, alert_message = AlerteCloseSell) if strategy.position_size > 0 strategy.exit(id='Close Long', stop=longStop, limit=longTake, alert_message = AlerteCloseBuy)
问题分析
原始策略的开仓条件仅依赖ta.crossover/ta.crossunder这类一次性交叉信号,这类信号仅在交叉触发的单根K线上有效。当止盈平仓后,即使EMA趋势和VI的强弱关系仍符合开仓要求(比如多单条件:EMA100>EMA200且VIP>VIM),由于没有新的交叉信号,策略不会再次开仓。
修改后的策略代码
//@version=5 strategy("VortexStrategyEMA", overlay=true, initial_capital = 1000, default_qty_type=strategy.percent_of_equity, default_qty_value=100) AlerteBuy = input("Alerte BUY") AlerteSell = input("Alerte SELL") AlerteCloseBuy = input("Alerte CLOSE BUY") AlerteCloseSell = input("Alerte CLOSE SELL") //EMA longer = ta.ema(close, 100) longest = ta.ema(close, 200) plot(longer, title="EMA100", color=#2962FF) plot(longest,title="EMA200", color=#E91E63) emahigh = ta.ema(high,14) emalow = ta.ema(low,14) //Vortex period_ = input.int(200, title="Length", minval=2) VMP = math.sum( math.abs( emahigh - emalow[1]), period_ ) VMM = math.sum( math.abs( emalow - emahigh[1]), period_ ) STR = math.sum( ta.atr(1), period_ ) VIP = VMP / STR VIM = VMM / STR emaVIP = ta.ema(VIP, 14) emaVIM = ta.ema(VIM, 14) plot(VIP, title="VI +", color=#2962FF) plot(VIM, title="VI -", color=#E91E63) //ConditionsLONG EMALONG = longer > longest // 跟踪当前VI的多单状态(VIP在VIM上方) currentLongVI = VIP > VIM // 修改开仓条件:初始交叉触发 或 无仓位且多单条件持续满足 LONG = (ta.crossover(VIP,VIM) and EMALONG) or (strategy.position_size == 0 and EMALONG and currentLongVI) //ConditionsSHORT EMASHORT = longer < longest // 跟踪当前VI的空单状态(VIP在VIM下方) currentShortVI = VIP < VIM // 修改开仓条件:初始交叉触发 或 无仓位且空单条件持续满足 SHORT = (ta.crossunder(VIP,VIM) and EMASHORT) or (strategy.position_size == 0 and EMASHORT and currentShortVI) //Strategy strategy.entry("Long", strategy.long, when=LONG, comment="Long" , alert_message = AlerteBuy) strategy.entry("Short", strategy.short, when=SHORT, comment="Short" , alert_message = AlerteSell) stopPer = input(5, title='Stop Loss %') / 100 takePer = input(10, title='Take Profit %') / 100 // Determine where you've entered and in what direction shortStop = strategy.position_avg_price * (1 + stopPer) shortTake = strategy.position_avg_price * (1 - takePer) longStop = strategy.position_avg_price * (1 - stopPer) longTake = strategy.position_avg_price * (1 + takePer) if strategy.position_size < 0 strategy.exit(id='Close Short', stop=shortStop, limit=shortTake, alert_message = AlerteCloseSell) if strategy.position_size > 0 strategy.exit(id='Close Long', stop=longStop, limit=longTake, alert_message = AlerteCloseBuy)
关键修改说明
- 新增VI状态跟踪变量:
currentLongVI和currentShortVI分别跟踪当前VIP与VIM的强弱关系,判断是否维持多/空趋势。 - 修改开仓条件逻辑:
- 保留原有的交叉信号作为初始开仓触发条件
- 新增规则:当策略无仓位时,若EMA趋势和VI状态仍符合多/空要求,允许再次开仓
- 这样在止盈平仓后,只要趋势和VI状态不变,策略就会重新开立新单,继续获取止盈收益
内容的提问来源于stack exchange,提问作者Axone
相关产品推荐
相关产品推荐

