//ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ // original Free EA Grail_2.mq4 on http://articles.mql4.com/163 // cleaned ,fixed and translated by finimej //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ extern int TakeProfit=5; // TakeProfit in pips extern int StopLoss= 29; // StopLoss in pips extern int Distan = 2; // MA distans in pips extern int Cls = 2; // Close at 2 pips profits extern int period_MA=16; // MA_period=16 extern bool UseHourTrade=false; //if true, then EA trading only between Time_1 and Time_2 extern int Time_1 = 0; // start hour extern int Time_2 = 0; // stop hour extern int Prots = 0; // //-------------------------------------------------------------------------------------------- int Nom_bl, // number of BuyLimit Nom_sl, // number of SellLimit total, // total OrderClose bl = 0, // 1 = has BuyLimit sl = 0, // 1 = has SellLimit b = 0, // 1 = has Buy s = 0; // 1 = has Sell //-------------------------------------------------------------------------------------------- double OP, // OpenPrice SL, // StopLoss TP, // TakeProfit Level, // level OP_bl, // OpenPrice BuyLimit OP_sl, // OpenPrice SellLimit cls, // close at profits MA, // MA spred, // spread Lot, // Lot size dist; //-------------------------------------------------------------------------------------------- datetime StopTime; // Time to wait after a trade is stopped out bool StoppedOut=false; int Magic; extern int useDelay = 0; //if last order get stopped out, then we shall delay it. extern int MinutesToDelay = 20; //how many minuetes shall the EA get delayed. extern bool UseMoneyManagement=false; extern int Risk = 10; extern double InitialLot=0.1; extern bool AccountIsMicro=false; extern double MyMaxLot=50; //==0, then use the system lots 1000, >0 then using this lots as max lot. extern int accoutlimit=1000; //stopp the EA trading if the accountquity is dropped less than this level //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ int init() { Magic = 3000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); Level=MarketInfo(Symbol(),MODE_STOPLEVEL); // get brokers stoploss level in pips if (Level==0) Level=5; //some broker has the stoploss = 0, set it to 5 to make the logic works Level=(Level+1)*Point; // :) SL=StopLoss*Point; // StopLoss TP=TakeProfit*Point; // TakeProfit dist=Distan*Point; // distance from MA cls=Cls*Point; // close at profits spred=GetSpread(); // spread if (Point==0.00001) { Level=Level*10; SL=SL*10; TP=TP*10; dist=dist*10; cls=cls*10; } return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ int start() { //========================================================================================== // EA do not trade if account equity is come to this point. if (AccountEquity()<accoutlimit) { ForceCloseAll(); return (0); } //========================================================================================== // here if useDelay=1, then the EA delay for defined minuetes if last order stoploss out. if (useDelay == 1) { StoppedOut = LastTradeStoppedOut(); if (CurTime() < StopTime) { Comment("Last trade stopped out, No Trades Until : " + TimeToStr(StopTime,TIME_DATE|TIME_MINUTES)); return(0); } } //========================================================================================== // here if we use the hourse trade, then EA only trade between time_1 and Time_2 if (UseHourTrade) { if (!(Hour() >= Time_1 && Hour() <= Time_2)) { Comment("This is not trading time."); return (0); } } //============================================================================================ // the takeprofits shall not be set in the limit order, sometimes broker fill your order 3 pips worse then your takeprofits in the limit, then you lost. // here I set the takeprofits in the limit order to zero, then set the takeprofits to 2 pips once the limit order become market order. SetOrderTakeprofits(); ScreenComments(); total=OrdersTotal(); // total OrderSelect bl=0; // initialize has buylimit orders sl=0; // initialize has buylimit orders b=0; // initialize has buy orders s=0; // initialize has sell orders //-------------------------------------------------------------------------------------------- for (int i=total; i>=0; i--) // go through the order loops { if (OrderSelect(i,SELECT_BY_POS)==true && // select the orders OrderSymbol()==Symbol()&&OrderMagicNumber() == Magic) { //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUY) // get the order Buy { b =1; // set the system, has buy order Close_B(OrderTicket(),OrderLots()); // close the Buy order if it has 2 pips profits } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELL) // get the order Sell { s =1; // set the system, has sell order Close_S(OrderTicket(),OrderLots()); // close the sell order if it has 2 pips profits } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUYLIMIT) // get the order BuyLimit { OP_bl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice BuyLimit Nom_bl=OrderTicket(); bl=1; // set the has buylimit orders } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELLLIMIT) // get the order SellLimit { OP_sl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice SellLimit Nom_sl=OrderTicket(); sl=1; // set the has sellLimit orders } //-------------------------------------------------------------------------------------------- } } //-------------------------------------------------------------------------------------------- MA = iMA(NULL,0, period_MA, 0,MODE_LWMA, PRICE_TYPICAL, 0);// get the current MA level, use line weighted MA, and use the typical price HLC/3 Modify_order(); // move the limit orders along the MA line Open_order() ; // open order //============================================================================================ return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ void Close_B(int Nomber, double lots) // close order Buy { //============================================================================================ if (NormalizeDouble(Bid-OrderOpenPrice(),Digits)>=cls)// if order in profits 2 pips { OrderClose( Nomber, lots, Bid, 1, Yellow); // close order b = 0; // set the has buy order = 0 } //============================================================================================ return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ void Close_S(int Nomber, double lots) // close order Sell { //============================================================================================ if (NormalizeDouble(OrderOpenPrice()-Ask,Digits)>=cls)// if order in profits 2 pips { OrderClose( Nomber, lots, Ask, 1, Yellow); // close order s = 0; // set the has sell order = 0 } //============================================================================================ return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ void Modify_order() //move the limit orders alone the line { //============================================================================================ if (bl==1) // if has buylimit orders { OP=MA-dist; // get the current buylimit openprice if (MathAbs(OP_bl-OP)>0.5*Point) // if old buylimit openprice diff than current buylimit openprice for half point { OrderModify(Nom_bl,OP,OP-SL,0,0,DeepSkyBlue);// modify the limit order alongs the side of MA line } } //-------------------------------------------------------------------------------------------- if (sl==1) // if has selllimit orders { OP=MA+spred+dist; // get the current selllimit openprice if (MathAbs(OP_sl-OP)>0.5*Point) // if old selllimit openprice diff than current selllimit openprice for half point { OrderModify( Nom_sl, OP, OP+SL, 0, 0, Pink);// modify the limit order alongs the side of MA line } } //============================================================================================ return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ void Open_order() // send limit orders { int Tek_Time=TimeHour(CurTime()); // if we use hours limit if (Tek_Time>Time_2 && Tek_Time<Time_1) return; // EA then runs only from Time 1 to Time 2 //============================================================================================ if (b==0 && bl==0) // if we do not have any buylimit or buy orders { OP=MA-dist; // get the current buylimit openprice if(OP>Ask-Level) OP=Ask-Level; // if the Ask price hit the current buylimit openprice OP=NormalizeDouble(OP,Digits); // normalize the computer double to nice normal mathmatical double OrderSend(Symbol(),OP_BUYLIMIT, Lots(),OP,3,OP-SL,0,"",Magic,0,Blue);// send in order bl=1; // set the has buylimit order = true } //-------------------------------------------------------------------------------------------- if (s==0 && sl==0) // if we do not have any selllimit or sellorders { OP=MA+spred+dist; // get the current selllimit openprice if(OP<Bid+Level) OP=Bid+Level; // if the bid price hit the current selllimit openprice OP=NormalizeDouble(OP,Digits); // normalize the computer double to nice normal mathmatical double OrderSend(Symbol(),OP_SELLLIMIT,Lots(),OP,3,OP+SL,0,"",Magic,0,Red);// send in order sl=1; // set the has selllimit order = true } ///============================================================================================ return; } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ double Lots() // calculate the lot size { if(UseMoneyManagement==false) return(InitialLot); double lots; int orders=HistoryTotal(); int losses=0; int decimalPlaces=1; if(AccountIsMicro==true) decimalPlaces=2; lots=NormalizeDouble((AccountFreeMargin()*Risk/1000.0)/100,decimalPlaces); StoppedOut = LastTradeStoppedOut(); if (StoppedOut==true) //if last order get stopped out, then use the minimum lot for the next operation { if(AccountIsMicro==false) lots=0.1; if(AccountIsMicro==true) lots=0.01; } if(lots<0.1 && AccountIsMicro==false) lots=0.1; if(lots<0.01 && AccountIsMicro==true) lots=0.01; double maxlot = MarketInfo(Symbol(), MODE_MAXLOT); if (MyMaxLot>0) { if (lots>MyMaxLot) return (MyMaxLot); } if(lots>maxlot) lots=maxlot-1; return(lots); } //ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ bool LastTradeStoppedOut() { int cnt, total; datetime NextTime; bool Stopped=false; NextTime = 0; total = HistoryTotal(); for (cnt = total - 1; cnt >= 0; cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_HISTORY); if(OrderSymbol()==Symbol() && OrderMagicNumber() == Magic) { Stopped = false; if (OrderType() == OP_BUY) { if (OrderClosePrice() - OrderOpenPrice() < 0) { Stopped = true; } cnt = 0; } if (OrderType() == OP_SELL) { if (OrderOpenPrice() - OrderClosePrice() < 0) { Stopped = true; } cnt = 0; } } } if (Stopped) { StopTime = OrderCloseTime() + MinutesToDelay*60; } return (Stopped); } void ForceCloseAll() { for (int l_pos_0 = OrdersTotal() - 1; l_pos_0 >= 0; l_pos_0--) { OrderSelect(l_pos_0, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderCloseTime() == 0) { if (OrderType() == OP_BUY ) Close_B(OrderTicket(), OrderLots()); if (OrderType() == OP_SELL) Close_S(OrderTicket(), OrderLots()); } } } int func_Symbol2Val(string symbol) { string mySymbol = StringSubstr(symbol,0,6); if(mySymbol=="AUDCAD") return(1); if(mySymbol=="AUDJPY") return(2); if(mySymbol=="AUDNZD") return(3); if(mySymbol=="AUDUSD") return(4); if(mySymbol=="CHFJPY") return(5); if(mySymbol=="EURAUD") return(6); if(mySymbol=="EURCAD") return(7); if(mySymbol=="EURCHF") return(8); if(mySymbol=="EURGBP") return(9); if(mySymbol=="EURJPY") return(10); if(mySymbol=="EURUSD") return(11); if(mySymbol=="GBPCHF") return(12); if(mySymbol=="GBPJPY") return(13); if(mySymbol=="GBPUSD") return(14); if(mySymbol=="NZDUSD") return(15); if(mySymbol=="USDCAD") return(16); if(mySymbol=="USDCHF") return(17); if(mySymbol=="USDJPY") return(18); Comment("unexpected Symbol"); return(19); } int func_TimeFrame_Const2Val(int Constant ) { switch(Constant) { case 1: // M1 return(1); case 5: // M5 return(2); case 15: return(3); case 30: return(4); case 60: return(5); case 240: return(6); case 1440: return(7); case 10080: return(8); case 43200: return(9); } } void ScreenComments() { Comment( "\n------------------------------------------------------" + "\n" + "Broker: " + AccountCompany() + "\n" + "Broker Time = ", Hour() + " : " + Minute() + "\n" + "Time Start Trading = ", Time_1 + "\n" + "Time Stop Trading = ", Time_2 + "\n" + "-------------------------------------------------------" + "\n" + "ACCOUNT INFORMATION:" + "\n" + "Account Name: " + AccountName() + "\n" + "Account Number: " + AccountNumber() + "\n" + "Account Leverage: " + DoubleToStr(AccountLeverage(), 0) + "\n" + "Account Balance: " + DoubleToStr(AccountBalance(), 2) + "\n" + "Account Equity: " + DoubleToStr(AccountEquity(), 2) + "\n" + "Used Margin: " + DoubleToStr(AccountMargin(), 2) + "\n" + "------------------------------------------------------" + "\n" + "LOTS: " + DoubleToStr(Lots(), 2) + "\n" + "------------------------------------------------------" + "\n" + "SPREAD: " + DoubleToStr(GetSpread(),1) + " pips" + "\n" + "------------------------------------------------------" ); } double GetSpread() { double Spread; if (Point == 0.00001) // Calculate the spread in pips for symbols quoted to 5 decimal places { Spread = (Ask - Bid) / (Point*10); // Current Spread price for this CurrencyPair in pip form. } if (Point == 0.0001) // Calculate the spread in pips for symbols quoted to 4 decimal places { Spread = (Ask - Bid) / (Point); // Current Spread price for this CurrencyPair in pip form. } if (Point == 0.001) // Calculate the spread in pips for symbols quoted to 3 decimal places { Spread = (Ask - Bid) / (Point*10); // Current Spread price for this CurrencyPair in pip form. } if (Point == 0.01) // Calculate the spread in pips for symbols quoted to 2 decimal places { Spread = (Ask - Bid) / (Point); // Current Spread price for this CurrencyPair in pip form. } return(Spread); } int SetOrderTakeprofits() { int cnt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != Magic) continue; if(OrderType() == OP_BUY) { if (OrderTakeProfit() ==0) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-SL, OrderOpenPrice()+TP, Red); } if(OrderType() == OP_SELL) { if (OrderTakeProfit() ==0) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+SL, OrderOpenPrice()-TP, Red); } } }
Sample
Analysis
Market Information Used:
Indicator Curves created:
Indicators Used:
Moving average indicator
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached
Other Features: