Quy tắc ánh xạ giữa bộ đệm và biểu đồ
Khi đăng ký các biểu đồ bằng cách sử dụng PlotIndexSetInteger(i, PLOT_DRAW_TYPE, type)
, mỗi lần gọi sẽ lần lượt gán một số lượng bộ đệm nhất định cho biểu đồ thứ i dựa trên số lượng cần thiết cho kiểu hiển thị type
(xem bảng ENUM_DRAW_TYPE trong phần trước). Do đó, số lượng bộ đệm này sẽ được loại bỏ khỏi việc xem xét khi liên kết bộ đệm với các biểu đồ tiếp theo (trong các lần gọi PlotIndexSetInteger
tiếp theo).
Ví dụ, nếu biểu đồ đầu tiên (với chỉ số 0) là DRAW_CANDLES, yêu cầu 4 bộ đệm chỉ báo, thì đúng số lượng này sẽ được liên kết với nó. Do đó, các bộ đệm có chỉ số từ 0 đến 3 sẽ được gắn kết, và bộ đệm trống tiếp theo để gắn kết sẽ là bộ đệm có chỉ số 4.
Nếu một biểu đồ đường đơn giản DRAW_LINE được đăng ký tiếp theo (chỉ số của nó trong chuỗi biểu đồ là 1), nó sẽ chỉ chiếm 1 bộ đệm — chính xác tại chỉ số 4.
Nếu một biểu đồ DRAW_ZIGZAG được cấu hình thêm (chỉ số biểu đồ tiếp theo là 2), thì vì nó sử dụng hai bộ đệm, các bộ đệm với chỉ số 5 và 6 sẽ được gán cho nó.
Tất nhiên, số lượng bộ đệm phải đủ cho tất cả các biểu đồ đã đăng ký. Ví dụ trên được minh họa trong bảng sau. Nó chỉ có 7 bộ đệm và 3 biểu đồ.
Chỉ số bộ đệm trong SetIndexBuffer | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Chỉ số biểu đồ trong PlotIndexSetInteger | 0 | 1 | 2 | ||||
Kiểu hiển thị | DRAW_CANDLES | DRAW_LINE | DRAW_ZIGZAG |
Chỉ số của bộ đệm và biểu đồ là độc lập, tức là chỉ số bộ đệm không nhất thiết phải trùng với chỉ số biểu đồ. Đồng thời, khi chỉ số biểu đồ tăng lên, chỉ số của các bộ đệm gắn với chúng cũng tăng, và sự chênh lệch trong chỉ số có thể ngày càng lớn nếu bạn sử dụng các kiểu hiển thị chiếm nhiều hơn một bộ đệm.
Mặc dù thường gọi các hàm SetIndexBuffer
trước PlotIndexSetInteger
, điều này không bắt buộc. Điều quan trọng duy nhất là sự tương ứng chính xác giữa chỉ số bộ đệm và chỉ số biểu đồ. Khi sử dụng các chỉ thị (xem phần tiếp theo), là một phương án thay thế cho việc gọi PlotIndexSetInteger
, các chỉ thị được thực thi trong mọi trường hợp trước trình xử lý OnInit
.
Để thể hiện sự khác biệt giữa chỉ số bộ đệm và chỉ số biểu đồ, hãy xem xét một ví dụ đơn giản của IndHighLowClose.mq5
. Trong tệp này, chúng ta sẽ vẽ phạm vi của mỗi nến giữa High
và Low
dưới dạng biểu đồ cột của kiểu DRAW_HISTOGRAM2 và gạch chân giá Close
bằng một đường đơn giản DRAW_LINE. Để truy cập chuỗi thời gian của các loại giá khác nhau, chúng ta cũng cần thay đổi dạng OnCalculate
từ đơn giản sang đầy đủ.
Vì biểu đồ cột yêu cầu 2 bộ đệm, nên cùng với bộ đệm cho đường Close
, chúng ta cần mô tả ba bộ đệm.
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 2
double highs[];
double lows[];
double closes[];
2
3
4
5
6
7
Đăng ký chúng trong OnInit
theo thứ tự ưu tiên.
int OnInit()
{
// mảng cho các bộ đệm cho 3 loại giá
SetIndexBuffer(0, highs);
SetIndexBuffer(1, lows);
SetIndexBuffer(2, closes);
// vẽ biểu đồ cột giữa High và Low nến dưới chỉ số 0
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_HISTOGRAM2);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 5);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue);
// vẽ đường Close tại chỉ số 1
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
PlotIndexSetInteger(1, PLOT_LINE_WIDTH, 2);
PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrRed);
return INIT_SUCCEEDED;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Đồng thời, độ rộng của biểu đồ cột được đặt là 5 pixel, và độ rộng của đường là 2. Kiểu không được gán rõ ràng, mặc định là STYLE_SOLID.
Bây giờ hãy xem xét hàm OnCalculate
thực tế.
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[])
{
// trên mỗi thanh mới hoặc tập hợp thanh (bao gồm phép tính đầu tiên)
if(prev_calculated != rates_total)
{
// điền vào tất cả các thanh mới
ArrayCopy(highs, high, prev_calculated, prev_calculated);
ArrayCopy(lows, low, prev_calculated, prev_calculated);
ArrayCopy(closes, close, prev_calculated, prev_calculated);
}
else // các tick trên thanh hiện tại
{
// cập nhật thanh cuối cùng
highs[rates_total - 1] = high[rates_total - 1];
lows[rates_total - 1] = low[rates_total - 1];
closes[rates_total - 1] = close[rates_total - 1];
}
// trả về số lượng thanh đã xử lý cho lần gọi tiếp theo
return rates_total;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Kết quả của chỉ báo này được hiển thị trong hình ảnh sau:
Biểu đồ cột High-Low và đường Close
Hãy chú ý đến một điểm quan trọng. Các biểu đồ được vẽ trên biểu đồ theo thứ tự tương ứng với chỉ số của chúng, dẫn đến việc một số biểu đồ trông cao hơn các biểu đồ khác (chồng lấn lên chúng). Trong trường hợp này, biểu đồ cột với chỉ số 0 được vẽ trước, sau đó đường với chỉ số 1 được vẽ lên trên nó. Đôi khi có ý nghĩa khi thay đổi thứ tự đăng ký các biểu đồ để cung cấp khả năng hiển thị tốt hơn cho các cấu trúc đồ họa nhỏ hơn, có thể bị che phủ bởi các biểu đồ lớn hơn (rộng hơn).
Việc đặt ưu tiên như vậy dọc theo trục Z tưởng tượng, đi sâu vào màn hình (vuông góc với màn hình), được gọi là thứ tự Z. Chúng ta sẽ gặp lại kỹ thuật này khi nghiên cứu các đối tượng đồ họa.
Cũng cần nhớ rằng, theo mặc định, các chỉ báo được hiển thị trên biểu đồ giá, nhưng hành vi này có thể được thay đổi trong cài đặt: hộp thoại Chart Properties
, tab Common
, tùy chọn Chart on foreground
. Có một tùy chọn tương tự trong giao diện phần mềm (ChartSetInteger(CHART_FOREGROUND)
, xem phần Chế độ hiển thị biểu đồ).