Đối tượng biểu đồ
Đối tượng biểu đồ OBJ_CHART
cho phép bạn tạo các hình thu nhỏ của các biểu đồ khác bên trong biểu đồ cho các công cụ và khung thời gian khác. Các đối tượng biểu đồ được bao gồm trong danh sách biểu đồ chung, mà chúng ta đã lấy bằng lập trình sử dụng các hàm ChartFirst
và ChartNext
. Như đã đề cập trong phần Kiểm tra trạng thái cửa sổ chính, thuộc tính biểu đồ đặc biệt CHART_IS_OBJECT
cho phép bạn tìm hiểu qua định danh liệu đó là cửa sổ đầy đủ hay đối tượng biểu đồ. Trong trường hợp sau, việc gọi ChartGetInteger(id, CHART_IS_OBJECT)
sẽ trả về true
.
Đối tượng biểu đồ có một tập hợp các thuộc tính chỉ đặc trưng cho nó.
Định danh | Mô tả | Kiểu |
---|---|---|
OBJPROP_CHART_ID | ID biểu đồ (chỉ đọc) | long |
OBJPROP_PERIOD | Chu kỳ biểu đồ | ENUM_TIMEFRAMES |
OBJPROP_DATE_SCALE | Hiển thị thang thời gian | bool |
OBJPROP_PRICE_SCALE | Hiển thị thang giá | bool |
OBJPROP_CHART_SCALE | Tỷ lệ (giá trị từ 0 - 5) | int |
OBJPROP_SYMBOL | Ký hiệu | string |
Định danh thu được qua thuộc tính OBJPROP_CHART_ID
cho phép bạn quản lý đối tượng như một biểu đồ thông thường bằng các hàm từ chương Làm việc với biểu đồ. Tuy nhiên, có một số hạn chế:
- Đối tượng không thể đóng bằng ChartClose
- Không thể thay đổi ký hiệu/chu kỳ trong đối tượng bằng hàm CartSetSymbolPeriod
- Các thuộc tính CHART_SCALE, CHART_BRING_TO_TOP, CHART_SHOW_DATE_SCALE và CHART_SHOW_PRICE_SCALE không được sửa đổi trong đối tượng.
Theo mặc định, tất cả các thuộc tính (ngoại trừ OBJPROP_CHART_ID
) bằng với các thuộc tính tương ứng của cửa sổ hiện tại.
Việc thể hiện các đối tượng biểu đồ được triển khai dưới dạng chỉ báo không bộ đệm ObjectChart.mq5
. Nó tạo một cửa sổ phụ với hai đối tượng biểu đồ cho cùng ký hiệu với biểu đồ hiện tại nhưng với các khung thời gian liền kề phía trên và dưới khung hiện tại.
Các đối tượng được gắn vào góc trên bên phải của cửa sổ phụ và có kích thước cố định như sau:
#define SUBCHART_HEIGHT 150
#define SUBCHART_WIDTH 200
2
Tất nhiên, chiều cao của cửa sổ phụ phải khớp với chiều cao của các đối tượng, cho đến khi chúng ta có thể phản ứng thích nghi với các sự kiện thay đổi kích thước.
#property indicator_separate_window
#property indicator_height SUBCHART_HEIGHT
#property indicator_buffers 0
#property indicator_plots 0
2
3
4
Một biểu đồ nhỏ được cấu hình trong hàm SetupSubChart
, hàm này nhận số của đối tượng, kích thước của nó và khung thời gian yêu cầu làm đầu vào. Kết quả của SetupSubChart
là định danh của đối tượng biểu đồ, mà chúng ta chỉ xuất ra nhật ký để tham khảo.
void OnInit()
{
Print(SetupSubChart(0, SUBCHART_WIDTH, SUBCHART_HEIGHT, PeriodUp(_Period)));
Print(SetupSubChart(1, SUBCHART_WIDTH, SUBCHART_HEIGHT, PeriodDown(_Period)));
}
2
3
4
5
Các macro PeriodUp
và PeriodDown
sử dụng hàm trợ giúp PeriodRelative
.
#define PeriodUp(P) PeriodRelative(P, +1)
#define PeriodDown(P) PeriodRelative(P, -1)
ENUM_TIMEFRAMES PeriodRelative(const ENUM_TIMEFRAMES tf, const int step)
{
static const ENUM_TIMEFRAMES stdtfs[] =
{
PERIOD_M1, // =1 (1)
PERIOD_M2, // =2 (2)
...
PERIOD_W1, // =32769 (8001)
PERIOD_MN1, // =49153 (C001)
};
const int x = ArrayBsearch(stdtfs, tf == PERIOD_CURRENT ? _Period : tf);
const int needle = x + step;
if(needle >= 0 && needle < ArraySize(stdtfs))
{
return stdtfs[needle];
}
return tf;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Dưới đây là hàm chính SetupSubChart
.
long SetupSubChart(const int n, const int dx, const int dy,
ENUM_TIMEFRAMES tf = PERIOD_CURRENT, const string symbol = NULL)
{
// tạo một đối tượng
const string name = Prefix + "Chart-"
+ (symbol == NULL ? _Symbol : symbol) + PeriodToString(tf);
ObjectCreate(0, name, OBJ_CHART, ChartWindowFind(), 0, 0);
// gắn vào góc trên bên phải của cửa sổ phụ
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_RIGHT_UPPER);
// vị trí và kích thước
ObjectSetInteger(0, name, OBJPROP_XSIZE, dx);
ObjectSetInteger(0, name, OBJPROP_YSIZE, dy);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, (n + 1) * dx);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 0);
// cài đặt biểu đồ cụ thể
if(symbol != NULL)
{
ObjectSetString(0, name, OBJPROP_SYMBOL, symbol);
}
if(tf != PERIOD_CURRENT)
{
ObjectSetInteger(0, name, OBJPROP_PERIOD, tf);
}
// tắt hiển thị các đường
ObjectSetInteger(0, name, OBJPROP_DATE_SCALE, false);
ObjectSetInteger(0, name, OBJPROP_PRICE_SCALE, false);
// thêm chỉ báo MA vào đối tượng bằng id của nó chỉ để minh họa
const long id = ObjectGetInteger(0, name, OBJPROP_CHART_ID);
ChartIndicatorAdd(id, 0, iMA(NULL, tf, 10, 0, MODE_EMA, PRICE_CLOSE));
return id;
}
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
30
31
32
33
34
Đối với một đối tượng biểu đồ, điểm neo luôn cố định ở góc trên bên trái của đối tượng, vì vậy khi gắn vào góc phải của cửa sổ, bạn cần cộng thêm chiều rộng của đối tượng (điều này được thực hiện bằng +1 trong biểu thức (n+1)*dx
cho OBJPROP_XDISTANCE
).
Ảnh chụp màn hình sau đây cho thấy kết quả của chỉ báo trên biểu đồ XAUUSD,H1.
Hai đối tượng biểu đồ trong cửa sổ phụ của chỉ báo
Như chúng ta có thể thấy, các biểu đồ nhỏ hiển thị các khung thời gian M30 và H2.
Điều quan trọng cần lưu ý là bạn có thể thêm chỉ báo vào các đối tượng biểu đồ và áp dụng mẫu tpl, bao gồm cả những mẫu có Expert Advisors. Tuy nhiên, bạn không thể tạo đối tượng bên trong các đối tượng biểu đồ.
Khi đối tượng biểu đồ bị ẩn do tắt khả năng hiển thị trên khung thời gian hiện tại hoặc trên tất cả các khung thời gian, thuộc tính CHART_WINDOW_IS_VISIBLE cho biểu đồ bên trong vẫn trả về
true
.