【问题标题】:Strategy Exit is not triggering correctly策略退出未正确触发
【发布时间】:2020-09-22 08:56:09
【问题描述】:

感谢您查看此内容,希望您能帮助我。

我创建了一个代码,它同时考虑了布林带和 RSI 指标,并创建了一个策略,当收盘价低于 BB 下带且 RSI 显示超卖,信号是买入,退出应该是当收盘价回到布林带基准线上方时。

此外,当收盘价高于布林带上限且 RSI 显示超买时,信号是卖出,并且应在收盘价回到布林带基准线下方时退出。

但是,退出有问题,因为它有时会正确触发,有时不会。请注意,我已经补充说,如果反向移动 200 点,它应该关闭交易。

您将在下面找到代码。请让我知道我做错了什么。谢谢!

// © hkanaan0

//@version=3
// 1. Define strategy settings
strategy(title="Bollinger Breakout", overlay=true,
     pyramiding=0, initial_capital=100000,
     commission_type=strategy.commission.cash_per_order,
     commission_value=4, slippage=2)

smaLength = input(title="SMA Length", type=integer, defval=50)
stdLength = input(title="StdDev Length", type=integer, defval=50)

ubOffset = input(title="Upper Band Offset", type=float, defval=2, step=0.5)
lbOffset = input(title="Lower Band Offset", type=float, defval=2, step=0.5)

usePosSize = input(title="Use Position Sizing?", type=bool, defval=true)
riskPerc   = input(title="Risk %", type=float, defval=0.5, step=0.25)

rsiSource = input(title = "RSI Source", type = source, defval = hlc3)
rsiLength = input(title = "RSI Length", type = integer, defval = 14)
rsiOverbought = input(title = "RSI Overbought Level", type = integer, defval = 70)
rsiOversold = input(title = "RSI Oversold Level", type = integer, defval = 30)

// 2. Calculate strategy values
rsiValue = rsi(rsiSource, rsiLength)
isRSIOB = rsiValue >= rsiOverbought
isRSIOS = rsiValue <= rsiOversold
isBullish = crossover(rsiValue, 55)
isBearish = crossunder(rsiValue, 45)

smaValue = sma(hlc3, smaLength)
stdDev   = stdev(hlc3, stdLength)

upperBand = smaValue + (stdDev * ubOffset)
lowerBand = smaValue - (stdDev * lbOffset)

riskEquity  = (riskPerc / 100) * strategy.equity
atrCurrency = (atr(20) * syminfo.pointvalue)
posSize     = usePosSize ? floor(riskEquity / atrCurrency) : 1

// 3. Output strategy data
plot(series=smaValue, title="SMA", color=blue, linewidth=2)

plot(series=upperBand, title="UB", color=green,
     linewidth=4)
plot(series=lowerBand, title="LB", color=red,
     linewidth=4)
     
//plotshape(isRSIOB, title="Overbought" , location=location.abovebar , color=red , transp=0 , style=shape.triangledown , text="Sell")
//plotshape(isRSIOS, title = "Oversold", location = location.belowbar, color =lime, transp = 0, style = shape.triangleup, text = "Buy")
plotshape(isBullish, title = "Bullish Momentum", location=location.abovebar, color=lime, transp = 0, style = shape.arrowup, text = "Bullish")
plotshape(isBearish, title = "Bearish Momentum", location=location.belowbar, color=red, transp = 0, style = shape.arrowdown, text = "Bearish")


// 4. Determine long trading conditions
enterLong = crossunder(close, lowerBand) and isRSIOS
exitLong  = crossover(close, smaValue)

// 5. Code short trading conditions
enterShort = crossover(close, upperBand) and isRSIOB
exitShort  = crossunder(close, smaValue)

// 6. Submit entry orders
if (enterLong)
    strategy.order(id="Enter Long", long=true, qty=posSize)

if (enterShort)
    strategy.order(id="Enter Short", long=false, qty=posSize)

// 7. Submit exit orders
strategy.exit(id="Exit Long", when=exitLong, loss = 200)
strategy.exit(id="Exit Short", when=exitShort, loss = 200)```

【问题讨论】:

    标签: pine-script


    【解决方案1】:

    发生的情况是 200 点是在 exit_short 或 exit_long 触发时计算的。所以如果在 12000 触发了 exit_short,即使你在 13000 做空,价格订单也只会在 11800 发生。

    为了解决这个问题,我计算了您入市时的止损价:

    opened_order = strategy.position_size[0] != 0 and strategy.position_size[1] == 0
    

    如果您当时不在一个位置,但现在是,strategy.position_size 会发生变化。所以我使用valuewhen(opened_order, close, 0) 来获取您开单时的收盘价。我取这个价格和 +- 200 个刻度,具体取决于订单打开的方向。

    最后,如果当前低/高触及止损价,则平仓。我还制作了不同的 cmets,因此您可以查看交易是否已停止,或者您是否获利。为此,我必须将 PineScript 更新到 v4,所以如果您不想要 cmets,您可以删除它们。

    这是代码:

    // Strategy settings
    strategy(title="Bollinger Breakout", overlay=true,
         pyramiding=0, initial_capital=100000,
         calc_on_order_fills = true,
         commission_type=strategy.commission.cash_per_order,
         commission_value=4, slippage=2)
    
    smaLength = input(title="SMA Length", defval=50)
    stdLength = input(title="StdDev Length", defval=50)
    
    ubOffset = input(title="Upper Band Offset", defval=2, step=0.5)
    lbOffset = input(title="Lower Band Offset", defval=2, step=0.5)
    
    usePosSize = input(title="Use Position Sizing?", defval=false)
    riskPerc   = input(title="Risk %", defval=2.5, step=0.25)
    
    rsiSource = input(title = "RSI Source", defval = hlc3)
    rsiLength = input(title = "RSI Length", defval = 14)
    rsiOverbought = input(title = "RSI Overbought Level", defval = 70)
    rsiOversold = input(title = "RSI Oversold Level", defval = 30)
    
    // Calculate strategy values
    rsiValue = rsi(rsiSource, rsiLength)
    isRSIOB = rsiValue >= rsiOverbought
    isRSIOS = rsiValue <= rsiOversold
    isBullish = crossover(rsiValue, 55)
    isBearish = crossunder(rsiValue, 45)
    
    smaValue = sma(hlc3, smaLength)
    stdDev   = stdev(hlc3, stdLength)
    
    upperBand = smaValue + (stdDev * ubOffset)
    lowerBand = smaValue - (stdDev * lbOffset)
    
    riskEquity  = (riskPerc / 100) * strategy.equity
    atrCurrency = (atr(20) * syminfo.pointvalue)
    posSize     = usePosSize ? floor(riskEquity / atrCurrency) : 1
    
    in_market = strategy.opentrades != 0
    opened_order = strategy.position_size[0] != 0 and strategy.position_size[1] == 0
    is_long = strategy.position_size > 0
    is_short = strategy.position_size < 0
    bought = is_long[0] and not is_long[1]
    sold = is_short[0] and not is_short[1]
    
    // Output strategy data
    
    plot(series=smaValue, title="SMA", color=color.blue, linewidth=2)
    plot(series=upperBand, title="UB", color=color.green, linewidth=4)
    plot(series=lowerBand, title="LB", color=color.red, linewidth=4)
    
    // Determine long trading conditions
    
    enterLong = crossunder(close, lowerBand) and isRSIOS
    plotshape(enterLong, title="Entry long signal", location=location.abovebar, color=color.lime, style=shape.triangledown)
    exitLong  = crossover(close, smaValue)
    
    // Determine short trading conditions
    
    enterShort = crossover(close, upperBand) and isRSIOB
    plotshape(enterShort, title="Entry short signal", location=location.belowbar, color=color.red, style = shape.triangleup)
    exitShort  = crossunder(close, smaValue)
    
    // Stop loss calculations
    
    moving_stop_price_long = not in_market ? close - (200 * syminfo.mintick) : na
    moving_stop_price_short = not in_market ? close + (200 * syminfo.mintick) : na
    stop_price = is_long ? valuewhen(bought, close[1], 0) - (200 * syminfo.mintick): is_short ? valuewhen(sold, close[1], 0) + (200 * syminfo.mintick) : na
    plot(stop_price ? stop_price : stop_price[1], "Stop price", color.red, 2, plot.style_linebr)
    
    // Submit entry orders
    
    if enterLong and not in_market
        strategy.order(id="Long", long=true, qty=posSize)
    
    if enterShort and not in_market
        strategy.order(id="Short", long=false, qty=posSize)
    
    // Submit exit orders
    if is_long
        strategy.exit("Long", limit=exitLong ? close : na, stop=stop_price)
    if is_short
        strategy.exit("Short", limit=exitShort ? close : na, stop=stop_price)
    

    【讨论】:

    • 另外,如果您希望新订单仅在您不在市场中时发生,您可以将and not opened_order 添加到 enterLong 和 enterShort 条件
    • 感谢 Eduardo 花时间帮助我。但是,问题仍然存在。该策略没有退出应有的位置。我上传了一张图片供您在这里查看。 ibb.co/5W01nLZ 此外,在图像中,止损显示在多头头寸的入场价上方。所以我不太确定代码在做什么。再次感谢
    • 哈桑,经过大量的神经牺牲,我认为它起作用了。我已经更新了原始帖子的代码。 Pine Script 的问题是它不允许输入具有价格、止损和已定义目标的订单,因此我必须启用calc_on_order_fills 并重写止损计算。
    • 我也不推荐使用收盘价和 200 个刻度作为止损,因为价格很容易达到那个 (i.imgur.com/BgOSFDW.png)。我更喜欢使用发出信号的蜡烛的高点。
    猜你喜欢
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2011-06-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多