Обновление MQL4 600 и именных труб

 

Здравствуйте,

После недавнего обновления я теперь не могу перехватить счетчик вызовов с одного экземпляра моего терминала MT4, чтобы передать его на другой MT4. Можете ли вы сказать мне, что изменилось в обновлении, что вызывает эту проблему? Ниже приведен код, который продолжает нормально работать с билдом 509, но не работает после недавнего обновления.


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);

}
 

Используйте кнопку SRC для размещения кода, иначе модераторы просто удалят его!

Кроме того, прочитайте многие другие темы, в которых упоминалось, что функции "A" больше не поддерживаются, и вам придется использовать широкие версии функций "W", такие как "CreateNamedPipeW" вместо "CreateNamedPipeA".

 
sksyen:

Спасибо за ответ и мои извинения за то, что не вставил SRC в виде файла.

Что касается вашего ответа, означает ли это, что мне просто нужно изменить именованную ссылку труб "A" на "W"? Я пытался найти несколько тем по этому поводу, но не смог найти - ваша помощь будет очень признательна. Еще раз спасибо.

Это не вставка источника в виде файла, а использование инструмента SRC для размещения кода здесь на форуме. Как использовать кнопку SRC. (предоставлено "RaptorUK").

Вот пара ссылок на аналогичные дилеммы с Wide версией Functions:

 

Спасибо. Теперь серверная сторона способна перехватывать счетчик коллов после обновления именованных труб "A" на "W". Однако другой экземпляр MT4, похоже, испытывает проблемы с получением информации. Я обновил именованные трубы до 'W' на принимающей стороне, но по какой-то причине она все еще не может получить данные. Есть идеи? Код на принимающей стороне см. ниже:

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;
  }
 
Просто в качестве предварительного уведомления, я изменил код, чтобы вызвать MetaTerminal1 в внешней строке PipeName, но данные и функции все еще не работают должным образом. Было ли что-то еще в коде, что нужно было подправить, кроме замены 'A' на 'W' для 'CreateNamedPip' и 'CreateFile'?
 

Замена "A" на "W" может показаться слишком простой. Возможно, есть и другие факторы, связанные с изменениями в новой архитектуре и функциями Unicode, которые также необходимо рассмотреть.

Однако, я не знаю, ошибка это или нет, потому что я никогда не использовал Named Pipes в MT4, но ваши "inBuffer" и "outBuffer" (в "CallNamedPipeW") имеют разные типы (один - "string", а другой - "int"). Это кажется неправильным.

На самом деле это может быть совершенно правильно, учитывая странные трюки MetaTrader для осуществления взаимодействия с DLL.

Я оставлю эту часть для того, кто лучше разбирается в взаимодействии MT4 и DLL.

 
"sksyen", не могли бы вы изменить свое первоначальное сообщение, чтобы код был в разделе SRC. Если кто-то из модераторов обратит на это внимание, он удалит эту часть сообщения и попросит вас в любом случае сделать все правильно. Так что сделайте это сейчас, пока вам не пришлось снова искать код, чтобы вставить его.
 

У меня также возникли проблемы с именованными трубами в последнем выпуске MT4.

Я изменил WaitNamedPipeA на WaitNamedPipeW, и теперь это работает.

f (!WaitNamedPipeW( FullPipeName, 1))

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


но когда я использую CreateFileA или CreateFileW, оба вызова просто постоянно зависают.


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


Есть идеи / решения?

 
chalky66:

У меня также есть проблемы с именованными трубами в последнем выпуске MT4

Я изменил WaitNamedPipeA на WaitNamedPipeW, и теперь все работает.

Пожалуйста, не забывайте использовать кнопку SRC в будущем...
 

Вот файл сервера, размещенный первоначально (в следующий раз я не забуду разместить его в SRC)

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: Спасибо. Серверная сторона теперь может ...
Используйте SRC и в следующий раз отредактируйте свое исходное сообщение.
Причина обращения: