How to create a Magic Number array? - page 4

 
Jon,
1) The first OrderSend() is checked that it was successful by testing that the return value is greater
than zero before attempting to place the second order.
2) To identify and process order pairs you could base your code on the following if the order pairs
were comprised of different types (however the algorythm would have to be altered if the grouping
was more than 2 or if the orders in a group were all of the same type):
The sample program "ReportsTrader.mq4" that follows places straddle orders near the issue of
reports or news events.
A straddle order is comprised of two pending orders above and below the market price. When one
pending order hits the market price it is changed into a market order and the other pending

order has to be deleted. So the order pairs require a sequence number to track them.

//+------------------------------------------------------------------+
//|                                                ReportsTrader.mq4 |
//|                                          Copyright © 2010, sxTed |
//|                                            MailTo: sxTed@gmx.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, sxTed"
#property link      "MailTo: sxTed@gmx.com"

//+------------------------------------------------------------------+
//| input parameters:                                                |
//+-----------0---+----1----+----2----+----3]------------------------+
extern int            ExpertID = 2;
extern int            StopLoss = 20;
extern int          TakeProfit = 60;
extern int    DistanceToMarket = 15;
extern double             Lots = 0.05;
extern bool         AlertError = true;

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void start() {
   static string Report[4][4] = {"2010.12.30 05:00", "USDJPY", "JPY Purchasing Manager Index"    , "0",
                                 "2010.12.30 09:00", "EURUSD", "EUR Italian Producer Price Index", "0",
                                 "2010.12.30 13:30", "USDJPY", "USD Initial Jobless Claims"      , "0",
                                 "2010.12.31 00:30", "AUDUSD", "AUD Private Sector Credit"       , "0"
                                };
   int    Position[10][7], iReports=ArrayRange(Report,0), i, k, iPairs, iPipsFactor;
   int    iOrders=OrdersTotal(), iPositions=ArrayRange(Position,0), iSequenceNumber;
   double dTS, dSL, pp;
   string sSequenceNumber;

   //----------------------------------------------------------------- triage of orders   
   if (iOrders > iPositions) iPositions=ArrayResize(Position,iOrders)/iOrders;
   ArrayInitialize(Position,0);
   for (i=0; i<iOrders; i++) {
      if (!OrderSelect(i,SELECT_BY_POS))   continue;
      if (OrderMagicNumber() != ExpertID) continue;
      iSequenceNumber = StrToInteger(OrderComment());
      for (k=0; k<iPositions; k++) {
         if (Position[k][6] == iSequenceNumber) {
            Position[k][OrderType()] = OrderTicket();
            break;
         }   
         if (Position[k][6] == 0) {
            Position[k][6]           = iSequenceNumber;
            Position[k][OrderType()] = OrderTicket();
            iPairs++;
            break;
         }   
      }      
   }
   //----------------------------------------------------------------- maintain straddle orders   
   for (i=0; i<iPairs; i++) {
      if (Position[i][OP_BUY] > 0) {
         if (OrderSelect(Position[i][OP_BUY], SELECT_BY_TICKET)) {
            if ((MarketInfo(OrderSymbol(),MODE_DIGITS) == 5) || (MarketInfo(OrderSymbol(),MODE_DIGITS) == 3)) iPipsFactor = 10;
            else iPipsFactor = 1;
            dTS=StopLoss*iPipsFactor*MarketInfo(OrderSymbol(),MODE_POINT);
            dSL=OrderStopLoss()+dTS*MathFloor((MarketInfo(OrderSymbol(),MODE_BID)-dTS-OrderStopLoss())/dTS);
            if (MarketInfo(OrderSymbol(),MODE_BID)-dSL >= dTS && dSL > OrderStopLoss()) {
               if (!OrderModify(OrderTicket(),OrderOpenPrice(),dSL,OrderTakeProfit(),0)) return(Error("OrderModify"));
            }
         }
      }
      if (Position[i][OP_SELL] > 0) {
         if (OrderSelect(Position[i][OP_SELL], SELECT_BY_TICKET)) {
            if ((MarketInfo(OrderSymbol(),MODE_DIGITS) == 5) || (MarketInfo(OrderSymbol(),MODE_DIGITS) == 3)) iPipsFactor = 10;
            else iPipsFactor = 1;
            dTS=StopLoss*iPipsFactor*MarketInfo(OrderSymbol(),MODE_POINT);
            dSL=OrderStopLoss()-dTS*MathFloor((OrderStopLoss()-dTS-MarketInfo(OrderSymbol(),MODE_ASK))/dTS);
            if (dSL-MarketInfo(OrderSymbol(),MODE_ASK) >= dTS && dSL < OrderStopLoss()) {
               if (!OrderModify(OrderTicket(),OrderOpenPrice(),dSL,OrderTakeProfit(),0)) return(Error("OrderModify"));
            }
         }
      }
      if (Position[i][OP_BUYSTOP] > 0 && Position[i][OP_SELLSTOP] == 0) {
         if (!OrderDelete(Position[i][OP_BUYSTOP])) return(Error("OrderDelete ticket "+Position[i][OP_BUYSTOP]));
      }
      if (Position[i][OP_BUYSTOP] == 0 && Position[i][OP_SELLSTOP] > 0) {
         if (!OrderDelete(Position[i][OP_SELLSTOP])) return(Error("OrderDelete ticket "+Position[i][OP_SELLSTOP]));
      }
   }
   //----------------------------------------------------------------- place new straddle orders for Report
   for (i=0; i<iReports; i++) {
      if (Report[i][3] == "0") {
         if ((TimeGMT() >= StrToTime(Report[i][0])-PERIOD_M5*60) && (TimeGMT() <= StrToTime(Report[i][0]))) {
            Report[i][3] = "done";
            sSequenceNumber=DoubleToStr(SequenceNumber(),0);
            if ((MarketInfo(Report[i][1],MODE_DIGITS) == 5) || (MarketInfo(Report[i][1],MODE_DIGITS) == 3)) iPipsFactor = 10;
            else iPipsFactor = 1;
            pp=MarketInfo(Report[i][1],MODE_ASK)+DistanceToMarket*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT);
            if (OrderSend(Report[i][1],OP_BUYSTOP,Lots,pp,3,pp-StopLoss*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT),pp+TakeProfit*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT),sSequenceNumber,ExpertID,0,Green) == -1) return(Error("OrderSend OP_BUYSTOP"));
            RefreshRates();
            pp=MarketInfo(Report[i][1],MODE_BID)-DistanceToMarket*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT);
            if (OrderSend(Report[i][1],OP_SELLSTOP,Lots,pp,3,pp+StopLoss*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT),pp-TakeProfit*iPipsFactor*MarketInfo(Report[i][1],MODE_POINT),sSequenceNumber,ExpertID,0,Red) == -1) return(Error("OrderSend OP_SELLSTOP"));
         }
      }
   }
}

int Error(string sErrorMessage) {
   int iErrorNumber=GetLastError();
   Print(sErrorMessage," error ",iErrorNumber);
   if (AlertError) Alert(sErrorMessage," error ",iErrorNumber);
   return(-1);
}

//+------------------------------------------------------------------+
//| Function..: SequenceNumber                                       |
//| Purpose...: Generate a sequential number.                        |
//| Returns...: dSeqNum - next sequence number.                      |
//| Notes.....: MT4 keeps the value of the global variable at the    |
//|             client terminal for 4 weeks since the last access.   |
//|             Use SequenceNumber() to generate a unique identity   |
//|             for each order (and passed via parameter <magic>     |
//|             number, or converted to a string and passed via the  |
//|             parameter <comment> to the OrderSend() function) as  |
//|             the trade servers of some brokers do modify the      |
//|             ticket number of a pending order when it changes to  |
//|             a market order.                                      |
//|             The same sequence number could, for example, be used |
//|             to identify the two positions of a straddle order.   |
//|             ******************************************************
//|             * If the expert has to close partial lots, then MT4  *
//|             * retains in the new order the contents of the       *
//|             * OrderMagicNumber() but loses OrderComment().       *
//|             ******************************************************
//| Sample....: string sNumber=DoubleToStr(SequenceNumber(),0);      |
//|             if(OrderSend("EURUSD",OP_BUY,1,Ask,3,Ask-25*Point,   |
//|                          Ask+25*Point,sNumber,16384,0,Green) > 0)|
//|                OrderSend("EURUSD",OP_BUY,1,Ask,3,Ask-25*Point,   |
//|                          Ask+65*Point,sNumber,16384,0,Green);    |
//+------------------------------------------------------------------+
double SequenceNumber() {
   double dSeqNum=1, d;
   string sName="SequenceNumber";

   while (GlobalVariableCheck("Semaphore")) d+=0;
   GlobalVariableSet("Semaphore",1);
   if (GlobalVariableCheck(sName)) dSeqNum=GlobalVariableGet(sName)+1;
   GlobalVariableSet(sName,dSeqNum);
   GlobalVariableDel("Semaphore");
   return(dSeqNum);
}

//+------------------------------------------------------------------+
//| Function..: TimeGMT                                              |
//| Thank you.: Slawa ref. http://www.metatrader4.com/forum/2435&nbsp;    |
//| Purpose...: Retrieve the current system date and time expressed  |
//|             in GMT (UTC) time.                                   |
//| Returns...: tGMT.                                                |
//+------------------------------------------------------------------+
#import "Kernel32.dll"
  void GetSystemTime(int& TimeArray[]);
#import

datetime TimeGMT() {
  int TimeArray[4];
  GetSystemTime(TimeArray);
  int YY=TimeArray[0]&0x0000FFFF;
  int MM=TimeArray[0]>>16;
  int DD=TimeArray[1]>>16;
  int hh=TimeArray[2]&0x0000FFFF;
  int mm=TimeArray[2]>>16;
  int ss=TimeArray[3]&0x0000FFFF;
  return(StrToTime(StringConcatenate(YY,".",MM,".",DD," ",hh,":",mm,":",ss)));
}
//+------------------------------------------------------------------+
Files:
 
Thanks! Wow, will take time to read and understand your code...
 

I don't know if you ever solved this problem Chee Chua, but I got very close to being able to do the same thing.

My system creates pricelevels (based on my inputs at the start) which are then supposed to be permanent, so that if price revisits a pricelevel and an order does not exist an order is placed. These pricelevels are created when each pending order is created using a for loop. The magicnumber is then derived from the pricelevel. 

You can see my code here:

https://www.mql5.com/en/forum/306224


My only problem is that sometimes my number comes out 1 digit less than the Pricelevel of the trade which I cannot solve.

Anyone want to take a crack at this?
Anyone want to take a crack at this?
  • 2019.03.11
  • www.mql5.com
Hi All, Anyone want to take a crack at this? This code will ask for inputs, so in this case the following were entered 2019.03.11 11:56:18.393 2016...