... just realised that, RefreshRates() in OnTick() function is totally unnecessary ... unless, I'm misunderstanding this.
I haven't read your code in your first post as it is wider than my screen.
RefreshRates may be a good idea when an order has been sent or when other code may have taken some time and some ticks may have been missed. It makes sure that you are working with up to date data.
BandVALUE_2=NormalizeDouble(BandUPPER_2-BandLOWER_2,Digits); // normalize
Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong- SL/TP are market orders when triggered, they don't need to be normalized, only 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
- Only the 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 to 1/10 then NormalizeDouble is wrong. Do it right.
double maximumSpread=0.5; // maximum spread allowed to open new order and/or modify existing trade
What does this mean? On EURUSD it is 5000 pips, On USDJPY it is 50 pips. Adjust Problems with a calculation - MQL4 forumdouble currentSpread=MarketInfo(Symbol(),MODE_SPREAD)/digits(); // acquire value of current spread
Why us a function call instead of just the predefined variables? What does the spread (in points) divided by 5 or 3 mean? Meaningless. You could use spread / pips2points or just compare directlymaximumSpread = 5; // pips if (Ask-Bid > maximumSpread * pips2dbl)
- Why are you looping and throwing away the next tick before returning? Just return. If you don't return then you must refresh rates.
- Are your books one column but two feet wide? No because that is unreadable. They are 6 inches, sometimes two columns, so you can read it easily. So should be your code. I'm not going to go scrolling back and forth trying to read it. Edit the post with formatted code and you might get additional help.
if(CompareDoubles(ResistanceATR(1),EMPTY_VALUE)==False
You would never write if( (2+2 == 4) == true) would you? if(2+2 == 4) is sufficient. So Don't write if(bool == true), just use if(bool) or if(!bool). Code becomes self documenting when you use meaningful variable names, like bool isLongEnabled. "if CompareDoubles " is an incomplete sentence. isEquivalent would make sense if you're testing approximate equal. Can price != price ? - MQL4 forum
OK ... this part of the script has been corrected ... and I hope it's alright.
double point2pip(){if(Digits==3||Digits==5)return(10); else return(1);} //+------------------------------------------------------------------+ void OnTick(){ if(!IsTradeAllowed())return; BandsCompress(); BandsExpands(); yesterdayATR(); SelectedATR(); selectedATR(); monthlyATR(); weeklyATR(); SignalATR(); TakeProfitATR=DoubleToStr(SelectedATR()*TargetATR/100,Digits); BandUPPER_0=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_UPPER,0); BandLOWER_0=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_LOWER,0); BandVALUE_0=DoubleToStr(BandUPPER_0-BandLOWER_0,Digits); BandUPPER_1=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_UPPER,1); BandLOWER_1=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_LOWER,1); BandVALUE_1=DoubleToStr(BandUPPER_1-BandLOWER_1,Digits); BandUPPER_2=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_UPPER,2); BandLOWER_2=iBands(NULL,0,13,3,0,PRICE_CLOSE,MODE_LOWER,2); BandVALUE_2=DoubleToStr(BandUPPER_2-BandLOWER_2,Digits); int signalATR=EntrySignal(); if(getOrdersTotal(MagicNumber,OP_BUY)>0){ orderStopLoss(MagicNumber,SupportATR(1)); orderTakeProfit(MagicNumber,TakeProfitATR); }else if(getOrdersTotal(MagicNumber,OP_SELL)>0){ orderStopLoss(MagicNumber,ResistanceATR(1)); orderTakeProfit(MagicNumber,TakeProfitATR); } double initialLotSize=LotSize(); if((OrderType()==OP_BUY)||(OrderType()==OP_SELL)==True){ double OrderSize=OrderLots(); double reducedLotSize=OrderSize/2; if(signalATR>0){ if(iBar<Time[0])OrderCLOSE(MagicNumber,OP_SELL); if(getOrdersTotal(MagicNumber,OP_BUY)==0 && directionATR!=+1){ OrderOPEN(OP_BUY,initialLotSize,0,SupportATR(1),0); iBar=Time[0]; directionATR=+1; }else{ double lastPriceBUY=getPriceBUY(); if(SupportATR(1)!=EMPTY_VALUE && lastPriceBUY!=EMPTY_VALUE && SupportATR(1)>=lastPriceBUY){ OrderOPEN(OP_BUY,reducedLotSize,0,SupportATR(1),0); } } }else if(signalATR<0){ if(iBar<Time[0])OrderCLOSE(MagicNumber,OP_BUY); if(getOrdersTotal(MagicNumber,OP_SELL)==0 && directionATR!=-1){ OrderOPEN(OP_SELL,initialLotSize,0,ResistanceATR(1),0); iBar=Time[0]; directionATR=-1; }else{ double lastPriceSELL=getPriceSELL(); if(ResistanceATR(1)!=EMPTY_VALUE && lastPriceSELL!=EMPTY_VALUE && ResistanceATR(1)<=lastPriceSELL){ OrderOPEN(OP_SELL,reducedLotSize,0,ResistanceATR(1),0); } } } } if((OrderType()==OP_BUY)==True && OrderProfit()==False && Close[0]<OrderOpenPrice()){ if(BandsCompress()==True)OrderCLOSE(MagicNumber,OP_BUY); }else if((OrderType()==OP_SELL)==True && OrderProfit()==False && Close[0]>OrderOpenPrice()){ if(BandsCompress()==True)OrderCLOSE(MagicNumber,OP_SELL); } double maximumSpread=0.5; // maximum spread (5 points) string currentSpread=DoubleToStr((Ask-Bid)/Point/point2pip(),1); if(currentSpread>(string)maximumSpread){ // while spread is greater than nominated orderSend=False; // disallow opening of any new trades Comment(space,"»»» current spread (",currentSpread,") exceeds maximum spread (",maximumSpread,")"); }else Comment(space,"iBands: expands (",BandsExpands(),") & compress (",BandsCompress(),") || ", "Server date & time: ",TimeToStr(TimeCurrent(),TIME_DATE)," ",TimeToStr(TimeCurrent(),TIME_MINUTES), " | Local date & time: ",TimeToStr(TimeLocal(),TIME_DATE)," ",TimeToStr(TimeLocal(),TIME_SECONDS), " | Execution (ms) Entry: ",executionEntry," Modify: ",executionModify," Exit: ",executionExit, " | ",Symbol()," ",Order," ",OrderLots(), " @ ",DoubleToStr(OrderOpenPrice(),Digits), " S / L @ (",DoubleToStr(MathAbs(OrderOpenPrice()-OrderStopLoss())/Point/point2pip(),Digits-4), ") T / P @ (",DoubleToStr(MathAbs(OrderOpenPrice()+OrderTakeProfit())/Point/point2pip(),Digits-4),")"); }
Should I also replace NormalizedDouble for something else ... or ... just in this particular case that's OK ???
//+------------------------------------------------------------------+ //| stdlib.mq4 | //| Copyright 2005-2014, MetaQuotes Software Corp. | //| https://www.mql4.com | //+------------------------------------------------------------------+ #property copyright "2005-2014, MetaQuotes Software Corp." #property link "https://www.mql4.com" #property library //+------------------------------------------------------------------+ //| right comparison of 2 doubles | //+------------------------------------------------------------------+ bool CompareDoubles(double number1,double number2) { if(NormalizeDouble(number1-number2,8)==0) return(true); else return(false); } //+------------------------------------------------------------------+
Should I also replace NormalizedDouble for something else ... or ... just in this particular case that's OK ???
You have to form your own opinion. Mine is : there is no problem with NormalizeDouble if properly used.
- darelco:I gave you the links. You must understand double comparison.
So, if ... Do NOT use NormalizedDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong... I have some query in regards to NormalizedDouble within the comparison of two doubles ...Should I also replace NormalizedDouble for something else ... or ... just in this particular case that's OK ???
- angevoyageur: You have to form your own opinion. Mine is : there is no problem with NormalizeDouble if properly used.
if(NormalizeDouble(number1-number2,8)==0) return(true);
Case in point. His function is used to compare two buffer valuesif(CompareDoubles(SupportATR(1),EMPTY_VALUE)==False
Either it will be exactly EMPTY_VALUE or it will not. The use is unnecessary.
If he uses the same function to compare two prices, the function fails when the differences is less than point/2 but greater than 10^-8.
The problem is NormalizeDouble is never necessary, and is seldom used properly.
Thank you guys,
Well, as angevoyageur points out: I have to form mine own opinion. So, let it be ...- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I'm just starting to learn coding in MQL4 and have a question to someone with much more experiences in that matter. Thus, in this part of the script below ... OnTick() - function ... I would like to disable any new orders as well as modification of already existing orders ... whenever the spread is above nominal value. However, with one exception ... which is the 'earlier exit'. So, I'm wondering about the operating speed of this EA and got some doubts. Should I keep the highlighted lines 'as is' or would be better to move it ... where EA calls directly for OrderSend(...) and/or OrderModify(...)