This forum is in read-only mode now. You may discuss your questions on forums of MQL4.community and MQL5.community
iMAonarray problem in an expert advisorBack to topics list | 1 2 |
|
47steps
2007.11.02 04:25
Once again on iMAONARRAY.
The examples I have found of setting up arrays seem only to apply to indicators. My problem is with an expert advisor. I am not sure I have implemented the array properly, so I would be very grateful if you could double check the code I am using for an iMAOnArray in an expert advisor. There are two arrays, and this is how I have set them up. double RSI[]; ArrayResize(RSI,100); ArraySetAsSeries(RSI,true); double OBV[]; ArrayResize(OBV,100); ArraySetAsSeries(OBV,true); for(int i=100; i>=0; i--) { RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i)); OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i)); } I then want to run MAs on the two arrays, as follows: double Green0 = iMAOnArray(RSI,0,2,0,MODE_SMA,0); double Green1 = iMAOnArray(RSI,0,2,0,MODE_SMA,1); and double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,0); double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,1); I do not seem to be able to get meaningful trades with this code. When I use Bars instead of 100, the EA cannot even complete one day of data. What am I doing wrong? Thanks for your help. Roy |
|
phy
2007.11.02 07:13
Try
ArrayResize(RSI,101) ArrayResize(OBV,101) Your loop has 101 increments but there are only 100 locations in the array. (this might not be the problem) |
|
47steps
2007.11.02 17:24
I'll give it a try, thanks. I guess that I have to make sure that i= is always a smaller number than the array size, is that the case?
What if I use Bars instead of a specific figure? |
|
phy
2007.11.02 20:23
As long as the number of items you store in an array is less than or equal to the storage aloocated for the array you will be OK.
Bars changes, as the chart grows. you can keep resizing if you are filling the array, if you like. |
|
47steps
2007.11.02 20:49
Thanks for the clarification. I think that the code below is working. In any case I do get trades that seem sensible. I suppose that if I set ArrayResize to Bars, I would need to have i=Bars-1.
As I said, it seems to work this way, but I'm wondering if it isn't counting backwards. Under what circumstances would you have ArraySetAsSeries true, with i=0 and <=101, and i++?? Very grateful for the help. 47 double OBV[]; ArrayResize(OBV,101); ArraySetAsSeries(OBV,false); for(int i=100; i>=0; i--) { OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i)); } double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,P_ZBar); double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,(P_ZBar+1)); |
|
phy
2007.11.02 21:18
I'm fuzzy on the ArraySetAsSeries... Would have to experiment some...
Apparently it is needed if you are going to create an array, and operate on it with the iXXXOnArray functions. Here is where it is dicussed in the documentation -- http://docs.mql4.com/search/ArraySetAsSeries |
|
47steps
2007.11.02 23:59
I have problems following the documentation on MQL, and find I have to experiment in most cases before I get anything right. Perhaps a background in programming (which I don't have) would help.
The Documentation says the following about ArraySetAsSeries: "Sets indexing direction of the array. If the set parameter has the TRUE value, the array will be indexed in a reversed order, i.e., the last element has a zero index. The FALSE value sets a standard indexing order. The function returns the previous status." By this account, when you set as TRUE you need int i=0; i>=100; i++ since the last array element is 0 and in the ixxxonarray function you will count from zero backwards from 0 by +1 increments. When you set as FALSE you need int int i=100; i>=0; i-- since the last array element is 100 and in the ixxxonarray function you will count backwards by -1 increments. Which is the correct choice for use in an EA? Or do I completely misunderstand this??? 47 |
|
phy
2007.11.03 02:45
You need it when you use some built in functions to perform some "indicator" function on an array you create.
Look again at the link, the other times ArraySetAsSeries is mentioned is all related to iSomethingOnArray(). "do I completely misunderstand this???" I don't know, just use it when they say you have to, which is when you are using one of the iSomethingOnArray() functions. Doesn't matter which way you count, up or down, as the function does one value at a time, unrelated to the count sequence. Just put bar 0 into array[0] bar 1 into array[1] etc for(int i=100; i>=0; i--) { RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i)); OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i)); } Your code should be fine |
|
47steps
2007.11.04 02:38
Thank you for your very helpful explanations. I appreciate your patience. I think the code is running properly, although I find it extremely slow when doing backtesting or optimizing.
47 |
|
phy
2007.11.04 06:26
An optimization here would be to reduce your array sizes to what is needed, instead of a size of 100 or 101 or Bars.
You can probably create and set the size once, it doesn't need to grow with what I see you doing. Use two loops, one to minimally fill the RSI array, another to minimally fill the OBV, unless both use the same period, then use one loop as you do above. |
|
47steps
2007.11.05 04:54
Thanks again for your helpful suggestions. Let us say that I want to run xxxonArray on 3 different Indicators: RSI, OBV, Force. Then in each case, I assume that I would only need to fill the array with a number of elements equal to the longest period of the xxxonArray + 1. Is that correct? The code would look as below. Would this be efficient coding? Can I use any letters I wish instead of i,j,k?
Also If I use ArraySetAsSeries TRUE for an array of xx elements, then the loop should be (int i=0; i<=xx; i++). Is this correct? Thanks, 47 double RSI[]; ArrayResize(RSI,35); ArraySetAsSeries(RSI,false); for(int i=34; i>=0; i--) { RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i)); } double Green0 = iMAOnArray(RSI,0,2,0,MODE_SMA,0); double Green1 = iMAOnArray(RSI,0,2,0,MODE_SMA,1); double Red0 = iMAOnArray(RSI,0,7,0,MODE_SMA,0); double Red1 = iMAOnArray(RSI,0,7,0,MODE_SMA,1); double Yellow0 = iMAOnArray(RSI,0,34,0,MODE_SMA,0); double Yellow1 = iMAOnArray(RSI,0,34,0,MODE_SMA,1); double BlueUpp0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,0); double BlueUpp1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,1); double BlueLow0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,0); double BlueLow1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,1); double OBV[]; ArrayResize(OBV,14); ArraySetAsSeries(OBV,false); for(int j=13; j>=0; j--) { OBV[j] = (iOBV(NULL,0,PRICE_MEDIAN,j)); } double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,0); double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,1); double Force[]; ArrayResize(Force,14); ArraySetAsSeries(Force,false); for(int k=13; k>=0; k--) { Force[k]= (iForce(NULL,0,MODE_SMMA,PRICE_TYPICAL,k)); } double FFast0 = iMAOnArray(Force,0,2,0,MODE_EMA,0); double FFast1 = iMAOnArray(Force,0,2,0,MODE_EMA,1); double FSlow0 = iMAOnArray(Force,0,13,0,MODE_EMA,0); double FSlow1 = iMAOnArray(Force,0,13,0,MODE_EMA,1); |
Back to topics list
| 1 2
Download MetaTrader 5 (450 Kb, web installer) — a new terminal for financial markets
