//+------------------------------------------------------------------+ //| Pip Nailer.mq4 | //| Flying Fish | //| | //+------------------------------------------------------------------+ #property copyright "Flying Fish" #property link "" string ExpertName = "Pip Nailer"; //---- input parameters int Ticket; int MagicNumber = 15125; extern double RiskPercent = 0.02; extern bool useFixedLot = false; extern double lotSize = 0; double AO[4], AC[4], SAR[4]; bool acFlag = false; bool aoFlag = false; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- MagicNumber = MagicNumber + Period(); int totalOrders = OrdersTotal(); for (int i = 0; i < totalOrders; i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if(OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol()) { Ticket = OrderTicket(); return(0); } } //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- if (!NewBar()) return(0); if (Ticket > 0) { OrderSelect(Ticket, SELECT_BY_TICKET); if (OrderCloseTime() != 0) Ticket = 0; } for( int i=0; i<4; i++) { AO[i] = iAO(NULL,0,i); AC[i] = iAC(NULL,0,i); SAR[i] = iSAR(NULL,0,0.02, 0.20, i); } bool signalAO = checkSignal(AO); bool signalAC = checkSignal(AC); bool signalSAR = checkSAR(SAR); if (Ticket > 0) { if (signalAC) acFlag = true; if (signalAO) aoFlag = true; if (acFlag && aoFlag) Ticket = CloseOrder(Ticket); } if (signalAO && signalAC && signalSAR) { if (SAR[1] < (Open[1]+Close[1])/2) Ticket = OpenOrder(LONG_VALUE); else Ticket = OpenOrder(SHORT_VALUE); acFlag = false; aoFlag = false; } //---- return(0); } //+------------------------------------------------------------------+ bool NewBar() { static datetime dt = 0; if (Time[0] != dt) { dt = Time[0]; return(true); } return(false); } int OpenOrder(int direction) { int Ticket; double Lots, TP; if(direction == LONG_VALUE) { TP = Open[0] - Low[1]; Lots = calcLots(TP); Ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,(Ask-Bid)/Point,Bid-TP,Ask+TP,ExpertName,MagicNumber,0,Green); if (Ticket == -1) Print("Failed to place Buy order, error = ",GetLastError()); } else { TP = High[1] - Open[0]; Lots = calcLots(TP); Ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,(Ask-Bid)/Point,Ask+TP,Bid-TP,ExpertName,MagicNumber,0,Green); if (Ticket == -1) Print("Failed to place Sell order, error = ",GetLastError()); } return(Ticket); } int CloseOrder(int Ticket) { OrderSelect(Ticket, SELECT_BY_TICKET); if(OrderType()==OP_BUY) { OrderClose(Ticket,OrderLots(),Bid,3,Green); if (GetLastError() != 0) { Print("Failed to close ticket (",OrderTicket(),"), Error: ",GetLastError()); return(Ticket); } } if(OrderType()==OP_SELL) { OrderClose(Ticket,OrderLots(),Ask,3,Red); if (GetLastError() != 0) { Print("Failed to close ticket (",OrderTicket(),"), Error: ",GetLastError()); return(Ticket); } } return(0); } double calcLots(double reward) { reward = reward/Point; double lot_min =MarketInfo(Symbol(),MODE_MINLOT); double lot_max =MarketInfo(Symbol(),MODE_MAXLOT); double lot_step=MarketInfo(Symbol(),MODE_LOTSTEP); if (reward < 1) return (lot_min); //guard against divide by zero error double risk = AccountBalance() * RiskPercent; double vol = risk / (reward*MarketInfo(Symbol(), MODE_TICKVALUE)); if (useFixedLot) vol = lotSize; vol=NormalizeDouble(vol/lot_step,0)*lot_step; if(vollot_max) vol=lot_max; return(vol); } bool checkSignal(double signal[]) { if (signal[1] > signal[2] && signal[2] < signal[3]) return(true); if (signal[1] < signal[2] && signal[2] > signal[3]) return(true); return(false); } bool checkSAR(double signal[]) { if (signal[1] < (Open[1]+Close[1])/2 && signal[2] > (Open[2]+Close[2])/2) return(true); if (signal[1] > (Open[1]+Close[1])/2 && signal[2] < (Open[2]+Close[2])/2) return(true); return(false); }