fix indicator plots starting at the wrong timestamp under certain cond.
plots would shift if the processing of indicaters would shift, if a new candle would for in MT while processing of indicator data of the client was still in process. The fix ensure, that any new indicator data starts at the correct timestamp.
This commit is contained in:
+56
-65
@@ -101,10 +101,6 @@ struct ChartWindowIndicator
|
|||||||
ChartWindowIndicator chartWindowIndicators[];
|
ChartWindowIndicator chartWindowIndicators[];
|
||||||
int chartWindowIndicatorCount = 0;
|
int chartWindowIndicatorCount = 0;
|
||||||
|
|
||||||
// Refresh chart window interval for JsonAPIIndicator
|
|
||||||
int chartWindowTimerInterval = 1; // Cycles of the globally set EventSetMillisecondTimer interval
|
|
||||||
int chartWindowTimerCounter = 0; // Keeps track of the current cycle
|
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
ControlErrors mControl;
|
ControlErrors mControl;
|
||||||
|
|
||||||
@@ -465,25 +461,19 @@ void OnTimer()
|
|||||||
// Ensure that all indicators have finished intitailisation
|
// Ensure that all indicators have finished intitailisation
|
||||||
for(int i=0; i<ArraySize(chartWindowIndicators); i++)
|
for(int i=0; i<ArraySize(chartWindowIndicators); i++)
|
||||||
{
|
{
|
||||||
CopyBuffer(chartWindowIndicators[i].indicatorHandle, 7, 0, 1, values); // '7' is the number of the 'alive' indicator buffer
|
//CopyBuffer(chartWindowIndicators[i].indicatorHandle, 7, 0, 1, values); // '7' is the number of the 'alive' indicator buffer
|
||||||
|
// Wait for CopyBuffer to return. Ensures that indicator has been initialized
|
||||||
|
CopyBuffer(chartWindowIndicators[i].indicatorHandle, 0, 0, 1, values); // '7' is the number of the 'alive' indicator buffer
|
||||||
}
|
}
|
||||||
chartIndicatorDataSocket.send(chartMsg,true);
|
chartIndicatorDataSocket.send(chartMsg,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: It looks like it is not necessary to throttle this.
|
|
||||||
// Trigger the indicator JsonAPIIndicator to check for new Messages
|
// Trigger the indicator JsonAPIIndicator to check for new Messages
|
||||||
if(chartWindowTimerCounter >= chartWindowTimerInterval)
|
for(int i=0; i<ArraySize(chartWindows); i++)
|
||||||
{
|
{
|
||||||
for(int i=0; i<ArraySize(chartWindows); i++)
|
long chartId = chartWindows[i].id;
|
||||||
{
|
EventChartCustom(chartId, 222, 222, 222.0);
|
||||||
long ChartId = chartWindows[i].id;
|
|
||||||
EventChartCustom(ChartId, 222, 222, 222.0);
|
|
||||||
}
|
|
||||||
chartWindowTimerCounter = 0;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
chartWindowTimerCounter++;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -823,6 +813,7 @@ void OpenChart(CJAVal &dataObject)
|
|||||||
CJAVal message;
|
CJAVal message;
|
||||||
message["error"]=(bool) false;
|
message["error"]=(bool) false;
|
||||||
message["chartId"] = (string) chartId;
|
message["chartId"] = (string) chartId;
|
||||||
|
message["mtChartId"] = (string) chartWindows[idx].id;
|
||||||
|
|
||||||
string t=message.Serialize();
|
string t=message.Serialize();
|
||||||
if(debug)
|
if(debug)
|
||||||
@@ -837,16 +828,16 @@ void AddChartIndicator(CJAVal &dataObject)
|
|||||||
{
|
{
|
||||||
|
|
||||||
string chartIdStr=dataObject["chartId"].ToStr();
|
string chartIdStr=dataObject["chartId"].ToStr();
|
||||||
string chartIndicatorId=dataObject["indicatorChartId"].ToStr();
|
string chartIndicatorId=dataObject["chartIndicatorId"].ToStr();
|
||||||
int chartIndicatorSubWindow=dataObject["chartIndicatorSubWindow"].ToInt();
|
int chartIndicatorSubWindow=dataObject["chartIndicatorSubWindow"].ToInt();
|
||||||
string shortName = dataObject["shortName"].ToStr();
|
string shortName = dataObject["shortName"].ToStr();
|
||||||
|
|
||||||
int chartIdx = GetChartWindowIdxByChartWindowId(chartIdStr);
|
int chartIdx = GetChartWindowIdxByChartWindowId(chartIdStr);
|
||||||
long ChartId = chartWindows[chartIdx].id;
|
long chartId = chartWindows[chartIdx].id;
|
||||||
|
|
||||||
double chartIndicatorHandle = iCustom(ChartSymbol(ChartId),ChartPeriod(ChartId),"JsonAPIIndicator",chartIndicatorId,shortName); //linelabel,colorstyle,linetype,linestyle,linewidth);
|
double chartIndicatorHandle = iCustom(ChartSymbol(chartId),ChartPeriod(chartId),"JsonAPIIndicator",chartIndicatorId,shortName); //linelabel,colorstyle,linetype,linestyle,linewidth);
|
||||||
|
|
||||||
if(ChartIndicatorAdd(ChartId, chartIndicatorSubWindow, chartIndicatorHandle))
|
if(ChartIndicatorAdd(chartId, chartIndicatorSubWindow, chartIndicatorHandle))
|
||||||
{
|
{
|
||||||
chartWindowIndicatorCount++;
|
chartWindowIndicatorCount++;
|
||||||
ArrayResize(chartWindowIndicators,chartWindowIndicatorCount);
|
ArrayResize(chartWindowIndicators,chartWindowIndicatorCount);
|
||||||
@@ -1528,54 +1519,54 @@ ENUM_TIMEFRAMES GetTimeframe(string chartTF)
|
|||||||
{
|
{
|
||||||
|
|
||||||
ENUM_TIMEFRAMES tf;
|
ENUM_TIMEFRAMES tf;
|
||||||
|
tf=NULL;
|
||||||
|
|
||||||
if(chartTF=="TICK")
|
if(chartTF=="TICK")
|
||||||
tf=PERIOD_CURRENT;
|
tf=PERIOD_CURRENT;
|
||||||
else
|
|
||||||
if(chartTF=="M1")
|
if(chartTF=="M1")
|
||||||
tf=PERIOD_M1;
|
tf=PERIOD_M1;
|
||||||
else
|
|
||||||
if(chartTF=="M5")
|
if(chartTF=="M5")
|
||||||
tf=PERIOD_M5;
|
tf=PERIOD_M5;
|
||||||
else
|
|
||||||
if(chartTF=="M15")
|
if(chartTF=="M15")
|
||||||
tf=PERIOD_M15;
|
tf=PERIOD_M15;
|
||||||
else
|
|
||||||
if(chartTF=="M30")
|
if(chartTF=="M30")
|
||||||
tf=PERIOD_M30;
|
tf=PERIOD_M30;
|
||||||
else
|
|
||||||
if(chartTF=="H1")
|
if(chartTF=="H1")
|
||||||
tf=PERIOD_H1;
|
tf=PERIOD_H1;
|
||||||
else
|
|
||||||
if(chartTF=="H2")
|
if(chartTF=="H2")
|
||||||
tf=PERIOD_H2;
|
tf=PERIOD_H2;
|
||||||
else
|
|
||||||
if(chartTF=="H3")
|
if(chartTF=="H3")
|
||||||
tf=PERIOD_H3;
|
tf=PERIOD_H3;
|
||||||
else
|
|
||||||
if(chartTF=="H4")
|
if(chartTF=="H4")
|
||||||
tf=PERIOD_H4;
|
tf=PERIOD_H4;
|
||||||
else
|
|
||||||
if(chartTF=="H6")
|
if(chartTF=="H6")
|
||||||
tf=PERIOD_H6;
|
tf=PERIOD_H6;
|
||||||
else
|
|
||||||
if(chartTF=="H8")
|
if(chartTF=="H8")
|
||||||
tf=PERIOD_H8;
|
tf=PERIOD_H8;
|
||||||
else
|
|
||||||
if(chartTF=="H12")
|
if(chartTF=="H12")
|
||||||
tf=PERIOD_H12;
|
tf=PERIOD_H12;
|
||||||
else
|
|
||||||
if(chartTF=="D1")
|
if(chartTF=="D1")
|
||||||
tf=PERIOD_D1;
|
tf=PERIOD_D1;
|
||||||
else
|
|
||||||
if(chartTF=="W1")
|
if(chartTF=="W1")
|
||||||
tf=PERIOD_W1;
|
tf=PERIOD_W1;
|
||||||
else
|
|
||||||
if(chartTF=="MN1")
|
if(chartTF=="MN1")
|
||||||
tf=PERIOD_MN1;
|
tf=PERIOD_MN1;
|
||||||
//error will be raised in config function
|
|
||||||
else
|
//if tf == NULL an error will be raised in config function
|
||||||
tf=NULL;
|
|
||||||
return(tf);
|
return(tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+182
-52
@@ -31,10 +31,10 @@ input string ShortName="JsonAPIIndicator";
|
|||||||
double B0[], B1[], B2[], B3[], B4[], B5[], B6[], B7[], B8[], B9[], B10[];
|
double B0[], B1[], B2[], B3[], B4[], B5[], B6[], B7[], B8[], B9[], B10[];
|
||||||
double B11[], B12[], B13[], B14[], B15[], B16[], B17[], B18[], B19[], B20[];
|
double B11[], B12[], B13[], B14[], B15[], B16[], B17[], B18[], B19[], B20[];
|
||||||
double B21[], B22[], B23[], B24[], B25[], B26[], B27[], B28[], B29[];
|
double B21[], B22[], B23[], B24[], B25[], B26[], B27[], B28[], B29[];
|
||||||
double alive[];
|
|
||||||
bool debug = false;
|
bool debug = false;
|
||||||
bool first = false;
|
|
||||||
int activeBufferCount = 0;
|
int activeBufferCount = 0;
|
||||||
|
long mtChartId = 0;
|
||||||
|
bool setFormingCandleBlank = true;
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Custom indicator initialization function |
|
//| Custom indicator initialization function |
|
||||||
@@ -61,7 +61,6 @@ int OnInit()
|
|||||||
chartSubscriptionSocket.setReceiveHighWaterMark(5); // TODO confirm settings
|
chartSubscriptionSocket.setReceiveHighWaterMark(5); // TODO confirm settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--- indicator buffers mapping;
|
//--- indicator buffers mapping;
|
||||||
ArraySetAsSeries(B0,true);
|
ArraySetAsSeries(B0,true);
|
||||||
ArraySetAsSeries(B1,true);
|
ArraySetAsSeries(B1,true);
|
||||||
@@ -93,8 +92,6 @@ int OnInit()
|
|||||||
ArraySetAsSeries(B27,true);
|
ArraySetAsSeries(B27,true);
|
||||||
ArraySetAsSeries(B28,true);
|
ArraySetAsSeries(B28,true);
|
||||||
ArraySetAsSeries(B29,true);
|
ArraySetAsSeries(B29,true);
|
||||||
ArraySetAsSeries(alive,true);
|
|
||||||
|
|
||||||
|
|
||||||
SetIndexBuffer(0,B0,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(0,B0,INDICATOR_CALCULATIONS);
|
||||||
SetIndexBuffer(1,B1,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(1,B1,INDICATOR_CALCULATIONS);
|
||||||
@@ -126,9 +123,6 @@ int OnInit()
|
|||||||
SetIndexBuffer(27,B27,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(27,B27,INDICATOR_CALCULATIONS);
|
||||||
SetIndexBuffer(28,B28,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(28,B28,INDICATOR_CALCULATIONS);
|
||||||
SetIndexBuffer(29,B29,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(29,B29,INDICATOR_CALCULATIONS);
|
||||||
SetIndexBuffer(29,B29,INDICATOR_CALCULATIONS);
|
|
||||||
SetIndexBuffer(30,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);
|
||||||
@@ -136,6 +130,14 @@ int OnInit()
|
|||||||
return(INIT_SUCCEEDED);
|
return(INIT_SUCCEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
// Print("INDI DEINIT ",reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| |
|
//| |
|
||||||
@@ -165,7 +167,9 @@ int OnCalculate(const int rates_total,
|
|||||||
{
|
{
|
||||||
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
|
if(rates_total>prev_calculated && setFormingCandleBlank)
|
||||||
{
|
{
|
||||||
B0[0] = EMPTY_VALUE;
|
B0[0] = EMPTY_VALUE;
|
||||||
B1[0] = EMPTY_VALUE;
|
B1[0] = EMPTY_VALUE;
|
||||||
@@ -198,9 +202,6 @@ int OnCalculate(const int rates_total,
|
|||||||
B28[0] = EMPTY_VALUE;
|
B28[0] = EMPTY_VALUE;
|
||||||
B29[0] = EMPTY_VALUE;
|
B29[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);
|
||||||
@@ -222,7 +223,7 @@ void SubscriptionHandler(ZmqMsg &chartMsg)
|
|||||||
Alert("Deserialization Error");
|
Alert("Deserialization Error");
|
||||||
ExpertRemove();
|
ExpertRemove();
|
||||||
}
|
}
|
||||||
if(message["indicatorChartId"]==IndicatorId)
|
if(message["chartIndicatorId"]==IndicatorId)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(message["action"]=="PLOT" && message["actionType"]=="DATA")
|
if(message["action"]=="PLOT" && message["actionType"]=="DATA")
|
||||||
@@ -378,6 +379,7 @@ void SubscriptionHandler(ZmqMsg &chartMsg)
|
|||||||
WriteToBuffer(message, B29);
|
WriteToBuffer(message, B29);
|
||||||
SetIndexBuffer(29,B29,INDICATOR_DATA);
|
SetIndexBuffer(29,B29,INDICATOR_DATA);
|
||||||
}
|
}
|
||||||
|
ChartRedraw(mtChartId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(message["action"]=="PLOT" && message["actionType"]=="ADDBUFFER")
|
if(message["action"]=="PLOT" && message["actionType"]=="ADDBUFFER")
|
||||||
@@ -387,30 +389,165 @@ void SubscriptionHandler(ZmqMsg &chartMsg)
|
|||||||
string linetypeStr = message["style"]["linetype"].ToStr();
|
string linetypeStr = message["style"]["linetype"].ToStr();
|
||||||
string linestyleStr = message["style"]["linestyle"].ToStr();
|
string linestyleStr = message["style"]["linestyle"].ToStr();
|
||||||
int linewidth = message["style"]["linewidth"].ToInt();
|
int linewidth = message["style"]["linewidth"].ToInt();
|
||||||
|
setFormingCandleBlank = message["style"]["blankforming"].ToBool();
|
||||||
|
|
||||||
color colorstyle = StringToColor(colorstyleStr);
|
color colorstyle = StringToColor(colorstyleStr);
|
||||||
int linetype = StringToEnumInt(linetypeStr);
|
int linetype = StringToEnumInt(linetypeStr);
|
||||||
int linestyle = StringToEnumInt(linestyleStr);
|
int linestyle = StringToEnumInt(linestyleStr);
|
||||||
|
|
||||||
/*
|
|
||||||
//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);
|
SetStyle(activeBufferCount, linelabel, colorstyle, linetype, linestyle, linewidth);
|
||||||
activeBufferCount = activeBufferCount + 1;
|
activeBufferCount = activeBufferCount + 1;
|
||||||
|
|
||||||
|
ClearBuffer(activeBufferCount-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void Clear(double &buffer[])
|
||||||
|
{
|
||||||
|
int bufferSize = ArraySize(buffer);
|
||||||
|
for(int i=0; i<bufferSize; i++)
|
||||||
|
{
|
||||||
|
buffer[i] = EMPTY_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void ClearBuffer(int bufferIdx)
|
||||||
|
{
|
||||||
|
switch(bufferIdx)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
Clear(B0);
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Clear(B1);
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
Clear(B2);
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
Clear(B3);
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
Clear(B4);
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
Clear(B5);
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
Clear(B6);
|
||||||
|
}
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
Clear(B7);
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
Clear(B8);
|
||||||
|
}
|
||||||
|
case 9:
|
||||||
|
{
|
||||||
|
Clear(B9);
|
||||||
|
}
|
||||||
|
case 10:
|
||||||
|
{
|
||||||
|
Clear(B10);
|
||||||
|
}
|
||||||
|
case 11:
|
||||||
|
{
|
||||||
|
Clear(B11);
|
||||||
|
}
|
||||||
|
case 12:
|
||||||
|
{
|
||||||
|
Clear(B12);
|
||||||
|
}
|
||||||
|
case 13:
|
||||||
|
{
|
||||||
|
Clear(B13);
|
||||||
|
}
|
||||||
|
case 14:
|
||||||
|
{
|
||||||
|
Clear(B14);
|
||||||
|
}
|
||||||
|
case 15:
|
||||||
|
{
|
||||||
|
Clear(B15);
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
Clear(B16);
|
||||||
|
}
|
||||||
|
case 17:
|
||||||
|
{
|
||||||
|
Clear(B17);
|
||||||
|
}
|
||||||
|
case 18:
|
||||||
|
{
|
||||||
|
Clear(B18);
|
||||||
|
}
|
||||||
|
case 19:
|
||||||
|
{
|
||||||
|
Clear(B19);
|
||||||
|
}
|
||||||
|
case 20:
|
||||||
|
{
|
||||||
|
Clear(B20);
|
||||||
|
}
|
||||||
|
case 21:
|
||||||
|
{
|
||||||
|
Clear(B21);
|
||||||
|
}
|
||||||
|
case 22:
|
||||||
|
{
|
||||||
|
Clear(B22);
|
||||||
|
}
|
||||||
|
case 23:
|
||||||
|
{
|
||||||
|
Clear(B23);
|
||||||
|
}
|
||||||
|
case 24:
|
||||||
|
{
|
||||||
|
Clear(B24);
|
||||||
|
}
|
||||||
|
case 25:
|
||||||
|
{
|
||||||
|
Clear(B25);
|
||||||
|
}
|
||||||
|
case 26:
|
||||||
|
{
|
||||||
|
Clear(B26);
|
||||||
|
}
|
||||||
|
case 27:
|
||||||
|
{
|
||||||
|
Clear(B27);
|
||||||
|
}
|
||||||
|
case 28:
|
||||||
|
{
|
||||||
|
Clear(B28);
|
||||||
|
}
|
||||||
|
case 29:
|
||||||
|
{
|
||||||
|
Clear(B29);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Update indicator buffer function |
|
//| Update indicator buffer function |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -418,39 +555,32 @@ void WriteToBuffer(CJAVal &message, double &buffer[])
|
|||||||
{
|
{
|
||||||
|
|
||||||
int bufferSize = ArraySize(buffer);
|
int bufferSize = ArraySize(buffer);
|
||||||
|
|
||||||
for(int i=0; i<bufferSize; i++)
|
|
||||||
{
|
|
||||||
buffer[i] = EMPTY_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int messageDataSize = message["data"].Size();
|
int messageDataSize = message["data"].Size();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// calculate the buffer offset
|
||||||
|
MqlRates r[];
|
||||||
|
mtChartId =(datetime)message["mtChartId"].ToInt();
|
||||||
|
datetime fromDate=(datetime)message["fromDate"].ToInt();
|
||||||
|
datetime toDate=TimeCurrent();
|
||||||
|
ENUM_TIMEFRAMES period = ChartPeriod(mtChartId);
|
||||||
|
string symbol = ChartSymbol(mtChartId);
|
||||||
|
int rateCount;
|
||||||
|
|
||||||
|
rateCount = CopyRates(symbol, period, fromDate, toDate, r);
|
||||||
|
int offset = rateCount - 1;
|
||||||
|
|
||||||
|
// write to buffer
|
||||||
for(int i=0; i<messageDataSize; i++)
|
for(int i=0; i<messageDataSize; i++)
|
||||||
{
|
{
|
||||||
// don't add more elements than the automatically sized buffer array can hold
|
// don't add more elements than the automatically sized buffer array can
|
||||||
if(i+1<bufferSize)
|
if(i+offset<bufferSize)
|
||||||
{
|
{
|
||||||
// the first element is the current unformed candle, so we start at index 1
|
double val = message["data"][i].ToDbl();
|
||||||
// we reverse the order of the incoming values, which are expected to be ascending
|
if(val >= EMPTY_VALUE)
|
||||||
//buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl();
|
val = EMPTY_VALUE;
|
||||||
buffer[i+1] = message["data"][messageDataSize-1-i].ToDbl();
|
buffer[i+offset] = val;
|
||||||
}
|
}
|
||||||
//if(i == messageDataSize-1)
|
|
||||||
// buffer[i+1] = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user