//+---------------------------------------------------------------------------| //| PRD Trader v1.7_R.mq4 | //| by William R Garrison | //| 10 June 2009 | //| | //| Based on PRD Signal2 indicator by BigBawls | //| which, in turn, is based on the trading system by Robert Hill | //| which uses the past regression deviated indicator with a | //| three-order scale-out order management system | //| | //| 9 June 2009 - Added low and high range for TP targets | //| 10 June 2009 - Adjust slippage for 5-digit pricing, | //| add RefreshRates() between orders | //| 11 June 2009 - Add option to record channel values | //| 11 June 2009 - Fix stop adjust for orders 2 and 3 when price is too close | //| 11 June 2009 - Move signal logic into EA | //| 12 June 2009 - Add closeout for reversal signal | //| Add "No TP" and channel line SL option for third order | //| 12 June 2009 - Add PermitTpAdjustEveryTick | //| Add cutoff time on Fridays | //| | //| Changes by Robert | //| 12 June 2009 - Added constants for easier readingof code | //| Modularized code for easier changes in future | //| Added inputs for past regression deviated | //| Added MinStopLoss | //| Fixed bug for Trade 1 closed when Trade2 is closed | //| Fixed bug in trailing stop for trade 3 | //| | //| 13 June 2009 - Changed PRD indicator to be optimizable, named new | //| indicator "past regression deviated Opt" | //+---------------------------------------------------------------------------+ #property copyright "Copyright 2009, William Garrison and Robert Hill" #include #include // Trade signals #define FLAT 0 #define LONG 1 #define SHORT 2 // Indicator buffers #define MEAN_YELLOW 0 #define UPPER_LIME 1 #define LOWER_LIME 2 #define UPPER_ORANGE 3 #define LOWER_ORANGE 4 #define UPPER_RED 5 #define LOWER_RED 6 int period=0; /*default 0 means the channel will use the open time from "x" bars back on which ever time period the indicator is attached to. one can change to 1,5,15,30,60...etc to "lock" the start time to a specific period, and then view the "locked" channels on a different time period...*/ extern int LR.length=55; // bars back regression begins extern double std.channel.1 = 0.809; // 1st channel extern double std.channel.2 = 1.618; // 2nd channel extern double std.channel.3 = 2.618; // 3nd channel extern double lot = 0.1; extern int UseMM = true; extern double Risk = 3.0; int Shift = 1; extern string target_range_desc = "1 for low targets, 2 for high targets"; extern int TargetRange = 2; extern bool DynamicTP = false; extern bool Order3OpenTP = true; extern int InitialStop = 150; extern int PipsLock = 10; extern int MinProfitForLock = 25; extern bool UseTrailingStop = false; extern int TrailingStop=30.0; extern bool UseChannelStop = true; extern int ChannelStopLinesBack = 2; extern bool EnterWithCCI=true; extern int CCIPeriod = 14; extern int CCIEntryLevel = 100; extern int TradeStartHour = 0; extern int TradeStopHour = 0; extern int FridayCutoffHour = 12; extern bool EmailAlert=false; extern bool RecordTicks = false; extern bool RecordChannel = false; extern string EAVersion = "PRD 1.7"; extern int MagicNumber1 = 090608; extern int MagicNumber2 = 090609; extern int MagicNumber3 = 090610; int slippage = 3; int lotdigits = 0; int pip_adjust = 0; double minlot, maxlot, stops_level; string tick_file_name; int buyzone, sellzone; double BuyEntry, SellEntry; int BuySellTimeFrame; datetime last_tick = -1; bool order2mod = false; bool order3mod = false; bool new_bar = false; int ticket1 = -1; int ticket1type = -1; int ticket2 = -1; int ticket2type = -1; int ticket3 = -1; int ticket3type = -1; double MeanYellow; double High1Lime; double Low1Lime; double High2Orange; double Low2Orange; double High3Red; double Low3Red; int totalTries = 5; int retryDelay = 1000; int OrderErr; int init() { double foo = MarketInfo(Symbol(),MODE_LOTSTEP); // Print("lotstep ", foo); if (foo == 0.01) lotdigits = 2; else if (foo == 0.1) lotdigits = 1; else lotdigits = 0; if ((Digits == 3) || (Digits == 5)) pip_adjust = 10; else pip_adjust = 1; stops_level = MarketInfo(Symbol(), MODE_STOPLEVEL) / pip_adjust; buyzone =-CCIEntryLevel; sellzone= CCIEntryLevel; Print("digits ", Digits, " lotdigits ", lotdigits, "buyzone ", buyzone, " sellzone ", sellzone); Print("pip_adjust ", pip_adjust, " InitialStop ", InitialStop*pip_adjust, " TrailingStop ", TrailingStop*pip_adjust, " slippage ", slippage*pip_adjust, " Stops Level ", stops_level*pip_adjust); // range check for the TP target range selection if (TargetRange < 1) TargetRange = 1; if (TargetRange > 2) TargetRange = 2; // range check for channel trailing stop value if (ChannelStopLinesBack < 1) ChannelStopLinesBack = 1; if (ChannelStopLinesBack > 2) ChannelStopLinesBack = 2; new_bar = false; // If the tick file doesn't exist, write the column header tick_file_name = Symbol()+"_ticks.csv"; if (RecordTicks) init_tick_file(); } void GetTicketInfo() { int total = OrdersTotal(); ticket1 = -1; ticket1type = -1; ticket2 = -1; ticket2type = -1; ticket3 = -1; ticket3type = -1; for(int cnt = 0; cnt < total; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType() <= OP_SELL && OrderSymbol() == Symbol()) { if (OrderMagicNumber() == MagicNumber1) { ticket1 = OrderTicket(); ticket1type = OrderType(); } if (OrderMagicNumber() == MagicNumber2) { ticket2 = OrderTicket(); ticket2type = OrderType(); } if (OrderMagicNumber() == MagicNumber3) { ticket3 = OrderTicket(); ticket3type = OrderType(); } } } } bool HandleTicket1() { double localtarget = 0; double localstop = 0; // what if the first target was so close to the open that ticket1 has no TP value? // go ahead and close ticket 1 whan ticket 2 closes if((ticket1 > 0) && (ticket2 < 0)) { OrderSelect(ticket1, SELECT_BY_TICKET, MODE_TRADES); CloseOrder(ticket1, OrderLots(), OrderType()); Print("Ticket 1 closed by ticket 2 closing"); ticket1 = -1; // Bug fix } // adjust targets if((DynamicTP > 0) && (ticket1 > 0) && (new_bar)) { bool foo = OrderSelect(ticket1, SELECT_BY_TICKET, MODE_TRADES); if (!foo) { Print("Error during target1 adjust order select ", ErrorDescription(GetLastError())); return(false); } if (TargetRange == 1) { if (OrderType() == OP_BUY) { Low1Lime = GetPRD(LOWER_LIME, 0); localtarget = Low1Lime; } else { // OrderType() == OP_SELL High1Lime = GetPRD(UPPER_LIME, 0); localtarget = High1Lime; } } else { // targets in high range MeanYellow = GetPRD(MEAN_YELLOW, 0); localtarget = MeanYellow; } localtarget = NormalizeDouble(localtarget, Digits); if(((OrderType() == OP_BUY) && (OrderTakeProfit() < localtarget)) || ((OrderType() == OP_SELL) && (OrderTakeProfit() > localtarget))) { if(!OrderModify(ticket1, OrderOpenPrice(), OrderStopLoss(), localtarget, 0, Blue)) { Print("Error during ticket1 target adjust ", ErrorDescription(GetLastError())); Print("TP1 buy/sell open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localtarget ", localtarget, " TP ", OrderTakeProfit()); } } } // end of ticket 1 return(true); } bool HandleTicket2() { double localtarget = 0; double localstop = 0; if(ticket2 > 0) { bool foo = OrderSelect(ticket2, SELECT_BY_TICKET, MODE_TRADES); if (!foo) { Print("Error during target2 adjust order select ", ErrorDescription(GetLastError())); return(false); } if (OrderType() == OP_BUY) { // bring stop to breakeven if first order closed if ((ticket1 < 0) && (!order2mod)) { if (Bid>=OrderOpenPrice()+MinProfitForLock*Point*pip_adjust) { localstop = OrderOpenPrice()+PipsLock*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if(!OrderModify(ticket2, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Blue)) { Print("Error during ticket2 stop adjust ", ErrorDescription(GetLastError())); Print("TS2 BE buy open ", OrderOpenPrice(), " BS ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit()); } else order2mod = true; } } if ((DynamicTP > 0) && (new_bar)) { if (TargetRange == 1) { // low range targets MeanYellow = GetPRD(MEAN_YELLOW, 0); localtarget = MeanYellow; } else { // high range targets High1Lime = GetPRD(UPPER_LIME, 0); localtarget = High1Lime; } localtarget = NormalizeDouble(localtarget, Digits); if(OrderTakeProfit() != localtarget) { if(!OrderModify(ticket2, OrderOpenPrice(), OrderStopLoss(), localtarget, 0, Blue)) { Print("Error during ticket2 target adjust ", ErrorDescription(GetLastError())); Print("TP2 buy open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localtarget ", localtarget, " TP ", OrderTakeProfit()); } } } //end of adjust TP } // end of OP_BUY else { // OrderType() == OP_SELL // bring stop to breakeven if first order closed if ((ticket1 < 0) && (!order2mod)) { if (Ask<=OrderOpenPrice()-MinProfitForLock*Point*pip_adjust) { localstop = OrderOpenPrice()-PipsLock*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if(!OrderModify(ticket2, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Red)) { Print("Error during ticket2 stop adjust ", ErrorDescription(GetLastError())); Print("TS2 BE sell open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit()); } else order2mod = true; } } if ((DynamicTP > 0) && (new_bar)) { if (TargetRange == 1) { MeanYellow = GetPRD(MEAN_YELLOW, 0); localtarget = MeanYellow; } else { Low1Lime = GetPRD(LOWER_LIME, 0); localtarget = Low1Lime; } localtarget = NormalizeDouble(localtarget, Digits); if(OrderTakeProfit() != localtarget) { if(!OrderModify(ticket2, OrderOpenPrice(), OrderStopLoss(), localtarget, 0, Red)) { Print("Error during ticket2 target adjust ", ErrorDescription(GetLastError())); Print("TP2 sell open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localtarget ", localtarget, " TP ", OrderTakeProfit()); } } } // end of adjust TP } // end of OP_SELL } // end of ticket 2 return(true); } bool HandleTicket3() { double localtarget = 0; double localstop = 0; if(ticket3 > 0) { bool foo = OrderSelect(ticket3, SELECT_BY_TICKET, MODE_TRADES); if (!foo) { Print("Error during target3 adjust order select ", ErrorDescription(GetLastError())); return(false); } if (OrderType() == OP_BUY) { // special for the last ticket, bring stop to breakeven if ((ticket1 < 0) && (!order3mod)) { if ((Bid>=OrderOpenPrice()+MinProfitForLock*Point*pip_adjust) && (OrderStopLoss() < OrderOpenPrice()+PipsLock*Point*pip_adjust)) { localstop = OrderOpenPrice()+PipsLock*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if(!OrderModify(ticket3, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Blue)) { Print("Error during ticket3 target adjust ", ErrorDescription(GetLastError())); Print("TS3 BE buy open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit()); } else order3mod = true; } } if((DynamicTP > 0) && (!Order3OpenTP) && (new_bar)) { if (TargetRange == 1) { High1Lime = GetPRD(UPPER_LIME,0); localtarget = High1Lime; } else { High2Orange = GetPRD(UPPER_ORANGE,0); localtarget = High2Orange; } localtarget = NormalizeDouble(localtarget,Digits); if(OrderTakeProfit() != localtarget) { if(!OrderModify(ticket3, OrderOpenPrice(), OrderStopLoss(), localtarget, 0, Blue)) { Print("Error during ticket3 target adjust ", ErrorDescription(GetLastError())); Print("TP3 buy open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localtarget ", localtarget, " TP ", OrderTakeProfit()); } } } if (((UseTrailingStop == 1) || (UseChannelStop) || (Order3OpenTP)) && (new_bar)) { localstop = 9999; if (UseChannelStop) { High3Red = GetPRD(UPPER_RED,0); High2Orange = GetPRD(UPPER_ORANGE,0); High1Lime = GetPRD(UPPER_LIME,0); MeanYellow = GetPRD(MEAN_YELLOW,0); Low1Lime = GetPRD(LOWER_LIME, 0); if (OrderClosePrice() > High3Red) { if (ChannelStopLinesBack == 2) localstop = High1Lime; else localstop = High2Orange; } else if (OrderClosePrice() > High2Orange) { if (ChannelStopLinesBack == 2) localstop = MeanYellow; else localstop = High1Lime; } else if (OrderClosePrice() > High1Lime) { if (ChannelStopLinesBack == 2) localstop = Low1Lime; else localstop = MeanYellow; } } if (UseTrailingStop == 1) localstop = Bid-TrailingStop*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if((localstop > OrderStopLoss()+(5*Point*pip_adjust)) && (Bid > localstop+stops_level*pip_adjust)) { if(!OrderModify(ticket3, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Red)) { Print("Error during ticket3 trailing stop ", ErrorDescription(GetLastError())); Print("TS3 Buy open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit(), " Channel ", UseChannelStop, " Bid ", Bid); } } } // end of trailing stop } // end of OP_BUY else { // OrderType() == OP_SELL // special for the last ticket, bring stop to breakeven if ((ticket1 < 0) && (!order3mod)) { if ((Ask<=OrderOpenPrice()-MinProfitForLock*Point*pip_adjust) && (OrderStopLoss() > OrderOpenPrice()-PipsLock*Point*pip_adjust)) { localstop = OrderOpenPrice()-PipsLock*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if(!OrderModify(ticket3, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Red)) { Print("Error during ticket3 target adjust ", ErrorDescription(GetLastError())); Print("TS3 BE sell open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit()); } else order3mod = true; } } if((DynamicTP > 0) && (!Order3OpenTP) && (new_bar)) { if (TargetRange == 1) { Low1Lime = GetPRD(LOWER_LIME,0); localtarget = Low1Lime; } else { Low2Orange = GetPRD(LOWER_ORANGE,0); localtarget = Low2Orange; } localtarget = NormalizeDouble(localtarget, Digits); if(OrderTakeProfit() != localtarget ) { if(!OrderModify(ticket3, OrderOpenPrice(), OrderStopLoss(), localtarget, 0, Red)) { Print("Error during ticket3 target adjust ", ErrorDescription(GetLastError())); Print("TP3 buy open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localtarget ", localtarget, " TP ", OrderTakeProfit()); } } } if (((UseTrailingStop == 1) || (UseChannelStop) || (Order3OpenTP)) && (new_bar)) { localstop = 0; if (UseChannelStop) { High1Lime = GetPRD(UPPER_LIME, 0); MeanYellow = GetPRD(MEAN_YELLOW,0); Low1Lime = GetPRD(LOWER_LIME,0); Low2Orange = GetPRD(LOWER_ORANGE,0); Low3Red = GetPRD(LOWER_RED,0); if (OrderClosePrice() < Low3Red) { if (ChannelStopLinesBack == 2) localstop = Low1Lime; else localstop = Low2Orange; } else if (OrderClosePrice() < Low2Orange) { if (ChannelStopLinesBack == 2) localstop = MeanYellow; else localstop = Low1Lime; } else if (OrderClosePrice() > Low1Lime) { if (ChannelStopLinesBack == 2) localstop = High1Lime; else localstop = MeanYellow; } } if (UseTrailingStop == 1) localstop = Ask+TrailingStop*Point*pip_adjust; localstop = NormalizeDouble(localstop, Digits); if((localstop < OrderStopLoss()-(5*Point*pip_adjust)) && (Ask < localstop-stops_level*pip_adjust)) { if(!OrderModify(ticket3, OrderOpenPrice(), localstop, OrderTakeProfit(), 0, Red)) { Print("Error during trailing stop ", ErrorDescription(GetLastError())); Print("TS3 sell open ", OrderOpenPrice(), " SL ", OrderStopLoss(), " localstop ", localstop, " TP ", OrderTakeProfit(), " Channel ", UseChannelStop, " Ask ", Ask); } } } // end of trailing stop } // end of OP_SELL } //end of ticket3 return(true); } int start() { double locallots = 0; double localstop = 0; double localtarget = 0; bool OK; if (RecordTicks) Write_Tick_To_File(); // there are function that only happen at the start of a bar if (Time[0] == last_tick) new_bar = false; else new_bar = true; // determine what orders are still open GetTicketInfo(); OK = HandleTicket1(); if (!OK) return(0); OK = HandleTicket2(); if (!OK) return(0); OK = HandleTicket3(); if (!OK) return(0); // open orders only at the start of a bar if (Time[0] == last_tick) return(0); last_tick = Time[0]; BuyEntry = BuySignal(); SellEntry = SellSignal(); if (RecordChannel) { Print("New Bar ", TimeToStr(last_tick, TIME_MINUTES), " Buy Signal ", BuyEntry, " Sell Signal ", SellEntry); High3Red = GetPRD(UPPER_RED,0); High2Orange = GetPRD(UPPER_ORANGE,0); High1Lime = GetPRD(UPPER_LIME,0); MeanYellow = GetPRD(MEAN_YELLOW,0); Low1Lime = GetPRD(LOWER_LIME,0); Low2Orange = GetPRD(LOWER_ORANGE,0); Low3Red = GetPRD(LOWER_RED,0); Print("Channels ", High3Red, " ", High2Orange, " ", High1Lime, " ", MeanYellow, " ", Low1Lime, " ", Low2Orange, " ", Low3Red); } // if any order is open, Check for reversal signal if (CheckForReversal(ticket1, ticket1type)) ticket1 = -1; if (CheckForReversal(ticket2, ticket2type)) ticket2 = -1; if (CheckForReversal(ticket3, ticket3type)) ticket3 = -1; // if there is no open order, we can open one here if ((ticket1 < 0) && (ticket2 < 0) && (ticket3 < 0)) { int Signal = GetSignal(); // check hours that trade is not disqualified if(((TradeStartHour < TradeStopHour) && ((Hour() < TradeStartHour) || (Hour() >= TradeStopHour))) || ((TradeStartHour > TradeStopHour) && (Hour() < TradeStartHour) && (Hour() >= TradeStopHour))) { Signal = FLAT; } // Check that we don't open new orders late on Fridays if((Day() == 5) && (FridayCutoffHour > 0) && (Hour() >= FridayCutoffHour)) { Signal = FLAT; } if (Signal == FLAT) return(0); locallots = LotsOptimized(); if (Signal == LONG) { if (!IsTradeAllowed()) Print("Buy order at ", Ask); else { // establish indicator values Low3Red = GetPRD(LOWER_RED, 0); Low1Lime = GetPRD(LOWER_LIME,0); MeanYellow = GetPRD(MEAN_YELLOW,0); High1Lime = GetPRD(UPPER_LIME,0); High2Orange = GetPRD(UPPER_ORANGE,0); // High3Red = GetPRD(UPPER_RED,0); // localstop = Low3Red; // if (localstop < Bid - InitialStop*Point*pip_adjust) localstop = Bid - InitialStop*Point*pip_adjust; localstop = NormalizeDouble(localstop,Digits); // First third of order if (TargetRange == 1) localtarget = Low1Lime; else localtarget = MeanYellow; localtarget = NormalizeDouble(localtarget,Digits); ticket1 = OpenBuyOrder("BE1 ", locallots, localstop, localtarget, MagicNumber1); // Second third of order if (TargetRange == 1) localtarget = MeanYellow; else localtarget = High1Lime; localtarget = NormalizeDouble(localtarget,Digits); ticket2 = OpenBuyOrder("BE2 ", locallots, localstop, localtarget, MagicNumber2); // Last third of order if (TargetRange == 1) localtarget = High1Lime; else localtarget = High2Orange; if (Order3OpenTP) localtarget = 0; localtarget = NormalizeDouble(localtarget,Digits); ticket3 = OpenBuyOrder("BE3 ", locallots, localstop, localtarget, MagicNumber3); order2mod = false; order3mod = false; } } // end of buy entry if (Signal == SHORT) { if (!IsTradeAllowed()) Print("Sell order at ", Bid); else { // establish indicator values High3Red = GetPRD(UPPER_RED,0); High1Lime = GetPRD(UPPER_LIME,0); MeanYellow = GetPRD(MEAN_YELLOW,0); Low1Lime = GetPRD(LOWER_LIME,0); Low2Orange = GetPRD(LOWER_ORANGE,0); // Low3Red = GetPRD(LOWER_RED,0); // localstop = High3Red; // if (localstop < Ask + InitialStop*Point*pip_adjust) localstop = Ask + InitialStop*Point*pip_adjust; localstop = NormalizeDouble(localstop,Digits); // First third of order if (TargetRange == 1) localtarget = High1Lime; else localtarget = MeanYellow; localtarget = NormalizeDouble(localtarget,Digits); ticket1 = OpenSellOrder("SE1 ", locallots, localstop, localtarget, MagicNumber1); // Second third of order if (TargetRange == 1) localtarget = MeanYellow; else localtarget = Low1Lime; localtarget = NormalizeDouble(localtarget,Digits); ticket2 = OpenSellOrder("SE2 ", locallots, localstop, localtarget, MagicNumber2); // Last third of order if (TargetRange == 1) localtarget = Low1Lime; else localtarget = Low2Orange; if (Order3OpenTP) localtarget = 0; localtarget = NormalizeDouble(localtarget,Digits); ticket3 = OpenSellOrder("SE3 ", locallots, localstop, localtarget, MagicNumber3); order2mod = false; order3mod = false; } } return(0); } // end of open new orders //---- return(0); } //+------------------------------------------------------------------+ //| OpenBuyOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ int OpenBuyOrder(string msg, double mLots, double StopLoss, double TakeProfit, int MagicNumber) { int err,ticket; double TPprice,STprice; RefreshRates(); ticket=OrderSend(Symbol(),OP_BUY,mLots,Ask,slippage*pip_adjust,0,0,EAVersion,MagicNumber,0,Green); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) { TPprice = TakeProfit; TPprice = ValidTakeProfit(OP_BUY,Ask, TPprice); } STprice = 0; if (StopLoss > 0) { STprice = StopLoss; STprice = ValidStopLoss(OP_BUY,Bid, STprice); } // Normalize stoploss / takeprofit to the proper # of digits. if (Digits > 0) { STprice = NormalizeDouble( STprice, Digits); TPprice = NormalizeDouble( TPprice, Digits); } ModifyOrder(ticket, OrderOpenPrice(), STprice, TPprice, LightGreen); } Print(msg, "buy open ", OrderOpenPrice(), " BS ", STprice, " TP ", TPprice); if (MagicNumber == MagicNumber3 && EmailAlert) SendMail(EAVersion+"Buy", "Buy orders open on "+Symbol()+" at price "+DoubleToStr(OrderOpenPrice(),Digits)); } } else { err = GetLastError(); if(err==0) { return(ticket); } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print(msg, "Error opening BUY order [" + EAVersion + "]: (" + err + ") " + ErrorDescription(err)); } } } return(ticket); } //+------------------------------------------------------------------+ //| OpenSellOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //+------------------------------------------------------------------+ int OpenSellOrder(string msg, double mLots, double StopLoss, double TakeProfit, int MagicNumber) { int err, ticket; double TPprice,STprice; RefreshRates(); ticket=OrderSend(Symbol(),OP_SELL,mLots,Bid,slippage*pip_adjust,0,0,EAVersion,MagicNumber,0,Red); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) { TPprice=TakeProfit; TPprice = ValidTakeProfit(OP_SELL,Bid, TPprice); } STprice = 0; if (StopLoss > 0) { STprice = StopLoss; STprice = ValidStopLoss(OP_SELL,Ask, STprice); } // Normalize stoploss / takeprofit to the proper # of digits. if (Digits > 0) { STprice = NormalizeDouble( STprice, Digits); TPprice = NormalizeDouble( TPprice, Digits); } ModifyOrder(ticket, OrderOpenPrice(), STprice, TPprice, LightGreen); } Print(msg, "sell open ", OrderOpenPrice(), " BS ", STprice, " TP ", TPprice); if (MagicNumber == MagicNumber3 && EmailAlert) SendMail(EAVersion+"Sell", "Sell orders open on "+Symbol()+" at price "+DoubleToStr(OrderOpenPrice(),Digits)); } } else { err = GetLastError(); if(err==0) { return(ticket); } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print("Error opening Sell order [" + EAVersion + "]: (" + err + ") " + ErrorDescription(err)); } } } return(ticket); } int CloseOrder(int ticket,double numLots,int cmd) { bool exit_loop = false, result; int cnt, err, digits; double myPrice; if (cmd == OP_BUY) myPrice = MarketInfo(Symbol( ), MODE_BID); if (cmd == OP_SELL) myPrice = MarketInfo(Symbol( ), MODE_ASK); digits = MarketInfo(Symbol( ), MODE_DIGITS) ; if (digits > 0) myPrice = NormalizeDouble( myPrice, digits); cnt = 0; while (!exit_loop) { if (IsTradeAllowed()) { result = OrderClose(ticket,numLots,myPrice,slippage*pip_adjust,Violet); err = GetLastError(); } else cnt++; if (result == true) exit_loop = true; err=GetLastError(); switch (err) { case ERR_NO_ERROR: exit_loop = true; break; case ERR_SERVER_BUSY: case ERR_NO_CONNECTION: case ERR_INVALID_PRICE: case ERR_OFF_QUOTES: case ERR_BROKER_BUSY: case ERR_TRADE_CONTEXT_BUSY: case ERR_TRADE_TIMEOUT: // for modify this is a retryable error, I hope. cnt++; // a retryable error break; case ERR_PRICE_CHANGED: case ERR_REQUOTE: RefreshRates(); continue; // we can apparently retry immediately according to MT docs. default: // an apparently serious, unretryable error. exit_loop = true; break; } // end switch if (cnt > totalTries) exit_loop = true; if (!exit_loop) { Sleep(retryDelay); RefreshRates(); } } // we have now exited from loop. if ((result == true) || (err == ERR_NO_ERROR)) { OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); return(true); // SUCCESS! } Print(" Error closing order : (", err , ") " + ErrorDescription(err)); return(false); } int ModifyOrder(int ord_ticket,double op, double price,double tp, color mColor) { int CloseCnt, err; CloseCnt=0; while (CloseCnt < 3) { if (OrderModify(ord_ticket,op,price,tp,0,mColor)) { CloseCnt = 3; } else { err=GetLastError(); Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err)); if (err>0) CloseCnt++; } } } double ValidStopLoss(int type, double price, double SL) { double newSL, temp; temp = stops_level*Point*pip_adjust; newSL = SL; if (type == OP_BUY) { if((price - SL) < temp) newSL = price - temp; } if (type == OP_SELL) { if((SL-price) < temp) newSL = price + temp; } newSL = NormalizeDouble(newSL,Digits); return(newSL); } double ValidTakeProfit(int type, double price, double TP) { double newTP, temp; temp = stops_level*Point*pip_adjust; newTP = TP; if (type == OP_BUY) { if((TP - price) < temp) newTP = price + temp; } if (type == OP_SELL) { if((price - TP) < temp) newTP = price - temp; } newTP = NormalizeDouble(newTP,Digits); return(newTP); } //+------------------------------------------------------------------+ //| Money Management | //+------------------------------------------------------------------+ double LotsOptimized() { double oLots; //---- select lot size if(UseMM == 1) oLots=NormalizeDouble(AccountFreeMargin()*Risk/100/MarketInfo(Symbol(),MODE_MARGINREQUIRED),lotdigits); else oLots = lot; // Print("Margin ", AccountFreeMargin(), " Risk/100 ", Risk/100, " reqd ", MarketInfo(Symbol(),MODE_MARGINREQUIRED), " digits ", lotdigits); //---- return lot size minlot = MarketInfo(Symbol(),MODE_MINLOT); maxlot = MarketInfo(Symbol(),MODE_MAXLOT); // Print("oLots ", oLots, " minlot ", minlot, " maxlot ", maxlot); if (oLots > maxlot) oLots = maxlot; if (oLots < minlot) oLots = minlot; return(oLots); } void init_tick_file() { int fhandle = 0; int fcount; int r; fhandle = FileOpen(tick_file_name, FILE_CSV|FILE_READ, ","); // Print("tick file init open ", fhandle); if (fhandle < 1) { // tick file does not exist - write header Print ("Tick file does not exist - write header"); fhandle = FileOpen(tick_file_name, FILE_CSV|FILE_WRITE, ","); fcount = FileWrite(fhandle, "Date/Time", "Bid", "Ask", "Spread", "Buy entry", "Sell entry"); if (fcount < 0) { Print("Error during tick header write ", GetLastError()); return; } FileClose(fhandle); Print("Tick file header written for ", Symbol()); } } void Write_Tick_To_File() { int fhandle; int fcount; string currentTime; fhandle = FileOpen(tick_file_name, FILE_CSV|FILE_READ|FILE_WRITE, ","); if (fhandle == -1) { Print("Tick file cannot be opened"); return; } fcount = FileSeek(fhandle, 0, SEEK_END); if (fcount < 0) { Print("Error during seek end of tick file ", GetLastError()); } currentTime = TimeToStr(TimeCurrent(), TIME_SECONDS); fcount = FileWrite(fhandle, currentTime, NormalizeDouble(Bid, Digits), NormalizeDouble(Ask, Digits), (Ask/Point)-(Bid/Point), BuyEntry, SellEntry); if (fcount < 0) { Print("Error during tick write ", GetLastError()); } FileClose(fhandle); } // ---------------------------------------------------------------------- // The signal check functions look for Bar-2 and Bar-1 to have crossed // the orange line. // ---------------------------------------------------------------------- int BuySignal() { double Low2Orange = GetPRD(LOWER_ORANGE,Shift); double Low2Orange2 = GetPRD(LOWER_ORANGE,Shift+1); if ((Close[Shift]>Low2Orange) && (Close[Shift+1] buyzone) return(1); else return(0); } return(1); } return(0); } int SellSignal() { double High2Orange = GetPRD(UPPER_ORANGE,Shift); double High2Orange2 = GetPRD(UPPER_ORANGE,Shift+1); if ((Close[Shift]High2Orange2)) { if (EnterWithCCI) { double cci=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL,Shift); if (cci < sellzone) return(1); else return(0); } return(1); } return(0); } int GetSignal() { int isBuy, isSell; isBuy = BuySignal(); if (isBuy > 0) return(LONG); isSell = SellSignal(); if (isSell > 0) return (SHORT); return(FLAT); } double GetPRD(int buffer, int pos) { double buffer_val; buffer_val = iCustom(NULL, 0, "Past Regression Deviated Opt", period, LR.length,std.channel.1, std.channel.2,std.channel.3, buffer, pos); return(buffer_val); } // ---------------------------------------------------------------------- // CheckForReversal will close an order if a opposite signal appears // returns true if order is now closed, false if no action taken // ---------------------------------------------------------------------- bool CheckForReversal(int l_ticket, int l_type) { if (l_ticket < 0) return(true); if (((l_type == OP_BUY) && (SellEntry > 0)) || ((l_type == OP_SELL) && (BuyEntry > 0))) { if (!OrderSelect(l_ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("Error during reversal ticket ", l_ticket, " select ", ErrorDescription(GetLastError())); return(false); } if (!OrderClose(l_ticket, OrderLots(), OrderClosePrice(), 3*pip_adjust, 0)) { Print("Error during reversal ticket ", l_ticket, " close ", ErrorDescription(GetLastError())); return(false); } return(true); } return(false); }