//+------------------------------------------------------------------+ //| PriceActionEA.mq4 | //| Copyright © 2011, Robert Hill | //| http://www.mrpipforex.com/ | //| | //| Based on idea from Miguel at Yahoo MTE&I group | //+------------------------------------------------------------------+ #include #include // Add defines for signals #define LONG 1 #define SHORT -1 #define FLAT 0 // MoneyManagement Account Usage #define EQUITY 2 #define MARGIN 3 extern int MagicNumber = 1234567; extern int SignalCandle = 1; extern string UserComment = "PriceAction_EA"; //+---------------------------------------------------+ //|Money Management | //+---------------------------------------------------+ extern string mm = "--- Money Management ---"; extern double Lots=0.1; extern bool UseMoneyManagement = false; extern double TradeRiskPercent = 1; // Change to whatever percent of equity you wish to risk. extern string mm0 = "MM Method"; extern string mm1 = " 1. AccountBalance"; extern string mm2 = " 2. Free Margin"; extern int mmMethod = 1; extern int TakeProfit = 0; extern int StopLoss=0; extern int Slippage = 3; extern string sm0="--Trading Hours Filter--"; extern string sm1=" Times are GMT when UseDST=false"; extern string sm2="UseTradingHours - Enter 0 for false, 1 for true"; extern int UseTradingHours = 0; extern string sm4="TradeAsian - Enter 0 for false, 1 for true"; extern int TradeAsianMarket = 1; extern int AsianStart = 100; // Start trades after time extern int AsianStop = 300; // Stop trading after time extern string sm5="Trade Europe - Enter 0 for false, 1 for true"; extern int TradeEuropeanMarket = 1; extern int EurStart = 900; // Start trades after time extern int EurStop = 1100; // Stop trading after time extern string sm6="Trade NY - Enter 0 for false, 1 for true"; extern int TradeNewYorkMarket = 0; extern int NYStart = 1300; // Start trades after time extern int NYStop = 1500; // Stop trading after time double myPoint; double mLots; bool YesStop; double TPprice, STprice; int init() { myPoint = SetPoint(); return(0); } int deinit() { return(0); } //+------------------------------------------------------------------+ //| GetSignal | //| | //| BUY Signal | //| Rule1: Prior candle open is less than close (up candle) | //| SELL Signal | //| Rule1: Prior candle open is greater than close (down candle) | //+------------------------------------------------------------------+ int GetEntrySignal() { //---- Buy conditions if (Open[SignalCandle] < Close[SignalCandle]) return(LONG); //---- Sell conditions if (Open[SignalCandle] > Close[SignalCandle]) return(SHORT); return (FLAT); } //+------------------------------------------------------------------+ //| Close at close of candle | //+------------------------------------------------------------------+ bool CheckExitCondition(int cmd, int ticket, double ol) { int Signal; if (!NewBar()) return(false); //---- if(cmd==OP_BUY) { CloseOrder(ticket,ol,OP_BUY); return(true); } if(cmd==OP_SELL) { CloseOrder(ticket,ol,OP_SELL); return(true); } return(false); //---- } //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { int NumOrders = 0, Position, signal; RefreshRates(); if (IsTradeAllowed()==false ) return(0); //+------------------------------------------------------------------+ //| Check for Open Position | //+------------------------------------------------------------------+ // Only allow 1 trade per Symbol // Handle bug where there are 2 orders on pair NumOrders = CalculateCurrentOrders(); if (NumOrders > 0) { HandleOpenPositions(); return(0); } YesStop = CheckTradeFilters(); if (YesStop == false) { signal=GetEntrySignal(); if (signal != FLAT) { mLots = GetLots(StopLoss); if(AccountFreeMargin()<(1000*mLots)) { Comment("We have no money. Free Margin = " + AccountFreeMargin()); return(0); } if(signal == LONG) { OpenTrade(OP_BUY, mLots); return; } if(signal == SHORT) { OpenTrade(OP_SELL, mLots); } } } return(0); //---- } int OpenTrade(int signal, double mLots) { int err, ticket; RefreshRates(); if (signal==OP_BUY) { ticket= OrderSend(Symbol(),OP_BUY,mLots,Ask,Slippage,0,0,UserComment,MagicNumber,0,Green); if (ticket > 0) { TPprice = 0; STprice = 0; if (StopLoss != 0 || TakeProfit != 0) { OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); if (TakeProfit > 0) { TPprice=TakeLong(OrderOpenPrice(), TakeProfit); TPprice = ValidTakeProfit(OP_BUY,Ask, TPprice); } if (StopLoss > 0) { STprice=StopLong(OrderOpenPrice(), 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); } OrderModify(ticket, OrderOpenPrice(), STprice, TPprice, 0, LightGreen); } } } else if (signal==OP_SELL) { ticket=OrderSend(Symbol(),OP_SELL,mLots,Bid,Slippage,0,0,UserComment,MagicNumber,0,Red); if (ticket > 0) { TPprice = 0; STprice = 0; if (StopLoss != 0 || TakeProfit != 0) { OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES); if (TakeProfit > 0) { TPprice=TakeShort(OrderOpenPrice(),TakeProfit); TPprice = ValidTakeProfit(OP_SELL,Bid, TPprice); } 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); } OrderModify(ticket, OrderOpenPrice(), STprice, TPprice, 0, LightGreen); } } } if(ticket<0) { err = GetLastError(); Print("OrderSend failed with error(" + err + ") " + ErrorDescription(err) ); } return(ticket); } //+------------------------------------------------------------------+ //| Handle Open Positions | //| Check if any open positions need to be closed or modified | //+------------------------------------------------------------------+ void HandleOpenPositions() { bool Done; int ticket, OrderTy; double OrderLTS, OrderOP; double OrderTP, OrderSL; int cnt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; ticket = OrderTicket(); OrderTy = OrderType(); OrderLTS = OrderLots(); OrderOP = NormalizeDouble(OrderOpenPrice(), Digits); OrderTP = OrderTakeProfit(); OrderSL = NormalizeDouble(OrderStopLoss(), Digits); // Check for TakeProfit Exits Done = false; Done = CheckTPClose(OrderTy, ticket, OrderLTS, TPprice); if (Done == true) return; // Check for internal StopLoss Done = false; Done = CheckSLClose(OrderTy, ticket, OrderLTS, STprice); if (Done == true) return; // Check for exit on signal Done = false; Done = CheckExitCondition(OrderTy, ticket, OrderLTS); if (Done == true) return; } } bool CheckSLClose(int cmd, int ticket, double ol, double IntSTprice) { if (cmd == OP_BUY) { if(Bid <= IntSTprice) { CloseOrder(ticket,ol,OP_BUY); return (true); } return(false); } if (cmd == OP_SELL) { if (IntSTprice > 0.1) { if(Ask >= IntSTprice) { CloseOrder(ticket,ol,OP_SELL); return(true); } } } return(false); } bool CheckTPClose(int cmd, int ticket, double ol, double IntTPprice ) { if (cmd == OP_BUY) { if(Bid >= IntTPprice && IntTPprice > 0.1) { CloseOrder(ticket,ol,OP_BUY); return(true); } return(false); } if (cmd == OP_SELL) { if(Ask <= IntTPprice) { CloseOrder(ticket,ol,OP_SELL); return(true); } } return(false); } int CloseOrder(int ticket,double numLots,int cmd) { bool result; int 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); result = OrderClose(ticket,numLots,myPrice,Slippage,Violet); if (result) return(true); err = GetLastError(); Print(" Error closing order : (", err , ") " + ErrorDescription(err)); return(false); } //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders() { int buys=0,sells=0, num = 0; //---- for(int i=0;i myMaxLot) lot = myMaxLot; return(lot); } bool NewBar() { static datetime dt = 0; if (Time[0] != dt) { dt = Time[0]; return(true); } return(false); } bool CheckTradeFilters() { bool myStop, Expired; double CurrentSpread; myStop = false; if (myStop ==false) { if (UseTradingHours == 1) { myStop = CheckTradingTimes(); } } return(myStop); } // Return true if time is not in session for trading bool CheckOutsideSession( int StartHour, int EndHour, int ct) { if(StartHour<=EndHour) { if(ct < StartHour || ct > EndHour) return(true) ; } else { if(ct > EndHour && ct < StartHour) return(true) ; } return(false) ; } bool CheckTradingTimes() { bool StopTrading; int ct; ct = Hour() * 100 + Minute(); StopTrading = true; // Check trading Asian Market if (TradeAsianMarket == 1) { StopTrading = CheckOutsideSession(AsianStart, AsianStop, ct); } if (StopTrading == true) { // Check trading European Market if (TradeEuropeanMarket == 1) { StopTrading = CheckOutsideSession(EurStart, EurStop, ct); } } if (StopTrading == true) { // Check trading New York Market if (TradeNewYorkMarket == 1) { StopTrading = CheckOutsideSession(NYStart, NYStop, ct); } } return(StopTrading); } //+------------------------------------------------------------------+