Use the SRC button to place code, otherwise the moderators are just going to delete it!
Also, read the many other threads that have mentioned that the "A" functions are no longer supported and you will have use the "W" Wide versions of the functions such as "CreateNamedPipeW" instead of "CreateNamedPipeA".
Thank you for replying and my apologies for not pasting the SRC as a file.
With regards to your response, does this mean I simply need to change the named pipes "A" reference to a "W" instead? I tried looking up some threads regarding this but was unable to find - your help is much appreciated. Thanks again.
It is not pasting the source as a file, but using the SRC tool to place code here on the forum. How to use the SRC button. (provided by "RaptorUK")
Here are a couple of references to similar dilemmas with the Wide version of Functions:
Thank you. The server side now is able to capture the call count after updating the named pipes "A" to "W'. However, from the other instance of the MT4, it appears to have trouble receiving the input of information. I've updated the name pipes to 'W' on the receiving end but it still fails to pull the data for some reason. Any ideas? See below for the code on the receiving end:
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; }
Changing "A" to "W" might seem to be too easy. There may be other factors with regard to changes in the new architecture and the Unicode functions that need to be addressed too.
However, I do not know if this is a bug or not, because I have never used Named Pipes with MT4, but your "inBuffer" and "outBuffer" (in "CallNamedPipeW") are of different types (one is "string" and the other is "int"). That does not seem to be correct.
Actually scratch that, it may be totally correct given MetaTrader's strange tricks to accomplish DLL interaction.
I will leave that part to someone who is more versed in MT4 to DLL interfacing.
I'm also having issues with named pipes in the latest release of MT4
I changed WaitNamedPipeA to WaitNamedPipeW and that is now working
f (!WaitNamedPipeW( FullPipeName, 1)) { Comment(TimeToStr(TimeLocal(), TIME_DATE|TIME_MINUTES|TIME_SECONDS) + " " + PipeName + " not available"); Sleep(1000); continue; }
but when I use either CreateFileA or CreateFileW, both calls just permanently hang
PipeHandle = CreateFileA(FullPipeName, GenericRead, 0, NULL, OPEN_EXISTING, 0, NULL);
Any ideas / solutions ?
I'm also having issues with named pipes in the latest release of MT4
I changed WaitNamedPipeA to WaitNamedPipeW and that is now working
Here's the Server file posted originally (I'll remember to post it in SRC next time)
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); }

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello,
After this recent update, I am now unable to capture the call count from one instance of my MT4 terminal to relay it onto another MT4. Can you tell me what has changed in the update that causes this issue? Below is the code that continues to work fine with build 509 but not after this recent update.