//+------------------------------------------------------------------+
//| Bago-Method_Mikhail-EA-V1.mq4 |
//| Copyright © 2006, Mikhail Veneracion |
//| |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| !!!IMPTORTANT NOTE!!! |
//| MOST OF THE CODE BELOW WAS AQUIRED FROM |
//| FIREDAVES UniversalMACrissEA |
//| I merely revised it to fit the Bagovino Method of Trading |
//| Copyright © 2006, firedave |
//| Partial Function Copyright © 2006, codersguru |
//| Partial Function Copyright © 2006, pengie |
//| http://www.fx-review.com/ | 56
//| http://www.forex-tsd.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Mikhail Veneracion"
#property link "NA"


//----------------------- INCLUDES
#include <stdlib.mqh>


//----------------------- EA PARAMETER
extern string
Expert_Name = "---------- Bago-Method_Mikhail-EA-V1";
extern int
MagicNumber = 1234;
extern double
StopLoss = 25,
TakeProfit = 0;

extern string
TrailingStop_Setting = "---------- Trailing Stop Setting";
extern int
TrailingStopType = 1,
TrailingStop = 25;
extern string
breakeven_setting = "---------- Break Even After Pips";
extern int
BreakEvenAfterPips = 40;
extern string
Indicator_Setting = "---------- Indicator Setting";
extern int
FastMAPeriod = 5,
FastMAType = 1, //0:SMA 1:EMA 2:SMMA 3:LWMA
FastMAPrice = 0, //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
FastMAshift = 0,
SlowMAPeriod = 8,
SlowMAType = 0, //0:SMA 1:EMA 2:SMMA 3:LWMA
SlowMAPrice = 0, //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
SlowMAshift = 0;

extern string
CossDistance_Setting = "---------- Min Cross Distance Setting";
extern int
MinCrossDistance = 1, //Always positive, 0:disable
MaxLookUp = 40; //Number of bar to keep checking for the entry condition

extern string
Exit_Setting = "---------- Exit Setting";
extern bool
StopAndReverse = false, // TURE:if signal change, exit and reverse order
PureSAR = false, // TRUE:no SL, no TP, no TS
ExitOnCross = true;

extern string
ThirdEMA_Setting = "---------- 3rd and 4th MA Filter Setting";

extern bool
UseThirdMA = false,
UseCounterTrend = false,
OnlyCounterTrend = false;
extern int
ThirdMAPeriod = 120,
ThirdMAType = 1, //0:SMA 1:EMA 2:SMMA 3:LWMA
ThirdMAPrice = 0, //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
ThirdMAshift = 0,
CTStopLoss = 0,
CTTakeProfit = 0;
extern string
FourthEMA_Setting = "---------- 4th MA Setting";
extern int
FourthMAPeriod = 288,
FourthMAType = 1, //0:SMA 1:EMA 2:SMMA 3:LWMA
FourthMAPrice = 0, //0:Close 1:Open 2:High 3:Low 4:Median 5:Typical 6:Weighted
FourthMAshift = 0;

extern string
RSI_Settings = "---------- RSI Filter Settings";
extern bool
UseRSIfilter = true;
extern int
RSIPeriod = 5,
RSIPrice = 1;

extern string
EMA_Angle_Setting = "---------- EMA Angle Setting";
extern bool
UseEMAAngle = false,
ExitOnAngle = false;
extern int
EMAPeriod =4,
StartEMAShift =3,
EndEMAShift =0;
extern double
AngleTreshold=2.00;
extern string
Order_Setting = "---------- Order Setting";
extern bool
ReverseCondition = false, // TRUE:buy-sell , sell-buy
ConfirmedOnEntry = true, // TRUE:entry on the next signal bar
OneEntryPerBar = true;
extern int
NumberOfTries = 10,
Slippage = 5;

extern string
OpenOrder_Setting = "---------- Multiple Open Trade Setting";
extern int
MaxOpenTrade = 1,
MinPriceDistance = 5;

extern string
Time_Parameters = "---------- EA Active Time";
extern bool
UseHourTrade = false;
extern int
StartHour = 7,
EndHour = 20;

extern string
MM_Parameters = "---------- Money Management";
extern double
Lots = 1;
extern bool
MM = true, //Use Money Management or not
AccountIsMicro = false; //Use Micro-Account or not
extern double
DecreaseFactor = 0; //Decrease Lots After Loss
extern int
Risk = 10; //10%

extern string
Alert_Setting = "---------- Alert Setting";
extern bool
EnableAlert = false;
extern string
SoundFilename = "alert.wav";

extern string
Testing_Parameters= "---------- Back Test Parameter";
extern bool
PrintControl = true,
Show_Settings = true;


//----------------------- GLOBAL VARIABLE
static int
TimeFrame = 0;
string
TicketComment = "Bago",
LastTrade,
LastAlert,
TradeDirection = "NONE",
PreviousDirection = "NONE",
CurrentDirection = "NONE";
datetime
CheckTime,
CheckEntryTime,
CrossTime;

//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{

//----------------------- GENERATE MAGIC NUMBER AND TICKET COMMENT
//----------------------- SOURCE : PENGIE
MagicNumber = subGenerateMagicNumber(MagicNumber, Symbol(), Period());
TicketComment = StringConcatenate(TicketComment, "-", Symbol(), "-", Period());

//----------------------- SET MinCrossDistance ALWAYS POSITIVE
MinCrossDistance = MathAbs(MinCrossDistance);

//----------------------- SHOW EA SETTING ON THE CHART
//----------------------- SOURCE : CODERSGURU
if(Show_Settings) subPrintDetails();
else Comment("");

//----------------------- INITIALIZE PURE Stop And Reverse
//----------------------- NO STOP LOSS, NO TAKE PROFIT, NO TRAILING STOP
if(PureSAR)
{
StopLoss = 0;
TakeProfit = 0;
TrailingStop = 0;
StopAndReverse = true;
}

//----------------------- MaxTrade ALWAYS >= 1
if(MaxOpenTrade<=0) MaxOpenTrade = 1;

//+------------------------------------------------------------------+
//| CHECK LAST OPEN TRADE |
//+------------------------------------------------------------------+
LastTrade = subCheckOpenTrade();
Print("Last Trade : ",LastTrade);
}

//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{

//----------------------- PREVENT RE-COUNTING WHILE USER CHANGING TIME FRAME
//----------------------- SOURCE : CODERSGURU
TimeFrame=Period();
return(0);
}


//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double
FastMACurrent,
SlowMACurrent,
ThirdMAValue;

int
cnt,
ticket,
total,
shiftCROSS,
Distance;

bool
BuyCondition,
SellCondition,
CounterTrend;

string
CrossDirection;

//----------------------- TIME FILTER
if (UseHourTrade)
{
if(!(Hour()>=StartHour && Hour()<=EndHour))
{
Comment("Non-Trading Hours!");
return(0);
}
}

//----------------------- CHECK CHART NEED MORE THAN 100 BARS
if(Bars<100)
{
Print("bars less than 100");
return(0);
}

//----------------------- TRAILING STOP SECTION
if(TrailingStop>0 && subTotalTrade()>0)
{
total = OrdersTotal();
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber)
{
subTrailingStop(OrderType());
}
}
}
//----------------------- BREAK EVEN AFTER PIPS SECTION
if(BreakEvenAfterPips >0 && subTotalTrade()>0)
{
total = OrdersTotal();
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber)
{
subBreakEvenAfterPips (OrderType());
}
}
}




//----------------------- ADJUST LOTS IF USING MONEY MANAGEMENT
if(MM) Lots = subLotSize();

//----------------------- SET VALUE FOR VARIABLE
if(ConfirmedOnEntry)
{
if(CheckTime==iTime(NULL,TimeFrame,0)) return(0); else CheckTime = iTime(NULL,TimeFrame,0);

FastMACurrent = iMA(NULL,TimeFrame,FastMAPeriod,FastMAshift,FastMAType,FastMAPrice,1);
SlowMACurrent = iMA(NULL,TimeFrame,SlowMAPeriod,SlowMAshift,SlowMAType,SlowMAPrice,1);
}
else
{
FastMACurrent = iMA(NULL,TimeFrame,FastMAPeriod,FastMAshift,FastMAType,FastMAPrice,0);
SlowMACurrent = iMA(NULL,TimeFrame,SlowMAPeriod,SlowMAshift,SlowMAType,SlowMAPrice,0);
}

CrossDirection = subCrossDirection(FastMACurrent,SlowMACurrent);

//+------------------------------------------------------------------+
//| START OF EMA ANGLE +
//+------------------------------------------------------------------+

double fEndMA, fStartMA;


double fAngle, mFactor, dFactor;
int nLimit, i;
int nCountedBars;
bool angle;
int ShiftDif;
string Sym;

if(EndEMAShift >= StartEMAShift)
{
bool ReverseCondition;
Print("Error: EndEMAShift >= StartEMAShift");
StartEMAShift = 6;
EndEMAShift = 0;
}
nLimit = Bars-nCountedBars;
dFactor = 2*3.14159/180.0;
mFactor = 10000.0;
Sym = StringSubstr(Symbol(),3,3);
if (Sym == "JPY") mFactor = 100.0;
ShiftDif = StartEMAShift-EndEMAShift;
mFactor /= ShiftDif;
string Angle,XAngle;
fEndMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+EndEMAShift);
fStartMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+StartEMAShift);
// 10000.0 : Multiply by 10000 so that the fAngle is not too small
// for the indicator Window.
fAngle = mFactor * (fEndMA - fStartMA)/2.0;
// fAngle = MathArctan(fAngle)/dFactor;

//market is in an uptrend
if(fAngle > AngleTreshold)
{
Print("market is an uptrend");
Angle = "UPAngle";
}

//market is in a downtrend
else if (fAngle < -AngleTreshold)
{ Print("market is a downtrend");
Angle = "DOWNAngle";
}

// Ema ANgle near zero, market is ranging
else if (fAngle < AngleTreshold && fAngle > -AngleTreshold){
Print("market is near zero");
UseCounterTrend = true;
Angle = "ZEROAngle";
}

//market is in a downtrend
if (fAngle > 0.0)
{ Print("market is a downtrend");
XAngle = "UPAngle";
}
//market is in a downtrend
if (fAngle < 0.0)
{ Print("market is a downtrend");
XAngle = "DOWNAngle";
}
//-----------------------END ANGLE

//----------------------- CONDITION CHECK
if(!ReverseCondition)
{
//----------------------- BUY CONDITION
if(CrossDirection=="UP")
{
BuyCondition = true;
TradeDirection = "UP";
CrossTime = iTime(NULL,TimeFrame,0);
}

//----------------------- SELL CONDITION
if(CrossDirection=="DOWN")
{
SellCondition = true;
TradeDirection = "DOWN";
CrossTime = iTime(NULL,TimeFrame,0);
}
}
else
{
//----------------------- SELL CONDITION
if(CrossDirection=="UP")
{
SellCondition = true;
TradeDirection = "UP";
CrossTime = iTime(NULL,TimeFrame,0);
}

//----------------------- BUY CONDITION
if(CrossDirection=="DOWN")
{
BuyCondition = true;
TradeDirection = "DOWN";
CrossTime = iTime(NULL,TimeFrame,0);
}
}

if(PrintControl)
{
if(BuyCondition) Print("MA Cross BUY");
if(SellCondition) Print("MA Cross SELL");
}

//----------------------- ALERT ON CROSS
if(EnableAlert && ConfirmedOnEntry)
{
if(TradeDirection=="UP" && LastAlert!="UP")
{
subCrossAlert("UP");
LastAlert = "UP";
}
if(TradeDirection=="DOWN" && LastAlert!="DOWN")
{
subCrossAlert("DOWN");
LastAlert ="DOWN";
}
}

//+------------------------------------------------------------------+
//| EXIT BASE ONLY ON MOVING AVERAGE CROSS |
//+------------------------------------------------------------------+
if(ExitOnCross && subTotalTrade()>0)
{
if((LastTrade=="BUY" && (FastMACurrent<SlowMACurrent)) || (LastTrade=="SELL" && (FastMACurrent>SlowMACurrent)))
{
subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();

if(IsTesting() && PrintControl) Print("EXIT ON CROSS !");
}
}
//+------------------------------------------------------------------+
//| EXIT BASE ONLY ON EMA ANGLE |
//+------------------------------------------------------------------+
if( ExitOnAngle && subTotalTrade()>0)
{
if((LastTrade=="BUY" && Angle == "DOWNAngle") || (LastTrade=="SELL" && Angle =="UPAngle"))
{
subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();

if(IsTesting() && PrintControl) Print("EXIT ON ANGLE !");
}
}
//+------------------------------------------------------------------+
//| CHECKING FOR MIN CROSS DISTANCE SEVERAL BAR AFTER THE CROSS |
//+------------------------------------------------------------------+
if(MaxLookUp>0 && MinCrossDistance>0)
{
BuyCondition = false;
SellCondition = false;
shiftCROSS = iBarShift(NULL,TimeFrame,CrossTime);
Distance = MathFloor(MathAbs((FastMACurrent-SlowMACurrent)/Point));

if(shiftCROSS<=MaxLookUp && Distance>=MinCrossDistance)
{
if(!ReverseCondition)
{
BuyCondition = TradeDirection=="UP";
SellCondition = TradeDirection=="DOWN";
}
else
{
SellCondition = TradeDirection=="UP";
BuyCondition = TradeDirection=="DOWN";
}
}

if(PrintControl)
{
Print(TimeToStr(CrossTime,TIME_MINUTES)," - ",shiftCROSS," - ",Distance," - ",MinCrossDistance," - ",TradeDirection);
if(BuyCondition ) Print("MinCrosDistance BUY");
if(SellCondition) Print("MinCrosDistance SELL");
}
}

//+------------------------------------------------------------------+
//| ADDITIONAL FILTER |
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| THIRD AND FOURTH MOVING AVERAGE |
//+------------------------------------------------------------------+
if(UseThirdMA)
{
ThirdMAValue = iMA(NULL,TimeFrame,ThirdMAPeriod,ThirdMAshift,ThirdMAType,ThirdMAPrice,0);
double FourthMAValue = iMA(NULL,TimeFrame,FourthMAPeriod,FourthMAshift,FourthMAType,FourthMAPrice,0);

if(!UseCounterTrend)
{
BuyCondition = (BuyCondition && FourthMAValue<ThirdMAValue);
SellCondition = (SellCondition && FourthMAValue>ThirdMAValue);
}
else
{
CounterTrend = ((BuyCondition && FastMACurrent<ThirdMAValue) ||
(SellCondition && FastMACurrent>ThirdMAValue));

//+------------------------------------------------------------------+
//| DON'T ALLOW ANY TREND FOLLOWING ENTRY / ONLY COUNTER TREND |
//+------------------------------------------------------------------+
if(OnlyCounterTrend && !CounterTrend)
{
BuyCondition = false;
SellCondition = false;
}
}
}
//+------------------------------------------------------------------+
//| RSI FILTER SETTINGS |
//+------------------------------------------------------------------+
if (UseRSIfilter)
{
double RSI = iRSI(NULL,0,RSIPeriod,RSIPrice,0);
BuyCondition = (BuyCondition && RSI>72.0000);
SellCondition = (SellCondition && RSI<28.0000);

}
//+------------------------------------------------------------------+
//| EMA ANGLE FILTER SETTINGS |
//+------------------------------------------------------------------+
if (UseEMAAngle)
{
BuyCondition = (BuyCondition && Angle == "UPAngle");
SellCondition = (SellCondition && Angle == "DOWNAngle");

}
//----------------------- STOP AND REVERSE
if(StopAndReverse && subTotalTrade()>0)
{
if((LastTrade=="BUY" && SellCondition) || (LastTrade=="SELL" && BuyCondition))
{
subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();
if(subTotalTrade()>0) subCloseOrder();

if(IsTesting() && PrintControl) Print("STOP AND REVERSE !");
}
}


//----------------------- ENTRY
//----------------------- TOTAL ORDER BASE ON MAGICNUMBER AND SYMBOL
total = subTotalTrade();

//----------------------- IF NUMBER TRADE LESS THAN MaxTrade
if(total<MaxOpenTrade && (BuyCondition || SellCondition))
{

//----------------------- ONE ENTRY PER BAR
if(OneEntryPerBar)
{
if(CheckEntryTime==iTime(NULL,TimeFrame,0)) return(0); else CheckEntryTime = iTime(NULL,TimeFrame,0);
}

//----------------------- BUY CONDITION
if(BuyCondition)
{
if(MaxOpenTrade>1 && !subHighestLowest("BUY")) return(0);

if(!CounterTrend)
{
ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_BUY,StopLoss,TakeProfit);
}
else
{
ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_BUY,CTStopLoss,CTTakeProfit);
}
subCheckError(ticket,"BUY");
LastTrade = "BUY";
return(0);
}

//----------------------- SELL CONDITION
if(SellCondition)
{
if(MaxOpenTrade>1 && !subHighestLowest("SELL")) return(0);

if(!CounterTrend)
{
ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_SELL,StopLoss,TakeProfit);
}
else
{
ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
if(ticket<=0) ticket = subOpenOrder(OP_SELL,CTStopLoss,CTTakeProfit);
}
subCheckError(ticket,"SELL");
LastTrade = "SELL";
return(0);
}
return(0);
}

return(0);
}

//----------------------- END PROGRAM

//+------------------------------------------------------------------+
//| FUNCTION DEFINITIONS
//+------------------------------------------------------------------+

//----------------------- MONEY MANAGEMENT FUNCTION
//----------------------- SOURCE : CODERSGURU
double subLotSize()
{
if(MM==false) return(Lots);
double lot=Lots;
int orders=HistoryTotal();
int losses=0;
int decimalPlaces=1;

if(AccountIsMicro==true) decimalPlaces=2;

lot=NormalizeDouble((AccountFreeMargin()*Risk/1000.0)/100,decimalPlaces);
if(DecreaseFactor>0)
{
for(int i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,decimalPlaces);
}

if(lot<0.1 && AccountIsMicro==false) lot=0.1;
if(lot<0.01 && AccountIsMicro==true) lot=0.01;
if(lot>99) lot=99;
return(lot);

}

/*
//+------------------------------------------------------------------+
//| START Calculate optimal lot size |
//+------------------------------------------------------------------+

double LotsOptimized()
{


//+------------------------------------------------------------------+
//| END Calculate optimal lot size |
//+------------------------------------------------------------------+
*/

//----------------------- NUMBER OF ORDER BASE ON SYMBOL AND MAGICNUMBER FUNCTION
int subTotalTrade()
{
int
cnt,
total = 0;

for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber) total++;
}
return(total);
}

//+------------------------------------------------------------------+
//| FUNCTION : CHECK OPEN ORDER BASE ON SYMBOL AND MAGIC NUMBER |
//| SOURCE : n/a |
//| MODIFIED : FIREDAVE |
//+------------------------------------------------------------------+
string subCheckOpenTrade()
{
int
cnt = 0;
string
lasttrade = "None";

for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY ) lasttrade = "BUY";
if(OrderType()==OP_SELL) lasttrade = "SELL";
}
}
return(lasttrade);
}

//----------------------- FIND LOWEST/HIGHEST BUY-SELL FUNCTION
bool subHighestLowest(string type)
{
int
cnt,
total = 0;

double
HighestBuy = 0,
LowestBuy = 10000,
HighestSell = 0,
LowestSell = 10000;

for(cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY)
{
if(OrderOpenPrice()<LowestBuy ) LowestBuy = OrderOpenPrice();
if(OrderOpenPrice()>HighestBuy) HighestBuy = OrderOpenPrice();
}

if(OrderType()==OP_SELL)
{
if(OrderOpenPrice()<LowestSell ) LowestSell = OrderOpenPrice();
if(OrderOpenPrice()>HighestSell) HighestSell = OrderOpenPrice();
}

}
}

if (type=="BUY" && (Ask<=LowestBuy -MinPriceDistance*Point || Ask>=HighestBuy +MinPriceDistance*Point)) return(true);
else if(type=="SELL" && (Bid<=LowestSell-MinPriceDistance*Point || Bid>=HighestSell+MinPriceDistance*Point)) return(true);
else return(false);
}

//+------------------------------------------------------------------+
//| FUNCTION : CHECK IS CROSS OR NOT |
//| SOURCE : CODERSGURU |
//| MODIFIED : FIREDAVE |
//+------------------------------------------------------------------+
string subCrossDirection(double fastMA, double slowMA)
{
if(fastMA>slowMA) CurrentDirection = "UP";
else if(fastMA<slowMA) CurrentDirection = "DOWN";

if(PreviousDirection=="NONE")
{
PreviousDirection = CurrentDirection;
return("NONE");
}

if(PrintControl) Print("Prev : ",PreviousDirection," - Curr : ",CurrentDirection);

if(PreviousDirection!=CurrentDirection)
{
PreviousDirection = CurrentDirection;
return(CurrentDirection);
}
else return("NONE");
}

//----------------------- OPEN ORDER FUNCTION
//----------------------- SOURCE : CODERSGURU
//----------------------- SOURCE : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subOpenOrder(int type, int stoploss, int takeprofit)
{
int
ticket = 0,
err = 0,
c = 0;

double
aStopLoss = 0,
aTakeProfit = 0,
bStopLoss = 0,
bTakeProfit = 0;

if(stoploss!=0)
{
aStopLoss = NormalizeDouble(Ask-stoploss*Point,4);
bStopLoss = NormalizeDouble(Bid+stoploss*Point,4);
}

if(takeprofit!=0)
{
aTakeProfit = NormalizeDouble(Ask+takeprofit*Point,4);
bTakeProfit = NormalizeDouble(Bid-takeprofit*Point,4);
}

if(type==OP_BUY)
{
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage ,aStopLoss,aTakeProfit,TicketComment,MagicNumber,0 ,Green);
err=GetLastError();
if(err==0)
{
if(ticket>0) break;
}
else
{
if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
if(ticket>0) break;
}
}
}
}
if(type==OP_SELL)
{
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,bStopLoss,bTakeProfit,TicketComment,MagicNumber, 0,Red);
err=GetLastError();
if(err==0)
{
if(ticket>0) break;
}
else
{
if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
if(ticket>0) break;
}
}
}
}
return(ticket);
}


//----------------------- CLOSE ORDER FUNCTION
void subCloseOrder()
{
int
cnt,
total = 0,
ticket = 0,
err = 0,
c = 0;

total = OrdersTotal();
for(cnt=total-1;cnt>=0;cnt--)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber)
{
switch(OrderType())
{
case OP_BUY :
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Violet);
err=GetLastError();
if(err==0)
{
if(ticket>0) break;
}
else
{
if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
if(ticket>0) break;
}
}
}
break;

case OP_SELL :
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Violet);
err=GetLastError();
if(err==0)
{
if(ticket>0) break;
}
else
{
if(err==0 || err==4 || err==136 || err==137 || err==138 || err==146) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
if(ticket>0) break;
}
}
}
break;

case OP_BUYLIMIT :
case OP_BUYSTOP :
case OP_SELLLIMIT:
case OP_SELLSTOP :
OrderDelete(OrderTicket());
}
}
}
}
//---------------------- BREAK EVEN FUNCTION
void subBreakEvenAfterPips(int Type)
{
if(Type==OP_BUY)
{
if((Bid-OrderOpenPrice()) > (Point*BreakEvenAfterPips))
OrderModify(
OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice(),
OrderTakeProfit(),
0,
GreenYellow);
}
if(Type==OP_SELL)
{
if((OrderOpenPrice()-Ask) > (Point*BreakEvenAfterPips))
OrderModify(
OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice(),
OrderTakeProfit(),
0,
Red);
}
}
//+------------------------------------------------------------------+
//| END Function Check BreakEven |
//+------------------------------------------------------------------+

//----------------------- TRAILING STOP FUNCTION
//----------------------- SOURCE : CODERSGURU
//----------------------- MODIFIED : FIREDAVE
void subTrailingStop(int Type)
{
if(Type==OP_BUY) // buy position is opened
{
switch(TrailingStopType)
{
//----------------------- AFTER PROFIT TRAILING STOP
case 1:
if(Bid-OrderOpenPrice()>Point*TrailingStop &&
OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
break;

//----------------------- TRAILING STOP
case 2:
if(Bid>OrderOpenPrice() &&
OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
break;
//----------------------- 50% TRAILING STOP
case 3:
if(Bid-OrderOpenPrice()>Point*TrailingStop &&
OrderStopLoss()<Bid-Point*TrailingStop)
{ double TB = (OrderOpenPrice()+Bid)/2;
if(OrderStopLoss()<TB){
OrderModify(OrderTicket(),OrderOpenPrice(),TB,OrderTakeProfit(),0,Green);
return(0);
}
}
break;


//----------------------- DEFAULT : AFTER PROFIT TRAILING STOP
default:
if(Bid-OrderOpenPrice()>Point*TrailingStop &&
OrderStopLoss()<Bid-Point*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
return(0);
}
}
}

if(Type==OP_SELL) // sell position is opened
{
switch(TrailingStopType)
{
//----------------------- AFTER PROFIT TRAILING STOP
case 1:
if(OrderOpenPrice()-Ask>Point*TrailingStop)
{
if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
break;

//----------------------- TRAILING STOP
case 2:
if(OrderOpenPrice()>Ask)
{
if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
break;

//----------------------- 50 %TRAILING STOP
case 3:
if(OrderOpenPrice()-Ask>Point*TrailingStop)
{

{ double TS = (OrderOpenPrice()+Ask)/2;
if(OrderStopLoss()>TS){
OrderModify(OrderTicket(),OrderOpenPrice(),TS,OrderTakeProfit(),0,Red);
return(0);
}
}
}
break;


//----------------------- BREAK EVEN AFTER PIPS



if((OrderOpenPrice()-Ask) > (Point*TrailingStop))
OrderModify(
OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice(),
OrderTakeProfit(),
0,
Red);

//----------------------- DEFAULT : AFTER PROFIT TRAILING STOP
default:
if(OrderOpenPrice()-Ask>Point*TrailingStop)
{
if(OrderStopLoss()>Ask+Point*TrailingStop || OrderStopLoss()==0)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}



//----------------------- CHECK ERROR CODE FUNCTION
//----------------------- SOURCE : CODERSGURU
void subCheckError(int ticket, string Type)
{
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES )) Print(Type + " order opened : ",OrderOpenPrice());
}
else Print("Error opening " + Type + " order : (",GetLastError(),") ", ErrorDescription(GetLastError()));
}

//----------------------- GENERATE MAGIC NUMBER BASE ON SYMBOL AND TIME FRAME FUNCTION
//----------------------- SOURCE : PENGIE
//----------------------- MODIFIED : FIREDAVE
int subGenerateMagicNumber(int MagicNumber, string symbol, int timeFrame)
{
int isymbol = 0;
if (symbol == "EURUSD") isymbol = 1;
else if (symbol == "GBPUSD") isymbol = 2;
else if (symbol == "USDJPY") isymbol = 3;
else if (symbol == "USDCHF") isymbol = 4;
else if (symbol == "AUDUSD") isymbol = 5;
else if (symbol == "USDCAD") isymbol = 6;
else if (symbol == "EURGBP") isymbol = 7;
else if (symbol == "EURJPY") isymbol = 8;
else if (symbol == "EURCHF") isymbol = 9;
else if (symbol == "EURAUD") isymbol = 10;
else if (symbol == "EURCAD") isymbol = 11;
else if (symbol == "GBPUSD") isymbol = 12;
else if (symbol == "GBPJPY") isymbol = 13;
else if (symbol == "GBPCHF") isymbol = 14;
else if (symbol == "GBPAUD") isymbol = 15;
else if (symbol == "GBPCAD") isymbol = 16;
else isymbol = 17;
if(isymbol<10) MagicNumber = MagicNumber * 10;
return (StrToInteger(StringConcatenate(MagicNumber, isymbol, timeFrame)));
}


//----------------------- PRINT COMMENT FUNCTION
//----------------------- SOURCE : CODERSGURU
void subPrintDetails()
{
string sComment = "";
string sp = "----------------------------------------\n";
string NL = "\n";

sComment = sp;
sComment = sComment + "TakeProfit=" + DoubleToStr(TakeProfit,0) + " | ";
sComment = sComment + "TrailingStop=" + DoubleToStr(TrailingStop,0) + " | ";
sComment = sComment + "StopLoss=" + DoubleToStr(StopLoss,0) + NL;
sComment = sComment + sp;
sComment = sComment + "Reverse Entry Condition=" + subBoolToStr(ReverseCondition) + NL;
sComment = sComment + "Confirmed On Entry=" + subBoolToStr(ConfirmedOnEntry) + NL;
sComment = sComment + "Stop And Reverse=" + subBoolToStr(StopAndReverse) + NL;
sComment = sComment + "Pure SAR=" + subBoolToStr(PureSAR) + NL;
sComment = sComment + sp;
sComment = sComment + "Lots=" + DoubleToStr(Lots,2) + " | ";
sComment = sComment + "MM=" + subBoolToStr(MM) + " | ";
sComment = sComment + "Risk=" + DoubleToStr(Risk,0) + "%" + NL;
sComment = sComment + sp;

Comment(sComment);
}


//----------------------- BOOLEN VARIABLE TO STRING FUNCTION
//----------------------- SOURCE : CODERSGURU
string subBoolToStr ( bool value)
{
if(value) return ("True");
else return ("False");
}

//----------------------- ALERT ON MA CROSS
//----------------------- SOURCE : FIREDAVE
void subCrossAlert(string type)
{
string AlertComment;

if(type=="UP") AlertComment = "Moving Average Cross UP !";
if(type=="DOWN") AlertComment = "Moving Average Cross DOWN !";

Alert(AlertComment);
PlaySound(SoundFilename);
}

//----------------------- END FUNCTION