IndyDave
IndyDave

Reputation: 3

How can I fix a pine script strategy.exit error when I am missing one of the parameters, but they appear to be present in the code?

I am receiving this error message when trying to convert a Pine Script v4 strategy to Pine Script v5.

strategy.exit must have at least one of the following parameters: 'profit', 'limit', 'loss', 'stop' or one of the following pairs: 'trail_offset' and 'trail_price' / 'trail_points'. To close the position at market price, use 'strategy.close'

Here is the code:

// This source code is subject to the terms of the Mozilla Public 
License 2.0 at https://mozilla.org/MPL/2.0/
// © IndyDave

//@version=4

strategy("SMA-EMA+BB+OBV", overlay=true, initial_capital = 10000, 
currency = currency.USD, slippage = 12)

// Input parameters
smaLength = input(14, title="SMA Length", type=input.integer)
emaLength = input(31, title="EMA Length", type=input.integer)
bbLength = input(6, title="Bollinger Bands Length", 
type=input.integer)
bbStdDev = input(2, title="Bollinger Bands Standard Deviation", 
type=input.float, step = .25)
obvLength = input(9, title="OBV Length", type=input.integer)
obvThreshold = input(0.1, title="OBV Threshold", type=input.float)
bbwThreshold = input(.1, title="BBW Threshold", type=input.float, 
step = .05)
trailStop = input(14, title="Trailing Stop Loss Percentage", 
type=input.float, step = .5) / 100
stopLoss = input(2.7, title="Stop Loss Percentage", type=input.float, 
step = .05) / 100
maLen = input(100,'MA Filter Length',type = input.integer, step = 25)

// Custom Position Size Inputs
positionSizeType = input("Percentage of Equity", title="Position Size 
Type", options=["Risk of Equity Percentage", "Percentage of Equity", 
"Set Dollar Size", "Set Contract Size"])
riskEquityPercentage = input(1, title="Risk of Equity Percentage", 
type=input.float, step = .05) / 100
percentageOfEquity = input(10, title="Percentage of Equity", 
type=input.float) / 100
flatDollarSize = input(1000, title="Set Dollar Size", 
type=input.float)
flatContractSize = input(1, title="Set Contract Size", 
type=input.integer)
leverageAmount = input(1, title="Leverage Amount", 
type=input.integer)
limitPositionSize = input(false,'Limit Position Size', type = 
input.bool,tooltip = 'Limit position size to strategy equity * 
leverage amount')
limitExchangeMax = input(false,'Limit Exchange Maximum',type = 
input.bool,tooltip = 'Limit position size to a certain amount set by 
the exchange')
exchangeMaxSize = input(0,'Exchange Max Contract Size', type = 
input.integer)

//Alerts

longEntryAlert = input(title="Long Entry Alert Message", 
type=input.string, defval="Take Profit: {{longTP}}\nStop Loss: 
{{longSL}}\nQty: {{qty}}")
longExitAlert = input(title="Long Exit Alert Message", 
type=input.string, defval="Long Exit")
shortEntryAlert = input(title="Short Entry Alert Message", 
type=input.string, defval="Take Profit: {{shortTP}}\nStop Loss: 
{{shortSL}}\nQty: {{qty}}")
shortExitAlert = input(title="Short Exit Alert Message", 
type=input.string, defval="Short Exit")

// Position Size Calculation
capital = strategy.equity * leverageAmount
var float customPositionSize = na

if positionSizeType == "Risk of Equity Percentage"
    customPositionSize := capital * riskEquityPercentage / (close * 
stopLoss) 
else if positionSizeType == "Percentage of Equity"
    customPositionSize := capital * percentageOfEquity / close 
else if positionSizeType == "Set Dollar Size"
    customPositionSize := flatDollarSize / close * leverageAmount
else
    customPositionSize := flatContractSize 

if limitPositionSize and customPositionSize > (strategy.equity * 
leverageAmount) / close
    customPositionSize := (strategy.equity * leverageAmount) / close 

if limitExchangeMax and customPositionSize > exchangeMaxSize
    customPositionSize := exchangeMaxSize



// Calculations
smaLine = sma(close, smaLength)
emaLine = ema(close, emaLength)
[upperBand, middleBand, lowerBand] = bb(close, bbLength, bbStdDev)
bandWidth = upperBand - lowerBand

// On-Balance Volume (OBV) Calculation
custom_obv = cum(change(close) > 0 ? volume : change(close) < 0 ? - 
   volume : 0)

//changeClose = change(close)
//custom_obv = cum(changeClose > 0 ? volume : changeClose < 0 ? - 
   volume : 0)
obvSlope = (custom_obv - nz(custom_obv[obvLength])) / obvLength

// Bollinger BandWidth (BBW) Calculation
bbw = (upperBand - lowerBand) / middleBand * 100

// Entry conditions

maFilter = sma(close,maLen)

enterLong = crossover(smaLine, emaLine) and bbw > bbwThreshold and 
obvSlope > obvThreshold and close > maFilter
enterShort = crossunder(smaLine, emaLine) and bbw > bbwThreshold and 
obvSlope < -obvThreshold and close < maFilter

// Trailing stop loss and stop loss
var float longSL = na
var float shortSL = na
var float longTP = na
var float shortTP = na

if strategy.position_size <= 0
    longSL := close * (1 - stopLoss)

if strategy.position_size >= 0
    shortSL := close * (1 + stopLoss)

// Define the alert messages
alert_messageLongEntry = str.replace_all(longEntryAlert, " 
{{longTP}}", tostring(longTP))
alert_messageLongEntry := str.replace_all(alert_messageLongEntry, " 
{{longSL}}", tostring(longSL))
alert_messageLongEntry := str.replace_all(alert_messageLongEntry, " 
{{qty}}", tostring(customPositionSize))
alert_messageLongEntry := str.replace_all(alert_messageLongEntry, " 
{{leverage}}", tostring(leverageAmount))


alert_messageShortEntry = str.replace_all(shortEntryAlert, " 
{{shortTP}}", tostring(shortTP))
alert_messageShortEntry := str.replace_all(alert_messageShortEntry, " 
{{shortSL}}", tostring(shortSL))
alert_messageShortEntry := str.replace_all(alert_messageShortEntry, " 
{{qty}}", tostring(customPositionSize))
alert_messageShortEntry := str.replace_all(alert_messageShortEntry, " 
{{leverage}}", tostring(leverageAmount))



// Execute trades

if enterLong

strategy.entry("Long", strategy.long, qty=customPositionSize, alert_message = alert_messageLongEntry)

if enterShort
strategy.entry("Short", strategy.short, qty=customPositionSize, alert_message = alert_messageShortEntry)



if strategy.position_size > 0
    strategy.exit("Exit Long", "Long", stop = longSL, trail_points=trailStop * close)

if strategy.position_size < 0
    strategy.exit("Exit Short", "Short", stop = shortSL, trail_points=trailStop * close)

I asked ChatGPT for help and it just returns my same code back to me. Where is my mistake? The code appears to work fine in v4.

Upvotes: 0

Views: 233

Answers (1)

G.Lebret
G.Lebret

Reputation: 3108

In your error message, it is stated that you must define a the PAIR : 'trail_offset' / 'trail_points'

strategy.exit must have at least one of the following parameters: 'profit', 'limit', 'loss', 'stop' or one of the following pairs: 'trail_offset' and 'trail_price' / 'trail_points'.

Your strategy.exit (V4) use trail_points = trailStop .

In strategy.exit (V5), if you use trail_points = trailStop, you must also define : trail_offset

trail_offset (series int/float) An optional parameter. Trailing stop price (specified in ticks). The offset in ticks to determine initial price of the trailing stop order: X ticks lower than 'trail_price' or 'trail_points' to exit long position; X ticks higher than 'trail_price' or 'trail_points' to exit short position. The default value is 'NaN'.

So you should define your trail_offset in v4, then convert your script in v5.

Upvotes: 0

Related Questions