iMA not displaying correctly in backtesting - mql4

I developed and started testing an EA in MQL4 that uses iMA function. Basically the program compares the iMA value of the current candle with the iMA value of the previous candle. When I test the EA using the Strategy Tester (Every Tick) my EA is not opening and closing trades correctly. What I mean is the trade does not open on the correct candle. Upon further investigating I noticed, on the current candle the value for iMA in the data window and chart are the same, but they difer from the 'Print' value. The value for the previous candle is correct. When I did a Google search I found that someone in 2008 reported this exact same issue. In 2008 there didn't appear to be a solution.
Now that we are in a new decade, I'm wondering if there is a solution?
Does anyone know if iMA works in MQL5 Strategy Tester?
double MAEMACurrent = iMA(NULL,0,3,0,MODE_EMA,PRICE_CLOSE,0);
double MAEMAPrevious = iMA(NULL,0,3,0,MODE_EMA,PRICE_CLOSE,1);
double MASlowEMACurrent = iMA(NULL,0,10,0,MODE_EMA,PRICE_CLOSE,0);
double MASlowEMAPrevious = iMA(NULL,0,10,0,MODE_EMA,PRICE_CLOSE,1);
Print("MAEMACurrent " + MAEMACurrent + " MAEMAPrevious " + MAEMAPrevious + " MASlowEMACurrent " + MASlowEMACurrent + " MASlowEMAPrevious " + MASlowEMAPrevious);
Chart & Data Window:
MAEMACurrent: 1.95552
MAEMAPrevious: 1.95572
MASlowEMACurrent: 1.95201
MASlowEMAPrevious: 1.95097
Print Value:
MAEMACurrent: 1.95538
MAEMAPrevious: 1.95572
MASlowEMACurrent: 1.951086
MASlowEMAPrevious: 1.950972
As you can see from the above example the 'Chart & Data Window' values for MAEMACurrent and the MASlowEMACurrent do not match 'Print Value'.
This is the first time that I'm asking a question, so if I've missed something or I am not following the correct protocol for asking a question please let me know.

First, always use the "NormalizeDouble" function to round the values to a proper number of fractions. In your case, if there are just 5 digits after fraction, use the following code to round the values of "MASlowEMACurrent" and "MASlowEMAPrevious" to 5 digits:
double dNormalizedValue = NormalizeDouble(MASlowEMACurrent, 5);
In addition, never compare the value of the in-progress candle on the chart with the values which are returned by the indicator or price functions like (iMA, iClose, etc). Please note that even a very slight time difference could cause differences in the two values. For other candles (in your case the previous candle), since they all have been closed and there are no changes in progress so you can compare the values on the chart with the values returned by the functions. So, iMA is working as expected.

Related

why mql4 show error 130 when we use Stoploss in OrderSend function

I am trying to create a EA in mql4, but in OrderSend function, when i use some value instead of zero it show ordersend error 130. Please help to solve this problem
Code line is
int order = OrderSend("XAUUSD",OP_SELL,0.01,Bid,3,Bid+20*0.01,tp,"",0,0,Red);
error number 130 means Invalid stops.
so that means there is a problem with the stops you set with the ordersend function.
I suggest you set it like that:
int order = OrderSend("XAUUSD",OP_SELL,0.01,Bid,3,Bid+20*Point,tp,"",0,0,Red);
so you could use Point instead of hard coding it.
and to check what is the error number means. I think you could refer to: https://book.mql4.com/appendix/errors
You should know that there exists a minimum Stop Loss Size (mSLS) given in pips. "mSLS" changes with the currency and broker. So, you need to put in the OnInit() procedure of your EA a variable to get it:
int mSLS = MarketInfo(symbol,MODE_STOPLEVEL);
The distance (in pips) from your Order Open Price (OOP) and the Stop-Loss Price (SLP) can not be smaller than mSLS value.
I will try to explain a general algorithm I use for opening orders in my EAs, and then apply the constrain on Stop-Loss level (at step 3):
Step 1. I introduce a flag (f) for the type of operation I will open, being:
f = 1 for Buy, and
f = -1 for Sell
You know that there are mql4 constants OP_SELL=1 and OP_BUY=0 (https://docs.mql4.com/constants/tradingconstants/orderproperties).
Once I have defined f, I set my operation type variable to
int OP_TYPE = int(0.5((1+f)*OP_BUY+(1-f)*OP_SELL));
that takes value OP_TYPE=OP_BUY when f=1, while OP_TYPE=OP_SELL when f=-1.
NOTE: Regarding the color of the orders I put them in an array
color COL[2]= {clrBlue,clrRed};
then, having OP_TYPE, I set
color COLOR=COL[OP_TYPE];
Step 2. Similarly, I set the Order Open Price as
double OOP = int(0.5*((1+f)*Ask+(1-f)*Bid));
which takes value OOP=Ask when f=1, while OOP=Bid when f=-1.
Step 3. Then, given my desired Stop Loss in pips (an external POSITIVE parameter of my EA, I named sl) I make sure that sl > SLS. In other words, I check
if (sl <= mSLS) // I set my sl as the minimum allowed
{
sl = 1 + mSLS;
}
Step 4. Then I calculate the Stop-Loss Price of the order as
double SLP = OOP - f * sl * Point;
Step 5. Given my desired Take Profit in pips (an external POSITIVE parameter of my EA, I named tp) I calculate the Take-Profit Price (TPP) of the order as
double TPP = OOP + f * tp * Point;
OBSERVATION: I can not affirm, but, according to mql4 documentation, the minimum distance rule between the stop-loss limit prices and the open price also applies to the take profit limit price. In this case, a "tp" check-up needs to be done, similar to that of the sl check-up, above. that is, before calculating TPP it must be executed the control lines below
if (tp <= mSLS) // I set my tp as the minimum allowed
{
tp = 1 + mSLS;
}
Step 5. I call for order opening with a given lot size (ls) and slippage (slip) on the operating currency pair (from where I get the Ask and Bid values)
float ls = 0.01;
int slip = 3; //(pips)
int order = OrderSend(Symbol(),OP_TYPE,ls,OOP,slip,SLP,TPP,"",0,0,COLOR);
Note that with these few lines it is easy to build a function that opens orders of any type under your command, in any currency pair you are operating, without receiving error message 130, passing to the function only 3 parameters: f, sl and tp.
It is worth including in the test phase of your EA a warning when the sl is corrected for being less than the allowed, this will allow you to increase its value so that it does not violate the stop-loss minimum value rule, while you have more control about the risk of its operations. Remember that the "sl" parameter defines how much you will lose if the order fails because the asset price ended up varying too much in the opposite direction to what was expected.
I hope I could help!
Whilst the other two answers are not necessarily wrong (and I will not go over the ground they have already covered), for completeness of answers, they fail to mention that for some brokers (specifically ECN brokers) you must open your order first, without setting a stop loss or take profit. Once the order is opened, use OrderModify() to set you stop loss and/or take profit.

Why "Money" And "Float" are giving same result that is "1"?

♥float = ⟦float⟧1.00000000000000000000000000006
♥money = ⟦money⟧1.00000000000000000000000000006
program notepad
dialog ♥float
dialog ♥money
I am getting text as "1" in dialoge box for both the variables.
Range for float and money types are limited in the G1ANT language I believe. C# float itself has a limited range of 6 - 9 digits (C# Documentation Here). I changed the values to a shorter one and it works. Screenshots below:

How to get OHLC prices for a historic bar in MQL4?

I'm getting a bit stuck with a piece of mql4 code. Esentially, I need to access and store the OHLC prices of a historic bar back in time maximum 30 days back from current date. This is how I am currently doing it.
input int referenceDay=1;
static double reference;
if ( Day() == referenceDay ) reference = Open[0];
This is working fine until the point I either add to the code which, it then resets the reference back to 0. I am looking for a way to be able to access the history on each new candle and store the price for the referenceDay.
The objective is that whenever the EA is loaded to the chart, it automatically goes into the history and updates the reference price to be used on this trading day without having to wait for the entire month's iteration in real time.
The objective is that whenever the EA is loaded to the chart, it automatically goes into the history and updates the reference price
So far so good.
Once EA gets loaded,
the definition of static double reference; sets the initial value of reference == 0.;
next, the call to Day() sets the rules:
int Day(); returns the current day of the month, which is not the "today"'s-day, but the day of month of the so called last known server time. Given the EA was loaded on Sunday afternoon, or Monday morning, before the Market was opened, the "last known server time" is still Friday ... remember, the Server-side datetime rules ( so, if trading on APAC or Australia / New Zealand TimeZone servers, additional gymnastics are in place ).
So, as the code continues - in all such cases, when the input int referenceDay value will accidentally != the last known server time Day(), your ( just ) initialised variable reference will remain == 0.
Surprised?
May test it:
static double reference = EMPTY; // .SET EXPLICIT INITIALISER
if ( Day() == referenceDay )
{ reference = Open[0];
print( reference,
"AFTER Day() MATCHED referenceDay" // THIS NEED NOT HAPPEN
);
}
else
{ print( reference,
"ON( ",Day(), " ) ",
"AFTER Day() DID NOT MATCH referenceDay = ",
referenceDay
}
May redefine the assignment strategy, using:
input int referenceDAYinput = 1;
int referenceDAYnDaysBACK = max( 0, // FUSED
Day() - referenceDAYinput
);
static double referenceLEVEL = iOpen( _Symbol,
PERIOD_D1,
referenceDAYnDaysBACK
);
This code snippet certainly does not strive to be the complete solution, but shows the mechanics for achieving the desired objective.
Your actual code will have to solve how many Trading days - which is needed to address the TimeSeries-indexing logic of MetaTrader Terminal 4 platofrm -- ( not just the Calendar days ) -- there were in between the referenceDAYinput and the "last known server time"-Day(), but your are this close to have this done.

Logic behind COBOL code

I am not able to understand what is the logic behind these lines:
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
Data definition:
000330 01 VAR1 COMP-1 VALUE 3.4E38. // 3.4 x 10 ^ 38
Here are those lines in context (the sub-program returns a square root):
MOVE VAR1 TO PARM1.
CALL "SQUAREROOT_ROUTINE" USING
BY REFERENCE PARM1,
BY REFERENCE RESULT.
COMPUTE temp = RESULT - 1.843E19.
IF temp IS LESS THAN 1.0E16 THEN
DISPLAY "OK"
ELSE
DISPLAY "False"
END-IF.
These lines are just trying to test if the result returned by the SQUAREROOT_ROUTINE is correct. Since the program is using float-values and rather large numbers this might look a bit complicated. Let's just do the math:
You start with 3.4E38, the squareroot is 1.84390889...E19.
By subtracting 1.843E19 (i.e. the approximate result) and comparing the difference against 1.0E16 the program is testing whether the result is between 1.843E19 and 1.843E19+1.0E16 = 1.844E19.
Not that this test would not catch an error if the result from SQUAREROOT_ROUTINE was too low instead of too high. To catch both types of wrong results you should compare the absolute value of the difference against the tolerance.
You might ask "Why make things so complicated"? The thing is that float-values usually are not exact and depending on the used precision you will get sightly different results due to rounding-errors.
well the logic itself is very straight forward, you are subtracting 1.843*(10^19) from the result you get from the SQUAREROOT_ROUTINE and putting that value in the variable called temp and then If the value of temp is less than 1.0*(10^16) you are going to print a line out to the SYSOUT that says "OK", otherwise you are going to print out "False" (if the value was equal to or greater than).
If you mean the logic as to why this code exists, you will need to talk to the author of the code, but it looks like a debugging display that was left in the program.

primefaces3.0 X-scale value change

I'm implementing line charts of primefaces(3.0) , I'm trying to change the value of X-scale
The values which I'm using are minX="0" maxX="38" , since primefaces linecharts is using jqplot , I added this script
<script>
$(function(){
widget_category.plot.axes.xaxis._tickInterval = 1;
widget_category.plot.axes.xaxis.numberTicks = 38;
});
</script>
But still the coordinates is coming in decimals.
I would like to mention that for Y scale, the values I used are minY="40" maxY="110" with style="height:1005px;" , As i figured out for a scale value , which can be 10 if height is defined as 1005px i.e. 5 * 14 = 70 which means Y scale is of 5 intervals , with 14 values and the line height is 1005 as 5*14*14 = 980 + 25 (which is top-margin added) 1005.
Though the same is not working out for X-Scale.
Any help would be helpful.
The arithmetic in your Y values are all multiplication operations on whole numbers, which will always result in a whole number. These whole numbers correlate perfectly to pixels.
Your X range however involves a multiplication of 1.0 and 38, one being an integer value and the other being determined as a float or double number. When performing a multiplication operation where one number is a float then the result value will always be a float, and standard floating point artithmetic rules will apply. This is why the coordinates are coming in decimals which don't equate perfectly to pixels.
When using Javascript you need to be careful of these kinds of pitfalls because it is not a strongly typed language like Java and it will not point things like this out to you.

Resources