If A is never greater than 31 - one option is to use bitwise operators... ( a single ampersand, a single | etc) in an increasing integer. As when you count in binary you are generating the same pattern you want...
eg.
1 = 001
2 = 010
3 = 011
4 = 100
5 = 101
6 = 110
7 = 111 etc. where '1' bit is true, and 0 bit is false.
So you treat the integer as an array of up to 31 bits. (its actually 32 bits, but we want to avoid the last bit as this may create issues with -ve numbers )
Eg for A = 5 = 5 bits = in binary is from 00000(0) to 11111(31) - so you want to count through from 0 to 31 to generate all 5 bit combinations.....
31 (ie 11111) = 2^5-1 so...
EDIT: Fixed boolean expression - still untested!
//untested - constants here are in Hex format as its relatively easy to 'visualise' the underlying binary format #define ENTRY_1 0x01 #define ENTRY_2 0x02 #define ENTRY_3 0x04 #define ENTRY_4 0x08 #define ENTRY_5 0x10 int max = MathPow(2,A); // Repeatedly adding 1 cycles through all combinations of bits. for(int combination = 0 ; combination < max ; combination++ ) { if ( (combination & ENTRY_1) != 0 ) { then entry1 is enabled } if ( (combination & ENTRY_2) != 0 ) { then entry2 is enabled } if ( (combination & ENTRY_3) != 0 ) { then entry3 is enabled } if ( (combination & ENTRY_4) != 0 ) { then entry4 is enabled } if ( (combination & ENTRY_5) != 0 ) { then entry5 is enabled } }
I tend to use extra brackets around bitwise operations - there are not needed here - but anything more complicated I like to see them ....
Instead of all the ENTRY_X constants you could also replace if (combination & ENTRY_X) with a function if(entryEnabled(combination,1)) eg
//untested bool entryEnabled(int combination,int entryNumber) { int bit = MathPow(2,entryNumber - 1); return ((combination & bit)!=0); //fixed boolean }
Just be careful MathPow returns correct integer (it should but I've never checked mql4's implementation, but I've come across some implementations in other languages which are not so accurate (issues with doubles) and also are VERY slow using logarithm series calculations even for simple things like powers of two... in which case it may be better, and a lot faster to just use a loop that multiplies by two
//untested bool entryEnabled(int combination,int entryNumber) { int bit = 1; for(int i = 1 ; i < entryNumber ; i++) bit *= 2; return ((combination & bit) !=0); //fixed boolean }
Though for performance, constants are the best.
Thanks for the reply Ydrol.
The A value is fixed at 21. I've tried to work with your first option and worked it out to the code blow. However I believe I'm doing something wrong as now the results are:
combination 1: all values false
combination 2: all values true
combination 3: all values true
etc
The total number of combinations generated is correct though (2097152).
Do you see where this is going wrong? I think it has something to do with this part:
if ( (combination && ENTRY_1) ) {....
combination is here just a number and can have a value from 0 up to 2097152.
#define ENTRY_1 0x01 #define ENTRY_2 0x02 #define ENTRY_3 0x04 #define ENTRY_4 0x08 #define ENTRY_5 0x10 #define ENTRY_6 0x12 #define ENTRY_7 0x14 #define ENTRY_8 0x16 #define ENTRY_9 0x18 #define ENTRY_10 0x20 #define ENTRY_11 0x22 #define ENTRY_12 0x24 #define ENTRY_13 0x26 #define ENTRY_14 0x28 #define ENTRY_15 0x30 #define ENTRY_16 0x32 #define ENTRY_17 0x34 #define ENTRY_18 0x36 #define ENTRY_19 0x38 #define ENTRY_20 0x40 #define ENTRY_21 0x42 bool Direction[3000000,21]; int init() { int Combinations = MathPow(2,21); for(int combination = 0 ; combination < Combinations ; combination++ ) { for(int C1=0;C1<21;C1++){ Direction[combination,0] = 0; // set standard value to false; } if ( (combination && ENTRY_1) ) { Direction[combination,0] = 1;} // set value to true if condition is true if ( (combination && ENTRY_2) ) { Direction[combination,1] = 1;} if ( (combination && ENTRY_3) ) { Direction[combination,2] = 1;} if ( (combination && ENTRY_4) ) { Direction[combination,3] = 1;} if ( (combination && ENTRY_5) ) { Direction[combination,4] = 1;} if ( (combination && ENTRY_6) ) { Direction[combination,5] = 1;} if ( (combination && ENTRY_7) ) { Direction[combination,6] = 1;} if ( (combination && ENTRY_8) ) { Direction[combination,7] = 1;} if ( (combination && ENTRY_9) ) { Direction[combination,8] = 1;} if ( (combination && ENTRY_10) ) { Direction[combination,9] = 1;} if ( (combination && ENTRY_11) ) { Direction[combination,10] = 1;} if ( (combination && ENTRY_12) ) { Direction[combination,11] = 1;} if ( (combination && ENTRY_13) ) { Direction[combination,12] = 1;} if ( (combination && ENTRY_14) ) { Direction[combination,13] = 1;} if ( (combination && ENTRY_15) ) { Direction[combination,14] = 1;} if ( (combination && ENTRY_16) ) { Direction[combination,15] = 1;} if ( (combination && ENTRY_17) ) { Direction[combination,16] = 1;} if ( (combination && ENTRY_18) ) { Direction[combination,17] = 1;} if ( (combination && ENTRY_19) ) { Direction[combination,18] = 1;} if ( (combination && ENTRY_20) ) { Direction[combination,19] = 1;} if ( (combination && ENTRY_21) ) { Direction[combination,20] = 1;} } return(0); } int deinit() { return(0); } int start() { return(0); }
for(int i = 1 ; i < entryNumber ; i++) bit *= 2;
- Exactly what I do for setting which days of the week EA can trade. external= 1 .. 63 covers all combinations.
- Drop your loop and just use
bit = 1 << entryNumber;
You dont need the multi-dimension array any more, as the integer itself is an array of bits, so it serves as the last dimension.
Also as you are looking at all possible combinations you dont really need the array at all, as it is just a very expensive way of representing the numbers 0 - 2^21-1.
I would ditch the Direction array completely and replace it with a function...
EDIT: Better option in posts below using shift operator as suggested :) ...
//untested bool Direction(int combination,int entryNumber) { int bit = 1; for(int i = 1 ; i < entryNumber ; i++) bit *= 2; return ((combination & bit) != 0); // fixed }Just be aware, generally, that you are dealing with some kind of exponential algorithm so things can get out of control very quickly :)
Your post
All masks must be a power of two. Not an increment of two.
#define ENTRY_1 0x01 #define ENTRY_2 0x02 #define ENTRY_3 0x04 #define ENTRY_4 0x08 #define ENTRY_5 0x10 #define ENTRY_6 0x12 #define ENTRY_7 0x14 #define ENTRY_8 0x16 #define ENTRY_9 0x18 #define ENTRY_10 0x20
#define ENTRY_1 0x01 #define ENTRY_2 0x02 #define ENTRY_3 0x04 #define ENTRY_4 0x08 #define ENTRY_5 0x10 #define ENTRY_6 0x20 #define ENTRY_7 0x40 #define ENTRY_8 0x80 #define ENTRY_9 0x100 #define ENTRY_10 0x200
Your post if ( (combination && ENTRY_2) ) { Direction[combination,1] = 1;} if ( (combination && ENTRY_3) ) { Direction[combination,2] = 1;}
Logical ands are wrong if ( (combination && TRUE) ) { Direction[combination,1] = 1;} if ( (combination && TRUE) ) { Direction[combination,2] = 1;}
Non-zero is true if ( (combination != 0) ) { Direction[combination,1] = 1;} if ( (combination != 0) ) { Direction[combination,2] = 1;}
Bit wise anding if ( (combination & ENTRY_2) != 0 ) { Direction[combination,1] = 1;} if ( (combination & ENTRY_3) != 0 ) { Direction[combination,2] = 1;}
Edit - just the shift operator as suggested by WHRoeder, forgot about that one thanks :)
Suggest, you replace Direction array with function below.
UPDATED: added -1
//untested bool Direction(int combination,int entryNumber) { return ((combination & ( 1 << (entryNumber-1) )) != 0); }
EDIT3:As its not an array any more you can have entryNumber with the range 1-21 instead of 0-20 . If the former - subtract 1, if the latter dont.
If you are just creating the Direction array to use as a flag and not making any further updates to it after you initialise it, then you dont need it.
You can replace all subsequent references of
Direction[number][entry-1]
with a call to a new function Direction(combination,entry), where Direction is now:
//untested // check any integer 'combination' and return true if the entryNumber bit is set. (starting from bit # 1) bool Direction(int combination,int entryNumber) { return ((combination & ( 1 << (entryNumber-1) )) != 0); }
and delete/remove your initialisation code, and the array, and the loop.
To understand how the function works read bitwise operators (Might want to google 'bitwise operators' too for more gentle introductions eg here )
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
In order to generate different combinations, I believe I need to work with permutations.
Every setup has A entries with 2 possibilities ( true/false).
Examples:
A = 5
entry1 entry2 entry3 entry4 entry 5
Combination 1: false false false false false
Combination 2: false false false false true
Combination 3: false false false true false
Combination 4: false false true false false
Combination 5: false true false false false
Combination 6: true false false false false
Combination 7: false false false true true
Combination 8: false false true false true
Combination 9: false true false false true
etc etc
Now I was wondering how to put this in code.
At the moment I can't get any further than this:
Does anybody have an idea? I think you need to be good a thinking in a wider dimension here. I'm not able to.