- Instead of Bid and Ask, consider using "OrderCurrentPrice()" instead.
- Your calculations are mixing units between points and prices and price deltas, so you will need to overhaul the code a bit before some of the other bugs can be fixed.
- Don't use NormaliseDouble(), rather align your priced with the TickSize as WHRoeder has explained here on many occasions. I don't remember the link but do a search and you will find it.
- You are also missing parenthesis for example in the calculation of the "stopPoints" where it should be something like "(aBidPrice - aNewSLPrice)/_Point" in order to properly get the value in Points.
- If "pnlPoints" and "stopPoints" are in points, then don't use "NormaliseDouble" because they don't have "Digits" and should in fact be an "int" (no need to be a "double").
- You compare "pnlPoints" and "breakeven" but I don't see its calculation anywhere.
- Also, as a sanity check, because the compiler many times messes this up, don't cascade "if"s one after the other without code block braces, except for the last one which is OK. You also have a "continue" statement which then invalidates the subsequent code block which will be executed almost always on opposite orders and when conditions are NOT met. Rather do something like this which will be easier to read:
if( ... ) { if( ... ) { if( ... ) { ... } } }
double pnlPoints = NormalizeDouble(aBidPrice - anOpenPrice/_Point,Digits); 1.23456 - 1.23000 / 0.00001 1.23456 - 123000 -122998.76544
-
Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it.
It's use is always wrong
- SL/TP (stops) need to be normalized to tick size (not Point.) (On 5Digit Broker Stops are only allowed to be placed on full pip values. How to find out in mql? - MQL4 forum) and abide by the limits Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial and that requires understanding floating point equality Can price != price ? - MQL4 forum
- Open price for pending orders need to be adjusted. On Currencies, Point == TickSize, so you will get the same answer, but it won't work on Metals. So do it right: Trailing Bar Entry EA - MQL4 forum or Bid/Ask: (No Need) to use NormalizeDouble in OrderSend - MQL4 forum
- Lot size must also be adjusted to a multiple of LotStep. If that is not a power of 1/10 then NormalizeDouble is wrong. Do it right.
Thanks for this, all look good, some were more "d'oh" moments than others, as for the "breakeven" that is a global integer I have also used if statements without code-block braces elsewhere in the EA & that works fine.
I will read up on the articles you suggested as well as LotStep, Point, & Ticksize as well.
Many thanks for your help
Regards
T
I will read up on the articles you suggested as well as LotStep, Point, & Ticksize as well.
Many thanks for your help
Regards
T
PS: Symbolinfo.mqh is a class of MQL5, its compatible to MT4, at least it can be compiled. Take that class, create a global object like
CSymbolInfo __Symbol;
and use the methods for
.Bid()
.Ask()
.NormalizePrice()
.LotsStep()
.LotsMin()
.LotsMax()
and its all done. There is no need to reinvent the same wheel all the time, if you dont want. And if you compare quotes which are stored in doubles, never use ==, instead use CompareDouble() which is part of stdlib.mqh.
Just another idea.
FMIC:
Thanks for explanation :) Whenever I change toe pnlPoints & stopPoints from double to integers, the error & warning section comes up with the "possible loss data due to type conversion". Could this be because there are double-formatted variables in the calculation by any chance - seeing as the anOpenprice & anAskPrice are double variables?;- Instead of Bid and Ask, consider using "OrderCurrentPrice()" instead.
- Your calculations are mixing units between points and prices and pricedeltas, so you will need to overhaul the code a bit before some of the other bugscan be fixed.
- Don't use NormaliseDouble(), rather align your priced with the TickSize as WHRoeder has explained here on many occasions. I don't remember the link but do a search and you will find it.
- You are also missing parenthesis for example in the calculation of the "stopPoints" where it should be something like "(aBidPrice - aNewSLPrice)/_Point" in order to properly get the value in Points.
- If "pnlPoints" and "stopPoints" are in points, then don't use "NormaliseDouble" because they don't have "Digits" and should in fact be an "int" (no need to be a "double").
- You compare "pnlPoints" and "breakeven" but I don't see its calculation anywhere.
- Also, as a sanity check, because the compiler many times messes this up, don't cascade "if"s one after the other without code block braces, except for the last one which is OK. You also have a "continue" statement which then invalidates the subsequent code block which will be executed almost always on opposite orders and when conditions are NOT met. Rather do something like this which will be easier to read:
double pnlPoints = (anOpenPrice - anAskPrice)/_Point;All the best
T
thecody1000:
Thanks for explanation :) Whenever I change toe pnlPoints & stopPoints from double to integers, the error & warning section comes up with the "possible loss data due to type conversion". Could this be because there are double-formatted variables in the calculation by any chance - seeing as the anOpenprice & anAskPrice are double variables?
Thanks for explanation :) Whenever I change toe pnlPoints & stopPoints from double to integers, the error & warning section comes up with the "possible loss data due to type conversion". Could this be because there are double-formatted variables in the calculation by any chance - seeing as the anOpenprice & anAskPrice are double variables?
Here is an example:
#define _ToPoints( dblPrice ) int( round( dblPrice / _Point ) ) double anClosePrice = OrderClosePrice(); int pnlPoints = _ToPoints( anOpenPrice - anClosePrice ); int stopPoints = _ToPoints( aNewSLPrice - anClosePrice ); int spreadPoints = (int) MarketInfo( _Symbol, MODE_SPREAD ); int mkStopLevel = (int) MarketInfo( _Symbol, MODE_STOPLEVEL ); int stopLevel = mkStopLevel + spreadPoints;
- Always be very careful with #defines.
_ToPoints(anOpenPrice - anClosePrice) // becomes int( round( anOpenPrice - anClosePrice / _Point ) ) // which you pointed out was wrong. // Always parenthesize arguments #define _ToPoints( dblPrice ) int( round( (dblPrice) / _Point ) )
- I'd code it
double tick_size(void){ return MarketInfo(_Symbol, MODE_TICKSIZE); } double min_lot(void){ return MarketInfo(_Symbol, MODE_MINLOT); } double lot_step(void){ return MarketInfo(_Symbol, MODE_LOTSTEP); } PRICE normalize_price(double p){ return round_nearest(p, tick_size() ); } double round_down( double v, double to){ return to * MathFloor(v / to); } double round_up( double v, double to){ return to * MathCeil( v / to); } double round_nearest( double v, double to){ return to * MathRound(v / to); } int to_points(double change){ return (int) round_nearest(change, _Point);
Looks good, but this also worked as well
int pnlPoints = int(NormalizeDouble((anOpenPrice - anAskPrice)/_Point,Digits)); int stopPoints = int(NormalizeDouble((aNewSLPrice - anAskPrice)/_Point,Digits)); int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo(Symbol(),MODE_SPREAD));
thecody1000:
I have already explained to you to not use NormalizeDouble here because Point values has no "Digits". Points are values are like 141231 for a price of 1.41231 - There are no decimal digits for points, so why would you want to Normalise an interger value with 4 or 5 decimal digits when it has none!
WHRoeder:
Thanks for the tips!
- Always be very careful with #defines.
- I'd code it
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
I know this is a common thread but I'm trying to modify my market order to breakeven (adding a stop loss to be equal to the order open price) when I make 100pips profit.
Everything is NormaliseDouble'd & there's even a mechanism that continues onto the next order select in the pool when a stop loss has already been added from a previous for loop (if(aNewSLPrice == aCurrentSL)continue;).
This means that there should be no Stoplevel violation anywhere. Here is the following code
The breakeven attribute is a global variable.