Ongoing Indicator Calculations vs Using Indicator Functions

 

I have been asking myself if I could really save run time with a current project I am working on. This project utilizing many indicators, and I was wondering if I really should be utilizing the the in-built functions and the custom indicator functions I created for myself or should I calculate the output of each of the individual function when I need them. 


My Conclusion was that calculating the outputs when I need them is much faster as this is O(1) in both time complexity and space complexity (since all indicators involved have a O(1) implementation to calculate the most recent output). The indicator functions while being O(1) in time complexity, they are O(n) in space complexity as the associated buffers will be the size of the bars in history. 


However, I wanted to know if my reasoning is correct and if it is, then is the boost to performance significant?


An example of what of what I am talking about: 


Instead of calling iATR (Which uses O(1) time complexity implementation), I would instead have an implementation like this within my EA (Which is O(1) in both space and time complexity). 


double atr = 0.0; 
datetime Last_Update_Time = 0; 
...


double ATR(ENUM_TIMEFRAMES tf, string symbol, int period, double curr_atr, datetime Last_Update, int shift){
        double curr_tr, tr_to_remove;
        ...
        if(curr_atr== 0){	
		...
                for(int i = 0; i < period; i++){
                        ...
                        curr_atr+= curr_tr/period;      
                }
        }
        else{
                int bar_shift = iBarShift(...); // Use Last_Update here
                for(int i = bar_shift, i >= 1; i++){
                        ....
                        curr_atr+= (curr_tr - tr_to_remove)/period;
                }
        }
        return curr_atr;
}
 
TraderTogami: I have been asking myself if I could really save run time with a current project I am working on. This project utilizing many indicators, and I was wondering if I really should be utilizing the the in-built functions and the custom indicator functions I created for myself or should I calculate the output of each of the individual function when I need them. My Conclusion was that calculating the outputs when I need them is much faster as this is O(1) in both time complexity and space complexity (since all indicators involved have a O(1) implementation to calculate the most recent output). The indicator functions while being O(1) in time complexity, they are O(n) in space complexity as the associated buffers will be the size of the bars in history. However, I wanted to know if my reasoning is correct and if it is, then is the boost to performance significant? An example of what of what I am talking about: Instead of calling iATR (Which uses O(1) time complexity implementation), I would instead have an implementation like this within my EA (Which is O(1) in both space and time complexity). 

Your reasoning about calculating values internally in the EA instead of using indicator's has merit and can greatly reduce testing and optimisation time if done properly.

However, your implementation is neither efficient nor accurate. Having a loop on every call and using division on every iteration is computationally costly and will build-up round off errors.

Instead of using an SMA of the True Range, consider using an incremental EMA (or SMMA), which is how the ATR was originally implemented ... Wilder's Average True Range (ATR).

You can also read up more on incremental EMA calculations here ... https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf (I have attached the same PDF file in a ZIP archive, in the case the link becomes invalid in the future).

 
Fernando Carreiro #:

Your reasoning about calculating values internally in the EA instead of using indicator's has merit and can greatly reduce testing and optimisation time if done properly.

However, your implementation is neither efficient nor accurate. Having a loop on every call and using division on every iteration is computationally costly and will build-up round off errors.

Instead of using an SMA of the True Range, consider using an incremental EMA (or SMMA), which is how the ATR was originally implemented ... Wilder's Average True Range (ATR).

You can also read up more on incremental EMA calculations here ... https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf (I have attached the same PDF file in a ZIP archive, in the case the link becomes invalid in the future).


Thanks for the confirmation and links. 

Oh and the second loop it usually runs 1 time (it just covers the missing updates since the last update). The round-off errors also don't matter since N is "small," so when we normalize the atr to 5 decimal points (or 3 depending on the symbol), the errors 10+ decimal points in don't matter.   

 
TraderTogami #Thanks for the confirmation and links. Oh and the second loop it usually runs 1 time (it just covers the missing updates since the last update). The round-off errors also don't matter since N is "small," so when we normalize the atr to 5 decimal points (or 3 depending on the symbol), the errors 10+ decimal points in don't matter.
If you wish to disregard the advice, then that is certainly your prerogative. However, you were the one that requested it. Simply brushing it aside without researching it properly, is neither logical nor scientific.
 
Fernando Carreiro #:
If you wish to disregard the advice, then that is certainly your prerogative. However, you were the one that requested it. Simply brushing it aside without researching it properly, is neither logical nor scientific.

Okay, it seems you are the one who isn't listening, but that's alright, I already thanked you for the extra pieces of knowledge you posted, as I looked at them. 


Maybe I wasn't clear I was taking them into consideration, thanks again for the reply. 

 
TraderTogami #: Okay, it seems you are the one who isn't listening, but that's alright, I already thanked you for the extra pieces of knowledge you posted, as I looked at them. Maybe I wasn't clear I was taking them into consideration, thanks again for the reply. 
Ok, understood!
Reason: