//+------------------------------------------------------------------+
//|                             AuslancoExpert_original_strategy.mq4 |
//|                                        Copyright © 2008, FerruFx |
//|                                                                  |
//| Based on the original Auslanco's strategy posted on ForexFactory |
//|               http://www.forexfactory.com/showthread.php?t=41509 |
//+------------------------------------------------------------------+

#property copyright "Copyright © 2008 www.ervent.net, FerruFx"
#property link "http://www.ervent.net"

//---- Trade settings
extern string Label1               = "=== General trade settings ===";
extern double Lot                  =   0.1;
extern double TakeProfit           =   0.0;
extern double StopLoss             =   0.0;
extern int    TrailingStop         =   0.0;
extern int    Trailing.Start.at    =   0.0;
extern int    Slippage             =   2.0;
extern bool   Managed.Lot.Size     = false;
extern double Risk                 =   2.0;

extern string Label2               = "=== Exit settings ===";
extern bool   Use.QQE.to.Exit      =  true;

int      MagicNumber;
datetime timeprev=0;
double   qqe0h4_prev,qqe2h4_prev;
double   qqe0h1_prev,qqe2h1_prev;
double   qqe0h1_prev2,qqe2h1_prev2;
double   gannh4_prev,gannh1_prev;

int init()
  {
   if (Symbol() == "AUDCADm" || Symbol() == "AUDCAD") { MagicNumber = 431801; }
   if (Symbol() == "AUDJPYm" || Symbol() == "AUDJPY") { MagicNumber = 431802; }
   if (Symbol() == "AUDNZDm" || Symbol() == "AUDNZD") { MagicNumber = 431803; }
   if (Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") { MagicNumber = 431804; }
   if (Symbol() == "CHFJPYm" || Symbol() == "CHFJPY") { MagicNumber = 431805; }
   if (Symbol() == "EURAUDm" || Symbol() == "EURAUD") { MagicNumber = 431806; }
   if (Symbol() == "EURCADm" || Symbol() == "EURCAD") { MagicNumber = 431807; }
   if (Symbol() == "EURCHFm" || Symbol() == "EURCHF") { MagicNumber = 431808; }
   if (Symbol() == "EURGBPm" || Symbol() == "EURGBP") { MagicNumber = 431809; }
   if (Symbol() == "EURJPYm" || Symbol() == "EURJPY") { MagicNumber = 431810; }
   if (Symbol() == "EURUSDm" || Symbol() == "EURUSD") { MagicNumber = 431811; }
   if (Symbol() == "GBPCHFm" || Symbol() == "GBPCHF") { MagicNumber = 431812; }
   if (Symbol() == "GBPJPYm" || Symbol() == "GBPJPY") { MagicNumber = 431813; }
   if (Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") { MagicNumber = 431814; }
   if (Symbol() == "NZDJPYm" || Symbol() == "NZDJPY") { MagicNumber = 431815; }
   if (Symbol() == "NZDUSDm" || Symbol() == "NZDUSD") { MagicNumber = 431816; }
   if (Symbol() == "USDCHFm" || Symbol() == "USDCHF") { MagicNumber = 431817; }
   if (Symbol() == "USDJPYm" || Symbol() == "USDJPY") { MagicNumber = 431818; }
   if (Symbol() == "USDCADm" || Symbol() == "USDCAD") { MagicNumber = 431819; }
   if (Symbol() == "AUDCHFm" || Symbol() == "AUDCHF") { MagicNumber = 431820; }
   if (Symbol() == "CADCHFm" || Symbol() == "CADCHF") { MagicNumber = 431821; }
   if (Symbol() == "CADJPYm" || Symbol() == "CADJPY") { MagicNumber = 431822; }
   if (MagicNumber == 0) { MagicNumber = 431899; }
   return(0);
  }
  
int deinit()
  {
   return(0);
  }
  
int start()
  {
   //---- Trail opened order
   if(TrailingStop > 0 && (CountLongs() != 0 || CountShorts() != 0)) trailing();
   
   if(timeprev!= /*Time[0]*/ iTime(Symbol(),PERIOD_H1,0)) { //---- Check signal only once a bar H1
   
    //---- QQE and Gann Hilo calculation for H4
    qqe0h4_prev   = iCustom(Symbol(),PERIOD_H4,"###QQE_Alert_MTF_v2###",5,240,false,false,false,false,0,1);
    qqe2h4_prev   = iCustom(Symbol(),PERIOD_H4,"###QQE_Alert_MTF_v2###",5,240,false,false,false,false,2,1);
   
    gannh4_prev = iCustom(Symbol(),PERIOD_H4,"###Gann_HiLo_Activator_v2###",10,0,1);
   
    //---- QQE and Gann Hilo calculation for H1
    qqe0h1_prev    = iCustom(Symbol(),PERIOD_H1,"###QQE_Alert_MTF_v2###",5,60,false,false,false,false,0,1);
    qqe2h1_prev    = iCustom(Symbol(),PERIOD_H1,"###QQE_Alert_MTF_v2###",5,60,false,false,false,false,2,1);
    qqe0h1_prev2   = iCustom(Symbol(),PERIOD_H1,"###QQE_Alert_MTF_v2###",5,60,false,false,false,false,0,2);
    qqe2h1_prev2   = iCustom(Symbol(),PERIOD_H1,"###QQE_Alert_MTF_v2###",5,60,false,false,false,false,2,2);
   
    gannh1_prev = iCustom(Symbol(),PERIOD_H1,"###Gann_HiLo_Activator_v2###",10,0,1);
   
    //---- Check for H4 signal
    if(CountLongs() == 0 && CountShorts() == 0) {
   
     //---- Check for H1 Entry
     if(qqe0h1_prev > 50 && qqe0h1_prev2 < 50) {
      if(/*Close[1]*/ iClose(Symbol(),PERIOD_H1,1) > gannh1_prev) {
       if(qqe0h4_prev > qqe2h4_prev && /*Close[1]*/ iClose(Symbol(),PERIOD_H4,1) > gannh4_prev) ManageBuy(); }}
     
     if(qqe0h1_prev < 50 && qqe0h1_prev2 > 50) {
      if(/*Close[1]*/ iClose(Symbol(),PERIOD_H1,1) < gannh1_prev) {
       if(qqe0h4_prev < qqe2h4_prev && /*Close[1]*/ iClose(Symbol(),PERIOD_H4,1) < gannh4_prev) ManageSell(); }}
    }  //---- if(Count
     
    //---- Check for exit
    if(Use.QQE.to.Exit) {
     if(CountLongs() != 0) {
      if(qqe0h1_prev < 50) CloseLongs(); }
     if(CountShorts() != 0) {
      if(qqe0h1_prev > 50) CloseShorts(); }
    }
    timeprev = /*Time[0]*/ iTime(Symbol(),PERIOD_H1,0);
   }  //---- if(timeprev
  
   return(0);
  }

int CountLongs()
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if( OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_BUY)
   count++;
 }  //---- for
 return(count);
}

int CountShorts()
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if(OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_SELL)
  count++;
 }  //---- for
 return(count);
}

double ManagedLotSize()
{
 double lot;
 
 if(Managed.Lot.Size && Risk > 0) lot = NormalizeDouble(((AccountEquity()*Risk)/100000),2);
 else lot = Lot;
 
 return(lot);
}

void ManageBuy()
{
 double tp,sl;
 if (TakeProfit==0) { tp=0; } else { tp=Ask+TakeProfit*Point; }
 if (StopLoss==0) { sl=0; } else { sl=Ask-StopLoss*Point; }
 
 for (int i = 1; i <=5; i++)   //---- Loop if requote
 {
  RefreshRates();
  int ticket=OrderSend(Symbol(),OP_BUY,ManagedLotSize(),Ask,Slippage,sl,tp,"AuslancoExpert" + " - " + Period(),MagicNumber,0,Lime);
 
  if(ticket<0)
  {
   Print("Error opening BUY order : ",GetLastError()); 
               
   Sleep(3000);   //---- wait for 3 seconds
  }
  else
  {
   break;
  }
 }
 if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
 {
  Print("BUY order opened : ",OrderOpenPrice());
 }
 else
 {
  Print("Error opening BUY order : ",GetLastError()); 
 }
}

void ManageSell()
{
 double tp,sl;
 if (TakeProfit==0) { tp=0; } else { tp=Bid-TakeProfit*Point; }
 if (StopLoss==0) { sl=0; } else { sl=Bid+StopLoss*Point; }
 
 for (int i = 1; i <=5; i++)   //---- Loop if requote
 {
  RefreshRates();
  int ticket=OrderSend(Symbol(),OP_SELL,ManagedLotSize(),Bid,Slippage,sl,tp,"AuslancoExpert" + " - " + Period(),MagicNumber,0,Red);
  
  if(ticket<0)
  {
   Print("Error opening SELL order : ",GetLastError()); 
               
   Sleep(3000);   //---- wait for 3 seconds
  }
  else
  {
   break;
  }
 }
 if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
 {
  Print("SELL order opened : ",OrderOpenPrice());
 }
 else
 {
  Print("Error opening SELL order : ",GetLastError()); 
 }
}

void CloseLongs()
{
 int trades = OrdersTotal();
 for( int trade=0; trade < trades; trade++ )
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber )
  {
   continue;
  }
  if( OrderType() == OP_BUY )
  {
   OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Blue);
  }
 }   //---- for
}

void CloseShorts()
{
 int trades = OrdersTotal();
 for( int trade=0; trade < trades; trade++ )
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  if( OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber )
  {
   continue;
  }
  if( OrderType() == OP_SELL )
  {
   OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Pink);
  }
 }   //---- for
}

void trailing()
{

 int trades = OrdersTotal();
 int cnt;
 for(cnt=0;cnt<trades;cnt++)
 {
  OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
  if(OrderType()<=OP_SELL && OrderSymbol()==Symbol() && OrderMagicNumber() == MagicNumber)
  {
   if(OrderType()==OP_BUY)
   {             
    if((Bid-OrderOpenPrice())>=(Point*TrailingStop) && (Bid-OrderOpenPrice())>=(Point*Trailing.Start.at))
    {
     if((OrderStopLoss()<=(Bid-Point*TrailingStop)) || (OrderStopLoss()==Trailing.Start.at))
     {
      OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue);
      return(0);
     }
    }
   }    //---- if(OrderType()==OP_BUY)
   else
   {
    if((OrderOpenPrice()-Ask)>=(Point*TrailingStop) && (OrderOpenPrice()-Ask)>=(Point*Trailing.Start.at))
    {
     if((OrderStopLoss()>=(Ask+Point*TrailingStop)) || (OrderStopLoss()==Trailing.Start.at))
     {
      OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
      return(0);
     }
    }
   }   //---- else
  }   //---- if(OrderType()<=OP_SELL
 }    //---- for
}     //---- void