Navigation:Home > Content >

_VirtualShell[ea]Name_Ron_MT4_v03a.mq4

Time: 2017-08-25 | Download file:_VirtualShell[ea]Name_Ron_MT4_v03a.mq4

//+--------------+
//|VirtualShell  |
//+--------------+
#property copyright "Ron Thompson"
#property link      "http://www.ForexMT4.com/"

// This EA is NEVER to be SOLD individually 
// This EA is NEVER to be INCLUDED as part of a collection that is SOLD


// EA SPECIFIC


// user input
extern double Lots                =       0.5 ;
extern double ProfitMade          =     100   ; 
extern double LossLimit           =     100   ;
extern double BreakEven           =       0   ;
extern double TrailStop           =      15   ;

// Point control for different brokers
double        myPoint;                              // support for 3/5 decimal places

// Reliable order control
int           OrderRetry;                           // count of order attempts
int           MaxRetries;                           // maximum number of attempts to place order

//multiple-trade control (if used)
bool          TradeAllowed=false;                   // used to manage trades

// order identification 
int           MagicNumber  = 200903151511;          // allows multiple experts to trade on same account
string        TradeComment = "VS.txt";              // where to log information

// Bar handling
datetime      bartime=0;                            // used to determine when a bar has moved
datetime      vopsavetime=0;                        // used to determine when a bar has moved
int           saveinterval=1;                       // how often to save to disk (minutes)


// Virtual Order Processor

#define vopCt         100           // maximum numbers of orders to handle

int     vopPTR;                     // pointer for ticket
int     vopOrderTicket[vopCt];      // ticket number
string  vopOrderSymbol[vopCt];      // which symbol 
int     vopOrderType[vopCt];        // buy or sell order
double  vopOrderLots[vopCt];        // lot size
double  vopOrderOpenPrice[vopCt];   // Order Open Price
double  vopOrderTakeProfit[vopCt];  // take profit
double  vopOrderStopLoss[vopCt];    // stop loss
int     vopOrderMagicNumber[vopCt]; // MagicNumber

string  vopFileName="vop.txt";


// used for verbose error logging
#include 


//+-------------+
//| Custom init |
//|-------------+
// Called ONCE when EA is added to chart or recompiled

int init()
  {
   // mask compiler Warnings
   if(1==0) CloseEverything();
  
   //init the random generator
   MathSrand(TimeLocal());
  
   // get normalized Point based on Broker decimal places
   myPoint = SetPoint();

   // Set retries to a rational number
   MaxRetries=10;


   //re-load the array, and sync it to real orders 
   logwrite(TradeComment,"Init loading file");
   vopLoad(vopFileName);
   vopSync();


   logwrite(TradeComment,"Init Complete");
   Comment(" ");



  }

//+----------------+
//| Custom DE-init |
//+----------------+
// Called ONCE when EA is removed from chart

int deinit()
  {


   logwrite(TradeComment,"DE-Init saving file");
   vopSave(vopFileName);

   // back test issue causes left-over stuff
   // in the array storage file. When testing.
   // delete tester storage after running.
   if( IsTesting() ) 
     {
      FileDelete(vopFileName);
      Print("Tester storage file deleted");
     }

   logwrite(TradeComment,"DE-Init Complete");
   Comment(" ");
  }


//+-----------+
//| Main      |
//+-----------+
// Called EACH TICK and each Bar[]

int start()
  {

   int      cnt=0;
   int      gle=0;
   int      ticket=0;
   int      OrdersPerSymbol=0;

   // stoploss and takeprofit and close control
   double SL=0;
   double TP=0;
   
   double CurrentProfit=0;
   double CurrentBasket=0;
     
   // direction control
   bool BUYme=false;
   bool SELLme=false;

   //volume
   double v1, v2, v3;
   double v12p, v23p;


   //Save the array once a minute in case of crash
   if(vopsavetime!=iTime(Symbol(), saveinterval, 0) ) 
     {
      vopsavetime=iTime(Symbol(), saveinterval, 0) ;
      vopSave(vopFileName);
     }


   OrdersPerSymbol=0;
   for(cnt=vopOrdersTotal();cnt>=0;cnt--)
     {
//XYZZY - what happens to vop if there is no ticket to select???????
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      vopPTR=vopSelect(OrderTicket());
      
      if( vopOrderSymbol[vopPTR]==Symbol() && vopOrderMagicNumber[vopPTR]==MagicNumber) OrdersPerSymbol++;
     }
   // one order at a time
   if(OrdersPerSymbol==0) TradeAllowed=true;

      
   // bar counting
   if(bartime!=iTime(Symbol(), 0, 0) ) 
     {
      bartime=iTime(Symbol(), 0, 0) ;


      //+-----------------------------+
      //| Code here will execute once |
      //| at the OPEN of a NEW BAR    |
      //+-----------------------------+

   
      if(TradeAllowed && MathRand()> 16383) { OpenBuy();  }
      if(TradeAllowed && MathRand()<=16383) { OpenSell(); }
      
              
      //+------------+
      //| End Insert |
      //+------------+

     }



     
   //+-----------------------------+
   //| Insert your indicator here  |
   //| And set either BUYme or     |
   //| SELLme true to place orders |
   //+-----------------------------+

   
   //+------------+
   //| End Insert |
   //+------------+
   


   //
   // Order Management
   //

   for(cnt=vopOrdersTotal();cnt>=0;cnt--)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      vopPTR=vopSelect(OrderTicket());

      if( vopOrderSymbol[vopPTR]==Symbol() && vopOrderMagicNumber[vopPTR]==MagicNumber )
        {
         
         
         if(vopOrderType[vopPTR]==OP_BUY)
           {
            CurrentProfit=(Bid-vopOrderOpenPrice[vopPTR]) ;

            // Modify for break even
            //=======================
            if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
              {
               vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]+(Ask-Bid);
               logwrite(TradeComment,"BREAKEVEN BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Bid="+Bid+" Ask="+Ask);
              }
             
            // check for trailing stop
            //=========================
            if( TrailStop>0)
              {
               // This starts trailing after 'TrailStop' pips of profit
               if(Close[0]>=vopOrderOpenPrice[vopPTR]+(TrailStop*myPoint) )  
                 {
                  // if you're here, then you're at least TrailStop pips in profit
                  if( Bid-(TrailStop*myPoint) > vopOrderStopLoss[vopPTR] )
                    {
                     vopOrderStopLoss[vopPTR]=Bid-(TrailStop*myPoint);
                     logwrite(TradeComment,"TRAILSTOP BUY Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Bid="+Bid);
                    }
                 }
              }

            // BUY closing management
            if(ProfitMade>0        && Close[0]>=vopOrderTakeProfit[vopPTR])   CloseBuy("PROFIT");
            if( LossLimit>0        && Close[0]<=vopOrderStopLoss[vopPTR]  )   CloseBuy("STOPLOSS");
              
           } //BUY




         if(vopOrderType[vopPTR]==OP_SELL)
           {
            CurrentProfit=(vopOrderOpenPrice[vopPTR]-Ask);
           
            // Modify for break even
            //=======================
            if(BreakEven>0 && vopOrderStopLoss[vopPTR]==0 && CurrentProfit >= (BreakEven*myPoint) )
              {
               vopOrderStopLoss[vopPTR]=vopOrderOpenPrice[vopPTR]-(Ask-Bid);
               logwrite(TradeComment,"BREAKEVEN SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" CurrentProfit="+CurrentProfit+" Ask="+Ask+" Bid="+Bid);
              }

            // check for trailing stop
            //=========================
            if( TrailStop>0)
              {
               // This starts trailing after 'TrailStop' pips of profit
               if(Close[0]<=vopOrderOpenPrice[vopPTR]-(TrailStop*myPoint) )  
                 {                 
                  // if you're here, then you're at least TrailStop pips in profit
                  if( Ask+(TrailStop*myPoint) < vopOrderStopLoss[vopPTR] )
                    {
                     vopOrderStopLoss[vopPTR]=Ask+(TrailStop*myPoint);
                     logwrite(TradeComment,"TRAILSTOP SELL Ticket="+vopOrderTicket[vopPTR]+" SL="+vopOrderStopLoss[vopPTR]+" Ask="+Ask);
                    }
                 }
              }

            // SELL closing management
            if(ProfitMade>0        && Close[0]<=vopOrderTakeProfit[vopPTR])   CloseSell("PROFIT");
            if( LossLimit>0        && Close[0]>=vopOrderStopLoss[vopPTR]  )   CloseSell("STOPLOSS");

               
           } //sell

        } //OrderSymbol
        
     } // for

  } // start()


//+-----------------+
//| CloseEverything |
//+-----------------+
// Closes all OPEN and PENDING orders

int CloseEverything()
  {
   int i;
    
   for(i=vopOrdersTotal();i>=0;i--)
     {

      OrderSelect(i, SELECT_BY_POS);
      vopPTR=vopSelect(OrderTicket());

      if(vopOrderSymbol[vopPTR]==Symbol() && vopOrderMagicNumber[vopPTR]==MagicNumber)
        {
         if(vopOrderType[vopPTR]==OP_BUY)       CloseBuy ("CLOSEEVERYTHING");
         if(vopOrderType[vopPTR]==OP_SELL)      CloseSell("CLOSEEVERYTHING");
         //
         //These types not supported in Virtual Order Processor
         //
         //if(OrderType()==OP_BUYLIMIT)  OrderDelete( vopOrderTicket[vopPTR] );
         //if(OrderType()==OP_SELLLIMIT) OrderDelete( vopOrderTicket[vopPTR] );
         //if(OrderType()==OP_BUYSTOP)   OrderDelete( vopOrderTicket[vopPTR] );
         //if(OrderType()==OP_SELLSTOP)  OrderDelete( vopOrderTicket[vopPTR] );
        }

     } //for
     
  } // closeeverything



// log data to a file name passed in
// print everything regardless of log setting
void logwrite (string filename, string mydata)
  {
   int myhandle;
   string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);

   Print(mydata+" "+gregorian);
   
   // don't log anything if testing
   if(IsTesting()) return(0);

   myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";");
   if(myhandle>0)
     {
      FileSeek(myhandle,0,SEEK_END);
      FileWrite(myhandle, mydata+" "+gregorian);
      FileClose(myhandle);
     }
  } 



//ENTRY LONG (buy, Ask) 
void OpenBuy()
  {
   int      gle=0;
   int      ticket=0;
   
   int OrderRetry=0;

   while(true)          
     {
      // place order - NO TP OR SL
      ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,0,0,0,"",0,White);
      gle=GetLastError();
      if(gle==0)
        {
         logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+Ask+" Bid="+Bid+" Lots="+Lots);
         vopOrderOpen(ticket, OP_BUY, Symbol(), Lots, Ask, Bid+(ProfitMade*myPoint), Bid-(LossLimit*myPoint), MagicNumber);
         //TradeAllowed=false;
         break;
        }
       else 
        {
         logwrite(TradeComment,"-----ERROR-----  Placing BUY order: Lots="+Lots+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
         Sleep(500);
         RefreshRates();

         OrderRetry++;
         if(OrderRetry>MaxRetries)
           {
            logwrite(TradeComment,"-----ERROR-----  Giving up on placing BUY order"); 
            return(gle);
           }
           
        }

     }//while - place order 
        
   // good time to check sync
   vopSync();

  }//BUY



//ENTRY SHORT (sell, Bid)
void OpenSell()
  {
   int      gle=0;
   int      ticket=0;
      
   int OrderRetry=0;

   while(true)
     {
      // place order - NO TP OR SL
      ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,0,0,0,"",0,Red);
      gle=GetLastError();
      if(gle==0)
        {
         logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+Bid+" Ask="+Ask+" Lots="+Lots);
         vopOrderOpen(ticket, OP_SELL, Symbol(), Lots, Bid, Ask-(ProfitMade*myPoint), Ask+(LossLimit*myPoint), MagicNumber);
         //TradeAllowed=false;
         break;
        }
         else 
        {
         logwrite(TradeComment,"-----ERROR-----  placing SELL order: Lots="+Lots+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); 
         Sleep(500);
         RefreshRates();

         OrderRetry++;
         if(OrderRetry>MaxRetries)
           {
            logwrite(TradeComment,"-----ERROR-----  Giving up on placing SELL order"); 
            return(gle);
           }
              
        }

     }//while - place order 

   // good time to check sync
   vopSync();
  
  }//SELL



void CloseBuy (string myInfo)
  {
   int gle;
   int cnt;

   int OrderRetry=0;
   
   string bBD=" Bid="+Bid;
   string bAS=" Ask="+Ask;
   string bTK=" Ticket="+vopOrderTicket[vopPTR];
   string bSL=" SL="+vopOrderStopLoss[vopPTR];
   string bTP=" TP="+vopOrderTakeProfit[vopPTR];
   string bPM=" PM="+ProfitMade;
   string bLL=" LL="+LossLimit;
   string bER;

   while(true)
     {
      OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Bid,0,White);
      gle=GetLastError();
      if(gle==0)
        {
         vopOrderClose(vopOrderTicket[vopPTR], myInfo);
         logwrite(TradeComment,"CLOSE BUY "+myInfo+ bBD+ bAS+ bTK+ bSL+ bTP+ bPM+ bLL);
         break;
        }
       else 
        {
         bER=" error="+gle+" "+ErrorDescription(gle);
         logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+Bid+ bTK + bSL + bTP + bPM + bLL);
         Sleep(500);
         RefreshRates();
        }


      OrderRetry++;
      if(OrderRetry>MaxRetries)
        {
         logwrite(TradeComment,"-----ERROR-----  Giving up on closing SELL order"); 
         return(gle);
        }
                     
     }//while
  
   // good time to check sync
   vopSync();
  
  }


void CloseSell (string myInfo)
  {
   int gle;
   int cnt;

   int OrderRetry=0;

   string sBD=" Bid="+Bid;
   string sAS=" Ask="+Ask;
   string sTK=" Ticket="+vopOrderTicket[vopPTR];
   string sSL=" SL="+vopOrderStopLoss[vopPTR];
   string sTP=" TP="+vopOrderTakeProfit[vopPTR];
   string sPM=" PM="+ProfitMade;
   string sLL=" LL="+LossLimit;
   string sER;
      
   while(true)
     {
      OrderClose(vopOrderTicket[vopPTR],vopOrderLots[vopPTR],Ask,0,Red);
      gle=GetLastError();
      sER=" error="+gle+" "+ErrorDescription(gle);
      
      if(gle==0)
        {
         vopOrderClose(vopOrderTicket[vopPTR], myInfo);
         logwrite(TradeComment,"CLOSE SELL "+myInfo+ sAS+ sBD+ sTK+ sSL+ sTP+ sPM+ sLL);
         break;
        }
      else 
        {
         logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+Ask+ sTK + sSL + sTP + sPM + sLL);
         RefreshRates();
         Sleep(500);
        }

      OrderRetry++;
      if(OrderRetry>MaxRetries)
        {
         logwrite(TradeComment,"-----ERROR-----  Giving up on closing SELL order"); 
         return(gle);
        }
                 
     }//while                 

   // good time to check sync
   vopSync();
  
  }      


// Function to correct the value of Point
// for brokers that add an extra digit to price
// Courtesy of Robert Hill

double SetPoint()
{
   double mPoint;
  
   if (Digits < 4)
      mPoint = 0.01;
   else
      mPoint = 0.0001;
  
   return(mPoint);
}


// Virtual Order Processor - open order
void vopOrderOpen (int vTKT, int vTYP, string vSYM, double vLOTS, double vOOP, double vTP, double vSL, int vMAG)
  {
   int i;
   logwrite(TradeComment,Symbol()+" vopOPEN: "+vTYP+" symbol="+vSYM+" ticket "+vTKT+" OpenPrice="+vOOP+" Lots="+vLOTS+" StopLoss="+vSL+" TakeProfit="+vTP+" MagicNumber"+vMAG  );

   // find next available ticket slot
   for(i=0; i<=99; i++)
     {
      if(vopOrderTicket[i]==0) break;
     }
   vopOrderTicket[i]=vTKT;
   vopOrderType[i]=vTYP;
   vopOrderSymbol[i]=vSYM;
   vopOrderLots[i]=vLOTS;
   vopOrderOpenPrice[i]=vOOP;
   vopOrderTakeProfit[i]=vTP;
   vopOrderStopLoss[i]=vSL;
   vopOrderMagicNumber[i]=vMAG;
  }


// Virtual Order Processor - close order
void vopOrderClose (int vTKT, string vINFO)
  {
   int i;
   
   // find next available ticket slot
   for(i=0; i<=99; i++)
     {
      if(vopOrderTicket[i]==vTKT) break;
     }
   logwrite(TradeComment,Symbol()+" vopCLOSE "+vINFO+": type="+vopOrderType[i]+" symbol="+vopOrderSymbol[i]+" ticket "+vopOrderTicket[i]+" OpenPrice="+vopOrderOpenPrice[i]+" Lots="+vopOrderLots[i]+" StopLoss="+vopOrderStopLoss[i]+" TakeProfit="+vopOrderTakeProfit[i]  );

   vopOrderTicket[i]=0;
   vopOrderType[i]=0;
   vopOrderSymbol[i]=" ";
   vopOrderLots[i]=0;
   vopOrderOpenPrice[i]=0;
   vopOrderTakeProfit[i]=0;
   vopOrderStopLoss[i]=0;
   vopOrderMagicNumber[i]=0;
  }


// Virtual Order Processor - find order by ticket
int vopSelect (int vTKT)
  {
   int i;
   
   // find next available ticket slot
   for(i=0; i<=99; i++)
     {
      if(vopOrderTicket[i]==vTKT) break;
     }
   return(i);
  }


   // Count active tickets
int vopOrdersTotal()
  {
   int i;
   int count=0;
   
   for(i=0; i<=99; i++)
     {
      if(vopOrderTicket[i]!=0) count++;
     }
   return(count);
  }
  
  

// VOP save routine
void vopSave (string vFN)
  {
   if(IsTesting()) return(0);
   
   
   int i;
   
   string fwTicket;      // ticket number
   string fwSymbol;      // which symbol 
   string fwType;        // buy or sell order
   string fwLots;        // lot size
   string fwOpenPrice;   // Order Open Price
   string fwTakeProfit;  // take profit
   string fwStopLoss;    // stop loss
   string fwMagicNumber; // MagicNumber

   //string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS);

   int myhandle=FileOpen(vFN, FILE_CSV|FILE_WRITE, ";");
   if(myhandle>0)
     {
      for(i=0; i<=99; i++)
        {
         fwTicket=DoubleToStr(vopOrderTicket[i],0);
         fwSymbol=vopOrderSymbol[i];
         fwType=DoubleToStr(vopOrderType[i],0);
         fwLots=DoubleToStr(vopOrderLots[i],2);
         fwOpenPrice=DoubleToStr(vopOrderOpenPrice[i],5);
         fwTakeProfit=DoubleToStr(vopOrderTakeProfit[i],5);
         fwStopLoss=DoubleToStr(vopOrderStopLoss[i],5);
         fwMagicNumber=DoubleToStr(vopOrderMagicNumber[i],0);

         FileWrite(myhandle, fwTicket, fwSymbol, fwType, fwLots, fwOpenPrice, fwTakeProfit, fwStopLoss, fwMagicNumber);
        }
        
     }
   
   FileClose(myhandle);
  }



// VOP load routine
void vopLoad (string vFN)
  {
   if(IsTesting()) return(0);
   

   int i;
   
   string fwTicket;      // ticket number
   string fwSymbol;      // which symbol 
   string fwType;        // buy or sell order
   string fwLots;        // lot size
   string fwOpenPrice;   // Order Open Price
   string fwTakeProfit;  // take profit
   string fwStopLoss;    // stop loss
   string fwMagicNumber; // MagicNumber

   int myhandle=FileOpen(vFN, FILE_CSV|FILE_READ, ";");
   if(myhandle>0)
     {
      for(i=0; i<=99; i++)
        {
         fwTicket= FileReadString(myhandle);
         fwSymbol= FileReadString(myhandle);
         fwType= FileReadString(myhandle);
         fwLots= FileReadString(myhandle);
         fwOpenPrice= FileReadString(myhandle);
         fwTakeProfit= FileReadString(myhandle);
         fwStopLoss= FileReadString(myhandle);
         fwMagicNumber= FileReadString(myhandle);
         
         vopOrderTicket[i]=StrToInteger(fwTicket);
         vopOrderSymbol[i]=fwSymbol;
         vopOrderType[i]=StrToInteger(fwTicket);
         vopOrderLots[i]=StrToDouble(fwTicket);
         vopOrderOpenPrice[i]=StrToDouble(fwTicket);
         vopOrderTakeProfit[i]=StrToDouble(fwTicket);
         vopOrderStopLoss[i]=StrToDouble(fwTicket);
         vopOrderMagicNumber[i]=StrToInteger(fwTicket);
         
        }
        
     }
   
   FileClose(myhandle);
  }



// VOP sync routine used after open or close
bool vopSync ()
  {
   if(IsTesting()) return(0);

   
   int loopct=0;
   int i;

   // ISSUES:
   //
   // there could be manual orders on the server 
   // so OrdersTotal()==vopOrdersTotal() won't always work
   //
   // there could be other vop EAs running, with unidentifiable 
   // orders open, so comparing server->array won't always work
   //
   // Adding anything to the orders to make them identifiable
   // defeats the purpose of the virtual order system
   //
   // Be sure to actually CHECK THE RETURN VALUE
   // and do something in case of out-of-sync
   //

   // are ALL the array tickets on the server 
   for(i=0; i<=99; i++)
     {
      if( vopOrderTicket[i]!=0 && OrderSelect(vopOrderTicket[i],SELECT_BY_TICKET) ) loopct++;
     }

   if( vopOrdersTotal()==loopct )
     {
       return(true);
     }
     else
     {
      logwrite(TradeComment," SYNC FAILED");
      Alert(TradeComment+" SYNC FAILED");
      return(false);
     }

  }//Sync
  

Recommend