Pine Script:价格低于入场价X个Ticks时如何全平多单
Pine Script 多单止损需求实现
我目前使用以下Pine Script代码进行多单交易:
strategy.entry("My Long Entry ", strategy.long) strategy.exit("My Exit 1", from_entry = "My Long Entry ", profit=15000, qty_percent = 50) strategy.exit("My Exit 2", from_entry = "My Long Entry ", qty_percent = 50, trail_offset=10000, trail_points=15000)
但我希望避免出现回撤情况,因此想实现:当价格触及入场价下方我指定的Ticks数对应的水平时,将全部多单持仓平仓。以下是我的完整代码:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © me //@version=5 strategy("Just Trend V2", process_orders_on_close=false, overlay=true, initial_capital=100, default_qty_value=1000, currency='USDT', default_qty_type=strategy.percent_of_equity, calc_on_every_tick = true, max_labels_count=500, use_bar_magnifier = true, margin_long = 1., commission_value = 0.07) backtestStartDate = input.time(timestamp("12 Mar 2023 GMT+01:00"), title="Start Date", group="Backtest Time Period") backtestEndDate = input.time(timestamp("13 Mar 2023 GMT+01:00"), title="End Date", group="Backtest Time Period") inTradeWindow = time > backtestStartDate and time <= backtestEndDate // ### Four Smoothed Moving Averages len1 = 21 //input(21, minval=1, title="Length 1", group = "Smoothed MA Inputs") src1 = close //input(close, title="Source 1", group = "Smoothed MA Inputs") smma1 = 0.0 sma_1 = ta.sma(src1, len1) smma1 := na(smma1[1]) ? sma_1 : (smma1[1] * (len1 - 1) + src1) / len1 plot(smma1, color=color.white, linewidth=2, title="21 SMMA") len2 = 50 //input(50, minval=1, title="Length 2", group = "Smoothed MA Inputs") src2 = close //input(close, title="Source 2", group = "Smoothed MA Inputs") smma2 = 0.0 sma_2 = ta.sma(src2, len2) smma2 := na(smma2[1]) ? sma_2 : (smma2[1] * (len2 - 1) + src2) / len2 plot(smma2, color=color.new(#6aff00,0), linewidth=2, title="50 SMMA") h100 = input.bool(title="Show 100 Line", defval=true, group = "Smoothed MA Inputs") len3 = 100 //input(100, minval=1, title="Length 3", group = "Smoothed MA Inputs") src3 = close //input(close, title="Source 3", group = "Smoothed MA Inputs") smma3 = 0.0 sma_3 = ta.sma(src3, len3) smma3 := na(smma3[1]) ? sma_3 : (smma3[1] * (len3 - 1) + src3) / len3 sma3plot = plot(h100 ? smma3 : na, color=color.new(color.yellow,0), linewidth=2, title="100 SMMA") len4 = 200 //input(200, minval=1, title="Length 4", group = "Smoothed MA Inputs") src4 = close //input(close, title="Source 4", group = "Smoothed MA Inputs") smma4 = 0.0 sma_4 = ta.sma(src4, len4) smma4 := na(smma4[1]) ? sma_4 : (smma4[1] * (len4 - 1) + src4) / len4 sma4plot = plot(smma4, color=color.new(#ff0500,0), linewidth=2, title="200 SMMA") // Trend Fill trendFill = input.bool(title="Show Trend Fill", defval=true, group = "Smoothed MA Inputs") ema2 = ta.ema(close, 2) ema2plot = plot(ema2, color=color.new(#2ecc71, 50), style=plot.style_line, linewidth=1, title="EMA(2)", editable = false) //bool condBuy = (ema2 > smma4 and trendFill) and close > smma1 and smma1 > smma2 and smma2 > smma3 and smma3 > smma4 bool condBuy = (ema2 > smma4 and trendFill) and close > smma1 and close > smma2 and close > smma3 and close > smma4 bool condSell = close < smma1 or close < smma2 or close < smma3 or close < smma4 fill(ema2plot, sma4plot, color= ema2 > smma4 and trendFill ? color.new(color.green, 50) : ema2 < smma4 and trendFill ? color.new(color.red, 50) : na, title = "Trend Fill") // End ### var Limit_Below_Entry_Price = 0.0 // LONG TRADES if inTradeWindow and condBuy and strategy.opentrades > 0 == false strategy.entry("My Long Entry ", strategy.long, limit = close) Limit_Below_Entry_Price := close - 100 strategy.exit("My Exit 1", from_entry = "My Long Entry ", profit=15000, qty_percent = 50) // 50*syminfo.mintick strategy.exit("My Exit 2", from_entry = "My Long Entry ", qty_percent = 50, trail_offset=10000, trail_points=15000) if close < Limit_Below_Entry_Price strategy.close_all() if inTradeWindow a = str.tostring(Limit_Below_Entry_Price) label.new(bar_index, na, a, yloc = yloc.abovebar, size = size.normal,textcolor = color.white)
问题分析与修改方案
原代码的止损逻辑存在几个瑕疵:仅用close判断会错过盘中跌破的情况,var定义的止损值会持续保留导致误触发,且未基于实际入场价计算止损。以下是优化后的完整代码:
优化后代码
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © me //@version=5 strategy("Just Trend V2", process_orders_on_close=false, overlay=true, initial_capital=100, default_qty_value=1000, currency='USDT', default_qty_type=strategy.percent_of_equity, calc_on_every_tick = true, max_labels_count=500, use_bar_magnifier = true, margin_long = 1., commission_value = 0.07) backtestStartDate = input.time(timestamp("12 Mar 2023 GMT+01:00"), title="Start Date", group="Backtest Time Period") backtestEndDate = input.time(timestamp("13 Mar 2023 GMT+01:00"), title="End Date", group="Backtest Time Period") inTradeWindow = time > backtestStartDate and time <= backtestEndDate // 可配置止损参数 stop_loss_ticks = input.int(100, title="止损Ticks数", group="止损设置") stop_loss_distance = stop_loss_ticks * syminfo.mintick // ### Four Smoothed Moving Averages len1 = 21 src1 = close smma1 = 0.0 sma_1 = ta.sma(src1, len1) smma1 := na(smma1[1]) ? sma_1 : (smma1[1] * (len1 - 1) + src1) / len1 plot(smma1, color=color.white, linewidth=2, title="21 SMMA") len2 = 50 src2 = close smma2 = 0.0 sma_2 = ta.sma(src2, len2) smma2 := na(smma2[1]) ? sma_2 : (smma2[1] * (len2 - 1) + src2) / len2 plot(smma2, color=color.new(#6aff00,0), linewidth=2, title="50 SMMA") h100 = input.bool(title="Show 100 Line", defval=true, group = "Smoothed MA Inputs") len3 = 100 src3 = close smma3 = 0.0 sma_3 = ta.sma(src3, len3) smma3 := na(smma3[1]) ? sma_3 : (smma3[1] * (len3 - 1) + src3) / len3 sma3plot = plot(h100 ? smma3 : na, color=color.new(color.yellow,0), linewidth=2, title="100 SMMA") len4 = 200 src4 = close smma4 = 0.0 sma_4 = ta.sma(src4, len4) smma4 := na(smma4[1]) ? sma_4 : (smma4[1] * (len4 - 1) + src4) / len4 sma4plot = plot(smma4, color=color.new(#ff0500,0), linewidth=2, title="200 SMMA") // Trend Fill trendFill = input.bool(title="Show Trend Fill", defval=true, group = "Smoothed MA Inputs") ema2 = ta.ema(close, 2) ema2plot = plot(ema2, color=color.new(#2ecc71, 50), style=plot.style_line, linewidth=1, title="EMA(2)", editable = false) bool condBuy = (ema2 > smma4 and trendFill) and close > smma1 and close > smma2 and close > smma3 and close > smma4 bool condSell = close < smma1 or close < smma2 or close < smma3 or close < smma4 fill(ema2plot, sma4plot, color= ema2 > smma4 and trendFill ? color.new(color.green, 50) : ema2 < smma4 and trendFill ? color.new(color.red, 50) : na, title = "Trend Fill") // End ### var float stop_level = na // LONG TRADES if inTradeWindow and condBuy and strategy.opentrades == 0 strategy.entry("My Long Entry ", strategy.long, limit = close) // 基于实际入场价计算止损水平 stop_level := strategy.entry_price("My Long Entry ") - stop_loss_distance strategy.exit("My Exit 1", from_entry = "My Long Entry ", profit=15000, qty_percent = 50) strategy.exit("My Exit 2", from_entry = "My Long Entry ", qty_percent = 50, trail_offset=10000, trail_points=15000) // 触发止损:盘中价格跌破止损线且有持仓 if strategy.opentrades > 0 and low < stop_level strategy.close_all() stop_level := na // 平仓后重置止损值 // 显示止损水平标签 if inTradeWindow and not na(stop_level) label.new(bar_index, stop_level, str.tostring(stop_level, "#.####"), yloc = yloc.belowbar, size = size.normal, textcolor = color.red, style=label.style_label_up)
优化说明
- 添加可配置的
stop_loss_ticks参数,自动转换为对应价格距离,适配不同品种 - 使用
strategy.entry_price()获取实际入场价,替代开仓时的close,计算更准确 - 用
low < stop_level判断盘中跌破情况,结合calc_on_every_tick = true确保实时触发止损 - 平仓后重置止损值为
na,避免无持仓时误触发 - 调整标签显示位置到止损价下方,更直观
内容的提问来源于stack exchange,提问作者ailauli69
相关产品推荐
相关产品推荐

