Kiểm tra số lượng thanh được tính toán: BarsCalculated
Khi chúng ta tạo một chỉ báo bên thứ ba bằng cách gọi iCustom
hoặc các hàm khác mà chúng ta sẽ thấy sau trong chương này, việc tính toán cần một khoảng thời gian. Như chúng ta biết, thước đo chính của sự sẵn sàng dữ liệu chỉ báo là số lượng thanh được tính toán, mà nó trả về từ hàm OnCalculate
của nó. Có handle của chỉ báo, chúng ta có thể tìm ra số lượng này.
int BarsCalculated(int handle)
Hàm này trả về số lượng thanh mà dữ liệu được tính toán trong chỉ báo được chỉ định bởi handle
. Trong trường hợp có lỗi, chúng ta nhận được -1.
Trong khi dữ liệu chưa được tính toán, kết quả là 0. Sau đó, số này nên được so sánh với kích thước của chuỗi thời gian (ví dụ, với rates_total
nếu chỉ báo gọi kiểm tra BarsCalculated
trong bối cảnh của hàm OnCalculate
của chính nó) để phân tích việc xử lý các thanh mới bởi chỉ báo.
Trong chỉ báo UseWPR2.mq5
, chúng ta sẽ cố gắng tạo IndWPR
trong khi thay đổi chu kỳ WPR trong đối số đầu vào.
input int WPRPeriod = 0;
Giá trị mặc định của nó là 0, là một giá trị không hợp lệ. Nó được đề xuất cố ý để thể hiện một tình huống bất thường. Nhớ lại rằng trong mã nguồn IndWPR.mq5
có các kiểm tra trong OnInit
và trong OnCalculate
.
// IndWPR.mq5
void OnInit()
{
if(WPRPeriod < 1)
{
Alert(StringFormat("Incorrect Period value (%d). Should be 1 or larger",
WPRPeriod));
}
...
}
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
{
if(rates_total < WPRPeriod || WPRPeriod < 1) return 0;
...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Do đó, ở chu kỳ bằng không, chúng ta nên nhận được thông báo lỗi, và BarsCalculated
sẽ luôn trả về 0. Sau khi chúng ta nhập một giá trị dương cho chu kỳ, chỉ báo phụ trợ nên bắt đầu tính toán bình thường (và với sự dễ dàng của việc tính toán WPR, gần như ngay lập tức), và BarsCalculated
nên trả về tổng số thanh.
Bây giờ hãy trình bày mã nguồn để tạo handle trong UseWPR2.mq5
.
// UseWPR2.mq5
int handle; // handle to global variable
int OnInit()
{
// passing name and parameter
handle = PRTF(iCustom(_Symbol, _Period, "IndWPR", WPRPeriod));
// next check is useless here because you have to wait,
// when the indicator is loaded, run and calculate
// (here it is for demonstration purposes only)
PRTF(BarsCalculated(handle));
// successful initialization depends on the descriptor
return handle == INVALID_HANDLE ? INIT_FAILED : INIT_SUCCEEDED;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Trong OnCalculate
, chúng ta chỉ ghi lại các giá trị BarsCalculated
và rates_total
.
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &data[])
{
// wait until the slave indicator is calculated on all bars
if(PRTF(BarsCalculated(handle)) != PRTF(rates_total))
{
return prev_calculated;
}
// ... here is usually further work using handle
return rates_total;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Biên dịch và chạy UseWPR2
, trước tiên với tham số 0, sau đó với một giá trị hợp lệ, ví dụ, 21. Dưới đây là các mục nhật ký cho chu kỳ bằng không.
iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
Alert: Incorrect Period value (0). Should be 1 or larger
BarsCalculated(handle)=0 / ok
rates_total=20000 / ok
...
2
3
4
5
6
Ngay sau khi tạo handle, dữ liệu chưa có sẵn, vì vậy lỗi INDICATOR_DATA_NOT_FOUND(4806) được hiển thị, và kết quả BarsCalculated
bằng -1. Tiếp theo là thông báo về tham số đầu vào không chính xác, điều này xác nhận việc tải và khởi chạy thành công chỉ báo IndWPR
. Trong đoạn tiếp theo, chúng ta nhận được giá trị BarsCalculated
bằng 0.
Để chỉ báo được tính toán, chúng ta sẽ nhập tham số đầu vào chính xác. Trong trường hợp này, BarsCalculated
bằng rates_total
.
iCustom(_Symbol,_Period,IndWPR,WPRPeriod)=10 / ok
BarsCalculated(handle)=-1 / INDICATOR_DATA_NOT_FOUND(4806)
BarsCalculated(handle)=20000 / ok
rates_total=20000 / ok
...
2
3
4
5
Sau khi chúng ta đã thành thạo việc kiểm tra sự sẵn sàng của một chỉ báo phụ, chúng ta có thể bắt đầu đọc dữ liệu của nó. Hãy làm điều này trong ví dụ tiếp theo UseWPR3.mq5
, nơi chúng ta sẽ làm quen với hàm CopyBuffer
.