//+------------------------------------------------------------------+
//|                           Copyright 2006, Larionov P.V.          |
//|                                          lolion@mail.ru          |
//+------------------------------------------------------------------+

#property copyright "Copyright 2006, ASCTRENDTS "
#property link      "lolion@mail.ru"

#define MAGIC 916883

extern double lStopLoss      = 20;
extern double sStopLoss      = 20;
extern double lTakeProfit    = 80;
extern double sTakeProfit    = 80;
extern double lTrailingStop  = 20;
extern double sTrailingStop  = 20;
extern int MainTrend         = 1440;
extern int ShiftBars                = 1;
extern int Risk                     = 3;
extern bool EnableCloseByASCTrend   =true;
extern int Slippage = 5;
extern bool UseHourTrade = true; //use timefilter
extern int FromHourTrade = 8;
extern int ToHourTrade = 18;
extern bool UseSound = false;
extern string NameFileSound = "alert.wav";
extern double Lots = 1.0;
extern string _Parameters_b_Lots = "Settings of the lot size calculation module";
extern int LotsWayChoice  = 1;    // Lot size selection: 
                                  //  0-fixed lot size, 
                                  //  1-% from deposit, 
                                  //  2-fractional proportional, 
                                  //  3-fractional fixed lot size, 
extern int LotsPercent=0;   // % from deposit 
extern int LotsDeltaDepo=500;  // factor of deposit increase 
extern int LotsDepoForOne=500;  // deposit size for 1 mini lot 
extern int LotsMax=10000; // Max number of mini lots 

extern color clOpenBuy = Blue;
extern color clCloseBuy = Aqua;
extern color clOpenSell = Red;
extern color clCloseSell = Violet;
extern color clModiBuy = Blue;
extern color clModiSell = Red;
extern string Name_Expert = "ASCTRENDTS";




void deinit(){

}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

bool PS=false, PB=false;

int start(){//1


 for(int i=ShiftBars;i<Bars; i++){//2
 PS = AscTrendSignal(MainTrend,"DOWN",i,Risk);
 PB = AscTrendSignal(MainTrend,"UP",i,Risk);
  if(PS||PB){//3
  break;
  }//3
 }//2
    
 if (UseHourTrade){//2
  if (!(Hour()>=FromHourTrade && Hour()<=ToHourTrade)){//3
  Comment("Non-Trading Hours");
  return(0);
  }//3
 }//2
 if(Bars<100){//2
 Print("bars less than 100");
 return(0);
 }//2
 if(lStopLoss<10){//2
 Print("StopLoss less than 10");
 return(0);
 }//2
 if(lTakeProfit<10){
 Print("TakeProfit less than 10");
 return(0);
 }//2
 if(sStopLoss<10){
 Print("StopLoss less than 10");
 return(0);
 }//2
 if(sTakeProfit<10){//2
 Print("TakeProfit less than 10");
 return(0);
 }//2
     
 if(AccountFreeMargin()<(500*Lots)){//2
 Print("You are out of Money", AccountFreeMargin());
 return(0);
 }//2
 if (!ExistPositions()){//2
  if (PS){//3
  OpenSell();
  return(0);
  }//3    
  if (PB){//3
  OpenBuy();
  return(0);
  }//3    
 }//2

 if (ExistPositions()){//2
  if(OrderType()==OP_BUY){//3
   if(EnableCloseByASCTrend){//4
    if (PS){//5
    CloseBuy();
    return(0); 
    }//5
   }//4
  }//3  
  if(OrderType()==OP_SELL){//3
   if(EnableCloseByASCTrend){//4
    if (PB){//5
    CloseSell();
    return(0);
    }//5
   }//4
  }//3
  if(lTrailingStop>0||sTrailingStop>0){//3  
  TrailingPositionsBuy(lTrailingStop);
  TrailingPositionsSell(sTrailingStop);
  }//3
  return (0);
 }//2
}//1
bool ExistPositions() {
	for (int i=0; i<OrdersTotal(); i++) {
		if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
			if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {
				return(True);
			}
		} 
	} 
	return(false);
}
void TrailingPositionsBuy(int trailingStop) { 
   for (int i=0; i<OrdersTotal(); i++) { 
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { 
         if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) { 
            if (OrderType()==OP_BUY) { 
               if (Bid-OrderOpenPrice()>trailingStop*Point) { 
                  if (OrderStopLoss()<Bid-trailingStop*Point) 
                     ModifyStopLoss(Bid-trailingStop*Point); 
               } 
            } 
         } 
      } 
   } 
} 
void TrailingPositionsSell(int trailingStop) { 
   for (int i=0; i<OrdersTotal(); i++) { 
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { 
         if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) { 
            if (OrderType()==OP_SELL) { 
               if (OrderOpenPrice()-Ask>trailingStop*Point) { 
                  if (OrderStopLoss()>Ask+trailingStop*Point || OrderStopLoss()==0)  
                     ModifyStopLoss(Ask+trailingStop*Point); 
               } 
            } 
         } 
      } 
   } 
} 
void ModifyStopLoss(double ldStopLoss) { 
   bool fm;
   fm = OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE); 
   if (fm && UseSound) PlaySound(NameFileSound); 
} 

void CloseBuy() { 
   bool fc; 
   fc=OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clCloseBuy); 
   if (fc && UseSound) PlaySound(NameFileSound); 
} 
void CloseSell() { 
   bool fc; 
   fc=OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clCloseSell); 
   if (fc && UseSound) PlaySound(NameFileSound); 
} 
void OpenBuy() { 
   double ldLot, ldStop, ldTake; 
   string lsComm; 
   ldLot = GetSizeLot(); 
   ldStop = GetStopLossBuy(); 
   ldTake = GetTakeProfitBuy(); 
   lsComm = GetCommentForOrder(); 
   OrderSend(Symbol(),OP_BUY,ldLot,Ask,Slippage,ldStop,ldTake,lsComm,MAGIC,0,clOpenBuy); 
   if (UseSound) PlaySound(NameFileSound); 
} 
void OpenSell() {
Print("OpenSell"); 
   double ldLot, ldStop, ldTake; 
   string lsComm; 
   ldLot = GetSizeLot(); 
   ldStop = GetStopLossSell(); 
   ldTake = GetTakeProfitSell(); 
   lsComm = GetCommentForOrder(); 
   OrderSend(Symbol(),OP_SELL,ldLot,Bid,Slippage,ldStop,ldTake,lsComm,MAGIC,0,clOpenSell); 
   Print("OrderSent !!!!!!!!"); 
   if (UseSound) PlaySound(NameFileSound); 
} 

string GetCommentForOrder(){
return(Name_Expert); 
} 


double GetSizeLot() { 
  double dLot; 
  if (LotsWayChoice==0) dLot=Lots; 

  // fixed % from deposit 
  if (LotsWayChoice==1) { 
    dLot=MathCeil(AccountFreeMargin()/10000*LotsPercent)/10; 
  } 

  // fractional proportional 
  if (LotsWayChoice==2) { 
    int k=LotsDepoForOne; 
    for (double i=2; i<=LotsMax; i++) { 
      k=k+i*LotsDeltaDepo; 
      if (k>AccountFreeMargin()) { 
        dLot=(i-1)/10; break; 
      } 
    } 
  } 

  // fractional fixed 
  if (LotsWayChoice==3) { 
    dLot=MathCeil((AccountFreeMargin()-LotsDepoForOne)/LotsDeltaDepo)/10; 
  } 

  if (dLot<0.1)  dLot=0.1;
  if (dLot>LotsMax) dLot=LotsMax;
   
  return(dLot);  
  } 
double GetStopLossBuy() { 	return (Bid-lStopLoss*Point);} 
double GetStopLossSell() { 	return(Ask+sStopLoss*Point); } 
double GetTakeProfitBuy() { 	return(Ask+lTakeProfit*Point); } 
double GetTakeProfitSell() { 	return(Bid-sTakeProfit*Point); }

//******************************************************************************************************
//bool AscTrendSignal(int TF, string Direction, int Shift=0 int Risk=3)
//Description: Determine of the moment of the signal receiving from the AscTrendSignal indicator.
//Settings: int TF - Timeframe,string Direction - Direction to enter. int Shift - which bar to look at, int Risk - settings of the indicator
//Returned value - True if the signal received, false if else.
//******************************************************************************************************
// !!!Please note: the custom indicator should be named as "ASCTrend"
// for the normal working function 
bool AscTrendSignal(int TF=0, string Direction="", int Shift=1, int Risk=3){//1
double ASCval1, ASCval2;
 ASCval1 = iCustom(NULL,NULL,"ASCTrend",Risk,300,0,Shift);
 ASCval2 = iCustom(NULL,NULL,"ASCTrend",Risk,300,1,Shift);
 //Print("ASC1 ",ASCval1," ASC2 ",ASCval2);
 if (Direction == "UP"){//2
  if(ASCval2>0){//3
  return(true);
  }//3
 }//2
 if (Direction == "DOWN"){//2
  if(ASCval1>0){//3
  Print(Direction);
  return(true);
  }//3
 }//2
}//1