Giancarlo Bianchi
Giancarlo Bianchi

Reputation: 35

How do I keep Alerts to fire when trade in opposite direction?

I have a strategy that connects to the broker with alerts (3commas style), but I am able to trade in both directions. The problem is that alerts keep firing when the close_long condition is met while still in a short position, how do I let the strategy know to not fire signals while trade is still on on the opposite direction or even no trade. Would be better if they just fire while in a trade in the direction they are meant to fire.

To be clear, conditions to enter short are the same as close long.

I know you could add this: if strategy.opentrades > 0 // There is an open order

if strategy.position_size > 0 // The open order is a LONG
    na
else if strategy.position_size < 0 // The open order is a SHORT
    na

But it didn't seem to work, specially if the strategy has some drawdown.

I also would like to avoid any kind of redundancy in the signals, as you can see I have many variables that should apply to a trade to take place, but I don't want multiple orders to be fired. But I don't want to wait till the candle is close for the alert to fire, specially in the stoploss signal.

This is the code I am using:

`//@version=5
strategy("Variety-N-Tuple Okx GALAUSDT 5m", overlay=true, commission_type=strategy.commission.percent, commission_value=0.05, initial_capital=100, default_qty_type=strategy.cash, default_qty_value=100, currency=currency.USD)
import loxx/loxxexpandedsourcetypes/4

greencolor = #2DD204
redcolor = #D2042D 
lightgreencolor = #96E881 
lightredcolor =  #DF4F6C

fact(int n)=>
    float out = 1
    for i = 1 to n 
        out *= i
    out

// TradingView user @lejmer was a key player in making this function come to life
nema(string nematype, float src, int per, int dpth, int mxdpth) =>
    var float[] coeff = array.new<float>(mxdpth + 1, 0.)
    if barstate.isfirst
        int nemadpth = math.max(math.min(dpth, mxdpth), 1)
        for k = 0 to dpth 
            array.set(coeff, k, nz(fact(dpth) / (fact(dpth - k) * fact(k)), 1))
            
    var float[] workarr = array.new<float>(dpth + 1, 0)
    array.set(workarr, 0, src)
    int sign = 1
    float nema = 0.
    float alpha = nematype == "EMA" ? 2.0 / (1.0 + per) : 1 / per
    for k = 0 to dpth - 1 
        temp = array.get(workarr, k + 1) + alpha * (array.get(workarr, k) - array.get(workarr, k + 1))
        array.set(workarr, k + 1, temp)
        nema += temp * sign * array.get(coeff, k + 1)
        sign *= -1
    nema

adaptvieATR(float src, int per)=>
    float mper = (per > 1) ? per : 1
    float mfast = math.max(mper / 2.0, 1)
    float mslow = mper * 5
    float mperDiff = mslow - mfast
    
    float noise = 0., float aatr = 0.
    float diff = math.abs(src - nz(src[1]))
    float signal = math.abs(src - nz(src[mper]))
    noise := nz(noise[1]) + diff - nz(diff[mper])
    float avgper = (noise != 0) ? (signal / noise) * mperDiff + mfast : mper
    aatr := nz(aatr[1]) + (2.0 / (1.0 + avgper)) * ((high - low) - nz(aatr[1]))  
    aatr
    
adaptiveDeviation(float price, int per)=>
    float m_per = (per > 1) ? per : 1
    float m_fastEnd = math.max(m_per / 2.0, 1)
    float m_slowEnd = m_per * 5
    float m_perDiff = m_slowEnd - m_fastEnd
    
    float difference = math.abs(ta.change(price))
    float signal = 0.
    float noise = 0.
    
    if bar_index > m_per 
        signal := math.abs(price - nz(price[m_per]))
        noise := nz(noise[1]) + difference - nz(difference[m_per])
    else
        for k = 0 to m_per - 1
            noise += nz(difference[k])
    
    float averageper = (signal /noise) * m_perDiff + m_fastEnd
    float alpha = 2.0 / (1.0 + averageper)
    float ema0 = 0., float ema1 = 0.
    ema0 := nz(ema0[1]) + alpha * (price - nz(ema0[1]))
    ema1 := nz(ema1[1])  + alpha * (price * price - nz(ema1[1]))
    float out = math.sqrt(averageper * (ema1 - ema0 * ema0) / math.max(averageper - 1, 1))
    out
    
fmedian(float src, int per)=>
    int midlea = 0
    int midleb = 0
    float[] sortMed = array.new<float>(per, 0.)
    if (per % 2) == 0
        midlea := int((per / 2) - 1)
        midleb := int(per / 2)
    else  
        midlea := int((per - 1) / 2)
        midleb := int(midlea)
    for k = 0 to per - 1
        array.set(sortMed, k, nz(src[k]))
    array.sort(sortMed)
    out = (array.get(sortMed, midlea) + array.get(sortMed, midleb)) / 2
    out
    
filt(float src, simple int len, float filter, filtper, type)=>
    float price = src
    float atr = ta.atr(len)
    float std = ta.stdev(src, len)
    float addev = adaptiveDeviation(src, len)
    float aatr = adaptvieATR(src, len)
    float out = fmedian(src, len)
    float mad = fmedian(math.abs(src - out), filtper)
    float filtdev = filter * (type == "ATR" ? atr: type == "Standard Deviation" ? std : type == "Median Absolute Deviation" ? mad : type == "Adaptive Deviation" ? addev : aatr)
    price := math.abs(price - nz(price[1])) < filtdev ? nz(price[1]) : price
    price
    
banVal(float src, simple int len, float filter, filtper, type)=>
    float atr = ta.atr(len)
    float std = ta.stdev(src, len)
    float addev = adaptiveDeviation(src, len)
    float aatr = adaptvieATR(src, len)
    float out = fmedian(src, len)
    float mad = fmedian(math.abs(src - out), filtper)
    float regdev = ta.dev(src, len)
    float filtdev = filter * (type == "ATR" ? atr : type == "Standard Deviation" ? std : 
         type == "Median Absolute Deviation" ? mad : type == "Adaptive Deviation" ? addev : type == "ER-Adaptive ATR" ? aatr : regdev)
    filtdev
    
smthtype = input.string("Kaufman", "Heiken-Ashi Better Smoothing", options = ["AMA", "T3", "Kaufman"], group=  "Source Settings")
srcoption = input.string("HAB Typical", "Source", group= "Source Settings", 
     options = 
     ["Close", "Open", "High", "Low", "Median", "Typical", "Weighted", "Average", "Average Median Body", "Trend Biased", "Trend Biased (Extreme)", 
     "HA Close", "HA Open", "HA High", "HA Low", "HA Median", "HA Typical", "HA Weighted", "HA Average", "HA Average Median Body", "HA Trend Biased", "HA Trend Biased (Extreme)",
     "HAB Close", "HAB Open", "HAB High", "HAB Low", "HAB Median", "HAB Typical", "HAB Weighted", "HAB Average", "HAB Average Median Body", "HAB Trend Biased", "HAB Trend Biased (Extreme)"])

per = input.int(13, "Period", group = "Basic Settings")
nemadpth = input.int(3, "Depth", maxval = 50, minval = 1, group = "Basic Settings")
nematype = input.string("EMA", "Moving Average Type", options = ["EMA", "RMA"] , group = "Basic Settings")

ptype = input.string("ATR", "Price Filter Type", options = ["ATR", "Standard Deviation", "Median Absolute Deviation", "Adaptive Deviation", "ER-Adaptive ATR", "Mean Absolute Deviation"], group=  "Filter Settings")
matype = input.string("ATR", "Moving Average Filter Type", options = ["ATR", "Standard Deviation", "Median Absolute Deviation", "Adaptive Deviation", "ER-Adaptive ATR", "Mean Absolute Deviation"], group=  "Filter Settings")
filterop = input.string("Both", "Filter Options", options = ["Price", "Moving Average Filter", "Both", "None"], group=  "Filter Settings")
filter = input.float(1, "Filter Multiplier", minval = 0, group= "Filter Settings")
filterperiod = input.int(10, "Filter Period", minval = 0, group= "Filter Settings")
madper = input.int(10, "MAD Internal Filter Period", minval = 0, group= "Filter Settings", tooltip = "Median Absolute Deviation only")

bndtype = input.string("ATR", "Band Type Type", options = ["ATR", "Standard Deviation", "Median Absolute Deviation", "Adaptive Deviation", "ER-Adaptive ATR", "Mean Absolute Deviation"], group=  "Bands Settings")
bndmult = input.float(1, "Band Multiplier", minval = 0, group= "Bands Settings")

colorbars = input.bool(true, "Color bars?", group = "UI Options")
showSigs = input.bool(true, "Show signals?", group= "UI Options")
showBands = input.bool(true, "Show bands?", group= "UI Options")

kfl=input.float(0.666, title="* Kaufman's Adaptive MA (KAMA) Only - Fast End", group = "Moving Average Inputs")
ksl=input.float(0.0645, title="* Kaufman's Adaptive MA (KAMA) Only - Slow End", group = "Moving Average Inputs")
amafl = input.int(2, title="* Adaptive Moving Average (AMA) Only - Fast", group = "Moving Average Inputs")
amasl = input.int(30, title="* Adaptive Moving Average (AMA) Only - Slow", group = "Moving Average Inputs")

haclose = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
haopen = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, open)
hahigh = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, high)
halow = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, low)
hamedian = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hl2)
hatypical = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlc3)
haweighted = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, hlcc4)
haaverage = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, ohlc4)

float src = switch srcoption
    "Close" => loxxexpandedsourcetypes.rclose()
    "Open" => loxxexpandedsourcetypes.ropen()
    "High" => loxxexpandedsourcetypes.rhigh()
    "Low" => loxxexpandedsourcetypes.rlow()
    "Median" => loxxexpandedsourcetypes.rmedian()
    "Typical" => loxxexpandedsourcetypes.rtypical()
    "Weighted" => loxxexpandedsourcetypes.rweighted()
    "Average" => loxxexpandedsourcetypes.raverage()
    "Average Median Body" => loxxexpandedsourcetypes.ravemedbody()
    "Trend Biased" => loxxexpandedsourcetypes.rtrendb()
    "Trend Biased (Extreme)" => loxxexpandedsourcetypes.rtrendbext()
    "HA Close" => loxxexpandedsourcetypes.haclose(haclose)
    "HA Open" => loxxexpandedsourcetypes.haopen(haopen)
    "HA High" => loxxexpandedsourcetypes.hahigh(hahigh)
    "HA Low" => loxxexpandedsourcetypes.halow(halow)
    "HA Median" => loxxexpandedsourcetypes.hamedian(hamedian)
    "HA Typical" => loxxexpandedsourcetypes.hatypical(hatypical)
    "HA Weighted" => loxxexpandedsourcetypes.haweighted(haweighted)
    "HA Average" => loxxexpandedsourcetypes.haaverage(haaverage)
    "HA Average Median Body" => loxxexpandedsourcetypes.haavemedbody(haclose, haopen)
    "HA Trend Biased" => loxxexpandedsourcetypes.hatrendb(haclose, haopen, hahigh, halow)
    "HA Trend Biased (Extreme)" => loxxexpandedsourcetypes.hatrendbext(haclose, haopen, hahigh, halow)
    "HAB Close" => loxxexpandedsourcetypes.habclose(smthtype, amafl, amasl, kfl, ksl)
    "HAB Open" => loxxexpandedsourcetypes.habopen(smthtype, amafl, amasl, kfl, ksl)
    "HAB High" => loxxexpandedsourcetypes.habhigh(smthtype, amafl, amasl, kfl, ksl)
    "HAB Low" => loxxexpandedsourcetypes.hablow(smthtype, amafl, amasl, kfl, ksl)
    "HAB Median" => loxxexpandedsourcetypes.habmedian(smthtype, amafl, amasl, kfl, ksl)
    "HAB Typical" => loxxexpandedsourcetypes.habtypical(smthtype, amafl, amasl, kfl, ksl)
    "HAB Weighted" => loxxexpandedsourcetypes.habweighted(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average" => loxxexpandedsourcetypes.habaverage(smthtype, amafl, amasl, kfl, ksl)
    "HAB Average Median Body" => loxxexpandedsourcetypes.habavemedbody(smthtype, amafl, amasl, kfl, ksl)
    "HAB Trend Biased" => loxxexpandedsourcetypes.habtrendb(smthtype, amafl, amasl, kfl, ksl)
    "HAB Trend Biased (Extreme)" => loxxexpandedsourcetypes.habtrendbext(smthtype, amafl, amasl, kfl, ksl)
    => haclose
    
src := filterop == "Both" or filterop == "Price" and filter > 0 ? filt(src, filterperiod, filter, madper, ptype) : src

out = nema(nematype, src, per, nemadpth, 50)

out := filterop == "Both" or filterop == "Moving Average Filter" and filter > 0 ? filt(out, filterperiod, filter, madper, matype)  : out
sig = nz(out[1])

state = out > sig ? 1 : out < sig ? -1 : 0
pregoLong = out > sig and (nz(out[1]) < nz(sig[1]) or nz(out[1]) == nz(sig[1]))
pregoShort = out < sig and (nz(out[1]) > nz(sig[1]) or nz(out[1]) == nz(sig[1]))

contsw = 0
contsw := nz(contsw[1])
contsw := pregoLong ? 1 : pregoShort ? -1 : nz(contsw[1])

goLong = pregoLong and nz(contsw[1]) == -1
goShort = pregoShort and nz(contsw[1]) == 1 

bandout = banVal(src, filterperiod, bndmult, madper, bndtype)
bndup = out + bandout
bnddn = out - bandout

plot(showBands ? bndup : na, "Upper Band", color = color.gray, linewidth = 1)
plot(showBands ? bnddn : na, "Lower Band", color = color.gray, linewidth = 1)

var color colorout = na
colorout := state == -1 ? redcolor : state == 1 ? greencolor : nz(colorout[1])

plot(out, "Step NTMA", color = colorout, linewidth = 2)
barcolor(colorbars ? colorout : na)

//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////// STRATEGY
//////////////////////////////////////////////////////////
 
longCondition= pregoLong and nz(contsw[1]) == -1
shortCondition= pregoShort and nz(contsw[1]) == 1 
closeLongCondition= pregoShort and nz(contsw[1]) == 1 
closeShortCondition= pregoLong and nz(contsw[1]) == -1

/////////////////////////////
// ZLSMA Filter
ZlFilterEnabled = input.bool(defval = true, title = "Enable Zlema Filter", group ="Zlema Filter" ) 
srcZ = input.source(hlcc4, title="Zlema Source")
zlen = input(title='Length', defval=72)
Zoffset = input(title='Offset', defval=0)

lsma = ta.linreg(srcZ, zlen, Zoffset)
lsma2 = ta.linreg(lsma, zlen, Zoffset)
eq = lsma - lsma2
zlsma = lsma + eq
bool ZFSlong = ZlFilterEnabled ? srcZ > zlsma : true
bool ZFSshort = ZlFilterEnabled ? srcZ < zlsma  : true

//////// TFS Volume Filter
i_TFSFilterEnabled = input.bool(defval = true, title = "TFS Volume Filter", group ="TFS Filter" ) 
i_TFSexitEnabled = input.bool(defval = true, title = "TFS Volume Filter on EXIT", group ="TFS Filter" ) 
AvgLen = input.int(6, minval=1)
TopBand = input.int(40000, step=1)
LowBand = input.int(-20000, step=1)
reverse = input(false, title='Trade reverse')
xClose = close
xOpen = open
xVolume = volume
TFSViff_1 = xClose < xOpen ? -xVolume : 0
nVolAccum = math.sum(xClose > xOpen ? xVolume : TFSViff_1, AvgLen)
nRes = nVolAccum / AvgLen
posTFS = 0.0
TFSViff_2 = nRes < LowBand ? -1 : nz(posTFS[1], 0)
posTFS := nRes > TopBand ? 1 : TFSViff_2
TFSViff_3 = reverse and posTFS == -1 ? 1 : posTFS
possig = reverse and posTFS == 1 ? -1 : TFSViff_3
barcolor(possig == -1 ? color.red : possig == 1 ? color.green : color.blue)
bool TFSlong = i_TFSFilterEnabled ? possig == 1 : true
bool TFSshort = i_TFSFilterEnabled ? possig == -1 : true
bool TFSexitlong = i_TFSexitEnabled ? possig == 1 : true
bool TFSexitshort = i_TFSexitEnabled ? possig == -1 : true


// ADX Filter

i_adxFilterEnabled = input.bool(defval = true, title = "Enable ADX Filter", group ="ADX Filter" ) 
i_adxVariant = input.string('MASANAKAMURA', title='ADX Variant', options=['ORIGINAL', 'MASANAKAMURA'], group ="ADX Filter" )
i_adxSmoothing = input.int(12, title="ADX Smoothing", group="ADX Filter")
i_adxDILength = input.int(4, title="DI Length", group="ADX Filter")
i_adxLowerThreshold = input.float(26, title="ADX Threshold", step=.5, group="ADX Filter")

calcADX_Masanakamura2(int _len) =>
    _smoothedTrueRange = 0.0
    _smoothedDirectionalMovementPlus = 0.0
    _smoothed_directionalMovementMinus = 0.0
    _trueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
    _directionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
    _directionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0
    _smoothedTrueRange := nz(_smoothedTrueRange[1]) - nz(_smoothedTrueRange[1]) / _len + _trueRange
    _smoothedDirectionalMovementPlus := nz(_smoothedDirectionalMovementPlus[1]) - nz(_smoothedDirectionalMovementPlus[1]) / _len + _directionalMovementPlus
    _smoothed_directionalMovementMinus := nz(_smoothed_directionalMovementMinus[1]) - nz(_smoothed_directionalMovementMinus[1]) / _len + _directionalMovementMinus
    DIP = _smoothedDirectionalMovementPlus / _smoothedTrueRange * 100
    DIM = _smoothed_directionalMovementMinus / _smoothedTrueRange * 100
    _DX = math.abs(DIP - DIM) / (DIP + DIM) * 100
    adx = ta.sma(_DX, _len)
    [DIP, DIM, adx]

[DIPlusO, DIMinusO, ADXO] = ta.dmi(i_adxDILength, i_adxSmoothing)
[DIPlusM2, DIMinusM2, ADXM2] = calcADX_Masanakamura2(i_adxDILength)

adx = i_adxFilterEnabled and i_adxVariant == "ORIGINAL" ? ADXO : ADXM2
bool isADXFilterEnabledAndAboveThreshold = i_adxFilterEnabled ? adx > i_adxLowerThreshold : true



//////// RSI
i_RSIFilterEnabled = input.bool(defval = false, title = "RSI Filter", group ="RSI Filter" ) 
RSI_Filter_Length = input.int(14, minval=1, title="RSI Length")
RSI_Filter_source = input.source(close, "Source")
rsiup_fiter =input(50, "Rsi Long Threshold")
rsidn_filter =input(50, "Rsi Short Threshold")

RSI_Filter_up = ta.rma(math.max(ta.change(RSI_Filter_source), 0), RSI_Filter_Length)
RSI_Filter_down = ta.rma(-math.min(ta.change(RSI_Filter_source), 0), RSI_Filter_Length)
RSI_filter = RSI_Filter_down == 0 ? 100 : RSI_Filter_up == 0 ? 0 : 100 - (100 / (1 + RSI_Filter_up / RSI_Filter_down))
bool RSIlong = i_RSIFilterEnabled ? RSI_filter > rsiup_fiter : true
bool RSIshort = i_RSIFilterEnabled ? RSI_filter < rsidn_filter : true



///Start / End Time Periods

i_startPeriodEnabled = input.bool(true, 'Start', group='Date Range', inline='Start Period')
i_startPeriodTime = input.time(timestamp('1 Jan 2022'), '', group='Date Range', inline='Start Period')
i_endPeriodEnabled = input.bool(true, 'End', group='Date Range', inline='End Period')
i_endPeriodTime = input.time(timestamp('31 Dec 2030'), '', group='Date Range', inline='End Period')

isStartPeriodEnabledAndInRange = i_startPeriodEnabled ? i_startPeriodTime <= time : true
isEndPeriodEnabledAndInRange = i_endPeriodEnabled ? i_endPeriodTime >= time : true

isStartEndPeriodsAndTimeInRange = isStartPeriodEnabledAndInRange and isEndPeriodEnabledAndInRange

// Trade Direction 

i_tradeDirection = input.string('Long and Short', title='Trade Direction', options=['Long and Short', 'Long Only', 'Short Only'], group='Trade Direction')

// Percent as Points

per(pcnt) =>
    strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)


/// Stop Loss

i_stopLossPercentLong = input.float(title='Stop Loss Long (%)', defval=1.9, minval=0.01, step=0.1) * 0.01
slLongClose = (close < strategy.position_avg_price * (1 - i_stopLossPercentLong))
i_stopLossShort = input.float(title='Stop Loss Short (%)', defval=1.5, minval=0.01, step=0.1) * 0.01
slShortClose = (close > strategy.position_avg_price * (1 + i_stopLossShort))



/// Leverage

i_leverage = input.float(1, 'Leverage', step=1, group='Leverage')
i_percentOfEquityToTrade = input.float(100, "% of Equity to Stake Per Trade", minval=0.01, maxval=100, step=5, group='Leverage') * .01
contracts = (i_percentOfEquityToTrade * strategy.equity / close * i_leverage)

//// Strategy Comment
i_key = input.string(defval='Key', title='Broker Key', group='Strategy Comments')
i_market = input.string(defval='Market', title='Market', group='Strategy Comments')
i_equity = input.string(defval='Equity', title='Equity', group='Strategy Comments')



/// Trade State Management
isInLongPosition = strategy.position_size > 0
isInShortPosition = strategy.position_size < 0


/// Trade Execution
longConditionCalc = (longCondition and isADXFilterEnabledAndAboveThreshold and TFSlong and RSIlong and ZFSlong)
shortConditionCalc = (shortCondition and isADXFilterEnabledAndAboveThreshold and TFSshort and RSIshort and ZFSshort)

closeLongConditionCalc= (closeLongCondition and TFSexitlong and ZFSshort) or shortConditionCalc
closeShortConditionCalc= (closeShortCondition and TFSexitshort and ZFSlong) or longConditionCalc


if isStartEndPeriodsAndTimeInRange
// Long Conditions
    if longConditionCalc and i_tradeDirection != 'Short Only' and isInLongPosition == false
        strategy.entry('Long', strategy.long, qty=contracts)
        alert('{ "xxxx": "openlong", "market": “GALA-PERP", "equity": 20 }', alert.freq_once_per_bar)

    if closeLongConditionCalc
        strategy.close('Long', qty_percent=100)
        alert('{ "xxxx": "closelong", "market": “GALA-PERP", "equity": 100 }', alert.freq_once_per_bar)
    
    if slLongClose
        strategy.close('Long', qty_percent=100)
        alert('{ "xxxx": "closelong", "market": “GALA-PERP", "equity": 100 }', alert.freq_once_per_bar)

// Short Conditions
    if shortConditionCalc and i_tradeDirection != 'Long Only' and isInShortPosition == false
        strategy.entry('Short', strategy.short, qty=contracts)
        alert('{ "xxxx": "openshort", "market": “GALA-PERP", "equity": 20 }', alert.freq_once_per_bar)

    if closeShortConditionCalc
        strategy.close('Short', qty_percent=100)
        alert('{ "xxxx": "closeshort", "market": “GALA-PERP", "equity": 100 }', alert.freq_once_per_bar)

    if slShortClose
        strategy.close('Short', qty_percent=100)
        alert('{ "xxxx": "closeshort", "market": “GALA-PERP", "equity": 100 }', alert.freq_once_per_bar)`

Upvotes: 1

Views: 190

Answers (1)

vitruvius
vitruvius

Reputation: 21121

closelong will fire while you are in a short trade because you don't check if you are in a long position to fire that alarm.

You use closeLongConditionCalc or slLongClose to fire a close long alert. As far as I see, none of them check if you are already in a long position (isInLongPosition).

Obviously, you don't want to call this alert if you are not already in a long position.

Alternatively, you can use the alert_message argument of the strategy.entry(), strategy.exit() and strategy.close() functions which I would recommend.

Upvotes: 1

Related Questions