#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#define OBJ_NAME "TestObjectGetDouble" // Object name
#define WND 0 // 차트 하단 창
#define EXT " (%$)" // 레벨별 가격 값을 표시하기 위한 형식 문자열
/+------------------------------------------------------------------+
//| Script program start function |
/+------------------------------------------------------------------+
void OnStart()
{
//--- 현재 차트 ID, 차트 심볼 및 심볼 Digits
long chart_id= ChartID();
string symbol = ChartSymbol(chart_id);
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
//--- 보이는 차트의 최대 및 최소 가격으로 피보나치 레벨 그래픽 객체를 구성합니다.
if(!CreateFibo(chart_id))
return;
//--- 객체 레벨의 수
int total=(int)ObjectGetInteger(chart_id, OBJ_NAME, OBJPROP_LEVELS);
double value =0;
double price0=0;
double price1=0;
//--- 앵커 포인트 가격
price0=ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_PRICE, 0);
price1=ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_PRICE, 1);
//--- 객체 레벨 수에 따른 루프
for(int i=0; i<total; i++)
{
//--- 현재 레벨에 설정된 값을 가져옵니다.
ResetLastError();
if(!ObjectGetDouble(chart_id, OBJ_NAME, OBJPROP_LEVELVALUE, i, value))
{
Print("ObjectGetDouble() failed. Error ", GetLastError());
return;
}
//--- 객체 바인딩의 최대 및 최소 가격과 이 두 가격 사이의 거리를 가격 값으로 가져옵니다.
double max=fmax(price0, price1);
double min=fmin(price0, price1);
double range=max-min;
//--- 객체의 현재 레벨에 대한 가격 값을 계산합니다.
double level_price=min+range*value;
//--- 차트의 어두운 배경과 밝은 배경 모두에서 볼 수 있도록 레벨의 색상을 설정합니다.
ObjectSetInteger(chart_id, OBJ_NAME, OBJPROP_LEVELCOLOR, i, clrRed);
//--- 레벨 값과 함께 가격 값이 표시되도록 레벨에 대한 형식 문자열을 설정합니다.
string level_text=ObjectGetString(chart_id, OBJ_NAME, OBJPROP_LEVELTEXT, i);
if(StringFind(level_text, EXT)<0)
{
level_text+=EXT;
ObjectSetString(chart_id, OBJ_NAME, OBJPROP_LEVELTEXT, i, level_text);
}
//--- 레벨 번호와 그 데이터(레벨 값과 가격)를 저널에 출력합니다.
PrintFormat("Fibo level [%d] value: %.3f, price: %.*f", i, value, digits, level_price);
}
/*
결과:
Fibo level [0] value: 0.000, price: 0.61989
Fibo level [1] value: 0.236, price: 0.62533
Fibo level [2] value: 0.382, price: 0.62869
Fibo level [3] value: 0.500, price: 0.63140
Fibo level [4] value: 0.618, price: 0.63412
Fibo level [5] value: 1.000, price: 0.64292
Fibo level [6] value: 1.618, price: 0.65715
Fibo level [7] value: 2.618, price: 0.68018
Fibo level [8] value: 4.236, price: 0.71745
*/
}
/+------------------------------------------------------------------+
//| 지정된 차트에 Fibo 레벨 그래픽 객체를 생성합니다. |
/+------------------------------------------------------------------+
bool CreateFibo(const long chart_id)
{
//---현재 보이는 차트에서 가장 높은 가격 값부터 가장 낮은 가격 값까지 Fibo 레벨을 그려서 가져옵니다.
double price_high=0, price_low=0;
datetime time_high =0, time_low =0;
if(!GetChartExtremums(chart_id, price_high, price_low, time_high, time_low))
return(false);
//--- 발견된 가격/시간 좌표에 Fibo Levels 객체를 구성합니다.
if(!ObjectCreate(chart_id, OBJ_NAME, OBJ_FIBO, WND, time_high, price_high, time_low, price_low))
{
PrintFormat("%s: ObjectCreate() failed. Error %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 모두 좋습니다 - 차트를 업데이트하고 'true'를 반환합니다.
ChartRedraw();
return(true);
}
/+------------------------------------------------------------------+
//| 차트의 최대, 최소 가격과 그 시간을 반환합니다. |
/+------------------------------------------------------------------+
bool GetChartExtremums(const long chart_id, double &price_high, double &price_low, datetime &time_high, datetime &time_low)
{
//--- 변수 재설정
price_high=price_low=0;
time_high =time_low =0;
//--- 차트 심볼
string symbol = ChartSymbol(chart_id);
//--- 차트에 보이는 첫 번째 바의 수와 바의 수를 기준으로 복사된 시계열 범위의 시작을 계산합니다.
int first = (int)ChartGetInteger(chart_id, CHART_FIRST_VISIBLE_BAR);
int count = (int)ChartGetInteger(chart_id, CHART_VISIBLE_BARS);
int start = first+1-count;
//--- timeseries가 복사될 배열
double array_high[];
double array_low[];
datetime array_time[];
int index;
//--- 'count'만큼의 시간 시리즈 3개를 배열에 복사하고 'start'부터 시작합니다.
ResetLastError();
if(CopySeries(symbol, PERIOD_CURRENT, start, count, COPY_RATES_TIME|COPY_RATES_HIGH|COPY_RATES_LOW, array_time, array_high, array_low)!=count)
{
PrintFormat("%s: CopySeries() failed. Error %d",__FUNCTION__, GetLastError());
return(false);
}
//--- array_high 배열에서 최대 가격 지수를 찾습니다.
index=ArrayMaximum(array_high);
if(index<0)
{
PrintFormat("%s: ArrayMaximum() failed. Error %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 보이는 차트에서 가장 높은 가격과 이 가격이 위치한 바의 최고가를 기억합니다
price_high=array_high[index];
time_high=array_time[index];
//--- array_low 배열에서 최소 가격 지수를 찾습니다.
index=ArrayMinimum(array_low);
if(index<0)
{
PrintFormat("%s: ArrayMinimum() failed. Error %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 보이는 차트의 최저가와 이 가격이 위치한 바의 시간 가치를 기억합니다.
price_low=array_low[index];
time_low=array_time[index];
//--- 모든게 작동합니다
return(true);
}
|