//__________________________________________________________
// This program is PUBLIC DOMAIN
// This program has NO Copyright
// The writer		:  Sergiy Podolyak
//	Write date		:  2010-2016
// http://www.graalino.com
// File        	:  OBz-Trading-Lib.mq4
// Description		:	Library of trading functions from the
//							trend-following experts "Ocean Breeze"
// Version     	:  1.92
// Version Date	:  21 Aug 2016
// Project     	:  MT4 trading
// Start Date  	:  May 2010
//_______________________________________________________________________________
//_______________________________________________________________________________
//_______________________________________________________________________________
#property library
// But You can just include any this function into your project, not as a library as a whole
//...................................................................................
// next is needed for calling "ErrorDescription" function
#include <stdlib.mq4>
//...................................................................................

#define		TRADING_OK_LEVEL								                  0
#define 		TRADING_POS_SIZE_LESS_MIN_LOT				                  (-100)
#define 		TRADING_ERROR_NOT_ENOUGH_MONEY			                  (-200)
#define 		TRADING_ERROR_OPENING_BUY					                  (-300)
#define 		TRADING_ERROR_OPENING_SELL					                  (-400)
#define 		TRADING_ERROR_CLOSING_BUY					                  (-500)
#define 		TRADING_ERROR_CLOSING_SELL					                  (-600)
#define 		TRADING_ERROR_BUY_MODIFY					                  (-700)
#define 		TRADING_ERROR_SELL_MODIFY					                  (-800)
#define 		TRADING_ERROR_TERMINAL						                  (-900)
//...............................................................................
//_____________________________/ Extremum situations \______________________________
#define 		TREND_MINIMUM									                  10100

#define 		TREND_DOWN										                  10200
#define 		TREND_DOWN_IN_CHANNEL						                  10300

#define 		TREND_FLAT										                  10400

#define 		TREND_UP											                  10500
#define 		TREND_UP_IN_CHANNEL							                  10600

#define 		TREND_MAXIMUM									                  10700
//...................................................................................
#define 		TRADING_TIMEOUT_MSEC							                  1000
//...............................................................................

#define 		TRADING_BUY_ORDER_OPENED					                  9400
#define 		TRADING_SELL_ORDER_OPENED					                  9500
#define 		TRADING_BUY_ORDER_CLOSED					                  9600
#define 		TRADING_SELL_ORDER_CLOSED					                  9700
//...............................................................................
#define		THERE_WERE_NO_ORDERS													-1000
//................................................................................
#define		FIND_SL_STRING_1														"[sl]"
#define		FIND_SL_STRING_2														"[Sl]"
#define		FIND_SL_STRING_3														"[sL]"
#define		FIND_SL_STRING_4														"[SL]"

#define		FIND_TP_STRING_1														"[tp]"
#define		FIND_TP_STRING_2														"[Tp]"
#define		FIND_TP_STRING_3														"[tP]"
#define		FIND_TP_STRING_4														"[TP]"

//_______________________________________________________________________________
//																	|
// 			Check_Situation_To_Close_Pos ()			|
//_________________________________________________|
int Check_Situation_To_Close_Pos
(
   string 	Bond_Name,
   int	 	Situation
)
{
	int 		i, j;
	int 		Last_Error;
	bool 		Result ;
	int 		Retries;
	int 		Curr_Slippage;
	int 		Action_Done;
	bool 		Is_Trade_Context_Free;
	int 		Ticket;
	//....................................................................................
	Action_Done = TRADING_OK_LEVEL;
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		Action_Done = TRADING_ERROR_TERMINAL;
		return (Action_Done);
	}
	//....................................................................................
	Retries = 5;
	Curr_Slippage =  (int) ( 3.0 * MathMax (1.0, MarketInfo (Bond_Name, MODE_SPREAD) ));
	//........../ check all our orders \.............................
	for (i = 0; i < OrdersTotal (); i++)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_TRADES) == FALSE)
		{
			break;
		}
		if (OrderSymbol () != Bond_Name)
		{
			continue;
		}
		Ticket = OrderTicket ();
		//......................................................................
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
		{
			Action_Done = TRADING_ERROR_CLOSING_BUY;
			break;
		}
		//......................................................................
		if (OrderCloseTime () != 0)
		{
			continue;
		}
		//.......... if open order is BUY, LONG POSITION ............................
		if ( (OrderType () == OP_BUY)
		      &&
		      ( (Situation == TREND_MAXIMUM)
		        ||
		        (Situation == TREND_DOWN)
		        ||
		        (Situation == TREND_DOWN_IN_CHANNEL)
		      )
		   )
		{
			//..........................................
			Is_Trade_Context_Free = Wait_For_Free_Trade_Context (Retries);
			if (Is_Trade_Context_Free == FALSE)
			{
				Action_Done = TRADING_ERROR_CLOSING_BUY;
				continue; // for i = Orders
			}
			//......................................................................
			if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
			{
				Action_Done = TRADING_ERROR_CLOSING_BUY;
				continue;
			}
			//......................................................................
			if (OrderCloseTime () != 0)
			{
				continue;
			}
			//......................................................................
			RefreshRates ();
			ResetLastError ();
			Result = OrderClose (Ticket,
			                     OrderLots (),
			                     MarketInfo (Bond_Name, MODE_BID),
			                     Curr_Slippage,
			                     White);
			if (Result != TRUE)
			{
				Last_Error = GetLastError ();
				for (j = 1; j <= Retries; j++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					//......................................................................
					if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
					{
						Action_Done = TRADING_ERROR_CLOSING_BUY;
						continue;
					}
					//......................................................................
					if (OrderCloseTime () != 0)
					{
						continue;
					}
					//......................................................................
					RefreshRates ();
					ResetLastError ();
					Result = OrderClose (Ticket,
					                     OrderLots (),
					                     MarketInfo (Bond_Name, MODE_BID),
					                     Curr_Slippage,
					                     White);
					if (Result == TRUE)
					{
						Action_Done = TRADING_BUY_ORDER_CLOSED;
						break; // for j
					}
				} // for j
			}	// if (Result != TRUE)
			if (Result != TRUE)
			{
				Last_Error = GetLastError ();
				if (Last_Error != 0)
				{
					Print ("Error at broker while closing BUY order #", Ticket,
					       " Err=", Last_Error, " ", ErrorDescription (Last_Error) );
				}
				Action_Done = TRADING_ERROR_CLOSING_BUY;
				continue; // for i
			}
			Action_Done = TRADING_BUY_ORDER_CLOSED;
			continue;
		}
		//.......................... if Open order is SHORT ..........................
		if ( (OrderType () == OP_SELL)
		      &&
		      ( (Situation == TREND_MINIMUM)
		        ||
		        (Situation == TREND_UP)
		        ||
		        (Situation == TREND_UP_IN_CHANNEL)
		      )
		   )
		{
			//..........................................
			Is_Trade_Context_Free = Wait_For_Free_Trade_Context (Retries);
			if (Is_Trade_Context_Free == FALSE)
			{
				Action_Done = TRADING_ERROR_CLOSING_BUY;
				continue; // for i = Orders
			}
			//......................................................................
			if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
			{
				Action_Done = TRADING_ERROR_CLOSING_SELL;
				continue;
			}
			//......................................................................
			if (OrderCloseTime () != 0)
			{
				continue;
			}
			//......................................................................
			RefreshRates ();
			ResetLastError ();
			Result = OrderClose (Ticket,
			                     OrderLots (),
			                     MarketInfo (Bond_Name, MODE_ASK),
			                     Curr_Slippage,
			                     White);
			if (Result != TRUE)
			{
				Last_Error = GetLastError ();
				for (j = 1; j <= Retries; j++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					//......................................................................
					if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
					{
						Action_Done = TRADING_ERROR_CLOSING_SELL;
						continue;
					}
					//......................................................................
					if (OrderCloseTime () != 0)
					{
						continue;
					}
					//......................................................................
					RefreshRates ();
					ResetLastError ();
					Result = OrderClose (OrderTicket (),
					                     OrderLots (),
					                     MarketInfo (Bond_Name, MODE_ASK),
					                     Curr_Slippage,
					                     White);
					if (Result == TRUE)
					{
						Action_Done = TRADING_SELL_ORDER_CLOSED;
						break; // for j
					}
				} // for j
			}	// if (Result != TRUE)
			if (Result != TRUE)
			{
				Last_Error = GetLastError ();
				if (Last_Error != 0)
				{
					Print ("Error at broker while closing SELL order #", OrderTicket (),
					       " Err=", Last_Error, " ", ErrorDescription (Last_Error) );
				}
				Action_Done = TRADING_ERROR_CLOSING_SELL;
				continue; // for i
			}
			//Action_Done = TRADING_SELL_ORDER_CLOSED;
			continue;
		}
	}
	return (Action_Done);
}
//___________________________________________________________________
//																	|
// 			Check_Situation_To_Open_Pos ()			|
//_________________________________________________|
int Check_Situation_To_Open_Pos
(
   string 	Bond_Name,
   int	  	Situation,
   int 	 	Full_Expert_ID,
   double 	Max_Risk,
   int		Portfolio_Bonds,
   double 	Stop_Loss_Here,
   double 	Take_Profit_Here,
   bool 		Use_Adaptive_Pos_Size_Param,
   string	Order_Comment,
   bool		ECN_Mode_Param,
   double 	First_Loss_Drop_Param,
   double 	Losses_Drop_Slope_Param,
   double 	Second_Profit_Drop_Param,
   double 	Recovery_Slope_Param,
   double	Max_Drop_Param
)
{
	int 		Result_Order_Ticket ;
	double 	Pos_Size_Lots;
	double 	Daily_Volatility ;
	int 	 	Price_Digits ;
	int 		Retries = 5;
	int 		i;
	int 		Last_Error;
	double 	Last_Bid;
	double 	Last_Ask;
	double 	Curr_SL;
	double 	Curr_TP;
	double 	Curr_SL_2;
	double 	Curr_TP_2;
	int 		Curr_Slippage ;
	int	 	Action_Done;
	bool		Is_Trade_Context_Free;
	bool		Modify_Order_Result;
	int 		Time_Frame = Period ();
	//....................................................................................
	Action_Done = TRADING_OK_LEVEL;
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		Action_Done = TRADING_ERROR_TERMINAL;
		return (Action_Done);
	}
	//...........................................................................
	if (! ( (Situation == TREND_MINIMUM) || (Situation == TREND_MAXIMUM) ) )
	{
		Action_Done = TRADING_OK_LEVEL;
		return (Action_Done);
	}
	//...........................................................................
	Pos_Size_Lots = Calc_Optimal_Pos_Size (Bond_Name,
	                                       Time_Frame,
	                                       Max_Risk,
	                                       Portfolio_Bonds,
	                                       Full_Expert_ID,
	                                       Use_Adaptive_Pos_Size_Param,
	                                       First_Loss_Drop_Param,
	                                       Losses_Drop_Slope_Param,
	                                       Second_Profit_Drop_Param,
	                                       Recovery_Slope_Param,
	                                       Max_Drop_Param);
	//.................................................................
	RefreshRates ();
	//.................................................................
	if (Pos_Size_Lots < MarketInfo (Bond_Name, MODE_MINLOT) )
	{
		Action_Done = TRADING_POS_SIZE_LESS_MIN_LOT;
		return (Action_Done);
	} // Pos_Size >= MINLOT
	//.....................................................................................
	Curr_Slippage = (int) (3.0 * MathMax (1.0, MarketInfo (Bond_Name, MODE_SPREAD) ));
	Price_Digits = (int)MarketInfo (Bond_Name, MODE_DIGITS);
	Daily_Volatility = Get_Daily_Volatility (Bond_Name);
	//=====================================/ to OPEN BUY conditions \=================
	if (Situation == TREND_MINIMUM)
	{
		if ( (AccountFreeMarginCheck (Bond_Name, OP_BUY, Pos_Size_Lots) <= 0.0)
		      || (GetLastError () == ERR_NOT_ENOUGH_MONEY) )
		{
			Action_Done = TRADING_ERROR_NOT_ENOUGH_MONEY;
			return (Action_Done);
		}
		//..........................................
		Is_Trade_Context_Free = Wait_For_Free_Trade_Context (Retries);
		if (Is_Trade_Context_Free == FALSE)
		{
			Action_Done = TRADING_ERROR_OPENING_BUY;
			return (Action_Done);
		}
		//..........................................
		RefreshRates ();
		Last_Ask = MarketInfo (Bond_Name, MODE_ASK);
		Curr_SL = MarketInfo (Bond_Name, MODE_ASK) * (1.0 - Stop_Loss_Here * Daily_Volatility);
		Curr_TP = MarketInfo (Bond_Name, MODE_BID) * (1.0 + Take_Profit_Here * Daily_Volatility);
		Curr_SL_2 = Curr_SL;
		Curr_TP_2 = Curr_TP;
		if (ECN_Mode_Param == TRUE)
		{
			Curr_SL_2 = 0.0;
			Curr_TP_2 = 0.0;
		}
		ResetLastError ();
		Result_Order_Ticket = OrderSend (Bond_Name,
		                                 OP_BUY,
		                                 Pos_Size_Lots,
		                                 Last_Ask,
		                                 Curr_Slippage,
		                                 NormalizeDouble (Curr_SL_2, Price_Digits),
		                                 NormalizeDouble (Curr_TP_2, Price_Digits),
		                                 Order_Comment,
		                                 Full_Expert_ID,
		                                 0,
		                                 Green) ;
		if (Result_Order_Ticket < 0)
		{
			Last_Error = GetLastError ();
			if (Last_Error == ERR_REQUOTE)
			{
				for (i = 1; i <= Retries; i++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					RefreshRates ();
					Last_Ask = MarketInfo (Bond_Name, MODE_ASK);
					Curr_SL = MarketInfo (Bond_Name, MODE_ASK) * (1.0 - Stop_Loss_Here * Daily_Volatility);
					Curr_TP = MarketInfo (Bond_Name, MODE_BID) * (1.0 + Take_Profit_Here * Daily_Volatility);
					Curr_SL_2 = Curr_SL;
					Curr_TP_2 = Curr_TP;
					if (ECN_Mode_Param == TRUE)
					{
						Curr_SL_2 = 0.0;
						Curr_TP_2 = 0.0;
					}
					ResetLastError ();
					Result_Order_Ticket = OrderSend (Bond_Name,
					                                 OP_BUY,
					                                 Pos_Size_Lots,
					                                 Last_Ask,
					                                 Curr_Slippage,
					                                 NormalizeDouble (Curr_SL_2, Price_Digits),
					                                 NormalizeDouble (Curr_TP_2, Price_Digits),
					                                 Order_Comment,
					                                 Full_Expert_ID,
					                                 0,
					                                 Green) ;
					if (Result_Order_Ticket > 0)
					{
						break;
					}
					else
					{
						Last_Error = GetLastError ();
					}
				} // for i
			}
		}
		//......................................................
		if (Result_Order_Ticket < 0)
		{
			Last_Error = GetLastError ();
			if (Last_Error != 0)
			{
				Print ("Error at broker while opening BUY order, err #", Last_Error, " ",
				       ErrorDescription (Last_Error) );
			}
			Action_Done = TRADING_ERROR_OPENING_BUY;
			return (Action_Done);
		}
		//......................................................
		if (ECN_Mode_Param == TRUE)
		{
			Sleep (TRADING_TIMEOUT_MSEC);
			RefreshRates ();
			ResetLastError ();
			Last_Ask = MarketInfo (Bond_Name, MODE_ASK);
			Modify_Order_Result = OrderModify (Result_Order_Ticket,
			                                   Last_Ask,
			                                   NormalizeDouble (Curr_SL, Price_Digits),
			                                   NormalizeDouble (Curr_TP, Price_Digits),
			                                   0, // TimeCurrent (),
			                                   Green);
			if (Modify_Order_Result != TRUE)
			{
				for (i = 1; i <= Retries; i++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					RefreshRates ();
					Last_Ask = MarketInfo (Bond_Name, MODE_ASK);
					//......................................................................
					if (OrderSelect (Result_Order_Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
					{
						Action_Done = TRADING_ERROR_BUY_MODIFY;
						return (Action_Done);
					}
					//......................................................................
					if (OrderCloseTime () != 0)
					{
						Action_Done = TRADING_ERROR_OPENING_BUY;
						return (Action_Done);
					}
					//......................................................................
					ResetLastError ();
					Modify_Order_Result = OrderModify (Result_Order_Ticket,
					                                   Last_Ask,
					                                   NormalizeDouble (Curr_SL, Price_Digits),
					                                   NormalizeDouble (Curr_TP, Price_Digits),
					                                   0, // TimeCurrent (),
					                                   Green);
					if (Modify_Order_Result == TRUE)
					{
						break;
					}
				} // for i
				//.......................................................................
			}
			if (Modify_Order_Result != TRUE)
			{
				Action_Done = TRADING_ERROR_BUY_MODIFY;
				return (Action_Done);
			}
		}
		Action_Done = TRADING_BUY_ORDER_OPENED;
		return (Action_Done);
	} // done, if it was MINIMUM
	//===============================/ if MAXIMUM to OPEN SELL conditions: \==============
	if (Situation == TREND_MAXIMUM)
	{
		ResetLastError ();
		if ( (AccountFreeMarginCheck (Bond_Name, OP_SELL, Pos_Size_Lots) <= 0.0)
		      || (GetLastError () == ERR_NOT_ENOUGH_MONEY) )
		{
			Action_Done = TRADING_ERROR_NOT_ENOUGH_MONEY;
			return (Action_Done);
		}
		//..........................................
		Is_Trade_Context_Free = Wait_For_Free_Trade_Context (Retries);
		if (Is_Trade_Context_Free == FALSE)
		{
			Action_Done = TRADING_ERROR_OPENING_BUY;
			return (Action_Done);
		}
		//..........................................
		RefreshRates ();
		Last_Bid = MarketInfo (Bond_Name, MODE_BID);
		Curr_SL = MarketInfo (Bond_Name, MODE_BID) * (1.0 + Stop_Loss_Here * Daily_Volatility);
		Curr_TP = MarketInfo (Bond_Name, MODE_ASK) * (1.0 - Take_Profit_Here * Daily_Volatility);
		Curr_SL_2 = Curr_SL;
		Curr_TP_2 = Curr_TP;
		if (ECN_Mode_Param == TRUE)
		{
			Curr_SL_2 = 0.0;
			Curr_TP_2 = 0.0;
		}
		ResetLastError ();
		Result_Order_Ticket = OrderSend (Bond_Name,
		                                 OP_SELL,
		                                 Pos_Size_Lots,
		                                 Last_Bid,
		                                 Curr_Slippage,
		                                 NormalizeDouble (Curr_SL_2, Price_Digits),
		                                 NormalizeDouble (Curr_TP_2, Price_Digits),
		                                 Order_Comment,
		                                 Full_Expert_ID,
		                                 0,
		                                 Red) ;
		if (Result_Order_Ticket < 0)
		{
			Last_Error = GetLastError ();
			if (Last_Error == ERR_REQUOTE)
			{
				for (i = 1; i <= Retries; i++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					RefreshRates ();
					Last_Bid = MarketInfo (Bond_Name, MODE_BID);
					Curr_SL = MarketInfo (Bond_Name, MODE_BID) * (1.0 + Stop_Loss_Here * Daily_Volatility);
					Curr_TP = MarketInfo (Bond_Name, MODE_ASK) * (1.0 - Take_Profit_Here * Daily_Volatility);
					Curr_SL_2 = Curr_SL;
					Curr_TP_2 = Curr_TP;
					if (ECN_Mode_Param == TRUE)
					{
						Curr_SL_2 = 0.0;
						Curr_TP_2 = 0.0;
					}
					ResetLastError ();
					Result_Order_Ticket = OrderSend (Bond_Name,
					                                 OP_SELL,
					                                 Pos_Size_Lots,
					                                 Last_Bid,
					                                 Curr_Slippage,
					                                 NormalizeDouble (Curr_SL_2, Price_Digits),
					                                 NormalizeDouble (Curr_TP_2, Price_Digits),
					                                 Order_Comment,
					                                 Full_Expert_ID,
					                                 0,
					                                 Red) ;
					if (Result_Order_Ticket > 0)
					{
						break;
					}
					else
					{
						Last_Error = GetLastError ();
					}
				}  // for i
			}
		}
		if (Result_Order_Ticket < 0)
		{
			Last_Error = GetLastError ();
			if (Last_Error != 0)
			{
				Print ("Error at broker while opening SELL order, err #", Last_Error, " ",
				       ErrorDescription (Last_Error) );
			}
			Action_Done = TRADING_ERROR_OPENING_SELL;
			return (Action_Done);
		}
		//......................................................
		if (ECN_Mode_Param == TRUE)
		{
			Sleep (TRADING_TIMEOUT_MSEC);
			RefreshRates ();
			Last_Bid = MarketInfo (Bond_Name, MODE_BID);
			//......................................................................
			if (OrderSelect (Result_Order_Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE)
			{
				Action_Done = TRADING_ERROR_OPENING_SELL;
				return (Action_Done);
			}
			//......................................................................
			if (OrderCloseTime () != 0)
			{
				Action_Done = TRADING_ERROR_SELL_MODIFY;
				return (Action_Done);
			}
			//......................................................................
			ResetLastError ();
			Modify_Order_Result = OrderModify (Result_Order_Ticket,
			                                   Last_Bid,
			                                   NormalizeDouble (Curr_SL, Price_Digits),
			                                   NormalizeDouble (Curr_TP, Price_Digits),
			                                   TimeCurrent (),
			                                   Green);
			if (Modify_Order_Result != TRUE)
			{
				for (i = 1; i <= Retries; i++)
				{
					Sleep (TRADING_TIMEOUT_MSEC);
					RefreshRates ();
					Last_Bid = MarketInfo (Bond_Name, MODE_BID);
					ResetLastError ();
					Modify_Order_Result = OrderModify (Result_Order_Ticket,
					                                   Last_Bid,
					                                   NormalizeDouble (Curr_SL, Price_Digits),
					                                   NormalizeDouble (Curr_TP, Price_Digits),
					                                   0, // TimeCurrent (),
					                                   Green);
					if (Modify_Order_Result == TRUE)
					{
						break;
					}
				}  // for i
				if (Modify_Order_Result != TRUE)
				{
					Action_Done = TRADING_ERROR_SELL_MODIFY;
					return (Action_Done);
				}
			}
		}
		Action_Done = TRADING_SELL_ORDER_OPENED;
		return (Action_Done);
	} // done, if it was MAXIMUM
	return (Action_Done);
}
//____________________________________________________________________________________________
//																	|
// 			Calc_Optimal_Pos_Size ()		 			|
//_________________________________________________|
double Calc_Optimal_Pos_Size
(
   string 	Bond_Name,
   int		Time_Frame,
   double 	Max_Risk,
   int		Portfolio_Bonds,
   int 		Full_Expert_ID,
   bool 		Use_Adaptive_Pos_Size_Param,
   double 	First_Loss_Drop_Param,
   double 	Losses_Drop_Slope_Param,
   double 	Second_Profit_Drop_Param,
   double 	Recovery_Slope_Param,
   double	Max_Drop_Param
)
{
	double 	Pos_Size ;
	double 	Pos_Size_Portfolio;
	double 	Pos_Size_Risk;
	//.................................................................
	Pos_Size_Risk = Calc_Pos_Size_To_Risk (Bond_Name,
	                                       Max_Risk);
	Pos_Size_Portfolio = Calc_Pos_Size_To_Portfolio (Bond_Name,
	                                                 Portfolio_Bonds);
	Pos_Size = MathMin (Pos_Size_Risk, Pos_Size_Portfolio);
	// ======================= USE ADAPTIVE POS SIZE ===================================
	if (Use_Adaptive_Pos_Size_Param == TRUE)
	{
		//      Print ("Adaptive: risk init=" + DoubleToStr (Pos_Size, 4));
		Pos_Size = Adjust_Pos_Size_To_History (Pos_Size,
		                                       Bond_Name,
		                                       Full_Expert_ID,
		                                       First_Loss_Drop_Param,
		                                       Losses_Drop_Slope_Param,
		                                       Second_Profit_Drop_Param,
		                                       Recovery_Slope_Param,
		                                       Max_Drop_Param);
		//      Print ("Adaptive: out=" + DoubleToStr (Pos_Size, 4));
	}
	// ============== ADJUST POS SIZE TO BROKER's LIMITS ====================================
	//	Print ("Optim Pos size=", DoubleToStr (Pos_Size, 4));
	Pos_Size = Adjust_Pos_Size_To_Broker (Bond_Name, Pos_Size);
	return (Pos_Size) ;
}
//____________________________________________________________________________________________
//																	|
// 			Calc_Pos_Size_To_Risk   () 				|
//_________________________________________________|
double Calc_Pos_Size_To_Risk (string 	Bond_Name,
                              double 	Max_Risk)
{
	double  Equity_Drawdown;
	double  Daily_Volatility ;
	double  Pos_Size ;
	int 	  Lot_Digits ;
	double  Stop_Loss_Points;
	double  One_Point_Cost;
	double  Tick_Value ;
	double  Margin_Init ;
	double  Min_Lot_Size;
	//........................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		Pos_Size = 0.0;
		return (Pos_Size);
	}
	//........................................................................
	RefreshRates ();
	//.................................................................
	Min_Lot_Size = MarketInfo (Bond_Name, MODE_MINLOT);
	Tick_Value = MarketInfo (Bond_Name, MODE_TICKVALUE);
	Margin_Init = MarketInfo (Bond_Name, MODE_MARGININIT);
	if ((MarketInfo (Bond_Name, MODE_MARGINCALCMODE) == 2) && (Margin_Init != 0.0))
	{
		Tick_Value = Tick_Value  * MarketInfo (Bond_Name, MODE_MARGINREQUIRED) / Margin_Init;
	}
	//	Print ("Tick val=", DoubleToStr(Tick_Value, 6));
	//..........................................................................
	Equity_Drawdown = MathMin (AccountEquity (), AccountBalance () ) * Max_Risk / 100.0; //percent
	Daily_Volatility = Get_Daily_Volatility (Bond_Name) ;
	//	Print ("Daily volat=", DoubleToStr (Daily_Volatility,5));
	//..........................................................................
	Stop_Loss_Points = MarketInfo (Bond_Name, MODE_BID) * Daily_Volatility
	                   / MarketInfo (Bond_Name, MODE_POINT);
	//	Print ("Stop_Loss_Points=", DoubleToStr (Stop_Loss_Points, 2));
	//..........................................................................
	One_Point_Cost = Tick_Value / (MarketInfo (Bond_Name, MODE_TICKSIZE)
	                               / MarketInfo (Bond_Name, MODE_POINT) ) ;
	//	Print (" One_Point_Cost =", DoubleToStr (One_Point_Cost, 4));
	//..........................................................................
	if (One_Point_Cost == 0.0)
	{
		Print ("Error: One_Point_Cost=0.0: ", DoubleToStr (One_Point_Cost, 6));
		Print ("Tick_Value= ", DoubleToStr (Tick_Value, 6));
		Print ("Equity_Drawdown= ", DoubleToStr (Equity_Drawdown, 6));
		Print ("Daily_Volat= ", DoubleToStr (Daily_Volatility, 5));
		Print ("Stop_Loss_Points= ", DoubleToStr (Stop_Loss_Points, 3));
		Print ("One_Point_Cost= ", DoubleToStr (One_Point_Cost, 6));
		return (0.0);
	}
	//..........................................................................
	Pos_Size = Equity_Drawdown / (One_Point_Cost * Stop_Loss_Points);
	//..........................................................................
	if (Pos_Size < Min_Lot_Size)
	{
		Pos_Size = Min_Lot_Size;
	}
	//.............................................................................
	Lot_Digits = Get_Lot_Digits (Bond_Name);
	//	Print (" Lot_Digits =" + Lot_Digits);
	Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits);
	//	Print (" Pos_Size =", DoubleToStr (Pos_Size, 4));
	//..........................................................................
	return (Pos_Size) ;
}
//________________________________________________________________________________________
//																	|
// 			Calc_Pos_Size_To_Portfolio ()				|
//_________________________________________________|
double Calc_Pos_Size_To_Portfolio (	string 	Bond_Name,
                                    int		Portfolio_Bonds)
{
	int 	 Lot_Digits ;
	double Min_Lot_Size;
	double Max_One_Order_Margin;
	double Min_Lot_Margin;
	double Free_Margin_Check;
	double Pos_Size = 1.0;
	double Account_Free_Margin;
	//........................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		Pos_Size = 0.0;
		//Print (" MT4: no connect");
		return (Pos_Size);
	}
	//.................................................................................
	RefreshRates ();
	ResetLastError ();
	//........................................................................
	Account_Free_Margin = AccountFreeMargin ();
	//	Print ("Account_Free_Margin=", DoubleToStr (Account_Free_Margin, 2));
	//...............................................................
	Min_Lot_Size = MarketInfo (Bond_Name, MODE_MINLOT);

	Free_Margin_Check = MathMin (AccountFreeMarginCheck (Bond_Name, OP_BUY, Min_Lot_Size),
	                             AccountFreeMarginCheck (Bond_Name, OP_SELL, Min_Lot_Size) );

	//	Print ("Free_Margin_Check=", DoubleToStr (Free_Margin_Check, 2));

	Min_Lot_Margin = Account_Free_Margin - Free_Margin_Check;

	//	Print ("Min_Lot_Margin=", DoubleToStr (Min_Lot_Margin, 2));
	//............................/MT4 visual mode bug workaround \.........................
	if ( (Min_Lot_Margin < 0.0) && (IsVisualMode () == TRUE))
	{
		Min_Lot_Margin = MathAbs (Min_Lot_Margin);
	}
	//...................................................................................
	if ( (Min_Lot_Margin <= 0.0)	|| (GetLastError () == ERR_NOT_ENOUGH_MONEY) )
	{
		Pos_Size = 0.0;
		if (Get_Total_Open_Orders (Bond_Name) <= 0 )
		{
			Print ("Error: No margin:");
			Print ("Min_Lot_Margin= ", DoubleToStr (Min_Lot_Margin, 2));
			Print ("Account_Free_Margin= ", DoubleToStr (Account_Free_Margin, 2));
		}
		return (Pos_Size);
	}
	//...................................................................................
	//...................................................................................
	//...................................................................................
	Max_One_Order_Margin =  MathMin (AccountEquity (), AccountBalance ()) / Portfolio_Bonds;

	//	Print ("Max_One_Order_Margin=", DoubleToStr (Max_One_Order_Margin, 4));
	//...................................................................................
	Pos_Size = (Max_One_Order_Margin / Min_Lot_Margin) * Min_Lot_Size;
	//...............................................................
	if (Pos_Size < Min_Lot_Size)
	{
		Pos_Size = Min_Lot_Size;
	}
	//..........................................................................
	Lot_Digits = Get_Lot_Digits (Bond_Name);
	Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits);
	//.............................................................................
	return (Pos_Size) ;
}
//____________________________________________________________________________________
//																	|
// 			Adjust_Pos_Size_To_History ()	 			|
//_________________________________________________|
double Adjust_Pos_Size_To_History (	double 	Pos_Size,
                                    string 	Bond_Name,
                                    int 		Full_Expert_ID,
                                    double 	First_Loss_Drop_Param,
                                    double 	Losses_Drop_Slope_Param,
                                    double 	Second_Profit_Drop_Param,
                                    double 	Recovery_Slope_Param,
                                    double	Max_Drop_Param)
{
	double 	PL_History;     // positive profits OR negative losses
	PL_History = Calc_PL_History_Factor (Bond_Name, Full_Expert_ID);
	Pos_Size = Reduce_Pos_Size_To_PL_History (PL_History,
	                                          Pos_Size,
	                                          Bond_Name,
	                                          First_Loss_Drop_Param,
	                                          Losses_Drop_Slope_Param,
	                                          Second_Profit_Drop_Param,
	                                          Recovery_Slope_Param,
	                                          Max_Drop_Param);
	return (Pos_Size) ;
}
//__________________________________________________________________________________________
//																	|
// 			Calc_PL_History_Factor ()					|
//_________________________________________________|
double Calc_PL_History_Factor (string 	Bond_Name,
                               int 		Full_Expert_ID)
{
	double 	Curr_Order_Profit ;
	int 	 	i;
	double	PL_History;     // positive profits OR negative losses
	//........................................................................
	PL_History = 0.0;
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (PL_History);
	}
	//........................................................................
	RefreshRates ();
	//.................................................................
	for (i = 0 ; i < OrdersHistoryTotal (); i++)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) == FALSE)
		{
			Print ("Error in history!");
			break;
		}
		//.................................................................
		if ( (OrderSymbol () != Bond_Name) ||
		      ( (OrderType () != OP_BUY) && (OrderType () != OP_SELL) )
		      //|| (OrderMagicNumber () != Full_Expert_ID)
		   )
		{
			continue;
		}
		//........................................
		Curr_Order_Profit = OrderProfit ();
		if (PL_History == 0.0)     // got only profits or first in the list
		{
			if (Curr_Order_Profit > 0.0)
			{
				continue;
			}
			if (Curr_Order_Profit <= 0.0)
			{
				PL_History = -1.0;
				continue;
			}
		}
		//.........../ was in a recovery, PL_History is positive \...............
		if (PL_History > 0)
		{
			if (Curr_Order_Profit > 0.0)
			{
				PL_History ++;
				continue;
			}
			else
			{
				PL_History = -1.0;
				continue;
			}
		}
		//......../ older was losses, count only newer losses ..........................
		if (PL_History < 0)
		{
			if (Curr_Order_Profit > 0.0)
			{
				PL_History = +1.0; // this is a recovery
				continue;
			}
			else
			{
				PL_History --;
				continue;
			}
		}
		//..................................................
	}		// "for" loop
	//..................................................
	return (PL_History);
}
//_____________________________________________________________________________________
//																	|
// 		Reduce_Pos_Size_To_PL_History ()				|
//_________________________________________________|
double Reduce_Pos_Size_To_PL_History (double 	PL_History,
                                      double 	Pos_Size,
                                      string 	Bond_Name,
                                      double		First_Loss_Drop_Param,
                                      double		Losses_Drop_Slope_Param,
                                      double		Second_Profit_Drop_Param,
                                      double		Recovery_Slope_Param,
                                      double 	Max_Drop_Param)
{
	int 	 	Lot_Digits ;
	double   Min_Lot_Size;
	double 	Scale_Factor;
	//........................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Pos_Size);
	}
	//.................................................................................
	RefreshRates ();
	//.................................................................
	Min_Lot_Size = MarketInfo (Bond_Name, MODE_MINLOT);
	if (Pos_Size < Min_Lot_Size)
	{
		return (Pos_Size);
	}
	//........................................................................
	if (PL_History == 0.0)
	{
		return (Pos_Size);
	}
	// .......................... got LOSSES, start decreasing size ..................
	Scale_Factor = 1.0;
	//...................................
	if (PL_History < 0.0)
	{
		Scale_Factor = MathMax (1.0,
		                        First_Loss_Drop_Param + MathAbs (PL_History * Losses_Drop_Slope_Param + 1.0)) ;
	}
	//....................... got profits, but under RECOVERY .........................
	if ( PL_History > 0.0)
	{
		Scale_Factor = MathMax (1.0, Second_Profit_Drop_Param - PL_History * Recovery_Slope_Param + 1.0);
	}
	//...............................................................
	Max_Drop_Param = MathMax (Max_Drop_Param, 1.0);
	Scale_Factor = MathMin (Max_Drop_Param, Scale_Factor);
	Scale_Factor = 1.0 / Scale_Factor;
	Scale_Factor = MathMin (1.0, Scale_Factor);
	//...............................................................
	Pos_Size = Pos_Size * Scale_Factor;
	if (Pos_Size < Min_Lot_Size)
	{
		Pos_Size = Min_Lot_Size;
	}
	//...............................................................
	Lot_Digits = Get_Lot_Digits (Bond_Name);
	Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits) ;
	//...............................................................
	return (Pos_Size) ;
}
//________________________________________________________________________________________
//																	|
// 			Adjust_Pos_Size_To_Broker ()				|
//_________________________________________________|
double Adjust_Pos_Size_To_Broker (string Bond_Name,
                                  double Pos_Size)
{
	double Min_Lot_Size;
	double Max_Lot_Size;
	int Lot_Digits;
	//........................................................................
	if (Pos_Size <= 0)
	{
		Pos_Size = 0.0;
		return (Pos_Size) ;
	}
	//...........................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Pos_Size);
	}
	//....................................................
	//	Print (" broker: Pos_Size =", DoubleToStr (Pos_Size, 4));
	Lot_Digits = Get_Lot_Digits (Bond_Name);
	Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits);
	//.................................................................
	RefreshRates ();
	//.................................................................
	Max_Lot_Size = MarketInfo (Bond_Name, MODE_MAXLOT);
	if (Pos_Size > Max_Lot_Size)
	{
		Pos_Size = Max_Lot_Size ;
		Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits);
		return (Pos_Size) ;
	}
	//...............................................................
	Min_Lot_Size = MarketInfo (Bond_Name, MODE_MINLOT);
	if (Pos_Size < Min_Lot_Size)
	{
		Pos_Size = Min_Lot_Size;
	}
	//...............................................................
	Lot_Digits = Get_Lot_Digits (Bond_Name);
	Pos_Size = NormalizeDouble (Pos_Size, Lot_Digits) ;
	//...............................................................
	//	Print (" broker out :Pos_Size =", DoubleToStr (Pos_Size, 4));
	return (Pos_Size) ;
}
//____________________________________________________________________________________________
//																	|
// 			Get_Total_Open_Orders	()			 		|
//_________________________________________________|
int Get_Total_Open_Orders (string 	Bond_Name)
{
	int Our_Buys;
	int Our_Sells;
	int i;
	int Ticket;
	//...........................................................
	Our_Buys = 0 ;
	Our_Sells = 0 ;
	//...........................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (0);
	}
	//.................................................................
	RefreshRates ();
	//.................................................................
	for (i = 0 ; i < OrdersTotal (); i++)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_TRADES) == FALSE)
		{
			break ;
		}
		Ticket = OrderTicket ();
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_TRADES) == FALSE) continue;

		if (OrderSymbol () == Bond_Name)
		{
			if (OrderType () == OP_BUY)
			{
				Our_Buys ++ ;
			}
			if (OrderType () == OP_SELL)
			{
				Our_Sells ++ ;
			}
		}
	}
	//..........return number of orders
	return (Our_Buys + Our_Sells);
}
//______________________________________________________________________________________
//																	|
// 		Get_Daily_Volatility ()							|
//_________________________________________________|
double Get_Daily_Volatility
(
   string Bond_Name
)
{
	double Daily_Volatility = 2.0 ;
	int Margin_Calc_Mode = (int) MarketInfo (Bond_Name, MODE_MARGINCALCMODE);
	switch (Margin_Calc_Mode )
	{
		case 0:
			Daily_Volatility = 2.0 ; 	// Forex, 2.0% per day
			break;
		case 1:
			Daily_Volatility = 2.0 ;	// CFD shares, 2.0% per day
			break;
		case 2:
			Daily_Volatility = 2.0 ; 	// Futures, 2% per day
			break;
		case 3:
			Daily_Volatility = 2.0 ;	// CFD Indexes, 2.0% per day
			break;
		default:
			Daily_Volatility = 2.0 ; 	// default = metals/CFD, 2.0% per day
			break;
	}
	return (Daily_Volatility / 100.0);
}
//______________________________________________________________________________________
//																								|
// 			Get_Lot_Digits() 															|
//______________________________________________________________________|
int Get_Lot_Digits
(
   string Bond_Name
)
{
	double min_lottep ;
	int Lot_Digits;
	min_lottep = MarketInfo (Bond_Name, MODE_LOTSTEP);
	Lot_Digits =  0;
	if (min_lottep < 1.0)
	{
		Lot_Digits = 1;
	}
	if (min_lottep < 0.1)
	{
		Lot_Digits = 2;
	}
	if (min_lottep < 0.01)
	{
		Lot_Digits = 3;
	}
	if (min_lottep < 0.001)
	{
		Lot_Digits = 4;
	}
	if (min_lottep < 0.0001)
	{
		Lot_Digits = 5;
	}
	if (min_lottep < 0.00001)
	{
		Lot_Digits = 6;
	}
	return (Lot_Digits);
}
//____________________________________________________________________________________________
//																	|
// 			Get_Tick_Value_In_Depo_Money ()			|
//_________________________________________________|
double Get_Tick_Value_In_Depo_Money (string Bond_Name)
{
	double Tick_Value = MarketInfo (Bond_Name, MODE_TICKVALUE);
	double Margin_Init = MarketInfo (Bond_Name, MODE_MARGININIT);
	if (Margin_Init != 0.0)
	{
		Tick_Value = Tick_Value
		             * MarketInfo (Bond_Name, MODE_MARGINREQUIRED) / Margin_Init;
	}
	return (Tick_Value);
}
//_______________________________________________________________________________
//																	|
// 			Wait_For_Free_Trade_Context ()			|
//_________________________________________________|
bool Wait_For_Free_Trade_Context (int Retries)
{
	int j;
	bool Ret_Value;
	//...........................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (FALSE);
	}
	//....................................................
	//..........................................
	for (j = 1; j <= Retries; j++)
	{
		if (IsTradeContextBusy () == TRUE)
		{
			Sleep (TRADING_TIMEOUT_MSEC);
			RefreshRates ();
		}
		else
		{
			break;
		}
	} // for j
	//..........................................
	Ret_Value = ! (IsTradeContextBusy () );
	return (Ret_Value);
}
//_______________________________________________________________________________
//																	|
// 			Last_Trade_Was_Stop_Loss ()				|
//_________________________________________________|
int Last_Trade_Was_Stop_Loss
(
   string	Bond_Name,
   int 		Expert_ID,
   int	 	Orders_Limit
)
{
	int 		i;
	int		Result = THERE_WERE_NO_ORDERS;
	int 		Ticket;
	string 	Order_Comment = "";
	//......................................................................
	string 	Find_SL_1 = FIND_SL_STRING_1;
	string 	Find_SL_2 = FIND_SL_STRING_2;
	string 	Find_SL_3 = FIND_SL_STRING_3;
	string 	Find_SL_4 = FIND_SL_STRING_4;
	//......................................................................
	int 		Position = -1;
	//....................................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Result);
	}
	//....................../ check all our orders \......................................
	if (OrdersHistoryTotal () <= 0)
	{
		Result = THERE_WERE_NO_ORDERS;
		return (Result);
	}
	//.......................................................
	//	for (i = 0; i < OrdersHistoryTotal (); i++)
	for (i = OrdersHistoryTotal () - 1; i >= 0 ; i--)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		Ticket = OrderTicket ();
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		if (OrderCloseTime () == 0)
		{
			continue;
		}
		//......................................................................
		if (OrderSymbol () != Bond_Name)
		{
			continue;
		}
		//......................................................................
		Order_Comment = OrderComment ();
		//......................................................................
		Position = StringFind (Order_Comment, Find_SL_1, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_SL_2, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_SL_3, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_SL_4, 0);
		if (Position < 0)
		{
			Result = FALSE;
			break;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
	}
	//......................................................................
	//Print ("SL: result=", Result);
	return (Result);
}
//_______________________________________________________________________________
//																	|
// 			Last_Trade_Was_Take_Profit ()				|
//_________________________________________________|
int Last_Trade_Was_Take_Profit
(
   string	Bond_Name,
   int 		Expert_ID,
   int	 	Orders_Limit
)
{
	int 		i;
	int		Result = THERE_WERE_NO_ORDERS;
	int 		Ticket;
	string 	Order_Comment = "";
	//......................................................................
	string 	Find_TP_1 = FIND_TP_STRING_1;
	string 	Find_TP_2 = FIND_TP_STRING_2;
	string 	Find_TP_3 = FIND_TP_STRING_3;
	string 	Find_TP_4 = FIND_TP_STRING_4;
	//......................................................................
	int 		Position = -1;
	//....................................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Result);
	}
	//....................../ check all our orders \......................................
	if (OrdersHistoryTotal () <= 0)
	{
		Result = THERE_WERE_NO_ORDERS;
		return (Result);
	}
	//.......................................................
	for (i = OrdersHistoryTotal () - 1; i >= 0 ; i--)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		Ticket = OrderTicket ();
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		if (OrderCloseTime () == 0)
		{
			continue;
		}
		//......................................................................
		if (OrderSymbol () != Bond_Name)
		{
			continue;
		}
		//......................................................................
		Order_Comment = OrderComment ();
		//Print ("TP:i=", i, " of =", OrdersHistoryTotal (), " Ticket=", Ticket, " Comment=", Order_Comment);
		//......................................................................
		Position = StringFind (Order_Comment, Find_TP_1, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_TP_2, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_TP_3, 0);
		if (Position < 0)
		{
			Result = FALSE;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
		Position = StringFind (Order_Comment, Find_TP_4, 0);
		if (Position < 0)
		{
			Result = FALSE;
			break;
		}
		else
		{
			Result = TRUE;
			break;
		}
		//......................................................................
	}
	//......................................................................
	//......................................................................
	//Print ("TP: result=", Result);
	return (Result);
}
//_______________________________________________________________________________
//																	|
// 			Last_Trade_Was_Long ()						|
//_________________________________________________|
int Last_Trade_Was_Long
(
   string	Bond_Name,
   int 		Expert_ID,
   int	 	Orders_Limit
)
{
	int 		i;
	int		Result = THERE_WERE_NO_ORDERS;
	int 		Ticket;
	//....................................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Result);
	}
	//....................../ check all our orders \......................................
	//	for (i = 0; i < OrdersHistoryTotal (); i++)
	for (i = OrdersHistoryTotal () - 1; i >= 0 ; i--)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		Ticket = OrderTicket ();
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_HISTORY) == FALSE) continue;
		//......................................................................
		if (OrderCloseTime () == 0)
		{
			continue;
		}
		//......................................................................
		//Order_Comment = OrderComment ();
		//Print("i=", i, " of =", OrdersHistoryTotal (), " Ticket=", Ticket, " Comment=", Order_Comment);
		//......................................................................
		if (OrderSymbol () != Bond_Name)
		{
			continue;
		}
		//......................................................................
		if (OrderType () == OP_BUY)
		{
			Result = TRUE;
			break;
		}
		if (OrderType () == OP_BUYLIMIT)
		{
			Result = TRUE;
			break;
		}
		if (OrderType () == OP_BUYSTOP)
		{
			Result = TRUE;
			break;
		}
		//......................................................................
	} // for (i < OrdersTotal)
	//......................................................................
	return (Result);
}
//_______________________________________________________________________________
//																	|
// 			Last_Trade_Was_Short ()						|
//_________________________________________________|
int Last_Trade_Was_Short
(
   string	Bond_Name,
   int 		Expert_ID,
   int	 	Orders_Limit
)
{
	int 		i;
	int		Result = THERE_WERE_NO_ORDERS;
	int 		Ticket;
	//....................................................................................
	if (TerminalInfoInteger (TERMINAL_CONNECTED) != TRUE )
	{
		return (Result);
	}
	//....................../ check all our orders \......................................
	for (i = 0; i < OrdersHistoryTotal (); i++)
	{
		if (OrderSelect (i, SELECT_BY_POS, MODE_HISTORY) == FALSE)
		{
			continue;
		}
		//......................................................................
		Ticket = OrderTicket ();
		if (OrderSelect (Ticket, SELECT_BY_TICKET, MODE_HISTORY) == FALSE) continue;
		//......................................................................
		if (OrderCloseTime () == 0)
		{
			continue;
		}
		//......................................................................
		if (OrderSymbol () != Bond_Name)
		{
			continue;
		}
		//......................................................................
		if (OrderType () == OP_SELL)
		{
			Result = TRUE;
			break;
		}
		if (OrderType () == OP_SELLLIMIT)
		{
			Result = TRUE;
			break;
		}
		if (OrderType () == OP_SELLSTOP)
		{
			Result = TRUE;
			break;
		}
		//......................................................................
	} // for (i < OrdersTotal)
	//......................................................................
	return (Result);
}
//____________________________________________________________________________________
//																	|
// 		Append_String_W_Pos_Size ()			 		|
//_________________________________________________|
string Append_String_W_Pos_Size
(
   string 	Bond_Name,
   double 	Max_Risk_Param,
   int 		Portfolio_Bonds,
   double	Take_Profit_Param,
   double 	Stop_Loss_Param,
   string 	Out_String,
   bool 		Use_Portfolio_Style
)
{
	double 	Pos_Size ;
	double 	Pos_Size_Risk ;
	double 	Pos_Size_Portfolio ;
	double 	Pos_Size_Min ;
	double 	Daily_Volatility;
	double 	Stop_Loss_Points;
	double 	Take_Profit_Points;
	//.............................................................................
	Pos_Size_Risk = Calc_Pos_Size_To_Risk (Bond_Name, Max_Risk_Param);
	// !!! unfortunatelly >> FreeMarginCheck() << cannot be called from custom indicator !!!!
	if (Use_Portfolio_Style == TRUE)
	{
		Pos_Size_Portfolio = Calc_Pos_Size_To_Portfolio (Bond_Name, Portfolio_Bonds);
		Pos_Size_Risk = MathMin (Pos_Size_Risk, Pos_Size_Portfolio);
	}
	Pos_Size = Adjust_Pos_Size_To_Broker (Bond_Name, Pos_Size_Risk);
	//..........................................................................
	RefreshRates ();
	//.................................................................
	Pos_Size_Min = MarketInfo (Bond_Name, MODE_MINLOT);
	//..........................................................................
	Daily_Volatility = Get_Daily_Volatility (Bond_Name) ;
	Stop_Loss_Points = Stop_Loss_Param * MarketInfo (Bond_Name, MODE_BID)
	                   * Daily_Volatility / MarketInfo (Bond_Name, MODE_POINT);
	Take_Profit_Points = Take_Profit_Param * MarketInfo (Bond_Name, MODE_BID)
	                     * Daily_Volatility / MarketInfo (Bond_Name, MODE_POINT);
	//..........................................................................
	Out_String = Out_String + "Pos Size (RISK) = " + DoubleToStr (Pos_Size, 2) + "\n" ;
	Out_String = Out_String + "Pos Size (MIN) = " + DoubleToStr (Pos_Size_Min, 2) + "\n" ;
	Out_String = Out_String + "Stop Loss = " + DoubleToStr (Stop_Loss_Points, 0) + " points\n";
	Out_String = Out_String + "Take Profit = "
	             + DoubleToStr (Take_Profit_Points, 0) + " points\n";
	return (Out_String);
}
//____________________________________________________________________________________
//																	|
// 		Append_String_W_Pos_Size_Indi ()		 		|
//_________________________________________________|
string Append_String_W_Pos_Size_Indi
(
   string 	Bond_Name,
   double 	Max_Risk_Param,
   double	Take_Profit_Param,
   double 	Stop_Loss_Param,
   string 	Out_String
)
{
	double 	Pos_Size ;
	double 	Pos_Size_Risk ;
	double 	Pos_Size_Min ;
	double 	Daily_Volatility;
	double 	Stop_Loss_Points;
	double 	Take_Profit_Points;
	//.............................................................................
	Pos_Size_Risk = Calc_Pos_Size_To_Risk (Bond_Name, Max_Risk_Param);
	Pos_Size = Adjust_Pos_Size_To_Broker (Bond_Name, Pos_Size_Risk);
	//..........................................................................
	RefreshRates ();
	//.................................................................
	Pos_Size_Min = MarketInfo (Bond_Name, MODE_MINLOT);
	//..........................................................................
	Daily_Volatility = Get_Daily_Volatility (Bond_Name) ;
	Stop_Loss_Points = Stop_Loss_Param * MarketInfo (Bond_Name, MODE_BID)
	                   * Daily_Volatility / MarketInfo (Bond_Name, MODE_POINT);
	Take_Profit_Points = Take_Profit_Param * MarketInfo (Bond_Name, MODE_BID)
	                     * Daily_Volatility / MarketInfo (Bond_Name, MODE_POINT);
	//..........................................................................
	Out_String = Out_String + "Pos Size (RISK) = " + DoubleToStr (Pos_Size, 2) + "\n" ;
	Out_String = Out_String + "Pos Size (MIN) = " + DoubleToStr (Pos_Size_Min, 2) + "\n" ;
	Out_String = Out_String + "Stop Loss = " + DoubleToStr (Stop_Loss_Points, 0) + " points\n";
	Out_String = Out_String + "Take Profit = "
	             + DoubleToStr (Take_Profit_Points, 0) + " points\n";
	return (Out_String);
}
//______________________________________________________________________________________
//																	|
// 		Get_Trend_Situation_String	()			 		|
//_________________________________________________|
string Get_Trend_Situation_String
(
   int Situation
)
{
	string Ret_String = "N/A";
	//......................................................
	switch (Situation)
	{
		case TREND_MINIMUM:
			Ret_String = "MINIMUM";
			break;
		case TREND_DOWN:
			Ret_String = "DOWN";
			break;
		case TREND_DOWN_IN_CHANNEL:
			Ret_String = "DOWN IN CHANNEL";
			break;
		case TREND_FLAT:
			Ret_String = "FLAT";
			break;
		case TREND_UP:
			Ret_String = "UP";
			break;
		case TREND_UP_IN_CHANNEL:
			Ret_String = "UP IN CHANNEL";
			break;
		case TREND_MAXIMUM:
			Ret_String = "MAXIMUM";
			break;
	}
	//......................................................
	return (Ret_String);
}
//\_____________________/ END OF THIS FILE \___________________________________/
