//+------------------------------------------------------------------+
//|                                            EACenterOfGravity.mq4 |
//|                                                            v0.01 |
//|                                           http://www.edlogic.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#define MAGICMA  19000006

extern int stopLoss = 220;
extern int breakEvenSteps = 77;
extern double maxLots = 0.10;
extern int riskPercent = 3;
extern int activateExitStrategyAtPips = -150;
extern int takeProfit = 330;
extern int maxOrders = 2;
double Lots;
int Nmbr_Bars = 180;
double g_Center[3],g_High1[3],g_High2[3],g_High3[3],g_Low3[3],g_Low2[3],g_Low1[3];
double HighOrders[3], LowOrders[3];
double bid, ask, point, g_orderTicket;
int digits, spread, minStopLevel, cogMagic = 706706706;

int start() {
   if(Bars<100 || IsTradeAllowed()==false) return;
   // if( MathAbs(CalculateCurrentOrders(Symbol() ) ) == 0)
   
   checkIfHighLowOrdersClosed();
   GravityCenter2();
   CheckToOpenOrders();

   //else                                    
      //CheckForClose();
   return(0);
}

void checkIfHighLowOrdersClosed()
{
  for (int idx = 0; idx < 3; idx++)
  {
    checkHighOrderClosed(idx);
    checkLowOrderClosed(idx);
  }
}

void checkHighOrderClosed(int idx)
{
  if (HighOrders[idx] >= 0)
  {
    if (checkIfOrderClosed(HighOrders[idx]))
      HighOrders[idx] = -255;
  }
}
 
void checkLowOrderClosed(int idx)
{
  if (LowOrders[idx] >= 0)
  {
    if (checkIfOrderClosed(LowOrders[idx]))
      LowOrders[idx] = -255;
  }
}

bool checkIfOrderClosed(double orderNumber)
{
  int totalOrders = OrdersTotal();
  double orderStopLoss, orderTakeProfit, orderProfit, orderLots, orderOpenPrice;
  double marketPrice;
  int    orderType,  orderTicket;
  string orderSymbol;
  
  for(int idx = totalOrders - 1; idx >= 0; idx--)
	{
		if (OrderSelect(idx, SELECT_BY_POS, MODE_TRADES))
		{
		  if(OrderMagicNumber() != cogMagic || OrderSymbol() != Symbol())
		  {
		    Alert("continue because symbol or magic not good");
		    continue;
		  }
		  
			orderType = OrderType();
			orderSymbol = OrderSymbol();
			orderStopLoss = OrderStopLoss();
			orderTakeProfit = OrderTakeProfit();
			orderTicket = OrderTicket();
			orderLots = OrderLots();
			orderOpenPrice = OrderOpenPrice();
		
		  if (orderNumber == orderTicket)
		  {
		    //Alert("return false orderexists ordernumber = ", orderTicket);
		    return (false);
		  }
		
		/*	
			if (ordertype == OP_BUY || ordertype == OP_SELL)
			{
			  if (orderstoploss == 0)
			   setstoploss(stoploss, takeprofit, ordersymbol, ordertype, orderticket);
			   
				orderprofit = OrderProfit();
				checktrailingstoploss(orderprofit, ordersymbol, ordertype, orderticket);
			}
		*/
		
		}
		else { Print( "Error when order select ", GetLastError()); Sleep(1); }
	}
  
	//Alert("returning true because order not found ordernumber = ", orderNumber);
	return (true);
}

void CheckToOpenOrders()  
{
  getMarketInfo(Symbol());
  
  for (int idx = 0; idx < 3; idx++)
  {
    checkToOpenHighOrder(idx);
    checkToOpenLowOrder(idx);
  }
}  

void checkToOpenHighOrder(int idx)
{
  if (HighOrders[idx] == -255)
  {
    switch (idx)
    {
      case 0:
      {
        if (bid > g_High1[1] && g_Center[2] > g_Center[1])
        {
          g_orderTicket = -255;
          openSellOrder(Symbol());
          
          if (g_orderTicket >= 0)
            HighOrders[idx] = g_orderTicket;
            
          Alert("ask g_High1[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_High1[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
      case 1:
      {
        if (bid > g_High2[1] && g_Center[2] > g_Center[1])
        {
          g_orderTicket = -255;
          openSellOrder(Symbol());
          
          if (g_orderTicket >= 0)
            HighOrders[idx] = g_orderTicket;
            
          Alert("ask g_High2[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_High2[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
      case 2:
      {
        if (bid > g_High3[1] && g_Center[2] > g_Center[1])
        {
          g_orderTicket = -255;
          openSellOrder(Symbol());
          
          if (g_orderTicket >= 0)
            HighOrders[idx] = g_orderTicket;
          
          Alert("ask g_High3[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_High3[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
    }
  }
}

void checkToOpenLowOrder(int idx)
{
  if (LowOrders[idx] == -255)
  {
    switch (idx)
    {
      case 0:
      {
        if (bid < g_Low1[1] && g_Center[2] < g_Center[1])
        {
          g_orderTicket = -255;
          openBuyOrder(Symbol());
          
          if (g_orderTicket >= 0)
            LowOrders[idx] = g_orderTicket;
          
          Alert("ask g_Low1[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_Low1[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
      case 1:
      {
        if (bid < g_Low2[1] && g_Center[2] < g_Center[1])
        {
          g_orderTicket = -255;
          openBuyOrder(Symbol());
          
          if (g_orderTicket >= 0)
            LowOrders[idx] = g_orderTicket;
          
          Alert("ask g_Low2[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_Low2[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
      case 2:
      {
        if (bid < g_Low3[1] && g_Center[2] < g_Center[1])
        {
          g_orderTicket = -255;
          openBuyOrder(Symbol());
          
          if (g_orderTicket >= 0)
            LowOrders[idx] = g_orderTicket;
            
          Alert("ask g_Low3[1] g_Center[2] g_Center[1] g_orderticket = ", ask, ", ", g_Low3[1], ", ", g_Center[2], ", ", g_Center[1], ", ", g_orderTicket);
        }
      }
      break;
      
    }
  }
}



bool openBuyOrder(string symbol)
{
  int buyOrderTicket = -1;
  
  while (buyOrderTicket < 0) // < 0 && OrdersTotal() < currmaxorders)
  {
    getMarketInfo(symbol);
    buyOrderTicket = OrderSend(symbol, OP_BUY, 0.10, ask, 3, 0, 0, "buyit", cogMagic, 0, CLR_NONE);
		
		if (buyOrderTicket < 0)
		{
			int error = GetLastError();
			// Print("buy Error = ", symbol, " ", ErrorDescription(error));
			
			if (error != 135) { return(buyOrderTicket >= 0); }
    }
  }

  if (buyOrderTicket >= 0) // && OrdersTotal() < currmaxorders)
  {  
    //lastopenedorder = "buy";	
	  setstoploss(stopLoss, takeProfit, symbol, OP_BUY, buyOrderTicket); 
	  g_orderTicket = buyOrderTicket;
	}
	
	return(buyOrderTicket < 0); // && OrdersTotal() < currmaxorders);
}

bool openSellOrder(string symbol)
{
  int sellOrderTicket = -1;
  
  while (sellOrderTicket < 0) // < 0 && OrdersTotal() < currmaxorders)
  {
    getMarketInfo(symbol);
    sellOrderTicket = OrderSend(symbol, OP_SELL, 0.10, bid, 3, 0, 0, "sellit", cogMagic, 0, CLR_NONE);
		
		if (sellOrderTicket < 0)
		{
			int error = GetLastError();
			//Print("sell Error = ", symbol, " ", ErrorDescription(error));
			
			if (error != 135) { return(sellOrderTicket >= 0); }
    }
  }

  if (sellOrderTicket >= 0) // && OrdersTotal() < currmaxorders)
  {  
    //lastopenedorder = "sell";	
	  setstoploss(stopLoss, takeProfit, symbol, OP_SELL, sellOrderTicket);
	  g_orderTicket = sellOrderTicket;
	}

	return(sellOrderTicket < 0); // && OrdersTotal() < currmaxorders);
}

int setstoploss(double newstoploss, double newtakeprofit, string symbol, int ordertype, int orderticket)
{
  double stop_loss, take_profit;
  bool   result = false;
  int    error;
	
	getMarketInfo(symbol);

	//Print ("start stoploss - symbol newstoploss newtakeprofit bid ask = ", symbol, " ", newstoploss, " ", newtakeprofit, " ", bid, " ", ask);

  if (orderticket > -1)
  {
    if(ordertype == OP_BUY || ordertype == OP_SELL)
    {
      while (result == false)
      {
        if (ordertype == OP_BUY) 
        {
          stop_loss = ask - newstoploss * point;  
          take_profit = ask + newtakeprofit * point;
        }
        else            
        {
          stop_loss = bid + newstoploss * point; 
          take_profit = bid - newtakeprofit * point;
        }

        result = OrderModify(orderticket, OrderOpenPrice(), stop_loss, take_profit, 0, CLR_NONE); Sleep(1); 

        if (result != TRUE)
        {
          // error = GetLastError(); Print("ticket descrip errnum spread newstoploss newtakeprofit bid ask stop_loss take_profit minstoplevel = ", orderticket, " ", ErrorDescription(error), " ", error, " ", spread, " ", newstoploss, " ", newtakeprofit, " ", bid, " ", ask, " ", stop_loss, " ", take_profit, " ", minStopLevel);
          return(0);
        }
      }
    }
  }
  else
    Print ("stoploss ticket bad < 0 = ", orderticket);
  	
  return(0);
}

void GravityCenter2()
   {
   //int Nmbr_Bars = 3;
   int Order = 3;
   double Ecart = 1.61803399;
   
   double gda_120[20][20],gda_124[20],gda_128[20],gda_132[20];
   int gi_136,gi_140,gi_144,gi_148,gi_152,gi_156,gi_160;
   double gd_164,gd_172,gd_180,gd_188,gd_196;
   datetime l_time_0 = 0;
   
   gi_152 = Order + 1;
   gda_124[1] = Nmbr_Bars + 1;
   for (gi_160 = 1; gi_160 <= gi_152 << 1 - 2; gi_160++) {
      gd_164 = 0;
      for (gi_156 = 0; gi_156 <= Nmbr_Bars; gi_156++) gd_164 += MathPow(gi_156, gi_160);
      gda_124[gi_160 + 1] = gd_164;
   }
   for (gi_160 = 1; gi_160 <= gi_152; gi_160++) {
      gd_164 = 0;
      for (gi_156 = 0; gi_156 <= Nmbr_Bars; gi_156++) {
         if (gi_160 == 1) gd_164 += (High[gi_156] + Low[gi_156]) / 2.0;
         else gd_164 += (High[gi_156] + Low[gi_156]) / 2.0 * MathPow(gi_156, gi_160 - 1);
      }
      gda_128[gi_160] = gd_164;
   }
   for (gi_140 = 1; gi_140 <= gi_152; gi_140++) {
      for (gi_136 = 1; gi_136 <= gi_152; gi_136++) {
         gi_144 = gi_136 + gi_140 - 1;
         gda_120[gi_136][gi_140] = gda_124[gi_144];
      }
   }
   for (gi_144 = 1; gi_144 <= gi_152 - 1; gi_144++) {
      gi_148 = 0;
      gd_188 = 0;
      for (gi_136 = gi_144; gi_136 <= gi_152; gi_136++) {
         if (MathAbs(gda_120[gi_136][gi_144]) > gd_188) {
            gd_188 = MathAbs(gda_120[gi_136][gi_144]);
            gi_148 = gi_136;
         }
      }
      if (gi_148 == 0) return (0);
      if (gi_148 != gi_144) {
         for (gi_140 = 1; gi_140 <= gi_152; gi_140++) {
            gd_196 = gda_120[gi_144][gi_140];
            gda_120[gi_144][gi_140] = gda_120[gi_148][gi_140];
            gda_120[gi_148][gi_140] = gd_196;
         }
         gd_196 = gda_128[gi_144];
         gda_128[gi_144] = gda_128[gi_148];
         gda_128[gi_148] = gd_196;
      }
      for (gi_136 = gi_144 + 1; gi_136 <= gi_152; gi_136++) {
         gd_180 = gda_120[gi_136][gi_144] / gda_120[gi_144][gi_144];
         for (gi_140 = 1; gi_140 <= gi_152; gi_140++) {
            if (gi_140 == gi_144) gda_120[gi_136][gi_140] = 0;
            else gda_120[gi_136][gi_140] = gda_120[gi_136][gi_140] - gd_180 * gda_120[gi_144][gi_140];
         }
         gda_128[gi_136] = gda_128[gi_136] - gd_180 * gda_128[gi_144];
      }
   }
   gda_132[gi_152] = gda_128[gi_152] / gda_120[gi_152][gi_152];
   for (gi_136 = gi_152 - 1; gi_136 >= 1; gi_136--) {
      gd_196 = 0;
      for (gi_140 = 1; gi_140 <= gi_152 - gi_136; gi_140++) {
         gd_196 += (gda_120[gi_136][gi_136 + gi_140]) * (gda_132[gi_136 + gi_140]);
         gda_132[gi_136] = 1 / gda_120[gi_136][gi_136] * (gda_128[gi_136] - gd_196);
      }
   }
   for (gi_156 = 0; gi_156 <= Nmbr_Bars; gi_156++) {
      gd_164 = 0;
      for (gi_144 = 1; gi_144 <= Order; gi_144++) gd_164 += (gda_132[gi_144 + 1]) * MathPow(gi_156, gi_144);
      g_Center[gi_156] = gda_132[1] + gd_164;
   }
   gd_172 = iStdDev(NULL, 0, Nmbr_Bars, 0, MODE_SMA, PRICE_HIGH, 0) * Ecart;
   for (gi_156 = 0; gi_156 <= Nmbr_Bars; gi_156++) {
      g_High3[gi_156] = g_Center[gi_156] + gd_172;
      g_High2[gi_156] = g_Center[gi_156] + (g_High3[gi_156] - g_Center[gi_156]) / 1.382;
      g_High1[gi_156] = g_Center[gi_156] + (g_High2[gi_156] - g_Center[gi_156]) / 1.618;
      g_Low1[gi_156] = g_Center[gi_156] - gd_172;
      g_Low2[gi_156] = g_Center[gi_156] - (g_Center[gi_156] - g_Low1[gi_156]) / 1.382;
      g_Low3[gi_156] = g_Center[gi_156] - (g_Center[gi_156] - g_Low2[gi_156]) / 1.618;
   }  
   
   
   
 }  //end of function
  
  
void getMarketInfo(string symbol)
{
  RefreshRates();
  //bid = MarketInfo(symbol, MODE_BID);
  //ask = MarketInfo(symbol, MODE_ASK);
  //point = MarketInfo(symbol, MODE_POINT);
  //Alert ("point = ", point); Sleep(5000); return (0);
  digits = MarketInfo(symbol, MODE_DIGITS);
  spread = MarketInfo(symbol, MODE_SPREAD);
  minStopLevel = MarketInfo(symbol, MODE_STOPLEVEL);
  //Alert("min stop level = ", minstoplevel); Sleep(1000);
  //Alert("spread = ", spread); return (0); Sleep(1000);
  bid = NormalizeDouble(MarketInfo(symbol, MODE_BID), digits);
  ask = NormalizeDouble(MarketInfo(symbol, MODE_ASK), digits);
  point = NormalizeDouble(MarketInfo(symbol, MODE_POINT), digits);
  //Alert("bid ask point = ", bid, ", ", ask, ", ", point); Sleep(10000);
}  
  
 