简体   繁体   中英

Pine Script: How to cancel order if not filled on bar after entry condition is met?

Trying to use barssince function to cancel entry order.

Want it to cancel if not filled on same candle order is placed/on candle following entry condition being met. I can't understand why it does not work it seems so simple.

rp1 = close[1] >= open [1] and close < open and high >= high[1] 

rp1p = highest(high,1)

plotshape(rp1, style=shape.circle, location=location.abovebar, color=color.red)

if rp1 and strategy.opentrades == 0 
    
    strategy.entry("RP", strategy.long, stop=rp1p)
    
    strategy.cancel("RP", when = barssince(rp1 and strategy.opentrades == 0) == 1)

I have faced the same issue. Pine seems to have a limitation that strategy.opentrades is only changed when the entry is effectively performed.

Initially, I tried to use the following code to cancel my entry not filled:

candlesToEntrytInput = input.int(defval=3, title="Limit in candles to trigger")

longConditionWasMet = <enter the rule for trading signal here>
targetPrice = <enter the entry price here>

entryID = "Entry:\n" + str.tostring(bar_index)

strategy.entry(entryID, strategy.long, stop=targetPrice, when=longConditionWasMet)

for tradeNumber = 0 to strategy.opentrades - 1
    tradeEntryID  = strategy.opentrades.entry_id(tradeNumber)
    splitPosition = str.pos(tradeEntryID, ":")
    signalBar     = str.tonumber(str.substring(traderEntryID, splitPosition + 1))
    entryIsNoLongerValid = bar_index - signalBar == candlesToEntrytInput and strategy.opentrades.size(tradeNumber) == 0
    strategy.cancel(traderEntryID, when=entryIsNoLongerValid)

That approach didn't work either. So I tried another solution:

shouldCancelEntry = ta.barssince(longConditionWasMet) == candlesToEntrytInput and strategy.position_size == 0
strategy.cancel(entryID, when=shouldCancelEntry)

This second approach actually works. However, the problem is when two consecutive long signals occur, in which case the logic fails.

It would be nice if the strategy.entry statement had an parameter called thresholdInCandlesToEntry . That would solve this issue.

I am working in a workaround in which I use a helper array to control my signals against strategy.opentrades . I will share my solution once it is complete.

Here my solution:

// LONG strategy
var myLongOrders = array.new_int(0)
longtEntryID     = "Long Entry:\n" + str.tostring(bar_index)
longExitID       = "Long Exit:\n" + str.tostring(bar_index)
stopLossInLong   = <target to be defined>
takeProfitInLong = <target to be defined>

longEntryHasBeenMet = <enter your LONG condition here>

// Scheduling LONG entry
if longEntryHasBeenMet
    array.push(myLongOrders, bar_index)
    strategy.order(longtEntryID, strategy.long, stop=high)
    strategy.exit(longExitID, longtEntryID, stop=stopLossInLong, limit=takeProfitInLong)

// In pine script, any order scheduled but not yet filled can be canceled.
// However, once a order is filled, the trade is only finished with use of close or exit functions.
// As scheduled orders are not stored in the strategy.opentrades array, manual control is required.
for myOrderIndex = 0 to (array.size(myLongOrders) == 0 ? na : array.size(myLongOrders) - 1)
    myLongOrder = array.get(myLongOrders, myOrderIndex)
    if bar_index - myLongOrder == thresholdForEntryInput
        longEntryID = "Long Entry:\n" + str.tostring(myLongOrder)
        strategy.cancel(longEntryID)

For more details, please see the script J2S Backtest: 123-Stormer Strategy that I shared in the community.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM