ButNakedbarTrading-exp





//+------------------------------------------------------------------+
//|                                       ButNakedbarTrading-exp.mq4 |
//|                                  Nick Bilak, beluck[AT]gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Nick Bilak"
#property link      "http://www.mql4.info/"
#include <stdlib.mqh>
#include <WinUser32.mqh>

extern int expertId = 1;

extern int TakeProfit1=50;
extern int TakeProfit2=150;
extern int _3bartrailpips=100;
extern int BreakEven=10;
extern int StopLoss=0;  
extern int  OrderPipsDiff=5;

extern bool InsideBar=true;
extern bool OutSideBar=true;

extern bool KeyReversalBar=true;
extern int  KeyReversalOpenDiff=10;

extern bool TwoBarReversal=true;
extern int  Open1Close2WithinPrevHLPips=10;
extern int  Open2WithinPrevClosePips=5;
extern int  BodyPips=10;
extern int  PipsFromMid=10;

extern int CancelOrderBars=4;

extern double Lots = 0.01;  
extern double MaximumRisk = 5;
extern int    LotDigits = 1;  
extern bool   FixedLot = true;

extern int    slippage=2;   	//slippage for market order 
int    shift=0;			//shift to current bar, 

extern int    OrderTriesNumber=2; //to repeate sending orders when got some error

extern string    EAName="bblo"; 

bool buysig,sellsig,closebuy,closesell,remorder;
int lastsig,last,tries,co,mkt;
double LotsRisk;
void start()  {


   //---- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false) return;

   co=CalculateCurrentOrders(Symbol());

   CheckForSignals();
   if (co>0) CheckForClose();
   CheckForOpen();
   
   co=CalculateCurrentOrders(Symbol());

   if (mkt>0) {
      BreakEvenStop(BreakEven,0);
      Trail3Bar();
   }
       
}


//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int ord; mkt=0;
//----
   for(int i=0;i<OrdersTotal();i++)  {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) continue;
      if(OrderSymbol()==symbol && OrderMagicNumber()==expertId) {
         ord++;
         if (OrderType()==OP_BUY || OrderType()==OP_SELL) mkt++;
      }
   }
//---- return orders volume
   return(ord);
}

//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForSignals() {
      //check long,short,exit signals
      buysig=false;
      sellsig=false;
      closebuy=false;
      closesell=false;
      remorder=false;
      

      int isins,isouts,iskeyrev,is2brev;
      if (InsideBar) isins=IsInsideBar(shift);
      if (OutSideBar) isouts=IsOutSideBar(shift);
      if (KeyReversalBar) iskeyrev=IsKeyReversalBar(shift);
      if (TwoBarReversal) is2brev=IsTwoBarReversal(shift);

      //long entry signal condition
      if (isins>0 || isouts>0 || iskeyrev>0 || is2brev>0) {
         buysig=true;
         closesell=true;
      }
      //short entry signal
      if (isins<0 || isouts<0 || iskeyrev<0 || is2brev<0) {
         buysig=false;
         sellsig=true;
         closebuy=true;
      }

      if (last>0 && (Time[0]-last)/(Period()*60)>=CancelOrderBars) {
         remorder=true;
      }

}

void CheckForOpen() {
   int    res,tr;
//---- sell conditions
   co=CalculateCurrentOrders(Symbol());
   if(sellsig && lastsig!=-1)  {
      co=CalculateCurrentOrders(Symbol());
	   if (co==0) {
        res = OpenStop(OP_SELLSTOP,LotsRisk(StopLoss), Low[shift]-OrderPipsDiff*Point, StopLoss, TakeProfit1);
        res = OpenStop(OP_SELLSTOP,LotsRisk(StopLoss), Low[shift]-OrderPipsDiff*Point, StopLoss, TakeProfit2);
	   }
	   lastsig=-1;
	   last=Time[0];
      return;
   }
//---- buy conditions
   if(buysig && lastsig!=1)  {
      co=CalculateCurrentOrders(Symbol());
	   if (co==0) {
        res = OpenStop(OP_BUYSTOP,LotsRisk(StopLoss), High[shift]+OrderPipsDiff*Point, StopLoss, TakeProfit1);
        res = OpenStop(OP_BUYSTOP,LotsRisk(StopLoss), High[shift]+OrderPipsDiff*Point, StopLoss, TakeProfit2);
	   }
	   last=Time[0];
	   lastsig=1;
      return;
   }
}
  


void BreakEvenStop(int BES, int BELP) {
   //move stoploss to lock some profit
   bool bres;
   double StopLoss;
   if ( BES > 2 ) {
      for (int i = 0; i < OrdersTotal(); i++) {
         if ( OrderSelect (i, SELECT_BY_POS) == false )  continue;
         if ( OrderSymbol() != Symbol() || OrderMagicNumber() != expertId )  continue;
         if ( OrderType() == OP_BUY ) {
            if ( Bid < OrderOpenPrice()+BES*Point )  continue;
            StopLoss = OrderOpenPrice()+BELP*Point;
            if ( StopLoss > OrderStopLoss() ) {
                  bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, White);
					   if (!bres) Print("Error Modifying BUY order : ",ErrorDescription(GetLastError()));
            }
         }
   
         if ( OrderType() == OP_SELL ) {
            if ( Ask > OrderOpenPrice()-BES*Point )  continue;
            StopLoss = OrderOpenPrice()-BELP*Point;
            if ( StopLoss < OrderStopLoss() ) {
                  bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, Gold);
					   if (!bres) Print("Error Modifying SELL order : ",ErrorDescription(GetLastError()));
            }
         }
      }
   }
   return;
}


int IsInsideBar(int shift) {
   //Inside Bar, The close of the inside bar should be higher than both the close and the bar midpoint The current bar must open 
   //equal or higher than the close of the inside bar a BuyStop order is to be placed at the high of the inside bar if the order 
   //is not hit within the next 4 bars cancel order. See picture below
   if (High[shift]>High[shift+1]) return(0);
   if (Low[shift]<Low[shift+1]) return(0);
   if (Close[shift]>Open[shift] && Close[shift]>(High[shift]+Low[shift])/2 && Open[shift-1]>=Close[shift]) return(1);
   if (Close[shift]<Open[shift] && Close[shift]<(High[shift]+Low[shift])/2 && Open[shift-1]<=Close[shift]) return(-1);
   return(false);
}

int IsOutSideBar(int shift) {
   //Outside Bar, The close of the outside bar should be higher than the open and higher that the bar midpoint the open 
   //of the current bar should open equal or higher than the close of the outside bar order A Buystop order should be 
   //placed on the high of the outside bar if it is not executed within the next 4 bars cancel order. See picture below
   if (High[shift]<High[shift+1]) return(0);
   if (Low[shift]>Low[shift+1]) return(0);
   if (Close[shift]>Open[shift] && Close[shift]>(High[shift]+Low[shift])/2 && Open[shift-1]>=Close[shift]) return(1);
   if (Close[shift]<Open[shift] && Close[shift]<(High[shift]+Low[shift])/2 && Open[shift-1]<=Close[shift]) return(-1);
   return(false);
}

int IsKeyReversalBar(int shift) {
   //Key Reversal Bar, The open of the key bar should be at least ?pips higher than the high of the previous bar. 
   //The close of the key bar should be with in the high and close of the previous bar. The open of the current bar should be 
   //lower than the close of the key bar. A SellStop order should be place on the low of the key bar if it is not executed within 
   //the next 4 bars then cancel the order. See picture below - short!
   if (Open[shift]<Low[shift+1]-KeyReversalOpenDiff*Point && Close[shift]>=Low[shift+1]  && Close[shift]<=Close[shift+1] && Open[shift-1]>Close[shift]) return(1);
   if (Open[shift]>High[shift+1]+KeyReversalOpenDiff*Point && Close[shift]<=High[shift+1]  && Close[shift]>=Close[shift+1] && Open[shift-1]<Close[shift]) return(-1);
   return(0);
}


int IsTwoBarReversal(int shift) {
   //Two Bar Reversal, The open of the first bar should be near the low the previous bar and the close should be much lower and 
   //have a good size body. The open of the second bar should be very near the close of the first bar but both should be well below 
   //the midpoint of each bar with the close to be very near the low 2 bar previous. A BuyStop Order should be place at the high of
   //the bar 1 if it is not executed within 4 bars cancel order. See picture below
   if (MathAbs(Open[shift+1]-Close[shift+1])>=BodyPips*Point && MathAbs(Open[shift+1]-Low[shift+2])<=Open1Close2WithinPrevHLPips*Point &&
       MathAbs(Close[shift]-Low[shift+2])<=Open1Close2WithinPrevHLPips*Point && 
       MathAbs(Open[shift]-Close[shift+1])<=Open2WithinPrevClosePips*Point &&
       Close[shift+1]<(High[shift+1]+Low[shift+1])/2-PipsFromMid*Point &&
       Open[shift]<(High[shift]+Low[shift])/2-PipsFromMid*Point)
         return(1);
   if (MathAbs(Open[shift+1]-Close[shift+1])>=BodyPips*Point && MathAbs(Open[shift+1]-High[shift+2])<=Open1Close2WithinPrevHLPips*Point &&
       MathAbs(Close[shift]-Low[shift+2])<=Open1Close2WithinPrevHLPips*Point && 
       MathAbs(Open[shift]-Close[shift+1])<=Open2WithinPrevClosePips*Point &&
       Close[shift+1]>(High[shift+1]+Low[shift+1])/2-PipsFromMid*Point &&
       Open[shift]>(High[shift]+Low[shift])/2-PipsFromMid*Point)
         return(-1);
   return(0);
}

int OpenStop(int mode,double lot, double prc, int SL, int TP) {
   int    res,tr,col;
   string mail;
   double openprice,sl,tp,stlev;
   tries=0;
   stlev=(1+MarketInfo(Symbol(),MODE_STOPLEVEL))*Point;
   while (res<=0 && tries<OrderTriesNumber) {
      tr=0; while (tr<5 && !IsTradeAllowed()) { tr++; Sleep(2000); }
      RefreshRates();
      if (mode==OP_SELLSTOP) {
         if (prc<=Bid-stlev) openprice=prc; 
         else openprice=Bid-stlev; 
         if (SL>0) sl=openprice+SL*Point;
         if (TP>0) tp=openprice-TP*Point;
         col=Red;
      } else
      if (mode==OP_BUYSTOP) {
         if (prc>=Ask+stlev) openprice=prc; 
         else openprice=Ask+stlev; 
         if (SL>0) sl=openprice-SL*Point;
         if (TP>0) tp=openprice+TP*Point;
         col=Blue;
      } else return;
      Print(Ask," ",Bid," ",Symbol(),"  ",mode,"  ",lot,"  ",openprice,"  ",sl,"  ",tp,"  ");
      res=OrderSend(Symbol(),mode,lot,openprice,slippage,sl,tp,EAName+"_"+expertId,expertId,0,col);
      tries++;
   }
   if (res<=0) Print("Error opening pending order : ",ErrorDescription(GetLastError()));
   return(res);
}

void CheckForClose()  {
   bool bres; int tr;
   for(int i=0;i<OrdersTotal();i++)  {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)  continue;
      if(OrderMagicNumber()!=expertId || OrderSymbol()!=Symbol()) continue;
      //---- check order type 
      if(OrderType()==OP_BUY && closebuy) {
         bres=CloseAtMarket(OrderTicket(),OrderLots());
         continue;
      }
      if(OrderType()==OP_SELL && closesell) {
         bres=CloseAtMarket(OrderTicket(),OrderLots());
         continue;
      }
      if(OrderType()==OP_BUYSTOP && (closebuy || remorder)) {
         bres=DeletePending(OrderTicket());
         continue;
      }
      if(OrderType()==OP_SELLSTOP && (closesell || remorder)) {
         bres=DeletePending(OrderTicket());
         continue;
      }
   }
}

bool DeletePending(int ticket) {
   bool bres=false; int tr;
   tries=0;
   while (!bres && tries<OrderTriesNumber) {
      bres=OrderDelete(ticket);
      tries++;
      tr=0; while (tr<5 && !IsTradeAllowed()) { tr++; Sleep(2000); }
   }
   if (!bres) Print("Error deleting order : ",ErrorDescription(GetLastError()));
   return (bres);
}

bool CloseAtMarket(int ticket,double lot) {
   //fault tolerant market order closing
   bool bres=false; int tr;
   tries=0;
   while (!bres && tries<OrderTriesNumber) {
      RefreshRates();
      bres=OrderClose(ticket,lot,OrderClosePrice(),slippage,White);
      tries++;
      tr=0; while (tr<5 && !IsTradeAllowed()) { tr++; Sleep(2000); }
   }
   if (!bres) Print("Error closing order : ",ErrorDescription(GetLastError()));
}


double LotsRisk(int StopLoss)  { 
   double lot=Lots;
   int SL=StopLoss;
   if (SL==0) SL=100;
//---- select lot size
   if (!FixedLot)
      lot=AccountFreeMargin()*MaximumRisk*0.001/SL;
   lot=NormalizeDouble(lot,LotDigits);
//---- return lot size
   if(lot<MarketInfo(Symbol(),MODE_MINLOT)) lot=MarketInfo(Symbol(),MODE_MINLOT);
   return(lot);
}

//3 bar trailing stop count back 3 bar and place a stop loss 2 pips below the lowest bar when counting back do not count the inside bars 
//skip to the next bar,  when a new bar opens perform the same task and move the trailing stop loss if able to. 
//If due to broker stop loss restrictions place the stop as close as possible to the next bar target and move it until 
//the next bar target is hit then repeat for each new bar

void Trail3Bar() {
   //_3bartrailpips
   bool bres;
   double StopLoss,H3,L3=99999;
   int i=0,cnt=3;
   
   while (i<=cnt) {
      i++;
      if (i>Bars-1) break;
      if (High[i]<=High[i+1] && Low[i]>=Low[i+1]) { cnt++; continue; } //skip inside Bar
      H3=MathMax(H3,High[i]);
      L3=MathMin(L3,Low[i]);
   }
   L3=L3-_3bartrailpips*Point;
   H3=H3+_3bartrailpips*Point;
   double stlev=(1+MarketInfo(Symbol(),MODE_STOPLEVEL))*Point;
   if (L3>=Bid-stlev) L3=Bid-stlev; 
   if (H3<=Ask+stlev) H3=Ask+stlev; 
   for (i = 0; i < OrdersTotal(); i++) {
      if ( OrderSelect (i, SELECT_BY_POS) == false )  continue;
      if ( OrderSymbol() != Symbol() || OrderMagicNumber() != expertId )  continue;
      if ( OrderType() == OP_BUY ) {
         StopLoss = L3;
         if ( StopLoss > OrderStopLoss() ) {
               bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, White);
				   if (!bres) Print("Error Modifying BUY order : ",ErrorDescription(GetLastError()));
         }
      }

      if ( OrderType() == OP_SELL ) {
         StopLoss = H3;
         if ( StopLoss < OrderStopLoss() || OrderStopLoss()<Point ) {
               bres=OrderModify (OrderTicket(), OrderOpenPrice(), StopLoss, OrderTakeProfit(), 0, Gold);
				   if (!bres) Print("Error Modifying SELL order : ",ErrorDescription(GetLastError()));
         }
      }
   }
}





Sample





Analysis



Market Information Used:

Series array that contains open time of each bar
Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar
Series array that contains close prices for each bar
Series array that contains open prices of each bar


Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders

It automatically opens orders when conditions are reached
It Closes Orders by itself

Other Features:

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:2.16 Total Net Profit:147.50

BackTest : EURUSD on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.32 Total Net Profit:-265.10

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:14.64 Total Net Profit:450.00

BackTest : EURUSD on H1

From 2010-03-01 to 2010-03-27 Profit Factor:5.47 Total Net Profit:143.00

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:200.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:200.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.32 Total Net Profit:-266.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-04-16 Profit Factor:0.02 Total Net Profit:-2379.30

BackTest : USDCAD on H1

From 2009-01-01 to 2010-01-01 Profit Factor:0.23 Total Net Profit:-1579.12

BackTest : USDCAD on H1

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

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.24 Total Net Profit:-86.82

Request Backtest for ButNakedbarTrading-exp


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

Pair: Period: