//+------------------------------------------------------------------+ //| SimpleSystem.mq4 | //| Copyright © 2009, Shivanand and Robert Hill | //| | //| //| Based on post by Shivanand //| 5 M Chart (EUR/USD, GBP/USD) //| //| Plot 20 SMA //| Plot 20 CCI with levels 100, 0, -100 //| //| When CCI crosses up 50 level AND when price breaks above 20 SMA, //| at the OPEN of the next candle that OPENS ABOVE 20 SMA go LONG for TP of 5 to 15. //| SL = Low of the Preceding candle (The one which broke above 20 SMA) //| //| Vice versa for SHORT ops. //| //+------------------------------------------------------------------+ #property copyright "Shivanand and Robert Hill" #property link "" #include #include extern int MagicNumber = 20050610; extern string UserComment = "SimpleSystem_EA"; extern double Lots = 0.1; extern bool UseMM = false; extern double MaximumRisk = 0.02; extern double DecreaseFactor = 3; extern double SMA_Period = 20; extern int CCI_Period = 20; extern int TakeProfit = 10; extern int MinStopLoss = 0;// 0= no stoploss extern int Slippage = 3; extern string ts0 = "---TrailingStopLoss---"; extern string ts1 = " 1. None"; extern string ts2 = " 2. Standard at input"; extern string ts3 = " 3. Trail immediately"; extern int TSMethod = 2; extern string ts12 = "Settings for Type 2"; extern double TrailingStop = 20; double myPoint; int StopLoss; int init() { myPoint = SetPoint(); return(0); } //-- Check for Start of a new Bar bool NewBar() { static datetime dt = 0; if (Time[0] != dt) { dt = Time[0]; return(true); } return(false); } //+------------------------------------------------------------------+ //| Check for open order conditions | //| When CCI crosses up 50 level AND when price breaks above 20 SMA, //| at the OPEN of the next candle that OPENS ABOVE 20 SMA go LONG for TP of 5 to 15. //| SL = Low of the Preceding candle (The one which broke above 20 SMA) //+------------------------------------------------------------------+ void CheckForOpen() { double ma_cur, ma_prev, cci; //---- get Moving Average ma_cur=iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,0); ma_prev=iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,1); cci = iCCI(NULL, 0, CCI_Period, PRICE_CLOSE, 1); //---- buy conditions if(Open[0]>ma_cur && High[1]>ma_prev && Open[1] < ma_prev && cci > 50) { // Set stoploss in pips for trailing to work StopLoss = (Bid - Low[1]) / myPoint; if (StopLoss < MinStopLoss) StopLoss = MinStopLoss; OpenTrade(OP_BUY); return; } //---- sell conditions if(Open[0] ma_prev && cci < -50) { StopLoss = (High[1] - Ask) / myPoint; if (StopLoss < MinStopLoss) StopLoss = MinStopLoss; OpenTrade(OP_SELL); return; } //---- } //+------------------------------------------------------------------+ //| Check for close order conditions | //+------------------------------------------------------------------+ void CheckForClose() { double ma; //---- get Moving Average ma=iMA(NULL,0,SMA_Period,0,MODE_SMA,PRICE_CLOSE,0); //---- for(int i=0;ima && Close[1]ma) OrderClose(OrderTicket(),OrderLots(),Ask,3,White); else HandleTrailingStop(OP_SELL, OrderTicket(), OrderOpenPrice(), OrderStopLoss(), OrderTakeProfit()); } } //---- } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { //---- check for history and trading if(Bars<100 || IsTradeAllowed()==false) return; //---- calculate open orders if(CalculateCurrentOrders()==0) { if (NewBar()) CheckForOpen(); } else CheckForClose(); //---- } void OpenTrade(int signal) { int res, err, ticket; double mLots; double TPprice,STprice; RefreshRates(); mLots = LotsOptimized(); if (signal==OP_BUY) { res=OrderSend(Symbol(),OP_BUY,mLots,Ask,Slippage,0,0,UserComment,MagicNumber,0,Green); if (res > 0) { ticket = res; OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) TPprice=TakeLong(OrderOpenPrice(), TakeProfit); STprice = 0; if (StopLoss > 0) { STprice=StopLong(Bid, 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); } } } else if (signal==OP_SELL) { res=OrderSend(Symbol(),OP_SELL,mLots,Bid,Slippage,0,0,UserComment,MagicNumber,0,Red); if (res > 0) { ticket = res; OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) TPprice=TakeShort(OrderOpenPrice(),TakeProfit); STprice = 0; if (StopLoss > 0) { STprice=StopShort(OrderOpenPrice() ,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); } } } if(res<0) { err = GetLastError(); Print("OrderSend failed with error(" + err + ") " + ErrorDescription(err) + " Lots:" + DoubleToStr(mLots, 2) ); } return; } int ModifyOrder(int ord_ticket,double op, double oSL, double oTP, color mColor) { int CloseCnt, err; double myStop, myTake; CloseCnt=0; while (CloseCnt < 3) { if (OrderModify(ord_ticket,op,oSL,oTP,0,mColor)) { CloseCnt = 3; } else { err=GetLastError(); Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err)); if (err>0) CloseCnt++; } } } //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders() { int buys=0,sells=0; //---- for(int i=0;i0) return(buys); else return(-sells); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot; int orders=HistoryTotal(); // history orders total int losses=0; // number of losses orders without a break if (!UseMM) return(Lots); //---- select lot size lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); //---- calcuulate number of losses orders without a break if(DecreaseFactor>0) { for(int i=orders-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; //---- if(OrderProfit()>0) break; if(OrderProfit()<0) losses++; } if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } //---- return lot size if(lot<0.1) lot=0.1; return(lot); } double SetPoint() { double mPoint; if (Digits < 4) mPoint = 0.01; else mPoint = 0.0001; return(mPoint); } double StopLong(double price,int stop) { if(stop==0) return(0); else return(price-(stop*myPoint)); } double StopShort(double price,int stop) { if(stop==0) return(0); else return(price+(stop*myPoint)); } double TakeLong(double price,int take) { if(take==0) return(0); else return(price+(take*myPoint)); } double TakeShort(double price,int take) { if(take==0) return(0); else return(price-(take*myPoint)); } double ValidStopLoss(int type, double price, double SL) { double minstop; if (SL < 0.1) return(SL); minstop = MarketInfo(Symbol(),MODE_STOPLEVEL); if (Digits == 3 || Digits == 5) minstop = minstop / 10; if (type == OP_BUY) { if((price - SL) < minstop*myPoint) SL = price - minstop*myPoint; } if (type == OP_SELL) { if((SL-price) < minstop*myPoint) SL = price + minstop*myPoint; } return(SL); } //+------------------------------------------------------------------+ //| HandleTrailingStop | //| Type 1 is do not trail | //| Type 2 waits for price to move the amount of the trailStop | //| before moving stop loss then moves like type 4 | //| Type 3 moves the stoploss without delay. | //+------------------------------------------------------------------+ void HandleTrailingStop(int cmd, int ticket, double op, double os, double tp) { switch (TSMethod) { case 2 : Delayed_TrailingStop (cmd, ticket, op, os, tp); break; case 3 : Immediate_TrailingStop (cmd, ticket, op, os, tp); break; } } //+------------------------------------------------------------------+ //| Immediate_TrailingStop.mq4 | //| Copyright © 2006, Forex-TSD.com | //| Written by MrPip,robydoby314@yahoo.com | //| | //| Moves the stoploss without delay. | //+------------------------------------------------------------------+ void Immediate_TrailingStop(int type, int ticket, double op, double os, double tp) { int digits; double pt, pBid, pAsk, BuyStop, SellStop; digits = MarketInfo(Symbol( ), MODE_DIGITS); if (type==OP_BUY) { pBid = MarketInfo(Symbol(), MODE_BID); pt = StopLoss * myPoint; if(pBid-os > pt) { BuyStop = pBid - pt; if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits); BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop); if (os < BuyStop) OrderModify(ticket,op,BuyStop,tp, 0,LightGreen); return; } } if (type==OP_SELL) { pAsk = MarketInfo(Symbol(), MODE_ASK); pt = StopLoss * myPoint; if(os - pAsk > pt) { SellStop = pAsk + pt; if (digits > 0) SellStop = NormalizeDouble( SellStop, digits); SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop); if (os > SellStop) OrderModify(ticket,op,SellStop,tp,0, DarkOrange); return; } } } //+------------------------------------------------------------------+ //| Delayed_TrailingStop.mq4 | //| Copyright © 2006, Forex-TSD.com | //| Written by MrPip,robydoby314@yahoo.com | //| | //| Waits for price to move the amount of the TrailingStop | //| Moves the stoploss pip for pip after delay. | //+------------------------------------------------------------------+ void Delayed_TrailingStop(int type, int ticket, double op, double os, double tp) { int digits; double pt, pBid, pAsk, BuyStop, SellStop; pt = TrailingStop * myPoint; digits = MarketInfo(Symbol(), MODE_DIGITS); if (type==OP_BUY) { pBid = MarketInfo(Symbol(), MODE_BID); BuyStop = pBid - pt; if (digits > 0) BuyStop = NormalizeDouble( BuyStop, digits); BuyStop = ValidStopLoss(OP_BUY,pBid, BuyStop); if (pBid-op > pt && os < BuyStop) OrderModify(ticket,op,BuyStop,tp,0,LightGreen); return; } if (type==OP_SELL) { pAsk = MarketInfo(Symbol(), MODE_ASK); pt = TrailingStop * myPoint; SellStop = pAsk + pt; if (digits > 0) SellStop = NormalizeDouble( SellStop, digits); SellStop = ValidStopLoss(OP_SELL, pAsk, SellStop); if (op - pAsk > pt && os > SellStop) OrderModify(ticket,op,SellStop,tp,0,DarkOrange); return; } } //+------------------------------------------------------------------+