//+------------------------------------------------------------------+ //| Martingale Grid.mq4 | //| Copyright © 2010 Boston Technologies | //| http://www.bostontechnologies.com | //+------------------------------------------------------------------+ #define DECIMAL_CONVERSION 10 #define COMMENT_DIGITS 2 // defines for evaluating entry conditions #define INITIAL_CROSS_BAR 2 #define LAST_BAR 1 #define THIS_BAR 0 #define NEGATIVE_VALUE -1 // defines for managing trade orders #define RETRYCOUNT 10 #define RETRYDELAY 500 #define LONG 1 #define SHORT -1 #define ALL 0 #define ORDER_COMMENT "Martingale Order" #define L1L "Level 1 Long" #define L1S "Level 1 Short" #property copyright "Boston Technologies" #property link "www.bostontechnologies.com" extern double InitialLots = 0.1; extern double MartingaleMultiplier = 2.0; extern int Levels.Per.Direction = 3; extern int Level.Distance = 10; extern int Stop = 0; extern int TakeProfit = 10; extern double TP.in.Dollars = 100; extern int TrailStart = 50; extern int TrailAmount = 10; extern int MagicNumber = 99945; extern bool WriteScreenshots = true; datetime lastTradeTime, lastTradeLevel2, orderPlacementTime; int Slippage = 2; int handle; string display = ""; double trailStart, trailAmount, pl, entryDistance; int orders.Long, orders.Short, orders.LimitLong, orders.LimitShort; int init() { if (Digits == 3 || Digits == 5) { Stop *= DECIMAL_CONVERSION; TakeProfit *= DECIMAL_CONVERSION; TrailStart *= DECIMAL_CONVERSION; TrailAmount *= DECIMAL_CONVERSION; Level.Distance *= DECIMAL_CONVERSION; } trailStart = TrailStart * Point; trailAmount = TrailAmount * Point; entryDistance = Level.Distance * Point; lastTradeTime = Time[1]; Print("Broker: " + AccountCompany()); return(0); } int deinit() { return(0); } int start() { display = ""; double lots = InitialLots; if( NoOpenPositionsExist( ORDER_COMMENT ) ) { DoPending(LONG, OP_BUYLIMIT, Ask - entryDistance, lots, Stop, TakeProfit, L1L); DoPending(SHORT, OP_SELLLIMIT, Bid + entryDistance, lots, Stop, TakeProfit, L1S); for( int i = 2; i <= Levels.Per.Direction; i++ ) { lots *= MartingaleMultiplier; DoPending(LONG, OP_BUYLIMIT, Ask - entryDistance * i, lots, Stop, TakeProfit, ORDER_COMMENT); DoPending(SHORT, OP_SELLLIMIT, Bid + entryDistance * i, lots, Stop, TakeProfit, ORDER_COMMENT); } } int orders.Total = CountOrders(); if( orders.Long + orders.LimitLong < Levels.Per.Direction ) { DeletePendings( LONG ); ExitAll( LONG ); if( orders.LimitShort == Levels.Per.Direction ) { /*if( DeletePendings( SHORT ) ) { Print("Short pendings deleted ok"); } else { Print("Short orders failed to delete"); }*/ DeletePendings( SHORT ); } } Comment("Limit shorts: " + orders.LimitShort + "\nLevels per direction: " + Levels.Per.Direction); if( orders.Short + orders.LimitShort < Levels.Per.Direction ) { DeletePendings( SHORT); ExitAll( SHORT ); if( orders.LimitLong == Levels.Per.Direction ) { DeletePendings( LONG ); } } if( pl + GetClosedPL(orderPlacementTime) >= TP.in.Dollars ) { ExitAll( LONG ); ExitAll( SHORT ); DeletePendings( SHORT ); DeletePendings( LONG ); } return(0); } double CheckLots(double lots) { double lot, lotmin, lotmax, lotstep, margin; lotmin = MarketInfo(Symbol(), MODE_MINLOT); lotmax = MarketInfo(Symbol(), MODE_MAXLOT); lotstep = MarketInfo(Symbol(), MODE_LOTSTEP); margin = MarketInfo(Symbol(), MODE_MARGINREQUIRED); if (lots*margin > AccountFreeMargin()) lots = AccountFreeMargin() / margin; lot = MathFloor(lots/lotstep + 0.5) * lotstep; if (lot < lotmin) lot = lotmin; if (lot > lotmax) lot = lotmax; return (lot); } void Screenshot(string moment_name) { if ( WriteScreenshots ) WindowScreenShot(WindowExpertName()+"_"+Symbol()+"_M"+Period()+"_"+ Year()+"-"+two_digits(Month())+"-"+two_digits(Day())+"_"+ two_digits(Hour())+"-"+two_digits(Minute())+"-"+two_digits(Seconds())+"_"+ moment_name+".gif", 1024, 768); } string two_digits(int i) { if (i < 10) return ("0"+i); else return (""+i); } bool NoOpenPositionsExist(string theComment) { int total = OrdersTotal(); for(int i = 0; i < total; i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && OrderComment() == theComment) { return (false); } } return (true); } bool Exit(int ticket, int dir, double volume, color clr, int t = 0) { int i, j, cmd; double prc, sl, tp, lots; string cmt; bool closed; Print("Exit("+dir+","+DoubleToStr(volume,3)+","+t+")"); for (i=0; i 0 ) { return( true ); } else { Print("DoPending: error \'"+ErrorDescription(GetLastError())+"\' when setting entry order"); Sleep(RETRYDELAY); } } return( false ); } bool DeletePendings(int direction) { bool retVal; bool pendings; int i; if( orders.LimitShort != 0 && direction == SHORT) { while( orders.LimitShort != 0 ) { for(i = OrdersTotal() - 1; i >= 0; i--) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); pendings = OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP; if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() && pendings ) { OrderDelete( OrderTicket() ); } } CountOrders(); } return( true ); } if( orders.LimitLong != 0 && direction == LONG) { while( orders.LimitLong != 0 ) { for(i = OrdersTotal() - 1; i >= 0; i--) { OrderSelect(i, SELECT_BY_POS, MODE_TRADES); pendings = OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP; if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() ) { OrderDelete( OrderTicket() ); } } CountOrders(); } return( true ); } } int CountOrders() { int count = 0; pl = 0; orders.Long = 0; orders.Short = 0; orders.LimitLong = 0; orders.LimitShort = 0; for( int i = OrdersTotal() - 1; i >= 0; i--) { OrderSelect( i, SELECT_BY_POS); if( OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ) { count++; pl += OrderProfit(); if(OrderType() != OP_BUY && OrderType() != OP_SELL ) { orderPlacementTime = OrderOpenTime(); } if( OrderType() == OP_BUY ) { orders.Long++; } if( OrderType() == OP_SELL ) { orders.Short++; } if( OrderType() == OP_BUYLIMIT ) { orders.LimitLong++; } if( OrderType() == OP_SELLLIMIT ) { orders.LimitShort++; } } } return( count ); } double GetClosedPL( datetime orderPlacementTime) { double closedPL = 0; for( int i = OrdersHistoryTotal() - 1; i >= 0; i--) { OrderSelect( i, SELECT_BY_POS, MODE_HISTORY); if( OrderOpenTime() < orderPlacementTime) { break; } if( OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ) { closedPL += OrderProfit(); } } return( closedPL ); }