//+------------------------------------------------------------------+ //| BarTrader_EA.mq4 | //| Copyright © 2008 | //| Converted from mt3 by MrPip for yahoo group | /* Name := BARTRADER Author := FAB4X Link := http://www.FAB4X.com Notes := Use on 15 or 30m charts */ //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, MrPip" #include <stdlib.mqh> extern int MagicNumberBase = 200000; extern int BuyGap = 17; extern int SellGap = 13; //+---------------------------------------------------+ //|Money Management | //+---------------------------------------------------+ extern string mm = "---Money Management---"; extern double Lots=1.0; extern double MaxLots = 100; extern bool UseMoneyManagement = true; // Change to false to shutdown money management controls. extern bool BrokerIsIBFX = false; extern string m1="Set mini and micro to false for standard account"; extern bool AccountIsMini = false; extern bool AccountIsMicro = false; extern string fm="UseFreeMargin = false to use Account Balance"; extern bool UseFreeMargin = false; extern double TradeSizePercent = 7.5; // Change to whatever percent of equity you wish to risk. extern bool BrokerPermitsFractionalLots = true; //+---------------------------------------------------+ //|Profit controls | //+---------------------------------------------------+ extern string st6 = "--Profit Controls--"; extern double StopLoss = 45; // Maximum pips willing to lose per position. extern int TakeProfit = 25; // Maximum profit level achieved. //***************************************************** // These inputs are used by the trailing stop function //***************************************************** extern string tsp0 = "--Trailing Stop Types--"; extern string tsp1 = " 1 = Trail immediately"; extern string tsp2 = " 2 = Wait to trail"; extern string tsp3 = " 3 = Uses 3 levels before trail"; extern bool UseTrailingStop = false; extern int TrailingStopType = 1; // Type 1 moves stop immediately, Type 2 waits til value of TS is reached extern string ts2 = "Settings for Type 2"; extern double TrailingStop = 40; // Change to whatever number of pips you wish to trail your position with. extern string ts3 = "Settings for Type 3"; extern double FirstMove = 20; // Type 3 first level pip gain extern double FirstStopLoss = 15; // Move Stop to Breakeven extern double SecondMove = 30; // Type 3 second level pip gain extern double SecondStopLoss = 20; // Move stop to lock is profit extern double ThirdMove = 40; // type 3 third level pip gain extern double TrailingStop3 = 20; // Move stop and trail from there extern int Slippage = 5; // Possible fix for not getting closed 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 bool YesStop; //+---------------------------------------------------+ //|General controls | //+---------------------------------------------------+ int MagicNumber=0; string setup; double lotMM; int TradesInThisSymbol; double myPoint; datetime vTime = 0; double myHigh,myLow,myClose,Pivot,BuyPrice,SellPrice; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- MagicNumber = MagicNumberBase + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); myPoint = SetPoint(Symbol()); Slippage = Slippage*myPoint; return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- double myStopLong, myStopShort; double myTakeLong, myTakeShort; // Check for valid inputs if (CheckValidUserInputs()) return(0); //+------------------------------------------------------------------+ //| Check for Open Position | //+------------------------------------------------------------------+ HandleOpenPositions(); // Check if any open positions were not closed TradesInThisSymbol = CheckOpenPositions(); //+------------------------------------------------------------------+ //| Check if OK to make new trades | //+------------------------------------------------------------------+ // Only allow 1 trade per Symbol if(TradesInThisSymbol > 0) { return(0);} YesStop = false; if (UseTradingHours == 1) { YesStop = CheckTradingTimes(); if (YesStop == true) { Comment ("Trading has been stopped - wrong time of day"); } else { Comment ("Trading has resumed - time is OK"); } } else Comment ("Trading Time Filter not in use"); if (YesStop == false) { myHigh=High[1]; myLow=Low[1]; myClose=Close[1]; Pivot = ( myHigh+myLow+myClose )/ 3 ; BuyPrice=Pivot+BuyGap*myPoint; SellPrice=Pivot-SellGap*myPoint; lotMM = GetLots(); ////////////////////////////////////////////////// // Open Trade at start of bar! ////////////////////////////////////////////////// if (vTime != Time[0]) { vTime = Time[0]; myStopLong = StopLong(BuyPrice,StopLoss,myPoint); myStopLong = ValidStopLoss(Symbol(), OP_BUY, Bid, myStopLong, myPoint); myTakeLong = TakeLong(BuyPrice,TakeProfit,myPoint); BuyPrice = NormalizeDouble( BuyPrice, Digits); myStopLong = NormalizeDouble( myStopLong, Digits); myTakeLong = NormalizeDouble( myTakeLong, Digits); OrderSend(Symbol(), OP_BUYSTOP,lotMM,BuyPrice,Slippage,myStopLong,myTakeLong, "", MagicNumber, 0, Blue); myStopShort = StopShort(SellPrice,StopLoss,myPoint); myStopShort = ValidStopLoss(Symbol(), OP_SELL, Ask, myStopShort, myPoint); myTakeShort = TakeShort(SellPrice,TakeProfit,myPoint); SellPrice = NormalizeDouble( SellPrice, Digits); myStopShort = NormalizeDouble( myStopShort, Digits); myTakeShort = NormalizeDouble( myTakeShort, Digits); OrderSend(Symbol(), OP_SELLSTOP,lotMM,SellPrice,Slippage,myStopShort,myTakeShort, "", MagicNumber, 0,Red); } } //---- return(0); } //+------------------------------------------------------------------+ //| Functions beyond this point should not need to be modified | //| Eventually will be placed in include file | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Check Open Position Controls | //+------------------------------------------------------------------+ int CheckOpenPositions() { int cnt, NumPositions; int NumBuyTrades, NumSellTrades; // Number of buy and sell trades in this symbol NumBuyTrades = 0; NumSellTrades = 0; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY ) NumBuyTrades++; if(OrderType() == OP_SELL ) NumSellTrades++; } NumPositions = NumBuyTrades + NumSellTrades; return (NumPositions); } //+------------------------------------------------------------------+ //| Handle Open Positions | //| Check if any open positions need to be closed or modified | // Close Order after each bar! //+------------------------------------------------------------------+ int HandleOpenPositions() { int cnt; bool YesClose; double pt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY) { if (vTime != Time[0]) { CloseOrder(OrderTicket(),OrderLots(),Bid); } else { if (UseTrailingStop) { HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()); } } } if(OrderType() == OP_SELL) { if (vTime != Time[0]) { CloseOrder(OrderTicket(),OrderLots(),Ask); } else { if(UseTrailingStop) { HandleTrailingStop(OP_SELL,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit()); } } } if (OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) { if (vTime != Time[0]) OrderDelete(OrderTicket(),Brown); } } } //+------------------------------------------------------------------+ //| Close Open Position Controls | //| Try to close position 3 times | //+------------------------------------------------------------------+ void CloseOrder(int ticket,double numLots,double close_price) { int CloseCnt, err; // try to close 3 Times CloseCnt = 0; while (CloseCnt < 3) { if (OrderClose(ticket,numLots,close_price,Slippage,Violet)) { CloseCnt = 3; } else { err=GetLastError(); Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err)); if (err > 0) CloseCnt++; } } } //***************************************************** // This function is used by the trailing stop function //***************************************************** //+------------------------------------------------------------------+ //| Modify Open Position Controls | //| Try to modify position 3 times | //+------------------------------------------------------------------+ void 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++; } } } //+------------------------------------------------------------------+ //| HandleTrailingStop | //| Type 1 moves the stoploss without delay. | //| Type 2 waits for price to move the amount of the trailStop | //| before moving stop loss then moves like type 1 | //| Type 3 uses up to 3 levels for trailing stop | //| Level 1 Move stop to 1st level | //| Level 2 Move stop to 2nd level | //| Level 3 Trail like type 1 by fixed amount other than 1 | //| Possible future types | //| Type 4 uses 2 for 1, every 2 pip move moves stop 1 pip | //| Type 5 uses 3 for 1, every 3 pip move moves stop 1 pip | //+------------------------------------------------------------------+ int HandleTrailingStop(int type, int ticket, double op, double os, double tp) { double pt, TS=0, myAsk, myBid; if (type == OP_BUY) { myBid = MarketInfo(Symbol(),MODE_BID); switch(TrailingStopType) { case 1: pt = myPoint*StopLoss; if(myBid-os > pt) ModifyOrder(ticket,op,myBid-pt,tp, Aqua); break; case 2: pt = myPoint*TrailingStop; if(myBid-op > pt && os < myBid - pt) ModifyOrder(ticket,op,myBid - pt,tp, Aqua); break; case 3: if (myBid - op > FirstMove * myPoint) { TS = op + FirstMove*myPoint - FirstStopLoss * myPoint; if (os < TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } if (myBid - op > SecondMove * myPoint) { TS = op + SecondMove*myPoint - SecondStopLoss * myPoint; if (os < TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } if (myBid - op > ThirdMove * myPoint) { TS = myBid - TrailingStop3*myPoint; if (os < TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } break; } return(0); } if (type == OP_SELL) { myAsk = MarketInfo(Symbol(),MODE_ASK); switch(TrailingStopType) { case 1: pt = myPoint*StopLoss; if(os - myAsk > pt) ModifyOrder(ticket,op,myAsk+pt,tp, Aqua); break; case 2: pt = myPoint*TrailingStop; if(op - myAsk > pt && os > myAsk+pt) ModifyOrder(ticket,op,myAsk+pt,tp, Aqua); break; case 3: if (op - myAsk > FirstMove * myPoint) { TS = op - FirstMove * myPoint + FirstStopLoss * myPoint; if (os > TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } if (op - myAsk > SecondMove * myPoint) { TS = op - SecondMove * myPoint + SecondStopLoss * myPoint; if (os > TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } if (op - myAsk > ThirdMove * myPoint) { TS = myAsk + TrailingStop3 * myPoint; if (os > TS) { ModifyOrder(ticket,op,TS,tp, Aqua); } } break; } } return(0); } //+------------------------------------------------------------------+ //| Get number of lots for this trade | //+------------------------------------------------------------------+ double GetLots() { double lot; if(UseMoneyManagement == true) { lot = LotsOptimized(); } else { lot = Lots; } // Use at least 1 micro lot if (AccountIsMicro == true) { if (lot < 0.01) lot = 0.01; if (lot > MaxLots) lot = MaxLots * 100; if (BrokerIsIBFX == true) lot = lot * 10; return(lot); } // Use at least 1 mini lot if(AccountIsMini == true) { if (lot < 0.1) lot = 0.1; if (lot > MaxLots) lot = MaxLots; if (BrokerIsIBFX == true) lot = lot * 10; return(lot); } // Standard account if( BrokerPermitsFractionalLots == false) { if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0; } if (lot > MaxLots) lot = MaxLots; return(lot); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=Lots; //---- select lot size lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradeSizePercent/10000)/10,1); // lot at this point is number of standard lots // if (Debug) Print ("Lots in LotsOptimized : ",lot); // Check if mini or standard Account if(AccountIsMini) { lot = MathFloor(lot*10)/10; // Use at least 1 mini lot if(lot<0.1) lot=0.1; if (lot > MaxLots) lot = MaxLots; }else { if (lot < 1.0) lot = 1.0; if (lot > MaxLots) lot = MaxLots; } return(lot); } // 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); } double StopLong(double price,int stop, double mPoint) { if(stop==0) return(0); else return(price-(stop*mPoint)); } double StopShort(double price,int stop, double mPoint) { if(stop==0) return(0); else return(price+(stop*mPoint)); } double TakeLong(double price,int take, double mPoint) { if(take==0) return(0); else return(price+(take*mPoint)); } double TakeShort(double price,int take, double mPoint) { if(take==0) return(0); else return(price-(take*mPoint)); } double ValidStopLoss(string mySymbol, int type, double price, double SL, double mPoint) { double minstop; if (SL < 0.1) return(SL); minstop = MarketInfo(mySymbol,MODE_STOPLEVEL); if (type == OP_BUY) { if((price - SL) < minstop*mPoint) SL = price - minstop*mPoint; } if (type == OP_SELL) { if((SL-price) < minstop*mPoint) SL = price + minstop*mPoint; } return(SL); } //+------------------------------------------------------------------+ //| CheckValidUserInputs | //| Check if User Inputs are valid for ranges allowed | //| return true if invalid input, false otherwise | //| Also display an alert for invalid input | //+------------------------------------------------------------------+ bool CheckValidUserInputs() { if (CheckTrailingStopType(TrailingStopType)) { Alert("TrailingStopType( 1 to 3) You entered ",TrailingStopType); return(true); } } //+------------------------------------------------+ //| Check for valid TrailingStopType | //| | //| return true if invalid, false if OK | //+------------------------------------------------+ bool CheckTrailingStopType(int stop_type) { if (stop_type < 0 ) return(true); if (stop_type > 3) return(true); return(false); } int func_Symbol2Val(string symbol) { string mySymbol = StringSubstr(symbol,0,6); if(mySymbol=="AUDCAD") return(1); if(mySymbol=="AUDJPY") return(2); if(mySymbol=="AUDNZD") return(3); if(mySymbol=="AUDUSD") return(4); if(mySymbol=="CHFJPY") return(5); if(mySymbol=="EURAUD") return(6); if(mySymbol=="EURCAD") return(7); if(mySymbol=="EURCHF") return(8); if(mySymbol=="EURGBP") return(9); if(mySymbol=="EURJPY") return(10); if(mySymbol=="EURUSD") return(11); if(mySymbol=="GBPCHF") return(12); if(mySymbol=="GBPJPY") return(13); if(mySymbol=="GBPUSD") return(14); if(mySymbol=="NZDJPY") return(15); if(mySymbol=="NZDUSD") return(16); if(mySymbol=="USDCAD") return(17); if(mySymbol=="USDCHF") return(18); if(mySymbol=="USDJPY") return(19); Comment("unexpected Symbol"); return(999); } //+------------------------------------------------------------------+ //| Time frame interval appropriation function | //+------------------------------------------------------------------+ int func_TimeFrame_Const2Val(int Constant ) { switch(Constant) { case 1: // M1 return(1); case 5: // M5 return(2); case 15: return(3); case 30: return(4); case 60: return(5); case 240: return(6); case 1440: return(7); case 10080: return(8); case 43200: return(9); } } double SetPoint(string mySymbol) { double mPoint, myDigits; myDigits = MarketInfo (mySymbol, MODE_DIGITS); if (myDigits < 4) mPoint = 0.01; else mPoint = 0.0001; return(mPoint); } //+------------------------------------------------------------------+
Sample
Analysis
Market Information Used:
Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains close prices for each bar
Series array that contains open time of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
It automatically opens orders when conditions are reached
Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
Other Features:
It issuies visual alerts to the screen