Time: 2014-03-02 | Download file:Pipmaker_V10.mq4
// This version Pipmaker_V10 has been modified from the PipMakerV5aNeo_Enhanced_V2_mod4 by Stech137. // All orders are now closed when ProfitTarget is reached to eliminate outlying orders from building up negative equity. // Multiplier/CounterTrendMultiplier now acts as Martingale - doubling lot size at Spacing pips away in opposite trend from initial order (CounterTrendMultiplier) or // at TrendSpacing intervals in same direction of initial order if set to "1". // Added option for a stop loss on each order but not profitable when used in backtests. // If UseCCI is "true" buy orders will only be executed if the CCIPeriod and the 1 minute period CCI are above zero (opposite for short). The 1 minute CCI is needed // to stop more orders from being executed when there is a sharp reversal in trend. The EA will then continue executing orders when the market has calmed down and // both CCI periods agree again. // This EA allows for both Buy and Sell orders at the same time in the same currency which will act as a hedge until the prevailing trend resumes thus limiting // drawdown. This obviously won't work if your broker does not allow hedging. #include#include #define NL "\n" // Regular variables extern bool TradeShort = true; extern bool TradeLong = true; extern bool UseDPO = true; // Trades long if 30Min-LWMA is above daily open and short if below (idea from OnlyPivot thread) extern bool UseCCI = true; // Uses CCI to determine trade direction if true. extern int CCIPeriod = 15; // Trades long if this CCI Period and 1M CCI period are above zero; Below zero for short. extern double LotSize = 0.2; extern double LotIncrement = 0.05; extern double Multiplier = 0; // Will increase orders in Martingale fashion in direction of trend if set to "1". Used with TrendSpacing only. extern int ProfitTarget = 2; // All orders closed when this profit target amount (in dollars) is reached extern double SL = 0; // Performs better with no initial stoploss. extern int OpenOnTick = 1; extern int Spacing = 15; // Minimum distance of orders placed against the trend of the initial order extern int TrendSpacing = 1000; // Minimum distance of orders placed with the trend of the initial order (set to 1000 to disable) extern double CounterTrendMultiplier = 0; // Will increase orders in Martingale fashion in opposite direction of trend if set to "1". Used with Spacing only. extern int CloseDelay = 91; // Minimum close time for IBFX to not be considered scalping extern bool CeaseTrading = false; extern string PasueTrading ="Pause Trading at Timeinterval"; extern int StartTime = 0; //Example: Trading pause starts at day 15 hour 14, minute 30 (server time)--> input= 151430 extern int EndTime = 0; //Example: Trading pause ends at day 15 hour 15, minute 10 (server time)--> input= 151510 extern string QuitTrading = "Quit Trading at Time"; extern int endDayHourMinute = 0; //Example: Quit trading on day 17 hour 21 minute 59 (server time)-->input=172159 extern bool RightSideLabel = true; extern int SessionTarget = 10000; //Trading will be stopped if this amount has been earned in this session extern int MaximumBuyOrders =10; extern int MaximumSellOrders =10; extern double SLTotalinDollar =10000; //SL for Total Open Position in Dollar // Internal settings int Step = 1; double stoploss = 0; int Error = 0; int Order = 0; int Slippage = 0; int Reference = 0; string TradeComment; double TickPrice = 0; int MaxBuys = 0; int MaxSells = 0; bool Auditing = false; string Filename; double initialBalance; int lotPrecision; int StopLoss=100; int init() { if (Symbol() == "AUDCADm" || Symbol() == "AUDCAD") Reference = 801001; if (Symbol() == "AUDJPYm" || Symbol() == "AUDJPY") Reference = 801002; if (Symbol() == "AUDNZDm" || Symbol() == "AUDNZD") Reference = 801003; if (Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") Reference = 801004; if (Symbol() == "CHFJPYm" || Symbol() == "CHFJPY") Reference = 801005; if (Symbol() == "EURAUDm" || Symbol() == "EURAUD") Reference = 801006; if (Symbol() == "EURCADm" || Symbol() == "EURCAD") Reference = 801007; if (Symbol() == "EURCHFm" || Symbol() == "EURCHF") Reference = 801008; if (Symbol() == "EURGBPm" || Symbol() == "EURGBP") Reference = 801009; if (Symbol() == "EURJPYm" || Symbol() == "EURJPY") Reference = 801010; if (Symbol() == "EURUSDm" || Symbol() == "EURUSD") Reference = 801011; if (Symbol() == "GBPCHFm" || Symbol() == "GBPCHF") Reference = 801012; if (Symbol() == "GBPJPYm" || Symbol() == "GBPJPY") Reference = 801013; if (Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") Reference = 801014; if (Symbol() == "NZDJPYm" || Symbol() == "NZDJPY") Reference = 801015; if (Symbol() == "NZDUSDm" || Symbol() == "NZDUSD") Reference = 801016; if (Symbol() == "USDCHFm" || Symbol() == "USDCHF") Reference = 801017; if (Symbol() == "USDJPYm" || Symbol() == "USDJPY") Reference = 801018; if (Symbol() == "USDCADm" || Symbol() == "USDCAD") Reference = 801019; if (Reference == 0) Reference = 801999; initialBalance= AccountBalance(); TradeComment = StringConcatenate(Symbol()," ",Period()," ","PM"," S_ID: ",TimeLocal()); Filename = StringConcatenate("PipMaker_v10_",Symbol(),"_",Period(),"_M",".txt"); CalculateLotPrecision(); return(0); } int deinit() { if(ObjectFind("MidPoint")==0){ ObjectDelete("MidPoint"); } if(ObjectFind("MarginPercent")==0){ ObjectDelete("MarginPercent"); } if(ObjectFind("LowMarginPercent")==0){ ObjectDelete("LowMarginPercent"); } Comment(""); return(0); } void CalculateLotPrecision(){ double lotstep=MarketInfo(Symbol(),MODE_LOTSTEP); if(lotstep==1) lotPrecision=0; if(lotstep==0.1) lotPrecision=1; if(lotstep==0.01) lotPrecision=2; if(lotstep==0.001) lotPrecision=3; } void PlaceBuyOrder() { double BuyOrders, Lots; double LowestBuy = 1000, HighestBuy; TickPrice = 0; RefreshRates(); for (Order = OrdersTotal() - 1; Order >= 0; Order--) { if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_BUY) { if (OrderOpenPrice() < LowestBuy) LowestBuy = OrderOpenPrice(); if (OrderOpenPrice() > HighestBuy) HighestBuy = OrderOpenPrice(); BuyOrders++; } } } if (Ask >= HighestBuy + (TrendSpacing * Point)) { if (Multiplier == 1) Lots = NormalizeDouble(MathPow(2,BuyOrders)*LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize + (LotIncrement * BuyOrders), lotPrecision); } if (Ask <= LowestBuy - (Spacing * Point)) { if (CounterTrendMultiplier == 1) Lots = NormalizeDouble(MathPow(2,BuyOrders)*LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize + (LotIncrement * BuyOrders), lotPrecision); } if(BuyOrders==0) { Lots = NormalizeDouble(LotSize, lotPrecision); } if (Lots == 0) { if (Multiplier == 1) Lots = NormalizeDouble(LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize, lotPrecision); } if(IsTradeAllowed()==true && (BuyOrders < MaximumBuyOrders)) { if (SL == 0) stoploss = 0; else stoploss = Ask - (SL * Point); OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, stoploss, 0, TradeComment, Reference, Green); } Error = GetLastError(); if (Error != 0) Write("Error opening BUY order: " + ErrorDescription(Error) + " (C" + Error + ") Ask:" + Ask + " Slippage:" + Slippage); else { TickPrice = Close[0]; } } void PlaceSellOrder() { double SellOrders, Lots; double HighestSell, LowestSell = 1000; TickPrice = 0; RefreshRates(); for (Order = OrdersTotal() - 1; Order >= 0; Order--) { if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_SELL) { if (OrderOpenPrice() > HighestSell) HighestSell = OrderOpenPrice(); if (OrderOpenPrice() < LowestSell) LowestSell = OrderOpenPrice(); SellOrders++; } } } if (Bid <= LowestSell - (TrendSpacing * Point)) { // if (Multiplier) if (Multiplier == 1) Lots = NormalizeDouble(MathPow(2,SellOrders)*LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize + (LotIncrement * SellOrders), lotPrecision); } if (Bid >= HighestSell + (Spacing * Point)) { // if (Multiplier) if (CounterTrendMultiplier == 1) Lots = NormalizeDouble(MathPow(2,SellOrders)*LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize + (LotIncrement * SellOrders), lotPrecision); } if(SellOrders==0) { Lots = NormalizeDouble(LotSize, lotPrecision); } if (Lots == 0) { // if (Multiplier) if (Multiplier == 1) Lots = NormalizeDouble(LotSize, lotPrecision); else Lots = NormalizeDouble(LotSize, lotPrecision); } if(IsTradeAllowed()==true && (SellOrders < MaximumSellOrders)) { if (SL == 0) stoploss = 0; else stoploss = Bid + (SL * Point); OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, stoploss, 0, TradeComment, Reference, Red); } Error = GetLastError(); if (Error != 0) Write("Error opening SELL order: " + ErrorDescription(Error) + " (D" + Error + ") Bid:" + Bid + " Slippage:" + Slippage); else { TickPrice = Close[0]; } } int start() { double MarginPercent; static double LowMarginPercent = 10000000, LowEquity = 10000000; double BuyPipTarget, SellPipTarget; int SellOrders, BuyOrders; double BuyPips, SellPips, BuyLots, SellLots; double LowestBuy = 999, HighestBuy = 0.0001, LowestSell = 999, HighestSell = 0.0001, HighPoint, MidPoint, LowPoint; double Profit = 0, BuyProfit = 0, SellProfit = 0, PosBuyProfit = 0, PosSellProfit = 0; int HighestBuyTicket, LowestBuyTicket, HighestSellTicket, LowestSellTicket; double HighestBuyProfit, LowestBuyProfit, HighestSellProfit, LowestSellProfit; bool SELLme = false; bool BUYme = false; double Margin = MarketInfo(Symbol(), MODE_MARGINREQUIRED); string Message; CutTotalLoss(); for (Order = OrdersTotal() - 1; Order >= 0; Order--) { if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference) { Profit = OrderProfit() + OrderSwap() + OrderCommission(); if (OrderType() == OP_BUY) { if (OrderOpenPrice() >= HighestBuy) { HighestBuy = OrderOpenPrice(); HighestBuyTicket = OrderTicket(); HighestBuyProfit = Profit; } if (OrderOpenPrice() <= LowestBuy) { LowestBuy = OrderOpenPrice(); LowestBuyTicket = OrderTicket(); LowestBuyProfit = Profit; } BuyOrders++; if (BuyOrders > MaxBuys) MaxBuys = BuyOrders; BuyLots += OrderLots(); BuyProfit += Profit; if (Profit > 0) PosBuyProfit += Profit; } if (OrderType() == OP_SELL) { if (OrderOpenPrice() <= LowestSell) { LowestSell = OrderOpenPrice(); LowestSellTicket = OrderTicket(); LowestSellProfit = Profit; } if (OrderOpenPrice() >= HighestSell) { HighestSell = OrderOpenPrice(); HighestSellTicket = OrderTicket(); HighestSellProfit = Profit; } SellOrders++; if (SellOrders > MaxSells) MaxSells = SellOrders; SellLots += OrderLots(); SellProfit += Profit; if (Profit > 0) PosSellProfit += Profit; } } } } BuyPipTarget = ProfitTarget; SellPipTarget = ProfitTarget; if (HighestBuy >= HighestSell) HighPoint = HighestBuy; else HighPoint = HighestSell; if (LowestBuy <= LowestSell) LowPoint = LowestBuy; else LowPoint = LowestSell; MidPoint = (HighPoint + LowPoint) / 2; // if ((SellOrders > 1 && BuyOrders > 0) || (SellOrders > 0 && BuyOrders > 1)) MidPoint = (HighPoint + LowPoint) / 2; RefreshRates(); if (BuyProfit + SellProfit >= ProfitTarget) { for (Order = OrdersTotal() - 1; Order >= 0; Order--) { if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference) { OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Green); } Error = GetLastError(); if (Error != 0) Write("Error closing order " + OrderTicket() + ": " + ErrorDescription(Error) + " (F" + Error + ") Lots:" + OrderLots() + " Ask:" + MarketInfo(OrderSymbol(), MODE_ASK)); } } } RefreshRates(); // BUY Trade Criteria if (HighestBuy > 0 && LowestBuy < 1000) { if (Ask <= LowestBuy - (Spacing * Point) || Ask >= HighestBuy + (TrendSpacing * Point)) { BUYme = true; if (OpenOnTick == 1 && TickPrice > 0 && Close[0] < TickPrice) BUYme = true; } if (CeaseTrading && BuyOrders == 0) BUYme = false; if (CCIDecision(1)!=1 || Direction(1)!=1 || PauseAtTime(StartTime,EndTime,1)!=1) BUYme = false;//Ask < Trend marketQuality()!=1 if (BUYme && TradeLong==true) PlaceBuyOrder(); } // SELL Trade Criteria if (HighestSell > 0 && LowestSell < 1000) { if (Bid >= HighestSell + (Spacing * Point) || Bid <= LowestSell - (TrendSpacing * Point)) { SELLme = true; // if (OpenOnTick && TickPrice > 0 && Close[0] > TickPrice) TradeAllowed = true; if (OpenOnTick == 1 && TickPrice > 0 && Close[0] > TickPrice) SELLme = true; } if (CeaseTrading && SellOrders == 0) SELLme = false; if (CCIDecision(-1)!=-1 || Direction(-1)!=-1 || PauseAtTime(StartTime,EndTime,-1)!=-1) SELLme = false;//Bid > Trend marketQuality()!=-1 if (SELLme && TradeShort==true) PlaceSellOrder(); } if(AccountMargin()!=0) { MarginPercent = MathRound((AccountEquity() / AccountMargin()) * 100); } if (LowMarginPercent > MarginPercent) LowMarginPercent = MarginPercent; if (AccountEquity() < LowEquity) LowEquity = AccountEquity(); Message = " PipMakerV10" + NL + " ProfitTarget " + DoubleToStr(BuyPipTarget, 2) + NL + " Buys " + BuyOrders + " Highest: " + MaxBuys + NL + " BuyLots " + DoubleToStr(BuyLots, 2) + NL + " BuyProfit " + DoubleToStr(BuyProfit, 2) + NL + " Highest Buy " + DoubleToStr(HighestBuy, Digits) + " #" + DoubleToStr(HighestBuyTicket, 0) + " Profit: " + DoubleToStr(HighestBuyProfit, 2) + NL + " Highest Sell " + DoubleToStr(HighestSell, Digits) + " #" + DoubleToStr(HighestSellTicket, 0) + " Profit: " + DoubleToStr(HighestSellProfit, 2) + NL + NL + " ProfitTarget " + DoubleToStr(SellPipTarget, 2) + NL + " Sells " + SellOrders + " Highest: " + MaxSells + NL + " SellLots " + DoubleToStr(SellLots, 2) + NL + " SellProfit " + DoubleToStr(SellProfit, 2) + NL + " Lowest Buy " + DoubleToStr(LowestBuy, Digits) + " #" + DoubleToStr(LowestBuyTicket, 0) + " Profit: " + DoubleToStr(LowestBuyProfit, 2) + NL + " Lowest Sell " + DoubleToStr(LowestSell, Digits) + " #" + DoubleToStr(LowestSellTicket, 0) + " Profit: " + DoubleToStr(LowestSellProfit, 2) + NL + NL + " Balance " + DoubleToStr(AccountBalance(), 2) + NL + " Equity " + DoubleToStr(AccountEquity(), 2) + " Lowest: " + DoubleToStr(LowEquity, 2) + NL + NL + " Margin " + DoubleToStr(AccountMargin(), 2) + NL + " MarginPercent " + DoubleToStr(MarginPercent, 2) + NL + " LowMarginPercent " + DoubleToStr(LowMarginPercent, 2) + NL + " Current Time is " + TimeToStr(TimeCurrent(), TIME_SECONDS); Comment(Message); if (RightSideLabel) { string MarPercent = DoubleToStr(MarginPercent, 0); string LowMarPercent = DoubleToStr(LowMarginPercent, 0); string AcctBalance = DoubleToStr(AccountBalance(), 0); ObjectDelete("MarginPercent"); if (ObjectFind("MarginPercent") != 0) { ObjectCreate("MarginPercent", OBJ_TEXT, 0, Time[0], Close[0]); ObjectSetText("MarginPercent", MarPercent + "% " + LowMarPercent + "% $" + AcctBalance, 10, "Arial Black", DodgerBlue); } else { ObjectMove("MarginPercent", 0, Time[0], Close[0]); } } if (ObjectFind("MidPoint") != 0) { ObjectCreate("MidPoint", OBJ_HLINE, 0, Time[0], MidPoint); ObjectSet("MidPoint", OBJPROP_COLOR, Gold); ObjectSet("MidPoint", OBJPROP_WIDTH, 2); } else { ObjectMove("MidPoint", 0, Time[0], MidPoint); } //QuitTrading(SellOrders); getSessionTarget(); QuitAtTime(endDayHourMinute); return(0); } void Write(string String) { int Handle; if (!Auditing) return; Handle = FileOpen(Filename, FILE_READ|FILE_WRITE|FILE_CSV, "/t"); if (Handle < 1) { Print("Error opening audit file: Code ", GetLastError()); return; } if (!FileSeek(Handle, 0, SEEK_END)) { Print("Error seeking end of audit file: Code ", GetLastError()); return; } if (FileWrite(Handle, TimeToStr(CurTime(), TIME_DATE|TIME_SECONDS) + " " + String) < 1) { Print("Error writing to audit file: Code ", GetLastError()); return; } FileClose(Handle); } int Direction(int tradeDirection) //tradeDirection=1: long, tradeDirection=-1: short { int returnValue; if(UseDPO==True) { if(iMA(Symbol(),PERIOD_M30,2,0,MODE_LWMA,PRICE_WEIGHTED,0)>(iOpen(Symbol(),PERIOD_D1,0)+MarketInfo(Symbol(),MODE_SPREAD)*Point)) {returnValue=1;} // Trade Direction Long if(iMA(Symbol(),PERIOD_M30,2,0,MODE_LWMA,PRICE_WEIGHTED,0)<(iOpen(Symbol(),PERIOD_D1,0)-MarketInfo(Symbol(),MODE_SPREAD)*Point)) {returnValue=-1;} // Trade Direction Short } else { if(tradeDirection==1){returnValue=1;} if(tradeDirection==-1){returnValue=-1;} } return(returnValue); } int CCIDecision(int tradeDirection) { int returnValue; if(UseCCI==true) { double val=(iCCI(NULL,CCIPeriod,14,PRICE_CLOSE,1)); double val1=(iCCI(NULL,PERIOD_M1,14,PRICE_CLOSE,1)); if((val>0)&&(val1>0)){returnValue=1;} if((val<0)&&(val1<0)){returnValue=-1;} } else { if(tradeDirection==1){returnValue=1;} if(tradeDirection==-1){returnValue=-1;} } return(returnValue); } void QuitAtTime(int endDayHour)//input example: close trading tomorrow at 20:59. Today: 14. April, toworrow:15.April. 142059 { int t=TimeDay(TimeCurrent())*10000+TimeHour(TimeCurrent())*100+TimeMinute(TimeCurrent()); if(t>=endDayHour && endDayHour!=0) { CeaseTrading=true; ExitAllTrades(Gold, "Stopped Trading because endtime reached!"); } } int PauseAtTime(int startTime, int endTime, int tradeDirection) { int returnValue; if(startTime!=0 && endTime!=0) { int t=TimeDay(TimeCurrent())*10000+TimeHour(TimeCurrent())*100+TimeMinute(TimeCurrent()); if(t>=startTime && t<=endTime) { returnValue=0; } else { if(tradeDirection==1){returnValue=1;} if(tradeDirection==-1){returnValue=-1;} } } else { if(tradeDirection==1){returnValue=1;} if(tradeDirection==-1){returnValue=-1;} } return (returnValue); } double SessionProfit() { double profitHistory; double profitOpenP; double returnValue; for(int i = OrdersHistoryTotal()-1; i>=0; i--) { OrderSelect(i,SELECT_BY_POS,MODE_HISTORY); if(OrderSymbol()==Symbol() && OrderMagicNumber()==Reference) { if(OrderComment()==TradeComment) { profitHistory +=OrderProfit(); } } } for(int j=OrdersTotal()-1;j>=0;j--) { OrderSelect(j,SELECT_BY_POS,MODE_TRADES); if(OrderSymbol()==Symbol() && OrderMagicNumber()==Reference) { if(OrderComment()==TradeComment) { profitOpenP +=OrderProfit(); } } } returnValue=profitHistory+profitOpenP; return(returnValue); } void getSessionTarget() { if(SessionTarget>0){ if(SessionProfit()>=SessionTarget) { CeaseTrading=true; ExitAllTrades(Aqua, "Session Target Achieved. YUHUUI!"); } } } void ExitAllTrades(color Color, string reason){ bool success; for (int cnt = OrdersTotal() - 1; cnt >= 0; cnt --){ OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference){ success=OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), Slippage, Color); if(success==true){ Print("Closed all positions because ",reason); } } } } void CutTotalLoss() { double TotalLossSell,TotalLossBuy,TotalLoss; // TotalLossBuy = 0; // TotalLossSell = 0; // TotalLoss = 0; for (Order = OrdersTotal() - 1; Order >= 0; Order--) { if (OrderSelect(Order, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_BUY && OrderProfit() < 0) { TotalLossBuy = TotalLossBuy + (OrderProfit() + OrderSwap() + OrderCommission()); } if (OrderSymbol() == Symbol() && OrderMagicNumber() == Reference && OrderType() == OP_SELL && OrderProfit() < 0) { TotalLossSell = TotalLossSell + (OrderProfit() + OrderSwap() + OrderCommission()); } } } TotalLoss = MathAbs(TotalLossBuy + TotalLossSell); if (TotalLossBuy < 0 || TotalLossSell < 0 && TotalLoss >= SLTotalinDollar) { if ((TimeCurrent()-OrderOpenTime()>=CloseDelay)) { ExitAllTrades(Aqua,"SLTotalinDollar was reached"); Error = GetLastError(); if (Error != 0) Write("Error closing BUY order " + OrderTicket() + ": " + ErrorDescription(Error) + " (A" + Error + ") Lots:" + OrderLots() + " Bid:" + MarketInfo(OrderSymbol(), MODE_BID)); CeaseTrading = true; } } return; }