Kodu yerleştirmek için SRC düğmesini kullanın, aksi takdirde moderatörler kodu silecektir!
Ayrıca, "A" işlevlerinin artık desteklenmediğini ve "CreateNamedPipeA" yerine "CreateNamedPipeW" gibi işlevlerin "W" Geniş sürümlerini kullanacağınızı belirten diğer birçok ileti dizisini okuyun.
Yanıtladığınız için teşekkür ederim ve SRC'yi dosya olarak yapıştırmadığım için özür dilerim.
Yanıtınızla ilgili olarak, bu, "A" adlı boruları bunun yerine "W" olarak değiştirmem gerektiği anlamına mı geliyor? Bununla ilgili bazı konuları aramayı denedim ama bulamadım - yardımınız çok takdir edildi. Tekrar teşekkürler.
Kaynağı bir dosya olarak yapıştırmak değil, kodu buraya foruma yerleştirmek için SRC aracını kullanmaktır. SRC düğmesi nasıl kullanılır. ("RaptorUK" tarafından sağlanır)
Geniş İşlevler sürümüyle ilgili benzer ikilemlere ilişkin birkaç referans:
Teşekkür ederim. Sunucu tarafı artık "A" adlı boruları "W" olarak güncelledikten sonra çağrı sayısını yakalayabilir. Ancak, MT4'ün diğer örneğinden, bilgi girişini almakta sorun yaşıyor gibi görünüyor. ad alıcı uçta 'W'ye yönlendirilir, ancak yine de bir nedenden dolayı verileri çekemez. Herhangi bir fikriniz var mı? Alıcı taraftaki kod için aşağıya bakın:
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; }
"A"yı "W" olarak değiştirmek çok kolay görünebilir. Yeni mimarideki değişiklikler ve Unicode işlevleriyle ilgili olarak ele alınması gereken başka faktörler de olabilir.
Ancak, bunun bir hata olup olmadığını bilmiyorum, çünkü MT4 ile Adlandırılmış Boruları hiç kullanmadım, ancak "inBuffer" ve "outBuffer" ("CallNamedPipeW" içinde) farklı türlerdedir (biri "string" ve diğeri "int" dir). Bu doğru görünmüyor.
Aslında bunu çizin, MetaTrader'ın DLL etkileşimini gerçekleştirmek için garip hileleri göz önüne alındığında tamamen doğru olabilir.
Bu kısmı, MT4'ten DLL arabirimine daha fazla hakim olan birine bırakacağım.
Ayrıca MT4'ün en son sürümünde adlandırılmış kanallarla ilgili sorunlar yaşıyorum
WaitNamedPipeA'yı WaitNamedPipeW olarak değiştirdim ve bu şimdi çalışıyor
f (!WaitNamedPipeW( FullPipeName, 1 )) { Comment ( TimeToStr ( TimeLocal (), TIME_DATE | TIME_MINUTES | TIME_SECONDS ) + " " + PipeName + " not available" ); Sleep ( 1000 ); continue ; }
ancak CreateFileA veya CreateFileW kullandığımda, her iki çağrı da kalıcı olarak askıda kalıyor
PipeHandle = CreateFileA(FullPipeName, GenericRead, 0, NULL, OPEN_EXISTING, 0, NULL);
Herhangi bir fikir/çözüm?
Ayrıca MT4'ün en son sürümünde adlandırılmış kanallarla ilgili sorunlar yaşıyorum
WaitNamedPipeA'yı WaitNamedPipeW olarak değiştirdim ve bu şimdi çalışıyor
İşte orijinal olarak gönderilen Sunucu dosyası (bir dahaki sefere SRC'de yayınlamayı hatırlayacağım)
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); }

- Ücretsiz alım-satım uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz
Merhaba,
Bu son güncellemeden sonra, artık MT4 terminalimin bir örneğinden gelen çağrı sayısını başka bir MT4'e aktarmak için yakalayamıyorum. Bu soruna neden olan güncellemede neyin değiştiğini söyleyebilir misiniz? Aşağıda, build 509 ile sorunsuz çalışmaya devam eden ancak bu son güncellemeden sonra çalışmayan kod bulunmaktadır.