› Forums › Development › Q & A For MQ4 Coding Newbies
This topic has been reported for inappropriate content
Tagged: MQL mq4 C coding tutorial
- This topic has 80 replies, 15 voices, and was last updated 9 years, 10 months ago by
Anti.
- AuthorPosts
- December 11, 2015 at 12:49 pm #10236
@simplex,
I hope this is the right place to ask about TickVolume. I am trying to put Gadi_TickVolume_2.2 on my chart, and trying to call using iCustom. I got no result, and at expert tab i got “unknown subwindow number -1 for object create function” . What can the problem be ?extern string customIndi = “Gadi_TickVolume_v2.2”;
double d1TVcur = iCustom(NULL,0,customIndi,PERIOD_D1,0,shift);
The only one variable is the TF (time frame). If i call it by passing the D1 TF like this :
double d1TVcur = iCustom(NULL,PERIOD_D1,customIndi,PERIOD_D1,0,shift);
i don’t think it is right, because i define the TF twice …

Thanks in advance bro
December 11, 2015 at 3:49 pm #10243@smallcat: right place? Well, yes and no!
Yes, because this thread is intended to discuss this kind of questions.
And no, because I don’t have the source code of Gadi_TickVolume_v2.2, so I do not know what’s happening inside. That’s the general problem if you don’t have the mq4 source: you can only guess and in many cases the result will be wrong. Most .ex4 are posted in forums without a trace of any proper documentation of the programming interface, my own ones included :whistle:, so using those indicators by iCustom() is more like gambling than like software development.
My guess re. the error message: the indicator is trying to access a certain subwindow index inside the terminal, probably to paint some objects on the chart. When called by iCustom(), the window index is -1, and the indicator runs into an error.
EDIT: properly coded, the indicator should check window index first, and if it is smaller than 0, just not paint any objects. (Remembering my own indicators drawing objects, I’m afraid that none of them checks this
… )My personal preference would always be to understand the algorithm of the indicator I’m trying to use, and then code it for myself. Then I know what’s happening inside. This approach is time consuming, but will pay out on the long run. I never use any .ex4 in my own projects, if I don’t have the source code.
In this special case, you might also ask gg53 if he’s got a simplified version of this indicator that does not paint any objects on the chart, or if he can provide any information that helps you avoid the error message in your iCustom() call.
s.
-
This reply was modified 10 years, 4 months ago by
simplex. Reason: clarification
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 11, 2015 at 4:02 pm #10247@smallcat: right place? Well, yes and no! Yes, because this thread is intended to discuss this kind of questions. And no, because I don’t have the source code of Gadi_TickVolume_v2.2, so I do not know what’s happening inside. That’s the general problem if you don’t have the mq4 source: you can only guess and in many cases the result will be wrong. Most .ex4 are posted in forums without a trace of any proper documentation of the programming interface, my own ones included
, so using those indicators by iCustom() is more like gambling than like software development. My guess re. the error message: the indicator is trying to access a certain subwindow index inside the terminal, probably to paint some objects on the chart. When called by iCustom(), the window index is -1, and the indicator runs into an error. EDIT: properly coded, the indicator should check window index first, and if it is smaller than 0, just not paint any objects. (Remembering my own indicators drawing objects, I’m afraid that none of them checks this
… ) My personal preference would always be to understand the algorithm of the indicator I’m trying to use, and then code it for myself. Then I know what’s happening inside. This approach is time consuming, but will pay out on the long run. I never use any .ex4 in my own projects, if I don’t have the source code. In this special case, you might also ask gg53 if he’s got a simplified version of this indicator that does not paint any objects on the chart, or if he can provide any information that helps you avoid the error message in your iCustom() call. s.Thanks a lot bro, trying to create one is a good idea …
December 12, 2015 at 2:12 pm #10273Hi guys!
A short advice for all unexperienced coders. When writing an indicator, you usually want to achieve 2 basic goals, no matter which calculation the indicator will perform:
- When loading initially, the indicator should calculate and display its values for a certain number of bars or for all bars on chart, if possible.
- After that, the indicator should calculate and display only bar zero on every tick, unless it’s a repainting algorithm.
If your indicator does not refresh at bar zero, you’ve got a problem with the second part. If it consumes too much CPU resources, you might have a problem with separating phase 1 from phase 2, thus recalculating all bars on every tick.
I’ve seen indicator code in posts and pm’s that seems to have this issue, @tankhang and @smallcat. To understand what’s wrong (or missing) I would suggest you read the following articles and look especially for function
IndicatorCounted()and what is done with it inside functionstart().Any questions? Please post!
Happy coding,
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 12, 2015 at 4:33 pm #10278Hi,
I am trying to create a tickVolume histogram (like GG did : Gadi_TickVolume_2.2 or previous versions). The idea based on chatting with GG last year, and the based code i took from “TVI.mq4” by “profitrader@inbox.ru” . It was a line indicator, not histogram. May be there is a histogram version out there, but i want to try to make it my self, so i can understand it better and trying to improve my coding skill …Below is the my code (v1) and the modified one (v2) that using Indicator Counted as advice from our great code simplex on his post above. I attach the indicators and an image as comparison.
The problem is :a) why the original code use 100 as a multiply factor at his code :
TVI_calculate=100.0*(DEMA_UpTicks-DEMA_DownTicks)/(DEMA_UpTicks+DEMA_DownTicks);
Edit: in my code it becomes :
bufEight (i) = 100.0*(bufSix (i) – bufSeven (i) )/(bufSix (i)+bufSeven (i) );
b) i am trying to define that if current bar tickVolume is bigger than previous, i will plot blue color for that bar (this rule is for tick value > 0 and tick value < 0). And if current bar having smaller value than previous one, i will plot red color.
I try to remove bug on my code, but still can not find. If any coders here can help, really appreciate it.Thanks in advance.
-
This reply was modified 10 years, 4 months ago by
smallcat.
Attachments:
You must be logged in to view attached files.December 12, 2015 at 6:58 pm #10285kiad posted some TVI histogram here @Penguin.
In Gadi_TickVolume, there is only one external buffer, which is the White line with the Tick value. The rest of the “fancy” features are done internaly.
G.
December 12, 2015 at 8:02 pm #10287Thanks for pointing out the issue.. I will read it later..
I re-coded the algorithm few times and it seem like the ‘problem’ is come from my understanding toward ‘how metatrader works’..
* I think I found the solution.. let met test on real market on Monday..
tankhang
-
This reply was modified 10 years, 4 months ago by
tankhang.
December 12, 2015 at 8:26 pm #10289a) why the original code use 100 as a multiply factor at his code : TVI_calculate=100.0*(DEMA_UpTicks-DEMA_DownTicks)/(DEMA_UpTicks+DEMA_DownTicks);
That factor 100 will simply transform a simple relation (a-b) / (a + b) for easier reading, that’s all: for a = 4 and b = 1 you will get 60.0 instead of 0.6. Simple scaling for convenience.
Your code in general: avoid variable names that say nothing, like buffer1 or buffSix. If you’re using meaningful names like volumeBullish and volumeBearish, or demaUp and demaDown, it will be much easier to read and to understand for yourself and others.
Why did you code so many main loops
for (i=0; i<limit; i++) { ... }and not only one, with all necessary algorithmic steps inside?Some of your main loops are counting upwards, some downwards. Why this? Usually prefer to count downwards, past to present. If a calculation requires precalculated values from the past (like an EMA and other recursive filters) you won’t run into problems, and your code will also be easier to read.
In your code, you’re setting buffers upTick and DnTick as follows:
//--- calculate raw up or dn tick for (i=0; i<limit; i++) { upTick = (Volume+(Close-Open)/getPoint)/2; dnTick = Volume-upTick; }and later:
for (i=limit-1; i>=0; i--) { if (bufEight>bufEight) { // should be blue if (bufEight>0) { // above zero level, going up upTick = bufSix; dnTick = 0.0; ... // and so on ... }That’s contradictory. If you do not want to show raw up / down volume, define extra hidden buffers for those variables.
Hope this helps, have fun!
s.
EDIT: these code snippets do not show brackets of buffers, don’t know why. But you know what I mean, right?
EDIT 2: formatting was gone … trying again!-
This reply was modified 10 years, 4 months ago by
simplex. Reason: clarification -
This reply was modified 10 years, 4 months ago by
simplex. Reason: repair formatting ... (hopefully!)
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 12, 2015 at 8:31 pm #10291@tankhang: great, good luck!
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 13, 2015 at 12:42 am #10300smallcat, kiad posted some TVI histogram here @Penguin. In Gadi_TickVolume, there is only one external buffer, which is the White line with the Tick value. The rest of the “fancy” features are done internaly. G.
Thanks for that information G …
@smallcat: [quote quote=10278]a) why the original code use 100 as a multiply factor at his code : TVI_calculate=100.0*(DEMA_UpTicks-DEMA_DownTicks)/(DEMA_UpTicks+DEMA_DownTicks);
That factor 100 will simply transform a simple relation (a-b) / (a + b) for easier reading, that’s all: for a = 4 and b = 1 you will get 60.0 instead of 0.6. Simple scaling for convenience. Your code in general: avoid variable names that say nothing, like buffer1 or buffSix. If you’re using meaningful names like volumeBullish and volumeBearish, or demaUp and demaDown, it will be much easier to read and to understand for yourself and others. Why did you code so many main loops
for (i=0; i<limit; i++) { ... }and not only one, with all necessary algorithmic steps inside? Some of your main loops are counting upwards, some downwards. Why this? Usually prefer to count downwards, past to present. If a calculation requires precalculated values from the past (like an EMA and other recursive filters) you won’t run into problems, and your code will also be easier to read. In your code, you’re setting buffers upTick and DnTick as follows://--- calculate raw up or dn tick for (i=0; i<limit; i++) { upTick = (Volume+(Close-Open)/getPoint)/2; dnTick = Volume-upTick; }and later:
for (i=limit-1; i>=0; i--) { if (bufEight>bufEight) { // should be blue if (bufEight>0) { // above zero level, going up upTick = bufSix; dnTick = 0.0; ... // and so on ... }That’s contradictory. If you do not want to show raw up / down volume, define extra hidden buffers for those variables. Hope this helps, have fun! s. EDIT: these code snippets do not show brackets of buffers, don’t know why. But you know what I mean, right? EDIT 2: formatting was gone … trying again! [/quote]
Hi Simplex,
Really really great, thanks. I just copy and paste most of the code from TVI. OK, you are right. I have made some notes from your post, and try to rebuild it … will post again later.
About the bracket that is not shown, i think it is blocked by the CMS it self (i think our great friend Saver0 using one of well known cms like: WordPress, Drupal, Joomla, Plone, etc) …Thanks bro
December 13, 2015 at 1:57 pm #10302Hi Guys!
From code posted and code sent to me, I’ve got an idea now that most of the coders around have a sense about the basics of code formatting, indentation, and commenting. Yet it might be useful to review an article that deals with the very basics of these topics. The article uses C code for examples, which is very similar to MQL. Recommended reading:
https://en.wikibooks.org/wiki/C_Programming/Structure_and_style
Note: personally, I do ‘not’ follow ‘all’ the details of this article in my own code. My formatting is a little different, because of (please don’t blame me for that) personal preferences. I hope anyone around who has reviewed several indicators I coded will confirm that my style of coding and commenting is consistent and clear. You may not like every detail of my coding style, and I won’t blame you for that. As long as you say that my code is clear and easy to read, assumed you understand all the methods I used, I’m happy with it (if I’m using
struct, and you don’t know what this is for, that’s no sign of bad style, ok?).That’s important: consistency in style will help you writing code that’s easy to read, to understand, and to maintain in future. When coding, always imagine your project is done, you put it away, and after 5 years you open your code file again: Would you understand your code at a glance? If your straight answer is no or I’m not sure, you should consider to work on enhancing your coding style.
The article above is a good point to start with when developing the basics of your coding style.
Any questions and remarks welcome!
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 13, 2015 at 2:02 pm #10303Ahhh, one more thing:
Good style does not mean an abundant number of comments in your code. These will only be disturbing, obfuscating the very structure of your algorithms.
Good style means that your code is so easy to understand, that it requires only a minimum of comments, and that you inserted exactly this minimum into your code.
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 14, 2015 at 12:52 pm #10338Found a nice and clear article about using and abusing inline comments in your code:
http://www.yacoset.com/Home/inline-documentation
Recommended reading!
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 14, 2015 at 6:11 pm #10348Hi guys! A short advice for all unexperienced coders. When writing an indicator, you usually want to achieve 2 basic goals, no matter which calculation the indicator will perform:
- When loading initially, the indicator should calculate and display its values for a certain number of bars or for all bars on chart, if possible.
- After that, the indicator should calculate and display only bar zero on every tick, unless it’s a repainting algorithm.
If your indicator does not refresh at bar zero, you’ve got a problem with the second part. If it consumes too much CPU resources, you might have a problem with separating phase 1 from phase 2, thus recalculating all bars on every tick. I’ve seen indicator code in posts and pm’s that seems to have this issue, @tankhang and @smallcat. To understand what’s wrong (or missing) I would suggest you read the following articles and look especially for function
IndicatorCounted()and what is done with it inside functionstart().Any questions? Please post! Happy coding, s.
Use IndicatorCounted() function in order to calculate only relevant bars. It’s fast and easy on the CPU.
G.
December 16, 2015 at 7:40 am #10419Use IndicatorCounted() function in order to calculate only relevant bars. It’s fast and easy on the CPU. G.
- When loading initially, the indicator should calculate and display its values for a certain number of bars or for all bars on chart, if possible.
- After that, the indicator should calculate and display only bar zero on every tick, unless it’s a repainting algorithm.
If your indicator does not refresh at bar zero, you’ve got a problem with the second part. If it consumes too much CPU resources, you might have a problem with separating phase 1 from phase 2, thus recalculating all bars on every tick.
Thanks G & simplex. So if we have some buffers (arrays), and we use IndicatorCounted(), is it better to check for New Bar coming, then we shift the content of the array ? We add a new space to array for storing the new result later. In this case, we are only work with last (current) candle, which will safe CPU load … or ?
Unfortunately TVI by our brother Kiads are in EX4 format … fortunately i found on the net how to create histogram. It uses iCustom to call to TVI, so i must change this part … trying to put it in one file (like simplex’s advice of using “time frame management” …)December 16, 2015 at 8:58 am #10422In an indicator, there’s no need to shift buffers manually. The terminal engine does that automatically. Only of you declare arrays which are no buffers you have to care for that yourself.
Did you read the articles I linked to?
In Sergey’s book chapter, scroll down, search for IndicatorCounted – it’s essential to understand those basics to code indicators which will calculate history bars only once, and bar zero on tick.
Please ask if you have questions about this chapter.
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 16, 2015 at 11:05 am #10428@simplex, yes i have read it. Thanks, it is nice information like :
i = Bars – IndicatorCounted() – 1;
Or limiting bars with :
if (i > LookBackBars – 1)
i = LookBackBars – 1;
But i mean the iMAonArray. The source must be an array, and the results are store in array (sorry not wrote it clearly). The source content will be bigger/more if a neq candle comes (except we are using LookBackBars). If we use the whole Bars, we increment the array space. If we use limiting bars like LookBackBars, we must shift each content to the left, and at the very right position, it is free (for new bar calculation). We do it at avery candle comes. Do we need to use ArraySetasSeries here (because we count i from left to right ?)
i = limit;
while (i>=0){
i–;
}
Or :
for (i=limit; i>=0;i–) ❴
❵
Thanks in advance.
December 16, 2015 at 12:41 pm #10431Oops – sorry: I seem to have totally misunderstood your question, or confused some posts.
So you like to increase the size of an array on each new bar? What is the maximum size of the array then?
s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 16, 2015 at 4:48 pm #10437Oops – sorry: I seem to have totally misunderstood your question, or confused some posts. So you like to increase the size of an array on each new bar? What is the maximum size of the array then? s.
Yes, sorry for making you confused. I did not write it clearly (on mobile phone it is a little difficult for me, old eyes :) … If i just take the whole Bars, it will be very very big on TF M1, and grows rapidly if a new candle appear, this is not good.
So, I think the max size of the array is the size of LookBackBars (historical) bars, may be around 1000 ? So, after this max size is reach, and a new candle comes, we must shift it to the left, and at the most right space, it will be empty, right ? We fill this empty space of array after the candle close / new candle comes.
ThanksDecember 16, 2015 at 6:31 pm #10440[quote quote=10348] Use IndicatorCounted() function in order to calculate only relevant bars. It’s fast and easy on the CPU. G.
- When loading initially, the indicator should calculate and display its values for a certain number of bars or for all bars on chart, if possible.
- After that, the indicator should calculate and display only bar zero on every tick, unless it’s a repainting algorithm.
If your indicator does not refresh at bar zero, you’ve got a problem with the second part. If it consumes too much CPU resources, you might have a problem with separating phase 1 from phase 2, thus recalculating all bars on every tick.
Thanks G & simplex. So if we have some buffers (arrays), and we use IndicatorCounted(), is it better to check for New Bar coming, then we shift the content of the array ? We add a new space to array for storing the new result later. In this case, we are only work with last (current) candle, which will safe CPU load … or ? Unfortunately TVI by our brother Kiads are in EX4 format … fortunately i found on the net how to create histogram. It uses iCustom to call to TVI, so i must change this part … trying to put it in one file (like simplex’s advice of using “time frame management” …) [/quote]
Hi Brother, Why you don’t contact me… hehehe…
This is my version of TVI (base on my teacher Mladen skeleton) still ‘mixed between old style coding and the new one’.. but already set for build 920 with 2 warnings from function. please forgive me if my code is not good .. can’t catch the train.. it’s too fast for my old brain..
hope it help and best regards
MTH
Attachments:
You must be logged in to view attached files.Intuition, Experiences and Common sense..
http://www.binaryoptionsedge.com/December 16, 2015 at 11:03 pm #10446@smallcat: since build 600 we can have up to 256 buffers in an mt4 indicator. Early this year I coded an indicator that used about 50 buffers for internal precalculations. The memory and cpu consumption was horrible at first. Then I reconsidered: do I really need all those bars on my charts? I limited it to 20000 maximum bars per chart, loaded the indicator, and it ran easily from that moment, without any problem. Background: if you have 500000 bars on a chart, and limit indicator calculation to 1000 bars, the indicator will allocate memory for 500000 bars anyway. All you’re limiting is cpu load.
If you like to start easy, you might do the same, and then declare your array as a hidden buffer. So the terminal engine will care for all the shifting automatically.
If you like to do it manually, you have to check whether a new bar appears, and if yes rotate your array cells in a loop. And you don’t have to declare the array as a series for that.
For iMAOnArray, please look here:
Unlike iMA(…), the iMAOnArray() function does not take data by symbol name, timeframe, the applied price. The price data must be previously prepared. The indicator is calculated from left to right. To access to the array elements as to a series array (i.e., from right to left), one has to use the ArraySetAsSeries() function.
And you did not confuse me, I think I managed that myself!

s.
A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 17, 2015 at 7:40 am #10453[quote quote=10419][quote quote=10348] Use IndicatorCounted() function in order to calculate only relevant bars. It’s fast and easy on the CPU. G.
- When loading initially, the indicator should calculate and display its values for a certain number of bars or for all bars on chart, if possible.
- After that, the indicator should calculate and display only bar zero on every tick, unless it’s a repainting algorithm.
If your indicator does not refresh at bar zero, you’ve got a problem with the second part. If it consumes too much CPU resources, you might have a problem with separating phase 1 from phase 2, thus recalculating all bars on every tick.
Thanks G & simplex. So if we have some buffers (arrays), and we use IndicatorCounted(), is it better to check for New Bar coming, then we shift the content of the array ? We add a new space to array for storing the new result later. In this case, we are only work with last (current) candle, which will safe CPU load … or ? Unfortunately TVI by our brother Kiads are in EX4 format … fortunately i found on the net how to create histogram. It uses iCustom to call to TVI, so i must change this part … trying to put it in one file (like simplex’s advice of using “time frame management” …) [/quote] Hi Brother, Why you don’t contact me… hehehe… This is my version of TVI (base on my teacher Mladen skeleton) still ‘mixed between old style coding and the new one’.. but already set for build 920 with 2 warnings from function. please forgive me if my code is not good .. can’t catch the train.. it’s too fast for my old brain.. hope it help and best regards MTH [/quote]
Thanjs a lot bro … really appreciate it , will look at it as soon as i am home …
December 17, 2015 at 7:51 am #10454since build 600 we can have up to 256 buffers in an mt4 indicator. Early this year I coded an indicator that used about 50 buffers for internal precalculations. The memory and cpu consumption was horrible at first. Then I reconsidered: do I really need all those bars on my charts? I limited it to 20000 maximum bars per chart, loaded the indicator, and it ran easily from that moment, without any problem. Background: if you have 500000 bars on a chart, and limit indicator calculation to 1000 bars, the indicator will allocate memory for 500000 bars anyway. All you’re limiting is cpu load. If you like to start easy, you might do the same, and then declare your array as a hidden buffer. So the terminal engine will care for all the shifting automatically. If you like to do it manually, you have to check whether a new bar appears, and if yes rotate your array cells in a loop. And you don’t have to declare the array as a series for that. For iMAOnArray, please look here:
Unlike iMA(…), the iMAOnArray() function does not take data by symbol name, timeframe, the applied price. The price data must be previously prepared. The indicator is calculated from left to right. To access to the array elements as to a series array (i.e., from right to left), one has to use the ArraySetAsSeries() function.
And you did not confuse me, I think I managed that myself!
s.Thanks bro, really great information. About hidden buffer, what is it actually? Just define it as an array, but not set is as SetIndexBuffer() at init() function ?
December 17, 2015 at 10:13 am #10457No, two simple steps:
- declare global arrays of type double for your buffers
- make them a buffer with SetIndexBuffer(). For all visible buffers, you set an index style and label. For the invisible ones, you do not set style and label.That’s all.
See pics from my CIX (I posted it).
Please note that buffer bDiff can be switched between visible and invisible depending on user’s choice.
s.
Attachments:
You must be logged in to view attached files.A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
December 17, 2015 at 11:26 am #10460Remember what I wrote about my opinion re. commenting your code over here? Just found a nice example (from a well-known coder) how the function of an absolutely simple indicator init sequence can be shaded by nonsense commenting.
All I did in the second version was delete all inline comments, add a simple function comment block on top, and rename buffers to something meaningful (important!) for easier reading. Easy reading was further enhanced by adding some blanks:
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, StartBar + 1);instead ofPlotIndexSetInteger(2,PLOT_DRAW_BEGIN,StartBar+1);Which one is easier to read and understand? (BTW: this is MQL5, not MQL4).
s.
Attachments:
You must be logged in to view attached files.A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)
-
This reply was modified 10 years, 4 months ago by
- AuthorPosts
- You must be logged in to reply to this topic.