I'm using the code from this article https://www.mql5.com/en/articles/159 to calculate when a new bar opens but it's not displaying the historical data for the indicator.
I have modified the TimeCurrent()
to iTime( _Symbol, _Period, shift )
so as to try to handle this, but it's not working.
Could you tell me what I'm doing wrong please?
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 RoyalBlue
#include <Lib_CisNewBar.mqh>
CisNewBar current_chart;
//---- input parameters
extern int Length=18; // Bollinger Bands Period
extern int Deviation=2; // Deviation was 2
extern double MoneyRisk=1.00; // Offset Factor
extern int Signal=1; // Display signals mode: 1-Signals & Stops; 0-only Stops; 2-only Signals;
extern int Line=1; // Display line mode: 0-no,1-yes
extern int Nbars=1000;
//---- indicator buffers
double TrendBuffer[];
extern bool SoundON=true;
bool TurnedUp = false;
bool TurnedDown = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
string short_name;
//---- indicator line
SetIndexBuffer(0,TrendBuffer);
SetIndexStyle(0,DRAW_LINE,0,1);
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
short_name="Example ("+Length+","+Deviation+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Trend Value");
//----
SetIndexDrawBegin(0,Length);
//----
return(INIT_SUCCEEDED);
}
void deinit()
{
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int shift;
for (shift=Nbars;shift>=0;shift--)
{
TrendBuffer[shift]=0;
}
for (shift=Nbars-Length-1;shift>=0;shift--)
{
int period_seconds=PeriodSeconds(_Period);
datetime new_time=iTime(_Symbol,_Period,shift)/period_seconds*period_seconds;
if(current_chart.isNewBar(new_time))
{
Print("time[shift] = "+TimeToString(time[shift]));
if( Close[shift] > Close[shift+1] )
TrendBuffer[shift]=1;
else if(Close[shift] < Close[shift+1] )
TrendBuffer[shift]=-1;
else
TrendBuffer[shift]=0;
}
}
return(0);
}
Thanks.
MQL4.56789
has another syntaxFor Custom Indicator, the "new"-MQL4.56789
source shall rather read
void OnInit(){ ... }
andvoid OnDeinit( const int anMT4_Reason2callDeinit ){ ... }
datetime
Your code defines a variable new_time
, typed as a datetime
The datetime type is intended for storing the date and time as the number of seconds elapsed since January 01, 1970.
and
Values range from 1 January, 1970 to 31 December, 3000
So, in case of your new_time
assignment, the proper iTime()
value is divided by an amount of PeriodSeconds()
and right next it is re-multiplied by the exact same value, which should not change the value of the iTime()
result.
Such operation, while having no theoretical impact on result, might in practice of a code-execution introduce a risk of a numerical inaccuracy, range overflow/underflow and a theoretical notice about a resolution of an 8-byte class storage is not helping to go past the upper bound limit, stated in the documentation as Dec-31, 3000.
In similar cases unpredicatable results and even MT4 unhandled exceptions and MQL4-code terminations are to be expected.
What worse one may expect for a production grade software? So, avoid, avoid and avoid any such risk.
There is no direct positive value for such a Custom Indicator calculation step.
TimeCurrent() / PeriodSeconds()
side-effect of roundingWhile iTime()
is always divisible by it's "own" time-frame PeriodSeconds()
, TimeCurrent()
is not.
Thus one may read the original ( assumed ) construct of
TimeCurrent() / PeriodSeconds() // .DIV is subject to rounding to int
* PeriodSeconds(); // before the forthcoming .MUL
"hacks" the need to align a [last known server time, time of the last quote receipt for one of the symbols selected in the "Market Watch" window] to one's "own" time-frame value of a start-of-current bar time.
MQL4
Current MQL4
code-execution engine is Build 890 ( 25 Sep 2015 ), so your cited source was using an MQL5
language syntax some 5 years old (!!), which namely in MQL4
-domain means _be_very_carefull_
In the meantime string
-s ceased to be string
-s,
many GUI functions have several calling protocols in parallel,
and
countless man*years of DLL/API-code-base dev/maint were lost due to similar moving sands.
So -5- years gap is a warning per-se.
One never enters the same river twice
MQL4.56789
allows a clean approach:in case your motivation is just to be able to detect on-demand a situation a new bar has started, the Build-890/1174 compiler allows for a cleaner approach:
bool aNewBarEVENT( const string anFxSYMBOL, // _Symbol,
const int aTimeFRAME // PERIOD_M6
)
{ static int pBars = EMPTY; // previous
int oBars = iBars( anFxSYMBOL, aTimeFRAME ); // observed
if ( pBars == oBars ) return( False ); // .NACK
pBars = oBars, return( True ); // .UPD + .ACK
}