[原创]金叉和死叉的箭头如何显示在均线交叉的位置?
金叉和死叉的箭头如何显示在均线交叉的位置(比如红圈位置)?不要显示在K线下方。万分感谢!
#property copyright "Copyright ?2004, by konKop,wellx"
#property link "http://www.metaquotes.net"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Yellow
#property indicator_color2 White
#property indicator_color3 Yellow
#property indicator_color4 White
extern int 均线周期1 = 20;
extern int 均线周期2 = 100;
extern int 类型1 = 1;
extern int 类型2 = 1;
extern string 类型说明 = "0-SMA; 1-EMA; 2-SMMA; 3-LWMA";
extern int 文字水平 = 0;
extern int 文字垂直 = 0;
extern int 文字大小 = 14;
extern string 文字标识 = "1";
extern color 文字颜色 = Yellow;
extern int 是否报警 = 1;
extern int 是否发邮件 = 1;
double g_ibuf_132;
double g_ibuf_136;
double g_ibuf_140;
double g_ibuf_144;
int gi_148;
int gi_152 = 0;
datetime g_time_156;
int init() {
IndicatorBuffers(4);
SetIndexStyle(0, DRAW_LINE);
SetIndexStyle(1, DRAW_LINE);
SetIndexStyle(2, DRAW_ARROW);
SetIndexStyle(3, DRAW_ARROW);
SetIndexBuffer(0, g_ibuf_132);
SetIndexBuffer(1, g_ibuf_136);
SetIndexBuffer(2, g_ibuf_140);
SetIndexBuffer(3, g_ibuf_144);
SetIndexArrow(2, 233);
SetIndexArrow(3, 234);
gi_148 = 0;
return (0);
}
int start() {
string ls_0;
int li_8 = IndicatorCounted();
if (li_8 < 0) return (-1);
if (li_8 > 0) li_8--;
int li_12 = Bars - li_8;
for (int li_16 = li_12 - 1; li_16 >= 0; li_16--) {
g_ibuf_132[li_16] = iMA(NULL, 0, 均线周期1, 0, 类型1, PRICE_CLOSE, li_16);
g_ibuf_136[li_16] = iMA(NULL, 0, 均线周期2, 0, 类型2, PRICE_CLOSE, li_16);
if (g_ibuf_132[li_16 + 1] < g_ibuf_136[li_16 + 1] && g_ibuf_132[li_16] > g_ibuf_136[li_16]) {
ls_0 = "[" + Period() + "分钟]" + TimeMonth(Time[li_16] + gi_148) + "月" + TimeDay(Time[li_16] + gi_148) + "日" + TimeHour(Time[li_16] + gi_148) + "点" + TimeMinute(Time[li_16] +
gi_148) + "分 " + Symbol() + "在价格" + DoubleToStr(Close[li_16], 4) + "发生" + "金叉";
writetext(文字标识, ls_0, 文字水平 + 20, 文字垂直 + 40, 文字颜色, 文字大小);
g_ibuf_140[li_16] = Low[li_16] - 3.0 * Point;
if (li_16 == 0) {
if (gi_152 == FALSE) {
if (是否报警 == 1 && Time[0] > g_time_156) {
Alert(ls_0);
g_time_156 = Time[0];
}
if (是否发邮件 == 1) SendMail(ls_0, ls_0);
gi_152 = TRUE;
}
}
}
if (g_ibuf_132[li_16 + 1] > g_ibuf_136[li_16 + 1] && g_ibuf_132[li_16] < g_ibuf_136[li_16]) {
ls_0 = "[" + Period() + "分钟]" + TimeMonth(Time[li_16] + gi_148) + "月" + TimeDay(Time[li_16] + gi_148) + "日" + TimeHour(Time[li_16] + gi_148) + "点" + TimeMinute(Time[li_16] +
gi_148) + "分 " + Symbol() + "在价格" + DoubleToStr(Close[li_16], 4) + "发生" + "死叉";
writetext(文字标识, ls_0, 文字水平 + 20, 文字垂直 + 40, 文字颜色, 文字大小);
g_ibuf_144[li_16] = High[li_16] + 3.0 * Point;
if (li_16 == 1) {
if (gi_152 == FALSE) {
if (是否报警 == 1 && Time[0] > g_time_156) {
Alert(ls_0);
g_time_156 = Time[0];
}
if (是否发邮件 == 1) SendMail(ls_0, ls_0);
gi_152 = TRUE;
}
}
} else gi_152 = FALSE;
}
return (0);
}
void writetext(string a_name_0, string a_text_8, int a_x_16, int a_y_20, color a_color_24, int a_fontsize_28) {
ObjectDelete(a_name_0);
ObjectCreate(a_name_0, OBJ_LABEL, 0, 0, 0);
ObjectSetText(a_name_0, a_text_8, a_fontsize_28, "Arial", a_color_24);
ObjectSet(a_name_0, OBJPROP_CORNER, 0);
ObjectSet(a_name_0, OBJPROP_XDISTANCE, a_x_16);
ObjectSet(a_name_0, OBJPROP_YDISTANCE, a_y_20);
}
asz.jpg
发表于:2018-08-22 23:32只看该作者
2楼
把
g_ibuf_140[li_16] = Low[li_16] - 3.0 * Point;
改成
g_ibuf_140[li_16] = g_ibuf_132[li_16];
把
g_ibuf_144[li_16] = High[li_16] + 3.0 * Point;
改成
g_ibuf_144[li_16] = g_ibuf_132[li_16];
点评
发表于 2018-08-23 02:55
韬客社区www.talkfx.co
3楼
乡巴佬对冲 发表于 2018-8-23 07:32
把 g_ibuf_140[li_16] = Low[li_16] - 3.0 * Point; 改成
韬客社区www.talkfx.co
发表于:2018-08-23 03:06只看该作者
5楼
大铅笔:你养我?
kkkkeee:我养你一辈子!
发表于:2018-08-23 03:11只看该作者
7楼
HOME龙尔 发表于 2018-8-23 11:08
大铅笔就是知识
韬客社区www.talkfx.co
8楼
一直后悔大学不是学计算机专业,感觉会写代码的帅帅的。。
韬客社区www.talkfx.co
发表于:2018-08-23 03:28只看该作者
9楼
kkkkeeee 发表于 2018-8-23 11:13
一直后悔大学不是学计算机专业,感觉会写代码的帅帅的。。
发表于:2018-08-23 04:08只看该作者
10楼
乡巴佬对冲 发表于 2018-8-23 11:28
现在学也来得及。 发现现在会编程的在国外也很吃香,报考国外非计算机硕士博士的时候你如果说编程能力 ...
韬客社区www.talkfx.co
发表于:2018-08-23 06:01只看该作者
11楼
本帖最后由 乡巴佬对冲 于 2018-8-23 14:08 编辑
很多人都不理解这个地方的原理,我简单讲一下我的理解吧,如果这样理解以后编写程序就简单多了。
MT4在启动的时候开始装填K线,K线都装填好了后才开始装指标。
假如画面只装一个20MA指标,这里说的是MA原始指标。装MA指标的时候,MT4先执行一次只有一次init()函数,然后每有一次价格更新,就是有新的tick,就会执行一次start() 函数。
那MA指标是如何画上的,第一次执行start() 时你要在程序里针对画面上所有的K线,挨个算出移动平均线,并且画在屏幕上。
所以要写一个循环,取画面的所有时序的K线值,进行计算,跳过前20个K线。注意这里只能取到当前以外的过去的K线值,取不到过去的tick值。
那怎么知道是不是第一次执行start()呢,第一次IndicatorCounted()函数取到的是0,然后取到的是除了当前K线之外的K线数。bar第一次取到的是画面上K线的数量。通过这两个变量控制循环。
第二次tick来时我们就不需要在程序里用作这个工作了,以前画过的MA不要重新画了,只画新出现的K线的MA就行。非要每次都重新再画一遍也没问题,影响速度,控制循环就行。有的有未来函数的就必须重新画,比如那个zigzag。用最新tick描画涉及最新K线刚显示完和新的K线还在tick途中两个状态,有一点点复杂。
不知道能否说清楚。
点评
发表于 2018-08-23 06:57
韬客社区www.talkfx.co
发表于:2018-08-23 06:05只看该作者
12楼
我是某某
高抛低吸,无坚不摧,唯快不破,无损必错
发表于:2018-08-23 06:21只看该作者
13楼
你是龙龙,或者是尔尔。
韬客社区www.talkfx.co
发表于:2018-08-23 06:57只看该作者
14楼
乡巴佬对冲 发表于 2018-8-23 14:01
很多人都不理解这个地方的原理,我简单讲一下我的理解吧,如果这样理解以后编写程序就简单多了。 MT4在 ...
韬客社区www.talkfx.co
发表于:2018-08-23 07:09只看该作者
15楼
本帖最后由 乡巴佬对冲 于 2018-8-23 15:14 编辑
你这个应该是画面上bar的数量不够i+50个造成的,在ExtMacdBuffer=语句的前面加一句,if(Bars <= i+50) continue;
以梦为马 发表于 2018-8-23 14:57
你好,请问一下, for(i=0; i
点评
发表于 2018-08-23 08:53
韬客社区www.talkfx.co
发表于:2018-08-23 08:53只看该作者
16楼
本帖最后由 以梦为马 于 2018-8-23 17:38 编辑
int i,limit;
limit=rates_total-prev_calculated;
if(prev_calculated>0) limit++;
for(i=0; i==============
Bars就代表k线数量啊,你加在那里,结论是永远成立的啊。
==================
这个问题的难点是怎么限制i, 当i> limit-50的时候,不参与 ExtMacdBuffer [ i ] 数组计算。
第一次运行的时候limit需要加这个限制条件 。
但是第一次运行结束,后面再来新的k线时候不需要这个限制条件了,因为这个时候limit是1.
@偶然帅
乡巴佬对冲 发表于 2018-8-23 15:09
你这个应该是画面上bar的数量不够i+50个造成的,在ExtMacdBuffer=语句的前面加一句,if(Bars
韬客社区www.talkfx.co
发表于:2018-08-23 09:38只看该作者
17楼
有点看不懂,可能是自己水平差。
韬客社区www.talkfx.co
发表于:2018-08-23 09:45只看该作者
18楼
本帖最后由 乡巴佬对冲 于 2018-8-23 17:56 编辑
你加上试一下看看
if(limit == 0) limit = 1;
以梦为马 发表于 2018-8-23 16:53
int i,limit; limit=rates_total-prev_calculated; if(prev_calculated>0) limit++;
点评
发表于 2018-08-23 11:02
韬客社区www.talkfx.co
发表于:2018-08-23 11:02只看该作者
19楼
乡巴佬对冲 发表于 2018-8-23 17:45
你加上试一下看看 if(limit == 0) limit = 1;
韬客社区www.talkfx.co
发表于:2018-08-23 12:05只看该作者
20楼
不知道你的程序干啥用的,你试一下下面的程序。
int limit=rates_total-prev_calculated;
if(limit == 0) limit = 1;
for(int i=limit-1; i>=0; i--){
if(Bars <= i+60) continue;
ExtMacdBuffer [ i ] = 某个数值 / iMA(NULL,0,50,0,MODE_SMA,PRICE_CLOSE,i) ;
}