quick channel

 

I am using quick channel that I down loaded from https://www.mql4.com/go?http://www.mt4i.com/quickchannel.aspx

I have discovered how to have the sending broker ea send all the data that I want to the receiving broker ea.

However, once received, I do not know how to break it back up into individual data points that I can use.

The data comes into the receiving broker ea as one variable. A string... but in that string are several variables... bid, ask, account equity, etc., etc., etc.,

How do I break that one string variable, back into individual parts again?

 
mrchuckw:

How do I break that one string variable, back into individual parts again?

You can use

int StringFind( string text, string matched_text, int start=0) 
 

to find characters like ";" that delimit the fields then use

string StringSubstr( string text, int start, int length=0) 
 

to chop the string up. Then

double StrToDouble( string value) 
int StrToInteger( string value) 
datetime StrToTime( string value) 
 

to convert the sub-strings to the correct data type. This is very tedious work but you only have to get it working once.

 

Something like

Untested

double tokenD(string text, int& pos, string delim=",", double deflt=0){
    return( tokenS(text, pos, delim, deflt) );
}
int tokenI(string text, int& pos, string delim=",", int deflt=0){
    return( tokenS(text, pos, delim, deflt) );
}
datetime tokenDt(string text, int& pos, string delim=",", datetime deflt=D''){
    return(StrToTime(tokenS( text, pos, delim, TimeToStr(deflt) )));
}
string tokenS(string text, int& pos, string delim=",", string deflt=""){
    int start = pos,    end = pos,  length = StringLen(text);
    for(; end < length; length++){
        string chr = StringSubstr(text, end,1);
        if (chr == delim)           break;
        if (chr == "\\"){
            chr = StringSubstr(text, end+1,1);
            if      (chr == "n")    chr = "\n";     // NL
            else if (chr == "t")    chr = "\t";     // tab
            else if (chr == "r")    chr = "\r";     // return
            // "\,", "\'", and '\"' handled implicitly. "\xHH" not implimented.
            pos = end+2;
            return(StringConcatenate( StringSubstr(text, start, end-start),
                                      chr,
                                      tokenS(text, pos, delim,"") ));
        }
    }
    pos = end + 1;  // Skip deliminator next time
    if (start == end)   return(deflt);
    return( SubStr(text, start, end-start) );
}

string test="1,2.3,10:23,ab\\,cd"; int pos=0;
int         A = tokenI(test, pos);  // 1
double      B = tokenD(test, pos);  // 2.3
datetime    C = tokenDt(test, pos); // today 10:23:00.00
string      D = tokenS(test, pos);  // "ab,cd"
 
WHRoeder:

Something like

Untested



OK... I'm working on this, but I cant get it to compile. I don't know if I'm putting it in the wrong place in the file.... I put it down at the bottom.

Here is the code from the original down load... can you tell me where to put your code, so it compiles correctly.? I can play with it from there.

From what I can see of the code, it is doing exactly what I need, if I could just get it to compile.

Thanks for the help... I've only been coding very part time for about 8 months... and still have tons to learn.

// ####################################################################
//
// Example receiver EA for the QuickChannel library. Designed to 
// receive messages from the sender-example, and simply logs them.
// In real life, this receiver could parse the messages, e.g.
// looking for its prices being better than those in the other 
// MT4 instance, and exploiting any arbitrage opportunity.
//
// The sender and receiver must use the same "channel" name,
// defined in these examples by the ChannelName parameter.
// You can safely have multiple senders on the same channel, e.g.
// EAs running on lots of different charts, all sending their latest
// prices to a single receiver. However, there should only ever
// be one receiver using a channel. If there is more 
// than one, then each receiver will only see some of the messages 
// because retrieving the list of available messages from 
// a channel also clears the list of messages.
//
// A single EA can send on multiple channels by calling QC_StartSender()
// more than once, and storing the different handle values for 
// later use with QC_SendMessage(). A single EA can also act as both
// sender and receiver.
//
// ####################################################################

// Imports from the QuickChannel library
#import "MT4iQuickChannel.dll"
   int QC_StartReceiver(string, int);
   int QC_ReleaseReceiver(int);
   string QC_GetMessages(int);
#import

// Kernel logging function whose output can be viewed in Dbgview
// (http://technet.microsoft.com/en-us/sysinternals/bb896647). 
// Easy way of checking how quickly messages are being transmitted.
#import "kernel32.dll"
   void OutputDebugStringA(string msg);
#import

// External, user-configurable properties
extern string  ChannelName = "QuickChannelTest";
extern bool    LogMessagesToDbgView = true;


// Handle which is acquired during start() and freed during deinit()
int glbHandle = 0;


// EA initialisation.
void init()
{
   // N.B. The QC_StartReceiver function needs a call to WindowHandle(). 
   // This can return zero during init() if an EA is loading while 
   // MT4 starts up. Therefore, the setup needs to be done in
   // start(), not in init(), so that WindowHandle() is guaranteed
   // to return a value.
}


// EA termination. The sender will typically do QC_ReleaseReceiver() here.
void deinit()
{
   QC_ReleaseReceiver(glbHandle);
   glbHandle = 0;
}



// EA per-tick function. 
void start()
{
   // Initialise receiving via QuickChannel. Return value is 1 if successful, or 0
   // if initialisation fails. This handle gets stored in a global variable
   // for later use in start()
   if (glbHandle == 0) {
      glbHandle = QC_StartReceiver(ChannelName, WindowHandle(Symbol(), Period()));
   
      if (glbHandle == 0) {
         Alert("Failed to get a QuickChannel receiver handle");
      }
   }

   // Don't do anything unless initialisation was successful...
   if (glbHandle != 0) {
      // Get all messages which have been sent since the last
      // check to QC_GetMessages(). If there are multiple 
      // pending messages then this will return a tab-separated
      // list. The call to QC_GetMessages() wipes the list while 
      // retrieving it.     
      string strMsgList = QC_GetMessages(glbHandle);
      
      // If we get a message from the example sender, then
      // we simply log it 
      if (strMsgList != "") {
         
         // There may either be one message, or multiple messages 
         // separated by tabs.
         //
         // The list is in the order that the messages were sent.
         // In some scenarios you may need to process it
         // in REVERSE ORDER, e.g. because the list includes 
         // two prices for the same symbol and you only want
         // to use the more recent report.
         
         string Messages[];
         StringSplit(strMsgList, "\t", Messages);
         
         for (int i = 0; i < ArraySize(Messages); i++) {
            string strMsg = Messages[i];

            if (LogMessagesToDbgView) OutputDebugStringA("..." + strMsg);
         
            Comment(strMsg);
            Print(strMsg);
         }
      }  
   }
}   


// Function which splits a delimited piece of text into its
// component parts. Used to process the potentially
// tab-separated list from QC_GetMessages()
void StringSplit(string InputString, string Separator, string & ResultArray[])
{
   ArrayResize(ResultArray, 0);
   
   int lenSeparator = StringLen(Separator), NewArraySize;
   while (InputString != "") {
      int p = StringFind(InputString, Separator);
      if (p == -1) {
         NewArraySize = ArraySize(ResultArray) + 1;
         ArrayResize(ResultArray, NewArraySize);      
         ResultArray[NewArraySize - 1] = InputString;
         InputString = "";
      } else {
         NewArraySize = ArraySize(ResultArray) + 1;
         ArrayResize(ResultArray, NewArraySize);      
         ResultArray[NewArraySize - 1] = StringSubstr(InputString, 0, p);
         InputString = StringSubstr(InputString, p + lenSeparator);
         if (InputString == "") {
            ArrayResize(ResultArray, NewArraySize + 1);      
            ResultArray[NewArraySize] = "";
         }
      }     
   }
}
 
got it figured out... thanks for everyone's help!
 

Hi,

have you files

QuickChannel_Example_Sender.mq4

and

QuickChannel_Example_Receiver.mq4 ?

I am installing quick channel, but I don´t have this two files.

Thank you, Endy

 

i think it should be

double tokenD(string text, int& pos, string delim=",", double deflt=0){
    return( StrToDouble(tokenS(text, pos, delim, deflt)) );
}
int tokenI(string text, int& pos, string delim=",", int deflt=0){
    return( StrToInteger(tokenS(text, pos, delim, deflt)) ); 

}

 
  1. I did say
    untested
  2. I was thinking double = string and int = string are implicit conversions.
  3. I have written/tested
    int      SubstrToInteger(string what, int start=0, int count=EMPTY){
       string   substr   = StringSubstr(what, start, count);
       int      value    = StrToInteger(substr);                   return(value); }
    double   SubstrToDouble(string what, int start=0, int count=EMPTY){
       string   substr   = StringSubstr(what, start, count);
       double   value    = StrToDouble(substr);                    return(value); }
    
    So probably yes.