Yes just reverse the loop.
Count up in stead of down, or down in stead of up depending on the situation, of course.
Yes just reverse the loop.
Count up in stead of down, or down in stead of up depending on the situation, of course.
//| DataExport |
//+------------------------------------------------------------------+
#property strict
#property indicator_separate_window
string file_name = "Data.csv";
int fileh =-1;
int lasterror;
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("IndiData");
fileh = FileOpen(file_name,FILE_CSV|FILE_WRITE,',');
if(fileh<1)
{
lasterror = GetLastError();
Print("Error updating file: ",lasterror);
return(false);
}
// writing file headers below
FileWrite(fileh,
"barInd",
"O1",
"H1",
"L1",
"C1"
);
return(0);
}
//+------------------------------------------------------------------+
int deinit()
{
if(fileh>0)
{
FileClose(fileh);
}
return(0);
}
//+------------------------------------------------------------------+
int start()
{
int barcount = IndicatorCounted();
if (barcount<0) return(-1);
if (barcount>0) barcount--;
int barInd=1;
while(barInd<Bars-barcount-1)
{
ExportIndiData(barInd);
barInd++;
}
return(0);
}
//+------------------------------------------------------------------+
void ExportIndiData(int barInd)
{
// write data
FileWrite(fileh,
barInd,
Open[barInd],
High[barInd],
Low[barInd],
Close[barInd]
);
}
//+------------------------------------------------------------------+
Maybe this but it may need some tweaking with the part just above the loop too...
Don't forget to make sure that that values are actually correct.
In some cases you might find the numbering is correct but the data can still be wrong.
Always verify.
Don't forget to make sure that that values are actually correct.
In some cases you might find the numbering is correct but the data can still be wrong.
Always verify.
Thanks Marco. Though as a beginner, I am still struggling with this one... any example you could give, please?
In addition to Marco's great advice, if you are starting out may I suggest you adopt the new event handling functions?
Your general structure would look like this:
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
return(rates_total);
}
There is also an excellent post by whroeder1 which will show you how to do your lookbacks correctly. It also explains a little bit about ArraySetAsSeries, which may be useful for your problem.
Forum on trading, automated trading systems and testing trading strategies
Range not behaving as expected
whroeder1, 2016.05.11 18:55
First define your maximum lookback. | int lookback = ... // iMA(period) has look back of period. // buffer[i+2] has look back of 2 (as TimeSeries) // buffer[i-2] has look back of 2 (not TimeSeries) // use maximum of all. int lookback = ... // iMA(period) has look back of period. // buffer[i+2] has look back of 2 (as TimeSeries) // buffer[i-2] has look back of 2 (not TimeSeries) // use maximum of all. |
Old way, counting down as a TimeSeries | int counted = IndicatorCounted(); for(int iBar = Bars - 1 - MathMax(lookback, counted); iBar >= 0; --iBar){ // Timeseries and Indicators Access uses index=iBar } |
New way, counting down as a TimeSeries (Bars always equals rates_total so can be substituted.) | for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar){ // Timeseries and Indicators Access uses index=iBar https://docs.mql4.com/series } return rates_total-1; // Recalculate current bar next tick. Returning rates_total-1 makes prev_calculated the same as IndicatorCounted(). Alternatively if you return rates_total then must decrement
prev_calculated if non-zero at the beginning of On_Calculate to recalculate
the current bar. Always count down so you're not using future values. |
New way, counting up, not a TimeSeries. | set all accessed arrays and buffers to ArraySetAsSeries(false) Not the Predefined Variables for(int iBar = MathMax(lookback, prev_calculated; iBar < Bars; ++iBar){ // To access a Timeseries use index=Bars -1- iBar // and convert any results back index=Bars -1- result } return rates_total-1; // Recalculate current bar next tick.Always count up so you're not using future values. |
Forum on trading, automated trading systems and testing trading strategies
Range not behaving as expected
whroeder1, 2016.07.28 15:25
New way, counting down as a TimeSeries, but not through bar zero. | #define LAST 1 for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= LAST; --iBar){ : } return rates_total-MathMax(1,LAST); // Recalculate Bar LAST once on new bar. |
- docs.mql4.com
And thats why i never really worry about those issues they are not really related to the end target.
Maybe this ?
//| DataExport |
//+------------------------------------------------------------------+
#property strict
#property indicator_separate_window
string file_name = "Data.csv";
int fileh =-1;
int lasterror;
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("IndiData");
fileh = FileOpen(file_name,FILE_CSV|FILE_WRITE,',');
if(fileh<1)
{
lasterror = GetLastError();
Print("Error updating file: ",lasterror);
return(false);
}
// writing file headers below
FileWrite(fileh,
"barInd",
"O1",
"H1",
"L1",
"C1"
);
return(0);
}
//+------------------------------------------------------------------+
int deinit()
{
if(fileh>0)
{
FileClose(fileh);
}
return(0);
}
//+------------------------------------------------------------------+
int start()
{
int barcount = 0;
if (barcount>IndicatorCounted()) return(-1);
if (barcount<IndicatorCounted()) barcount++;
int barInd=1;
while(barInd<Bars-barcount-1)
{
ExportIndiData(barInd);
barInd++;
}
return(0);
}
//+------------------------------------------------------------------+
void ExportIndiData(int barInd)
{
// write data
FileWrite(fileh,
barInd,
Open[barInd],
High[barInd],
Low[barInd],
Close[barInd]
);
}
//+------------------------------------------------------------------+
I recognize it may be my mistake perhaps I did not do a good job explaining before. So giving it another try:
Current setup I have:
BarInd (Descending! NOT OK!) | Date (Ascending! OK!) | Open | High | Low | Close
What all solutions offered provide so far:
Attaching again the base script, this time also Date column attached to help visualize better.
Very grateful again for further help.
//| DataExport |
//+------------------------------------------------------------------+
#property strict
#property indicator_separate_window
string file_name = "Data.csv";
int fileh =-1;
int lasterror;
//+------------------------------------------------------------------+
int init()
{
IndicatorShortName("IndiData");
fileh = FileOpen(file_name,FILE_CSV|FILE_WRITE,',');
if(fileh<1)
{
lasterror = GetLastError();
Print("Error updating file: ",lasterror);
return(false);
}
// writing file headers below
FileWrite(fileh,
"barId",
"Date",
"O1",
"H1",
"L1",
"C1"
);
return(0);
}
//+------------------------------------------------------------------+
int deinit()
{
if(fileh>0)
{
FileClose(fileh);
}
return(0);
}
//+------------------------------------------------------------------+
int start()
{
int barcount = IndicatorCounted();
if (barcount<0) return(-1);
if (barcount>0) barcount--;
int barInd=Bars-barcount-1;
while(barInd>1)
{
ExportIndiData(barInd);
barInd--;
}
return(0);
}
//+------------------------------------------------------------------+
void ExportIndiData(int barInd)
{
datetime t = Time[barInd];
string bar_datetime =
StringConcatenate(TimeYear(t)+"-"+
TimeMonth(t)+"-"+
TimeDay(t)+" "+
TimeHour(t)+":"+
TimeMinute(t)+":"+
TimeSeconds(t));
// write data
FileWrite(fileh,
barInd,
bar_datetime,
Open[barInd],
High[barInd],
Low[barInd],
Close[barInd]
);
}
//+------------------------------------------------------------------+
humblebee9:
Current setup I have: BarInd (Descending!) | Date (Ascending!) | Open | High | Low | Close What all solutions offered provide so far: barInd (Ascending!) | Date (Descending!) | Open | High | Low | Close What I would like the end result to be: barInd (Ascending!) | Date (Ascending!) | Open | High | Low | Close |
|
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Working on a very simple array data export to CSV. All is working well, except that the bar indicator [barInd] counting is in reverse to what I would prefer it to be.