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

Forums ProRealTime English forum ProBuilder support Please correct Code to allow this to work to backtest and in automatic trading

Viewing 5 posts - 1 through 5 (of 5 total)
  • #252464

    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

    #252481

    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)??

    1 user thanked author for this post.
    #252482

    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:

     

     

    1 user thanked author for this post.
    #252483

    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

    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.

    1 user thanked author for this post.
Viewing 5 posts - 1 through 5 (of 5 total)

Create your free account now and post your request to benefit from the help of the community
Register or Login