extern double Lots = 0.1;
extern int slippage = 3;
extern int SessionBeginHour = 10;
extern int SessionEndHour = 19;
extern int DisregardAfterHour = 10;
extern int OrdersCloseHour = 10;
extern double RangeMultiplier = 0.5;
extern double TPMultiplier = 2;
extern double SLMultiplier = 1;
extern int TPAddPt = 0;
extern int SLAddPt = 5;
extern int MinRangePt = 0;
extern int MaxRangePt = 60;

int sessionLength, nDigits;
double x, nPoint, buyAt, sellAt;

int init () {
  sessionLength = SessionEndHour - SessionBeginHour;

  if (sessionLength <= 0) {
    sessionLength += 24;
  }
  
  nDigits = Digits;
  nPoint = Point;

  if (Digits == 3
  || Digits == 5) {
    nDigits --;
    nPoint *= 10;
    slippage *= 10;
  }

  buyAt = 0;
  sellAt = 0;
  return (0);
}

int deinit () {
  return (0);
}

int start () {
  static int lastHour = - 1;
  datetime currentHour = Hour ();
  double b = Bid;
  double a = Ask;
  double s = (a - b);

  if (currentHour != lastHour) {

    if (currentHour == DisregardAfterHour) {
      buyAt = 0;
      sellAt = 0;
    }

    if (currentHour == OrdersCloseHour) {
      int n = OrdersTotal ();

      for (int i = 0; i < n; i ++) {
        if (! (OrderSelect (i, SELECT_BY_POS, MODE_TRADES)
        && OrderClose (OrderTicket (), OrderLots (), OrderClosePrice (), slippage))) {
          return (0);
        }
      }
    }

    lastHour = currentHour;

    if (currentHour == SessionEndHour) {
      double h = High[iHighest (NULL, 0, MODE_HIGH, sessionLength, 1)];
      double l = Low[iLowest (NULL, 0, MODE_LOW, sessionLength, 1)];
      double r = h - l;
      x = r * RangeMultiplier;
      double ref = Close[1];

      if (r < MinRangePt * nPoint
      || r > MaxRangePt * nPoint) {
        buyAt = 0;
        sellAt = 0;
      } else {
        buyAt = ref - x;
        sellAt = ref + x;
      }
    }
  }

  if (b <= buyAt) {
    if (OrderSend (Symbol (), OP_BUY, Lots, nd (a), slippage,
      nd (b - (x * SLMultiplier + SLAddPt * nPoint)),
      nd (b + (x * TPMultiplier + TPAddPt * nPoint))) > 0) {
      buyAt = 0;
      sellAt = 0;
    } else {
      return (0);
    }
  } else
  if (sellAt > 0 && b >= sellAt) {
    if (OrderSend (Symbol (), OP_SELL, Lots, nd (b), slippage,
      nd (a + (x * SLMultiplier + SLAddPt * nPoint)),
      nd (a - (x * TPMultiplier + TPAddPt * nPoint))) > 0) {
      buyAt = 0;
      sellAt = 0;
    } else {
      return (0);
    }
  }

  return (0);
}

double nd (double d) {
  return (NormalizeDouble (d, Digits));
}