Actualización del MQL4 600 y de los tubos con nombre

 

Hola,

Después de esta reciente actualización, ahora no puedo capturar el recuento de llamadas de una instancia de mi terminal MT4 para transmitirlo a otra MT4. ¿Pueden decirme qué ha cambiado en la actualización que causa este problema? Abajo está el código que sigue funcionando bien con la build 509 pero no después de esta reciente actualización.


extern string PipeName = "MetaTerminal1";

extern int SuspendSeconds = 10;

extern int SleepMS = 10;







#define  PIPE_BASE_NAME "\\\\.\\pipe\\mt4-"



#define  GENERIC_READ 0x80000000

#define  GENERIC_WRITE 0x40000000

#define  PIPE_ACCESS_DUPLEX 3

#define  PIPE_UNLIMITED_INSTANCES 255

#define  PIPE_NOWAIT 1

#define  PIPE_TYPE_MESSAGE 4

#define  PIPE_READMODE_MESSAGE 2

#define  PIPE_WAIT 0



#import "kernel32.dll"

int CreateNamedPipeA(string pipeName,int openMode,int pipeMode,int maxInstances,int outBufferSize,int inBufferSize,int defaultTimeOut,int security);

int PeekNamedPipe(int PipeHandle, int PassAsZero, int PassAsZero2, int PassAsZero3, int & BytesAvailable[], int PassAsZero4);

int CreateFileA(string Filename, int AccessMode, int ShareMode, int PassAsZero, int CreationMode, int FlagsAndAttributes, int AlsoPassAsZero);

int CloseHandle(int fileHandle);

// int ReadFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesRead[], int PassAsZero);

        int ReadFile(int FileHandle, int& inBuffer[],int BufferLength, int& BytesRead[], int lpOverlapped);

int WriteFile(int FileHandle, string Buffer, int BufferLength, int & BytesWritten[], int PassAsZero);

//      int WriteFile(int FileHandle,int& inBuffer[], int NumberOfBytesToWrite, int& bytesWritten[], int lpOverlapped);

int MulDiv(string X, int N1, int N2);

#import



// Number of pipe instances to create by default. This value can overridden by the optional parameter to

// CreatePipeServer(). The number of instances is in effect the maximum number of messages which

// can be sent to the server between each call which the server makes to CheckForPipeMessages().

// If more messages than this are sent, the extra messages will fail and the sender(s) will need to retry.

#define  DEFAULT_MAX_PIPES 200



// Number of pipe instances to allocate. Defaults to DEFAULT_MAX_PIPES unless it is overridden

int glbPipeCount = DEFAULT_MAX_PIPES;

// Array of pipe handles allocated by CreatePipeServer()

int glbPipe[DEFAULT_MAX_PIPES];

// Persistent storage of the pipe name passed as a parameter to CreatePipeServer()

string glbPipeName;



// Starts the pipe server by creating n instances of the pipe

void CreatePipeServer(string PipeName, int UsePipeInstances = DEFAULT_MAX_PIPES)

{

// Store the number of pipe instances to use and resize the array accordinging

glbPipeCount = UsePipeInstances;

ArrayResize(glbPipe, glbPipeCount);

// Store the name to use for the pipe instances

glbPipeName = PipeName;

// Create the pipe instances

for (int i = 0; i < glbPipeCount; i++)

glbPipe[i] = CreatePipeInstance();

return;

}



// Closes all the resources used by the pipe server: i.e. closes all the pipe instances

void DestroyPipeServer()

{

for (int i = 0; i < glbPipeCount; i++)

CloseHandle(glbPipe[i]);

return;

}



// Service function which creates a pipe instance

int CreatePipeInstance()

{

string strPipeName = StringConcatenate(PIPE_BASE_NAME, glbPipeName);

return (CreateNamedPipeA(strPipeName, GENERIC_READ | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 1000, 1000, 0, NULL));

}

datetime StartTime=0;

int brCall=0;



int aPairCount=0;

string aPair[1000];

int aDigit[1000];

datetime aLastSinhTime[1000];

double aBid[1000];

double aAsk[1000];



int init()

{

StartTime=TimeLocal();

brCall=0;

aPairCount=0;



// Create the server

CreatePipeServer(PipeName);

return(0);

}



int deinit()

{

// Destroy the pipe server

DestroyPipeServer();

Comment("");

return(0);

}



int start()

{

while(!IsStopped() && IsConnected())    

{

for(int i = 0; i < glbPipeCount; i++)

CheckPipe(i);

Comment("\nStart Time: "+TimeToStr(StartTime,TIME_DATE|TIME_SECONDS)+

"\nLocal Time: "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+

"\nCall Count: "+DoubleToStr(brCall,0)

);

Sleep(MathMax(SleepMS,10));

}

return(0);

}



bool CheckPipe(int PipeIndex)

{

bool Result=false;

string sMsg = "";

// See if there's data available on the pipe

int BytesAvailable[1] = {0};

int res = PeekNamedPipe(glbPipe[PipeIndex], 0, 0, 0, BytesAvailable, 0);

if (res != 0) {

// PeekNamedPipe() succeeded



// Is there data?

if (BytesAvailable[0] != 0) {

Result=true;



// Keep reading until either we have all the data, or an error occurs

int TotalBytesRead = 0;

while (TotalBytesRead < BytesAvailable[0])

{

string ReadBuffer="";

int iBuffer[256];

int BytesRead[1] = {0};

ReadFile(glbPipe[PipeIndex],iBuffer,4*ArraySize(iBuffer),BytesRead,NULL);

for(int i=0; i<BytesRead[0]; i++)

ReadBuffer = ReadBuffer + CharToStr( (iBuffer[i/4] >> ((i & 3)*8)) & 0xff);

// Did we get any data from the read?

if(BytesRead[0] > 0)

{

// Yes, got some data. Add it to the total message which is passed back

sMsg = StringConcatenate(sMsg, StringSubstr(ReadBuffer, 0, BytesRead[0]));

TotalBytesRead += BytesRead[0];

}

else

{

// No, the read failed. Stop reading, and pass back an empty string

sMsg = "";

TotalBytesRead = 999999;

}

}

if(StringLen(sMsg)>0)

{

string outString="n/a";

RefreshRates();

brCall=brCall+1;

double pBid=MarketInfo(sMsg,MODE_BID);

double pAsk=MarketInfo(sMsg,MODE_ASK);

if(pBid>0.0001 && pAsk>0.0001)

{

int ai=0;

bool fl=true;

for(i=1;i<=aPairCount;i++)

if(aPair[i]==sMsg)

{

ai=i;

break;

}

if(ai==0)

{

aPairCount=aPairCount+1;

ai=aPairCount;

aPair[ai]=sMsg;

aDigit[ai]=MarketInfo(sMsg,MODE_DIGITS);

aLastSinhTime[ai]=TimeLocal();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if(MathAbs(aBid[ai]-pBid)>=0.00001 || MathAbs(aAsk[ai]-pAsk)>=0.00001)

{

aLastSinhTime[ai]=TimeLocal();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if(TimeLocal()-aLastSinhTime[ai]>SuspendSeconds)

fl=false;

if(fl)

outString=DoubleToStr(aBid[ai],aDigit[ai])+"|"+DoubleToStr(aAsk[ai],aDigit[ai]);

else

outString="Suspended";

}



int bytesWritten[1];

bool fSuccess=WriteFile(glbPipe[PipeIndex],outString,StringLen(outString)+1,bytesWritten,NULL) != 0;

if(!fSuccess || bytesWritten[0] != StringLen(outString)+1)

{

Sleep(10);

}

}

// Destroy and recreate the pipe instance

CloseHandle(glbPipe[PipeIndex]);

glbPipe[PipeIndex] = CreatePipeInstance();

} else {

// No data available on pipe

}

} else {

// PeekNamedPipe() failed

}

return(Result);

}
 

Utiliza el botón SRC para colocar el código, de lo contrario los moderadores lo borrarán.

Además, lea los muchos otros hilos que han mencionado que las funciones "A" ya no son compatibles y tendrá que utilizar las versiones "W" Wide de las funciones como "CreateNamedPipeW" en lugar de "CreateNamedPipeA".

 
sksyen:

Gracias por responder y mis disculpas por no pegar el SRC como archivo.

Con respecto a su respuesta, ¿significa esto que simplemente tengo que cambiar la referencia "A" de las tuberías con nombre por una "W" en su lugar? Traté de buscar algunos hilos con respecto a esto, pero fue incapaz de encontrar - su ayuda es muy apreciada. Gracias de nuevo.

No se trata de pegar la fuente como un archivo, sino de utilizar la herramienta SRC para colocar el código aquí en el foro. Cómo utilizar el botón SRC. (proporcionado por "RaptorUK")

Aquí hay un par de referencias a dilemas similares con la versión Wide de Functions:

 

Gracias. El lado del servidor ahora es capaz de capturar el recuento de llamadas después de actualizar las tuberías con nombre "A" a "W'. Sin embargo, desde la otra instancia de la MT4, parece tener problemas para recibir la entrada de información. He actualizado el nombre de las tuberías a "W" en el extremo receptor, pero todavía no puede extraer los datos por alguna razón. ¿Alguna idea? Vea a continuación el código en el extremo receptor:

extern double MaxDD          = 30;
extern double MM             = 30;

extern string PipeName       = "Terminal";
extern string ServerPairName = "";
extern double BidCorrection  = 0;
extern double AskCorrection  = 0;

extern int    APips     = 2;
extern int    TPips     = 5;
extern int    StopPips       = 15;
extern int    VirtualStops   = false;

extern int    ConfirmMS     = 20;
extern int    SleepMS       = 20;
extern int    Slippage      = 1;    
extern int    Magic         = 2013; 


#define  PIPE_BASE_NAME     "\\\\.\\pipe\\mt4-"     // MUST tally with client code
#define  ERROR_MORE_DATA 234

#import "kernel32.dll"
        int CallNamedPipeW(string PipeName, string outBuffer, int outBufferSz, int& inBuffer[], int inBufferSz, int& bytesRead[], int timeOut);
#import


datetime StartTime=0;
double   MinLots=0.1;
double   MaxLots=0.1;
double   LotStep=0.1;
double   MyPoint=0.0001;

string   MasterPair="";
double   MaxBalance=0;
double   TotalPips=0;
int      TotalTrades=0;
double   EntrySlippage=0;
int      EntryMS=0;
int      OpenErrors=0;


int      LastTicket=0;
double   MasterBid=0;
double   MasterAsk=0;

string   LastQ="";
           
int init()
  {
   Comment("Initialization ...");
   if(StringLen(ServerPairName)>=1)
      MasterPair=ServerPairName;
   else
      MasterPair=Symbol();

   StartTime=0;
   return(0);
  }

int deinit()
  {
   Comment("");
   return(0);
  }

int start()
  {
   double CurrentPips=0;
   string sInfo="";
   if(IsStopped() || !IsConnected())
      return(0);

   if(Digits<=3)
      MyPoint=0.01;
   MinLots=MarketInfo(Symbol(),MODE_MINLOT);
   MaxLots=MarketInfo(Symbol(),MODE_MAXLOT);
   LotStep=MarketInfo(Symbol(),MODE_LOTSTEP);

   if(StartTime<=0)
     {
      MaxBalance=AccountBalance();
      StartTime=TimeLocal();
      TotalPips=0;
      EntrySlippage=0;
      TotalTrades=0;
      EntryMS=0;
      LastTicket=0;
      OpenErrors=0;
     }

   while(!IsStopped())  
     {
      RefreshRates();
      double dBid=Bid;
      double dAsk=Ask;
      int OldTicket=LastTicket;
      LastTicket=0;
      for(int j=OrdersTotal()-1; j>=0; j--) 
          if(OrderSelect(j, SELECT_BY_POS, MODE_TRADES))
            if((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Magic))
              {
               if(OrderType()==OP_BUY)
                  CurrentPips=dBid-OrderOpenPrice();
               else
                  CurrentPips=OrderOpenPrice()-dAsk;
               CurrentPips=CurrentPips/MyPoint;
               LastTicket=OrderTicket();
          

              }

      if(LastTicket==0 && OldTicket>0)
         if(OrderSelect(OldTicket, SELECT_BY_TICKET, MODE_HISTORY))
           {
            if(OrderType()==OP_BUY)
               TotalPips=TotalPips+(OrderClosePrice()-OrderOpenPrice())/MyPoint;
            else
               TotalPips=TotalPips+(OrderOpenPrice()-OrderClosePrice())/MyPoint;
           }

      MaxBalance=MathMax(MaxBalance,AccountBalance());
      if(AccountBalance()<=0)
         break;
      sInfo="";
      CheckMaster();
      if(MaxDD<=100*(MaxBalance-AccountBalance())/MaxBalance)
         sInfo=sInfo+"\nMaximum Drawdawn Reached !!!";
      else   
      if(MasterBid>=Point && MasterAsk>=Point)
         sInfo=sInfo+"\nBuy/Sell Levels: "+DoubleToStr((MasterBid-dAsk)/MyPoint-APips,1)+" / "+DoubleToStr((dBid-MasterAsk)/MyPoint-APips,1)+" pips";
      else
      if(StringLen(LastQ)>0)
         sInfo=sInfo+"\nServer: "+LastQ;
      else
         sInfo=sInfo+"\nServer not working !!!";

      if(LastTicket>0)
         sInfo=sInfo+", Position: "+DoubleToStr(CurrentPips,1)+" pips";
      else
      if(MasterBid>=Point && MasterAsk>=Point && MaxDD>100*(MaxBalance-AccountBalance())/MaxBalance)
        {
         bool Oper=-1;
         if((dAsk)>=1.0000)
            Oper=OP_BUY;
         else
         if((dBid)>=1.0000)
            Oper=OP_SELL;
         if(Oper!=-1 && ConfirmMS>0)
           {
            Sleep(ConfirmMS);
            RefreshRates();
            dBid=Bid;
            dAsk=Ask;
            CheckMaster();
            if(Oper==OP_BUY)
               Oper=-1;
            if(Oper==OP_SELL)
               Oper=-1;
           }
         if(Oper!=-1 && IsTradeContextBusy()==false)
           {
            double Lots=MathMax(MinLots,MathMin(MaxLots,MathCeil((MM/100)*AccountFreeMargin()/LotStep/(100000/100))*LotStep));
            int ExecutionTime=GetTickCount();
            if(Oper==OP_BUY)
               LastTicket=OrderSend(Symbol(), OP_BUY, Lots, NormalizeDouble(dAsk,Digits), Slippage*MyPoint/Point, 0, 0, "", Magic,0,Blue);
            else   
               LastTicket=OrderSend(Symbol(), OP_SELL, Lots, NormalizeDouble(dBid,Digits), Slippage*MyPoint/Point, 0, 0, "", Magic,0,Red);
            ExecutionTime=GetTickCount()-ExecutionTime;   
            if(LastTicket<0)
              {
               OpenErrors=OpenErrors+1;
              }
            else
              {
               TotalTrades=TotalTrades+1;
               EntryMS=EntryMS+ExecutionTime;
               if(OrderSelect(LastTicket,SELECT_BY_TICKET))
                  if(OrderType()==OP_BUY)
                     EntrySlippage=EntrySlippage+(dAsk-OrderOpenPrice())/MyPoint;
                  else   
                     EntrySlippage=EntrySlippage+(OrderOpenPrice()-dBid)/MyPoint;
              }
           }
        }

      Comment("\nMagic# "+DoubleToStr(Magic,0)+", MM "+DoubleToStr(MM,2)+ ", Max DD: " + DoubleToStr(MaxDD,1)+"%, Current Drawdawn: "+DoubleToStr(100*(MaxBalance-AccountBalance())/MaxBalance,1)+" %"+
              "\nMin Lot "+DoubleToStr(MinLots,2)+", Max Lot "+DoubleToStr(MaxLots,2)+", Lot Step "+DoubleToStr(LotStep,2)+", Stop Level "+DoubleToStr(MarketInfo(Symbol(),MODE_STOPLEVEL)*Point/MyPoint,1)+" pips"+
              "\n"+sInfo+
              "\nStart Time: "+TimeToStr(StartTime,TIME_DATE|TIME_SECONDS)+
              "\nLocal Time: "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+
              "\nTotal Pips: "+DoubleToStr(TotalPips,1)+
              "\nTotal Trades: "+DoubleToStr(TotalTrades,0)+
              "\nEntry Errors: "+DoubleToStr(OpenErrors,0)+
              "\nOpen Slippage: "+DoubleToStr(EntrySlippage,1)+" pips"+
              "\nAverage Speed: "+DoubleToStr(EntryMS/MathMax(TotalTrades,1),0)+" ms"+
              "\nAverage Slippage: "+DoubleToStr(EntrySlippage/MathMax(TotalTrades,1),1)+" pips"
             );
      Sleep(MathMax(SleepMS,10));
      if(IsTesting())
         break;
     }
   return(0);
  }

void CheckMaster()
  {
   MasterBid=0;
   MasterAsk=0;
   LastQ="";
   if(IsTesting())
     {
      MasterBid=NormalizeDouble(MarketInfo(MasterPair,MODE_BID)/2+MarketInfo(MasterPair,MODE_ASK)/2-MyPoint+2*MyPoint*(MathRand()-32767/2)/(32767/6),Digits);
      MasterAsk=MasterBid+2*MyPoint;
     }
   else
     {
      string MyPipeName = PIPE_BASE_NAME+PipeName;
      int inBuffer[2048];
      int bytesRead[1];
      string extMessage = MasterPair;
      bool fSuccess = CallNamedPipeW(MyPipeName,extMessage,StringLen(extMessage)+1,inBuffer,4*ArraySize(inBuffer),bytesRead,0) != 0;
      int lastError = GetLastError();
      if(fSuccess/* || lastError == ERROR_MORE_DATA*/) 
        { 
         string inString = "";
         for(int i=0; i<bytesRead[0]; i++)
             inString = inString + CharToStr( (inBuffer[i/4] >> ((i & 3)*8)) & 0xff);
         int ai=StringFind(inString, "|", 0);
         if(ai>0)
           {
            MasterBid=StrToDouble(StringSubstr(inString, 0, ai));
            MasterAsk=StrToDouble(StringSubstr(inString, ai+1));
           }
         LastQ=inString;  
        }
     }
   if(MasterBid>0.0001)
      MasterBid=MasterBid+BidCorrection;
   if(MasterAsk>0.0001)
      MasterAsk=MasterAsk+AskCorrection;
  }
 
Sólo como aviso previo, he cambiado el código para llamar a MetaTerminal1 en la cadena externa PipeName pero los datos y las funciones siguen sin funcionar correctamente. ¿Había algo más en el código que necesitara ser ajustado excepto el cambio de la 'A' a la 'W' para 'CreateNamedPip' y 'CreateFile'?
 

Cambiar la "A" por la "W" puede parecer demasiado fácil. Puede haber otros factores con respecto a los cambios en la nueva arquitectura y las funciones de Unicode que deben ser abordados también.

Sin embargo, no sé si se trata de un error o no, porque nunca he utilizado Named Pipes con MT4, pero su "inBuffer" y "outBuffer" (en "CallNamedPipeW") son de tipos diferentes (uno es "string" y el otro es "int"). Esto no parece ser correcto.

En realidad tacha eso, puede ser totalmente correcto dado los extraños trucos de MetaTrader para lograr la interacción de DLL.

Dejaré esa parte a alguien que esté más versado en la interacción de MT4 con DLL.

 
"sksyen", podrías cambiar tu post original para tener el código en una sección de SRC. Si uno de los moderadores pasa por encima de esto, borrará esa parte del post y te pedirá que lo hagas bien de todos modos. Así que hazlo ahora antes de que tengas que volver a buscar el código para pegarlo.
 

También estoy teniendo problemas con las tuberías con nombre en la última versión de MT4

He cambiado WaitNamedPipeA por WaitNamedPipeW y ahora funciona

f (!WaitNamedPipeW( FullPipeName, 1))

{
Comment(TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) + " " + PipeName + " not available"); 
Sleep(1000);
continue;
}


pero cuando uso CreateFileA o CreateFileW, ambas llamadas se cuelgan permanentemente


PipeHandle = CreateFileA(FullPipeName, GenericRead, 0, NULL, OPEN_EXISTING, 0, NULL);


¿Alguna idea o solución?

 
chalky66:

También estoy teniendo problemas con las tuberías con nombre en la última versión de MT4

He cambiado WaitNamedPipeA por WaitNamedPipeW y ahora funciona

Por favor, recuerde utilizar el botón SRC en el futuro.
 

Aquí está el archivo del servidor publicado originalmente (me acordaré de publicarlo en SRC la próxima vez)

extern string PipeName = "MetaTerminal1";

extern int SuspendSeconds = 10;

extern int SleepMS = 10;







#define  PIPE_BASE_NAME "\\\\.\\pipe\\mt4-"



#define  GENERIC_READ 0x80000000

#define  GENERIC_WRITE 0x40000000

#define  PIPE_ACCESS_DUPLEX 3

#define  PIPE_UNLIMITED_INSTANCES 255

#define  PIPE_NOWAIT 1

#define  PIPE_TYPE_MESSAGE 4

#define  PIPE_READMODE_MESSAGE 2

#define  PIPE_WAIT 0



#import "kernel32.dll"

int CreateNamedPipeA(string pipeName,int openMode,int pipeMode,int maxInstances,int outBufferSize,int inBufferSize,int defaultTimeOut,int security);

int PeekNamedPipe(int PipeHandle, int PassAsZero, int PassAsZero2, int PassAsZero3, int & BytesAvailable[], int PassAsZero4);

int CreateFileA(string Filename, int AccessMode, int ShareMode, int PassAsZero, int CreationMode, int FlagsAndAttributes, int AlsoPassAsZero);

int CloseHandle(int fileHandle);

// int ReadFile(int FileHandle, int BufferPtr, int BufferLength, int & BytesRead[], int PassAsZero);

        int ReadFile(int FileHandle, int& inBuffer[],int BufferLength, int& BytesRead[], int lpOverlapped);

int WriteFile(int FileHandle, string Buffer, int BufferLength, int & BytesWritten[], int PassAsZero);

//      int WriteFile(int FileHandle,int& inBuffer[], int NumberOfBytesToWrite, int& bytesWritten[], int lpOverlapped);

int MulDiv(string X, int N1, int N2);

#import



// Number of pipe instances to create by default. This value can overridden by the optional parameter to

// CreatePipeServer(). The number of instances is in effect the maximum number of messages which

// can be sent to the server between each call which the server makes to CheckForPipeMessages().

// If more messages than this are sent, the extra messages will fail and the sender(s) will need to retry.

#define  DEFAULT_MAX_PIPES 200



// Number of pipe instances to allocate. Defaults to DEFAULT_MAX_PIPES unless it is overridden

int glbPipeCount = DEFAULT_MAX_PIPES;

// Array of pipe handles allocated by CreatePipeServer()

int glbPipe[DEFAULT_MAX_PIPES];

// Persistent storage of the pipe name passed as a parameter to CreatePipeServer()

string glbPipeName;



// Starts the pipe server by creating n instances of the pipe

void CreatePipeServer(string PipeName, int UsePipeInstances = DEFAULT_MAX_PIPES)

{

// Store the number of pipe instances to use and resize the array accordinging

glbPipeCount = UsePipeInstances;

ArrayResize(glbPipe, glbPipeCount);

// Store the name to use for the pipe instances

glbPipeName = PipeName;

// Create the pipe instances

for (int i = 0; i < glbPipeCount; i++)

glbPipe[i] = CreatePipeInstance();

return;

}



// Closes all the resources used by the pipe server: i.e. closes all the pipe instances

void DestroyPipeServer()

{

for (int i = 0; i < glbPipeCount; i++)

CloseHandle(glbPipe[i]);

return;

}



// Service function which creates a pipe instance

int CreatePipeInstance()

{

string strPipeName = StringConcatenate(PIPE_BASE_NAME, glbPipeName);

return (CreateNamedPipeA(strPipeName, GENERIC_READ | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 1000, 1000, 0, NULL));

}

datetime StartTime=0;

int brCall=0;



int aPairCount=0;

string aPair[1000];

int aDigit[1000];

datetime aLastSinhTime[1000];

double aBid[1000];

double aAsk[1000];



int init()

{

StartTime=TimeLocal();

brCall=0;

aPairCount=0;



// Create the server

CreatePipeServer(PipeName);

return(0);

}



int deinit()

{

// Destroy the pipe server

DestroyPipeServer();

Comment("");

return(0);

}



int start()

{

while(!IsStopped() && IsConnected())    

{

for(int i = 0; i < glbPipeCount; i++)

CheckPipe(i);

Comment("\nStart Time: "+TimeToStr(StartTime,TIME_DATE|TIME_SECONDS)+

"\nLocal Time: "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+

"\nCall Count: "+DoubleToStr(brCall,0)

);

Sleep(MathMax(SleepMS,10));

}

return(0);

}



bool CheckPipe(int PipeIndex)

{

bool Result=false;

string sMsg = "";

// See if there's data available on the pipe

int BytesAvailable[1] = {0};

int res = PeekNamedPipe(glbPipe[PipeIndex], 0, 0, 0, BytesAvailable, 0);

if (res != 0) {

// PeekNamedPipe() succeeded



// Is there data?

if (BytesAvailable[0] != 0) {

Result=true;



// Keep reading until either we have all the data, or an error occurs

int TotalBytesRead = 0;

while (TotalBytesRead < BytesAvailable[0])

{

string ReadBuffer="";

int iBuffer[256];

int BytesRead[1] = {0};

ReadFile(glbPipe[PipeIndex],iBuffer,4*ArraySize(iBuffer),BytesRead,NULL);

for(int i=0; i<BytesRead[0]; i++)

ReadBuffer = ReadBuffer + CharToStr( (iBuffer[i/4] >> ((i & 3)*8)) & 0xff);

// Did we get any data from the read?

if(BytesRead[0] > 0)

{

// Yes, got some data. Add it to the total message which is passed back

sMsg = StringConcatenate(sMsg, StringSubstr(ReadBuffer, 0, BytesRead[0]));

TotalBytesRead += BytesRead[0];

}

else

{

// No, the read failed. Stop reading, and pass back an empty string

sMsg = "";

TotalBytesRead = 999999;

}

}

if(StringLen(sMsg)>0)

{

string outString="n/a";

RefreshRates();

brCall=brCall+1;

double pBid=MarketInfo(sMsg,MODE_BID);

double pAsk=MarketInfo(sMsg,MODE_ASK);

if(pBid>0.0001 && pAsk>0.0001)

{

int ai=0;

bool fl=true;

for(i=1;i<=aPairCount;i++)

if(aPair[i]==sMsg)

{

ai=i;

break;

}

if(ai==0)

{

aPairCount=aPairCount+1;

ai=aPairCount;

aPair[ai]=sMsg;

aDigit[ai]=MarketInfo(sMsg,MODE_DIGITS);

aLastSinhTime[ai]=TimeLocal();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if(MathAbs(aBid[ai]-pBid)>=0.00001 || MathAbs(aAsk[ai]-pAsk)>=0.00001)

{

aLastSinhTime[ai]=TimeLocal();

aBid[ai]=pBid;

aAsk[ai]=pAsk;

}

else

if(TimeLocal()-aLastSinhTime[ai]>SuspendSeconds)

fl=false;

if(fl)

outString=DoubleToStr(aBid[ai],aDigit[ai])+"|"+DoubleToStr(aAsk[ai],aDigit[ai]);

else

outString="Suspended";

}



int bytesWritten[1];

bool fSuccess=WriteFile(glbPipe[PipeIndex],outString,StringLen(outString)+1,bytesWritten,NULL) != 0;

if(!fSuccess || bytesWritten[0] != StringLen(outString)+1)

{

Sleep(10);

}

}

// Destroy and recreate the pipe instance

CloseHandle(glbPipe[PipeIndex]);

glbPipe[PipeIndex] = CreatePipeInstance();

} else {

// No data available on pipe

}

} else {

// PeekNamedPipe() failed

}

return(Result);

}
 
sksyen: Gracias. El lado del servidor ahora es capaz de ...
Utiliza el SRC y la próxima vez edita tu post original.