NarrowBreakout__GBPM30





//+------------------------------------------------------------------+
//|                                            NarrowBreakout_GBPM30 |
//|                                   Copyright © 2006, Lingyu Jiang |
//+------------------------------------------------------------------+
extern string    Broker="Alpari";                                  // you can also set "FXDD", "IBFX" here

//---- common parameters
extern bool      UseMM=true;
extern double    LotsIfNoMM=1.0;
extern double    MMRiskFactor=0.2;
extern int       Spread=4;
extern int       Start=9;
extern int       EOD=17;

//---- input parameters for narrow range breakout
extern int       NLookbackBars=4;
extern int       NPips=10;
extern int       NStopLoss=45;
extern int       NBreakEven=15;
extern int       NTakeProfit=0;
extern int       NRangeMax=43; 

//---- global variables
double Lots=1.0;
int    MagicNumber2=2;
double EntryLong2=0,EntryShort2=0;

int init()
{
   if (Broker == "FXDD") {
      Spread=3;
      Start=10;
      EOD=18;
      NLookbackBars=4;
      NPips=10;
      NStopLoss=45;
      NBreakEven=16;
      NTakeProfit=0;
      NRangeMax=42;
   } 
   else if (Broker == "IBFX") {
      Spread=4;
      Start=8;
      EOD=16;
      NLookbackBars=4;
      NPips=10;
      NStopLoss=45;
      NBreakEven=15;
      NTakeProfit=0;
      NRangeMax=43;
   }
   return (0);
}

//--- MM calculation
double CalculateMMLot()
{
   double lot_min =MarketInfo(Symbol(),MODE_MINLOT);
   double lot_max =MarketInfo(Symbol(),MODE_MAXLOT);
   double lot_step=MarketInfo(Symbol(),MODE_LOTSTEP);
   double lot;
   //--- check data
   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);
   }
   //--- basic formula
   lot=NormalizeDouble((AccountBalance())*MMRiskFactor/AccountLeverage()/10.0,2);
   lot=NormalizeDouble(lot/lot_step,0)*lot_step;
   if(lot<lot_min) lot=lot_min;
   if(lot>lot_max) lot=lot_max;
   //---
   return(lot);
  }

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   //---- 
   int i,Ticket,LastOrderTime,StartTime,StartTime1,StartTime2,EODTime;

   if (UseMM) Lots=CalculateMMLot(); else Lots=LotsIfNoMM;

   //Count time
   if(CurTime()>=StrToTime(Start+":00")-60){
      StartTime1=StrToTime(Start+":00");
      if(DayOfWeek()==5)   EODTime=MathMin(StrToTime("22:55"),StrToTime(EOD+":00")-60);
      else if (EOD==24)    EODTime=StrToTime("23:59");
      else                 EODTime=StrToTime(EOD+":00")-60;
   }
   
   // Set narrow range breakout orders
   if(TimeHour(CurTime()) >= Start && TimeHour(CurTime())<EOD) {
      SetNarrowRangeBreakoutOrders(MagicNumber2);
   }
   
   //Manage of open orders
   for (i=0;i<OrdersTotal();i++){
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if (OrderMagicNumber()!=MagicNumber2) continue;
      if(CurTime()<=GlobalVariableGet("LastOrderTime")+10) Sleep(10000);
      if(CurTime()>=EODTime){     //close open positions at EOD
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)      OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)     OrderClose(OrderTicket(),OrderLots(),Ask,3,Red);
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)  OrderDelete(OrderTicket());
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP) OrderDelete(OrderTicket());
         GlobalVariableSet("LastOrderTime",CurTime());
      }   
      else {
         double OpenPrice = 0;
         // manage narrow range breakout orders
         if (OrderMagicNumber() == MagicNumber2) {
            OpenPrice = 0;
            //move at BE if profit>BE
            if(OrderSymbol()==Symbol() && OrderType()==OP_BUY){
               if (EntryLong2 != 0) {
                  OpenPrice = EntryLong2;
               } else {
                  OpenPrice = OrderOpenPrice();
               }
               if(High[1]-OpenPrice>=NBreakEven*Point && High[0]-OpenPrice>=NBreakEven*Point && OrderStopLoss()<OpenPrice+5*Point){
                  OrderModify(OrderTicket(),OrderOpenPrice(),OpenPrice+5*Point,OrderTakeProfit(),0,Green);
                  GlobalVariableSet("LastOrderTime",CurTime());
               }   
            }   
            if(OrderSymbol()==Symbol() && OrderType()==OP_SELL){
               if (EntryShort2 != 0) {
                  OpenPrice = EntryShort2;
               } else {
                  OpenPrice = OrderOpenPrice();
               }
               if(OpenPrice-Low[1]-Spread*Point>=NBreakEven*Point && OpenPrice-Low[0]-Spread*Point>=NBreakEven*Point && OrderStopLoss()>OpenPrice-5*Point){
                  OrderModify(OrderTicket(),OrderOpenPrice(),OpenPrice-5*Point,OrderTakeProfit(),0,Green);
                  GlobalVariableSet("LastOrderTime",CurTime());
               }
            }
         }   
      }
   }
   
   //Reset global variables at EOD
   if(CurTime()>=EODTime) GlobalVariablesDeleteAll();
   
   return(0);
  }

//+------------------------------------------------------------------+
int SetNarrowRangeBreakoutOrders(int MN) {
   int i,Ticket,LastOrderTime,Bought=0,Sold=0,ShiftToStart,ShiftToBeginOfRange;
   double SLLong,SLShort,TPLong,TPShort;

   //Check Orders
   for (i=0;i<OrdersTotal();i++){
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()==Symbol() && (OrderType()==OP_BUYSTOP || OrderType()==OP_BUY) && OrderMagicNumber()==MN) Bought++;
      if(Bought>1){ //more than 1 buy order
         if(CurTime()<=GlobalVariableGet("LastOrderTime")+10) Sleep(10000);
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)      OrderClose(OrderTicket(),OrderLots(),Bid,3,Red);
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUYSTOP)  OrderDelete(OrderTicket());
      }
      if(OrderSymbol()==Symbol() && (OrderType()==OP_SELLSTOP || OrderType()==OP_SELL) && OrderMagicNumber()==MN) Sold++;
      if(Sold>1){ //more than 1 sell order
         if(CurTime()<=GlobalVariableGet("LastOrderTime")+10) Sleep(10000);
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)     OrderClose(OrderTicket(),OrderLots(),Ask,3,Red);
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELLSTOP) OrderDelete(OrderTicket());
      }
   }
   
   if(Bought==0 && Sold==0){ //no buy order
      // determine range
      EntryLong2   =High[Highest(NULL,PERIOD_M30,MODE_HIGH,NLookbackBars,1)]+(NPips+Spread)*Point;
      EntryShort2  =Low[Lowest (NULL,PERIOD_M30,MODE_LOW, NLookbackBars,1)]-NPips*Point;
      SLLong      =MathMax(EntryLong2-NStopLoss*Point,EntryShort2);
      SLShort     =MathMin(EntryShort2+NStopLoss*Point,EntryLong2);
      if (NTakeProfit!=0) {
         TPLong      =EntryLong2+NTakeProfit*Point;
         TPShort     =EntryShort2-NTakeProfit*Point;
      } else {
         TPLong      =0;
         TPShort     =0;
      }
   
      if (EntryLong2-EntryShort2>=NRangeMax*Point) { //So we can filter out large ranges
         // Ensures that no trades will be opened
         Bought=1;
         Sold=1;
         return (0);
      }

      if(CurTime()<=GlobalVariableGet("LastOrderTime")+10) Sleep(10000);
      Ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,EntryLong2,3,SLLong,TPLong,NULL,MN,0,Green);
      if(Ticket<0 && GetLastError()==130 && High[0]+Spread*Point>=EntryLong2 && Ask <= EntryLong2+3*Point && Ask>=EntryLong2-3*Point)
         Ticket=OrderSend(Symbol(),OP_BUY,Lots,EntryLong2,3,SLLong,TPLong,NULL,MN,0,Green);
      GlobalVariableSet("LastOrderTime",OrderOpenTime()); 


      if(CurTime()<=GlobalVariableGet("LastOrderTime")+10) Sleep(10000);
      Ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,EntryShort2,3,SLShort,TPShort,NULL,MN,0,Green);
      if(Ticket<0 && GetLastError()==130 && Low[0]<=EntryShort2 && Bid>=EntryShort2-3*Point && Bid<=EntryShort2+3*Point)
         Ticket=OrderSend(Symbol(),OP_SELL,Lots,EntryShort2,3,SLShort,TPShort,NULL,MN,0,Green);
      GlobalVariableSet("LastOrderTime",OrderOpenTime()); 
   }
}



Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar


Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached

Other Features:


BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.11 Total Net Profit:-17.14

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:0.15 Total Net Profit:-22.80

BackTest : USDCAD on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:3.70 Total Net Profit:156.55

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.05 Total Net Profit:-77.20

BackTest : USDCAD on H1

From 2009-01-01 to 2010-01-01 Profit Factor:0.09 Total Net Profit:-38.41

BackTest : EURUSD on H1

From 2010-03-01 to 2010-03-27 Profit Factor:0.00 Total Net Profit:6.40

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for NarrowBreakout__GBPM30


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: