'Tradingview - Pinescript and strategy issues

I'm not a coder but doing my best :)

I have made some code for tradingview where I use ema's and hoffman strategy to open and close orders.

First it was an indicator code but now I want to rewrite it into a strategy code and here it goes wrong.

Somehowe the strategy part does not work as planned and I am stuck. The strategy should enter a long order when c_long is true, at c_longEntryPrice with a stoploss of c_longStopPrice and take profit of c_longExitPrice. The lines are drawn into the chart and the label is added to it with the values of the prices, so that part is OK

If the order is entered and for the comming 5 bars the EntryPrice is not hit (order not filled) the order should be canceled. This is not working as intended.

When I look at the triangle of the the long entry order it is not located at the c_longEntryPrice level but at the [open] price level of the new bar. Is this normal???

If someone could help would be great and helpfull.

Regards, JLo

here is the code I have already written

//@version=5
strategy("3min Hoffman and MA Slope scalping", shorttitle="3min HS", format=format.price, precision=0, overlay=true)

var g_strategy        = "Strategy waarden"

i_longProfitPerc    = input.float(title='Long TP (%)', minval=0.5, step=0.5, defval=1, inline='2', group= g_strategy) * 0.01
i_shortProfitPerc   = input.float(title='Short TP (%)', minval=0.5, step=0.5, defval=1, inline='2', group= g_strategy) * 0.01
i_entryPerc         = input.float(title='Entry Point (%)', minval=0.05, step=0.01, defval=0.10, group= g_strategy) * 0.01
i_mntMargin         = input.float(title='mnt Margin (%)', minval=0.5, step=0.5, defval=1.0, group= g_strategy) * 0.01
i_Leverage          = input.float(title='Leverage', minval=0, step=5, defval=10, group= g_strategy)
i_investment        = input.float(title='Investment', minval=10, step=5, defval=10, group= g_strategy)

var g_hof           = "Hoffman Inventory Retractment %" 
i_irpChk            = input.bool(title = "Use Hoffman Inventory Retractment", defval = true, group = g_hof, tooltip = "Use retractment criterea for evaluation or not")
i_irp               = input.int(title = "Inventory Retracement Percentage %",defval=35, maxval=100, group = g_hof)
i_candlePosChk      = input.bool(title = "Check Candle position vs emaFast", defval = true, group = g_hof, tooltip = "Check if Candle is totally below or above emaFast")

var g_ema           = "EMA trend"
i_emaGapChk         = input.bool(title = "Use Ema Gap", defval = true, group = g_ema, tooltip = "Gap between Emas must be greater than % of the whole security price,\neg. 0.1 = 0.1% of the security price which is the minimum gap tolerated for an entry")
i_emaGap            = input.float(title = "Ema Gap %", defval = 0.1, step = 0.01, group = g_ema)
i_emaslowChk        = input.bool(title = "Use slow Ema", defval = true, group = g_ema, tooltip = "Use slow EMA for Bull or Bearish criterea")
i_emalongChk        = input.bool(title = "Use long Ema", defval = false, group = g_ema, tooltip = "Use long EMA for Bull or Bearish criterea")
i_emaSlopePeriod    = input.int(title="Bars back for slope cal.", defval=5, minval = 1, group = g_ema, tooltip = "Lookback period for Slope of EMA values")
i_slope             = input.int(title="Slope for EMA trend", defval=20, minval = 15, step = 1, group = g_ema, tooltip = "Slope for Slope period EMA values")

// Get Ema trend Lines and conditions
c_emaFast = ta.sma(close, 5)
c_emaSlow = ta.ema(close, 18)
c_emaSSlow = ta.ema(close, 144)

c_emaGap = math.abs(c_emaFast - c_emaSlow) >= ((close / 100) * i_emaGap)

c_emaLong = (i_emaslowChk ? c_emaFast >= c_emaSlow : true) and (i_emalongChk ? c_emaSlow >= c_emaSSlow : true) and (i_emaGapChk ? c_emaGap : true)
c_emaShort = (i_emaslowChk ? c_emaFast < c_emaSlow :true) and (i_emalongChk ? c_emaSlow < c_emaSSlow : true) and (i_emaGapChk ? c_emaGap : true)

// Plot
plot(c_emaFast, "Ema fast", color = color.yellow, linewidth = 2, display = display.all)
plot(c_emaSlow, "Ema slow", color = color.orange, linewidth = 2, display = display.all)
plot(c_emaSSlow, "Ema long", color = color.red, linewidth = 2, display = display.all)

// Get Hoffman inventory retractments my code
Total = math.abs(high - low) // Candle Range 100%
dlong = (close > open ? math.abs(high - close) : math.abs(high - open))
dshort = (close < open ? math.abs(close - low) : math.abs(low-open)) 
perc = i_irp/100 // Percent 45% to Decimal 0.45

// Price Level % for Retracement
dl = dlong / Total
ds = dshort / Total
db = math.abs(open-close) / Total

c_hoffLongMy = dl > perc //and open < close 
c_hoffShortMy = ds > perc //and open > close 

c_hoffLong = (i_irpChk ? c_hoffLongMy : true) and (i_candlePosChk ? low > c_emaFast : true) 
c_hoffShort = (i_irpChk ? c_hoffShortMy : true) and (i_candlePosChk ? high < c_emaFast : true)

// Angle of emaFast Slope
i_src = ohlc4

angle(_i_src) =>
    rad2degree = 180 / 3.14159265359  //pi 
    ang = rad2degree * math.atan((_i_src[0] - _i_src[1]) / ta.atr(14))
    ang

c_slope = angle(c_emaFast)

c_longSlope = c_slope >= i_slope
c_shortSlope = c_slope <= -i_slope

// Plot 
plotshape(c_hoffLong, style=shape.triangleup, location=location.belowbar, color=color.green, title = "Long Bar")
plotshape(c_hoffShort, style=shape.triangledown, location=location.abovebar, color=color.red, title = "Short Bar")

c_longCondition = c_hoffLong and c_emaLong and c_longSlope
c_shortCondition = c_hoffShort and c_emaShort and c_shortSlope

// Entry point
c_longEntryPrice = high * (1 + i_entryPerc)
c_shortEntryPrice = low * (1 - i_entryPerc)

// Exit point
c_longExitPrice = c_longEntryPrice * (1 + i_longProfitPerc)
c_shortExitPrice = c_shortEntryPrice * (1 - i_shortProfitPerc)

c_shortLiqPrice=c_shortEntryPrice * (1 + (1 / i_Leverage) - i_mntMargin)
c_longLiqPrice=c_longEntryPrice * (1 - (1 / i_Leverage) + i_mntMargin)

// StopLoss point
c_longStopPrice = low * (1 - i_entryPerc)
c_shortStopPrice = high * (1 + i_entryPerc)

c_longStopvsLiq = (c_longStopPrice > c_longLiqPrice) ? true : false
c_shortStopvsLiq = (c_shortStopPrice < c_shortLiqPrice) ? true : false

// Quantity of contracts
c_longDistSL = math.abs(c_longStopPrice - c_longEntryPrice) / c_longEntryPrice
c_shortDistSL = math.abs(c_shortEntryPrice - c_shortStopPrice) / c_shortEntryPrice

c_longQtyContractsT = (i_investment / c_longEntryPrice) / c_longDistSL
c_shortQtyContractsT = (i_investment / c_shortEntryPrice) / c_longDistSL

c_longQtyContractsUSD = (i_investment / c_longDistSL)
c_shortQtyContractsUSD = (i_investment / c_longDistSL)

longQtyContractsTicker=str.format("{0,number,#.###}", c_longQtyContractsT)
shortQtyContractsTicker=str.format("{0,number,#.###}", c_shortQtyContractsT)
longQtyContractsUSD=str.format("{0,number,#}", c_longQtyContractsUSD)
shortQtyContractsUSD=str.format("{0,number,#}", c_shortQtyContractsUSD)

// Plot order lines
var line EntryLine = na
var line StopLine = na
var line LiqLine = na
var line ExitLine = na

c_longLabelHeight=hl2 + 0.015*hl2
c_shortLabelHeight=hl2 - 0.015*hl2

c_short =c_shortCondition and barstate.isconfirmed and c_shortStopvsLiq
c_long = c_longCondition and barstate.isconfirmed and c_longStopvsLiq

if c_short
    label.new(x=bar_index, y=c_longLabelHeight, style=label.style_label_down,
         color=color.rgb(60, 60, 70), textcolor=color.white, size=size.large,
         text= "Short" + "\n\n Entry - " + str.tostring(c_shortEntryPrice, format.mintick) + "\nQty T   - " + str.tostring(shortQtyContractsTicker) + "\nQty $   - " + str.tostring(shortQtyContractsUSD) + "\nStop - " + str.tostring(c_shortStopPrice, format.mintick) + "\n  Exit - " + str.tostring(c_shortExitPrice, format.mintick) + "\n Liq - " + str.tostring(c_shortLiqPrice, format.mintick))
    EntryLine := line.new(bar_index, c_shortEntryPrice, bar_index + 5,c_shortEntryPrice, color = color.gray, width = 2)
    StopLine := line.new(bar_index, c_shortStopPrice, bar_index + 5, c_shortStopPrice, color = color.red, width = 2)
    LiqLine := line.new(bar_index, c_shortLiqPrice, bar_index + 5, c_shortLiqPrice, color = color.orange, width = 2)
    ExitLine := line.new(bar_index, c_shortExitPrice, bar_index + 5, c_shortExitPrice, color = color.green, width = 2)
    //HalfLine := line.new(bar_index, c_shortHalfStopPrice, bar_index + 5, c_shortHalfStopPrice, color = color.yellow, width = 2)

if c_long
    label.new(x=bar_index, y=c_shortLabelHeight, style=label.style_label_up,
         color=color.rgb(60, 60, 70), textcolor=color.white, size=size.large,
         text="Long" + "\n\n Entry - " + str.tostring(c_longEntryPrice, format.mintick) + "\nQty T  - " + str.tostring(longQtyContractsTicker) + "\nQty $  - " + str.tostring(longQtyContractsUSD) + "\nStop - " + str.tostring(c_longStopPrice, format.mintick) + "\n  Exit - " + str.tostring(c_longExitPrice, format.mintick) + "\n Liq - " + str.tostring(c_longLiqPrice, format.mintick))
    EntryLine := line.new(bar_index, c_longEntryPrice, bar_index + 5,c_longEntryPrice, color = color.gray, width = 2)
    StopLine := line.new(bar_index, c_longStopPrice, bar_index + 5, c_longStopPrice, color = color.red, width = 2)
    LiqLine := line.new(bar_index, c_longLiqPrice, bar_index + 5, c_longLiqPrice, color = color.orange, width = 2)
    ExitLine := line.new(bar_index, c_longExitPrice, bar_index + 5, c_longExitPrice, color = color.green, width = 2)

// Send out an alert if this candle meets our conditions
alertcondition((c_long) or c_short, title="condition Alert!", message="!! Long/Short order Alarm !!")

shouldPlaceOrderlong = c_long
BarsSincePlacingOrderlong = ta.barssince(shouldPlaceOrderlong)
CancelLong = BarsSincePlacingOrderlong == 5 and strategy.position_size == 0

shouldPlaceOrdershort = c_short
BarsSincePlacingOrdershort = ta.barssince(shouldPlaceOrdershort)
CancelShort = BarsSincePlacingOrdershort == 5 and strategy.position_size == 0
    
plotshape(CancelLong ? c_longLabelHeight : na, location=location.absolute, style=shape.labeldown, color=color.gray, textcolor=color.white, text="cancel\nlong", size=size.tiny)
plotshape(CancelShort ? c_shortLabelHeight : na, location=location.absolute, style=shape.labelup, color=color.gray, textcolor=color.white, text="cancel\nshort", size=size.tiny)

strategy.entry("Long", strategy.long, when=c_long)
strategy.exit("XLong", from_entry="Long", limit=c_longExitPrice)
strategy.cancel("Long", when = CancelLong)

strategy.entry("Short", strategy.short, when=c_short)
strategy.exit("XShort", from_entry="Short", limit=c_shortExitPrice)
strategy.cancel("Short", when = CancelShort)

if c_long
    alertsyntax_c_long='long Entry=' + str.tostring(c_longEntryPrice) + ' Stoploss [SL]=' + str.tostring(c_longStopPrice) + ' Exit [TP]=' + str.tostring(c_longExitPrice)
    alert(message=alertsyntax_c_long, freq=alert.freq_once_per_bar_close)
if c_short
    alertsyntax_c_short='short Entry=' + str.tostring(c_shortEntryPrice) + ' Stoploss [SL]=' + str.tostring(c_shortStopPrice) + ' Exit [TP]=' + str.tostring(c_shortExitPrice)
    alert(message=alertsyntax_c_short, freq=alert.freq_once_per_bar_close)
if CancelLong
    alertsyntax_cancellong='cancel long'
    alert(message=alertsyntax_cancellong, freq=alert.freq_once_per_bar_close)
if CancelShort
    alertsyntax_cancelshort='cancel short'
    alert(message=alertsyntax_cancelshort, freq=alert.freq_once_per_bar_close)


Solution 1:[1]

to open at the same candle (close) you need to add in the strategy line on top: process_orders_on_close = true

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Antonio Signore