//+------------------------------------------------------------------+
//| month_first_kline.mq5 |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property description "æ¯æçç¬¬ä¸æ ¹k线ã第ä¸ä¸ªå¨æ¥"
#property description "æ¯å£ãå¹´çç¬¬ä¸æ ¹k线"
#property description "æ¯å¨çç¬¬ä¸æ ¹k线"
#property description "æ¯æ¬çç¬¬ä¸æ ¹k线"
enum LineTimeType {
Week, // å¨
TenDay, // æ¬ï¼10天ï¼
Month, // æ
Quarter, // å£
Year, // å¹´
nYear // nå¹´
};
//--- input parameters
input LineTimeType ltt = Month; // çº¿çæ¶é´ç±»å
input int n_year = 10; // çº¿çæ¶é´ç±»å == nå¹´
input bool first_kline = true, // æ¯ä¸ªæçç¬¬ä¸æ ¹k线
first_Sunday = false; // æ¯ä¸ªæç第ä¸ä¸ªå¨æ¥
input color color_first_kline = C'100,100,100', // é¢è²ï¼æ¯ä¸ªæçç¬¬ä¸æ ¹k线
color_first_Sunday = C'150,150,150'; // é¢è²ï¼æ¯ä¸ªæç第ä¸ä¸ªå¨æ¥
//---- kline data of start time
input bool flag_time_start_kline = true; // 忽ç¥EURUSDå¼å§ä¹åçæ¶é´
input string time_start_kline = "1999.01.01 00:00"; // EURUSDå¼å§æ¶é´
//---- global parameters
string prefix_month_first_kline = "first_kline_of_month-";
string prefix_month_first_Sunday = "month_first_Sunday-";
datetime time_last = NULL;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
int ret;
string err;
if (ltt == nYear && n_year < 1) {
ret = INIT_FAILED;
err = StringFormat("åæ°è®¾ç½®é误ï¼n_year: %d", n_year);
Alert(err);
} else
ret = INIT_SUCCEEDED;
return(ret);
}
void OnDeinit(const int reason) { del_all_line(); }
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(
const int rates_total,
const int prev_calculated,
const int begin,
const double &price[]
) {
/* ç»æ¯æçæ 示线 */
datetime time_curr;
time_curr = iTime(NULL, 0, 0);
if (
! IsStopped()
&& (first_kline || first_Sunday)
&& (time_last == NULL || time_last < time_curr)
) {
draw_line(time_curr);
time_last = time_curr;
}
ChartRedraw();
return(rates_total);
}
//+------------------------------------------------------------------+
void del_all_line() {
/* å 餿æç»çº¿ */
//---- æ¯æçç¬¬ä¸æ ¹k线
ObjectsDeleteAll(0, prefix_month_first_kline, 0, OBJ_VLINE);
//---- æ¯æç第ä¸ä¸ªå¨æ¥
ObjectsDeleteAll(0, prefix_month_first_Sunday, 0, OBJ_VLINE);
}
void draw_line_month_first_kline(datetime t_p) {
string name;
/* æ ç¤ºæ¯æçç¬¬ä¸æ ¹k线 */
name = prefix_month_first_kline + TimeToString(t_p, TIME_DATE);
if (ObjectFind(0, name) < 0) {
ObjectCreate(0, name, OBJ_VLINE, 0, t_p, 0);
ObjectSetInteger(0, name, OBJPROP_COLOR, color_first_kline);
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
}
}
void draw_line_month_first_Sunday(datetime t_p) {
/* æ ç¤ºæ¯æç第ä¸ä¸ªå¨æ¥00:00
* ç¹æ®æ
åµ:
* 2019.03.08
* 2018.03.09
* 2017.12.08
* 2017.03.10
* 2016.07.08
*/
MqlDateTime x;
int i;
datetime t_q;
string name;
TimeToStruct(t_p, x);
i = 7 - x.day_of_week;
if (i == 1)
// å¨å
i += 7;
x.day += i;
if (
(x.year == 2019 && x.mon == 3)
|| (x.year == 2018 && x.mon == 3)
|| (x.year == 2017 && x.mon == 12)
|| (x.year == 2017 && x.mon == 3)
|| (x.year == 2016 && x.mon == 7)
)
// ç¹æ®æ
åµ
x.day += 7;
t_q = StructToTime(x);
name = prefix_month_first_Sunday + TimeToString(t_q, TIME_DATE);
if (ObjectFind(0, name) < 0) {
ObjectCreate(0, name, OBJ_VLINE, 0, t_q, 0);
ObjectSetInteger(0, name, OBJPROP_COLOR, color_first_Sunday);
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
}
}
MqlDateTime get_right_time(const datetime dt) {
/* è®¡ç®æ£ç¡®çæ¶é´ */
int n, m;
MqlDateTime x;
TimeToStruct(dt, x);
x.day = 1;
x.hour = 0;
x.min = 0;
x.sec = 0;
if (ltt == Week) {
// å¨
n = x.day_of_week;
if (0 < n) {
m = (int)StructToTime(x) - n * 24 * 3600;
TimeToStruct(m, x);
}
} else if (ltt == TenDay) {
// æ¬
if (x.day < 11)
// 䏿¬
x.day = 1;
else if (x.day < 21)
// 䏿¬
x.day = 11;
else
// 䏿¬
x.day = 21;
} else if (ltt == Month)
// æ
x.day = 1;
else if (ltt == Quarter) {
// å£
x.day = 1;
if (x.mon < 4)
x.mon = 1;
else if (x.mon < 7)
x.mon = 4;
else if (x.mon < 10)
x.mon = 7;
else
x.mon = 10;
} else if (ltt == Year || ltt == nYear) {
// å¹´
x.day = 1;
x.mon = 1;
}
return(x);
}
void next_time(MqlDateTime &x) {
/* ä¸ä¸ä¸ªæ¶é´ */
int m;
if (ltt == Week) {
// å¨
m = (int)StructToTime(x) + 7 * 24 * 3600;
TimeToStruct(m, x);
} else if (ltt == TenDay) {
// æ¬
if (x.day == 1)
// 䏿¬
x.day = 11;
else if (x.day == 11)
// 䏿¬
x.day = 21;
else {
// 䏿¬
x.day = 1;
x.mon += 1;
if (12 < x.mon) {
x.mon = 1;
x.year += 1;
}
}
} else if (ltt == Month) {
// æ
x.mon += 1;
if (12 < x.mon) {
x.mon = 1;
x.year += 1;
}
} else if (ltt == Quarter) {
// å£
x.mon += 3;
if (12 < x.mon) {
x.mon = 1;
x.year += 1;
}
} else if (ltt == Year)
// å¹´
x.year += 1;
else if (ltt == nYear)
// nå¹´
x.year += n_year;
}
datetime get_time_start(void) {
/* è·åå¼å§æ¶é´ */
datetime t_start, tsk;
if (time_last == NULL)
t_start = iTime(NULL, 0, -1);
else
t_start = time_last;
tsk = StringToTime(time_start_kline);
if (flag_time_start_kline && t_start < tsk)
t_start = tsk;
return(t_start);
}
void draw_line(const datetime time_curr) {
datetime t_start, t_stop, t_p;
MqlDateTime x;
// åå¾è¡¨ç¬¬ä¸æ ¹k线
t_start = get_time_start();
// åå¾è¡¨æå䏿 ¹k线
t_stop = time_curr;
x = get_right_time(t_start);
t_p = StructToTime(x);
while (t_p < t_stop) {
//---- ä¸ä¸ªæç1å·
next_time(x);
t_p = StructToTime(x);
//---- æ ç¤ºæ¯æçç¬¬ä¸æ ¹k线
if (first_kline)
draw_line_month_first_kline(t_p);
//---- æ ç¤ºæ¯æç第ä¸ä¸ªå¨æ¥
if (first_Sunday && ltt != Week)
draw_line_month_first_Sunday(t_p);
}
ChartRedraw();
}
//+------------------------------------------------------------------+
Comments