Closeing Problems, Please help - page 8

 
Ais:

Hello Cameofx,
Thanks for kind response.
This coding system is very simple and easy.
All done manually in MetaEditor.
In fact, the system is being designed to develop large programs easily and with high speed.
The system should be also flexible and reliable.
Best regards!

Ais, Thank you for your reply. I learned a lot from your posts :)

Cameo

 

Hi Friends!

One thing from the past hangs over me day after day.
This is documentation to AIS5 Trade Machine.
I'll be back as soon as God will decide.

Bye for now!

 

Hello Ais
Your absence will be sorely missed. Take care.
We welcome your return.
Your friend, Cheers

 

Hello Ais
Upon your return, I am sorry to burden you immediately with more questions. It is not your system in particular, I have this problem with most all programs. It has to do with user-defined functions. How does the user-defined function get it's definition.
For example:

int       iSignalOpen ()     //       - i      17 l       1 o     //< This is what iSignalOpen function will do.....
{                                                                 //< When the chart is opened, first pass..
if    ( ( iTradeBarTime    == iTime   ( 0 , 0 , 0 ) )   //< false input, EMPTY == (0,0,0)------|
      &&         //                                         &&                                 |--(return)EMPTY
      ( iTradeBarOnce    == 1 ))                        //< true  input, 1 == 1 ---------------|
      return ( EMPTY);
      
// This proves, 'EMPTY' will always be returned when the chart first opens. At the next tick...       
// ... 'iTime' will have parameters, example: (EUR/USD,HOUR_1,1) it is a predefined function so that...
// ... these parameters will be collected so that an expression can be calculated. Where as the... 
// ... 'iTradeBarTime' is not predefined. 'iTradeBarTime' was assigned 'EMPTY' at declaration earlier in the program.
// 'iTradeBarTime' knows that it is 'EMPTY'and nothing else. 
// When and how did 'iTradeBarTime' get deifined to collect data so that it's value can be other than 'EMPTY'? 
// The 'iTradeBarTime' has to have the same values as the 'iTime', or the input will never be 'true'?
// If it is never 'true', the return is always 'EMPTY'? 
I can not seem to find any firm answer in the book or forum. In a relay logic schematic, an AND gate would work the same as the above example. Only when there are two 'true' inputs, will there be a 'true' output. It is only then, will control continue.
Waiting for your reply. Thank you in advance.
Cheers
 

Hello Huckleberry

Let's clarify this part of code.

1. Probably major difficulties:
1.1. all humans think and act differently;
1.2. I like to use strictly limited number of data types;
1.3. I like to use "standard" data types only:
1.3.1. "int",
1.3.2. "double",
1.3.3. "string";
1.4. I use other data types only in special cases;
1.5. I denote type of my program elements by small letter in the first position of the names:
1.5.1. "i" for "int" data type,
1.5.2. "d" for "double" data type,
1.5.3. "s" for "string" data type,
1.5.4. "r" for "undefined" data type;
1.6. this programming technique helps me to control type casting;
1.7. predefined functions and constants can have also following data types:
1.7.1. "bool",
1.7.2. "color",
1.7.3. "datetime";
1.8. I am always trying to cast these types to "int" type;
1.9. for today my data casting usually is implicit;
1.10. some essentials of my programming techniques:
1.10.1. I liked to use pair of constants "TRUE" and "EMPTY" instead of pair of constants "TRUE" and "FALSE";
1.10.2. in "if" statements sometimes I used "1" and "0" instead of "TRUE" and "FALSE";
1.10.3. I used constant "EMPTY" with negative value "-1" to denote invalid results for unsigned data elements;
1.10.4. in future I will use "bool" type with "b" prefix in names.

2. We have to know about MQL4 data types following:
2.1. "int" is an <!>signed</!> long 4-byte integer number with values from -2147483648 to 2147483647;
2.2. "datetime" is an <!>unsigned</!> long 4-byte integer number with values from 0 to 4294967295;
2.3. assigning "datetime" values to "int" variables, we get correct results up to approximately 2038.01.01.

3. We have to know about "iTime ( symbol, timeframe, shift )" function following:
3.1. this function always returns a value of "datetime" type;
3.2. there are 2 different cases of the return:
3.2.1. "0" if local history is empty;
3.2.2. open time for the bar indicated with "shift" in all other cases;
3.3. "iTime ( 0, 0, 0 )" returns open time for the zero bar of the current chart;
3.4. while zero bar is the same, "iTime ( 0, 0, 0 )" returns the same value;
3.5. when current zero bar is completed, this bar became bar number 1 and forming of new zero bar is starting;
3.6. "iTime ( 0, 0, 0 )" returns the new value;
3.7. thus, value of "iTime ( 0, 0, 0 )" is changing when zero bar changed.

4. We prevented work with empty history in program block "2.2.3.1. History data inspection".

5. When order is succesfully closed in "iTryClose" function we assign "iTradeBarTime = iTime ( 0, 0, 0 ) ;".

6. In "iSignalOpen" function we inspect if "iTradeBarTime == iTime ( 0, 0, 0 ) )".

7. If it is true and repeated trade is forbidden by "iTradeBarOnce = 1 ;" then we forbid signal to open by "EMPTY" value.

Cheers

 

Hello Ais
Thank you for your response. I will study up on this and be back soon.
Cheers

 

Hello Ais,
Sorry for my slow reply. I started back to work at my regular occupation on Monday. Time is a little shorter these days. Study time is shorter.
As I had mentioned earlier within this thread, I like to break things down to the nuts and bolts. How does one sprocket provided power to another and so forth. So I have found that the control within the program is fascinating. Please understand that I give you all due respect for the patience and knowledge you have provided, but I have questions has to why 2.2.3.1 block is necessary.
How can the iBaseLag + iBaseBar be an expression?
I understood that iBaseLag and iBaseBar are within the parameter for iHighest and iLowest. Unless they are explicit numbers,
how can one determine what exact number it will be. iBaseLag is 20, which represents 20 bars used for calculating the average.
iBaseBar represent at what bar averageing should begin. Bar 1 thru 20, in this case, bar zero is not considered.
I took the liberty to shorten the program by /* 2.2.3.1*/. Tested the program and found the same results. When running the program in real trading conditions, this may not be a good idea.
What is your take please?
Also, your explanation to block 2.1.2 had clarification to my confusion. The iTime returns open time of the zero bar.
iTradeBarTime is a type cast datetime as well. The program knows at what bar the trade has taken place, therefore only one trade per bar. . . iTradeBarOnce == 1
Thank you
I'll be studying more in the days to come. But can the reservered block 2.1.1 be used for a function that would provide additional positions to existing positions. Example: an existing long, then adding three or more longs?
With the functions that are already in the program, would there be conflicts with additonal positions?
Thanks again for everything. Stay well
Cheers

 

Hello Huckleberry,

Let's take a careful look at the main part of the program, including block 2.2.3.1.:

////////////////////////////////////////////////////////////////////<        14>
// < 2.2.3. Code : Special : Start >                              //<          >
int       start   ()         //       - i       9 l       - o     //<          >
{                                                                 //<          >
// < 2.2.3.1. History data inspection 4 >`````````````````````````//<          >
static    int       iTrigger   = 0       ; if ( iTrigger == 0 ) { //<          >
  if  ( ( iTime ( 0 , 0 , 0 ) == 0                          )     //<          >
  ||    ( iBars ( 0 , 0     )  < iBaseLag     + iBaseBar    ) )   //<          >
          return                         ; else iTrigger  = 1 ; } //<          >
// </2.2.3.1. History data inspection 4 >`````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
int       iTicket           = iGetTicket ()                     ; //<          >
//                                                                //<          >
if      ( iTicket < 0 )       iTryOpen   ()                     ; //<          >
else                          iTryClose  ()                     ; //<          >
// </2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
int       iTrap   =           GetLastError ()                   ; //<          >
if      ( iTrap   > 0 )       Alert  ( "Exception " , iTrap   ) ; //<          >
// </2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
}                                                                 //<          >
// </2.2.3. Code : Special : Start >                              //<          >
////////////////////////////////////////////////////////////////////<         0>

This code works in following manner:

1. the block 2.2.3.1., the very first block of the program, is a simple trigger:
1.1. "static int iTrigger" stores own value all the lifetime of the program, such is "static";
1.2. initially "iTrigger == 0";
1.3. statement "if ( iTrigger == 0 )" is executed on each tick;
1.4. very first time, when "iTrigger == 0", history data inspection is executed inside the block {..};
1.5. if history data are incorrect, statement "return;" is executed;
1.6. it means that execution of main function "start ()" ended;
1.7. on next tick statement "if ( iTrigger == 0 )" is executed again;
1.8. if history data are correct, statement "iTrigger = 1 ;" is executed;
1.9. then execution of main function "start ()" continues;
1.10. on next tick statement "if ( iTrigger == 0 )" is executed again;
1.11. value of "iTrigger" now and in future will always "== 1" because it is static;
1.12. so in future history data inspection will always skipped;
1.13. such is the simple trigger;

2. history data inspection consist of two parts:
2.1. check if local history is empty "iTime ( 0, 0, 0 ) == 0";
2.2. check if size of local history is enough for computation of "iATR ( 0, 0, iBaseLag, iBaseBar )", where:
2.2.1. "iBaseBar" is starting bar for "iATR";
2.2.2. "iBaseLag" is number of averaging bars for "iATR";
2.2.3. "iBaseLag + iBaseBar" is an usual expression, result is always a sum of "iBaseLag" and "iBaseBar";
2.2.4. in other words expression "iBaseLag + iBaseBar" is equivalent of the sum of "iBaseLag" and "iBaseBar";
2.2.5. we can assign any values for "iBaseLag" and "iBaseBar" in program input in block 1.1.1.;
2.2.6. let we assign "iBaseLag = 100 ;" and "iBaseBar = 7 ;";
2.2.7. then correct computation of "iATR ( 0, 0, iBaseLag, iBaseBar )" will possible, if size of local history is equal to 107 or greater, because the last bar number for the computation is
#106 and bar number zero is always considered.

It is possible to add any number of functions in any program, block 2.1.1 just demonstrates sample of possible implementation.
Providing additional positions will require much more complex code of position analysis and management than function 2.1.4.
But everything is possible.

Cheers

 

Hello Ais
Thank you for your quick reponse. I can follow much of what you state. Specially about iATR function. Your saying that using the expression iBaseLag + iBasebar, in and of itself, is an exceptable part of the formula. I was under the impression that they had to be with in the parameters of a defined function or they were not allowed. This is for checking the size of the local history, if there are actually enough bars to proceed. Is that what you are pointing out? So many more steps, but necessary steps to accomplish the goal. Steps that would be overlooked, or taken for granted.
I'll chew so more on the rest. Thank you for your time.
Cheers

 

Hello Huckleberry
MQL4 is a very friendly environment, especially comparing to, for example, C or assemblers.
Requirements for various checks and other tricks are significally reduced.
But implementations of maximum possible checks into development environment always reduce performance.
In any way programmer always is responsible for bad behaviour of program.
So for me redundant recheck is better than, for example, elementary corruption of boundaries.
Cheers

Reason: