//+------------------------------------------------------------------+ //| 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: