ArrayMaximum
Tìm kiếm phần tử lớn nhất trong chiều đầu tiên của một mảng số đa chiều.
cpp
int ArrayMaximum(
const void& array[], // mảng để tìm kiếm
int start=0, // chỉ số bắt đầu kiểm tra
int count=WHOLE_ARRAY // số lượng phần tử được kiểm tra
);
1
2
3
4
5
2
3
4
5
Tham số
array[]
[in] Một mảng số, nơi thực hiện tìm kiếm.
start=0
[in] Chỉ số bắt đầu kiểm tra.
count=WHOLE_ARRAY
[in] Số lượng phần tử để tìm kiếm. Mặc định, tìm kiếm trong toàn bộ mảng (count=WHOLE_ARRAY).
Giá trị trả về
Hàm trả về chỉ số của phần tử được tìm thấy, có tính đến chuỗi của mảng. Trong trường hợp thất bại, trả về -1.
Ghi chú
Giá trị cờ AS_SERIES được tính đến khi tìm kiếm giá trị tối đa.
Các hàm ArrayMaximum
và ArrayMinimum
chấp nhận mảng có bất kỳ chiều nào làm tham số. Tuy nhiên, việc tìm kiếm luôn được áp dụng cho chiều đầu tiên (chiều số 0).
Ví dụ:
cpp
#property description "Chỉ báo hiển thị các nến của khung thời gian lớn hơn trên khung hiện tại."
//--- cài đặt chỉ báo
#property indicator_chart_window
#property indicator_buffers 16
#property indicator_plots 8
//---- plot 1
#property indicator_label1 "BearBody"
#property indicator_color1 clrSeaGreen,clrSeaGreen
//---- plot 2
#property indicator_label2 "BearBodyEnd"
#property indicator_color2 clrSeaGreen,clrSeaGreen
//---- plot 3
#property indicator_label3 "BearShadow"
#property indicator_color3 clrSalmon,clrSalmon
//---- plot 4
#property indicator_label4 "BearShadowEnd"
#property indicator_color4 clrSalmon,clrSalmon
//---- plot 5
#property indicator_label5 "BullBody"
#property indicator_color5 clrOlive,clrOlive
//---- plot 6
#property indicator_label6 "BullBodyEnd"
#property indicator_color6 clrOlive,clrOlive
//---- plot 7
#property indicator_label7 "BullShadow"
#property indicator_color7 clrSkyBlue,clrSkyBlue
//---- plot 8
#property indicator_label8 "BullShadowEnd"
#property indicator_color8 clrSkyBlue,clrSkyBlue
//--- hằng số định sẵn
#define INDICATOR_EMPTY_VALUE 0.0
//--- tham số đầu vào
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H4; // Khung thời gian để tính toán chỉ báo
input datetime InpDateStart=D'2013.01.01 00:00'; // Ngày bắt đầu phân tích
//--- bộ đệm chỉ báo cho nến giảm
double ExtBearBodyFirst[];
double ExtBearBodySecond[];
double ExtBearBodyEndFirst[];
double ExtBearBodyEndSecond[];
double ExtBearShadowFirst[];
double ExtBearShadowSecond[];
double ExtBearShadowEndFirst[];
double ExtBearShadowEndSecond[];
//--- bộ đệm chỉ báo cho nến tăng
double ExtBullBodyFirst[];
double ExtBullBodySecond[];
double ExtBullBodyEndFirst[];
double ExtBullBodyEndSecond[];
double ExtBullShadowFirst[];
double ExtBullShadowSecond[];
double ExtBullShadowEndFirst[];
double ExtBullShadowEndSecond[];
//--- biến toàn cục
datetime ExtTimeBuff[]; // bộ đệm thời gian của khung thời gian lớn hơn
int ExtSize=0; // kích thước bộ đệm thời gian
int ExtCount=0; // chỉ số trong bộ đệm thời gian
int ExtStartPos=0; // vị trí ban đầu để tính toán chỉ báo
bool ExtStartFlag=true; // cờ phụ trợ để nhận vị trí ban đầu
datetime ExtCurrentTime[1]; // thời gian cuối cùng của thanh khung thời gian lớn hơn được tạo
datetime ExtLastTime; // thời gian cuối cùng từ khung thời gian lớn hơn, mà tại đó thực hiện tính toán
bool ExtBearFlag=true; // cờ để xác định thứ tự ghi dữ liệu vào bộ đệm chỉ báo giảm
bool ExtBullFlag=true; // cờ để xác định thứ tự ghi dữ liệu vào bộ đệm chỉ báo tăng
int ExtIndexMax=0; // chỉ số của phần tử tối đa trong mảng
int ExtIndexMin=0; // chỉ số của phần tử tối thiểu trong mảng
int ExtDirectionFlag=0; // hướng di chuyển giá cho nến hiện tại
//--- độ lệch giữa giá mở và đóng của nến để vẽ chính xác
const double ExtEmptyBodySize=0.2*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//+------------------------------------------------------------------+
//| Điền phần chính của nến |
//+------------------------------------------------------------------+
void FillCandleMain(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
int &index_max,int &index_min)
{
//--- tìm chỉ số của phần tử tối đa và tối thiểu trong các mảng
index_max=ArrayMaximum(high,ExtStartPos,last-start+1); // tối đa trong High
index_min=ArrayMinimum(low,ExtStartPos,last-start+1); // tối thiểu trong Low
//--- xác định bao nhiêu thanh từ khung thời gian hiện tại sẽ được điền
int count=fill_index-start+1;
//--- nếu giá đóng tại thanh đầu tiên vượt quá giá tại thanh cuối cùng, nến là nến giảm
if(open[start]>close[last])
{
//--- nếu trước đó nến là nến tăng, xóa giá trị của bộ đệm chỉ báo tăng
if(ExtDirectionFlag!=-1)
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
//--- nến giảm
ExtDirectionFlag=-1;
//--- tạo nến
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
close[last],high[index_max],low[index_min],start,count,ExtBearFlag);
//--- thoát hàm
return;
}
//--- nếu giá đóng tại thanh đầu tiên nhỏ hơn giá tại thanh cuối cùng, nến là nến tăng
if(open[start]<close[last])
{
//--- nếu trước đó nến là nến giảm, xóa giá trị của bộ đệm chỉ báo giảm
if(ExtDirectionFlag!=1)
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,start,count);
//--- nến tăng
ExtDirectionFlag=1;
//--- tạo nến
FormCandleMain(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,close[last],
open[start],high[index_max],low[index_min],start,count,ExtBullFlag);
//--- thoát hàm
return;
}
//--- nếu bạn ở phần này của hàm, giá mở tại thanh đầu tiên bằng
//--- giá đóng tại thanh cuối cùng; nến như vậy được coi là nến giảm
//--- nếu trước đó nến là nến tăng, xóa giá trị của bộ đệm chỉ báo tăng
if(ExtDirectionFlag!=-1)
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
//--- nến giảm
ExtDirectionFlag=-1;
//--- nếu giá đóng và mở bằng nhau, sử dụng độ lệch để hiển thị chính xác
if(high[index_max]!=low[index_min])
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],start,count,ExtBearFlag);
else
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,
open[start],open[start]-ExtEmptyBodySize,high[index_max],
high[index_max]-ExtEmptyBodySize,start,count,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Điền phần cuối của nến |
//+------------------------------------------------------------------+
void FillCandleEnd(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
const int index_max,const int index_min)
{
//--- không vẽ trong trường hợp chỉ có một thanh
if(last-start==0)
return;
//--- nếu giá đóng tại thanh đầu tiên vượt quá giá tại thanh cuối cùng, nến là nến giảm
if(open[start]>close[last])
{
//--- tạo phần cuối của nến
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,
open[start],close[last],high[index_max],low[index_min],fill_index,ExtBearFlag);
//--- thoát hàm
return;
}
//--- nếu giá đóng tại thanh đầu tiên nhỏ hơn giá tại thanh cuối cùng, nến là nến tăng
if(open[start]<close[last])
{
//--- tạo phần cuối của nến
FormCandleEnd(ExtBullBodyEndFirst,ExtBullBodyEndSecond,ExtBullShadowEndFirst,ExtBullShadowEndSecond,
close[last],open[start],high[index_max],low[index_min],fill_index,ExtBullFlag);
//--- thoát hàm
return;
}
//--- nếu bạn ở phần này của hàm, giá mở tại thanh đầu tiên bằng
//--- giá đóng tại thanh cuối cùng; nến như vậy được coi là nến giảm
//--- tạo phần cuối của nến
if(high[index_max]!=low[index_min])
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],fill_index,ExtBearFlag);
else
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
open[start]-ExtEmptyBodySize,high[index_max],high[index_max]-ExtEmptyBodySize,fill_index,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Hàm khởi tạo chỉ báo tùy chỉnh |
//+------------------------------------------------------------------+
int OnInit()
{
//--- kiểm tra chu kỳ chỉ báo
if(!CheckPeriod((int)Period(),(int)InpPeriod))
return(INIT_PARAMETERS_INCORRECT);
//--- hiển thị dữ liệu giá ở phía trước
ChartSetInteger(0,CHART_FOREGROUND,0,1);
//--- liên kết bộ đệm chỉ báo
SetIndexBuffer(0,ExtBearBodyFirst);
SetIndexBuffer(1,ExtBearBodySecond);
SetIndexBuffer(2,ExtBearBodyEndFirst);
SetIndexBuffer(3,ExtBearBodyEndSecond);
SetIndexBuffer(4,ExtBearShadowFirst);
SetIndexBuffer(5,ExtBearShadowSecond);
SetIndexBuffer(6,ExtBearShadowEndFirst);
SetIndexBuffer(7,ExtBearShadowEndSecond);
SetIndexBuffer(8,ExtBullBodyFirst);
SetIndexBuffer(9,ExtBullBodySecond);
SetIndexBuffer(10,ExtBullBodyEndFirst);
SetIndexBuffer(11,ExtBullBodyEndSecond);
SetIndexBuffer(12,ExtBullShadowFirst);
SetIndexBuffer(13,ExtBullShadowSecond);
SetIndexBuffer(14,ExtBullShadowEndFirst);
SetIndexBuffer(15,ExtBullShadowEndSecond);
//--- đặt một số giá trị thuộc tính để tạo chỉ báo
for(int i=0;i<8;i++)
{
PlotIndexSetInteger(i,PLOT_DRAW_TYPE,DRAW_FILLING); // loại xây dựng đồ họa
PlotIndexSetInteger(i,PLOT_LINE_STYLE,STYLE_SOLID); // kiểu đường vẽ
PlotIndexSetInteger(i,PLOT_LINE_WIDTH,1); // độ rộng đường vẽ
}
//---
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[])
{
//--- trong trường hợp chưa có thanh nào được tính toán
if(prev_calculated==0)
{
//--- nhận thời gian đến của các thanh khung thời gian lớn hơn
if(!GetTimeData())
return(0);
}
//--- đặt chỉ mục trực tiếp
ArraySetAsSeries(time,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(close,false);
//--- biến bắt đầu để tính toán các thanh
int start=prev_calculated;
//--- nếu thanh được tạo, tính lại giá trị chỉ báo trên đó
if(start!=0 && start==rates_total)
start--;
//--- vòng lặp để tính toán giá trị chỉ báo
for(int i=start;i<rates_total;i++)
{
//--- điền i phần tử của bộ đệm chỉ báo bằng giá trị trống
FillIndicatorBuffers(i);
//--- thực hiện tính toán cho các thanh bắt đầu từ ngày InpDateStart
if(time[i]>=InpDateStart)
{
//--- xác định vị trí, từ đó các giá trị sẽ được hiển thị, lần đầu tiên
if(ExtStartFlag)
{
//--- lưu số của thanh ban đầu
ExtStartPos=i;
//--- xác định ngày đầu tiên từ khung thời gian lớn hơn vượt quá time[i]
while(time[i]>=ExtTimeBuff[ExtCount])
if(ExtCount<ExtSize-1)
ExtCount++;
//--- thay đổi giá trị của cờ để không chạy lại vào khối này
ExtStartFlag=false;
}
//--- kiểm tra xem còn phần tử nào trong mảng không
if(ExtCount<ExtSize)
{
//--- chờ giá trị của khung thời gian hiện tại đạt đến giá trị của khung thời gian lớn hơn
if(time[i]>=ExtTimeBuff[ExtCount])
{
//--- vẽ phần chính của nến (không điền khu vực giữa thanh cuối và thanh áp chót)
FillCandleMain(open,close,high,low,ExtStartPos,i-1,i-2,ExtIndexMax,ExtIndexMin);
//--- điền phần cuối của nến (khu vực giữa thanh cuối và thanh áp chót)
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- dịch chuyển vị trí ban đầu để vẽ nến tiếp theo
ExtStartPos=i;
//--- tăng bộ đếm mảng
ExtCount++;
}
else
continue;
}
else
{
//--- đặt lại giá trị mảng
ResetLastError();
//--- nhận ngày cuối cùng từ khung thời gian lớn hơn
if(CopyTime(Symbol(),InpPeriod,0,1,ExtCurrentTime)==-1)
{
Print("Lỗi sao chép dữ liệu, mã = ",GetLastError());
return(0);
}
//--- nếu ngày mới muộn hơn, dừng tạo nến
if(ExtCurrentTime[0]>ExtLastTime)
{
//--- xóa khu vực giữa thanh cuối và thanh áp chót trong bộ đệm chỉ báo chính
ClearEndOfBodyMain(i-1);
//--- điền khu vực bằng bộ đệm chỉ báo phụ
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- dịch chuyển vị trí ban đầu để vẽ nến tiếp theo
ExtStartPos=i;
//--- đặt lại cờ hướng giá
ExtDirectionFlag=0;
//--- lưu ngày cuối cùng mới
ExtLastTime=ExtCurrentTime[0];
}
else
{
//--- tạo nến
FillCandleMain(open,close,high,low,ExtStartPos,i,i,ExtIndexMax,ExtIndexMin);
}
}
}
}
//--- trả về giá trị của prev_calculated cho lần gọi tiếp theo
return(rates_total);
}
//+------------------------------------------------------------------+
//| Kiểm tra tính đúng đắn của chu kỳ chỉ báo được chỉ định |
//+------------------------------------------------------------------+
bool CheckPeriod(int current_period,int high_period)
{
//--- chu kỳ chỉ báo phải vượt quá khung thời gian mà nó được hiển thị
if(current_period>=high_period)
{
Print("Lỗi! Giá trị của chu kỳ chỉ báo phải vượt quá giá trị của khung thời gian hiện tại!");
return(false);
}
//--- nếu chu kỳ chỉ báo là một tuần hoặc một tháng, chu kỳ là đúng
if(high_period>32768)
return(true);
//--- chuyển đổi giá trị chu kỳ sang phút
if(high_period>30)
high_period=(high_period-16384)*60;
if(current_period>30)
current_period=(current_period-16384)*60;
//--- chu kỳ chỉ báo phải là bội số của khung thời gian mà nó được hiển thị
if(high_period%current_period!=0)
{
Print("Lỗi! Giá trị của chu kỳ chỉ báo phải là bội số của giá trị của khung thời gian hiện tại!");
return(false);
}
//--- chu kỳ chỉ báo phải vượt quá khung thời gian mà nó được hiển thị 3 lần hoặc hơn
if(high_period/current_period<3)
{
Print("Lỗi! Chu kỳ chỉ báo phải vượt quá khung thời gian hiện tại 3 lần hoặc hơn!");
return(false);
}
//--- chu kỳ chỉ báo là đúng cho khung thời gian hiện tại
return(true);
}
//+------------------------------------------------------------------+
//| Nhận dữ liệu thời gian từ khung thời gian lớn hơn |
//+------------------------------------------------------------------+
bool GetTimeData(void)
{
//--- đặt lại giá trị lỗi
ResetLastError();
//--- sao chép tất cả dữ liệu cho thời gian hiện tại
if(CopyTime(Symbol(),InpPeriod,InpDateStart,TimeCurrent(),ExtTimeBuff)==-1)
{
//--- nhận mã lỗi
int code=GetLastError();
//--- in ra thông báo lỗi
PrintFormat("Lỗi sao chép dữ liệu! %s",code==4401
? "Lịch sử vẫn đang được tải lên!"
: "Mã = "+IntegerToString(code));
//--- trả về false để thực hiện lại nỗ lực tải dữ liệu
return(false);
}
//--- nhận kích thước mảng
ExtSize=ArraySize(ExtTimeBuff);
//--- đặt chỉ số vòng lặp cho mảng về 0
ExtCount=0;
//--- đặt vị trí của nến hiện tại trên khung thời gian về 0
ExtStartPos=0;
ExtStartFlag=true;
//--- lưu giá trị thời gian cuối cùng từ khung thời gian lớn hơn
ExtLastTime=ExtTimeBuff[ExtSize-1];
//--- thực thi thành công
return(true);
}
//+--------------------------------------------------------------------------+
//| Hàm tạo phần chính của nến. Tùy thuộc vào giá trị của cờ, |
//| hàm xác định dữ liệu và mảng nào sẽ được sử dụng để hiển thị chính xác. |
//+--------------------------------------------------------------------------+
void FormCandleMain(double &body_fst[],double &body_snd[],
double &shadow_fst[],double &shadow_snd[],
const double fst_value,const double snd_value,
const double fst_extremum,const double snd_extremum,
const int start,const int count,const bool flag)
{
//--- kiểm tra giá trị của cờ
if(flag)
{
//--- tạo thân nến
FormMain(body_fst,body_snd,fst_value,snd_value,start,count);
//--- tạo bóng nến
FormMain(shadow_fst,shadow_snd,fst_extremum,snd_extremum,start,count);
}
else
{
//--- tạo thân nến
FormMain(body_fst,body_snd,snd_value,fst_value,start,count);
//--- tạo bóng nến
FormMain(shadow_fst,shadow_snd,snd_extremum,fst_extremum,start,count);
}
}
//+-------------------------------------------------------------------------------+
//| Hàm tạo phần cuối của nến. Tùy thuộc vào giá trị của cờ, |
//| hàm xác định dữ liệu và mảng nào sẽ được sử dụng để hiển thị chính xác. |
//+-------------------------------------------------------------------------------+
void FormCandleEnd(double &body_fst[],double &body_snd[],
double &shadow_fst[],double &shadow_snd[],
const double fst_value,const double snd_value,
const double fst_extremum,const double snd_extremum,
const int end,bool &flag)
{
//--- kiểm tra giá trị của cờ
if(flag)
{
//--- tạo phần cuối của thân nến
FormEnd(body_fst,body_snd,fst_value,snd_value,end);
//--- tạo phần cuối của bóng nến
FormEnd(shadow_fst,shadow_snd,fst_extremum,snd_extremum,end);
//--- thay đổi giá trị của cờ thành giá trị ngược lại
flag=false;
}
else
{
//--- tạo phần cuối của thân nến
FormEnd(body_fst,body_snd,snd_value,fst_value,end);
//--- tạo phần cuối của bóng nến
FormEnd(shadow_fst,shadow_snd,snd_extremum,fst_extremum,end);
//--- thay đổi giá trị của cờ thành giá trị ngược lại
flag=true;
}
}
//+---------------------------------------------------------------------------------+
//| Xóa phần cuối của nến (khu vực giữa thanh cuối và thanh áp chót) |
//+---------------------------------------------------------------------------------+
void ClearEndOfBodyMain(const int ind)
{
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,ind,1);
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,ind,1);
}
//+--------------------------------------------------------------------------+
//| Xóa nến |
//+--------------------------------------------------------------------------+
void ClearCandle(double &body_fst[],double &body_snd[],double &shadow_fst[],
double &shadow_snd[],const int start,const int count)
{
//--- kiểm tra
if(count!=0)
{
//--- điền bộ đệm chỉ báo bằng giá trị trống
ArrayFill(body_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(body_snd,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_snd,start,count,INDICATOR_EMPTY_VALUE);
}
}
//+--------------------------------------------------------------------------+
//| Tạo phần chính của nến |
//+--------------------------------------------------------------------------+
void FormMain(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int start,const int count)
{
//--- kiểm tra
if(count!=0)
{
//--- điền bộ đệm chỉ báo bằng giá trị
ArrayFill(fst,start,count,fst_value);
ArrayFill(snd,start,count,snd_value);
}
}
//+-----------------------------------------------------------------------------+
//| Tạo phần cuối của nến |
//+-----------------------------------------------------------------------------+
void FormEnd(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int last)
{
//--- điền bộ đệm chỉ báo bằng giá trị
ArrayFill(fst,last-1,2,fst_value);
ArrayFill(snd,last-1,2,snd_value);
}
//+------------------------------------------------------------------+
//| Điền phần tử i của bộ đệm chỉ báo bằng giá trị trống |
//+------------------------------------------------------------------+
void FillIndicatorBuffers(const int i)
{
//--- đặt giá trị trống vào ô của bộ đệm chỉ báo
ExtBearBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
}
1
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497