
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
This is NOT in the documentation! Consequently, this is an essay on a free subject. Just like my statement about automatic initialization, even cooler. At least mine had a disclaimer...
It is impossible to describe absolutely everything in the documentation.
If "prev_calculate==0" - it means that we have to go through the whole indicator buffer. If "prev_calculate!=0", then only the rightmost bar or several new ones will be calculated (we use limit):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
It is impossible to describe absolutely everything in the documentation.
If "prev_calculate==0" - it means that we have to go through the whole indicator buffer. If "prev_calculate!=0", then only the rightmost bar or several new ones will be calculated (we use limit):
{
//---
if(prev_calculated==0)
{
Print("prev_calculated==0");
for(int i=0;i<rates_total;i++)
{
//--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
}
return(rates_total);
}
//--- экономный пересчёт только самого правого бара или новых баров
int limit=rates_total-prev_calculated+1;
//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
for(int i=0;i<limit;i++)
{
ExtBuffer[i]=чевой-то там;
}
What is the value? I don't need any values except for the rightmost bar. BUT!!! Then when this rightmost one shifts to the left this data must be saved...
You don't have to write all the buffers, but you could write one with my wishes in mind. If it is the first run, all history should be empty. If prev_calculated was reset as a result of history swapping, ALL that was put into buffer should remain unchanged. Even if there are holes.
Preliminary conclusions:
Why are you talking nonsense? If this initialization is put into OnCalculate, it is zeroed without any cycles. But if we zeroize prev_calculated, it clears all the data that have been accumulated during the operation...
What's the value??? I don't need any value other than the rightmost bar. BUT!!! Then when this rightmost one shifts to the left, that data needs to be saved...
...
I've already suggested a way:
Forum on trading, automated trading systems and testing of trading strategies
prev_calculated
Karputov Vladimir, 2016.10.18 15:11
Sorry for the delay in replying. The only way to save the calculated values for a given timeframe is to save them to a file. You need to take care of the synchronisation - so that when reading from the file the data are placed on their bars. The most logical way is to synchronize it with the bar open time, but there may be some nuances: for example, the bar open time (saved to a file) was 2016.09.05. 25:02, but now there is a bar on the chart with time equal to 2016.09.05. 25:01.An indicator is not a database or a repository.
Therefore, if the indicator displays data that then cannot be calculated on the history, then it is only necessary to save the indicator buffer to a file, and then (in case of history swapping) to read and synchronize the file and bars.I've already suggested a way:
An indicator is not a database or a repository.
Therefore, if the indicator shows the data, which then can't be calculated on the history, then we have only to save the indicator buffer in a file, and then (in the case of history paging) perform the reading and synchronize the file and the bars.... and preferably without writing to a file or even more so to GV.
Vladimir, since you dedicated this topic specifically to prev_calculated, make it useful on this topic. First of all, you should specify the problem that usually occurs with this variable. If you are not familiar with these problems, I will formulate
---
a-- even though it says in the help
The reason is (it is written in help + told by developers) that the variable gets reset to zero when the checksum changes, usually because of history swap.
---
b - you can't use prev_calculated == 0 as a flag of first run onCalculate either. For the same reason
---
c - and you can't use prev_calculated == 0 as a history paging flag either
---
To reduce the wear and tear on users, the wording should be brief and unambiguous: if history paging has not happened at the current call of OnCalculate, prev_calculated contains the number of bars processed at the previous call. If it happened - it is reset to zero
---
All 3 mentioned problems can be solved with crutches. However, since MT5 cannot have crutches by definition, Vladimir, could you create an attractive solution for these three problems? An ugly one is something like this:
#property indicator_buffers 0
#property indicator_plots 0
struct BROWNIE {
int i_Prew_Calculated; // кол-во посчитанных баров
bool b_First_Run; // флаг первого запуска
bool b_History_Updated; // флаг обновления истории
BROWNIE() {
i_Prew_Calculated = WRONG_VALUE;
b_First_Run = true;
b_History_Updated = false;
}
void f_Reset(bool b_Reset_First_Run = true) {
i_Prew_Calculated = WRONG_VALUE;
if(b_Reset_First_Run) b_First_Run = true;
b_History_Updated = false;
}
void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
if(i_New_Prew_Calculated > -1) {
b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
if(b_First_Run) b_First_Run = false;
if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
}
}
};
BROWNIE go_Brownie;
int OnInit(void) {return(INIT_SUCCEEDED);}
void OnDeinit(const int reason) {
go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}
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 &TickVolume[],
const long &Volume[],
const int &Spread[]
) {
if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
go_Brownie.f_Update(prev_calculated);
return(rates_total);
}
Disclaimer: Code - just an idea, I didn't try it on a chart.
In OnDeinit there is a sample - processing for the indicator that doesn't use buffers, it doesn't care about TF and symbol, at each change of TF/symbol there is no need to start from scratch. For example, it works with existing graphical elements, outputs information about account status, orders, etc.
---
By the way
If this option is enabled, it is only necessary to save the indicator buffer to a file and then (in case of history loading) read and synchronize the file and bars.
... and preferably without writing to a file or even more so to a GV.
Maybe this will suit you?
I didn't get into details, but this is solved by this line of code. Copying an array into itself with an index shift.
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.