// http://www.stevehopwoodforex.com //please do not publish this outside of http://www.stevehopwoodforex.com #include #include #property strict #define NL "\n" string Gap,ScreenMessage; #define version "PendingEA 1.60" #property copyright "Copyright © 2015, milanese " #property link "http://SteveHopwoodForex.com" extern bool alerts = false; // Allow Alerts? extern string gen="----General inputs----"; extern int MagicNumber=88987; extern double RequiredMarginPercentile=1000; extern double FixedLot=0.1; extern bool RemoveEAAfterClosingLastEAPos=true; extern bool showUserDisplay=true; extern bool showDisplayBox=true; extern color displayBoxBackgroundColour=clrDimGray; extern bool DoNeverUseATR=false; extern bool AddSpreadToComment=true; extern int slippage=1; extern string gen1="----Pending Price Inputs----"; extern double PendingPriceBuy=0; extern double PendingPriceSell=0; extern bool SetAutoPendingStopBuy=true; extern bool SetAutoPendingStopSell=true; extern bool SetAutoPendingLimitBuy=false; extern bool SetAutoPendingLimitSell=false; extern bool useATRForDistancePendingToPrice=true; extern int atrDistancePendingTF=PERIOD_H4; extern double atrMultiplicatorDistancePending=1.1; extern int atrPeriodDistancePending=14; extern double DistancePendingToPrice=40; extern string pen1="----Use previous candle High/low for initial Pending----"; extern string pen2="----using this overrides all other initial PendingPrice settings----"; extern bool useCandleHighLowForInitial=false; extern int TimeFrameForCandleHL=PERIOD_M15; extern bool SetNewEveryNextIfNotFilled=true; extern string dyn="----Dynamic Initial Pending Move Options----"; extern string dyn1="----This is only working with AutoBuySellStop----"; extern bool movePendingBuyDownIfPriceMovesDown=false; extern bool movePendingSellUpIfPriceMovesUp=false; extern string opp="----After First Fill Options----"; extern bool RemoveEA_afterFilling=false; extern bool DeleteOppositeAfterFill=true; extern bool MoveOppositeOrderWithPrice=false; extern double OppositeMoveLevel=10; extern double MinDistanceForOppositeMoveToPrice=25; extern string sta="----Stacking Inputs----"; extern bool UseStacking=true; extern double LotForStackPositions=0.05; extern bool UseStackLotTooForFirstOpposite=false; extern bool useATRForStackingLevel=true; extern int atrForStackingLevelTF=PERIOD_H4; extern double atrMultiplicatorForStackingLevel=1; extern int atrPeriodForStackingLevel=14; extern double StackingLevel=50; extern int MaxOpenPositions=10; int TicksToCount=5; double AverageSpread=0; bool UseFixedLot=true; bool weHaveOpenTrades=false; extern string gen3="----Spread and Price Buffer inputs----"; extern double MaxSpreadAllowedMultiplicator=1; extern int MaxDiffPrice=4; extern string man="----Trade Management & PartClose & SL/TP inputs----"; extern string slSet="---SL/TP inputs----"; extern bool useATRForStopLoss=true; extern int atrForStopLossTF=PERIOD_H4; extern double atrMultiplicatorForStopLoss=1.4; extern int atrPeriodForStopLoss=14; extern double SL=50; extern bool useATRForTakeProfit=true; extern int atrForTakeProfitTF=PERIOD_H4; extern double atrMultiplicatorForTakeProfit=1.6; extern int atrPeriodForTakeProfit=14; extern double TP=150; extern string jumSet="---General TradeManagement inputs----"; extern bool manageAllTradesInThisPair=false; extern bool Use_SetBEAndJump=true; extern bool MoveSLOnlyIfWin=true; extern string pBasketSet="---PairBasket Management inputs----"; extern string pBasketSet1="---Values are in AccountCurrency----"; extern bool UseCloseAllOfPairInProfit=true; extern double CloseAllOfPairInProfit=75; extern bool UseCloseAllOfPairInLoss=true; extern double CloseAllOfPairInLoss=50; extern string partSet="---PartClose inputs----"; extern bool PartCloseEnabled=true; extern bool PartCloseWithBE=false; extern bool PartCloseAsFirstTP=true; extern bool useATRForPartClosePips=true; extern int atrForPartClosePipsTF=PERIOD_H4; extern double atrMultiplicatorForPartClosePips=1.5; extern int atrPeriodForPartClosePips=14; extern double PartCloseFirstTpPips=25; extern double PartClosePercent=10; extern string bejsSet="---BE & JS inputs----"; extern double BEProfit=4; extern double JumpStep=15; extern bool useATRForSLMinDistanceToPrice=true; extern int atrForSLMinDistanceToPriceTF=PERIOD_H4; extern double atrMultiplicatorForSLMinDistanceToPrice=1.1; extern int atrPeriodForSLMinDistanceToPrice=14; extern double SLMinDistanceToPrice=45; extern string fridayClSet="---FridayClose inputs----"; extern bool UseCloseFriday=false; extern int FridayCloseHour=21; extern int FridayCloseMinute=15; double bevar; bool TradeHasPartClosed=false; string SpreadGvName; int CountedTicks=0; double adr=0; double Risk_percent=3; double LotStep,MinLot,MaxLot; bool ForceTradeClosure=false; //Calculating the factor needed to turn pip values into their correct points value to accommodate different Digit size. //Thanks to Lifesys for providing this code. Coders, you need to briefly turn of Wrap and turn on a mono-spaced font to view this properly and see how easy it is to make changes. string pipFactor[] = {"JPY","XAG","SILVER","BRENT","WTI","XAU","GOLD","SP500","S&P","UK100","WS30","DAX30","DJ30","NAS100","CAC40"}; double pipFactors[] = { 100, 100, 100, 100, 100, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1}; double factor;//For pips/points stuff. Set up in int init() /////////////////////////////////////////////////////////////////////////////////////// bool BrokerHasSundayCandle=false; double awr_value=0; bool BuyOk=false; bool SellOk=false; //Steve shell mandatory variables int O_R_Setting_max_retries=10; double O_R_Setting_sleep_time=4.0; /* seconds */ double O_R_Setting_sleep_max=15.0; /* seconds */ int RetryCount=10;//Will make this number of attempts to get around the trade context busy error. bool CriminalIsECN=true; bool TakingEmergencyAction; int TicketNo=-1,OpenTrades; //end of Steve shell mandatory variables bool SignalBuy=false; bool SignalSell=false; double lot; bool FlagCloseFriday=false; int myHour=99; //int multiplier=1; double spread=0; int myMinute=99; double CostPip=5; bool TPChangeFlag=false; double lotForOrder=0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit(void) { while(IsConnected()==false) { Comment("Waiting for MT4 connection..."); Sleep(1000); }//while (IsConnected()==false) if(!IsExpertEnabled()) { if(alerts) Alert("HiddenPendingEA"+": Please enable \"Expert Advisors\" in the top toolbar of Metatrader to run this EA"); } if(!IsTradeAllowed()) { if(alerts) Alert("HiddenPendingEA"+": Trade is not allowed. EA cannot run. Please check \"Allow live trading\" in the \"Common\" tab of the EA properties window"); } factor=PFactor(Symbol()); LotStep= MarketInfo(Symbol(),MODE_LOTSTEP); MinLot = MarketInfo(Symbol(),MODE_MINLOT); MaxLot = MarketInfo(Symbol(),MODE_MAXLOT); BrokerHasSundayCandle=false; for(int CC=0; CC<8; CC++) { if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,CC))==0) { BrokerHasSundayCandle=true; break; } } //idiot check if(RemoveEA_afterFilling==true && UseStacking==true) { if(alerts) Alert("HiddenPendingEA"+":You cannot use Stacking & RemoveEA_afterFilling together!!"); if(alerts) Alert("HiddenPendingEA"+":RemoveEA_afterFilling is set to false"); RemoveEA_afterFilling=false; } if(useCandleHighLowForInitial==true) { SetAutoPendingStopBuy=false; SetAutoPendingStopSell=false; SetAutoPendingLimitBuy=false; SetAutoPendingLimitSell=false; } adr=GetAtr(Symbol(),atrDistancePendingTF,atrPeriodDistancePending,0); if(CloseEnough(adr,0))adr=0.05; if(DoNeverUseATR==false) { if(useATRForDistancePendingToPrice==true) { DistancePendingToPrice=NormalizeDouble((atrMultiplicatorDistancePending*adr*factor),0); if(alerts) Alert("HiddenPendingEA"+":DistancePendingToPrice calculated with ATR: ",DoubleToStr(DistancePendingToPrice,0)); } } if(SetAutoPendingStopBuy==true)PendingPriceBuy=NormalizeDouble(Ask+(DistancePendingToPrice/factor),Digits); if(SetAutoPendingStopSell==true)PendingPriceSell=NormalizeDouble(Bid-(DistancePendingToPrice / factor),Digits); if(SetAutoPendingLimitBuy==true)PendingPriceBuy=NormalizeDouble(Ask-(DistancePendingToPrice / factor),Digits); if(SetAutoPendingLimitSell==true)PendingPriceSell=NormalizeDouble(Bid+(DistancePendingToPrice/factor),Digits); if(UseStacking==false && DeleteOppositeAfterFill==true) MaxOpenPositions=1; if(UseStacking==false && DeleteOppositeAfterFill==false) MaxOpenPositions=2; if(useCandleHighLowForInitial==true) { PendingPriceBuy=iHigh(Symbol(),TimeFrameForCandleHL,1); PendingPriceSell=iLow(Symbol(),TimeFrameForCandleHL,1); } if(PendingPriceBuy!=0)CreateBuyLine(); if(PendingPriceSell!=0)CreateSellLine(); if(Use_SetBEAndJump && MoveSLOnlyIfWin==false && SL!=0) { SLMinDistanceToPrice=SL; if(alerts) Alert("SLMinDistanceToPrice set to SL-Value!"); if(alerts) Alert("SLMinDistanceToPrice new: ",DoubleToString(SLMinDistanceToPrice,1)); } if(Use_SetBEAndJump && MoveSLOnlyIfWin==false && SL==0) { if(alerts) Alert("SL can not be 0"); if(alerts) Alert("SL set to 30 pips!"); SL=30; SLMinDistanceToPrice=SL; if(alerts) Alert("SLMinDistanceToPrice new: ",DoubleToString(SLMinDistanceToPrice,1)); } //Check if we have open trades to adapt the PendingPrices this is a new security check if EA is new initilised CheckForOpenTrades(); if(DoNeverUseATR==false) { setATRValues(); } if(showUserDisplay==true) { DisplayUserFeedback(); } ChartSetInteger(ChartID(),CHART_FOREGROUND,false); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); ObjectDelete("messageBox"); ObjectDelete("PendingPriceBuy"); ObjectDelete("PendingPriceSell"); if(alerts) Alert(__FUNCTION__,"_UninitReason = ",getUninitReasonText(_UninitReason)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateLots(double risk_percent) { int SLp=740; double risk_value; risk_value=AccountBalance()*(risk_percent/100.0)/(SLp*MarketInfo(Symbol(),MODE_TICKVALUE)/factor/MarketInfo(Symbol(),MODE_TICKSIZE)); return(MathMin(MathMax(MinLot,MathRound(risk_value/LotStep)*LotStep),MaxLot)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountBuys(string strSymbol,int nMagic) { int nOrderCount=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(manageAllTradesInThisPair==false) { if(OrderMagicNumber()!=nMagic) continue; } if(OrderSymbol()!=strSymbol) continue; if(OrderType()==OP_BUY) nOrderCount++; } return(nOrderCount); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountSells(string strSymbol,int nMagic) { int nOrderCount=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(manageAllTradesInThisPair==false) { if(OrderMagicNumber()!=nMagic) continue; } if(OrderSymbol()!=strSymbol) continue; if(OrderType()==OP_SELL) nOrderCount++; } return(nOrderCount); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountBuysScanning(string strSymbol,int nMagic) { int nOrderCount=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if(OrderType()==OP_BUY) nOrderCount++; } return(nOrderCount); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountSellsScanning(string strSymbol,int nMagic) { int nOrderCount=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if(OrderType()==OP_SELL) nOrderCount++; } return(nOrderCount); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountHisto(string strSymbol,int nMagic) { int nOrderCount=0; for(int i=OrdersHistoryTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) if((OrderType()==OP_BUY) || (OrderType()==OP_SELL)) if(OrderMagicNumber()==nMagic) if(OrderSymbol()==strSymbol) nOrderCount++; } return(nOrderCount); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double LastOpenTradePrice(string strSymbol,int nMagic) { double priceLastOpenOrder=0; datetime opendate=0; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if(OrderOpenTime()>=opendate) { priceLastOpenOrder=OrderOpenPrice(); opendate=OrderOpenTime(); } } return(priceLastOpenOrder); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ /*double CalculateTpForBuy(string strSymbol) { RefreshRates(); double tp=0; awr_value = 1.385*(iATR(NULL, PERIOD_D1, 14, 1)); tp=Ask+NormalizeDouble(awr_value,Digits); return(tp); } double CalculateTpForSell(string strSymbol) { RefreshRates(); double tp=0; awr_value = 1.385*(iATR(NULL, PERIOD_D1, 14, 1)); tp=Bid-NormalizeDouble(awr_value,Digits); return(tp); } */ bool CheckTradeAllowedMargin() { bool allowed=true; if(IsTesting()==false) { if((MarketInfo(Symbol(),MODE_MARGINREQUIRED)*lot)>=(AccountFreeMargin()/2))allowed=false; if(AccountMargin()>0) { double freemarginpercentile=(AccountEquity()/AccountMargin())*100; if(freemarginpercentile=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if((OrderType()==OP_BUY)) ticket=OrderTicket(); if(OrderOpenPrice()>=OrderHighOpenPrice)OrderHighOpenPrice=OrderOpenPrice(); } if(ticket>0)bool order_select=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); return(OrderHighOpenPrice); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double ReturnLowOpenPrice(string strSymbol,int nMagic) { double OrderLowOpenPrice=9999; int ticket=-1; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if((OrderType()==OP_SELL)) ticket=OrderTicket(); if(OrderOpenPrice()<=OrderLowOpenPrice)OrderLowOpenPrice=OrderOpenPrice(); } if(ticket>0) bool order_select=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); return(OrderLowOpenPrice); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool AllowedSpread(string strSymbol) { bool IsOk=true; if(spread>AverageSpread*MaxSpreadAllowedMultiplicator)IsOk=false; return(IsOk); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ManageOpenTrades() { if(UseCloseFriday==true)CloseFriday(Symbol(),MagicNumber); if(MoveOppositeOrderWithPrice==true && DeleteOppositeAfterFill==false) MoveOpposite(); if(Use_SetBEAndJump==true && MoveSLOnlyIfWin==true) SetBEAndJump(Symbol(),MagicNumber); if(Use_SetBEAndJump==true && MoveSLOnlyIfWin==false) DoJS(Symbol(),MagicNumber); if(PartCloseEnabled==true) { if(PartCloseAsFirstTP==true)doPartCloseFirstTP(Symbol(),MagicNumber); } if(UseCloseAllOfPairInProfit==true) { double ProfitPair=GetProfitPair(Symbol()); if(ProfitPair>=CloseAllOfPairInProfit) CloseAllOfPair(); if(ForceTradeClosure==true) CloseAllOfPair(); } if(UseCloseAllOfPairInLoss==true) { double ProfitPair=GetProfitPair(Symbol()); if(ProfitPair<=-(CloseAllOfPairInLoss)) CloseAllOfPair(); if(ForceTradeClosure==true) CloseAllOfPair(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MoveOpposite() { if(CountBuysScanning(Symbol(),MagicNumber)>0) { if(Bid>PendingPriceSell+(MinDistanceForOppositeMoveToPrice/factor)+(OppositeMoveLevel/factor)) PendingPriceSell=PendingPriceSell+(OppositeMoveLevel/factor); CreateSellLine(); } if(CountSellsScanning(Symbol(),MagicNumber)>0) { if(Bid0) { weHaveOpenTrades=true; if(UseStacking==true) { if(CountBuysScanning(Symbol(),MagicNumber)+CountSellsScanning(Symbol(),MagicNumber)0) { weHaveOpenTrades=true; if(UseStacking==true) { if(CountBuysScanning(Symbol(),MagicNumber)+CountSellsScanning(Symbol(),MagicNumber)=20)) return (false); else return (true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SM(string message) { ScreenMessage=StringConcatenate(ScreenMessage,Gap,message); }//End void SM() //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DisplayUserFeedback() { string marginOk=""; if(IsTesting()==true && IsVisualMode()==false) return; if(showUserDisplay==false) { ObjectDelete("messageBox"); return; } if(showDisplayBox==true) { RectLabelCreate(); } else ObjectDelete("messageBox"); ScreenMessage=""; if(CheckTradeAllowedMargin()==true) marginOk="Margin is OK to take trades"; if(CheckTradeAllowedMargin()==false) marginOk="We have no Margin to take trades"; SM("Updates for this EA are to be found at http://www.stevehopwoodforex.com"+NL); SM(version); SM(" Copyright 2015, by milanese"+NL); SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); SM("Broker time = "+TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS)+" Local time = "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+" GMT time = "+TimeToStr(TimeGMT(),TIME_DATE|TIME_SECONDS)+NL); SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); SM("Open Price of last open order="+DoubleToStr(LastOpenTradePrice(Symbol(),MagicNumber),Digits)+NL); if(int(LastClosedTrade(Symbol(),MagicNumber))!=0) { SM("Last EA Trade closure was at: "+DateToStr(LastClosedTrade(Symbol(),MagicNumber))+NL); } else SM("No closed EA Trade found!"+NL); if(int(LastOpenedTrade(Symbol(),MagicNumber))!=0) { SM("Last EA Trade was opened at: "+DateToStr(LastOpenedTrade(Symbol(),MagicNumber))+NL); } else SM("No opened EA Trade found!"+NL); SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); if(Use_SetBEAndJump==true) { if(PartCloseEnabled==true && PartCloseWithBE==true) { double CloseLots=NormalizeLots(Symbol(),FixedLot *(PartClosePercent/100)); double CloseLotsStack=NormalizeLots(Symbol(),LotForStackPositions *(PartClosePercent/100)); SM("Part-close is enabled at "+DoubleToStr(PartClosePercent,2)+"% ("+DoubleToStr(CloseLots,2)+" Fixed lots to close)"+NL); if(UseStacking==True) SM("Part-close is enabled at "+DoubleToStr(PartClosePercent,2)+"% ("+DoubleToStr(CloseLotsStack,2)+" LotsForStack to close)"+NL); }//if (PartCloseEnabled) } if(PartCloseEnabled==true && PartCloseAsFirstTP==true) { SM("PartClose as first TP is enabled"+NL); double CloseLots=NormalizeLots(Symbol(),FixedLot *(PartClosePercent/100)); double CloseLotsStack=NormalizeLots(Symbol(),LotForStackPositions *(PartClosePercent/100)); SM("Part-close is enabled at "+DoubleToStr(PartClosePercent,2)+"% ("+DoubleToStr(CloseLots,2)+" Fixed lots to close)"+NL); if(UseStacking==True) SM("Part-close is enabled at "+DoubleToStr(PartClosePercent,2)+"% ("+DoubleToStr(CloseLotsStack,2)+" LotsForStack to close)"+NL); } SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); if(DoNeverUseATR==true) { SM("All automatic calculating ATR settings are deactivated, manual inputs are used"+NL); } if(DoNeverUseATR==false) { if(useATRForDistancePendingToPrice==true) { SM("DistancePendingToPrice (for initial Pendings) is calculated with ATR"+NL); } if(useATRForStackingLevel==true && UseStacking==true) { SM("Stack-Level is calculated with ATR"+NL); } if(useATRForSLMinDistanceToPrice==true && Use_SetBEAndJump==true) { SM("SLMinDistance is calculated by ATR"+NL); } if(useATRForPartClosePips==true && PartCloseEnabled==true && PartCloseAsFirstTP==true) { SM("PartClosePipsForFirstTP are calculated by ATR"+NL); } } SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); if(manageAllTradesInThisPair==true) { SM("The EA manages all open positions on :"+Symbol()+NL); } SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); if(UseStacking==true) { SM("StackingLevel= "+DoubleToStr(StackingLevel,1)+NL); } SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); SM("SLMinDistanceToPrice= "+DoubleToStr(SLMinDistanceToPrice,1)+NL); SM("PendingPriceBuy= "+DoubleToString(PendingPriceBuy,Digits)+NL); SM("PendingPriceSell= "+DoubleToString(PendingPriceSell,Digits)+NL); SM("Profit for all open Positions in this Pair = "+DoubleToString(GetProfitPair(Symbol()),2)+NL); if(UseCloseAllOfPairInProfit==true) { SM("PairBasket will be closed if PairProfit = "+DoubleToString(CloseAllOfPairInProfit,2)+NL); } if(UseCloseAllOfPairInLoss==true) { SM("PairBasket will be closed if PairLoss = "+DoubleToString(CloseAllOfPairInLoss,2)+NL); } SM("Count Open Buys="+IntegerToString(CountBuys(Symbol(),MagicNumber))+NL); SM("Count Open Sells="+IntegerToString(CountSells(Symbol(),MagicNumber))+NL); SM("Count Historical Trades EA="+IntegerToString(CountHisto(Symbol(),MagicNumber))+NL); SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); if(CloseEnough(AverageSpread,0)) { GetAverageSpread(); int left=TicksToCount-CountedTicks; SM("Calculating the average spread. "+DoubleToStr(left,0)+" left to count."+NL); }// else SM("AverageSpread(in points) is = "+DoubleToStr((AverageSpread),0)+" MaxAllowedSpread(in points) is = "+DoubleToStr((AverageSpread*MaxSpreadAllowedMultiplicator),0)+" Actual Spread(in points) is= "+DoubleToStr((spread),0)+NL); SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL); SM("RequiredMarginPercentile= "+DoubleToString(RequiredMarginPercentile,2)+NL); SM(marginOk+NL); Comment(ScreenMessage); }//void DisplayUserFeedback() //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool SendSingleTrade(int type,string comment,double lotsize,double price,double stop,double take) { //pah (Paul) contributed the code to get around the trade context busy error. Many thanks, Paul. bool do_order=false; int ticket=-1; if((CountBuysScanning(Symbol(),MagicNumber)+CountSellsScanning(Symbol(),MagicNumber))-1) { ModifyOrder(ticket,stop,take); if(UseStacking==false && DeleteOppositeAfterFill==true) { PendingPriceBuy=0; PendingPriceSell=0; ObjectDelete("PendingPriceSell"); ObjectDelete("PendingPriceBuy"); } if(UseStacking==false && DeleteOppositeAfterFill==false) { if(type==OP_SELL) { PendingPriceSell=0; ObjectDelete("PendingPriceSell"); } if(type==OP_BUY) { PendingPriceBuy=0; ObjectDelete("PendingPriceBuy"); } } if(UseStacking==true && DeleteOppositeAfterFill==false) { if(orders_count(MagicNumber)<=MaxOpenPositions) { if(type==OP_SELL) { PendingPriceSell=Bid-(StackingLevel/factor); ObjectDelete("PendingPriceSell"); CreateSellLine(); } if(type==OP_BUY) { PendingPriceBuy=Ask+(StackingLevel/factor); ObjectDelete("PendingPriceBuy"); CreateBuyLine(); } } else { if(type==OP_SELL) { PendingPriceSell=0; ObjectDelete("PendingPriceSell"); } if(type==OP_BUY) { PendingPriceBuy=0; ObjectDelete("PendingPriceBuy"); } } } if(UseStacking==true && DeleteOppositeAfterFill==true) { if(orders_count(MagicNumber)<=MaxOpenPositions) { if(type==OP_SELL) { PendingPriceSell=Bid-(StackingLevel/factor); PendingPriceBuy=0; ObjectDelete("PendingPriceSell"); ObjectDelete("PendingPriceBuy"); CreateSellLine(); } if(type==OP_BUY) { PendingPriceBuy=Ask+(StackingLevel/factor); PendingPriceSell=0; ObjectDelete("PendingPriceBuy"); ObjectDelete("PendingPriceSell"); CreateBuyLine(); } } else { if(type==OP_SELL) { PendingPriceSell=0; PendingPriceBuy=0; ObjectDelete("PendingPriceSell"); ObjectDelete("PendingPriceBuy"); } if(type==OP_BUY) { PendingPriceBuy=0; PendingPriceSell=0; ObjectDelete("PendingPriceBuy"); ObjectDelete("PendingPriceSell"); } } } break;//Exit the trade send loop }//if (ticket > -1)} if(cc == RetryCount - 1) return(false); //Error trapping for both if(ticket<0) { string stype; if(type == OP_BUY) stype = "OP_BUY"; if(type == OP_SELL) stype = "OP_SELL"; if(type == OP_BUYLIMIT) stype = "OP_BUYLIMIT"; if(type == OP_SELLLIMIT) stype = "OP_SELLLIMIT"; if(type==OP_BUYSTOP) stype="OP_BUYSTOP"; if(type== OP_SELLSTOP) stype = "OP_SELLSTOP"; int err=GetLastError(); if(alerts) Alert(Symbol()," ",WindowExpertName()," ",stype," order send failed with error(",err,"): ",ErrorDescription(err)); Print(Symbol()," ",WindowExpertName()," ",stype," order send failed with error(",err,"): ",ErrorDescription(err)); return(false); }//if (ticket < 0) }//for (int cc = 0; cc < RetryCount; cc++); TicketNo=ticket; //Make sure the trade has appeared in the platform's history to avoid duplicate trades. //My mod of Matt's code attempts to overcome the bastard crim's attempts to overcome Matt's code. bool TradeReturnedFromCriminal=false; while(!TradeReturnedFromCriminal) { TradeReturnedFromCriminal=O_R_CheckForHistory(ticket); if(!TradeReturnedFromCriminal) { if(alerts) Alert(Symbol()," sent trade not in your trade history yet. Turn of this ea NOW."); }//if (!TradeReturnedFromCriminal) }//while (!TradeReturnedFromCriminal) //Got this far, so trade send succeeded if(RemoveEA_afterFilling==true) ExpertRemove(); if(alerts) Alert("Trade has filled correctly"); Print("Trade has filled correctly"); return(true); } return(false); }//End bool SendSingleTrade(int type, string comment, double lotsize, double price, double stop, double take) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ModifyOrder(int ticket,double stop,double take) { //Modifies an order already sent if the crim is ECN. if(CloseEnough(stop,0) && CloseEnough(take,0)) return; //nothing to do if(!OrderSelect(ticket,SELECT_BY_TICKET)) return;//Trade does not exist, so no mod needed //RetryCount is declared as 10 in the Trading variables section at the top of this file for(int cc=0; cc0 && stop>0) { while(IsTradeContextBusy()) Sleep(100); if(OrderModify(ticket,OrderOpenPrice(),stop,take,OrderExpiration(),CLR_NONE)) { if(alerts) Alert("Modify Order Succeeded !"); Print("Modify Order Succeeded !"); return; } }//if (take > 0 && stop > 0) if(!CloseEnough(take,0) && CloseEnough(stop,0)) { while(IsTradeContextBusy()) Sleep(100); if(OrderModify(ticket,OrderOpenPrice(),OrderStopLoss(),take,OrderExpiration(),CLR_NONE)) { if(alerts) Alert("Modify Order Succeeded !"); Print("Modify Order Succeeded !"); return; } }//if (take == 0 && stop != 0) if(CloseEnough(take,0) && !CloseEnough(stop,0)) { while(IsTradeContextBusy()) Sleep(100); if(OrderModify(ticket,OrderOpenPrice(),stop,OrderTakeProfit(),OrderExpiration(),CLR_NONE)) { if(alerts) Alert("Modify Order Succeeded !"); Print("Modify Order Succeeded !"); return; } }//if (take == 0 && stop != 0) }//for (int cc = 0; cc < RetryCount; cc++) //Got this far, so the order modify failed int err=GetLastError(); Print(Symbol()," SL/TP order modify failed with error(",err,"): ",ErrorDescription(err)); if(alerts) Alert(Symbol()," SL/TP order modify failed with error(",err,"): ",ErrorDescription(err)); }//void ModifyOrder(int ticket, double tp, double sl) //============================================================================= // O_R_CheckForHistory() // // This function is to work around a very annoying and dangerous bug in MT4: // immediately after you send a trade, the trade may NOT show up in the // order history, even though it exists according to ticket number. // As a result, EA's which count history to check for trade entries // may give many multiple entries, possibly blowing your account! // // This function will take a ticket number and loop until // it is seen in the history. // // RETURN VALUE: // TRUE if successful, FALSE otherwise // // // FEATURES: // * Re-trying under some error conditions, sleeping a random // time defined by an exponential probability distribution. // // * Displays various error messages on the log for debugging. // // ORIGINAL AUTHOR AND DATE: // Matt Kennel, 2010 // //============================================================================= bool O_R_CheckForHistory(int ticket) { //My thanks to Matt for this code. He also has the undying gratitude of all users of my trading robots int lastTicket=OrderTicket(); int cnt=0; int err=GetLastError(); // so we clear the global variable. err=0; bool exit_loop=false; bool success=false; while(!exit_loop) { /* loop through open trades */ int total=OrdersTotal(); for(int c=0; c3) { /* look through history too, as order may have opened and closed immediately */ total=OrdersHistoryTotal(); for(int c=0; cO_R_Setting_max_retries) { exit_loop=true; } if(!(success || exit_loop)) { Print("Did not find #"+IntegerToString(ticket)+" in history, sleeping, then doing retry #"+IntegerToString(cnt)); O_R_Sleep(O_R_Setting_sleep_time,O_R_Setting_sleep_max); } } // Select back the prior ticket num in case caller was using it. if(lastTicket>=0) { bool order_select=OrderSelect(lastTicket,SELECT_BY_TICKET,MODE_TRADES); } if(!success) { Print("Never found #"+IntegerToString(ticket)+" in history! crap!"); } return(success); }//End bool O_R_CheckForHistory(int ticket) //============================================================================= // O_R_Sleep() // // This sleeps a random amount of time defined by an exponential // probability distribution. The mean time, in Seconds is given // in 'mean_time'. // This returns immediately if we are backtesting // and does not sleep. // //============================================================================= void O_R_Sleep(double mean_time,double max_time) { if(IsTesting()) { return; // return immediately if backtesting. } double p = (MathRand()+1) / 32768.0; double t = -MathLog(p)*mean_time; t=MathMin(t,max_time); int ms=int(t*1000); if(ms<10) { ms=10; } Sleep(ms); }//End void O_R_Sleep(double mean_time, double max_time) //see also the original function by WHRoeder, http://forum.mql4.com/45425#564188, fxdaytrader double NormalizeLots(string symbol,double lots) { if(CloseEnough(MathAbs(lots),0.0)) return(0.0); //just in case ... otherwise it may happen that after rounding 0.0 the result is >0 and we have got a problem, fxdaytrader double ls=MarketInfo(symbol,MODE_LOTSTEP); lots=MathMin(MarketInfo(symbol,MODE_MAXLOT),MathMax(MarketInfo(symbol,MODE_MINLOT),lots)); //check if lots >= min. lots && <= max. lots, fxdaytrader return(MathRound(lots/ls)*ls); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool NewBar(int TimeFrame) { static datetime LastTime=0; if(iTime(NULL,TimeFrame,0)!=LastTime) { LastTime=iTime(NULL,TimeFrame,0); return (true); } else return (false); } // for 6xx build compatibility string StringSubstrOld(string x,int a,int b=-1) { if(a<0) a=0; // Stop odd behaviour if(b<=0) b=-1; // new MQL4 EOL flag return StringSubstr(x,a,b); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void LookForTrading() { bool Sell_Flag=true; bool Buy_Flag=true; SignalBuy=false; SignalSell=false; RefreshRates(); double DiffOfPriceSell=MathAbs(Bid-PendingPriceSell); double DiffOfPriceBuy=MathAbs(Ask-PendingPriceBuy); if(DiffOfPriceSell>MaxDiffPrice/factor) Sell_Flag=false; if(DiffOfPriceBuy>MaxDiffPrice/factor) Buy_Flag=false; if(PendingPriceBuy!=0)CreateBuyLine(); if(PendingPriceSell!=0)CreateSellLine(); int m_bar=0;//Need to deal with a Sunday candle int d= TimeDayOfWeek(TimeCurrent()); if(d == 1 && BrokerHasSundayCandle && Period()==1440) m_bar=m_bar+1; adr=GetAtr(Symbol(),PERIOD_D1,10,m_bar+1); if(movePendingBuyDownIfPriceMovesDown && SetAutoPendingStopBuy) { if(CountBuysScanning(Symbol(),MagicNumber)==0 && CountSellsScanning(Symbol(),MagicNumber)==0) { if((PendingPriceBuy-Bid)>DistancePendingToPrice/factor) { PendingPriceBuy=Bid+(DistancePendingToPrice/factor); CreateBuyLine(); } } } if(movePendingSellUpIfPriceMovesUp && SetAutoPendingStopSell) { if(CountSellsScanning(Symbol(),MagicNumber)==0 && CountBuysScanning(Symbol(),MagicNumber)==0) { if((Bid-PendingPriceSell)>DistancePendingToPrice/factor) { PendingPriceSell=Bid-(DistancePendingToPrice/factor); CreateSellLine(); } } } if(useCandleHighLowForInitial==true && (CountBuysScanning(Symbol(),MagicNumber)==0 && CountSellsScanning(Symbol(),MagicNumber)==0) && SetNewEveryNextIfNotFilled==true) { PendingPriceBuy=iHigh(Symbol(),TimeFrameForCandleHL,1); PendingPriceSell=iLow(Symbol(),TimeFrameForCandleHL,1); CreateBuyLine(); CreateSellLine(); } // SIGNAL BUY CHECK RefreshRates(); if((DeleteOppositeAfterFill==true && CountSellsScanning(Symbol(),MagicNumber)==0 && CountBuysScanning(Symbol(),MagicNumber)<=MaxOpenPositions)) { if(Bid>PendingPriceBuy && Buy_Flag==true) SignalBuy=true; } if((DeleteOppositeAfterFill==false && CountSellsScanning(Symbol(),MagicNumber)<=MaxOpenPositions && CountBuysScanning(Symbol(),MagicNumber)<=MaxOpenPositions)) { if(Bid>PendingPriceBuy && Buy_Flag==true) SignalBuy=true; } // SIGNAL SELL CHECK if((DeleteOppositeAfterFill==true && CountBuysScanning(Symbol(),MagicNumber)==0 && CountSellsScanning(Symbol(),MagicNumber)<=MaxOpenPositions)) { if(Bid=TicksToCount) { AverageSpread=SpreadTotal/TicksToCount; //Save the average for restarts. GlobalVariableSet(SpreadGvName,AverageSpread); }//if (CountedTicks >= TicksToCount) }//void GetAverageSpread() //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawHorizontalLine(string name,double price,color col,int style,int width) { ObjectDelete(name); ObjectCreate(name,OBJ_HLINE,0,TimeCurrent(),price); ObjectSet(name,OBJPROP_COLOR,col); ObjectSet(name,OBJPROP_STYLE,style); ObjectSet(name,OBJPROP_WIDTH,width); }//void DrawLine(string name, double price, color col) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CreateBuyLine() { ObjectDelete("PendingPriceBuy"); DrawHorizontalLine("PendingPriceBuy",PendingPriceBuy,DarkGreen,STYLE_SOLID,2); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CreateSellLine() { ObjectDelete("PendingPriceSell"); DrawHorizontalLine("PendingPriceSell",PendingPriceSell,Red,STYLE_SOLID,2); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double PFactor(string symbol) { //This code supplied by Lifesys. Many thanks Paul - we all owe you. Gary was trying to make me see this, but I could not understand his explanation. Paul used Janet and John words for(int i=ArraySize(pipFactor)-1; i>=0; i--) if(StringFind(symbol,pipFactor[i],0)!=-1) return (pipFactors[i]); return(10000); }//End double PFactor(string pair) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CloseEnough(double num1,double num2) { /* This function addresses the problem of the way in which mql4 compares doubles. It often messes up the 8th decimal point. For example, if A = 1.5 and B = 1.5, then these numbers are clearly equal. Unseen by the coder, mql4 may actually be giving B the value of 1.50000001, and so the variable are not equal, even though they are. This nice little quirk explains some of the problems I have endured in the past when comparing doubles. This is common to a lot of program languages, so watch out for it if you program elsewhere. Gary (garyfritz) offered this solution, so our thanks to him. */ if(num1==0 && num2==0) return(true); //0==0 if(MathAbs(num1 - num2) / (MathAbs(num1) + MathAbs(num2)) < 0.00000001) return(true); //Doubles are unequal return(false); }//End bool CloseEnough(double num1, double num2) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick() { SpreadGvName=Symbol()+" THPEA_average_spread"; AverageSpread=GlobalVariableGet(SpreadGvName);//If no gv, then the value will be left at zero. double sell_lot=FixedLot,buy_lot=FixedLot; if(weHaveOpenTrades==true && RemoveEAAfterClosingLastEAPos==true) { if(orders_count(MagicNumber)==0) { weHaveOpenTrades=false; PendingPriceBuy=0; PendingPriceSell=0; ObjectDelete("PendingPriceBuy"); ObjectDelete("PendingPriceSell"); ExpertRemove(); } } if(DoNeverUseATR==false) { setATRValues(); } if(showUserDisplay==true) { DisplayUserFeedback(); } if(CountBuys(Symbol(),MagicNumber)>0 || CountSells(Symbol(),MagicNumber)>0) ManageOpenTrades(); //Spread calculation spread=MarketInfo(Symbol(),MODE_SPREAD); if(CloseEnough(AverageSpread,0)) { GetAverageSpread(); ScreenMessage=""; int left=TicksToCount-CountedTicks; SM("Calculating the average spread. "+DoubleToStr(left,0)+" left to count."); Comment(ScreenMessage); }// //Keep the average spread updated static double SpreadTotal=0; static int counter=0; SpreadTotal+=spread; counter++; if(counter>=2000) { AverageSpread=SpreadTotal/counter; //Save the average for restarts. GlobalVariableSet(SpreadGvName,AverageSpread); SpreadTotal=0; counter=0; }//if (counter >= 500) if(LotForStackPositions!=FixedLot && LotForStackPositions!=0) { if((CountBuysScanning(Symbol(),MagicNumber)>0) && UseStacking==true) buy_lot=LotForStackPositions; else buy_lot=FixedLot; if((CountSellsScanning(Symbol(),MagicNumber)>0) && UseStacking==true) sell_lot=LotForStackPositions; else sell_lot=FixedLot; if((UseStackLotTooForFirstOpposite==true) && (CountSellsScanning(Symbol(),MagicNumber)>0 || CountBuysScanning(Symbol(),MagicNumber)>0)) { sell_lot=LotForStackPositions; buy_lot=LotForStackPositions; } } //Lot size and part-close idiot check for the cretins. Code provided by phil_trade. Many thanks, Philippe. //adjust Min_lot if(buy_lot=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(manageAllTradesInThisPair==false) { if(OrderMagicNumber()!=nMagic) continue; } if(OrderSymbol()!=symbol)continue; if(OrderType()==OP_SELL) { ticket=OrderTicket(); doPartClose=false; if(OrderStopLoss()>OrderOpenPrice() || CloseEnough(OrderStopLoss(),0)) { NewSL=NormalizeDouble(OrderOpenPrice()-(BEProfit/factor),Digits); if(PartCloseWithBE==true && PartCloseEnabled==true) { doPartClose=true; } } else { doPartClose=false; NewSL=NormalizeDouble(OrderStopLoss()-(JumpStep/factor),Digits); } if((NewSL-Bid)>(SLMinDistanceToPrice/factor)) { if(((NewSLAsk+(10/factor))) { if(alerts) Alert("SetBEAndJump :Attempting to move SL of ",symbol," to ",NewSL); Print("SetBEAndJump :Attempting to move SL of ",symbol," to ",NewSL); ModifyOrder(ticket,NewSL,0); if(doPartClose==true) { PartCloseTrade(ticket); if(TradeHasPartClosed==true && alerts)Alert("Ticket: ",ticket," was part closed"); else// Alert("Partclose failed!"); TradeHasPartClosed=false; }//doPartClose }// if(((NewSLAsk+(10/factor))) }//if((NewSL-Bid)>(SLMinDistanceToPrice/factor)) }//OP_SELL if(OrderType()==OP_BUY) { ticket=OrderTicket(); doPartClose=false; if(OrderStopLoss()(SLMinDistanceToPrice/factor)) { if(((NewSL>OrderStopLoss()) || (OrderStopLoss()<(1/factor))) && (NewSL!=0) && (NewSLOrderStopLoss()) || (OrderStopLoss()<(1/factor))) && (NewSL!=0) && (NewSL(SLMinDistanceToPrice/factor)) }//OP_BUY }//for... } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void doPartCloseFirstTP(string symbol,int nMagic) { int ticket=-1; double NewSL; bool doPartClose=false; TradeHasPartClosed=false; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; string name=OrderComment(); if(StringFind(name,"from #")==0) continue; if(manageAllTradesInThisPair==false) { if(OrderMagicNumber()!=nMagic) continue; } if(OrderSymbol()!=symbol)continue; if(OrderType()==OP_SELL) { ticket=OrderTicket(); doPartClose=false; NewSL=NormalizeDouble(OrderOpenPrice(),Digits); name=OrderComment(); if(StringFind(name,"from #")<0)doPartClose=true; if((NewSL-Bid)>(PartCloseFirstTpPips/factor)) { if(doPartClose==true) { PartCloseTrade(ticket); if(TradeHasPartClosed==true && alerts)Alert("Ticket: ",ticket," was part closed"); else if(alerts) Alert("Partclose failed!"); TradeHasPartClosed=false; }//doPartClose }//if((NewSL-Bid)>(SLMinDistanceToPrice/factor)) }//OP_SELL if(OrderType()==OP_BUY) { ticket=OrderTicket(); doPartClose=false; NewSL=NormalizeDouble(OrderOpenPrice(),Digits); name=OrderComment(); if(StringFind(name,"from #")<0)doPartClose=true; if((Bid-NewSL)>(PartCloseFirstTpPips/factor)) { if(doPartClose==true) { PartCloseTrade(ticket); if(TradeHasPartClosed==true && alerts)Alert("Ticket: ",ticket," was part closed"); else if(alerts) Alert("Partclose failed!"); TradeHasPartClosed=false; }//doPartClose }//if((Bid-NewSL)>(PartCloseFirstTpPips/factor)) }//OP_BUY }//for... } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DoJS(string symbol,int nMagic) { int ticket=-1; double NewSL=0; if(CloseEnough(OrderStopLoss(),0)) return; for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(manageAllTradesInThisPair==false) { if(OrderMagicNumber()!=nMagic) continue; } if(OrderSymbol()!=symbol)continue; if(OrderType()==OP_SELL) { ticket=OrderTicket(); { NewSL=NormalizeDouble(OrderStopLoss()-(JumpStep/factor),Digits); if((NewSL-Bid)>(SLMinDistanceToPrice/factor)) { if(((NewSLAsk+(10/factor))) { if(alerts) Alert("DoJS :Attempting to move SL of ",symbol," to ",NewSL); Print("DoJS :Attempting to move SL of ",symbol," to ",NewSL); ModifyOrder(ticket,NewSL,0); } } } // return; } if(OrderType()==OP_BUY) { ticket=OrderTicket(); { NewSL=NormalizeDouble(OrderStopLoss()+(JumpStep/factor),Digits); if((Bid-NewSL)>(SLMinDistanceToPrice/factor)) { if(((NewSL>OrderStopLoss()) || (OrderStopLoss()<(1/factor))) && (NewSL!=0) && (NewSL=0) return true; if(!ObjectCreate(0,"messageBox",OBJ_RECTANGLE_LABEL,0,0,0)) { Print(__FUNCTION__, ": failed to create a rectangle label! Error code = ",GetLastError()); return(false); } //--- set label coordinates ObjectSetInteger(0,"messageBox",OBJPROP_XDISTANCE,0); ObjectSetInteger(0,"messageBox",OBJPROP_YDISTANCE,0); //--- set label size ObjectSetInteger(0,"messageBox",OBJPROP_XSIZE,500); ObjectSetInteger(0,"messageBox",OBJPROP_YSIZE,500); //--- set background color ObjectSetInteger(0,"messageBox",OBJPROP_BGCOLOR,displayBoxBackgroundColour); //--- set border type ObjectSetInteger(0,"messageBox",OBJPROP_BORDER_TYPE,BORDER_SUNKEN); //--- set the chart's corner, relative to which point coordinates are defined ObjectSetInteger(0,"messageBox",OBJPROP_CORNER,0); //--- set flat border color (in Flat mode) ObjectSetInteger(0,"messageBox",OBJPROP_COLOR,Red); //--- set flat border line style ObjectSetInteger(0,"messageBox",OBJPROP_STYLE,STYLE_SOLID); //--- set flat border width ObjectSetInteger(0,"messageBox",OBJPROP_WIDTH,1); //--- display in the foreground (false) or background (true) ObjectSetInteger(0,"messageBox",OBJPROP_BACK,false); //--- enable (true) or disable (false) the mode of moving the label by mouse ObjectSetInteger(0,"messageBox",OBJPROP_SELECTABLE,true); ObjectSetInteger(0,"messageBox",OBJPROP_SELECTED,false); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(0,"messageBox",OBJPROP_HIDDEN,false); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(0,"messageBox",OBJPROP_ZORDER,0); //--- successful execution return(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string DateToStr(datetime mt4date,string mask="") { int counter; int c_counter; string dayTextC; string ltext="",rtext=""; if(StringSubstrOld(mask,0,1)=="'") { for(counter=1; counter=0; c_counter--) { if(StringSubstrOld(mask,c_counter,1)=="'") break; rtext=StringSubstrOld(mask,c_counter,1)+rtext; } mask=StringSubstrOld(mask,0,c_counter); } if(mask=="") mask="Y.N.D H:I:S"; bool blank=false; if(StringSubstrOld(StringUpper(mask),0,1)=="B") { blank= true; mask = StringRight(mask,-1); } string mth[12] = {"January","February","March","April","May","June","July","August","September","October","November","December"}; string dow[7] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; int dd = TimeDay(mt4date); int mm = TimeMonth(mt4date); int yy = TimeYear(mt4date); int dw = TimeDayOfWeek(mt4date); int hr = TimeHour(mt4date); int min = TimeMinute(mt4date); int sec = TimeSeconds(mt4date); bool twelveHoursT=false; if(StringFind(StringUpper(mask),"A",0)>=0) twelveHoursT=true; int twelveHours=12; if(hr>12) twelveHours=hr-12; else if(hr>0) twelveHours=hr; string ampm="am"; if(hr>=12) ampm="pm"; int daynumber=int((MathMod(dd,10))); if(daynumber==1) dayTextC="st"; else if(daynumber==2) dayTextC = "nd"; else if(daynumber==3) dayTextC = "rd"; else dayTextC="th"; if(dd>10 && dd<14) dayTextC="th"; int days = int(MathInt(mt4date/86400)); int hrs = int(MathInt(mt4date/3600)); int mins = int(MathInt(mt4date/60)); string outdate=""; for(int i=0; i=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if((OrderType()==OP_BUY) || (OrderType()==OP_SELL)) if(OrderMagicNumber()==nMagic) if(OrderSymbol()==strSymbol) if(OrderOpenTime()>opentime) opentime=OrderOpenTime(); } return(opentime); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ datetime LastClosedTrade(string strSymbol,int nMagic) { datetime timeelapsed=0; datetime closetime=0; for(int i=OrdersHistoryTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) continue; if((OrderType()==OP_BUY) || (OrderType()==OP_SELL)) if(OrderMagicNumber()==nMagic) if(OrderSymbol()==strSymbol) if(OrderCloseTime()>closetime) closetime=OrderCloseTime(); } return(closetime); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string StringUpper(string str) { string outstr = ""; string lower = "abcdefghijklmnopqrstuvwxyz"; string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(int i=0; i=0) outstr=outstr+StringSubstrOld(upper,t1,1); else outstr=outstr+StringSubstrOld(str,i,1); } return(outstr); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string StringLower(string str) { string outstr=""; int i; string lower = "abcdefghijklmnopqrstuvwxyz"; string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(i=0; i=0) outstr=outstr+StringSubstrOld(lower,t1,1); else outstr=outstr+StringSubstrOld(str,i,1); } return(outstr); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string StringRight(string str,int n=1) { if(n > 0) return(StringSubstrOld(str,StringLen(str)-n,n)); if(n < 0) return(StringSubstrOld(str,-n,StringLen(str)-n)); return(""); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double MathInt(double n,int d=0) { return(MathFloor(n*MathPow(10,d)+0.000000000001)/MathPow(10,d)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string NumberToStr(double n,string mask="") { int ix,jx; int i; string char_var; bool comma,zeros,aster,blank,Round,overf,lftsh,swtch,trimf; string out1=""; string out2= ""; if(MathAbs(n)==2147483647) n=0; string ltext="",rtext=""; if(StringSubstrOld(mask,0,1)=="'") { for(ix=1; ix=0; jx--) { if(StringSubstrOld(mask,jx,1)=="'") break; rtext=StringSubstrOld(mask,jx,1)+rtext; } mask=StringSubstrOld(mask,0,jx); } if(mask=="") mask="TR-9.2"; mask=StringUpper(mask); if(mask == "B") return(ltext+rtext); int dotadj = 0; int dot = StringFind(mask,".",0); if(dot<0) { dot = StringLen(mask); dotadj = 1; } int nleft = 0; int nright = 0; for(i=0; i="0" && char_var<="9") nleft=10*nleft+StrToInteger(char_var); } if(dotadj==0) { for(i=dot+1; i<=StringLen(mask); i++) { char_var=StringSubstrOld(mask,i,1); if(char_var>="0" && char_var<="9") nright=10*nright+StrToInteger(char_var); } } nright=MathMin(nright,7); if(dotadj==1) { for(i=0; i="0" && char_var<="9") { dot=i; break; } } } string csym=""; if(StringFind(mask,"$",0) >= 0) csym = "$"; if(StringFind(mask,"£",0) >= 0) csym = "£"; if(StringFind(mask,"€",0) >= 0) csym = "€"; if(StringFind(mask,"¥",0) >= 0) csym = "¥"; string leadsign = ""; string trailsign = ""; if(StringFind(mask,"+",0)>=0 && StringFind(mask,"+",0) 0) leadsign = "+"; if(n < 0) leadsign = "-"; } if(StringFind(mask,"-",0)>=0 && StringFind(mask,"-",0)=0 && StringFind(mask,"-",0)>dot) if(n<0) trailsign="-"; else trailsign=" "; if(StringFind(mask,"(",0)>=0 || StringFind(mask,")",0)>=0) { leadsign = " "; trailsign = " "; if(n<0) { leadsign = "("; trailsign = ")"; } } if(StringFind(mask,"%",0)>=0) trailsign="%"+trailsign; if(StringFind(mask,",",0)>=0) comma=true; else comma=false; if(StringFind(mask,"Z",0)>=0) zeros=true; else zeros=false; if(StringFind(mask,"*",0)>=0) aster=true; else aster=false; if(StringFind(mask,"B",0)>=0) blank=true; else blank=false; if(StringFind(mask,"R",0)>=0) Round=true; else Round=false; if(StringFind(mask,"~",0)>=0) overf=true; else overf=false; if(StringFind(mask,"L",0)>=0) lftsh=true; else lftsh=false; if(StringFind(mask,";",0)>=0) swtch=true; else swtch=false; if(StringFind(mask,"T",0)>=0) trimf=true; else trimf=false; if(Round) n=MathFix(n,nright); string outstr=DoubleToStr(n,0); int dleft=0; for(i=0; i= "0" && char_var <= "9") dleft++; if(char_var == ".") break; } // Insert fill characters....... string fill=" "; if(zeros) fill = "0"; if(aster) fill = "*"; if(n<0) outstr="-"+StringRepeat(fill,nleft-dleft)+StringSubstrOld(outstr,1,StringLen(outstr)-1); else outstr=StringRepeat(fill,nleft-dleft)+StringSubstrOld(outstr,0,StringLen(outstr)); outstr=StringSubstrOld(outstr,StringLen(outstr)-9-nleft,nleft+1+nright-dotadj); // Insert the commas....... if(comma) { bool digflg = false; bool stpflg = false; out1 = ""; out2 = ""; for(i=0; i="0" && char_var<="9") digflg=true; } outstr=out1; } // Add currency symbol and signs........ outstr=csym+leadsign+outstr+trailsign; // 'Float' the currency symbol/sign....... out1 = ""; out2 = ""; bool fltflg=true; for(i=0; i= "0" && char_var <= "9") fltflg = false; if((char_var == " " && fltflg) || (blank && n == 0) ) out1 = out1 + " "; else out2=out2+char_var; } outstr=out1+out2; // Overflow........ if(overf && dleft>nleft) outstr="~"+StringSubstrOld(outstr,1,StringLen(outstr)-1); // Left shift....... if(lftsh) { int len= StringLen(outstr); outstr = StringLeftTrim(outstr); outstr = outstr + StringRepeat(" ",len-StringLen(outstr)); } // Switch period and comma....... if(swtch) { out1 = ""; for(i=0; i 0) return(1); else if(n < 0) return (-1); else return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double DivZero(double varA,double varB) { if(CloseEnough(varB,0.0)) return (0); return (varA / varB); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int orders_count(int magic,int type=-1,string comment="") { int orders_total=OrdersTotal(),count=0; for(int i=0; i=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; //if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if((OrderType()==OP_BUY) || (OrderType()==OP_SELL)) profit=profit+(OrderProfit()+OrderSwap()+OrderCommission()); } return(profit); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAllOfPair() { ForceTradeClosure=false; bool result=false; if(OrdersTotal() == 0) return; for(int cc=OrdersTotal()-1; cc>=0; cc--) { if(!OrderSelect(cc,SELECT_BY_POS)) continue; // if(OrderMagicNumber()!=MagicNumber) continue; if(OrderSymbol()!=Symbol()) continue; while(IsTradeContextBusy()) Sleep(100); if(OrderType()==OP_BUY || OrderType()==OP_SELL) result=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),1000,CLR_NONE); if(result) cc++; //if (!result) ForceTradeClosure= true; //original, fxdaytrader //mod. fxdaytrader, orderclose-retry if failed with ordercloseprice(). Maybe very seldom, but it can happen, so it does not hurt to implement this: if(!result) { while(IsTradeContextBusy()) Sleep(100); RefreshRates(); if(OrderType()==OP_BUY) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), 5000, CLR_NONE); if(OrderType()==OP_SELL) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), 5000, CLR_NONE); if(!result) ForceTradeClosure=true; } //end mod. }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--) } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseFriday(string strSymbol,int nMagic) { int ticket=-1; if((DayOfWeek()==5) && (TimeHour(TimeCurrent())>=FridayCloseHour) && (TimeMinute(TimeCurrent())>=FridayCloseMinute)) { for(int i=OrdersTotal()-1; i>=0; i--) { if(!OrderSelect(i,SELECT_BY_POS)) continue; if(OrderMagicNumber()!=nMagic) continue; if(OrderSymbol()!=strSymbol) continue; if(OrderType()==OP_BUY) { ticket=OrderTicket(); if(AllowedSpread(strSymbol)==true) { while(IsTradeContextBusy()) Sleep(100); if(alerts) Alert("CloseFriday:Attempting to close ",strSymbol); Print("CloseFriday:Attempting to close ",strSymbol); if(OrderClose(ticket,OrderLots(),Bid,slippage,Red)) { if(alerts) Alert("CloseFriday:Close ",strSymbol," Succeeded !"); Print("CloseFriday:Close ",strSymbol," Succeeded !"); } else { if(alerts) Alert("CloseFriday:Close ",strSymbol," Failed !"); Print("CloseFriday:Close ",strSymbol," Failed !"); } } } if(OrderType()==OP_SELL) { ticket=OrderTicket(); if(AllowedSpread(strSymbol)==true) { while(IsTradeContextBusy()) Sleep(100); if(alerts) Alert("CloseFriday:Attempting to close ",strSymbol); Print("CloseFriday:Attempting to close ",strSymbol); if(OrderClose(ticket,OrderLots(),Ask,slippage,Red)) { if(alerts) Alert("CloseFriday:Close ",strSymbol," Succeeded !"); Print("CloseFriday:Close ",strSymbol," Succeeded !"); } else { if(alerts) Alert("CloseFriday:Close ",strSymbol," Failed !"); Print("CloseFriday:Close ",strSymbol," Failed !"); } } } } } } //+------------------------------------------------------------------+