2 Commits

Author SHA1 Message Date
Gunther Schulz 08b83713af fix compiler failure 2020-11-22 13:15:51 +01:00
Gunther Schulz 775a962d38 format code with new MT5 code styler 2020-11-22 13:14:33 +01:00
2 changed files with 1735 additions and 1284 deletions
+1542 -1137
View File
File diff suppressed because it is too large Load Diff
+193 -147
View File
@@ -40,8 +40,6 @@ bool debug = true;
bool first = false; bool first = false;
int activeBufferCount = 0; int activeBufferCount = 0;
int activeBufferCount = 0;
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Custom indicator initialization function | //| Custom indicator initialization function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -49,20 +47,24 @@ int OnInit()
{ {
bool result = chartSubscriptionSocket.connect(StringFormat("tcp://%s:%d", HOST, CHART_SUB_PORT)); bool result = chartSubscriptionSocket.connect(StringFormat("tcp://%s:%d", HOST, CHART_SUB_PORT));
if (result == false) {Print("Failed to subscrbe on port ", CHART_SUB_PORT);} if(result == false)
else { {
Print("Accepting Chart Indicator data on port ", CHART_SUB_PORT); Print("Failed to subscrbe on port ", CHART_SUB_PORT);
// TODO subscribe only to own IndicatorId topic }
// Subscribe to all topics else
chartSubscriptionSocket.setSubscribe(""); {
//chartSubscriptionSocket.setLinger(1000); Print("Accepting Chart Indicator data on port ", CHART_SUB_PORT);
chartSubscriptionSocket.setLinger(10000); // TODO subscribe only to own IndicatorId topic
// Number of messages to buffer in RAM. // Subscribe to all topics
chartSubscriptionSocket.setReceiveHighWaterMark(5); // TODO confirm settings chartSubscriptionSocket.setSubscribe("");
} //chartSubscriptionSocket.setLinger(1000);
chartSubscriptionSocket.setLinger(10000);
// Number of messages to buffer in RAM.
chartSubscriptionSocket.setReceiveHighWaterMark(5); // TODO confirm settings
}
//--- indicator buffers mapping; //--- indicator buffers mapping;
ArraySetAsSeries(B0,true); ArraySetAsSeries(B0,true);
ArraySetAsSeries(B1,true); ArraySetAsSeries(B1,true);
@@ -108,22 +110,26 @@ int OnInit()
SetIndexBuffer(19,B19,INDICATOR_DATA); SetIndexBuffer(19,B19,INDICATOR_DATA);
SetIndexBuffer(20,alive,INDICATOR_CALCULATIONS); // If the buffer index changes, the line starting with "CopyBuffer(chartWindowIndicators[i].indicatorHandle," in JsonAPI.mq5 has to be updated SetIndexBuffer(20,alive,INDICATOR_CALCULATIONS); // If the buffer index changes, the line starting with "CopyBuffer(chartWindowIndicators[i].indicatorHandle," in JsonAPI.mq5 has to be updated
//--- //---
IndicatorSetString(INDICATOR_SHORTNAME,ShortName); IndicatorSetString(INDICATOR_SHORTNAME,ShortName);
return(INIT_SUCCEEDED); return(INIT_SUCCEEDED);
} }
void SetStyle(int bufferIdx, string linelabel, color colorstyle, int linetype, int linestyle, int linewidth) {
PlotIndexSetString(bufferIdx,PLOT_LABEL,linelabel); //+------------------------------------------------------------------+
PlotIndexSetInteger(bufferIdx,PLOT_LINE_COLOR,0,colorstyle); //| |
PlotIndexSetInteger(bufferIdx,PLOT_DRAW_TYPE,linetype); //+------------------------------------------------------------------+
PlotIndexSetInteger(bufferIdx,PLOT_LINE_STYLE,linestyle); void SetStyle(int bufferIdx, string linelabel, color colorstyle, int linetype, int linestyle, int linewidth)
PlotIndexSetInteger(bufferIdx,PLOT_LINE_WIDTH,linewidth); {
} PlotIndexSetString(bufferIdx,PLOT_LABEL,linelabel);
PlotIndexSetInteger(bufferIdx,PLOT_LINE_COLOR,0,colorstyle);
PlotIndexSetInteger(bufferIdx,PLOT_DRAW_TYPE,linetype);
PlotIndexSetInteger(bufferIdx,PLOT_LINE_STYLE,linestyle);
PlotIndexSetInteger(bufferIdx,PLOT_LINE_WIDTH,linewidth);
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Custom indicator iteration function | //| Custom indicator iteration function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -138,151 +144,190 @@ int OnCalculate(const int rates_total,
const long &volume[], const long &volume[],
const int &spread[]) const int &spread[])
{ {
// While a new candle is forming, set the current value to be empty // While a new candle is forming, set the current value to be empty
if(rates_total>prev_calculated)
{
B0[0] = EMPTY_VALUE;
B1[0] = EMPTY_VALUE;
B2[0] = EMPTY_VALUE;
B3[0] = EMPTY_VALUE;
B4[0] = EMPTY_VALUE;
B5[0] = EMPTY_VALUE;
B6[0] = EMPTY_VALUE;
B7[0] = EMPTY_VALUE;
B8[0] = EMPTY_VALUE;
B9[0] = EMPTY_VALUE;
B10[0] = EMPTY_VALUE;
B11[0] = EMPTY_VALUE;
B12[0] = EMPTY_VALUE;
B13[0] = EMPTY_VALUE;
B14[0] = EMPTY_VALUE;
B15[0] = EMPTY_VALUE;
B16[0] = EMPTY_VALUE;
B17[0] = EMPTY_VALUE;
B18[0] = EMPTY_VALUE;
B19[0] = EMPTY_VALUE;
}
if(first==false)
alive[0] = 1;
// ChartRedraw(0);
if(rates_total>prev_calculated){
B0[0] = EMPTY_VALUE;
B1[0] = EMPTY_VALUE;
B2[0] = EMPTY_VALUE;
B3[0] = EMPTY_VALUE;
B4[0] = EMPTY_VALUE;
B5[0] = EMPTY_VALUE;
B6[0] = EMPTY_VALUE;
B7[0] = EMPTY_VALUE;
B8[0] = EMPTY_VALUE;
B9[0] = EMPTY_VALUE;
B10[0] = EMPTY_VALUE;
B11[0] = EMPTY_VALUE;
B12[0] = EMPTY_VALUE;
B13[0] = EMPTY_VALUE;
B14[0] = EMPTY_VALUE;
B15[0] = EMPTY_VALUE;
B16[0] = EMPTY_VALUE;
B17[0] = EMPTY_VALUE;
B18[0] = EMPTY_VALUE;
B19[0] = EMPTY_VALUE;
}
if(first==false) alive[0] = 1;
// ChartRedraw(0);
//--- return value of prev_calculated for next call //--- return value of prev_calculated for next call
return(rates_total); return(rates_total);
} }
void SubscriptionHandler(ZmqMsg &chartMsg){ //+------------------------------------------------------------------+
CJAVal message; //| |
// Get data from request //+------------------------------------------------------------------+
string msg=chartMsg.getData(); void SubscriptionHandler(ZmqMsg &chartMsg)
if(debug) Print("Processing:"+msg); {
// Deserialize msg to CJAVal array CJAVal message;
if(!message.Deserialize(msg)){ // Get data from request
Alert("Deserialization Error"); string msg=chartMsg.getData();
ExpertRemove(); if(debug)
} Print("Processing:"+msg);
if(message["indicatorChartId"]==IndicatorId) { // Deserialize msg to CJAVal array
if(!message.Deserialize(msg))
{
Alert("Deserialization Error");
ExpertRemove();
}
if(message["indicatorChartId"]==IndicatorId)
{
if(message["action"]=="PLOT" && message["actionType"]=="DATA") { if(message["action"]=="PLOT" && message["actionType"]=="DATA")
int bufferIdx = message["indicatorBufferId"].ToInt(); {
if (bufferIdx == 0) WriteToBuffer(message, B0); int bufferIdx = message["indicatorBufferId"].ToInt();
if (bufferIdx == 1) WriteToBuffer(message, B1); if(bufferIdx == 0)
if (bufferIdx == 2) WriteToBuffer(message, B2); WriteToBuffer(message, B0);
if (bufferIdx == 3) WriteToBuffer(message, B3); if(bufferIdx == 1)
if (bufferIdx == 4) WriteToBuffer(message, B4); WriteToBuffer(message, B1);
if (bufferIdx == 5) WriteToBuffer(message, B5); if(bufferIdx == 2)
if (bufferIdx == 6) WriteToBuffer(message, B6); WriteToBuffer(message, B2);
if (bufferIdx == 7) WriteToBuffer(message, B7); if(bufferIdx == 3)
if (bufferIdx == 8) WriteToBuffer(message, B8); WriteToBuffer(message, B3);
if (bufferIdx == 9) WriteToBuffer(message, B9); if(bufferIdx == 4)
if (bufferIdx == 10) WriteToBuffer(message, B10); WriteToBuffer(message, B4);
if (bufferIdx == 11) WriteToBuffer(message, B11); if(bufferIdx == 5)
if (bufferIdx == 12) WriteToBuffer(message, B12); WriteToBuffer(message, B5);
if (bufferIdx == 13) WriteToBuffer(message, B13); if(bufferIdx == 6)
if (bufferIdx == 14) WriteToBuffer(message, B14); WriteToBuffer(message, B6);
if (bufferIdx == 15) WriteToBuffer(message, B15); if(bufferIdx == 7)
if (bufferIdx == 16) WriteToBuffer(message, B16); WriteToBuffer(message, B7);
if (bufferIdx == 17) WriteToBuffer(message, B17); if(bufferIdx == 8)
if (bufferIdx == 18) WriteToBuffer(message, B18); WriteToBuffer(message, B8);
if (bufferIdx == 19) WriteToBuffer(message, B19); if(bufferIdx == 9)
} WriteToBuffer(message, B9);
else if(message["action"]=="PLOT" && message["actionType"]=="ADDBUFFER") { if(bufferIdx == 10)
string linelabel = message["style"]["linelabel"].ToStr(); WriteToBuffer(message, B10);
string colorstyleStr = message["style"]["color"].ToStr(); if(bufferIdx == 11)
string linetypeStr = message["style"]["linetype"].ToStr(); WriteToBuffer(message, B11);
string linestyleStr = message["style"]["linestyle"].ToStr(); if(bufferIdx == 12)
int linewidth = message["style"]["linewidth"].ToInt(); WriteToBuffer(message, B12);
if(bufferIdx == 13)
color colorstyle = StringToColor(colorstyleStr); WriteToBuffer(message, B13);
int linetype = StringToEnumInt(linetypeStr); if(bufferIdx == 14)
int linestyle = StringToEnumInt(linestyleStr); WriteToBuffer(message, B14);
if(bufferIdx == 15)
/* WriteToBuffer(message, B15);
//if (aa == false) { if(bufferIdx == 16)
Print("SETBUFF ActCount ",activeBufferCount); WriteToBuffer(message, B16);
if (activeBufferCount == 0) {SetIndexBuffer(0,B1,INDICATOR_DATA);} // Two semicolons ar required! No idea why. Seems to be a timing problem, better to keep it in init() if(bufferIdx == 17)
WriteToBuffer(message, B17);
if (activeBufferCount == 1) {SetIndexBuffer(1,B2,INDICATOR_DATA);;} if(bufferIdx == 18)
if (activeBufferCount == 2) {SetIndexBuffer(2,B3,INDICATOR_DATA);;} WriteToBuffer(message, B18);
if (activeBufferCount == 3) {SetIndexBuffer(3,B4,INDICATOR_DATA);;} if(bufferIdx == 19)
if (activeBufferCount == 4) {SetIndexBuffer(4,B5,INDICATOR_DATA);;} WriteToBuffer(message, B19);
}
else
if(message["action"]=="PLOT" && message["actionType"]=="ADDBUFFER")
{
string linelabel = message["style"]["linelabel"].ToStr();
string colorstyleStr = message["style"]["color"].ToStr();
string linetypeStr = message["style"]["linetype"].ToStr();
string linestyleStr = message["style"]["linestyle"].ToStr();
int linewidth = message["style"]["linewidth"].ToInt();
//aa = true;} color colorstyle = StringToColor(colorstyleStr);
*/ int linetype = StringToEnumInt(linetypeStr);
int linestyle = StringToEnumInt(linestyleStr);
SetStyle(activeBufferCount, linelabel, colorstyle, linetype, linestyle, linewidth);
activeBufferCount = activeBufferCount + 1; /*
} //if (aa == false) {
Print("SETBUFF ActCount ",activeBufferCount);
if (activeBufferCount == 0) {SetIndexBuffer(0,B1,INDICATOR_DATA);} // Two semicolons ar required! No idea why. Seems to be a timing problem, better to keep it in init()
if (activeBufferCount == 1) {SetIndexBuffer(1,B2,INDICATOR_DATA);;}
if (activeBufferCount == 2) {SetIndexBuffer(2,B3,INDICATOR_DATA);;}
if (activeBufferCount == 3) {SetIndexBuffer(3,B4,INDICATOR_DATA);;}
if (activeBufferCount == 4) {SetIndexBuffer(4,B5,INDICATOR_DATA);;}
//aa = true;}
*/
SetStyle(activeBufferCount, linelabel, colorstyle, linetype, linestyle, linewidth);
activeBufferCount = activeBufferCount + 1;
}
}
} }
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Update indicator buffer function | //| Update indicator buffer function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void WriteToBuffer(CJAVal &message, double &buffer[]) { void WriteToBuffer(CJAVal &message, double &buffer[])
{
int bufferSize = ArraySize(buffer);
int messageDataSize = message["data"].Size(); int bufferSize = ArraySize(buffer);
// TODO check if this is working as expected. Seems to
if(first==false) {
for(int i=0;i<activeBufferCount;i++) {
//Print("BUFF ",bufferSize-messageDataSize, " ",ArraySize(B2)," ", ArraySize(B3), " ",messageDataSize);
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,bufferSize-messageDataSize);
}
first = true;
}
for(int i=0;i<messageDataSize;i++){ int messageDataSize = message["data"].Size();
// don't add more elements than the automatically sized buffer array can hold // TODO check if this is working as expected. Seems to
if(i+1<bufferSize){ if(first==false)
// the first element is the current unformed candle, so we start at index 1 {
// we reverse the order of the incoming values, which are expected to be ascending for(int i=0; i<activeBufferCount; i++)
//buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl(); {
buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl(); //Print("BUFF ",bufferSize-messageDataSize, " ",ArraySize(B2)," ", ArraySize(B3), " ",messageDataSize);
} PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,bufferSize-messageDataSize);
}
first = true;
}
for(int i=0; i<messageDataSize; i++)
{
// don't add more elements than the automatically sized buffer array can hold
if(i+1<bufferSize)
{
// the first element is the current unformed candle, so we start at index 1
// we reverse the order of the incoming values, which are expected to be ascending
//buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl();
buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl();
}
}
// Set the most recent plotted value to nothing, as we do not have any data for yet unformed candles
buffer[0] = EMPTY_VALUE;
} }
// Set the most recent plotted value to nothing, as we do not have any data for yet unformed candles
buffer[0] = EMPTY_VALUE;
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| Check for new indicator data function | //| Check for new indicator data function |
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void CheckMessages(){ void CheckMessages()
// This is a workaround for Timer(). It is needed, because OnTimer() works if the indicator is manually added to a chart, but not with ChartIndicatorAdd() {
// This is a workaround for Timer(). It is needed, because OnTimer() works if the indicator is manually added to a chart, but not with ChartIndicatorAdd()
ZmqMsg chartMsg; ZmqMsg chartMsg;
// Recieve chart instructions stream from client via live Chart socket. // Recieve chart instructions stream from client via live Chart socket.
chartSubscriptionSocket.recv(chartMsg,true); chartSubscriptionSocket.recv(chartMsg,true);
// Request recieved // Request recieved
if(chartMsg.size()>0){ if(chartMsg.size()>0)
// Handle subscription SubscriptionHandler() {
SubscriptionHandler(chartMsg); // Handle subscription SubscriptionHandler()
ChartRedraw(ChartID()); SubscriptionHandler(chartMsg);
ChartRedraw(ChartID());
}
} }
}
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
//| OnTimer() workaround function | //| OnTimer() workaround function |
@@ -293,6 +338,7 @@ void OnChartEvent(const int id,
const double &dparam, const double &dparam,
const string &sparam) const string &sparam)
{ {
if(id==CHARTEVENT_CUSTOM+222) CheckMessages(); if(id==CHARTEVENT_CUSTOM+222)
CheckMessages();
} }
//+---------------------------------------------------- //+----------------------------------------------------