ArrayCopy
Nó sao chép một mảng vào một mảng khác.
int ArrayCopy(
void& dst_array[], // mảng đích
const void& src_array[], // mảng nguồn
int dst_start=0, // chỉ số bắt đầu ghi vào mảng đích
int src_start=0, // chỉ số đầu tiên của mảng nguồn
int count=WHOLE_ARRAY // số lượng phần tử
);
2
3
4
5
6
7
Tham số
dst_array[]
[out] Mảng đích
src_array[]
[in] Mảng nguồn
dst_start=0
[in] Chỉ số bắt đầu từ mảng đích. Mặc định, chỉ số bắt đầu là 0.
src_start=0
[in] Chỉ số bắt đầu cho mảng nguồn. Mặc định, chỉ số bắt đầu là 0.
count=WHOLE_ARRAY
[in] Số lượng phần tử cần sao chép. Mặc định, toàn bộ mảng được sao chép (count=WHOLE_ARRAY).
Giá trị trả về
Trả về số lượng phần tử đã sao chép.
Ghi chú
Nếu count<0
hoặc count>src_size-src_start
, toàn bộ phần còn lại của mảng sẽ được sao chép. Mảng được sao chép từ trái sang phải. Đối với mảng chuỗi, vị trí bắt đầu được xác định chính xác để điều chỉnh sao chép từ trái sang phải.
Nếu mảng có kiểu khác nhau, trong quá trình sao chép, nó sẽ cố gắng chuyển đổi từng phần tử của mảng nguồn sang kiểu của mảng đích. Mảng chuỗi chỉ có thể được sao chép vào mảng chuỗi. Mảng của các lớp và cấu trúc chứa các đối tượng yêu cầu khởi tạo không được sao chép. Mảng cấu trúc chỉ có thể được sao chép vào mảng cùng kiểu.
Đối với mảng động với cách đánh chỉ số như trong chuỗi thời gian, kích thước của mảng đích sẽ tự động tăng lên theo lượng dữ liệu được sao chép (nếu lượng dữ liệu vượt quá kích thước mảng). Kích thước mảng đích không tự động giảm.
Ví dụ:
#property description "Chỉ báo làm nổi bật các nến là"
#property description "đỉnh và đáy cục bộ. Độ dài khoảng để tìm"
#property description "các giá trị cực đại cần được xác định bằng tham số đầu vào."
//--- cài đặt chỉ báo
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- vẽ
#property indicator_label1 "Extremums"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- hằng số định sẵn
#define INDICATOR_EMPTY_VALUE 0.0
//--- tham số đầu vào
input int InpNum=4; // Độ dài nửa khoảng
//--- bộ đệm chỉ báo
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- biến toàn cục
int ExtStart=0; // chỉ số của nến đầu tiên không phải là cực trị
int ExtCount=0; // số lượng không phải cực trị trong khoảng
//+------------------------------------------------------------------+
//| Điền các nến không phải cực trị |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
const double &low[],const double &close[])
{
//--- điền các nến
ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
}
//+------------------------------------------------------------------+
//| Hàm khởi tạo chỉ báo tùy chỉnh |
//+------------------------------------------------------------------+
int OnInit()
{
//--- ánh xạ bộ đệm chỉ báo
SetIndexBuffer(0,ExtOpen);
SetIndexBuffer(1,ExtHigh);
SetIndexBuffer(2,ExtLow);
SetIndexBuffer(3,ExtClose);
SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- chỉ định giá trị không hiển thị
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- chỉ định tên của bộ đệm chỉ báo để hiển thị trong cửa sổ dữ liệu
PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Hàm lặp chỉ báo tùy chỉnh |
//+------------------------------------------------------------------+
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[])
{
//--- đặt đánh chỉ số thẳng trong chuỗi thời gian
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- biến bắt đầu tính toán thanh
int start=prev_calculated;
//--- không thực hiện tính toán cho các thanh InpNum*2 đầu tiên
if(start==0)
{
start+=InpNum*2;
ExtStart=0;
ExtCount=0;
}
//--- nếu thanh vừa hình thành, kiểm tra cực trị tiềm năng tiếp theo
if(rates_total-start==1)
start--;
//--- chỉ số thanh cần kiểm tra cực trị
int ext;
//--- vòng lặp tính toán giá trị chỉ báo
for(int i=start;i<rates_total-1;i++)
{
//--- ban đầu trên thanh i không vẽ
ExtOpen[i]=0;
ExtHigh[i]=0;
ExtLow[i]=0;
ExtClose[i]=0;
//--- chỉ số cực trị để kiểm tra
ext=i-InpNum;
//--- kiểm tra đỉnh cục bộ
if(IsMax(high,ext))
{
//--- làm nổi bật nến cực trị
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=1;
//--- làm nổi bật các nến khác đến cực trị bằng màu trung tính
FillCandles(open,high,low,close);
//--- thay đổi giá trị biến
ExtStart=ext+1;
ExtCount=0;
//--- chuyển sang lần lặp tiếp theo
continue;
}
//--- kiểm tra đáy cục bộ
if(IsMin(low,ext))
{
//--- làm nổi bật nến cực trị
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=2;
//--- làm nổi bật các nến khác đến cực trị bằng màu trung tính
FillCandles(open,high,low,close);
//--- thay đổi giá trị biến
ExtStart=ext+1;
ExtCount=0;
//--- chuyển sang lần lặp tiếp theo
continue;
}
//--- tăng số lượng không phải cực trị trong khoảng
ExtCount++;
}
//--- trả về giá trị của prev_calculated cho lần gọi tiếp theo
return(rates_total);
}
//+------------------------------------------------------------------+
//| Kiểm tra xem phần tử mảng hiện tại có phải là đỉnh cục bộ không |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
{
//--- biến bắt đầu khoảng
int i=ind-InpNum;
//--- kết thúc khoảng
int finish=ind+InpNum+1;
//--- kiểm tra nửa đầu của khoảng
for(;i<ind;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- kiểm tra nửa sau của khoảng
for(i=ind+1;i<finish;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- đây là một cực trị
return(true);
}
//+------------------------------------------------------------------+
//| Kiểm tra xem phần tử mảng hiện tại có phải là đáy cục bộ không |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
{
//--- biến bắt đầu khoảng
int i=ind-InpNum;
//--- biến kết thúc khoảng
int finish=ind+InpNum+1;
//--- kiểm tra nửa đầu của khoảng
for(;i<ind;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- kiểm tra nửa sau của khoảng
for(i=ind+1;i<finish;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- đây là một cực trị
return(true);
}
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187