// The "awg" chart objects, the color sign of the position opening and closing
// were deleted becouse of remote running



#define major   1
#define minor   0

extern string _tmp11_ ="----- EquityStart-(Be kell �ll�tani)----";
extern double EquityStart =3000;
extern string _tmp1_ = " --- Trade params AcTp, AcSl in%, L=Starting Leverage---";
extern int AccDigits = 5;
extern int StopLoss = 0;
extern int TakeProfit = 0;
extern int Slippage = 3;
extern bool GridCloseOn = true;
extern double Delta = 0.0040;
extern double Delta2 = 0.002;
extern double TP = 0.0040;
extern int MaxOpPos =100;
extern bool EmTpOn = true;
extern double MaxAgTr = 3;
extern double L = 0.5;
extern double MaxWinPos = 3;
extern bool OppositeSignPlusCloseOn=true;
extern bool MartingaleOn=true;
extern double X = 2;
extern bool AcTpCloseOn=true;
extern double AcTp = 0.5;
extern bool AcSlCloseOn=true;
extern double AcSl = -20;



extern int Magic = 2;

extern string  EMA = "---EMA----";

extern int     Ema =2;

extern string _tmp3_ = " --- Trailing ---";
extern int TrailingStart = 200;
extern int TrailingSize = 10;




/*
extern string _tmp4_ = " --- Chart ---";
extern color clBuy = DodgerBlue;
extern color clSell = Red;
extern color clModify = Silver;
extern color clClose = Gold;
extern color clBuyAwg = Green;
extern color clSellAwg = Red;
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include <stdlib.mqh>
#include <stderror.mqh>

int RepeatN = 5;
int BuyCnt, SellCnt;


double sl, tp;
int i, l;
int Current;


void init()

{

}

void deinit() 
{
}
void start() 
{


double EmaCurr = iMA(NULL, 0, Ema, 0, MODE_EMA, PRICE_CLOSE, Current + 0);
double EmaPrev = iMA(NULL, 0, Ema, 0, MODE_EMA, PRICE_CLOSE, Current + 1);
double EmaPrev3 = iMA(NULL, 0, Ema, 0, MODE_EMA, PRICE_CLOSE, Current + 3);





/*
  ObjectCreate("BuyAwg", OBJ_HLINE, 0, 0, 0);
  ObjectSet("BuyAwg", OBJPROP_COLOR, clBuyAwg); 
  ObjectCreate("SellAwg", OBJ_HLINE, 0, 0, 0);
  ObjectSet("SellAwg", OBJPROP_COLOR, clSellAwg);
 */
  bool TrailingOn=false;

 
//---------------------------------long, short setup--------------------------------------------  
bool ShortSignOn=false;
bool LongSignOn=false;
bool ShortCloseSign=false;
bool LongCloseSign=false;
//--------------------Closing by AcTp/AcSL ------------------


  if (AccountBalance()==AccountEquity()) EquityStart=AccountEquity(); 
double FloatingResult=100*(AccountEquity()/EquityStart-1);
if (FloatingResult<=AcSl)
 {
 CloseOrders(OP_SELL);
 CloseOrders(OP_BUY);
 }
 
 if (FloatingResult>=AcTp)
 {
 CloseOrders(OP_SELL);
 CloseOrders(OP_BUY);
 }


//-------long "setup"-----------------------------------------
if (EmaPrev3<EmaCurr)LongSignOn=true;
//-------short "setup"---------------------------------------------
if (EmaPrev3>EmaCurr)ShortSignOn=true;
//--------------------------------------Closing by grid-----------------  
if(Bid-AwgPriceL()>=TP && GridCloseOn==true)CloseOrders(OP_BUY); 
if(AwgPriceS()-Ask>= TP && GridCloseOn==true)CloseOrders(OP_SELL);
//---------Closing for Opposite sign, if the awerage is winner and the positions are only in one directon---
if(OppositeSignPlusCloseOn==true && BuyCnt>0 && SellCnt==0)
{
if (ShortSignOn==true && AwgPriceL()<Bid)CloseOrders(OP_BUY);//
}
if(OppositeSignPlusCloseOn==true && SellCnt>0 && BuyCnt==0)
{
if (LongSignOn==true && AwgPriceS()>Ask)CloseOrders(OP_SELL);//
}

//----------Closing at 0 of the opened positions against to trend--------- 
if (BuyCnt>=MaxAgTr && Bid-AwgPriceL()>=0)CloseOrders(OP_BUY);
if (SellCnt>=MaxAgTr && AwgPriceS()-Ask>=0)CloseOrders(OP_SELL);
//-------------------------------Trail switch on if allowed------------------------  
if (BuyCnt>0 && SellCnt==0)
 {
 TrailingOn=true;
 TrailPositions();
 }   
if (BuyCnt==0 && SellCnt>0)
 {
 TrailingOn=true;
 TrailPositions();
 } 
//--------------------------Opening Long -----------------------------------------------------------

if (OrdersCountBar0(0) > 0) return;
  
  RecountOrders();
  if (LongSignOn==true)
  {
   if (BuyCnt > MaxOpPos) return;
   if (SellCnt>0 && MathAbs(Bid-LastShOpPo()) < Delta2) return;  
 
   if (MathAbs(LastLoOpPo()-Ask) < Delta) return;  
   if(AwgPriceL()<Ask && BuyCnt>=MaxWinPos) return;  
   for (i=0; i<RepeatN; i++)
   {
      RefreshRates();
      double price = Ask;
      //Print(" for ciklus i=", i);
      sl = If(StopLoss > 0, price - StopLoss*Point*fpc(), 0);
      tp = If(TakeProfit > 0, price + TakeProfit*Point*fpc(), 0);
      int ticket = Buy(Symbol(), LoGetLots(), price, sl, tp, Magic);
      if (ticket > 0) break;
    }

    return;
  }
  
//---------------------------------------Short Opening------------------------------------------
     if (ShortSignOn==true)
  { 
    if (SellCnt > MaxOpPos) return; 
    if (BuyCnt>0 && MathAbs(LastLoOpPo()-Ask) < Delta2) return;       
    if (MathAbs(Bid-LastShOpPo()) < Delta) return; 
    if(AwgPriceS()>Bid && SellCnt>=MaxWinPos) return;     
    for (i=0; i<RepeatN; i++)
    {  
     RefreshRates();
     price = Bid;
     sl = If(StopLoss > 0, price + StopLoss*Point*fpc(), 0);
     tp = If(TakeProfit > 0, price - TakeProfit*Point*fpc(), 0);
     ticket = Sell(Symbol(), ShGetLots(), price, sl, tp, Magic);
     if (ticket > 0) break;
    } //for (i=0; i<RepeatN; i++)
  }

} // void start()

/////////////////////////////////////////////////////////////////////////////////////////////////



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
double If(bool cond, double if_true, double if_false)
{
  if (cond) return (if_true);
  return (if_false);
}

int fpc()
{
  if (AccDigits == 5) return (10);
  if (AccDigits == 6) return (100);
  return (1); 
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


double LoGetLots() 
{
double LoGetLots;
LoGetLots=L*(AccountEquity()/1000000);
double LoLot = 0;
double ShLot = 0;
if(BuyCnt!=0 && MartingaleOn==true)
{
int cnt = OrdersTotal();
  for (int i=0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;    
    int type = OrderType();
    if (type == OP_BUY)LoGetLots=(OrderLots()*X);
}

}
return (LoGetLots);
}
//***************************************************************************************
double ShGetLots() 
{
double ShGetLots;
ShGetLots=L*(AccountEquity()/1000000);
double LoLot = 0;
double ShLot = 0;
if(SellCnt!=0 && MartingaleOn==true)
 {
int cnt = OrdersTotal();
  for (int i=0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;    
    int type = OrderType();
    if (type == OP_SELL)ShGetLots=(OrderLots()*X);
  }

 }
 return(ShGetLots);
}
//*******************************************************************
void RecountOrders()
{
  BuyCnt = 0;
  SellCnt = 0;
  

  int cnt = OrdersTotal();
  for (int i=0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    int type = OrderType();
    if (type == OP_BUY) BuyCnt++;
    if (type == OP_SELL) SellCnt++;
   
  }
}

int OrdersCountBar0(int TF)
{
  int orders = 0;

  int cnt = OrdersTotal();
  for (int i=0; i<cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;

    if (OrderOpenTime() >= iTime(NULL, TF, 0)) orders++;
  }

  cnt = OrdersHistoryTotal();
  for (i=0; i<cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;

    if (OrderOpenTime() >= iTime(NULL, TF, 0)) orders++;
  }
 
  return (orders);
}

int CloseOrders(int type1, int type2 = -1) 

{  

  int cnt = OrdersTotal();
  for (int i=cnt-1; i >= 0; i--) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    int type = OrderType();
    if (type != type1 && type != type2) continue;
    
    if (type == OP_BUY)
   
    {
    
      RefreshRates();
      CloseOrder(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID));
     
      continue;
    }
    
    if (type == OP_SELL) 
    
    {
      RefreshRates();
      CloseOrder(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK));
    
      continue;
    }    
  }
  
  int orders = 0;
  cnt = OrdersTotal();
  for (i = 0; i < cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    
    type = OrderType();
    if (type != type1 && type != type2) continue;
    
    orders++;
  }
  
  return (orders); 
}

//-AwgPriceL --------
double AwgPriceL()
{
double AwgPriceL;
double LoLot;
double SUML;
int i;

LoLot = 0;
for( i=0; i < OrdersTotal(); i++)  
{
   if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
   if (OrderSymbol() != Symbol()) continue;
   if (OrderMagicNumber() != Magic) continue;
   int type = OrderType();
   if (type == OP_BUY)             
   {
    LoLot += OrderLots();
    SUML += OrderOpenPrice()*OrderLots();     
   
    }
}
if (LoLot != 0) AwgPriceL = SUML/LoLot; ObjectSet("BuyAwg", OBJPROP_PRICE1, AwgPriceL);// " SumOpBuy: ", SumOpBuy);

return(AwgPriceL);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
double AwgPriceS()
{
double AwgPriceS;
double ShLot;
double SUMS;
int i, type;

ShLot = 0;
for( i=0; i < OrdersTotal(); i++) // Order searching cycle 
 {
  if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
  if (OrderSymbol() != Symbol()) continue;
  if (OrderMagicNumber() != Magic) continue;

  type = OrderType();
  if (type == OP_SELL)          
  {
   ShLot += OrderLots();
   SUMS += OrderOpenPrice()*OrderLots();       
  
   }
 }
if (ShLot != 0) AwgPriceS = SUMS/ShLot;
ObjectSet("SellAwg", OBJPROP_PRICE1, AwgPriceS);

return(AwgPriceS);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
double LastShOpPo()
{
double LastShOpPo;
int i, type;
for( i=0; i < OrdersTotal(); i++) // Order searching cycle 
 {
  if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
  if (OrderSymbol() != Symbol()) continue;
  if (OrderMagicNumber() != Magic) continue;
  type = OrderType();
  if (type == OP_SELL)          
  {
   LastShOpPo=OrderOpenPrice();
  }
 }
return(LastShOpPo);
}   

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
double LastLoOpPo()
{
double LastLoOpPo;
int i, type;
for( i=0; i < OrdersTotal(); i++) // Order searching cycle 
   {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;
    type = OrderType();
    if (type == OP_BUY)             // If the next is available order analysis: 
    {
     LastLoOpPo=OrderOpenPrice();
    } 
   }
return(LastLoOpPo);    
}
   
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void TrailPositions()
{
  int StopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) + 1;
  double sl;
  
  int cnt = OrdersTotal();
  for (int i=0; i<cnt; i++) 
  {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != Magic) continue;

    int type = OrderType();
    if (type == OP_BUY) 
    {
      if (Bid-AwgPriceL() > TrailingStart*Point*fpc()) 
      {
        sl = Bid - TrailingSize*Point*fpc();
                
        if (sl >= Bid - StopLevel*Point) continue;
        
        if (OrderStopLoss() < sl - 1*Point*fpc()|| OrderStopLoss() == 0) 
        {
       
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderMagicNumber() != Magic) continue;
          OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(), 0, 0);
        }
      }
    }

    if (type == OP_SELL)
    {
      if (AwgPriceS()-Ask > TrailingStart*Point*fpc()) 
      {
        sl = Ask + TrailingSize*Point*fpc();
        
        if (sl <= Ask + StopLevel*Point) continue;
        
        if (OrderStopLoss() > sl + 1*Point*fpc() || OrderStopLoss() == 0) 
        {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderMagicNumber() != Magic) continue;
          OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(), 0, 0);
        }
      }
    }
  }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int SleepOk = 2000;
int SleepErr = 6000;

int Buy(string symbol, double lot, double price, double sl, double tp, int magic, string comment="") 
{
  int dig = MarketInfo(symbol, MODE_DIGITS);

  price = NormalizeDouble(price, dig);
  sl = NormalizeDouble(sl, dig);
  tp = NormalizeDouble(tp, dig);
    
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);
  string _sl = DoubleToStr(sl, dig);
  string _tp = DoubleToStr(tp, dig);

  int res = OrderSend(symbol, OP_BUY, lot, price, Slippage, sl, tp, comment, magic, 0, 0);
  if (res >= 0) {
    Sleep(SleepOk);
    return (res);
  }     
       
  int code = GetLastError();
  Print("Error opening BUY order: ", ErrorDescription(code), " (", code, ")");
  Sleep(SleepErr);
    
  return (-1);
}

int Sell(string symbol, double lot, double price, double sl, double tp, int magic, string comment="") 
{
  int dig = MarketInfo(symbol, MODE_DIGITS);

  price = NormalizeDouble(price, dig);
  sl = NormalizeDouble(sl, dig);
  tp = NormalizeDouble(tp, dig);
  
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);
  string _sl = DoubleToStr(sl, dig);
  string _tp = DoubleToStr(tp, dig);

  
  int res = OrderSend(symbol, OP_SELL, lot, price, Slippage, sl, tp, comment, magic, 0, 0);
  if (res >= 0) {
    Sleep(SleepOk);
    return (res);
  }     
       
  int code = GetLastError();
  Print("Error opening SELL order: ", ErrorDescription(code), " (", code, ")");
  Sleep(SleepErr);
    
  return (-1);
}

bool CloseOrder(int ticket, double lot, double price) 
{
  if (!OrderSelect(ticket, SELECT_BY_TICKET)) return(false);
  if (OrderCloseTime() > 0) return(false);
  
  int dig = MarketInfo(OrderSymbol(), MODE_DIGITS);
  string _lot = DoubleToStr(lot, 2);
  string _price = DoubleToStr(price, dig);
  
  bool res = OrderClose(ticket, lot, price, Slippage,0);
  if (res) {
    Sleep(SleepOk);
    return (res);
  }     
       
  int code = GetLastError();
  Sleep(SleepErr);
    
  return (false);
}


