วันอังคารที่ 21 พฤษภาคม พ.ศ. 2556

simple grid



//+------------------------------------------------------------------+
//|                                              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<RETRYCOUNT; i++) {
        for (j=0; (j<50) && IsTradeContextBusy(); j++)
            Sleep(100);
        RefreshRates();

        if (dir == LONG) {
            prc = Bid;
        }
        if (dir == SHORT) {
            prc = Ask;
       }
        Print("Exit: prc="+DoubleToStr(prc,Digits));

        closed = OrderClose(ticket,volume,prc,Slippage,clr);
        if (closed) {
            Print("Trade closed");
            Screenshot("Exit");

            return (true);
        }

        Print("Exit: error \'"+ErrorDescription(GetLastError())+"\' when exiting with "+DoubleToStr(volume,3)+" @"+DoubleToStr(prc,Digits));
        Sleep(RETRYDELAY);
    }

    Print("Exit: can\'t enter after "+RETRYCOUNT+" retries");
    return (false);
}

string ErrorDescription(int error_code)
{
    string error_string;

    switch( error_code ) {
        case 0:
        case 1:   error_string="no error";                                                  break;
        case 2:   error_string="common error";                                              break;
        case 3:   error_string="invalid trade parameters";                                  break;
        case 4:   error_string="trade server is busy";                                      break;
        case 5:   error_string="old version of the client terminal";                        break;
        case 6:   error_string="no connection with trade server";                           break;
        case 7:   error_string="not enough rights";                                         break;
        case 8:   error_string="too frequent requests";                                     break;
        case 9:   error_string="malfunctional trade operation (never returned error)";      break;
        case 64:  error_string="account disabled";                                          break;
        case 65:  error_string="invalid account";                                           break;
        case 128: error_string="trade timeout";                                             break;
        case 129: error_string="invalid price";                                             break;
        case 130: error_string="invalid stops";                                             break;
        case 131: error_string="invalid trade volume";                                      break;
        case 132: error_string="market is closed";                                          break;
        case 133: error_string="trade is disabled";                                         break;
        case 134: error_string="not enough money";                                          break;
        case 135: error_string="price changed";                                             break;
        case 136: error_string="off quotes";                                                break;
        case 137: error_string="broker is busy (never returned error)";                     break;
        case 138: error_string="requote";                                                   break;
        case 139: error_string="order is locked";                                           break;
        case 140: error_string="long positions only allowed";                               break;
        case 141: error_string="too many requests";                                         break;
        case 145: error_string="modification denied because order too close to market";     break;
        case 146: error_string="trade context is busy";                                     break;
        case 147: error_string="expirations are denied by broker";                          break;
        case 148: error_string="amount of open and pending orders has reached the limit";   break;
        case 149: error_string="hedging is prohibited";                                     break;
        case 150: error_string="prohibited by FIFO rules";                                  break;
        case 4000: error_string="no error (never generated code)";                          break;
        case 4001: error_string="wrong function pointer";                                   break;
        case 4002: error_string="array index is out of range";                              break;
        case 4003: error_string="no memory for function call stack";                        break;
        case 4004: error_string="recursive stack overflow";                                 break;
        case 4005: error_string="not enough stack for parameter";                           break;
        case 4006: error_string="no memory for parameter string";                           break;
        case 4007: error_string="no memory for temp string";                                break;
        case 4008: error_string="not initialized string";                                   break;
        case 4009: error_string="not initialized string in array";                          break;
        case 4010: error_string="no memory for array\' string";                             break;
        case 4011: error_string="too long string";                                          break;
        case 4012: error_string="remainder from zero divide";                               break;
        case 4013: error_string="zero divide";                                              break;
        case 4014: error_string="unknown command";                                          break;
        case 4015: error_string="wrong jump (never generated error)";                       break;
        case 4016: error_string="not initialized array";                                    break;
        case 4017: error_string="dll calls are not allowed";                                break;
        case 4018: error_string="cannot load library";                                      break;
        case 4019: error_string="cannot call function";                                     break;
        case 4020: error_string="expert function calls are not allowed";                    break;
        case 4021: error_string="not enough memory for temp string returned from function"; break;
        case 4022: error_string="system is busy (never generated error)";                   break;
        case 4050: error_string="invalid function parameters count";                        break;
        case 4051: error_string="invalid function parameter value";                         break;
        case 4052: error_string="string function internal error";                           break;
        case 4053: error_string="some array error";                                         break;
        case 4054: error_string="incorrect series array using";                             break;
        case 4055: error_string="custom indicator error";                                   break;
        case 4056: error_string="arrays are incompatible";                                  break;
        case 4057: error_string="global variables processing error";                        break;
        case 4058: error_string="global variable not found";                                break;
        case 4059: error_string="function is not allowed in testing mode";                  break;
        case 4060: error_string="function is not confirmed";                                break;
        case 4061: error_string="send mail error";                                          break;
        case 4062: error_string="string parameter expected";                                break;
        case 4063: error_string="integer parameter expected";                               break;
        case 4064: error_string="double parameter expected";                                break;
        case 4065: error_string="array as parameter expected";                              break;
        case 4066: error_string="requested history data in update state";                   break;
        case 4099: error_string="end of file";                                              break;
        case 4100: error_string="some file error";                                          break;
        case 4101: error_string="wrong file name";                                          break;
        case 4102: error_string="too many opened files";                                    break;
        case 4103: error_string="cannot open file";                                         break;
        case 4104: error_string="incompatible access to a file";                            break;
        case 4105: error_string="no order selected";                                        break;
        case 4106: error_string="unknown symbol";                                           break;
        case 4107: error_string="invalid price parameter for trade function";               break;
        case 4108: error_string="invalid ticket";                                           break;
        case 4109: error_string="trade is not allowed in the expert properties";            break;
        case 4110: error_string="longs are not allowed in the expert properties";           break;
        case 4111: error_string="shorts are not allowed in the expert properties";          break;
        case 4200: error_string="object is already exist";                                  break;
        case 4201: error_string="unknown object property";                                  break;
        case 4202: error_string="object is not exist";                                      break;
        case 4203: error_string="unknown object type";                                      break;
        case 4204: error_string="no object name";                                           break;
        case 4205: error_string="object coordinates error";                                 break;
        case 4206: error_string="no specified subwindow";                                   break;
        default:   error_string="unknown error";
    }

    return(error_string);
}

void ExitAll(int direction) {

   for (int i = 0; i < OrdersTotal(); i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
     
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
         if (OrderType() == OP_BUY && direction == LONG) { Exit(OrderTicket(), LONG, OrderLots(), Blue); }
         if (OrderType() == OP_SELL && direction == SHORT) { Exit( OrderTicket(), SHORT, OrderLots(), Red); }
      }
   }
}

bool DoPending(int dir, int pendingType, double entryPrice, double volume, int stop, int take, string comment)  {

   double sl, tp;

   int retVal = 0;

   double lots = CheckLots(volume);
   string info;
 
   for (int i=0; i<RETRYCOUNT; i++) {
     for (int j=0; (j<50) && IsTradeContextBusy(); j++)
         Sleep(100);
      RefreshRates();  

      switch(dir)  {
         case LONG:
           if (stop != 0) { sl = entryPrice-(stop*Point); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice +(take*Point); }
                else { tp = 0; }
               
                info = "Type: " + pendingType + ", \nentryPrice: " + DoubleToStr(entryPrice, Digits) + ", \nAsk " + DoubleToStr(Ask,Digits)
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, Digits)
                   + ", \nTP: " + DoubleToStr(tp, Digits);
           Print(info);
           Comment(info);

                retVal = OrderSend(Symbol(), pendingType, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, Blue);
                //retVal = OrderSend(Symbol(), pendingType, lots, 1.39, Slippage, 1.38, 1.40, "", 0, 0, Blue);
                break;

         case SHORT:
           if (stop != 0) { sl = entryPrice+(stop*Point); }
                else { sl = 0; }
                if (take != 0) { tp = entryPrice-(take*Point); }
                else { tp = 0; }
               
                info = "Type: " + pendingType + ", \nentryPrice: " + DoubleToStr(entryPrice, Digits) + ", \nBid " + DoubleToStr(Bid,Digits)
                   + ", \nLots " + DoubleToStr(lots, 2) + " , \nStop: " + DoubleToStr(sl, Digits)
                   + ", \nTP: " + DoubleToStr(tp, Digits);
           Print(info);
           Comment(info);
         
                retVal = OrderSend(Symbol(), pendingType, lots, entryPrice, Slippage, sl, tp, comment, MagicNumber, 0, Red);
                break;
      }
         
      if( retVal > 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 );
}

ไม่มีความคิดเห็น:

แสดงความคิดเห็น