Please correct Code to allow this to work to backtest and in automatic trading

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #252464 quote
    JJCWMANCH
    Participant
    New

    Hi ProRealTime team,

    I’m building a single ProBacktest/ProOrder strategy that automatically selects among 8 sub-strategies (Trend-Confirmation, Divergence Reversal, Breakout, Pullback, ORB, Mean-Reversion to VWAP, Squeeze→Expansion, and News/Volume-Impulses). It computes a Quality Score gating (0–6, must be ≥4), and then ranks the eligible strategies each bar to decide whether to go long/short. Risk management uses ATR-based stops/targets with an optional trailing stop, and the system trades only 08:00–16:30 London.

    To maximize compatibility, I:

    • Use fractions (e.g., 5/4 instead of 1.25) to avoid decimal-locale issues.

    • Avoid underscores in the key sizing variables.

    • Avoid multiple statements per line.

    • Compute MACD step-by-step (no inline subtraction) and a manual intraday VWAP that resets daily.

    • Keep indicators to standard names: ExponentialAverage, RSI, AverageTrueRange, Average, Lowest.

    Issue we’re hitting:
    Even with the simplifications, the editor frequently flags “Unknown command line 1”, and when we isolate, we get hard errors on lines like:

    • Assignment to macdLine = emaMacdFast - emaMacdSlow (fixed by expanding into two assignments), then

    • The ATR line atr = AverageTrueRange[atrLen] (or with (close)), and earlier we also saw failures when using comma decimals (hence the switch to fractions).

    Could you please confirm, for the IG/ProOrder build we are using:

    1. The exact function signatures expected for:

      • ExponentialAverage[period](priceSeries)

      • RSI[period](priceSeries)

      • AverageTrueRange[period] (with or without (close))

    2. Whether assignments like a = b - c are valid on our build (or if we must use an intermediate variable).

    3. Whether the code below violates any reserved words, naming rules, or requires any additional declarations.

    4. Whether manual daily reset logic (using Day <> Day[1]) is acceptable inside strategies.

    If you can pinpoint which single line is rejected by the current parser (and why), I can adjust it immediately. Thank you!

    —End of message—


    Full strategy file (paste from line 1)

    DEFPARAM CumulateOrders = False DEFPARAM PreLoadBars = 2000 // -------- Session (London) -------- sessionStart = 080000 sessionEnd = 163000 // -------- Risk & sizing (fractions, no decimals) -------- fixedSize = 1 riskATRmult = 5/4 // 1.25 targetRmultiple= 3/2 // 1.50 useTrailingStop= 1 trailATRmult = 1 // 1.00 // -------- Indicator lengths -------- rsiLen = 14 emaFast = 20 emaSlow = 50 macdF = 12 macdS = 26 macdSig = 9 atrLen = 14 rvolLen = 60 // -------- Opening Range window -------- ORStart = 080000 OREnd = 083000 // -------- Quality score threshold -------- minQualityScore = 4 // -------- Divergence swing settings -------- swingLookback = 20 swingDepth = 2 // -------- Cooldown -------- cooldownBarsAfterExit = 1 ONCE lastOrderBar = -100000 // ================== CORE INDICATORS ================== ema20 = ExponentialAverage[emaFast](close) ema50 = ExponentialAverage[emaSlow](close) // --- MACD (stepwise to avoid inline subtraction parser issues) --- emaMacdFast = ExponentialAverage[macdF](close) emaMacdSlow = ExponentialAverage[macdS](close) macdDiff = emaMacdFast macdDiff = macdDiff - emaMacdSlow macdLine = macdDiff macdSignal = ExponentialAverage[macdSig](macdLine) macdHist = macdLine - macdSignal rsi = RSI[rsiLen](close) // --- ATR (confirm signature on your build) --- atr = AverageTrueRange[atrLen] // -------- Manual intraday VWAP (resets daily) -------- ONCE vCumPV = 0.0 ONCE vCumV = 0.0 IF Day <> Day[1] THEN vCumPV = 0.0 vCumV = 0.0 ENDIF tp = (High + Low + Close) / 3 vCumPV = vCumPV + tp * Volume vCumV = vCumV + Volume vwap = 0.0 IF vCumV > 0 THEN vwap = vCumPV / vCumV ENDIF // -------- Relative volume (RVOL) -------- avgVol = Average[rvolLen](Volume) rvol = 0.0 IF avgVol > 0 THEN rvol = Volume / avgVol ENDIF // -------- Candle anatomy -------- barRange = High - Low body = Abs(Close - Open) bodyPct = 0.0 posInBar = 0.0 IF barRange > 0 THEN bodyPct = 100 * body / barRange posInBar = 100 * (Close - Low) / barRange ENDIF // -------- ATR baseline (for quality test) -------- atrBase = Average[100](atr) // -------- Opening Range (first 30m) -------- ONCE ORH = 0.0 ONCE ORL = 0.0 IF Day <> Day[1] THEN ORH = 0.0 ORL = 0.0 ENDIF IF Time = ORStart THEN ORH = High ORL = Low ENDIF IF Time > ORStart AND Time <= OREnd THEN IF High > ORH THEN ORH = High ENDIF IF Low < ORL THEN ORL = Low ENDIF ENDIF IF ORH = 0.0 AND BarIndex > 0 THEN ORH = ORH[1] ORL = ORL[1] ENDIF // -------- Helpers -------- inSession = (Time >= sessionStart AND Time <= sessionEnd) canTradeBar= (BarIndex > lastOrderBar + cooldownBarsAfterExit) // ================== QUALITY SCORE 0..6 ================== q_rvol = 0 IF rvol >= 13/10 THEN q_rvol = 1 ENDIF q_vwapL = 0 IF Close > vwap THEN q_vwapL = 1 ENDIF q_rsi50L = 0 IF rsi > 50 THEN q_rsi50L = 1 ENDIF q_macd0L = 0 IF macdLine > 0 THEN q_macd0L = 1 ENDIF q_candleL = 0 IF bodyPct >= 60 AND posInBar >= 75 THEN q_candleL = 1 ENDIF q_atr = 0 IF atr >= atrBase THEN q_atr = 1 ENDIF qualityLong = q_rvol + q_vwapL + q_rsi50L + q_macd0L + q_candleL + q_atr q_vwapS = 0 IF Close < vwap THEN q_vwapS = 1 ENDIF q_rsi50S = 0 IF rsi < 50 THEN q_rsi50S = 1 ENDIF q_macd0S = 0 IF macdLine < 0 THEN q_macd0S = 1 ENDIF q_candleS = 0 IF bodyPct >= 60 AND posInBar <= 25 THEN q_candleS = 1 ENDIF qualityShort = q_rvol + q_vwapS + q_rsi50S + q_macd0S + q_candleS + q_atr // ================== DIVERGENCE TOOLS ================== isSwingLow = (Low[2] > Low[1] AND Low > Low[1] AND Low[1] < Low[3] AND Low[1] < Low[2]) isSwingHigh = (High[2] < High[1] AND High < High[1] AND High[1] > High[3] AND High[1] > High[2]) ONCE low1Idx = -1 ONCE low2Idx = -1 ONCE low1 = 0.0 ONCE low2 = 0.0 ONCE macdLow1= 0.0 ONCE macdLow2= 0.0 ONCE high1Idx = -1 ONCE high2Idx = -1 ONCE high1 = 0.0 ONCE high2 = 0.0 ONCE macdHigh1= 0.0 ONCE macdHigh2= 0.0 IF isSwingLow THEN low2Idx = low1Idx low2 = low1 macdLow2 = macdLow1 low1Idx = BarIndex - 1 low1 = Low[1] macdLow1 = macdLine[1] ENDIF IF isSwingHigh THEN high2Idx = high1Idx high2 = high1 macdHigh2 = macdHigh1 high1Idx = BarIndex - 1 high1 = High[1] macdHigh1 = macdLine[1] ENDIF validLowSwings = (low1Idx > 0 AND low2Idx > 0 AND (low1Idx - low2Idx) >= swingDepth AND (BarIndex - low1Idx) <= swingLookback) validHighSwings = (high1Idx > 0 AND high2Idx > 0 AND (high1Idx - high2Idx) >= swingDepth AND (BarIndex - high1Idx) <= swingLookback) bullDiv = 0 IF validLowSwings AND low1 < low2 AND macdLow1 > macdLow2 THEN bullDiv = 1 ENDIF bearDiv = 0 IF validHighSwings AND high1 > high2 AND macdHigh1 < macdHigh2 THEN bearDiv = 1 ENDIF // ================== STRATEGY SIGNALS (8) ================== macdBullX = (macdLine crosses over macdSignal) macdBearX = (macdLine crosses under macdSignal) rsiUpFrom30 = (rsi crosses over 30) rsiDnFrom70 = (rsi crosses under 70) emaTrendUp = (ema50 >= ema50[1]) emaTrendDown = (ema50 <= ema50[1]) // 1) MACD–RSI Trend-Confirmation TrendConf_Long = rsiUpFrom30 AND macdBullX AND emaTrendUp TrendConf_Short = rsiDnFrom70 AND macdBearX AND emaTrendDown // 2) RSI+MACD Divergence Reversal reversalBullCandle = (Close > Open AND posInBar >= 65 AND bodyPct >= 50) reversalBearCandle = (Close < Open AND posInBar <= 35 AND bodyPct >= 50) DivRev_Long = (bullDiv = 1 AND rsi < 30 AND reversalBullCandle) DivRev_Short = (bearDiv = 1 AND rsi > 70 AND reversalBearCandle) // 3) RSI Trend Filter + MACD Breakout breakAboveOR = (Time > OREnd AND Close > ORH AND High[1] <= ORH) breakBelowOR = (Time > OREnd AND Close < ORL AND Low[1] >= ORL) RSItrendLong = (rsi > 50) RSItrendShort = (rsi < 50) Breakout_Long = RSItrendLong AND macdBullX AND macdHist > macdHist[1] AND (breakAboveOR OR Close > ema20) AND rvol >= 13/10 Breakout_Short = RSItrendShort AND macdBearX AND macdHist < macdHist[1] AND (breakBelowOR OR Close < ema20) AND rvol >= 13/10 // 4) RSI Pullback + MACD Trend Bias rsiTurnUp = (rsi > rsi[1] AND rsi[1] <= rsi[2]) rsiTurnDown = (rsi < rsi[1] AND rsi[1] >= rsi[2]) Pullback_Long = (macdHist > 0) AND (rsi >= 40 AND rsi <= 50) AND rsiTurnUp AND (Close >= ema20 OR Close >= vwap) AND rvol >= 12/10 Pullback_Short = (macdHist < 0) AND (rsi <= 60 AND rsi >= 50) AND rsiTurnDown AND (Close <= ema20 OR Close <= vwap) AND rvol >= 12/10 // 5) Opening-Range Breakout (ORB) + Trend Filter ORB_Long = (Time > OREnd) AND (Close > ORH) AND emaTrendUp AND rsi > 50 AND macdHist > macdHist[1] AND rvol >= 13/10 ORB_Short = (Time > OREnd) AND (Close < ORL) AND emaTrendDown AND rsi < 50 AND macdHist < macdHist[1] AND rvol >= 13/10 // 6) Mean Reversion to VWAP (fade) farFromVWAP_Long = (Close < vwap AND (vwap - Close) >= (3 * Average[5](atr)) / 2) farFromVWAP_Short = (Close > vwap AND (Close - vwap) >= (3 * Average[5](atr)) / 2) MR_Long = farFromVWAP_Long AND rsi < 30 AND (macdHist > macdHist[1]) AND reversalBullCandle MR_Short = farFromVWAP_Short AND rsi > 70 AND (macdHist < macdHist[1]) AND reversalBearCandle // 7) Volatility Squeeze -> Expansion (ATR squeeze proxy) lowATRNow = (atr <= Lowest[150](atr) * 11/10) Squeeze_Long = lowATRNow AND Close > ema20 AND rsi > 50 AND rvol >= 13/10 AND Close > High[1] Squeeze_Short = lowATRNow AND Close < ema20 AND rsi < 50 AND rvol >= 13/10 AND Close < Low[1] // 8) News / Volume-Spike Reaction (First Pullback) impulseUp = (rvol >= 2 AND bodyPct >= 70 AND Close > vwap AND macdLine > 0) impulseDown = (rvol >= 2 AND bodyPct >= 70 AND Close < vwap AND macdLine < 0) pullbackOK_L = impulseUp AND Close >= ema20 AND rsi > 50 AND macdLine >= 0 pullbackOK_S = impulseDown AND Close <= ema20 AND rsi < 50 AND macdLine <= 0 NewsPB_Long = pullbackOK_L AND (Close > High[1]) NewsPB_Short = pullbackOK_S AND (Close < Low[1]) // ============== ELIGIBILITY + RANKING ============== Elig_TrendConf_L = TrendConf_Long AND (qualityLong >= minQualityScore) Elig_DivRev_L = DivRev_Long AND (qualityLong >= minQualityScore) Elig_Breakout_L = Breakout_Long AND (qualityLong >= minQualityScore) Elig_Pullback_L = Pullback_Long AND (qualityLong >= minQualityScore) Elig_ORB_L = ORB_Long AND (qualityLong >= minQualityScore) Elig_MR_L = MR_Long AND (qualityLong >= minQualityScore) Elig_Squeeze_L = Squeeze_Long AND (qualityLong >= minQualityScore) Elig_NewsPB_L = NewsPB_Long AND (qualityLong >= minQualityScore) Elig_TrendConf_S = TrendConf_Short AND (qualityShort >= minQualityScore) Elig_DivRev_S = DivRev_Short AND (qualityShort >= minQualityScore) Elig_Breakout_S = Breakout_Short AND (qualityShort >= minQualityScore) Elig_Pullback_S = Pullback_Short AND (qualityShort >= minQualityScore) Elig_ORB_S = ORB_Short AND (qualityShort >= minQualityScore) Elig_MR_S = MR_Short AND (qualityShort >= minQualityScore) Elig_Squeeze_S = Squeeze_Short AND (qualityShort >= minQualityScore) Elig_NewsPB_S = NewsPB_Short AND (qualityShort >= minQualityScore) bestLong = -1 bestShort = -1 score = 0 IF Elig_NewsPB_L THEN score = qualityLong + 80 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_ORB_L THEN score = qualityLong + 70 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_Breakout_L THEN score = qualityLong + 60 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_Squeeze_L THEN score = qualityLong + 50 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_Pullback_L THEN score = qualityLong + 40 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_TrendConf_L THEN score = qualityLong + 30 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_MR_L THEN score = qualityLong + 20 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_DivRev_L THEN score = qualityLong + 10 IF score > bestLong THEN bestLong = score ENDIF ENDIF IF Elig_NewsPB_S THEN score = qualityShort + 80 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_ORB_S THEN score = qualityShort + 70 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_Breakout_S THEN score = qualityShort + 60 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_Squeeze_S THEN score = qualityShort + 50 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_Pullback_S THEN score = qualityShort + 40 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_TrendConf_S THEN score = qualityShort + 30 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_MR_S THEN score = qualityShort + 20 IF score > bestShort THEN bestShort = score ENDIF ENDIF IF Elig_DivRev_S THEN score = qualityShort + 10 IF score > bestShort THEN bestShort = score ENDIF ENDIF goLong = (bestLong > bestShort) goShort = (bestShort > bestLong) // ================== ORDERS & RISK ================== sizeToUse = fixedSize riskPoints = atr * riskATRmult IF riskPoints <= 0 THEN riskPoints = 1 ENDIF IF inSession AND canTradeBar THEN IF NOT LongOnMarket AND NOT ShortOnMarket AND goLong THEN lastOrderBar = BarIndex BUY sizeToUse CONTRACTS AT MARKET SET STOP pLOSS riskPoints SET TARGET pPROFIT (targetRmultiple * riskPoints) ENDIF IF NOT LongOnMarket AND NOT ShortOnMarket AND goShort THEN lastOrderBar = BarIndex SELLSHORT sizeToUse CONTRACTS AT MARKET SET STOP pLOSS riskPoints SET TARGET pPROFIT (targetRmultiple * riskPoints) ENDIF ENDIF IF useTrailingStop = 1 THEN IF LongOnMarket AND Close >= TradePrice + riskPoints THEN SET STOP TRAILING (trailATRmult * atr) ENDIF IF ShortOnMarket AND Close <= TradePrice - riskPoints THEN SET STOP TRAILING (trailATRmult * atr) ENDIF ENDIF // -------- Safety exits -------- IF LongOnMarket AND (macdBearX OR (rsi < 50 AND Close < vwap)) THEN SELL AT MARKET ENDIF IF ShortOnMarket AND (macdBullX OR (rsi > 50 AND Close > vwap)) THEN EXITSHORT AT MARKET ENDIF IF LongOnMarket AND Close >= vwap AND macdHist < macdHist[1] THEN SELL AT MARKET ENDIF IF ShortOnMarket AND Close <= vwap AND macdHist > macdHist[1] THEN EXITSHORT AT MARKET ENDIF IF LongOnMarket AND Time > OREnd AND (Close < ORH AND Close < ema20) THEN SELL AT MARKET ENDIF IF ShortOnMarket AND Time > OREnd AND (Close > ORL AND Close > ema20) THEN EXITSHORT AT MARKET ENDIF IF LongOnMarket AND (macdHist <= 0 OR Close < vwap) THEN SELL AT MARKET ENDIF IF ShortOnMarket AND (macdHist >= 0 OR Close > vwap) THEN EXITSHORT AT MARKET ENDIF IF LongOnMarket AND Close >= vwap THEN SELL AT MARKET ENDIF IF ShortOnMarket AND Close <= vwap THEN EXITSHORT AT MARKET ENDIF
    Trading-strategy.txt
    #252481 quote
    GraHal
    Participant
    Master
    Wow, where did you get all that code from? The code looks like you copied bits from from various posts on here and pasted them altogether … I might be wrong, let me know? I started trying to fix the 1st line that showed with a red line under (Line 50 I think it was) but then the next line showed a redline and so on and so on? Also there appears to be loads of lines of code that are not even used anywhere in the Strategy … as in used as part of a condition to buy, Sell, SellShort or ExitShort? Tell me I’m wrong and maybe somebody (much cleverer than I am at coding) might take a look with a view to fixing it all and getting it to run (which I would like to see also)??
    robertogozzi and Iván González thanked this post
    #252482 quote
    robertogozzi
    Moderator
    Master
    As to the many syntax errors in your code, they are due to not abiding by the naming conventions for variables:
    • they MUST always start with a letter and may only contain letters and digits (characters, such as underscore etc…, are thus not allowed)
    • they are case insensitive (myrsi, MYRSI and mYrsI all refer to the same variable, it’s up to you to choose what is the most readable format, usually mixing their case appropriately is a good practice)
    • they CANNOT be equal to keywords recognized as such by the ProRealTime language, so that Close, High, MacdSignal, Rsi, MacdLine etc… are not allowed, just start with X (or any other letter or combination of letters), or append it to the end of the name (in this case you can also append a digit) to make it different from any KeyWord; keywords are usually coloured in GREEN and/or CYAN.
    This is the amended code with your text within multiline comments at the beginning:
    /*
    
    Trading Strategy:
    for long and buy set ups: • MACD line crosses above Signal, trade at maximum 1% if the cross happens below the MACD zero line Price prints a lower lows, otherwise make buy at 0.5% of total trading fund as signal is not as strong. • RSI also has already or does cross so it it shows higher lows. The buy should turnup from the 0-35 zone to buy at the maximum 1% amount (dependent on MACD rule), or else it buys at 0.5%. • then the next criteria needs to see a green bullish candle that needs to show bullish momentum: bullish reversal candle, Hammer, Engulfing, Morning Star with volume rising also. •The last criteria needs to assess the VWAP (Volume-Weighted Average Price) bar and to buy only if bullish momentum is shown which needs to be when price is above VWAP.
    
    For Short sell Setups: • MACD line crosses below Signal, trade at maximum 1% if the cross happens above the MACD zero line (momentum fading at overbought levels). Price prints a lower lows, otherwise make sell at 0.5% amount of total trading fund as signal is not as strong. • RSI also has already or does cross so it it shows lower highs. The sell should roll over from the 65-100 zone to sell at the maximum 1% amount (dependent on MACD rule), or else it sells at 0.5%. • then the last criteria needs to see a red bearish candle that needs to show bullish momentum: bearish reversal candle (Shooting Star, Bearish Engulfing, Evening Star/ Inverted hammer) on increasing sell volume. The last criteria needs to short and sell is to assess the VWAP and to sell only if bearish momentum is shown which is when the price is below the VWAP.
    
    */
    
    DEFPARAM CumulateOrders = False
    DEFPARAM PreLoadBars = 2000
    
    // -------- Session (London) --------
    sessionStart = 080000
    sessionEnd = 163000
    
    // -------- Risk & sizing (fractions, no decimals) --------
    fixedSize = 1
    riskATRmult = 5/4 // 1.25
    targetRmultiple= 3/2 // 1.50
    useTrailingStop= 1
    trailATRmult = 1 // 1.00
    
    // -------- Indicator lengths --------
    rsiLen = 14
    emaFast = 20
    emaSlow = 50
    macdF = 12
    macdS = 26
    macdSig = 9
    atrLen = 14
    rvolLen = 60
    
    // -------- Opening Range window --------
    ORStart = 080000
    OREnd = 083000
    
    // -------- Quality score threshold --------
    minQualityScore = 4
    
    // -------- Divergence swing settings --------
    swingLookback = 20
    swingDepth = 2
    
    // -------- Cooldown --------
    cooldownBarsAfterExit = 1
    ONCE lastOrderBar = -100000
    
    // ================== CORE INDICATORS ==================
    ema20 = ExponentialAverage[emaFast](close)
    ema50 = ExponentialAverage[emaSlow](close)
    
    // --- MACD (stepwise to avoid inline subtraction parser issues) ---
    emaMacdFast = ExponentialAverage[macdF](close)
    emaMacdSlow = ExponentialAverage[macdS](close)
    macdDiff = emaMacdFast
    macdDiff = macdDiff - emaMacdSlow
    myMacdLine = macdDiff
    myMacdSignal = ExponentialAverage[macdSig](myMacdLine)
    macdHist = myMacdLine - myMacdSignal
    
    myRSI = RSI[rsiLen](close)
    
    // --- ATR (confirm signature on your build) ---
    atr = AverageTrueRange[atrLen]
    
    // -------- Manual intraday VWAP (resets daily) --------
    ONCE vCumPV = 0.0
    ONCE vCumV = 0.0
    IF Day <> Day[1] THEN
    vCumPV = 0.0
    vCumV = 0.0
    ENDIF
    tp = (High + Low + Close) / 3
    vCumPV = vCumPV + tp * Volume
    vCumV = vCumV + Volume
    vwap = 0.0
    IF vCumV > 0 THEN
    vwap = vCumPV / vCumV
    ENDIF
    
    // -------- Relative volume (RVOL) --------
    avgVol = Average[rvolLen](Volume)
    rvol = 0.0
    IF avgVol > 0 THEN
    rvol = Volume / avgVol
    ENDIF
    
    // -------- Candle anatomy --------
    barRange = High - Low
    body = Abs(Close - Open)
    bodyPct = 0.0
    posInBar = 0.0
    IF barRange > 0 THEN
    bodyPct = 100 * body / barRange
    posInBar = 100 * (Close - Low) / barRange
    ENDIF
    
    // -------- ATR baseline (for quality test) --------
    atrBase = Average[100](atr)
    
    // -------- Opening Range (first 30m) --------
    ONCE ORH = 0.0
    ONCE ORL = 0.0
    IF Day <> Day[1] THEN
    ORH = 0.0
    ORL = 0.0
    ENDIF
    IF Time = ORStart THEN
    ORH = High
    ORL = Low
    ENDIF
    IF Time > ORStart AND Time <= OREnd THEN
    IF High > ORH THEN
    ORH = High
    ENDIF
    IF Low < ORL THEN
    ORL = Low
    ENDIF
    ENDIF
    IF ORH = 0.0 AND BarIndex > 0 THEN
    ORH = ORH[1]
    ORL = ORL[1]
    ENDIF
    
    // -------- Helpers --------
    inSession = (Time >= sessionStart AND Time <= sessionEnd)
    canTradeBar= (BarIndex > lastOrderBar + cooldownBarsAfterExit)
    
    // ================== QUALITY SCORE 0..6 ==================
    qXrvol = 0
    IF rvol >= 13/10 THEN
    qXrvol = 1
    ENDIF
    
    qXvwapL = 0
    IF Close > vwap THEN
    qXvwapL = 1
    ENDIF
    
    qXrsi50L = 0
    IF myRSI > 50 THEN
    qXrsi50L = 1
    ENDIF
    
    qXmacd0L = 0
    IF myMacdLine > 0 THEN
    qXmacd0L = 1
    ENDIF
    
    qXcandleL = 0
    IF bodyPct >= 60 AND posInBar >= 75 THEN
    qXcandleL = 1
    ENDIF
    
    qXatr = 0
    IF atr >= atrBase THEN
    qXatr = 1
    ENDIF
    
    qualityLong = qXrvol + qXvwapL + qXrsi50L + qXmacd0L + qXcandleL + qXatr
    
    qXvwapS = 0
    IF Close < vwap THEN
    qXvwapS = 1
    ENDIF
    
    qXrsi50S = 0
    IF myRSI < 50 THEN
    qXrsi50S = 1
    ENDIF
    
    qXmacd0S = 0
    IF myMacdLine < 0 THEN
    qXmacd0S = 1
    ENDIF
    
    qXcandleS = 0
    IF bodyPct >= 60 AND posInBar <= 25 THEN
    qXcandleS = 1
    ENDIF
    
    qualityShort = qXrvol + qXvwapS + qXrsi50S + qXmacd0S + qXcandleS + qXatr
    
    // ================== DIVERGENCE TOOLS ==================
    isSwingLow = (Low[2] > Low[1] AND Low > Low[1] AND Low[1] < Low[3] AND Low[1] < Low[2])
    isSwingHigh = (High[2] < High[1] AND High < High[1] AND High[1] > High[3] AND High[1] > High[2])
    
    ONCE low1Idx = -1
    ONCE low2Idx = -1
    ONCE low1 = 0.0
    ONCE low2 = 0.0
    ONCE macdLow1= 0.0
    ONCE macdLow2= 0.0
    
    ONCE high1Idx = -1
    ONCE high2Idx = -1
    ONCE high1 = 0.0
    ONCE high2 = 0.0
    ONCE macdHigh1= 0.0
    ONCE macdHigh2= 0.0
    
    IF isSwingLow THEN
    low2Idx = low1Idx
    low2 = low1
    macdLow2 = macdLow1
    low1Idx = BarIndex - 1
    low1 = Low[1]
    macdLow1 = myMacdLine[1]
    ENDIF
    
    IF isSwingHigh THEN
    high2Idx = high1Idx
    high2 = high1
    macdHigh2 = macdHigh1
    high1Idx = BarIndex - 1
    high1 = High[1]
    macdHigh1 = myMacdLine[1]
    ENDIF
    
    validLowSwings = (low1Idx > 0 AND low2Idx > 0 AND (low1Idx - low2Idx) >= swingDepth AND (BarIndex - low1Idx) <= swingLookback)
    validHighSwings = (high1Idx > 0 AND high2Idx > 0 AND (high1Idx - high2Idx) >= swingDepth AND (BarIndex - high1Idx) <= swingLookback)
    
    bullDiv = 0
    IF validLowSwings AND low1 < low2 AND macdLow1 > macdLow2 THEN
    bullDiv = 1
    ENDIF
    
    bearDiv = 0
    IF validHighSwings AND high1 > high2 AND macdHigh1 < macdHigh2 THEN
    bearDiv = 1
    ENDIF
    
    // ================== STRATEGY SIGNALS (8) ==================
    macdBullX = (myMacdLine crosses over myMacdSignal)
    macdBearX = (myMacdLine crosses under myMacdSignal)
    rsiUpFrom30 = (myRSI crosses over 30)
    rsiDnFrom70 = (myRSI crosses under 70)
    emaTrendUp = (ema50 >= ema50[1])
    emaTrendDown = (ema50 <= ema50[1])
    
    // 1) MACD-RSI Trend-Confirmation
    TrendConfXLong = rsiUpFrom30 AND macdBullX AND emaTrendUp
    TrendConfXShort = rsiDnFrom70 AND macdBearX AND emaTrendDown
    
    // 2) RSI+MACD Divergence Reversal
    reversalBullCandle = (Close > Open AND posInBar >= 65 AND bodyPct >= 50)
    reversalBearCandle = (Close < Open AND posInBar <= 35 AND bodyPct >= 50)
    DivRevXLong = (bullDiv = 1 AND myRSI < 30 AND reversalBullCandle)
    DivRevXShort = (bearDiv = 1 AND myRSI > 70 AND reversalBearCandle)
    
    // 3) RSI Trend Filter + MACD Breakout
    breakAboveOR = (Time > OREnd AND Close > ORH AND High[1] <= ORH)
    breakBelowOR = (Time > OREnd AND Close < ORL AND Low[1] >= ORL)
    RSItrendLong = (myRSI > 50)
    RSItrendShort = (myRSI < 50)
    BreakoutXLong = RSItrendLong AND macdBullX AND macdHist > macdHist[1] AND (breakAboveOR OR Close > ema20) AND rvol >= 13/10
    BreakoutXShort = RSItrendShort AND macdBearX AND macdHist < macdHist[1] AND (breakBelowOR OR Close < ema20) AND rvol >= 13/10
    
    // 4) RSI Pullback + MACD Trend Bias
    rsiTurnUp = (myRSI > myRSI[1] AND myRSI[1] <= myRSI[2])
    rsiTurnDown = (myRSI < myRSI[1] AND myRSI[1] >= myRSI[2])
    PullbackXLong = (macdHist > 0) AND (myRSI >= 40 AND myRSI <= 50) AND rsiTurnUp AND (Close >= ema20 OR Close >= vwap) AND rvol >= 12/10
    PullbackXShort = (macdHist < 0) AND (myRSI <= 60 AND myRSI >= 50) AND rsiTurnDown AND (Close <= ema20 OR Close <= vwap) AND rvol >= 12/10
    
    // 5) Opening-Range Breakout (ORB) + Trend Filter
    ORBXLong = (Time > OREnd) AND (Close > ORH) AND emaTrendUp AND myRSI > 50 AND macdHist > macdHist[1] AND rvol >= 13/10
    ORBXShort = (Time > OREnd) AND (Close < ORL) AND emaTrendDown AND myRSI < 50 AND macdHist < macdHist[1] AND rvol >= 13/10
    
    // 6) Mean Reversion to VWAP (fade)
    farFromVWAPXLong = (Close < vwap AND (vwap - Close) >= (3 * Average[5](atr)) / 2)
    farFromVWAPXShort = (Close > vwap AND (Close - vwap) >= (3 * Average[5](atr)) / 2)
    MRXLong = farFromVWAPXLong AND myRSI < 30 AND (macdHist > macdHist[1]) AND reversalBullCandle
    MRXShort = farFromVWAPXShort AND myRSI > 70 AND (macdHist < macdHist[1]) AND reversalBearCandle
    
    // 7) Volatility Squeeze -> Expansion (ATR squeeze proxy)
    lowATRNow = (atr <= Lowest[150](atr) * 11/10)
    SqueezeXLong = lowATRNow AND Close > ema20 AND myRSI > 50 AND rvol >= 13/10 AND Close > High[1]
    SqueezeXShort = lowATRNow AND Close < ema20 AND myRSI < 50 AND rvol >= 13/10 AND Close < Low[1]
    
    // 8) News / Volume-Spike Reaction (First Pullback)
    impulseUp = (rvol >= 2 AND bodyPct >= 70 AND Close > vwap AND myMacdLine > 0)
    impulseDown = (rvol >= 2 AND bodyPct >= 70 AND Close < vwap AND myMacdLine < 0)
    pullbackOKXL = impulseUp AND Close >= ema20 AND myRSI > 50 AND myMacdLine >= 0
    pullbackOKXS = impulseDown AND Close <= ema20 AND myRSI < 50 AND myMacdLine <= 0
    NewsPBXLong = pullbackOKXL AND (Close > High[1])
    NewsPBXShort = pullbackOKXS AND (Close < Low[1])
    
    // ============== ELIGIBILITY + RANKING ==============
    EligXTrendConfXL = TrendConfXLong AND (qualityLong >= minQualityScore)
    EligXDivRevXL = DivRevXLong AND (qualityLong >= minQualityScore)
    EligXBreakoutXL = BreakoutXLong AND (qualityLong >= minQualityScore)
    EligXPullbackXL = PullbackXLong AND (qualityLong >= minQualityScore)
    EligXORBXL = ORBXLong AND (qualityLong >= minQualityScore)
    EligXMRXL = MRXLong AND (qualityLong >= minQualityScore)
    EligXSqueezeXL = SqueezeXLong AND (qualityLong >= minQualityScore)
    EligXNewsPBXL = NewsPBXLong AND (qualityLong >= minQualityScore)
    
    EligXTrendConfXS = TrendConfXShort AND (qualityShort >= minQualityScore)
    EligXDivRevXS = DivRevXShort AND (qualityShort >= minQualityScore)
    EligXBreakoutXS = BreakoutXShort AND (qualityShort >= minQualityScore)
    EligXPullbackXS = PullbackXShort AND (qualityShort >= minQualityScore)
    EligXORBXS = ORBXShort AND (qualityShort >= minQualityScore)
    EligXMRXS = MRXShort AND (qualityShort >= minQualityScore)
    EligXSqueezeXS = SqueezeXShort AND (qualityShort >= minQualityScore)
    EligXNewsPBXS = NewsPBXShort AND (qualityShort >= minQualityScore)
    
    bestLong = -1
    bestShort = -1
    score = 0
    
    IF EligXNewsPBXL THEN
    score = qualityLong + 80
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXORBXL THEN
    score = qualityLong + 70
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXBreakoutXL THEN
    score = qualityLong + 60
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXSqueezeXL THEN
    score = qualityLong + 50
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXPullbackXL THEN
    score = qualityLong + 40
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXTrendConfXL THEN
    score = qualityLong + 30
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXMRXL THEN
    score = qualityLong + 20
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    IF EligXDivRevXL THEN
    score = qualityLong + 10
    IF score > bestLong THEN
    bestLong = score
    ENDIF
    ENDIF
    
    IF EligXNewsPBXS THEN
    score = qualityShort + 80
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXORBXS THEN
    score = qualityShort + 70
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXBreakoutXS THEN
    score = qualityShort + 60
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXSqueezeXS THEN
    score = qualityShort + 50
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXPullbackXS THEN
    score = qualityShort + 40
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXTrendConfXS THEN
    score = qualityShort + 30
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXMRXS THEN
    score = qualityShort + 20
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    IF EligXDivRevXS THEN
    score = qualityShort + 10
    IF score > bestShort THEN
    bestShort = score
    ENDIF
    ENDIF
    
    goLong = (bestLong > bestShort)
    goShort = (bestShort > bestLong)
    
    // ================== ORDERS & RISK ==================
    sizeToUse = fixedSize
    riskPoints = atr * riskATRmult
    IF riskPoints <= 0 THEN
    riskPoints = 1
    ENDIF
    
    IF inSession AND canTradeBar THEN
    IF NOT LongOnMarket AND NOT ShortOnMarket AND goLong THEN
    lastOrderBar = BarIndex
    BUY sizeToUse CONTRACTS AT MARKET
    SET STOP pLOSS riskPoints
    SET TARGET pPROFIT (targetRmultiple * riskPoints)
    ENDIF
    IF NOT LongOnMarket AND NOT ShortOnMarket AND goShort THEN
    lastOrderBar = BarIndex
    SELLSHORT sizeToUse CONTRACTS AT MARKET
    SET STOP pLOSS riskPoints
    SET TARGET pPROFIT (targetRmultiple * riskPoints)
    ENDIF
    ENDIF
    
    IF useTrailingStop = 1 THEN
    IF LongOnMarket AND Close >= TradePrice + riskPoints THEN
    SET STOP TRAILING (trailATRmult * atr)
    ENDIF
    IF ShortOnMarket AND Close <= TradePrice - riskPoints THEN
    SET STOP TRAILING (trailATRmult * atr)
    ENDIF
    ENDIF
    
    // -------- Safety exits --------
    IF LongOnMarket AND (macdBearX OR (myRSI < 50 AND Close < vwap)) THEN
    SELL AT MARKET
    ENDIF
    IF ShortOnMarket AND (macdBullX OR (rsi > 50 AND Close > vwap)) THEN
    EXITSHORT AT MARKET
    ENDIF
    IF LongOnMarket AND Close >= vwap AND macdHist < macdHist[1] THEN
    SELL AT MARKET
    ENDIF
    IF ShortOnMarket AND Close <= vwap AND macdHist > macdHist[1] THEN
    EXITSHORT AT MARKET
    ENDIF
    IF LongOnMarket AND Time > OREnd AND (Close < ORH AND Close < ema20) THEN
    SELL AT MARKET
    ENDIF
    IF ShortOnMarket AND Time > OREnd AND (Close > ORL AND Close > ema20) THEN
    EXITSHORT AT MARKET
    ENDIF
    IF LongOnMarket AND (macdHist <= 0 OR Close < vwap) THEN
    SELL AT MARKET
    ENDIF
    IF ShortOnMarket AND (macdHist >= 0 OR Close > vwap) THEN
    EXITSHORT AT MARKET
    ENDIF
    IF LongOnMarket AND Close >= vwap THEN
    SELL AT MARKET
    ENDIF
    IF ShortOnMarket AND Close <= vwap THEN
    EXITSHORT AT MARKET
    ENDIF
    GraHal and Iván González thanked this post
    #252483 quote
    JJCWMANCH
    Participant
    New
    Many thanks for looks ng into this.
    Tbh I had to use and various AI coding platforms to put this together, clearly it is not working!   Is it possible to build in multiple strategies and a scoring criterias to have the appropriate strategy assigned at any given time, to multiple instruments, for automatic trading? I would very much like to build a fully automated trading platform that reacts in real time to price changes. I tried to implement  eight basic main strategies and rules to give a underlying base to have 8 strategies be deployed to react to market changes live. But if even two strategies can be built and then switched depending on the state of the share price etc, I would be very interested how to build this and what code has been used please!   Thanks
    #252484 quote
    GraHal
    Participant
    Master
    strategy assigned at any given time, to multiple instruments
    A single coded Strategy can only be assigned to a single Instrument. You could run the same coded Strategy duplicated multiple times across multiple Instruments.
    robertogozzi thanked this post
Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.

Please correct Code to allow this to work to backtest and in automatic trading


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
JJCWMANCH @jjcwmanch Participant
Summary

This topic contains 4 replies,
has 3 voices, and was last updated by GraHal
4 months, 3 weeks ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 10/11/2025
Status: Active
Attachments: 1 files
Logo Logo
Loading...