アップデート MQL4 600 & ネイムドパイプ

 

こんにちは。

最近のアップデート後、私のMT4ターミナルの1つのインスタンスからコールカウントをキャプチャして、別の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"関数は サポートされなくなり、"CreateNamedPipeA" の代わりに "CreateNamedPipeW" などの "W" Wide バージョンを使用する必要があると述べられています。

 
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;
  }
 
一応、PipeNameのextern文字列でMetaTerminal1を呼び出すようにコードを変更しましたが、まだデータや関数が 正常に動作しません。CreateNamedPip'と'CreateFile'の'A'を'W'に変更した以外に何か調整する必要があったのでしょうか?
 

A "を "W "に変えるのは簡単すぎるように思えるかもしれません。新アーキテクチャやUnicode関数の変更については、他にも対応しなければならない要因があるかもしれません。

ただ、MT4でNamed Pipesを 使ったことがないので、バグかどうかわかりませんが、"CallNamedPipeW "の "inBuffer "と "outBuffer "が異なる型(一方は "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ボタンを 使用することを忘れないでください ... ...
 

元々投稿されていたServerファイルはこちらです(次回は忘れずに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を使用して、次回は元の 投稿を編集して ください。