ProBacktest : propagation of variable’s value over bars execution

Viewing 15 posts - 1 through 15 (of 20 total)
  • Author
    Posts
  • #259932 quote
    PROPRO
    Participant
    Junior

    I would like to be able to change my market position depending of profit/loss level of my probacktest strategy (or proOrder) from launch to current bar included current position, not only cumulated closed positions.

    As I didn’t find the way to do it using StrategyProfit variable, I would like to simply initiate a variable : 0 at beginning and incremented at each bar closing with the net profit or loss of the bar. I tried something as :

    Mybalance = My balance + (close[0] – close [1]) * (boolean result of my indicators calculated at previous bar close, i.e. 1 if buy, 0 if out of market and -1 if sell).


    I’m confident with the formula with my boolean as I’ve been using since long time and it works perfectly. I think the problem is coming from the fact that Mybalance value is not propagated over bar execution by ProBackTest (and certainly ProOrder) as it is by proBuilder), so the Mybalance may be re-initiated to 0 at each new bar execution .. so Mybalance = (close[0] – close[1] …..) without any accumulation.


    Could please confirm that, in ProBackTest or ProOrder) values of variables are not propagated from a bar execution to next bar execution and if possible how to proceed ?


    Thanks a lot in advance

    #259943 quote
    JS
    Participant
    Veteran

    Hi,

    Variables such as MyBalance are indeed carried over from one bar to the next…

    Your “issue” comes from using (Close[0]-Close[1]), which does not represent an actual position…

    You can calculate the open PnL, for example, in the following way:

    OpenPnL=(Close-PositionPrice)*CountOfPosition*PointValue

    Equity=StrategyProfit+OpenPnL

    robertogozzi and Iván González thanked this post
    #259945 quote
    Nicolas
    Keymaster
    Master

    FYI, there are numerous code blocks with explanation available here: https://www.prorealcode.com/snippets/

    Iván González thanked this post
    #259946 quote
    PROPRO
    Participant
    Junior

    Thks for the feedbacks. Will try tomorrow the formula from JS but for my understanding :


    • Beside the fact my formula didn’t include CountOfPosition and PointValueEquity, is there something wrong to use Close and Close[1] ? I use them in other parts of ProOrder code and there is no problem ..


    • in ProOrder, is there a way to use a cutomized variable that can carry over from bars to bars, or are there only a list of PRT specific one’s that can carry over from bar to bar ? Is there a way to carry the value of a variable over the bars ??


    Tks a lot

    #259957 quote
    JS
    Participant
    Veteran

    Hi,

    • There is essentially nothing wrong with (Close – Close[1]); it shows the change in price…

    However, it is not the same as an actual position…

    For example, a real position is opened at the “Open” of a candle and involves slippage, costs, etc…

    • Values of variables (for example, MyBalance) are carried over from one bar to the next…


    #259965 quote
    PeterSt
    Participant
    Master

    … But to answer your question …


    All variables carry over to the next bar. All. However, lines like these :


    Mybalance = Mybalance + [...]
    


    can technically not be in your code as is (or “sec” if you like). This is because

    a. PRT generally allows you to code it like that but

    b. the result will be BS because nothing can add to a non-initialized variable as such. But as said, PRT allows it. Anyway the result will be rubbish and thus you would need to code this as


    MyBalance = 0
    [...]
    [...]
    MyBalance = MyBalance + [...]
    


    Well, that is what you would think.

    … And there it goes wrong too, because the first line always resets the MyBalance to 0 and nothing carries over.

    aha


    The solution would be this :

    Once MyBalance = 0   // Only Initialise a first time (at the first call of your program).
    [...]
    [...]
    MyBalance = MyBalance + [...]
    


    And now all will work as intended, that is, the “carry over” you ask about.


    What remains is what others pointed out – your Close() etc. solution for calculating the actual performance per bar on the open position. And not on the StrategyProfit because that works upon closed positions (discarding the current open position). Although others are correct with their solution via close (though they are still not complete but never mind) – you should use PositionPerf.

    Right, now you can do all. 🙂

    #259968 quote
    JS
    Participant
    Veteran

    PositionPerf is not suitable for your purpose, as it is a ratio/percentage and therefore not expressed in monetary value or points…

    However, perhaps PeterSt could show how he intends to calculate the Open PnL using PositionPerf?

    #259969 quote
    PROPRO
    Participant
    Junior

    Tks PeterST. Great explanation and makes me discover ‘Once’ that I didn’t know yet


    Unfortunately, it’s still not working 🙁 May I ask you if you were talking about ProBackTest when you say that all variables carry over bars ??



    #259970 quote
    PROPRO
    Participant
    Junior

    In fact, my issue is not about calculating the accurate PNL (row of net …). I know the calculation rule used by ProBacktest and I know how to replicate. My issue is only about the fact that a variable carries over bars to bars or not in ProBackTest : it seems not or I missed something ..

    #259974 quote
    PROPRO
    Participant
    Junior

    Sorry, I did more basic tests and obviously all variables can carry over bars to bars. I’m still investigating to understand what was wrong ..

    #259975 quote
    robertogozzi
    Moderator
    Master

    This is the code to calculate the Profit or Loss each bar (when OnMarket):

    // this line detects when a new Trade has been opened (in order to reinitialise some values later)
    NewTrade = (LongOnMarket AND ShortOnMarket[1]) OR (LongOnMarket[1] AND ShortOnMarket) OR (OnMarket AND Not OnMarket[1]) OR (OnMarket AND (StrategyProfit <> StrategyProfit[1]))
    //
    //    Profit Calculations when On Market (updated to the current bar, i.e. the bar that just closed)
    //
    IF OnMarket THEN
       Pips  = PositionPerf * PositionPrice / PipSize            // if you need PIPS
       Money = PositionPerf * PositionPrice / PipSize * pipvalue // if you need MONEY
    ELSE
       Pips        = 0
       Money       = 0
       CurrentGain = 0
    ENDIF
    //
    // To tell the Gain or Loss in the c utrent bar
    IF OnMarket THEN
       IF NewTrade THEN
          // in case it's a new trade, there's no prior value to subtract
          CurrentGain = Money                  // or CurrentGain = Pips
       ELSE
          // subtract the prior value from the current value
          // if negative, then it's a loss
             CurrentGain = Money - Money[1] // or CurrentGain = Pips - Pips[1]
       ENDIF
    ENDIF
    graph Pips
    graph Money
    graph CurrentGain
    
    
    
    #259984 quote
    PeterSt
    Participant
    Master


    PROPRO wrote: Tks PeterST. Great explanation and makes me discover ‘Once’ that I didn’t know yet Unfortunately, it’s still not working 🙁 May I ask you if you were talking about ProBackTest when you say that all variables carry over bars ??

    There is no difference between ProBacktest and Live (ProOrder) and Optimization for that matter.

    So if from now on you just think like this, you won’t be distracted by it and can focus on the real “problem”.


    Maybe a small kind of subjective addition : To me it feels like you come from another platform where these different environments (Backtest vs Live) do matter, for even obvious reason and mostly hard to solve, already because of the lack of insight in the differences and the necessity to test all in Live before you really know. Not so in ProRealTime; In PRT these environments are really 100% the same**.


    **): But do note that I am not talking about the different “markets” in these different environments; these are not the same at all, as you will be aware of. Thus, no Quotes data in PRT to begin with, Demo may be different from the normal environment for data, and no real market for the backtest environment anyway.

    #259985 quote
    PeterSt
    Participant
    Master


    JS wrote: PositionPerf is not suitable for your purpose, as it is a ratio/percentage and therefore not expressed in monetary value or points… However, perhaps PeterSt could show how he intends to calculate the Open PnL using PositionPerf?

    I take it that Roberto’s example sufficiently speaks ?

    But similar to what I said before, his example doesn’t contain all. For his example the easy to understand lacking entity is NumberOfContracts. Less visible elements are in fact all the elements that a symbol can bear in the realm of points (they are really *all* necessary, depending on the instrument and also broker (like IB vs IG). Then there are also plainly lacking elements like ContractSize (this lacks in PRT but really is necessary too – try Forex in BB vs IG).


    As far as I recall the good example of meeting all the elements in one instrument (type) then try Futures of Currency – and then within the IB environment.


    Of course one should not omit the Commission which is in order for IB, which is a very special pain because it is in Money while often you will need it in Points. Or the other way around : you use the Commission in Money and thus need the other amount(s) in Money too. Then there is a difference between the Open Position and just the Portfolio because the Open Position formally contains only half of the Commission which Backtest really applies (IB) (without you knowing). More pain comes in once you know or notice that the closing Commission is applied by PRT by means of a dummy small trade after the original position was closed, which make equations with StrategyProfit fail (did it change ? then …).

    Apply this all to in-bar trades where your code can’t reach the exit and entry (Pending Orders – Limit/Stop) and by the time you solved that too, well, you may have lost some hair. 🙂

    #260108 quote
    robertogozzi
    Moderator
    Master


    PeterSt wrote: But similar to what I said before, his example doesn’t contain all. For his example the easy to understand lacking entity is NumberOfContracts.

    You are right, these two lines will account for the number of contracts. They should replace the similar lines in my code above (the code for commissions, overnight fees, etc… is not as straigjtforward, though):

    Pips  = PositionPerf * PositionPrice / PipSize / abs(CountOfPosition)            // if you need PIPS
    Money = PositionPerf * PositionPrice / PipSize * pipvalue / abs(CountOfPosition) // if you need MONEY
    
    #260114 quote
    PeterSt
    Participant
    Master

    Hi Roberto – not to hang out the teacher (most will be obvious for you) :


    A Pips/Points based solution is *not* allowed to use CountOfPosition (the number of contracts involved). This is because your whole “regime” will be based on points. Commonly this regime is applied throughout, where profit and exit choices etc. are based on points. This is then not related to the number of contracts in the open position.

    If MyProfitPoints > 10 then
       // Exit
    endif
    

    In the end this is so because indeed PositionPerf is based on a percentage – see the documentation. Btw in itself I find this hard to all grasp, especially if the understanding is required when for example converting to Money. For fun you could indeed try Commission as a profound example, which is of course normally not in order for IG, so never mind for most people. Still, would you focus on needing to earn at least the commission (otherwise you can’t make profit), then the system of Spread comes down to the very same : you would need the Spread in points.


    And so the Money regime may come more handy because you don’t need to deal with these conversions. Well, that is what one would think, because it depends;

    When you want to earn 10 points because 10 points is equal to USD 500, then make that 11 and the profit you will make (before going out) will be 550. This is sufficiently easy to work with. But when you trade with the microstructure of the instrument, you will really need the TickSize of say 0,25 (the minimum step in points) or else you really won’t know what you are tuning. Thus, you would not want to do something like

    If MyProfitMoney > 12.50 then   // This implies more than one tick
      // Exit
    endif
    

    because it implies that > 15 would also depict logic – which is not true because the next “step” will be > 25 (2 ticks). And thus will this be the more convenient setup :

    If MyProfitPoints > 0.5 then   // Points/Pips. 1 Point = USD 50.
      // Exit
    endif
    

    Thus any Parameter involved (Optimisation) will increase e.g. a take profit level by means of steps of 1 (tick). And not by means of some random amount of money.


    In the end in a self-respecting system both regimes will be used, I think because working with Points (Pips) throughout is far more convenient and decent (portable to other instruments with the proper parameters). This, while Money is just required because of the cost element which is the most crucial to about any system, *if* only a somewhat higher frequency of trades occur per time unit (like 20+ per day) – and the lower the profit per trade, the more crucial/impacting the cost element is (the cost element is fixed per number of contracts involved).




Viewing 15 posts - 1 through 15 (of 20 total)
  • You must be logged in to reply to this topic.

ProBacktest : propagation of variable’s value over bars execution


ProOrder: Automated Strategies & Backtesting

New Reply
Author
author-avatar
PROPRO @propro Participant
Summary

This topic contains 19 replies,
has 5 voices, and was last updated by PROPRO
3 days, 23 hours ago.

Topic Details
Forum: ProOrder: Automated Strategies & Backtesting
Language: English
Started: 04/07/2026
Status: Active
Attachments: No files
Logo Logo
Loading...