//+------------------------------------------------------------------------------+//
//)   ____  _  _  ____  ____  ____  ____  __  __    __      ___  _____  __  __   (//
//)  ( ___)( \/ )(  _ \(  _ \( ___)( ___)(  \/  )  /__\    / __)(  _  )(  \/  )  (//
//)   )__)  )  (  )(_) ))   / )__)  )__)  )    (  /(__)\  ( (__  )(_)(  )    (   (//
//)  (__)  (_/\_)(____/(_)\_)(____)(____)(_/\/\_)(__)(__)()\___)(_____)(_/\/\_)  (//
//)   http://fxdreema.com                           Copyright © 2012, fxDreema   (//
//+------------------------------------------------------------------------------+//
#property copyright ""
#property link      "http://fxdreema.com"

///////
// Advanced system settings
#define POINT_FORMAT         0.0001  // Relative to EURUSD. 0.0001 to use 4-digits format, 0.00001 to use 5-digits format 
#define USE_VIRTUAL_STOPS    "no"    // Use "yes" or "no"
//--
#define USE_EMERGENCY_STOPS  "no"   // "yes" to use emergency (hard stops) when virtual stops are in use. "always" to use EMERGENCY_STOPS_ADD as emergency stops when there is no virtual stop.
#define EMERGENCY_STOPS_REL  0       // Use 0 to disable hard stops when virtual stops are enabled. Use a value >=0 to automatically set hard stops with virtual. Example: if 2 is used, then hard stops will be 2 times bigger than virtual ones.
#define EMERGENCY_STOPS_ADD  0       // Add pips to relative size of emergency stops (hard stops)
//--
#define EVENTS_MODE          "tick" // Use "period" to listen every EVENTS_CYCLE_PERIOD milliseconds or "tick" to listen only when a new tick is received
#define EVENTS_CYCLE_PERIOD  1        // Time delay in events listener while in "period" mode. The smaller period - the faster events reaction. Use "1" as minimum
#define EVENT_TIMER_PERIOD   60        // Timer event period (in seconds)
//--
#define ENABLE_EVENT_TICK  1 // "Tick"  event: 1 - enable, 0 - disable
#define ENABLE_EVENT_TRADE 0 // "Trade" event: 1 - enable, 0 - disable
#define ENABLE_EVENT_TIMER 0 // "Timer" event: 1 - enable, 0 - disable
//--
#define SIMULATE_TICKS        0        // Use this for offline charts - feed the EA with ticks coming from a certain market (SIMULATE_TICKS_MARKET). Options: 1 - enable, 0 - disable
#define SIMULATE_TICKS_MARKET "EURUSD" // When SIMULATE_TICKS is enabled, feed the EA with ticks coming from the chosen market
///////

#define detect_broker_digits 0


// External variables given from blocks
extern string inp2="-= Input parameters for block 2 (Condition) =-";
extern int inp2_Ro_MAperiod=100; // MA period

extern string inp4="-= Input parameters for block 4 (Condition) =-";
extern int inp4_Lo_ADXperiod=14; // ADX period
extern int inp4_Ro_ADXperiod=14; // ADX period

extern string inp5="-= Input parameters for block 5 (Buy now) =-";
extern int inp5_dlStopLoss_SHIFT=0; // Candle ID
extern double inp5_TakeProfitPips=10; // in pips...

extern string inp8="-= Input parameters for block 8 (Sell now) =-";
extern int inp8_dlStopLoss_SHIFT=0; // Candle ID
extern double inp8_TakeProfitPips=10; // in pips...

// Standard global variables
extern string inpstd="-= System =-";
extern int MagicStart=2131; // Magic Start (MagicNumber=MagicStart+Group#)

// On-Off switches for blocks
bool tick1=true; // No trade is running
bool tick2=true; // Condition
bool tick3=true; // Condition
bool tick4=true; // Condition
bool tick5=true; // Buy now
bool tick6=true; // AND
bool tick7=true; // AND
bool tick8=true; // Sell now

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| EXPERT INITIALIZATION SECTOR                                          |//
//| Runs only once when expert loads                                      |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////

int init()
{
	int logo_x=230; int logo_y=0;
	string name="fxdreema_logo1";
	if (ObjectFind(name)==-1) {
   	   ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	   ObjectSet      (name, OBJPROP_BACK, false);
	   ObjectSet      (name, OBJPROP_XDISTANCE, logo_x-1);
	   ObjectSet      (name, OBJPROP_YDISTANCE, logo_y+1);
	   ObjectSetText  (name, "g", 16, "Webdings", C'0x11,0x11,0x11');
	}
   	
	name="fxdreema_logo2";
	if (ObjectFind(name)==-1) {
       ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	   ObjectSet      (name, OBJPROP_BACK, false);
	   ObjectSet      (name, OBJPROP_XDISTANCE, logo_x+20);
	   ObjectSet      (name, OBJPROP_YDISTANCE, logo_y+1);
	   ObjectSetText  (name, "gggg", 16, "Webdings", White);
	}

	name="fxdreema_logo3";
   	if (ObjectFind(name)==-1) {
	   ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	   ObjectSet      (name, OBJPROP_BACK, false);
	   ObjectSet      (name, OBJPROP_XDISTANCE, logo_x);
	   ObjectSet      (name, OBJPROP_YDISTANCE, logo_y);
	   ObjectSetText  (name, "fx", 18, "Arial", Magenta);
	}

   	name="fxdreema_logo4";
   	if (ObjectFind(name)==-1) {
	   ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	   ObjectSet      (name, OBJPROP_BACK, false);
	   ObjectSet      (name, OBJPROP_XDISTANCE, logo_x+20);
	   ObjectSet      (name, OBJPROP_YDISTANCE, logo_y);
	   ObjectSetText  (name, "dreema", 18, "Arial", DimGray);
	}
	
	DrawStatus("Starting...");
	ListOfIDsConnectedToMe(""); // calculate only
   //Comment("Program "+WindowExpertName( ) +" loaded at "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS));
	if (SIMULATE_TICKS==1) {EventsListener(); EventsListener();}
	return(0);
}
  

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| EXPERT START (TICK) SECTOR                                            |//
//| Runs at every new tick (begins with "start()" function)               |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////

int start() {static int p=0; if (p!=Period()) {DrawStatus("Working"); p=Period();} EventsListener(); return(0);}
int EventTick()
{	TicksFromStart("update");
			tick1();
// Main beginning on the graph
	DrawSpreadInfo();
	return(0);
}
	//////////////////////////////////////////
	// Define block 1 (No trade is running) //
	void tick1(string _parent_="")
	{if (tick1==true) {
		//////
		// Inputs
		string OrdersScope = "group"  ; // Group mode <== [group|manual|all]
		int    OrdersGroup = 0        ; // Group # (empty=Default)
		string SymbolScope = "all"    ; // Market mode <== [all|symbol]
		string SYMBOL      = Symbol() ; // Market (empty=Current)
		string BuysOrSells = "both"   ; // Filter by type <== [buys|sells|both]
		// Inputs
		//////
		
		LoopedStop();
		bool exist=false;
		for (int pos=OrdersTotal()-1; pos>=0; pos--) {
		   if (OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) {
		      if (FilterOrderBy(OrdersScope,OrdersGroup, SymbolScope,SYMBOL, BuysOrSells)) {
		         exist=true; break;
		      }
		   }
		}
		LoopedResume();
		if (exist==false) {tick2("1");} else {/* Next blocks in chain (inverted output) */}
	}}

	////////////////////////////////
	// Define block 2 (Condition) //
	void tick2(string _parent_="")
	{if (tick2==true) {
		// Lo
		double f_Lo_1=iClose(Symbol(), 0, 1);
		// Ro
		double f_Ro_2=iMA(Symbol(),0,inp2_Ro_MAperiod,0,MODE_SMA,PRICE_CLOSE,1);
		
		// Condition
		if (f_Lo_1>f_Ro_2) {tick7("2");} else {/* Next blocks in chain (inverted output) */}
	}}

	////////////////////////////////
	// Define block 3 (Condition) //
	void tick3(string _parent_="")
	{if (tick3==true) {
		// Lo
		double f_Lo_1=iSAR(Symbol(),0,0.02,0.2,1);
		// Ro
		double f_Ro_2=iClose(Symbol(), 0, 1);
		
		// Condition
		if (f_Lo_1<f_Ro_2) {tick6("3");} else {/* Next blocks in chain (inverted output) */}
	}}

	////////////////////////////////
	// Define block 4 (Condition) //
	void tick4(string _parent_="")
	{if (tick4==true) {
		// Lo
		double f_Lo_1=iADX(Symbol(),0,inp4_Lo_ADXperiod,PRICE_CLOSE,1,1);
		// Ro
		double f_Ro_2=iADX(Symbol(),0,inp4_Ro_ADXperiod,PRICE_CLOSE,2,1);
		
		// Condition
		if (f_Lo_1>f_Ro_2) {tick5("4");} else {tick8("4");}
	}}

	//////////////////////////////
	// Define block 5 (Buy now) //
	void tick5(string _parent_="")
	{if (tick5==true) {
		//////
		// Inputs
		int    OrdersGroup    = 0                   ; // Group # (empty=Default)
		string SYMBOL         = Symbol()            ; // Market (empty=Current)
		string VolumeMode     = "fixed"             ; // Volume size mode <== [fixed|equity|balance|freemargin|equityRisk|balanceRisk|freemarginRisk|dynamic]
		double VolumeSize     = 0.1                 ; // in lots or money... (size)
		double VolumeRisk     = 2.5                 ; // Risk percent (%)
		double VolumePercent  = 100                 ; // Volume size (%)
		string StopLossMode   = "dynamicLevel"      ; // Stop-Loss mode <== [none|fixed|dynamicLevel|dynamicPips|dynamicDigits]
		double StopLossPips   = 100                 ; // in pips... (pips)
		string TakeProfitMode = "fixed"             ; // Take-Profit mode <== [none|fixed|dynamicLevel|dynamicPips|dynamicDigits]
		double TakeProfitPips = inp5_TakeProfitPips ; // in pips... (pips)
		double Slippage       = 4                   ; // Slippage (pips)
		string MyComment      = "Long trade"        ; // Comment (text)
		color  ArrowColorBuy  = Blue                ; // Arrow color
		// Inputs
		//////
		
		SetSymbol(SYMBOL);
		int MagicNumber=MagicStart+OrdersGroup;
		
		/////
		// Stop Loss and Take Profit
		double SL=0;
		double TP=0;
		
		if (StopLossMode=="fixed") {SL=StopLoss("buy",StopLossPips);}
		if (TakeProfitMode=="fixed") {TP=TakeProfit("buy",TakeProfitPips);}
		
		if (StopLossMode=="dynamicLevel")
		{
		   double f_dlStopLoss_2=iSAR(Symbol(),0,0.02,0.2,inp5_dlStopLoss_SHIFT);
		   SL=f_dlStopLoss_2;
		}
		if (StopLossMode=="dynamicPips")
		{
		   double f_dpStopLoss_3=100;
		   SL=StopLoss("buy",f_dpStopLoss_3);
		}
		if (StopLossMode=="dynamicDigits")
		{
		   double f_ddStopLoss_4=0.0100;
		   SL=StopLoss("buy",toPips(f_ddStopLoss_4,SYMBOL));
		}
		if (TakeProfitMode=="dynamicLevel")
		{
		   double f_dlTakeProfit_5=1;
		   TP=f_dlTakeProfit_5;
		}
		if (TakeProfitMode=="dynamicPips")
		{
		   double f_dpTakeProfit_6=100;
		   TP=TakeProfit("buy",f_dpTakeProfit_6);
		}
		if (TakeProfitMode=="dynamicDigits")
		{
		   double f_ddTakeProfit_7=0.0100;
		   TP=TakeProfit("buy",toPips(f_ddTakeProfit_7,SYMBOL));
		}
		// Stop Loss and Take Profit
		/////
		
		/////
		// Volume size
		double VolumeLots=0;
		if (VolumeMode=="fixed") {VolumeLots=DynamicLots("fixed",VolumeSize);}
		if (VolumeMode=="equity") {VolumeLots=DynamicLots("equity",VolumePercent);}
		if (VolumeMode=="balance") {VolumeLots=DynamicLots("balance",VolumePercent);}
		if (VolumeMode=="freemargin"){VolumeLots=DynamicLots("freemargin",VolumePercent);}
		if (VolumeMode=="equityRisk") {VolumeLots=DynamicLots("equityRisk",VolumeRisk,toPips(SymbolAsk()-SL));}
		if (VolumeMode=="balanceRisk") {VolumeLots=DynamicLots("balanceRisk",VolumeRisk,toPips(SymbolAsk()-SL));}
		if (VolumeMode=="freemarginRisk") {VolumeLots=DynamicLots("freemarginRisk",VolumeRisk,toPips(SymbolAsk()-SL));}
		if (VolumeMode=="dynamic") {
		   double f_dVolumeSize_1=0.1;
		   VolumeLots=AlignLots(f_dVolumeSize_1);
		}
		// Volume size
		/////
		
		/////
		// Placing an order
		int Ticket=BuyNow(VolumeLots,SL,TP,Slippage,MagicNumber,MyComment,ArrowColorBuy);
		// Placing an order
		/////
		
		if (Ticket>-1) {/* Next blocks in chain */} else {/* Error output */}
	}}

	//////////////////////////
	// Define block 6 (AND) //
	void tick6(string _parent_="")
	{if (tick6==true) {
		static bool passed=false;
		static string list[];
		static string check[];
		static int old_tick=-1;
		bool go_to_next=false;
		static int list_size;
		
		if (!passed) {passed=true;
		   StringExplode(",",ListOfIDsConnectedToMe("6"),list);
		   list_size=ArraySize(list);
		}
		if (list_size==0) {
		   // This block is at the very top => pass everytime
		   go_to_next=true;
		}
		else {
		   // This block is child
		   int TicksFromStart=TicksFromStart();
		   if (old_tick!=TicksFromStart) {old_tick=TicksFromStart;
		      ArrayResize(check,0); // reset
		   }
		   if (ArraySearchS(list,_parent_)>-1 && ArraySearchS(check,_parent_)==-1) {
		      ArrayValueS(check,_parent_); // add current parent
		      //Alert(list_size);
		      if (list_size==ArraySize(check)) {go_to_next=true;}
		   }
		   
		}
		if (go_to_next==true) {tick4("6");} else {/* Next blocks in chain (inverted output) */}
	}}

	//////////////////////////
	// Define block 7 (AND) //
	void tick7(string _parent_="")
	{if (tick7==true) {
		static bool passed=false;
		static string list[];
		static string check[];
		static int old_tick=-1;
		bool go_to_next=false;
		static int list_size;
		
		if (!passed) {passed=true;
		   StringExplode(",",ListOfIDsConnectedToMe("7"),list);
		   list_size=ArraySize(list);
		}
		if (list_size==0) {
		   // This block is at the very top => pass everytime
		   go_to_next=true;
		}
		else {
		   // This block is child
		   int TicksFromStart=TicksFromStart();
		   if (old_tick!=TicksFromStart) {old_tick=TicksFromStart;
		      ArrayResize(check,0); // reset
		   }
		   if (ArraySearchS(list,_parent_)>-1 && ArraySearchS(check,_parent_)==-1) {
		      ArrayValueS(check,_parent_); // add current parent
		      //Alert(list_size);
		      if (list_size==ArraySize(check)) {go_to_next=true;}
		   }
		   
		}
		if (go_to_next==true) {tick3("7");} else {/* Next blocks in chain (inverted output) */}
	}}

	///////////////////////////////
	// Define block 8 (Sell now) //
	void tick8(string _parent_="")
	{if (tick8==true) {
		//////
		// Inputs
		int    OrdersGroup    = 0                   ; // Group # (empty=Default)
		string SYMBOL         = Symbol()            ; // Market (empty=Current)
		string VolumeMode     = "fixed"             ; // Volume size mode <== [fixed|equity|balance|freemargin|equityRisk|balanceRisk|freemarginRisk|dynamic]
		double VolumeSize     = 0.1                 ; // in lots or money... (size)
		double VolumeRisk     = 2.5                 ; // Risk percent (%)
		double VolumePercent  = 100                 ; // Volume size (%)
		string StopLossMode   = "dynamicLevel"      ; // Stop-Loss mode <== [none|fixed|dynamicLevel|dynamicPips|dynamicDigits]
		double StopLossPips   = 100                 ; // in pips... (pips)
		string TakeProfitMode = "fixed"             ; // Take-Profit mode <== [none|fixed|dynamicLevel|dynamicPips|dynamicDigits]
		double TakeProfitPips = inp8_TakeProfitPips ; // in pips... (pips)
		double Slippage       = 4                   ; // Slippage (pips)
		string MyComment      = "Short trade"       ; // Comment (text)
		color  ArrowColorSell = Red                 ; // Arrow color
		// Inputs
		//////
		
		SetSymbol(SYMBOL);
		int MagicNumber=MagicStart+OrdersGroup;
		
		/////
		// Stop Loss and Take Profit
		double SL=0;
		double TP=0;
		
		if (StopLossMode=="fixed") {SL=StopLoss("sell",StopLossPips);}
		if (TakeProfitMode=="fixed") {TP=TakeProfit("sell",TakeProfitPips);}
		
		if (StopLossMode=="dynamicLevel")
		{
		   double f_dlStopLoss_2=iSAR(Symbol(),0,0.02,0.2,inp8_dlStopLoss_SHIFT);
		   SL=f_dlStopLoss_2;
		}
		if (StopLossMode=="dynamicPips")
		{
		   double f_dpStopLoss_3=100;
		   SL=StopLoss("sell",f_dpStopLoss_3);
		}
		if (StopLossMode=="dynamicDigits")
		{
		   double f_ddStopLoss_4=0.0100;
		   SL=StopLoss("sell",toPips(f_ddStopLoss_4,SYMBOL));
		}
		if (TakeProfitMode=="dynamicLevel")
		{
		   double f_dlTakeProfit_5=1;
		   TP=f_dlTakeProfit_5;
		}
		if (TakeProfitMode=="dynamicPips")
		{
		   double f_dpTakeProfit_6=100;
		   TP=TakeProfit("sell",f_dpTakeProfit_6);
		}
		if (TakeProfitMode=="dynamicDigits")
		{
		   double f_ddTakeProfit_7=0.0100;
		   TP=TakeProfit("sell",toPips(f_ddTakeProfit_7,SYMBOL));
		}
		// Stop Loss and Take Profit
		/////
		
		/////
		// Volume size
		double VolumeLots=0;
		if (VolumeMode=="fixed") {VolumeLots=DynamicLots("fixed",VolumeSize);}
		if (VolumeMode=="equity") {VolumeLots=DynamicLots("equity",VolumePercent);}
		if (VolumeMode=="balance") {VolumeLots=DynamicLots("balance",VolumePercent);}
		if (VolumeMode=="freemargin"){VolumeLots=DynamicLots("freemargin",VolumePercent);}
		if (VolumeMode=="equityRisk") {VolumeLots=DynamicLots("equityRisk",VolumeRisk,toPips(SL-SymbolBid()));}
		if (VolumeMode=="balanceRisk") {VolumeLots=DynamicLots("balanceRisk",VolumeRisk,toPips(SL-SymbolBid()));}
		if (VolumeMode=="freemarginRisk") {VolumeLots=DynamicLots("freemarginRisk",VolumeRisk,toPips(SL-SymbolBid()));}
		if (VolumeMode=="dynamic") {
		   double f_dVolumeSize_1=0.1;
		   VolumeLots=AlignLots(f_dVolumeSize_1);
		}
		// Volume size
		/////
		
		/////
		// Placing an order
		int Ticket=SellNow(VolumeLots,SL,TP,Slippage,MagicNumber,MyComment,ArrowColorSell);
		// Placing an order
		/////
		
		if (Ticket>-1) {/* Next blocks in chain */} else {/* Error output */}
	}}

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| EXPERT TARDE EVENTS SECTOR                                            |//
//| Runs when the Trade event occurs                                      |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////

void EventTrade()
{

}

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| EXPERT TIMER EVENTS SECTOR                                            |//
//| Runs when the Timer event occurs                                      |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////

void EventTimer()
{

}

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| EXPERT DEINITIALIZATION SECTOR                                        |//
//| Runs only once when expert unloads                                    |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////

int deinit()
{
	DrawStatus("Stopped");
	switch(UninitializeReason())
	{
      case REASON_CHARTCLOSE: Print("Unitialize: Chart closed"); break;
      case REASON_REMOVE:     Print("Unitialize: Expert removed from chart"); break;
      case REASON_RECOMPILE:  Print("Unitialize: Expert recompiled"); break;
      case REASON_CHARTCHANGE:Print("Unitialize: Symbol or timeframe changed on the chart"); break;
      case REASON_PARAMETERS: Print("Unitialize: Inputs parameters was changed by user"); break;
      case REASON_ACCOUNT:    Print("Unitialize: Other account activated"); break;
	}
	
	return(0);
}



/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| FUNCTIONS, USED IN THIS EXPERT ADVISOR                                |//
//| Custom and System functions                                           |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
	
	bool LoopedStop(string action="set")
	{
	   LoopedResume("set");
	   return(true);
	}
	
	bool FilterOrderBy(string OrdersScope="all", int OrdersGroup=0, string SymbolScope="all", string SYMBOL="", string BuysOrSells="both", string LimitsOrStops="")
	{
	   if (SYMBOL=="") {SYMBOL=Symbol();}
	   // Trades
	   if (LimitsOrStops=="")
	   {
	      if (SymbolScope=="all" || OrderSymbol()==SYMBOL) {
	         if (OrdersScope=="all" || (OrdersScope=="group" && OrderMagicNumber()==(MagicStart+OrdersGroup)) || (OrdersScope=="manual" && OrderMagicNumber()==0)) {
	            if (
	               (BuysOrSells=="buys"  && OrderType()==OP_BUY)
	               ||
	               (BuysOrSells=="sells" && OrderType()==OP_SELL)
	               ||
	               (BuysOrSells=="both"  && (OrderType()==OP_BUY || OrderType()==OP_SELL))
	               )
	            {
	               return(true);
	            }
	         }
	      }
	   }
	   // Pending orders
	   if (LimitsOrStops!="")
	   {
	      if (SymbolScope=="all" || OrderSymbol()==SYMBOL) {
	         if (OrdersScope=="all" || (OrdersScope=="group" && OrderMagicNumber()==(MagicStart+OrdersGroup)) || (OrdersScope=="manual" && OrderMagicNumber()==0)) {
	            if (
	               ((BuysOrSells=="buys" || BuysOrSells=="both") && (OrderType()==OP_BUYLIMIT || OrderType()==OP_BUYSTOP))
	               ||
	               ((BuysOrSells=="sells" || BuysOrSells=="both") && (OrderType()==OP_SELLLIMIT || OrderType()==OP_SELLSTOP))
	               )
	            {
	               if (
	                  ((LimitsOrStops=="stops" || LimitsOrStops=="both") && (OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP))
	                  ||
	                  ((LimitsOrStops=="limits" || LimitsOrStops=="both") && (OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT))               
	                  )
	               {
	                  return(true);
	               }
	            }
	         }
	      }
	   }
	   // Rejected from filter
	   return(false);
	}
	
	bool LoopedResume(string action="set")
	{
	   static int ticket;
	   if (action=="set") {
	      ticket=OrderTicket(); return(true);
	   } else {
	      OrderSelect(ticket,SELECT_BY_TICKET); return(true);
	   }
	   return(false);
	}
	
	string SetSymbol(string symbol="")
	{
		if (symbol=="") {symbol=Symbol();}
	   GetSymbol(symbol); return(symbol);
	}
	
	double StopLoss(string mode="buy", double SL=0, double price=0)
	{
	   double ask=MarketInfo(GetSymbol(),MODE_ASK);
	   double bid=MarketInfo(GetSymbol(),MODE_BID);
	   if (SL!=0 && (mode=="buy" || mode=="")) {if (price>0) {ask=price;} SL=ask-toDigits(SL);}
	   if (SL!=0 && mode=="sell") {if (price>0) {bid=price;} SL=bid+toDigits(SL);}
	   return(SL);
	}
	
	double TakeProfit(string mode="buy", double TP=0, double price=0)
	{
	   double ask=MarketInfo(GetSymbol(),MODE_ASK);
	   double bid=MarketInfo(GetSymbol(),MODE_BID);
	   if (TP!=0 && (mode=="buy" || mode=="")) {if (price>0) {ask=price;} TP=ask+toDigits(TP);}
	   if (TP!=0 && mode=="sell") {if (price>0) {bid=price;} TP=bid-toDigits(TP);}
	   return(TP);
	}
	
	double toPips(double digits,string symbol="")
	{
	   if (symbol=="") {symbol=GetSymbol();}
	   return(digits/(PipValue()*MarketInfo(symbol,MODE_POINT)));
	}
	
	double DynamicLots(string mode="balance", double value=0, double sl=0, string align="align")
	{
	   double size=0;
	   string symbol=GetSymbol();
	   double LotStep=MarketInfo(symbol,MODE_LOTSTEP);
	   double LotSize=MarketInfo(symbol,MODE_LOTSIZE);
	   double MinLots=MarketInfo(symbol,MODE_MINLOT);
	   double MaxLots=MarketInfo(symbol,MODE_MAXLOT);
	   double TickValue=MarketInfo(symbol,MODE_TICKVALUE);
	   
	        if (mode=="equity")     {size=(value/100)*AccountEquity()/LotSize;}
	   else if (mode=="balance")    {size=(value/100)*AccountBalance()/LotSize;}
	   else if (mode=="freemargin") {size=(value/100)*AccountFreeMargin()/LotSize;}
	   else if (mode=="equityRisk") {size=((value/100)*AccountEquity())/(sl*TickValue*PipValue(symbol));}
	   else if (mode=="balanceRisk") {size=((value/100)*AccountBalance())/(sl*TickValue*PipValue(symbol));}
	   else if (mode=="freemarginRisk") {size=((value/100)*AccountFreeMargin())/(sl*TickValue*PipValue(symbol));}
	   else if (mode=="fixed" || mode=="lots") {size=value;}
	
	   if (size>MaxLots) {size=size/LotSize;}
	
	   double stepsize=0;
	   while(size+0.000000001>stepsize){stepsize+=LotStep;}
	   size=stepsize-LotStep;
	   
	   if (align=="align") {
	      if (size<MinLots) {size=MinLots;}
	      if (size>MaxLots) {size=MaxLots;}
	   }
	   
	   return (size);
	}
	
	double SymbolAsk(string symbol="")
	{
	   if (symbol=="") {symbol=GetSymbol();}
	   return(MarketInfo(symbol,MODE_ASK));
	}
	
	double AlignLots(double lots)
	{
		string symbol=GetSymbol();
	
	   double LotStep=MarketInfo(symbol,MODE_LOTSTEP);
	   double LotSize=MarketInfo(symbol,MODE_LOTSIZE);
	   double MinLots=MarketInfo(symbol,MODE_MINLOT);
	   double MaxLots=MarketInfo(symbol,MODE_MAXLOT);
	   
	   if (lots>MaxLots) {lots=lots/LotSize;}
	   
	   double stepsize=0;
	   while(lots+0.000000001>stepsize){stepsize+=LotStep;}
	   lots=stepsize-LotStep;
	   
	   if (lots<MinLots) {lots=MinLots;}
	   if (lots>MaxLots) {lots=MaxLots;}
	   
	   return (lots);
	}
	
	int BuyNow(double lots,double sl,double tp,double slippage=0,int magic=0,string comment="",color arrowcolor=CLR_NONE)
	{
	   if(IsTradeContextBusy()) {while(true){Sleep(1); if(!IsTradeContextBusy()) {break;}}}
	   
	   string symbol=GetSymbol();
	   int time0=GetTickCount();
	   int ticket=-1; bool ECNmodified=true;
	   slippage=slippage*PipValue();
	   
	   double ask=MarketInfo(symbol,MODE_ASK);
	   double digits=MarketInfo(symbol,MODE_DIGITS);
	
	   sl=NormalizeDouble(sl,digits);
	   tp=NormalizeDouble(tp,digits);
	   
	   lots=AlignLots(lots);
	   
	   if (sl<0 || (sl>0 && sl>ask)) {Print("Cannot open Buy trade when SL("+DoubleToStr(sl,digits)+") > Open price("+DoubleToStr(ask,digits)+") price."); return(-1);}
	   if (tp<0 || (tp>0 && tp<ask)) {Print("Cannot open Buy trade when TP("+DoubleToStr(tp,digits)+") < Open price("+DoubleToStr(ask,digits)+") price."); return(-1);}
	   
	   if (IsBrokerECN()==false) {
	      if (USE_VIRTUAL_STOPS=="yes") {
	         // determine sizes
	         double vsl=sl;
	         double vtp=tp;
	         if (USE_EMERGENCY_STOPS=="no" || (EMERGENCY_STOPS_REL<=0 && EMERGENCY_STOPS_ADD<=0)) {sl=0; tp=0;}
	         if (sl>0 || USE_EMERGENCY_STOPS=="always") sl=ask-EMERGENCY_STOPS_REL*(ask-sl); sl=sl-toDigits(EMERGENCY_STOPS_ADD,symbol);
	         if (tp>0 || USE_EMERGENCY_STOPS=="always") tp=ask+EMERGENCY_STOPS_REL*(tp-ask); tp=tp+toDigits(EMERGENCY_STOPS_ADD,symbol);
	         // sending...
	         ticket=OrderSend(symbol,OP_BUY,lots,ask,slippage,sl,tp,comment,magic,0,arrowcolor);
	         if (ticket>-1) VirtualStopsDriver("set",ticket,vsl,vtp,toPips(ask-vsl,symbol),toPips(vtp-ask,symbol));
	      }
	      else {
	         ticket=OrderSend(symbol,OP_BUY,lots,ask,slippage,sl,tp,comment,magic,0,arrowcolor);  
	      }
	   }
	   if (IsBrokerECN()!=false || ticket==-1)  {
	      ticket=OrderSend(symbol,OP_BUY,lots,ask,slippage, 0, 0,comment,magic,0,arrowcolor);
	      if (ticket>-1 && (sl!=0 || tp!=0)) {
	         ECNmodified=ModifyStops(ticket,sl,tp,CLR_NONE);
	         if (IsBrokerECN()==false && ECNmodified==true) {
	            IsBrokerECN(true); Print("ECN/STP broker detected. ECN/STP mode turned ON.");
	         }
	      }
	   }
	   if (ticket>-1 && ECNmodified==false) {Alert("New trade #"+ticket+" opened successfully, but failed to modify it's hard stops!");}
	   if (ticket==-1) {Print("Buy Error: "+ErrorMessage());}
	   if (ticket>-1) {
	      if (OrderSelect(ticket,SELECT_BY_TICKET)) {
	         double slip=toPips(OrderOpenPrice()-ask,symbol);
	         if (!IsTesting() && !IsVisualMode()) Print("Operation details: Speed "+(GetTickCount()-time0)+" ms | Slippage "+DoubleToStr(slip,1)+" pips");
	      }
	      RegisterEvent("trade");
	   }
	   return(ticket);
	}
	
	void StringExplode(string sDelimiter, string sExplode, string &sReturn[]){
	   int ilBegin = -1,ilEnd = 0;
	   int ilElement=0;
	   while (ilEnd != -1){
	      ilEnd = StringFind(sExplode, sDelimiter, ilBegin+1);
	      ArrayResize(sReturn,ilElement+1);
	      sReturn[ilElement] = "";     
	      if (ilEnd == -1){
	         if (ilBegin+1 != StringLen(sExplode)){
	            sReturn[ilElement] = StringSubstr(sExplode, ilBegin+1, StringLen(sExplode));
	         }
	      } else { 
	         if (ilBegin+1 != ilEnd){
	            sReturn[ilElement] = StringSubstr(sExplode, ilBegin+1, ilEnd-ilBegin-1);
	         }
	      }      
	      ilBegin = StringFind(sExplode, sDelimiter,ilEnd);  
	      ilElement++;    
	   }
	}
	
	int TicksFromStart(string cmd="read")
	{
	   static int ticks=0;
	   if (cmd=="update") {ticks++; if (ticks<0) ticks=0;}
	   return(ticks);
	}
	
	int ArraySearchS(string array[], string value)
	{
	   bool founded=false;
	   int index;
	   int size=ArraySize(array);
	   if (size>0)
	   {
	      for (int i=0; i<size; i++) {
	         if (array[i]==value) {
	            founded=true;
	            index=i;
	            break;
	         }  
	   	}
	   }
	   if (founded==true) {return (index);} else {return (-1);}
	}
	
	bool ArrayValueS(string &array[], string value)
	{
	   bool founded=false;
	   int size=ArraySize(array);
	   for (int i=0; i<size; i++) {
	      if (array[i]==value) {founded=true; break;}
	   }
	   if (founded==false) {
	      ArrayResize(array,size+1);
	      array[size]=value;
	      return (true);
	   } else {
	      return (false);  
	   }
	}
	
	double SymbolBid(string symbol="")
	{
	   if (symbol=="") {symbol=GetSymbol();}
	   return(MarketInfo(symbol,MODE_BID));
	}
	
	int SellNow(double lots,double sl,double tp,double slippage=0,int magic=0,string comment="",color arrowcolor=CLR_NONE)
	{
	   if(IsTradeContextBusy()) {while(true){Sleep(1); if(!IsTradeContextBusy()) {break;}}}
	   
	   string symbol=GetSymbol();
	   int time0=GetTickCount();
	   int ticket=-1; bool ECNmodified=true;
	   slippage=slippage*PipValue();
	
	   double bid=MarketInfo(symbol,MODE_BID);
	   double digits=MarketInfo(symbol,MODE_DIGITS);
	 
	   sl=NormalizeDouble(sl,digits);
	   tp=NormalizeDouble(tp,digits);
	   
	   if (sl<0 || (sl>0 && sl<bid)) {Print("Cannot open Sell trade when SL("+DoubleToStr(sl,digits)+") < Open price("+DoubleToStr(bid,digits)+") price."); return(-1);}
	   if (tp<0 || (tp>0 && tp>bid)) {Print("Cannot open Sell trade when TP("+DoubleToStr(tp,digits)+") > Open price("+DoubleToStr(bid,digits)+") price."); return(-1);}
	   
	   lots=AlignLots(lots);
	   
	   if (IsBrokerECN()==false) {
	      if (USE_VIRTUAL_STOPS=="yes") {
	         // determine sizes
	         double vsl=sl;
	         double vtp=tp;
	         if (USE_EMERGENCY_STOPS=="no" || (EMERGENCY_STOPS_REL<=0 && EMERGENCY_STOPS_ADD<=0)) {sl=0; tp=0;}
	         if (sl>0 || USE_EMERGENCY_STOPS=="always") sl=bid+EMERGENCY_STOPS_REL*(sl-bid); sl=sl+toDigits(EMERGENCY_STOPS_ADD,symbol);
	         if (tp>0 || USE_EMERGENCY_STOPS=="always") tp=bid-EMERGENCY_STOPS_REL*(bid-tp); tp=tp-toDigits(EMERGENCY_STOPS_ADD,symbol);
	         // sending...
	         ticket=OrderSend(symbol,OP_SELL,lots,bid,slippage,sl,tp,comment,magic,0,arrowcolor);
	         if (ticket>-1) VirtualStopsDriver("set",ticket,vsl,vtp,toPips(bid+vsl,symbol),toPips(vtp-bid,symbol));
	      }
	      else {
	         ticket=OrderSend(symbol,OP_SELL,lots,bid,slippage,sl,tp,comment,magic,0,arrowcolor);  
	      }
	   }
	   if (IsBrokerECN()!=false || ticket==-1)  {
	      ticket=OrderSend(symbol,OP_SELL,lots,bid,slippage, 0, 0,comment,magic,0,arrowcolor);
	      if (ticket>-1 && (sl!=0 || tp!=0)) {
	         ECNmodified=ModifyStops(ticket,sl,tp,CLR_NONE);
	         if (IsBrokerECN()==false && ECNmodified==true) {
	            IsBrokerECN(true); Print("ECN/STP broker detected. ECN/STP mode turned ON.");
	         }
	      }
	   }
	   if (ticket>-1 && ECNmodified==false) {Alert("New trade opened successfully, but failed to modify its stops!");}
	   if (ticket==-1) {Print("Sell Error: "+ErrorMessage());}
	   if (ticket>-1) {
	      if (OrderSelect(ticket,SELECT_BY_TICKET)) {
	         double slip=toPips(bid-OrderOpenPrice(),symbol);
	         if (!IsTesting() && !IsVisualMode()) Print("Operation details: Speed "+(GetTickCount()-time0)+" ms | Slippage "+DoubleToStr(slip,1)+" pips");
	      }
	      RegisterEvent("trade");
	   }
	   return(ticket);
	}
	
	void EventsListener(string action="listen",string command="")
	{
	   ///////
	   // Define used variables
	   int i=-1, j=-1, k=-1; int ti=-1;
	   int size=-1;
	   static int start_time=-1;
	   static double tt0=0;
	   static double ask0=0;
	   static double bid0=0;
	   static bool initial_pass=false;
	   static int history_total=0;
	   static int history_total_checked=0;
	   static int shorts_hist_count=0;
	   static int longs_hist_count=0;
	   
	   //-- Virtual stops
	   static string vs_memory_id[];
	   static double vs_memory_sl[];
	   static double vs_memory_tp[];
	   int vs_id;
	   
	   int pos=0;
	   
	   // Define used variables
	   ///////
	   
	   // Event: Timer
	   if (ENABLE_EVENT_TIMER==1)
	   {
	      static double t0=0; // old time
	      if (!TimerStopped()) {
	         double t; // will be current time
	         double tx;
	         static double tx0;
	         bool milli=false;
	         if (TimerPeriod()>=1 || (TimerPeriod()<0 && EVENT_TIMER_PERIOD>0) || IsTesting() || IsVisualMode()) {t=TimeLocal();} else {t=GetTickCount(); milli=true;}
	         if (TimerPeriod()>=0) {tx=TimerPeriod();} else {tx=EVENT_TIMER_PERIOD;}
	         if (milli==true) {tx=tx*1000;}
	         if (tx!=tx0) {t0=0;}
	      
	         if (t>=t0+tx) {t0=t; tx0=tx; EventTimer();}
	      }
	   }
	   
	   // Endless loop (only in case of EA running on Demo or Real)
	   bool loop_it=true;
	   while(loop_it==true && !IsStopped() && (IsTesting() || IsVisualMode() || IsExpertEnabled())) {
	      if (initial_pass==true && !IsTesting()) {DrawEPSMeter();}
	   
	      //////
	      // in case of testing - make it to pass once
	      if (IsStopped() || IsTesting() || IsVisualMode() || EVENTS_MODE=="tick" || action=="register") {loop_it=false;}
	      //////
	      
	      //////
	      // in case of Script - pass 1st tick and start looping on 2'nd tick
	      if (initial_pass==false) {loop_it=false; initial_pass=true;}
	      //////
	      
	      //-- Event: EventTick()
	      if (ENABLE_EVENT_TICK==1)
	      {
	         if (action=="listen") {
	            if (EVENTS_MODE!="tick") {
	               string market_for_ticks=Symbol();
	               if (SIMULATE_TICKS==1) {market_for_ticks=SIMULATE_TICKS_MARKET;}
	               double ask=MarketInfo(market_for_ticks,MODE_ASK);
	               double bid=MarketInfo(market_for_ticks,MODE_BID);
	               double tt=MarketInfo(market_for_ticks,MODE_TIME);
	            }
	            if ((EVENTS_MODE=="tick" || (tt!=tt0 || ask!=ask0 || bid!=bid0))) {tt0=tt; ask0=ask; bid0=bid;
	               VirtualStopsDriver("listen"); // will work only if this is used: #define USE_VIRTUAL_STOPS "yes"
	               EventTick();
	            }
	         }
	      }
	      
	      //-- Event: EventTrade()
	      if (ENABLE_EVENT_TRADE==1)
	      {
	         if (start_time==-1) {start_time=TimeCurrent();}
	         bool e=false;
	      
	         ///////
	         // HISTORY TRADES
	         /*
	         int total=OrdersHistoryTotal();
	         if (total!=history_total) {
	            history_total=total;
	            for (pos=total-1; pos>=0; pos--) {
	               if (OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY)) {
	                  if (OrderOpenTime()>=start_time) {
	                     if (history_total>history_total_checked) {
	                        history_total_checked++;
	                     
	                        if (OrderType()==OP_BUY) {longs_hist_count++;}
	                        if (OrderType()==OP_SELL) {shorts_hist_count++;}
	                     
	                     }
	                  } else {break;}
	               }
	            }
	         }
	         */
	         // HISTORY TRADES
	         ///////
	      
	         ///////
	         // TRADES AND ORDERS
	         int tickets_now[]; ArrayResize(tickets_now,0);
	         int tn=0;
	         static int    memory_ti[];
	         static double memory_sl[];
	         static double memory_tp[];
	         static double memory_vl[];
	         static bool loaded=false;
	         
	         static int total_trades0=0; int total_trades=OrdersTotal();
	         
	         // Load memory_ti with current trades if started now or EA reloaded
	         if (loaded==false) {loaded=true;
	           for (pos=total_trades-1; pos>=0; pos--) {
	              if (OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) {
	                 ArrayResize(memory_ti,tn+1);
	                 ArrayResize(memory_sl,tn+1);
	                 ArrayResize(memory_tp,tn+1);
	                 ArrayResize(memory_vl,tn+1);
	                 memory_ti[tn]=OrderTicket();
	                 memory_sl[tn]=attrStopLoss();
	                 memory_tp[tn]=attrTakeProfit();
	                 memory_vl[tn]=attrLots();
	                 
	                 tn++;
	               }
	            }
	         }
	         tn=0;
	         
	         for (pos=total_trades-1; pos>=0; pos--) {
	            if (OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) {
	               //if (OrderOpenTime()>=start_time) {
	                  ArrayResize(tickets_now,tn+1);
	                  tickets_now[tn]=OrderTicket();
	                  tn++;
	               
	                  // Trades and Orders
	                  // 1. Add new trade to memory, if not inside
	                  i=-1; ti=-1; size=ArraySize(memory_ti); if (size>0){for (i=0; i<size; i++) {if (memory_ti[i]==OrderTicket()) {ti=OrderTicket(); break;}}}
	                  
	                  if (ti<0) {
	                    ArrayResize(memory_ti,size+1); memory_ti[size]=attrTicket();
	                    ArrayResize(memory_sl,size+1); memory_sl[size]=attrStopLoss();
	                    ArrayResize(memory_tp,size+1); memory_tp[size]=attrTakeProfit();
	                    ArrayResize(memory_vl,size+1); memory_vl[size]=attrLots();
	                    //if (OrderOpenTime()>=start_time) {
	                        UpdateEventValues("Trade","new",""); EventTrade();
	                    //}
	                  }
	                  
	                  // 2. Check for SL or TP modification
	                  else if (i>-1) {
	                    e=false;
	                    if (memory_sl[i]!=attrStopLoss())   {memory_sl[i]=attrStopLoss(); e=true; UpdateEventValues("Trade","modify","sl");}
	                    if (memory_tp[i]!=attrTakeProfit()) {memory_tp[i]=attrTakeProfit(); if (e==true) {UpdateEventValues("Trade","modify","sltp");} else {e=true; UpdateEventValues("Trade","modify","tp");}}
	                    if (e==true) {EventTrade(); e=false;}
	                    if (memory_vl[i]!=attrLots())       {memory_vl[i]=attrLots(); e=true; UpdateEventValues("Trade","modify","lots");}
	                  }
	               //} else {break;}
	            }
	         }
	      
	         // There are closed orders/trades
	         bool missing=true;
	         
	         if (ArraySize(tickets_now)<ArraySize(memory_ti))
	         {
	            for(i=ArraySize(memory_ti)-1; i>=0; i--) { // for each ticket in the memory...
	               for(j=0; j<=ArraySize(tickets_now); j++) { // check if trade exists now
	                  if (memory_ti[i]==tickets_now[j]) {missing=false; break;}
	               }
	               if (missing==true) {
	                  if (OrderSelect(memory_ti[i],SELECT_BY_TICKET))
	                  {
	                     // This can happen more than once
	                     ArrayStripKeyI(memory_ti,i);
	                     ArrayStripKey(memory_sl,i);
	                     ArrayStripKey(memory_tp,i);
	                     ArrayStripKey(memory_vl,i);
	                     ObjectDelete("#"+OrderTicket()+" sl");
	                     ObjectDelete("#"+OrderTicket()+" tp");
	                     UpdateEventValues("Trade","closed","");
	                     EventTrade(); e=false;
	                  }
	               }
	               missing=true;
	            }
	            //ArrayIntersectI(memory_ti,tickets_now); // Remove closed orders from memory
	         }
	         // TRADES AND ORDERS
	         ///////
	      }
	      /*
	      int obj_total=ObjectsTotal();
	      string name;
	      for(i=0;i<obj_total;i++)
	      {
	         name=ObjectName(i);
	         //Print(i,"Object name for object #",i," is " + name);
	         //Print(ObjectGetValueByShift(name, 0));
	
	      }
	      */
	
	      if (loop_it==true) {Sleep(EVENTS_CYCLE_PERIOD);} // Endless loop resolution
	   }
	}
	
	void UpdateEventValues(string e_type="",string e_reason="",string e_detail="")
	{
	   e_Reason(e_reason);
	   e_ReasonDetail("set",e_detail);
	   if (e_type=="Trade" || e_type=="EventTrade") {
	      e_attrClosePrice ("set",attrClosePrice());
	      e_attrComment    ("set",attrComment());
	      e_attrCommission ("set",attrCommission());
	      e_attrExpiration ("set",attrExpiration());
	      e_attrLots       ("set",attrLots());
	      e_attrMagicNumber("set",attrMagicNumber());
	      e_attrOpenPrice  ("set",attrOpenPrice());
	      e_attrProfit     ("set",attrProfit());
	      e_attrStopLoss   ("set",attrStopLoss());
	      e_attrSymbol     ("set",attrSymbol());
	      e_attrTakeProfit ("set",attrTakeProfit());
	      e_attrTicket     ("set",attrTicket());
	      e_attrType       ("set",attrType());
	   }
	}
	
	string DrawStatus(string text)
	{
	   static string memory;
	   if (text=="getCurrentStatus") {return(memory);}
	   
	   int strlen=StringLen(text);
	   string rect1; for (int i=1; i<=strlen; i++) {rect1=rect1+"g";}
		int x=340; int y=0;
	   string name;
	
	   static bool draw_status1=true;
	   if (draw_status1==true) {draw_status1=false;
	      name="StatusTitle";
	      if (ObjectFind(name)==-1) {
	         ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	         ObjectSet      (name, OBJPROP_BACK, false);
	         ObjectSet      (name, OBJPROP_XDISTANCE, x);
	         ObjectSet      (name, OBJPROP_YDISTANCE, y);
	         ObjectSetText  (name, "Status", 7, "Arial", Gray);
	      }
	   }
	   
	   if (text!=memory) {memory=text;
	      name="StatusText";
	      if (ObjectFind(name)==-1) {
	         ObjectCreate   (name, OBJ_LABEL, 0, 0, 0);
	         ObjectSet      (name, OBJPROP_BACK, false);
	         ObjectSet      (name, OBJPROP_XDISTANCE, x+2);
	         ObjectSet      (name, OBJPROP_YDISTANCE, y+8);
	      }
	      ObjectSetText  (name, text, 12, "Arial", LightBlue);
	   }
	   return(text);
	}

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| FUNCTIONS, CALLED FROM FUNCTIONS                                      |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////
	
	string GetSymbol(string symbol="")
	{
	   static string memory="";
	   if (memory=="") {memory=Symbol();}
	   if (symbol=="") {return(memory);}
	   if (symbol!="") {memory=symbol; return(memory);}
	   return(Symbol());
	}
	
	double toDigits(double pips,string symbol="")
	{
		if (symbol=="") {symbol=GetSymbol();}
	   return(
	      NormalizeDouble(
	         pips*PipValue()*MarketInfo(symbol,MODE_POINT),
	         MarketInfo(symbol,MODE_DIGITS)
	      )
	   );
	}
	
	int PipValue(string symbol="")
	{
	   if (symbol=="") {symbol=Symbol();}
	   int digits=MarketInfo(symbol,MODE_DIGITS);
	   if ((digits==2 || digits==4)) {return(POINT_FORMAT/0.0001);}
	   if ((digits==3 || digits==5)) {return(POINT_FORMAT/0.00001);}
	   if ((digits==6))              {return(POINT_FORMAT/0.000001);}
	   return(1);
	}
	
	bool IsBrokerECN(bool set=false)
	{
		static bool memory=false;
	   if (set==true) {memory=true;}
	   return(memory);
	}
	
	double VirtualStopsDriver(string command="", int ti=-1, double sl=0, double tp=0, double slp=0, double tpp=0)
	{
	   int i, ii=-1, size;
	   //static int    mem_ti[];
	   //static double mem_sl[];
	   //static double mem_tp[];
	   //static double mem_vl[];
	   if (USE_VIRTUAL_STOPS!="yes") {return;} // Virtual stops are not enabled => stop here
	   
	   // Set SL and TP
	   if ((command=="set" || command=="modify" || command=="clear" || command=="partial") && ti>-1)
	   {
	      // update record (add/modify)
	      string name="";
	      name="#"+ti+" sl";
	      if (sl>0) {
	         if (ObjectFind(name)==-1) {
	            ObjectCreate(name,OBJ_HLINE,0,0,sl);
	            ObjectSet(name,OBJPROP_WIDTH,1);
	            ObjectSet(name,OBJPROP_COLOR,DeepPink);
	            ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);
	            ObjectSetText(name,name+" (virtual)");
	         }
	         else {ObjectSet(name,OBJPROP_PRICE1,sl);}
	      } else {ObjectDelete(name);}
	      name="#"+ti+" tp";
	      if (tp>0) {
	         if (ObjectFind(name)==-1) {
	            ObjectCreate(name,OBJ_HLINE,0,0,tp);
	            ObjectSet(name,OBJPROP_WIDTH,1);
	            ObjectSet(name,OBJPROP_COLOR,DodgerBlue);
	            ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);
	            ObjectSetText(name,name+" (virtual)");
	         }
	         else {ObjectSet(name,OBJPROP_PRICE1,tp);}
	      } else {ObjectDelete(name);}
	      // print message
	      if (command=="set" || command=="modify") Print(command+" #"+ti+": virtual sl "+DoubleToStr(sl,Digits)+" tp "+DoubleToStr(tp,Digits));
	      return(1);
	   }
	   
	   // Get SL or TP
	   if ((command=="get sl" || command=="get tp") && ti>-1)
	   {
	      if (command=="get sl") return(ObjectGet("#"+ti+" sl",OBJPROP_PRICE1));
	      else if (command=="get tp") return(ObjectGet("#"+ti+" tp",OBJPROP_PRICE1));
	      return(0);
	   }
	   
	   // Listen trades/orders
	   if (command=="" || command=="listen")
	   {
	      for (int pos=0; pos<OrdersTotal(); pos++) {
	         if (OrderSelect(pos,SELECT_BY_POS)) {
	            // check SL and TP
	            double sl_lvl=ObjectGet("#"+OrderTicket()+" sl",OBJPROP_PRICE1);
	            double tp_lvl=ObjectGet("#"+OrderTicket()+" tp",OBJPROP_PRICE1);
	            // close trade/order
	            if (OrderType()==OP_BUY) {
	               double bid=MarketInfo(OrderSymbol(),MODE_BID);
	               if ((sl_lvl>0 && bid<=sl_lvl) || (tp_lvl>0 && bid>=tp_lvl)) {
	                  if (OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,CLR_NONE))
	                  {
	                     ObjectDelete("#"+OrderTicket()+" sl");
	                     ObjectDelete("#"+OrderTicket()+" tp");
	                  }
	                  return;
	               }
	            }
	            else if (OrderType()==OP_SELL) {
	               double ask=MarketInfo(OrderSymbol(),MODE_ASK);
	               if ((sl_lvl>0 && ask>=sl_lvl) || (tp_lvl>0 && ask<=tp_lvl)) {
	                  if (OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,CLR_NONE))
	                  {
	                     ObjectDelete("#"+OrderTicket()+" sl");
	                     ObjectDelete("#"+OrderTicket()+" tp");
	                  }
	                  return;
	               }
	            }
	         }
	      }
	   }
	   return(1);
	}
	
	bool ModifyStops(int ticket, double sl=-1, double tp=-1, color clr=CLR_NONE)
	{
	   int time0=GetTickCount();
	   bool success=false;
	   if (OrderSelect(ticket,SELECT_BY_TICKET)) {
	   	if (USE_VIRTUAL_STOPS=="yes" && (sl!=attrStopLoss() || tp!=attrTakeProfit())) {
	         // modify virtual stops
	         VirtualStopsDriver("modify",ticket,sl,tp);
	         // modify hard stops (if needed)
	         if (USE_EMERGENCY_STOPS!="no" && (EMERGENCY_STOPS_REL>0 || EMERGENCY_STOPS_ADD>0)) {
	            double sl_dist=NormalizeDouble(EMERGENCY_STOPS_REL*MathAbs(OrderOpenPrice()-sl),SymbolDigits(OrderSymbol()));
	            double tp_dist=NormalizeDouble(EMERGENCY_STOPS_REL*MathAbs(OrderOpenPrice()-tp),SymbolDigits(OrderSymbol()));
	            if (IsOrderTypeBuy()) {
	               sl=OrderOpenPrice()-sl_dist-toDigits(EMERGENCY_STOPS_ADD,OrderSymbol());
	               tp=OrderOpenPrice()+tp_dist+toDigits(EMERGENCY_STOPS_ADD,OrderSymbol());
	            } else {
	               sl=OrderOpenPrice()+sl_dist+toDigits(EMERGENCY_STOPS_ADD,OrderSymbol());
	               tp=OrderOpenPrice()-tp_dist-toDigits(EMERGENCY_STOPS_ADD,OrderSymbol());
	            }
	            if (sl<0) {sl=attrStopLoss();}
	            if (tp<0) {tp=attrTakeProfit();}
	            success=OrderModify(ticket,OrderOpenPrice(),sl,tp,OrderExpiration(),clr);
	            if (success==true) {
	               if (!IsTesting() && !IsVisualMode()) Print("Operation details: Speed "+(GetTickCount()-time0)+" ms");
	               RegisterEvent("trade");
	            }
	            return(success);
	         }
	   	}
	      else if (USE_VIRTUAL_STOPS=="no" && (sl!=OrderStopLoss() || tp!=OrderTakeProfit())) {
	         if(IsTradeContextBusy()) {while(true){Sleep(1); if(!IsTradeContextBusy()) {break;}}}
	         
	         // modify stops
	         if (sl<0) {sl=attrStopLoss();}
	         if (tp<0) {tp=attrTakeProfit();}
	         success=OrderModify(ticket,OrderOpenPrice(),sl,tp,OrderExpiration(),clr);
	         if (success==true) {
	            if (!IsTesting() && !IsVisualMode()) Print("Operation details: Speed "+(GetTickCount()-time0)+" ms");
	            RegisterEvent("trade");
	         }
	         return(success);
	      }
	   } else {Print("Cannot modify stops for #"+ticket+". This trade/order does not exists.");}
	}
	
	string ErrorMessage(int error_code=0)
	{
	   if (error_code<=0) {error_code=GetLastError();}
	   string error_string;
	//----
	   switch(error_code)
	     {
	      //---- codes returned from trade server
	      case 0:
	      case 1:   error_string="No error returned"; break;
	      case 2:   error_string="Common error"; break;
	      case 3:   error_string="Invalid trade parameters"; break;
	      case 4:   error_string="Trade server is busy"; break;
	      case 5:   error_string="Old version of the client terminal"; break;
	      case 6:   error_string="No connection with trade server"; break;
	      case 7:   error_string="Not enough rights"; break;
	      case 8:   error_string="Too frequent requests"; break;
	      case 9:   error_string="Malfunctional trade operation (never returned error)"; break;
	      case 64:  error_string="Account disabled"; break;
	      case 65:  error_string="Invalid account"; break;
	      case 128: error_string="Trade timeout"; break;
	      case 129: error_string="Invalid price"; break;
	      case 130: error_string="Invalid stops"; break;
	      case 131: error_string="Invalid trade volume"; break;
	      case 132: error_string="Market is closed"; break;
	      case 133: error_string="Trade is disabled"; break;
	      case 134: error_string="Not enough money"; break;
	      case 135: error_string="Price changed"; break;
	      case 136: error_string="Off quotes"; break;
	      case 137: error_string="Broker is busy (never returned error)"; break;
	      case 138: error_string="Requote"; break;
	      case 139: error_string="Order is locked"; break;
	      case 140: error_string="Only long trades allowed"; break;
	      case 141: error_string="Too many requests"; break;
	      case 145: error_string="Modification denied because order too close to market"; break;
	      case 146: error_string="Trade context is busy"; break;
	      case 147: error_string="Expirations are denied by broker"; break;
	      case 148: error_string="Amount of open and pending orders has reached the limit"; break;
	      case 149: error_string="Hedging is prohibited"; break;
	      case 150: error_string="Prohibited by FIFO rules"; break;
	      //---- mql4 errors
	      case 4000: error_string="No error"; break;
	      case 4001: error_string="Wrong function pointer"; break;
	      case 4002: error_string="Array index is out of range"; break;
	      case 4003: error_string="No memory for function call stack"; break;
	      case 4004: error_string="Recursive stack overflow"; break;
	      case 4005: error_string="Not enough stack for parameter"; break;
	      case 4006: error_string="No memory for parameter string"; break;
	      case 4007: error_string="No memory for temp string"; break;
	      case 4008: error_string="Not initialized string"; break;
	      case 4009: error_string="Not initialized string in array"; break;
	      case 4010: error_string="No memory for array string"; break;
	      case 4011: error_string="Too long string"; break;
	      case 4012: error_string="Remainder from zero divide"; break;
	      case 4013: error_string="Zero divide"; break;
	      case 4014: error_string="Unknown command"; break;
	      case 4015: error_string="Wrong jump"; break;
	      case 4016: error_string="Not initialized array"; break;
	      case 4017: error_string="dll calls are not allowed"; break;
	      case 4018: error_string="Cannot load library"; break;
	      case 4019: error_string="Cannot call function"; break;
	      case 4020: error_string="Expert function calls are not allowed"; break;
	      case 4021: error_string="Not enough memory for temp string returned from function"; break;
	      case 4022: error_string="System is busy"; break;
	      case 4050: error_string="Invalid function parameters count"; break;
	      case 4051: error_string="Invalid function parameter value"; break;
	      case 4052: error_string="String function internal error"; break;
	      case 4053: error_string="Some array error"; break;
	      case 4054: error_string="Incorrect series array using"; break;
	      case 4055: error_string="Custom indicator error"; break;
	      case 4056: error_string="Arrays are incompatible"; break;
	      case 4057: error_string="Global variables processing error"; break;
	      case 4058: error_string="Global variable not found"; break;
	      case 4059: error_string="Function is not allowed in testing mode"; break;
	      case 4060: error_string="Function is not confirmed"; break;
	      case 4061: error_string="Send mail error"; break;
	      case 4062: error_string="String parameter expected"; break;
	      case 4063: error_string="Integer parameter expected"; break;
	      case 4064: error_string="Double parameter expected"; break;
	      case 4065: error_string="Array as parameter expected"; break;
	      case 4066: error_string="Requested history data in update state"; break;
	      case 4099: error_string="End of file"; break;
	      case 4100: error_string="Some file error"; break;
	      case 4101: error_string="Wrong file name"; break;
	      case 4102: error_string="Too many opened files"; break;
	      case 4103: error_string="Cannot open file"; break;
	      case 4104: error_string="Incompatible access to a file"; break;
	      case 4105: error_string="No order selected"; break;
	      case 4106: error_string="Unknown symbol"; break;
	      case 4107: error_string="Invalid price parameter for trade function"; break;
	      case 4108: error_string="Invalid ticket"; break;
	      case 4109: error_string="Trade is not allowed in the expert properties"; break;
	      case 4110: error_string="Longs are not allowed in the expert properties"; break;
	      case 4111: error_string="Shorts are not allowed in the expert properties"; break;
	      case 4200: error_string="Object is already exist"; break;
	      case 4201: error_string="Unknown object property"; break;
	      case 4202: error_string="Object is not exist"; break;
	      case 4203: error_string="Unknown object type"; break;
	      case 4204: error_string="No object name"; break;
	      case 4205: error_string="Object coordinates error"; break;
	      case 4206: error_string="No specified subwindow"; break;
	      case 4207: error_string="Some error in object function"; break;
	      default:   error_string="Unknown error";
	     }
	//----
	   if (error_code>0) {Print("("+error_code+") "+error_string);}
	   return(error_code);
	  }
	
	void RegisterEvent(string command="")
	{
		EventsListener("register",command);
	   return;
	}
	
	bool TimerStopped() {if (TimerStop(-1)==1) {return(true);} return(false);}
	
	double TimerPeriod(double t=-1) {static double time=-1; if (t>=0){time=t;} if (t>-1){TimerStop(0);} return(time);}
	
	void DrawEPSMeter()
	{
	   static int frames=0;
	   static int frame=0;
	   static int eps=0;
	   static int time0=0;
	   static int direction=0;
	   
	   int tl=TimeLocal();
	   if (tl>time0) {
	      time0=tl; eps=frame; frame=0;
	      int x=0; int y=0;
	      string name="fxdreema_eps_meter";
	      if (ObjectFind(name)==-1) {
	         ObjectDelete(name);
	         ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
	         ObjectSet   (name, OBJPROP_CORNER, 3);
	         ObjectSet   (name, OBJPROP_XDISTANCE, x+1);
	         ObjectSet   (name, OBJPROP_YDISTANCE, y+1);
	      }
	      ObjectSetText(name, "Events per second: "+eps, 10, "Arial", DarkSeaGreen);
	   } else {
	   frame++; frames++;
	   }
	   
	   /*
	   if (direction==0) {
	      
	      if (frames==20) {Comment(fps,"fps |");}
	      if (frames==40) {Comment(fps,"fps ||");}
	      if (frames==60) {Comment(fps,"fps |||");}
	         if (frames==80) {Comment(fps,"fps ||||");}
	         if (frames==100) {Comment(fps,"fps |||||");}
	         if (frames==120) {Comment(fps,"fps ||||||");}
	         if (frames==140) {Comment(fps,"fps |||||||");}
	         if (frames==160) {Comment(fps,"fps ||||||||");}
	         if (frames==180) {Comment(fps,"fps |||||||||");}
	         if (frames==200) {Comment(fps,"fps ||||||||||"); frames=0; direction=1;}
	      }
	      if (direction==1) {
	         if (frames==20)  {Comment(fps+"fps ||||||||||");}
	         if (frames==40)  {Comment(fps+"fps |||||||||");}
	         if (frames==60)  {Comment(fps+"fps ||||||||");}
	         if (frames==80)  {Comment(fps+"fps |||||||");}
	         if (frames==100) {Comment(fps+"fps ||||||");}
	         if (frames==120) {Comment(fps+"fps |||||");}
	         if (frames==140) {Comment(fps+"fps ||||");}
	         if (frames==160) {Comment(fps+"fps |||");}
	         if (frames==180) {Comment(fps+"fps ||");}
	         if (frames==200) {Comment(fps+"fps |"); frames=0; direction=0;}
	      }
	      */
	}
	
	double attrStopLoss(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrStopLoss());}
	   if (USE_VIRTUAL_STOPS=="yes" && sel=="") {return(VirtualStopsDriver("get sl",OrderTicket()));}
	   return(OrderStopLoss());
	}
	
	double attrTakeProfit(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrTakeProfit());}
	   if (USE_VIRTUAL_STOPS=="yes" && sel=="") {return(VirtualStopsDriver("get tp",OrderTicket()));}
	   return(OrderTakeProfit());
	}
	
	double attrLots(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrLots());}
	   return(OrderLots());
	}
	
	int attrTicket(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrTicket());}
	   return(OrderTicket());
	}
	
	bool ArrayStripKeyI(int &array[], int key)
	{
	   bool stripped=false;
	   int size=ArraySize(array);
	   if (size>0)
	   {
	      int i=0; int x=0;
	      for (i=0; i<size; i++)
	      {
	         if (i!=key)
	         {
	            array[x]=array[i];
	            x++;
	         } else {
	            stripped=true;  
	         }
	      }
	      ArrayResize(array,x);
	   }
	   return (stripped);
	}
	
	bool ArrayStripKey(double &array[], double key)
	{
	   bool stripped=false;
	   int size=ArraySize(array);
	   if (size>0)
	   {
	      int i=0; int x=0;
	      for (i=0; i<size; i++)
	      {
	         if (i!=key)
	         {
	            array[x]=array[i];
	            x++;
	         } else {
	            stripped=true;  
	         }
	      }
	      ArrayResize(array,x);
	   }
	   return (stripped);
	}
	
	string e_Reason(string inp="") {static string mem; if(inp!=""){mem=inp;} return(mem);}
	
	string e_ReasonDetail(string cmd="", string inp="") {static string mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	double e_attrClosePrice(string cmd="", double inp=-1) {static double mem=-1; if(cmd=="set"){mem=inp;} return(mem);}
	
	double attrClosePrice(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrClosePrice());}
	   return(OrderClosePrice());
	}
	
	string e_attrComment(string cmd="", string inp="") {static string mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	string attrComment(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrComment());}
	   return(OrderComment());
	}
	
	double e_attrCommission(string cmd="", double inp=0) {static double mem=0; if(cmd=="set"){mem=inp;} return(mem);}
	
	double attrCommission(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrCommission());}
	   return(OrderCommission());
	}
	
	datetime e_attrExpiration(string cmd="", datetime inp=0) {static datetime mem=0; if(cmd=="set"){mem=inp;} return(mem);}
	
	datetime attrExpiration(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrExpiration());}
	   return(OrderExpiration());
	}
	
	double e_attrLots(string cmd="",double inp=-1) {static double mem=-1; if(cmd=="set"){mem=inp;} return(mem);}
	
	int e_attrMagicNumber(string cmd="", int inp=-1) {static int mem=-1; if(cmd=="set"){mem=inp;} return(mem);}
	
	int attrMagicNumber(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrMagicNumber());}
	   return(OrderMagicNumber());
	}
	
	double e_attrOpenPrice(string cmd="", double inp=-1) {static double mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	double attrOpenPrice(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrOpenPrice());}
	   return(OrderOpenPrice());
	}
	
	double e_attrProfit(string cmd="", double inp=0) {static double mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	double attrProfit(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrProfit());}
	   return(OrderProfit());
	}
	
	double e_attrStopLoss(string cmd="", double inp=-1) {static double mem=-1; if(cmd=="set"){mem=inp;} return(mem);}
	
	string e_attrSymbol(string cmd="", string inp="") {static string mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	string attrSymbol(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrSymbol());}
	   return(OrderSymbol());
	}
	
	double e_attrTakeProfit(string cmd="", double inp=-1) {
	   static double mem=-1;
	   static double pips=0;
	   double price;
	   if(cmd=="pipsFromHere"){
	      if (e_attrTakeProfit()>0) {
	         if (e_attrType()==OP_BUY || e_attrType()==OP_BUYSTOP || e_attrType()==OP_BUYLIMIT)
	         {
	            price=SymbolAsk(e_attrSymbol());
	            pips=toPips(MathAbs(price-e_attrTakeProfit()),e_attrSymbol());
	         }
	         else
	         {
	            price=SymbolBid(e_attrSymbol());
	            pips=toPips(MathAbs(price-e_attrTakeProfit()),e_attrSymbol());
	         }
	      }
	   }
	   if(cmd=="set"){mem=inp;}
	   return(mem);
	}
	
	int e_attrTicket(string cmd="", int inp=-1) {static int mem=-1; if(cmd=="set"){mem=inp;} return(mem);}
	
	int e_attrType(string cmd="", int inp=-1) {static int mem; if(cmd=="set"){mem=inp;} return(mem);}
	
	double attrType(string sel="")
	{
	   if (sel=="e" || sel=="event") {return(e_attrType());}
	   return(OrderType());
	}
	
	int SymbolDigits(string symbol="")
	{
	   if (symbol=="") {symbol=GetSymbol();}
	   return(MarketInfo(symbol,MODE_DIGITS));
	}
	
	bool IsOrderTypeBuy() {
	   if (
	   OrderType()==OP_BUY
	   ||
	   OrderType()==OP_BUYSTOP
	   ||
	   OrderType()==OP_BUYLIMIT
	   ) {return(true);}
	   return(false);
	}
	
	int TimerStop(int s=1) {static int stopped=0; if (s==0 || s==1){stopped=s;} return(stopped);}

/////////////////////////////////////////////////////////////////////////////
//+-----------------------------------------------------------------------+//
//| PERMANENT FUNCTIONS                                                   |//
//+-----------------------------------------------------------------------+//
/////////////////////////////////////////////////////////////////////////////


string ListOfIDsConnectedToMe(string src) {
	static bool passed=false;
	static string ids[7];
	static string lst[7];
	if (passed==false) {passed=true;
		ids[0]="2";lst[0]="1";
		ids[1]="7";lst[1]="2";
		ids[2]="3";lst[2]="7";
		ids[3]="6";lst[3]="3";
		ids[4]="4";lst[4]="6";
		ids[5]="5";lst[5]="4";
		ids[6]="8";lst[6]="4";
	}
	if (src!="") {
		int i=0; int maxi=ArraySize(ids); for (i=0; i<maxi; i++) {if (ids[i]==src) {return(lst[i]); break;}}
	}
	return("");
}
void DrawSpreadInfo() {
	static bool allow_draw=true;
	if (allow_draw==false) {return;}
	if ((IsTesting()/*||IsVisualMode()*/)) {if (allow_draw==true) {allow_draw=false;}} // Allowed to draw only once in testing mode
	
	double pip_value=0;
	int digits=MarketInfo(Symbol(),MODE_DIGITS);
	if ((digits==2 || digits==4)) {pip_value=(POINT_FORMAT/0.0001);}
	if ((digits==3 || digits==5)) {pip_value=(POINT_FORMAT/0.00001);}
	if ((digits==6))              {pip_value=(POINT_FORMAT/0.000001);}
	   
   static double max_spread=0;
   static double min_spread=0;
   static double avg_spread=0;
   static double avg_add=0;
   static double avg_cnt=0;
   double current_spread=(MarketInfo(Symbol(),MODE_ASK)-MarketInfo(Symbol(),MODE_BID))/(pip_value*MarketInfo(Symbol(),MODE_POINT));
   if (current_spread>max_spread) {max_spread=current_spread;}
   if (current_spread<min_spread || min_spread==0) {min_spread=current_spread;}
   avg_add=avg_add+current_spread; avg_cnt++;
   avg_spread=avg_add/avg_cnt;
   
   int x=0; int y=0;
   string name="current_spread";
   if (ObjectFind(name)==-1) {
	  ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
	  ObjectSet   (name, OBJPROP_CORNER, 2);
	  ObjectSet   (name, OBJPROP_XDISTANCE, x+1);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+1);
   }
   ObjectSetText(name, "Spread: "+DoubleToStr(current_spread,2), 18, "Arial", DarkOrange);
   
   name="max_spread_label";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+148);
      ObjectSet   (name, OBJPROP_YDISTANCE, x+17);
	  ObjectSetText(name, "max:", 7, "Arial", OrangeRed);
   }
   name="max_spread";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+173);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+17);
   }
   ObjectSetText(name, DoubleToStr(max_spread,2), 7, "Arial", OrangeRed);
   
   name="avg_spread_label";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+148);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+9);
	  ObjectSetText(name, "avg:", 7, "Arial", DarkOrange);
   }
   name="avg_spread";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+173);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+9);
   }
   ObjectSetText(name, DoubleToStr(avg_spread,2), 7, "Arial", DarkOrange);
   
   name="min_spread_label";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+148);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+1);
	  ObjectSetText(name, "min:", 7, "Arial", Gold);
   }
   name="min_spread";
   if (ObjectFind(name)==-1) {
      ObjectCreate(name, OBJ_LABEL, 0, 0, 0);
      ObjectSet   (name, OBJPROP_CORNER, 2);
      ObjectSet   (name, OBJPROP_XDISTANCE, x+173);
      ObjectSet   (name, OBJPROP_YDISTANCE, y+1);
   }
   ObjectSetText(name, DoubleToStr(min_spread,2), 7, "Arial", Gold);
}
//+------------------------------------------------------------------+
//| END                                                              |
//| Created with fxDreema EA Builder            http://fxdreema.com/ |
//+------------------------------------------------------------------+

/*<fxdreema:eNrtWntv4jgQ/ypVPsAqb2h6OolSdrcSjx50q7u/Ijcx1NcQR3agy5363W/8SEggKaK3ZbdS/yrMjMfz+NkzHoqCTvAvD7qBwXGek3TBjQsU2JYgWnZgZIz+jaM8TNESGxdA8wJjtiJrchbjszu0WGEuySAa0RgnKF2s0EKKuoEx+mPoSrYVGDHKcRgxDH+MCxJYjntunZ/7pl/lL2lM5hvF90zXdEyvq/lLtCBRyHPEcq3dthyr0H6f0OiRi/XKzMAw5V8zMHCUhveMPmJmXNwHJlBtoMY4F34pRhiTBcl5wbc6gbFgKHsIKSM4zVFOaFrsdEuzW3pJ85wuJckPDBTlZA3OURAlqdhH2ndLokfxEaJprAkn9wkOE3LPENuEC0ZXmWDCcr7hOVbKnMDIyRIM4hi0xVxEwjd1gGmKw4xkISf/YL3U/GSapgoC2LziOFwTlq9QAoGimUwNLEyplDhXEhj0L3AabVpkdvghw0ktpA0iKI5rIvABryFw24S4wjEVDqlAcaNNBDHJMCM0lkkXbBDlZLlKBB7EGl5VLWJZ54ZLxB5xrgMy+Db9NrsyLp45ANt4ImlMnySkuwLRJckSpHONfEW6vhIqqhIcJAzwbzKfc7EB2GebGlQJnudbesc0lXQbBIClM6+2EU6O6STDKY4nLMaMa/sFjLEMJmyiVxII1IprvGkymB0TjgBScRW1GWJwUHPQB2ikLOblkmpA7IPe203e22az975zpPfwvQ/oJsWxOpXfzkG/nSa/Hb/Zb7f7Tvx2D/rtNvnttaDdcd+J395Bv70mv/0WnNvH5hv8vFxtxvTplE77B532m5x23RaQH321gYohhVqNkt746pSedw563mm81rrNnnv+u/G8e9Dz7jFAPzrnsM0MJ8kpkP6sDN5KtBR3T5CgnWqs69DvPA3b67Bgj4tWZUzPcoag2yX8jK3SFHrkQmFfu6O7SqDclFuLHkhpnEU0kz2QJ7pK3fZt2V8UaayJs83yniblGvAAJYmO6uyv0eVkuJWFy4VPmIg81wm6p/mDClK92Pst0bBr0di9p8s47DKqzpe5LP13xGa2OAvlNzB+TpNYAQlWRyiNE1xYPScJ3mfsp1kGFqJIJl+HfR0T0k8oxxpLfblan8bAsHbiVkXj7fVo8HnaGw12nwv9yXQ66N9eT8Y10Anb6BLsKd4Xv2ufpy1eCl0QY7gNcsp2PYVUkFGv2cuuPsejXtEYS3nLNHWMRj3+QOZ51XApDioelLj4OrkahDO9B5jZy7KE4PiGkQgXALyZXvcHYX84mQ2OjZR4Bn69/nxbjXRr9DQcZ/CQWqn3pU4kTel8XlXryncg2o18pX1rQ7LzM5D8Yo7hI5n1ps1Jlm6AxCzHmRaGt5xdZBh9hzfOUmfe/GS/aXoawP3bAXC/wyP8g0DovgRC95cEYe/qz+ZkyNEPGAMC26sGdrLcI26NjlxfGbxYpwbr/7qJf0KA7Pdw2Xql/w0492o4rz1zSpB3JPUsVeSXIW6b9ZbpS9EmacGmYIkA3NFktcQjHVpPZPW7aju33JmelsmL1KrzpoQ/ap79ySsmcIp3g1mE07xefeWgsqq3CW9gxxolK7yDtCp5H2qWztJdIVLYKzteW1QKmg0p54W3ghZvUrQk0RCv9YyuIndD1GyvYrwYeyYF/31XtEPtmvQ1e9nXH5YnGd9y1/gUu6rZ73Zj8ThDj/iG0TnJGw9ETaIAh7jLzBJNyVbgLW1XV1iB6zg7za61PIl949Psu5MpaHFmCcky/SMJxKKYvY02fbpc6itHzRLShXp7FjdTjzH61KcJZXC1arMu5T7P6m56mmFhjjq7CNiqdeBWbYYOBLtaSwTB2SW42yU/qKT4L73L/fq7fG+UUtYVEYbx1YEnONST573RUNvWnTfduvtSIe3Wtq6PUcptu4r8UUo/SulHKf0opR+l9MhSKqaqD5TllVrqVmupuFy1W1OR4V+2lmrDIpqm
OBLDg+0jVfz/hVnGXqIVJ7G+Ma4Gn3vfhrfFvxvQFYvw/lAcWDliC/VTenVC/KzUW69Wb7er75Tq7Ver77Srd0r1zqvVO+3q/VK9+2r1frt6t1TvvVq9267eK9X7jeph1fX4bjB9nfZu2f3h73Ci0+34r/7ThKXhq6Y3xTe8HWsXk5f98YQ8OvuluK5jW+2Us9hqu8P3urY31O+W+svJXl1tfer03BQiq0Fub16u21H1Yx7PUZrzgiypa8SI+P2tpD7/B4AnfQQ=
:fxdreema>*/