#property copyright "Shinigami© 2007"
#property link      "shini1984@gmail.com"
#define ORDER_ID 2019

extern double LongEntry = 0; // set your level here
extern double LongTarget = 0; // set your level here
extern double LongStoploss = 0; // set your level here
extern double ShortEntry = 0; // set your level here
extern double ShortTarget = 0; // set your level here
extern double ShortStoploss = 0; // set your level here
//---- input parameters for MM
extern string MM.start = "----------MoneyManagement---------";
extern string MM = "0 for basic lot, 1 for % of deposit"; // more to come
extern int MMformula = 0;
extern double BasicLot=0.1;
extern double MMRiskFactor=0.1;
extern int LotPrecision = 1;
int Magic = 6582542354345246254762854321;
string Commentz = "EA by Shinigami";
datetime last=0;



//----------------------------------------------------

double CalculateMM()
{
 double lot,calculatedlot=0;
 if(MMformula==0)
  {
   lot=BasicLot;
   return(lot);
  }
 if(MMformula==1)
  {
   double lot_min =MarketInfo(Symbol(),MODE_MINLOT);
   double lot_max =MarketInfo(Symbol(),MODE_MAXLOT);
   double lot_step=MarketInfo(Symbol(),MODE_LOTSTEP);
    if(lot_min<0 || lot_max<=0.0 || lot_step<=0.0) 
     {
      Print("CalculateMMLot: invalid MarketInfo() results [",lot_min,",",lot_max,",",lot_step,"]");
      return(0);
     }
    if(AccountLeverage()<=0)
     {
      Print("CalculateMMLot: invalid AccountLeverage() [",AccountLeverage(),"]");
      return(0);
     }
    lot=NormalizeDouble(AccountBalance()*MMRiskFactor/100/10.0,LotPrecision);//instead of AccountLeverage() I use 100
    if(CheckLoss()==1)
    lot=NormalizeDouble(lot/CountLoss(),1);
    lot=NormalizeDouble(lot/lot_step,0)*lot_step;
    if(lot<lot_min)
    lot=lot_min;
    if(lot>lot_max) 
    lot=lot_max;
    return(lot);
   }
  else
  return(BasicLot);
}

//----------------------------------------------------------

int start()
 {
  start.TR();
 }
 
//----------------------------------------------------

int start.TR()    //function of all functions
{
RefreshRates();
if(iTime(Symbol(),0,1)==last)
return(0);
if(CheckBuy()==0)
 {
  if(iOpen(Symbol(),0,0)>LongEntry)
  OpenBuy();
 }
if(CheckSell()==0)
 {
  if(iOpen(Symbol(),0,0)<ShortEntry)
  OpenSell();
 }
if(OrdersTotal()>0)
 {
  if(CheckBuy()==1)
  CheckExit.Buy();
  if(CheckSell()==1)
  CheckExit.Sell();
 }
last=iTime(Symbol(),0,1);

return(0);
}

//-------------------------------------------------------------

int CheckExit.Buy()
{
RefreshRates();
if(iOpen(Symbol(),0,0)<LongStoploss)
CloseBuy();
return(0);
}

//-------------------------------------------------------------

int CheckExit.Sell()
{
RefreshRates();
if(iOpen(Symbol(),0,0)>ShortStoploss)
CloseSell();
return(0);
}

//----------------------------------------------------
int CloseBuy()
{
RefreshRates();
 int i=0;
 for(i=0;i<OrdersTotal();i++)
  {
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderType()==OP_BUY)
      OrderClose(OrderTicket(),OrderLots(),Bid,3,Blue);
  }
 return(0);
}

//--------------------------------------------------------------------

int CloseSell()
{
RefreshRates();
 int i=0;
 for(i=0;i<OrdersTotal();i++)
  {
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderType()==OP_SELL)
      OrderClose(OrderTicket(),OrderLots(),Ask,3,DodgerBlue);
  }
 return(0);
}

//----------------------------------------------------

int CheckBuy()
{
RefreshRates();
 int i=0,orders=0;
 for(i=0;i<OrdersTotal();i++)
  {
   OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderOpenTime()>iTime(Symbol(),PERIOD_D1,0))
       {
        if(OrderType()==OP_BUY)
        orders++;
       }
  }
 for(i=OrdersHistoryTotal();i>=0;i--)
  {
   OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol())
    {
     if(OrderMagicNumber()==Magic)
      {
       if(OrderOpenTime()>iTime(Symbol(),PERIOD_D1,0))
        {
         if(OrderType()==OP_BUY)
          {
           orders++;
           break;
          }
        }
      }
    }
  }
 return(orders);
}

//----------------------------------------------------

int CheckSell()
{
RefreshRates();
 int ni=0,orderz=0;
 for(ni=0;ni<OrdersTotal();ni++)
  {
   OrderSelect(ni,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderType()==OP_SELL)
      orderz++;
  }
 for(ni=OrdersHistoryTotal();ni>=0;ni--)
  {
   OrderSelect(ni,SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol())
    {
     if(OrderMagicNumber()==Magic)
      {
       if(OrderOpenTime()>iTime(Symbol(),PERIOD_D1,0))
        {
         if(OrderType()==OP_BUY)
          {
           orderz++;
           break;
          }
        }
      }
    }
  }
 return(orderz);
}


//-----------------------------------------------------------

int OpenBuy()
{
RefreshRates();
 OrderSend ( Symbol() , OP_BUY , CalculateMM() , Ask , 3 ,
             0 ,
             LongTarget , 
             Commentz , Magic , 0 , Green );
return(0);
}

//-----------------------------------------------------------

int OpenSell()
{
RefreshRates();
 OrderSend ( Symbol() , OP_SELL , CalculateMM() , Bid , 3 ,
             0 , 
             ShortTarget ,
             Commentz , Magic , 0 , Red );
return(0);
}

//--------------------------------------------------------

//--------------------------------------------------------

int CheckLoss()
{
RefreshRates();
int i=0,check=0;
   for(i=OrdersHistoryTotal();i>0;i--)
    {
      OrderSelect(i-1,SELECT_BY_POS,MODE_HISTORY);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderProfit()<0)
      check=1;
      break;
    }
return(check);
}

//----------------------------------------------------------

int CountLoss()
{
int i=0,losses=0;
   for(i=OrdersHistoryTotal();i>0;i--)
    {
      OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
      if(OrderSymbol()!=Symbol())
      continue;
      if(OrderMagicNumber()!=Magic)
      continue;
      if(OrderProfit()<0)
       {
        losses++;
        continue;
       }
      if(OrderProfit()>0)
      break;
    }
return(losses);
}

