//+------------------------------------------------------------------+
//|                                           Place Market Order.mq4 |
//+------------------------------------------------------------------+
#property show_inputs

#include <hanover --- function header.mqh>

extern string     TradeRisk              = "1%";
extern string     BuyOrSell              = "B";
extern double     SLpips                 = 10;
extern double     TPpips                 = 10;
extern string     TPmultiples            = "1";
extern string     VolWeights             = "1";
extern string     TradeComment           = "";
extern int        TradeMagicNo           = 0;
extern string     ArrowColor             = "";
extern bool       AdjustForSpread        = true;

string   ccy;
int      dig, tmf, ticket, type;
double   spr, pnt, tickval, bidp, askp, minlot, lotstep, lswap, sswap, TradeVol, entry, SL, TP, AcctFreeMgn;
double   TPM[10], VW[10], TotWgt;

//+------------------------------------------------------------------+
int start()  {
//+------------------------------------------------------------------+

  ccy     = Symbol();
  tmf     = Period();
  pnt     = MarketInfo(ccy,MODE_POINT);
  dig     = MarketInfo(ccy,MODE_DIGITS);
  spr     = MarketInfo(ccy,MODE_SPREAD);
  tickval = MarketInfo(ccy,MODE_TICKVALUE);
  minlot  = MarketInfo(ccy,MODE_MINLOT);
  lotstep = MarketInfo(ccy,MODE_LOTSTEP);
  lswap   = MarketInfo(ccy,MODE_SWAPLONG);
  sswap   = MarketInfo(ccy,MODE_SWAPSHORT);
  if (dig == 3 || dig == 5) {
    pnt     *= 10;
    spr     /= 10;
    tickval *= 10;
  }  

  StrToDoubleArray(TPmultiples,TPM);
  StrToDoubleArray(VolWeights,VW);
  TotWgt = VW[0] + VW[1] + VW[2] + VW[3] + VW[4] + VW[5] + VW[6] + VW[7] + VW[8] + VW[9];

  BuyOrSell   = StringUpper(BuyOrSell);
  TradeRisk   = StringUpper(TradeRisk);
  AcctFreeMgn = AccountEquity();
  if (StringFind(TradeRisk,"B") >= 0)   AcctFreeMgn = AccountBalance();
  if (StringFind(TradeRisk,"F") >= 0)   AcctFreeMgn = AccountFreeMargin();

  for (int z=0; z<10; z++)   {
    entry   = 0;
    bidp    = MarketInfo(ccy,MODE_BID);
    askp    = MarketInfo(ccy,MODE_ASK);
    if (BuyOrSell == "B")  {
      type  = OP_BUY;
      entry = NormalizeDouble(askp,dig);
      SL    = NormalizeDouble(bidp-SLpips*pnt,dig);
      TP    = NormalizeDouble(bidp+TPpips*TPM[z]*pnt,dig);
      if (AdjustForSpread)  {
        SL  = NormalizeDouble(askp-SLpips*pnt,dig);
        TP  = NormalizeDouble(askp+TPpips*TPM[z]*pnt,dig);
    } }
    if (BuyOrSell == "S")  {
      type  = OP_SELL;
      entry = NormalizeDouble(bidp,dig);
      SL    = NormalizeDouble(askp+SLpips*pnt,dig);
      TP    = NormalizeDouble(askp-TPpips*TPM[z]*pnt,dig);
      if (AdjustForSpread)  {
        SL  = NormalizeDouble(bidp+SLpips*pnt,dig);
        TP  = NormalizeDouble(bidp-TPpips*TPM[z]*pnt,dig);
    } }

    TradeVol = StrToNumber(TradeRisk)*DivZero(VW[z],TotWgt);
    if (StringFind(TradeRisk,"&") >= 0)     TradeVol = DivZero(StrToNumber(TradeRisk)/100*AcctFreeMgn*DivZero(VW[z],TotWgt), CalcADR(30)*tickval);  
    if (StringFind(TradeRisk,":") >= 0)     TradeVol = DivZero(StrToNumber(TradeRisk)/100*AcctFreeMgn*DivZero(VW[z],TotWgt), 100*tickval);  
    if (SLpips <= 0)  {
      SL = 0;
    } else {
      if (StringFind(TradeRisk,"$") >= 0)   TradeVol = DivZero(StrToNumber(TradeRisk)*DivZero(VW[z],TotWgt), MathAbs(entry-SL)/pnt*tickval);
      if (StringFind(TradeRisk,"%") >= 0)   TradeVol = DivZero(AcctFreeMgn*StrToNumber(TradeRisk)/100*DivZero(VW[z],TotWgt), MathAbs(entry-SL)/pnt*tickval);
    }
    if (TPpips <= 0)
      TP = 0;

    if (lotstep > 0) 
      TradeVol = lotstep * MathInt(TradeVol/lotstep);
    if (lotstep == 0.01)   TradeVol = NormalizeDouble(MathInt(TradeVol,2),2); 
    if (lotstep == 0.1)    TradeVol = NormalizeDouble(MathInt(TradeVol,1),1); 
    if (lotstep == 1)      TradeVol = NormalizeDouble(MathInt(TradeVol,0),0);

    if (TradeVol < minlot)   continue;
  
    datetime expiry = 0;
    color    colr   = CLR_NONE;
    if (ArrowColor > "")       colr = StrToColor(ArrowColor);

    ticket = OrderSend(ccy,type,TradeVol,entry,99,0,0,TradeComment,TradeMagicNo,expiry,colr);
    if (ticket < 0)  {
      MessageBox("Error creating order " + err_msg(GetLastError()));
      return(0);
    } else {
      if (SL>0 || TP>0)  {
        bool OK = OrderModify(ticket,0,SL,TP,expiry);
        if (!OK)  {
          MessageBox("Error modifying order " + err_msg(GetLastError()));
          return(0);
    } } }
  }
  return(0);
}

//+------------------------------------------------------------------+
double CalcADR(int ADRdays)  {
//+------------------------------------------------------------------+
  double sum = 0;
  double cnt = 0;
  double hi  = 0;
  double lo  = 999999;
  for (int k=1; k<=ADRdays; k++)   {
    datetime dt = iTime(Symbol(),PERIOD_D1,k);
    if (TimeDayOfWeek(dt) == 0)   continue;
    double range = (iHigh(Symbol(),PERIOD_D1,k) - iLow(Symbol(),PERIOD_D1,k))/pnt;
    sum += range;
    cnt += 1;
    hi   = MathMax(hi,range);
    lo   = MathMin(lo,range);
  }
  double adr = DivZero(sum,cnt);
  return(adr);
}

//+------------------------------------------------------------------+
#include <hanover --- extensible functions.mqh>

