A Better Way To Code - TheRumpledOne

 
Files:
 

Hey Rumpled One,

Although we've never conversed, I'm aware of your work, having been trading Fx for quite some time now. I'm eager to hear your ideas concerning bringing MT4's coding paradigm up-to-date. I believe I also have several ideas which can help us to do so. It's funny that you just started this thread today, b/c I was just going through some of my libraries and thinking about re-organizing them. My intention is to start an open-source project with the goal of doing exactly what you're talking about. It's been kind of a back-burner project for some time, but just recently I have gotten the infrastructure in place to make it viable (Redmine w/ subversion).

Anyway, I'd love to talk more about your ideas. This thing with the indicators has always bugged me as well...so I'm going to take a closer look at what you're proposing.

Regards,

BW

 

Hmmm....after looking more closely at your post...

I could be wrong here, but...

I'm not sure that, doing it the conventional way, that the while loop causes "calculations would be run EACH AND EVERY BAR for EACH AND EVERY BAR!!" I say that, because the documentation of IndicatorCounted() seems to say otherwise: "The function returns the amount of bars not changed after the indicator had been launched last. The most calculated bars do not need any recalculation. In most cases, same count of index values do not need for recalculation. The function is used to optimize calculating."

So if we take this basic setup:

int limit;

int counted_bars=IndicatorCounted();

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

for(int i=limit; i>=0; i--)

{ ...

}

I've always understood it that when this is run at startup IndicatorCounted() would be 0. So if bars was 500...then the loop would run 500 times, once for each bar. Then when bar 501 was streamed in, we'd only run the loop once (each tick) for bar 501 at index [0]. So it seems like it's efficient as far as that goes. Please correct me if I'm wrong here.

However, I do see what you're doing with the new bar calculation to avoid the re-paint. I think that's a really good idea.

My big beef with the while...loop and all this is that it can obviously be a bit confusing. I wish that the designers had abstracted that out and just left us to do the actual calculations.

One other comment. By using the global switch OkToInit we could be opening ourselves to threading problems, especially when we first start the platform. One solution to this might be a centralized service provider EA. In this case the service provider could help with the synchronization problems. There are a lot of other things that such an EA can do, some of which I already have implemented.

 

Bad Bad Bad coding (I say it with a smile)

just check and stick with: int IndicatorCounted( )

The function returns the amount of bars not changed after the indicator had been launched last. The most calculated bars do not need any recalculation. In most cases, same count of index values do not need for recalculation. The function is used to optimize calculating.

Keep your coding simple and at least compact. Follow the tools you have. MQL4 doesn't have everything, for what you need now it is more then ok, MQL5 will be bulky and more options.

I saw your coding in your other very good idea indicators, but you really have to reuse things that you coded so many times over and over, this will speed up your processing of the final product. I could code an indicator of yours 20 times with less code and the same result. ( no meaning of pointing a finger, just... somebody has to say it )

The repainting issue... on bar[0] all the time till it becomes bar[1].

if bar[1] still changes, your math formula or combination with other indicators are wrong or it's your intention to let it do that, like trend lines that have to follow or something like that.

Whatever you use in your for() function, up calculation or downwards, think about: you don't need to recalculate things over and over again, but also know the results in different ways, you have to rely on what you make, if you see one fault, it will become a bigger one if you don't care. There are enough people that complain about computer slowdowns, well that's your answer.

If you are planning to use more loops, try to make one big one, and combine every process in one loop, or at least less then before, reuse variables...

good coding oh yes! please, check my IN10TION newsReader

 

Thanks for responding.

First, remember I have only been coding in MT4 since Dec 2007, so I am still a MT4 rookie. But I do have over 30 years programming experience. Yes, I punched cards in the 70s...LOL!

Many of my first indicators that I posted are cut and paste "FRANKENSTEIN" code because I just wanted to get things working. When I look at that code now, I cringe. IN10TION, you're correct, that code can be better written. mladen writes really tight code... nice work!!

Perhaps, there is something I don't understand about MT4's inner workings specifically the way MT4 uses buffers and how the buffers are plotting on the chart. I posted an indicator yesterday that streams in a separate window tick by tick. Funny thing is, that is NOT what I wanted it to do, I made a mistake. When I "fixed" the mistake, I realized the mistake was actually more useful!! It made more sense, to me, to see the values tick by tick instead of bar by bar.

IN10TION, it's not my intention to use more loops. My intention was to eliminate recalculations.

mladen: you're right.. computers only do EXACTLY what you tell them to do! One must be exact in coding.

Thanks again for responding.

 

WHAT'S WRONG WITH THIS PICTURE?

Ok, I put this to the test.

executes :

barstimes immediately after init

2times on normal tick input

3times on normal new bar tick input

int start()

{

int limit;

int counted_bars=IndicatorCounted();

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

for(int i=limit; i>=0; i--)

{

// LOAD BUFFERS

TestBuffer = limit ;

} //for

Comment( "Limit=", limit, "\n",

"counted_bars=", counted_bars, "\n",

"Bars=", Bars, "\n",

" ") ;

return(0);

}

What don't I understand?

What did I do wrong or not do right?

Limit is always 68922.

So the for loop is running 68923 times each and every time?

Or is it because the market is closed this isn't working "right"?

Please shed some light on this.

Thanks.

NOTE: I am NOT trying to prove anyone wrong. I am trying to learn and understand.

Files:
 

wait for live data (changing time frames, or symbols means all the bars changed) or test it with visual handle training made by klot (there is a description how to use it, but I can not remember which post, maybe ND can help. Honestly, I am too lazy to write down all the things this EA can simulate)

intIndicatorCounted( )The function returns the amount of bars not changed after the indicator had been launched last. The most calculated bars do not need any recalculation. In most cases, same count of index values do not need for recalculation. The function is used to optimize calculating. Note: The latest bar is not considered to be calculated and, in the most cases, it is necessary to recalculate only this bar. However, there occur some boundary cases where custom indicator is called from the expert at the first tick of the new bar. It is possible that the last tick of the previous bar had not been processed (because the last-but-one tick was being processed when this last tick came), the custom indicator was not called and it was not calculated because of this. To avoid indicator calculation errors in such situations, the IndicatorCounted() function returns the count of bars minus one.
TheRumpledOne:
WHAT'S WRONG WITH THIS PICTURE?

Ok, I put this to the test.

int start()

{

int limit;

int counted_bars=IndicatorCounted();

if(counted_bars>0) counted_bars--;

limit=Bars-counted_bars;

for(int i=limit; i>=0; i--)

{

// LOAD BUFFERS

TestBuffer = limit ;

} //for

Comment( "Limit=", limit, "\n",

"counted_bars=", counted_bars, "\n",

"Bars=", Bars, "\n",

" ") ;

return(0);

}

What don't I understand?

What did I do wrong or not do right?

Limit is always 68922.

So the for loop is running 68923 times each and every time?

Or is it because the market is closed this isn't working "right"?

Please shed some light on this.

Thanks.

NOTE: I am NOT trying to prove anyone wrong. I am trying to learn and understand.
 

Thanks again, mladen.

I love learning your techniques.

 

That code :

int counted_bars=IndicatorCounted();

int i,limit;

if(counted_bars<0) return(-1);

if(counted_bars>0) counted_bars--;

limit = Bars-counted_bars;

//

//

// the looping part

//

//

for (i=limit; i>=0; i--)

{

....

}

executes :

barstimes immediately after init

3times on normal tick input

4times on normal new bar tick input

I would not avoid that extra 2 executions (in 3 and 4 times) since it does not take as much processor time and ads on code "security"

also : repainting does not have anything to to with recalculating. Repainting code is a code that is supposed to do something and does something else (seems like a joke what I just said, but it is exactly that : code must be clear of "assumptions" in order not to repaint. As a lot of good coders used to say "Computer only does what you tell it to do")

 

When IndicatorCounted() Will Not Work

Some indicators make coding a lot more difficult. They operate on the last value (previous bar) to create the new value. Then IndicatorCounted() does not work!

This article tells you how to fix that. When I first read it, I thought, "I will have to read this six times before I can use it successfully." Fortunately I was wrong - it only took me four times. Plus some "trial and error."

The results: It sped up the backtesting by about 100 times, as it no longer recalculated every bar for the complicated indicator, for every tick. This obviously will speed up live execution the same.

Enjoy!

Multiple Null Bar Re-Count in Some Indicators - MQL4 Articles

Big Be

 

Thanks for sharing Big Be.

Reason: